1 /*
2 * GNUitar
3 * Pump module - processeing sound
4 * Copyright (C) 2000,2001,2003 Max Rudensky <fonin@ziet.zhitomir.ua>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * $Id: pump.c,v 1.18 2005/04/24 19:11:22 fonin Exp $
21 *
22 * $Log: pump.c,v $
23 * Revision 1.18 2005/04/24 19:11:22 fonin
24 * Optimized for zero input (after the noise filter) to avoid the extra calcs
25 *
26 * Revision 1.17 2005/04/15 14:32:39 fonin
27 * Few improvements with the effects save/load; fixed nasty bug with CR/LF translation when saving preset files on Win32
28 *
29 * Revision 1.16 2004/08/10 15:07:31 fonin
30 * Support processing in float/int - type DSP_SAMPLE
31 *
32 * Revision 1.15 2003/12/28 10:16:08 fonin
33 * Code lickup
34 *
35 * Revision 1.14 2003/12/21 08:40:36 dexterus
36 * biquad files amd eqbank working
37 *
38 * Revision 1.13 2003/04/12 20:02:10 fonin
39 * New noise gate effect.
40 *
41 * Revision 1.12 2003/04/11 18:34:36 fonin
42 * Added distort2 effect.
43 *
44 * Revision 1.11 2003/03/28 19:56:08 fonin
45 * Sampling rate is 44100 by default.
46 *
47 * Revision 1.10 2003/03/09 21:12:41 fonin
48 * New variables for new "change sampling params" feature.
49 *
50 * Revision 1.9 2003/02/05 21:10:10 fonin
51 * Cleanup before release.
52 *
53 * Revision 1.8 2003/02/03 17:23:26 fonin
54 * One more newline after the effects were loaded by pump_start().
55 *
56 * Revision 1.7 2003/02/03 11:39:25 fonin
57 * Copyright year changed.
58 *
59 * Revision 1.6 2003/01/29 19:34:00 fonin
60 * Win32 port.
61 *
62 * Revision 1.5 2001/06/02 14:05:59 fonin
63 * Added GNU disclaimer.
64 *
65 * Revision 1.4 2001/03/25 17:42:32 fonin
66 * open() can overwrite existing files from now, because program switches back to real user priorities after start.
67 *
68 * Revision 1.3 2001/03/25 12:10:06 fonin
69 * Text messages begin from newline rather than end with it.
70 *
71 * Revision 1.2 2001/01/13 10:02:35 fonin
72 * Fix: setuid root program shouldnt overwrite existing files.
73 *
74 * Revision 1.1.1.1 2001/01/11 13:22:01 fonin
75 * Version 0.1.0 Release 1 beta
76 *
77 */
78
79 #include <stdio.h>
80 #include <stdlib.h>
81 #include <string.h>
82 #ifndef _WIN32
83 # include <unistd.h>
84 #else
85 # include <io.h>
86 #endif
87 #include <assert.h>
88 #include <fcntl.h>
89 #include <sys/types.h>
90 #include <sys/stat.h>
91 #include "pump.h"
92 #include "gui.h"
93
94 #include "autowah.h"
95 #include "phasor.h"
96 #include "chorus.h"
97 #include "delay.h"
98 #include "echo.h"
99 #include "tremolo.h"
100 #include "vibrato.h"
101 #include "distort.h"
102 #include "distort2.h"
103 #include "sustain.h"
104 #include "reverb.h"
105 #include "tracker.h"
106 #include "noise.h"
107 #include "eqbank.h"
108
109 struct effect *effects[MAX_EFFECTS];
110 int n = 0;
111 unsigned short audio_lock = 0; /*
112 * when nonzero pause pumping
113 */
114 extern char version[];
115 unsigned short write_track = 0; /*
116 * when nonzero we should write
117 * sample to disk
118 */
119 extern void initSinLookUp(void); /*
120 * from chorus.c
121 */
122
123 unsigned short nchannels = 1;
124 unsigned int sample_rate = 44100;
125 unsigned short bits = 16;
126 unsigned int buffer_size = MIN_BUFFER_SIZE * 2;
127 #ifdef _WIN32
128 unsigned int nbuffers = MAX_BUFFERS;
129 #endif
130
131 int
pump_sample(DSP_SAMPLE * s,int size)132 pump_sample(DSP_SAMPLE *s, int size)
133 {
134 struct data_block db;
135 int i;
136
137 if (audio_lock)
138 return 0;
139
140 db.data = s;
141 db.len = size;
142
143 /* no input, no output :-) to avoid extra calc. Optimized for noise gate,
144 * when all input is zero.
145 * This is the heuristics - since there is no the standard function
146 * in the ANSI C library that reliably compares the memory region
147 * with the given byte, we compare just a few excerpts from an array.
148 * If everything is zero, we have a large chances that all array is zero. */
149 if(s[0]==0 && s[1]==0 && s[16]==0 && s[17]==0 &&
150 s[24]==0 && s[25]==0 && s[32]==0 && s[33]==0 &&
151 s[buffer_size-1]==0) {
152 /* nothing */
153 }
154 /*
155 * Pumping
156 */
157 else for (i = 0; i < n; i++) {
158 effects[i]->proc_filter(effects[i], &db);
159 }
160
161 /*
162 * Writing track
163 */
164 if (write_track) {
165 track_write(s, size);
166 }
167
168 return 0;
169 }
170
171 struct effect_creator effect_list[] = {
172 {"autowah", autowah_create},
173 {"distort", distort_create},
174 {"delay", delay_create},
175 {"reverb", reverb_create},
176 {"vibrato", vibrato_create},
177 {"chorus", chorus_create},
178 {"echo", echo_create},
179 {"phasor", phasor_create},
180 {"tremolo", tremolo_create},
181 {"sustain", sustain_create},
182 {"distort2", distort2_create},
183 {"noise gate", noise_create},
184 {"eq bank", eqbank_create},
185 {NULL, NULL}
186 };
187
188 void
pump_start(int argc,char ** argv)189 pump_start(int argc, char **argv)
190 {
191 int i,
192 j;
193
194 void (*create_f[10]) (struct effect *);
195
196 initSinLookUp();
197
198 audio_lock = 1;
199 j = 0;
200
201 if (argc == 1) {
202 int k = 0;
203 printf("\nPossible effects:");
204 while (effect_list[k].str) {
205 printf("\n %s", effect_list[k].str);
206 k++;
207 }
208 }
209 for (i = 1; i < argc; i++) {
210 int k = 0;
211 while (effect_list[k].str && strcmp(argv[i], effect_list[k].str)) {
212 k++;
213 }
214 if (effect_list[k].str) {
215 create_f[j++] = effect_list[k].create_f;
216 printf("\nadding %s", effect_list[k].str);
217 gtk_clist_append(GTK_CLIST(processor), &effect_list[k].str);
218 } else {
219 printf("\n%s is not a known effect", argv[i]);
220 }
221 }
222 create_f[j++] = NULL;
223
224 /*
225 * Cleaning effects[]
226 */
227 for (j = 0; j < MAX_EFFECTS; j++) {
228 effects[j] = NULL;
229 }
230
231 while (n < MAX_EFFECTS && create_f[n]) {
232 effects[n] = (struct effect *) calloc(1, sizeof(struct effect));
233 create_f[n] (effects[n]);
234 effects[n]->proc_init(effects[n]);
235 n++;
236 }
237 audio_lock = 0;
238 }
239
240 void
pump_stop(void)241 pump_stop(void)
242 {
243 int i;
244
245 audio_lock = 1;
246 for (i = 0; i < n; i++) {
247 effects[i]->proc_done(effects[i]);
248 }
249 n = 0;
250 }
251
252 void
passthru(struct effect * p,struct data_block * db)253 passthru(struct effect *p, struct data_block *db)
254 {
255 }
256
257 /* for UNIX; O_BINARY exists only on Win32. We must open() files with this
258 * flag because otherwise it gets corrupted by the CR/LF translation */
259 #ifndef O_BINARY
260 # define O_BINARY 0
261 #endif
262
263 void
save_pump(char * fname)264 save_pump(char *fname)
265 {
266 int i;
267 int fd = 0;
268
269 fprintf(stderr, "\nWriting preset (%s)...", fname);
270 if ((fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
271 S_IREAD | S_IWRITE)) < 0) {
272 perror("Save failed");
273 return;
274 }
275
276 /*
277 * writing signature
278 */
279 write(fd, version, 13);
280 for (i = 0; i < n; i++) {
281 if (effects[i]->proc_save != NULL) {
282 write(fd, &effects[i]->id, sizeof(effects[i]->id));
283 write(fd, &effects[i]->toggle, sizeof(effects[i]->toggle));
284 effects[i]->proc_save(effects[i], fd);
285 }
286 }
287 close(fd);
288 fprintf(stderr, "ok\n");
289 }
290
291 void
load_pump(char * fname)292 load_pump(char *fname)
293 {
294 int fd = 0;
295 unsigned short effect_tag = MAX_EFFECTS+1;
296 char rc_version[32]="";
297
298 if (!(fd = open(fname, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE))) {
299 perror("Load failed");
300 return;
301 }
302
303 /*
304 * reading signature and compare with our version
305 */
306 read(fd, rc_version, 13);
307 if (strncmp(version, rc_version, 13) != 0) {
308 fprintf(stderr, "\nThis is not my rc file.");
309 close(fd);
310 return;
311 }
312
313 gtk_clist_clear(GTK_CLIST(processor));
314 audio_lock = 1;
315 pump_stop();
316
317 n = 0;
318 while (read(fd, &effect_tag, sizeof(unsigned short)) > 0) {
319 if(effect_tag < 0 || effect_tag > EFFECT_AMOUNT) {
320 fprintf(stderr,"\nInvalid effect %i, load finished",effect_tag);
321 break;
322 }
323
324 fprintf(stderr, "\nloading %s", effect_list[effect_tag].str);
325
326 effects[n] = (struct effect *) calloc(1, sizeof(struct effect));
327 effect_list[effect_tag].create_f(effects[n]);
328 read(fd, &effects[n]->toggle, sizeof(unsigned short));
329 effects[n]->proc_load(effects[n], fd);
330 effects[n]->proc_init(effects[n]);
331 gtk_clist_append(GTK_CLIST(processor),
332 &effect_list[effect_tag].str);
333 n++;
334 }
335 close(fd);
336 fprintf(stderr, "\n");
337 audio_lock = 0;
338 }
339