imported trunk from svn
[cryosleep-ng.git] / cryosleep.c
blob0e911e1d281fa6bc669ac38be5971fc3ecc9f446
2 #define _GNU_SOURCE
3 #define VERSION "0.3.1.0"
5 #include <string.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <math.h>
9 #include <assert.h>
10 #include <time.h>
11 #include <linux/soundcard.h>
12 #include <sys/ioctl.h>
13 #include <unistd.h>
14 #include <fcntl.h>
16 typedef enum { false = 0, true = 1 } bool;
18 typedef union
20 struct
22 signed short int left;
23 signed short int right;
24 } leftright;
25 } longtrick;
27 /* output device stuff */
29 int output_fd = -1;
30 bool output_stop = true;
32 #define wavrate ((double)44100)
33 #define pi ((double)3.141596)
34 #define barksize (24)
35 #define bufsize (8000)
36 longtrick buffer[bufsize];
37 static double barkbounds[barksize+1] =
39 0,100,200,300,400,510,630,770,920,1080,1270,1480,1720,2000,2380,2700,
40 3150,3700,4400,5300,6400,7700,9500,12000,15500
43 static double perfectspectrum[barksize] =
44 {7.48973,
45 8.60855,
46 7.30108,
47 6.08735,
48 5.05958,
49 4.22398,
50 3.55564,
51 2.84894,
52 1.99757,
53 1.37338,
54 0.814002,
55 0.479557,
56 -0.125073,
57 -0.522579,
58 -0.939505,
59 -1.68769,
60 -2.2336,
61 -3.15377,
62 -4.26618,
63 -5.23179,
64 -6.09273,
65 -7.06462,
66 -8.35773,
67 -10.1641};
69 static double perfect_amp(double freq)
71 int i;
72 for(i = 0 ; i < barksize ; i ++)
73 if (freq>=barkbounds[i] && freq < barkbounds[i+1])
75 double left = barkbounds[i];
76 double right = barkbounds[i+1];
77 double center = (left+right)/2.0;
78 double y1 = 0;
79 double y2 = 0;
80 if (freq<=center)
82 if (i>0) y1 = perfectspectrum[i-1];
83 y2 = perfectspectrum[i];
85 else
87 y1 = perfectspectrum[i];
88 if (i<barksize) y1 = perfectspectrum[i+1];
90 double answer = y1+(freq-left)*(y2-y1)/(center-left);
91 answer = exp10(answer/10.0);
92 printf("freq %g will be played at volume %g\n",freq,answer);
93 return answer;
95 return 0;
98 static double *lfo_frequencies[barksize];
99 static double *lfo_phases[barksize];
100 static double *lfo_amps[barksize];
101 static double *std_frequencies[barksize];
102 static double *std_phases[barksize];
103 static double std_amps[barksize];
104 static double scaling_factor = 2.0*pi/wavrate;
106 const char* n_comments = "";
107 const char* n_playrate = "44100";
108 const char* n_lfo_shaping = "";
109 const char* n_freq_shaping = "";
110 const char* n_brainwave_freq = "100";
111 const char* n_output_filename = "cryosleep-generation.raw";
112 const char* n_dsp_filename = "/dev/dsp";
113 static bool n_independent_stereo_channels = false;
114 static double n_freq_lo;
115 static double n_freq_hi;
116 static int n_traces = 1;
117 static bool n_use_dsp = false;
118 static bool n_stereo = false;
119 static bool n_perfect = false;
121 bool __atob(const char* v)
123 if (!v)
124 return false;
125 if (strcmp(v,"true")==0)
126 return true;
127 if (strcmp(v,"yes")==0)
128 return true;
130 return false;
133 void handle_value(const char* name, const char* value)
135 if ((!name)||(!strlen(name)))
136 return;
138 if (strcmp(name,"lfo-shaping")==0)
139 n_lfo_shaping = strdup(value);
140 else if (strcmp(name, "traces")==0)
141 n_traces = atoi(value);
142 else if (strcmp(name,"frequency-shaping")==0)
143 n_freq_shaping = strdup(value);
144 else if (strcmp(name,"frequency-low")==0)
145 n_freq_lo = atof(value);
146 else if (strcmp(name,"frequency-high")==0)
147 n_freq_hi = atof(value);
148 else if (strcmp(name,"dsp-filename")==0)
149 n_dsp_filename = strdup(value);
150 else if (strcmp(name,"output-filename")==0)
151 n_output_filename = strdup(value);
152 else if (strcmp(name,"comments")==0)
153 n_comments = strdup(value);
154 else if (strcmp(name,"brainwave-frequency")==0)
155 n_brainwave_freq = strdup(value);
156 else if (strcmp(name,"playrate")==0)
157 n_playrate = strdup(value);
158 else if (strcmp(name,"use-dsp")==0)
159 n_use_dsp = __atob(value);
160 else if (strcmp(name,"stereo")==0)
161 n_stereo = __atob(value);
162 else if (strcmp(name,"independent-stereo")==0)
163 n_independent_stereo_channels = __atob(value);
164 else
165 printf("%s=\"%s\"\n", name, value);
168 void read_line(char* buffer)
170 char* fieldname;
171 char* value;
173 // kick off comments
174 char* c;
175 for(c=buffer; *c; c++)
176 if ((*c)=='#')
177 *c=0;
179 // now skip leading spaces
180 while ((*buffer==' ')||(*buffer=='\n')||(*buffer=='\r')||(*buffer=='\t'))
181 *buffer++;
183 // find the ':'
184 char* colon = strchr(buffer,':');
185 if (!colon)
187 if (strlen(buffer))
189 fprintf(stderr,"Maybe broken line: \"%s\"\n", buffer);
191 return;
194 /* skip off follwing spaces in variable name */
195 char* backptr;
196 backptr = colon;
197 while ((backptr>buffer)&&((*backptr==' ')||(*backptr=='\t')||(*backptr=='\n')||(*backptr=='\r')))
198 backptr--;
199 *backptr = 0;
201 /* now get the field name */
202 fieldname = buffer;
204 /* jump to value and skip spaces there */
205 buffer = backptr+1;
206 while ((*buffer==' ')||(*buffer=='\n')||(*buffer=='\r')||(*buffer=='\t'))
207 *buffer++;
209 if (strlen(buffer))
211 backptr=buffer+strlen(buffer)-1;
212 while ((backptr>buffer)&&((*backptr==' ')||(*backptr=='\t')||(*backptr=='\n')||(*backptr=='\r')))
213 backptr--;
214 backptr++;
215 *backptr=0;
216 value = buffer;
218 else
219 value = "";
221 handle_value(fieldname,value);
224 void read_cf(const char* fn)
226 char buffer[8192];
228 FILE* fp = fopen(fn,"r");
229 while (!feof(fp))
231 if (fgets(buffer, sizeof(buffer)-1, fp))
232 read_line(buffer);
236 int dsp_open(const char* device)
238 int p;
239 output_fd=open(device,O_WRONLY);
240 if (output_fd==-1)
242 fprintf(stderr,"Could not open dsp device \"%s\"\n",device);
243 exit(50);
246 // set dsp parameters
247 p=AFMT_S16_LE;
248 if (ioctl(output_fd,SNDCTL_DSP_SETFMT,&p)==-1)
250 fprintf(stderr,"dsp: setting dsp to standard 16 bit failed\n");
251 exit(50);
253 p=2;
254 if (ioctl(output_fd,SNDCTL_DSP_CHANNELS,&p)==-1)
256 fprintf(stderr,"dsp: setting dsp to 2 channels failed\n");
257 exit(50);
259 p=11025;
260 if (ioctl(output_fd,SNDCTL_DSP_SPEED,&p)==-1)
262 printf("dsp: setting dsp speed (%d) failed\n",p++);
263 if (ioctl(output_fd,SNDCTL_DSP_SPEED,&p)==-1)
265 printf("dsp: setting dsp speed (%d) failed\n",p);
266 p+=2;
267 if (ioctl(output_fd,SNDCTL_DSP_SPEED,&p)==-1)
269 printf("dsp: setting dsp speed (%d) failed\n",p);
270 exit(50);
274 return 0;
277 #define choose(lo,hi) ((double)(random()%10000)*(hi-lo)/10000.0+lo)
278 #define mean(lo,hi) ((lo+hi)/2)
280 void file_open(const char * name)
282 output_fd = open(name,O_CREAT|O_WRONLY|O_TRUNC,S_IRUSR|S_IWUSR);
283 assert(output_fd!=-1);
286 void open_output()
288 assert(output_fd == -1);
289 if (n_use_dsp)
290 dsp_open(n_dsp_filename);
291 else
292 file_open(n_output_filename);
295 void run_cryo_loop()
297 double pos = 0.0, maximum = 0.0, phase, freq;
298 int i, j, k = 0, track;
300 output_stop=false;
302 srandom(time(NULL));
303 open_output();
305 char yeah[1024];
306 double brainwave = 0;
307 if (n_stereo)
308 brainwave = atof(n_brainwave_freq);
310 double playrate = playrate = atof(n_playrate);
313 double lfo_shaping = atof(n_lfo_shaping);
314 double freq_shaping = atof(n_freq_shaping);
316 for ( track = 0 ; track < barksize ; track ++)
318 lfo_frequencies[track] = (double*)malloc(sizeof(double)*n_traces);
319 lfo_phases[track] = (double*)malloc(sizeof(double)*n_traces);
320 lfo_amps[track] = (double*)malloc(sizeof(double)*n_traces);
321 std_frequencies[track] = (double*)malloc(sizeof(double)*n_traces);
322 std_phases[track] = (double*)malloc(sizeof(double)*n_traces);
325 for ( track = 0 ; track < barksize ; track ++ )
326 for ( i = 0 ; i < n_traces ; i ++ )
328 double down = barkbounds [ track ] ;
329 double up = barkbounds [ track+1 ] ;
330 freq = choose ( n_freq_lo,n_freq_hi ) ;
331 lfo_phases [ track ] [ i ] = choose ( 0,2.0*pi ) ;
332 lfo_frequencies [ track ] [ i ] = freq*scaling_factor;
333 lfo_amps [ track ] [ i ] = sqrt ( pow ( freq , - lfo_shaping ) ) ;
334 std_phases [ track ] [ i ] = choose ( 0,2.0*pi ) ;
335 double trace_freq =
336 std_frequencies [ track ] [ i ] = choose ( down,up ) *scaling_factor;
337 if (n_perfect)
338 std_amps [ track ] = perfect_amp(mean ( down,up ));
339 else
340 std_amps [ track ] = sqrt ( pow ( mean ( down,up ) , - freq_shaping ) ) ;
344 while ( ! output_stop )
346 for ( j = 0 ; j < bufsize ; j++ )
348 register double left;
349 register double right;
350 register double * phases;
351 register double * freqs;
352 register double * amps;
353 if (n_independent_stereo_channels)
355 register double volume_left;
356 register double volume_right;
357 // panner version
358 for ( track = left = right = 0 ; track < barksize ; track ++ )
360 phases = lfo_phases [ track ] ;
361 freqs = lfo_frequencies [ track ] ;
362 amps = lfo_amps [ track ] ;
363 volume_left = 0;
364 volume_right = 0;
365 for( i = 0; i < n_traces /2 ; i ++ )
367 volume_left += sin ( phases [ i ] + freqs [ i ] * pos ) * amps [ i ] ;
369 for( i = n_traces/2; i < n_traces ; i ++ )
371 volume_right += sin ( phases [ i ] + freqs [ i ] * pos ) * amps [ i ] ;
373 #ifdef firefix
374 volume_left = 1.0 - abs(volume_left);
375 volume_right = 1.0 - abs(volume_right);
376 #endif
377 phases = std_phases [ track ] ;
378 freqs = std_frequencies [ track ] ;
379 volume_left *= std_amps [ track ] ;
380 volume_right *= std_amps [ track ] ;
381 for(i = 0 ; i < n_traces ; i ++)
383 phase = phases [ i ] ;
384 freq = freqs [ i ] ;
385 left += volume_left * sin ( phase + pos * freq ) ;
386 freq += brainwave * scaling_factor;
387 right += volume_right * sin ( phase + pos * freq ) ;
391 else
393 // brainwave version
394 register double volume;
395 for ( track = left = right = 0 ; track < barksize ; track ++ )
397 phases = lfo_phases [ track ] ;
398 freqs = lfo_frequencies [ track ] ;
399 amps = lfo_amps [ track ] ;
400 for( i = volume = 0 ; i < n_traces ; i ++ )
402 volume += sin ( phases [ i ] + freqs [ i ] * pos ) * amps [ i ] ;
404 phases = std_phases [ track ] ;
405 freqs = std_frequencies [ track ] ;
406 volume *= std_amps [ track ] ;
407 for(i = 0 ; i < n_traces ; i ++)
409 phase = phases [ i ] ;
410 freq = freqs [ i ] ;
411 left += volume * sin ( phase + pos * freq ) ;
412 freq += brainwave * scaling_factor;
413 right += volume * sin ( phase + pos * freq ) ;
417 pos += 1.0 ;
418 if ( fabs ( left ) > maximum )
419 maximum = fabs ( left ) ;
420 if ( fabs ( right ) > maximum )
421 maximum = fabs ( right ) ;
422 left *= 32767.0 / maximum;
423 right *= 32767.0 / maximum;
424 buffer [ j ] . leftright . left = (signed short)left;
425 buffer [ j ] . leftright . right = (signed short)right;
427 double total = (++k)*bufsize;
428 total/=(double)playrate;
429 sprintf(yeah,"%g seconds processed (maximum = %g)" ,total, maximum);
430 printf("%s\n", yeah);
431 long written = write(output_fd,buffer,4*bufsize);
432 assert(written == 4*bufsize);
433 printf("Written\n");
435 close(output_fd);
436 output_fd = -1;
437 output_stop = false;
440 int main(int argc, char* argv[])
442 if (argc>1)
443 read_cf(argv[1]);
444 else
446 fprintf(stderr,"cryosleep <config>\n");
447 exit(2);
450 printf("Cryosleep v" VERSION " (c) Werner Van Belle, Enrico Weigelt <weigelt@metux.de> 2003, 2007, 2008\n");
451 run_cryo_loop();