1 /* WhySynth DSSI software synthesizer plugin
2  *
3  * Copyright (C) 2005-2008, 2010 Sean Bolton and others.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be
11  * useful, but WITHOUT ANY WARRANTY; without even the implied
12  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13  * PURPOSE.  See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free
17  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301 USA.
19  */
20 
21 #define _BSD_SOURCE    1
22 #define _SVID_SOURCE   1
23 #define _ISOC99_SOURCE 1
24 
25 #include <stdlib.h>
26 #include <math.h>
27 
28 #include <ladspa.h>
29 
30 #include "whysynth_types.h"
31 #include "dssp_event.h"
32 #include "effects.h"
33 
34 /* Okay, this is kinda goofy, the result of having changed my mind at least
35  * three times....
36  *
37  * Basically the idea was to allow y_instantiate() a way to query effects as to
38  * their memory needs, then allocate one buffer to be shared between different
39  * effects.
40  *
41  * Each effect needs a function effect_<name>_request_buffers(), which is
42  * called during instantiate() to query the effect's memory needs, and again
43  * from run_synth() any time the effect type changes.
44  *
45  * The first time this function is called (during instantiate()) is a "dry run",
46  * and anything written to the allocated memory will be lost.  Subsequent times
47  * this function is called will be to actually set up the memory for running
48  * the effect.
49  *
50  * This function must call effects_request_buffer() for each piece of memory it
51  * needs. This function (effect_<name>_request_buffers()) may access anything
52  * within the first 4Kb of memory requested, but must not assume anything beyond
53  * that will exist (since it won't the first time the function is called).
54  *
55  * At some point while allocating buffers, this function may call
56  * effects_request_silencing_of_subsequent_allocations().  Any buffers allocated
57  * after this call will be silenced before the effect_<name>_process() function
58  * is called.
59  */
60 
61 /*
62  * effects_request_buffer
63  */
64 void *
effects_request_buffer(y_synth_t * synth,size_t size)65 effects_request_buffer(y_synth_t *synth, size_t size)
66 {
67     void *p = (void *)((char *)(synth->effect_buffer) + synth->effect_buffer_allocation);
68 
69     synth->effect_buffer_allocation += size;
70     if (synth->effect_buffer_highwater < synth->effect_buffer_allocation)
71         synth->effect_buffer_highwater = synth->effect_buffer_allocation;
72     /* printf("allocation = %ld, highwater = %ld\n", synth->effect_buffer_allocation, synth->effect_buffer_highwater); */
73     return p;
74 }
75 
76 /*
77  * effects_setup
78  */
79 int
effects_setup(y_synth_t * synth)80 effects_setup(y_synth_t *synth)
81 {
82     synth->effect_buffer = (void *)malloc(4096);
83     if (!synth->effect_buffer)
84         return 0;
85 
86     synth->effect_buffer_highwater = 0;
87     effects_start_allocation(synth);
88     effect_reverb_request_buffers(synth);
89     effects_start_allocation(synth);
90     effect_delay_request_buffers(synth);
91     effects_start_allocation(synth);
92     effect_screverb_request_buffers(synth);
93 
94     if (synth->effect_buffer_highwater > 4096) {
95         free(synth->effect_buffer);
96         synth->effect_buffer = (void *)calloc(1, synth->effect_buffer_highwater);
97         if (!synth->effect_buffer)
98             return 0;
99     }
100 
101     return 1;
102 }
103 
104 /*
105  * effects_cleanup
106  */
107 void
effects_cleanup(y_synth_t * synth)108 effects_cleanup(y_synth_t *synth)
109 {
110     if (synth->effect_buffer) free(synth->effect_buffer);
111     synth->effect_buffer = NULL;
112 }
113 
114 /*
115  * effects_process
116  */
117 void
effects_process(y_synth_t * synth,unsigned long sample_count,LADSPA_Data * out_left,LADSPA_Data * out_right)118 effects_process(y_synth_t *synth, unsigned long sample_count,
119                 LADSPA_Data *out_left, LADSPA_Data *out_right)
120 {
121     unsigned long i;
122     int current_effect_mode = lrintf(*(synth->effect_mode)); /* will not be 0 */
123 
124     if (current_effect_mode != synth->last_effect_mode) {
125 
126         synth->last_effect_mode = current_effect_mode;
127 
128         effects_start_allocation(synth);
129         /* assume we need to silence entire allocation unless effect says otherwise */
130         effects_request_silencing_of_subsequent_allocations(synth);
131         switch(current_effect_mode) {
132           case 1:  /* Tim Goetze's Plate2x2 reverb */
133             effect_reverb_request_buffers(synth);
134             effect_reverb_setup(synth);
135             break;
136 
137           case 2:  /* Dual delay */
138             effect_delay_request_buffers(synth);
139             effect_delay_setup(synth);
140             break;
141 
142           case 3:  /* Sean Costello's reverb */
143             effect_screverb_request_buffers(synth);
144             effect_screverb_setup(synth);
145             break;
146         }
147     }
148 
149     if (synth->effect_buffer_silence_count) /* buffer is still dirty */
150         current_effect_mode = 0;
151 
152     switch(current_effect_mode) {
153 
154       case 0:  /* effect buffer is still dirty, so silence some of it after running the DC blocker */
155         {   float r = synth->dc_block_r,
156                   l_xnm1 = synth->dc_block_l_xnm1,
157                   l_ynm1 = synth->dc_block_l_ynm1,
158                   r_xnm1 = synth->dc_block_r_xnm1,
159                   r_ynm1 = synth->dc_block_r_ynm1;
160             float dry = 1.0f - *(synth->effect_mix);
161 
162             for (i = 0; i < sample_count; i++) {
163                 l_ynm1 = synth->voice_bus_l[i] - l_xnm1 + r * l_ynm1;
164                 l_xnm1 = synth->voice_bus_l[i];
165                 out_left[i] = l_ynm1 * dry;
166                 r_ynm1 = synth->voice_bus_r[i] - r_xnm1 + r * r_ynm1;
167                 r_xnm1 = synth->voice_bus_r[i];
168                 out_right[i] = r_ynm1 * dry;
169             }
170             synth->dc_block_l_xnm1 = l_xnm1;
171             synth->dc_block_l_ynm1 = l_ynm1;
172             synth->dc_block_r_xnm1 = r_xnm1;
173             synth->dc_block_r_ynm1 = r_ynm1;
174 
175             i = synth->effect_buffer_allocation - synth->effect_buffer_silence_count;
176             if (i > 8 * sample_count * sizeof(float)) {
177                 i = 8 * sample_count * sizeof(float);
178                 memset(synth->effect_buffer + synth->effect_buffer_silence_count, 0, i);
179                 synth->effect_buffer_silence_count += i;
180             } else {
181                 memset(synth->effect_buffer + synth->effect_buffer_silence_count, 0, i);
182                 synth->effect_buffer_silence_count = 0;
183             }
184         }
185         break;
186 
187       case 1:  /* Tim Goetze's Plate2x2 reverb */
188         effect_reverb_process(synth, sample_count, out_left, out_right);
189         break;
190 
191       case 2:  /* Dual delay */
192         effect_delay_process(synth, sample_count, out_left, out_right);
193         break;
194 
195       case 3:  /* Sean Costello's reverb */
196         effect_screverb_process(synth, sample_count, out_left, out_right);
197         break;
198     }
199 }
200 
201