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