1 /*
2 * AutoZen
3 * Steven James <pyro@linuxlabs.com>
4 * Linux Labs http://www.linuxlabs.com
5 * http://www.linuxlabs.com/software/AutoZen.html
6 *
7 * This is Free software, licensed under the GNU Public License V2.
8 *
9 * Version: 2.1
10 */
11
12 #include <stdio.h>
13 #include <math.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <fcntl.h>
17 #include <time.h>
18 #include <sys/ioctl.h>
19 #include <sys/stat.h>
20 #include <pthread.h>
21 #include <gtk/gtk.h>
22
23
24 /* Messy, but should manage to include the OSS
25 Headers for Linux and the various *BSDs
26 + Solaris. Thanks to Trevor Johnson for this */
27
28 /* "The nice thing about standards..." */
29 #if defined (__FreeBSD__)
30 #include <sys/soundcard.h>
31 #else
32 #if defined (__NetBSD__) || defined (__OpenBSD__)
33 #include <soundcard.h> /* OSS emulation */
34 #undef ioctl
35 #else
36 /* BSDI, Linux, Solaris */
37 #include <sys/soundcard.h>
38 #endif /* __NetBSD__ or __OpenBSD__ */
39 #endif /* __FreeBSD__ */
40
41 //#define DEBUG
42 /////////////////////////////////////////////////////////////////////////
43 //
44 // Global Widgets
45 //
46 /////////////////////////////////////////////////////////////////////////
47 GtkObject *adj_beat;
48 GtkWidget *scale_beat;
49
50 GtkObject *adj_base;
51 GtkWidget *scale_base;
52
53 GtkWidget *ClockTime;
54 GtkWidget *BeatFreq;
55
56 GtkWidget *BaseFreq;
57 GtkWidget *VolLabel;
58
59 GtkObject *adj_vol;
60
61 GtkWidget *PhaseLabel;
62 GtkObject *adj_colorboxphase;
63 GtkWidget *scale_colorboxphase;
64
65 GtkWidget *PlayPixWid;
66 GdkPixmap *PlayPix;
67 GdkBitmap *PlayBit;
68
69 GdkPixmap *PausePix;
70 GdkBitmap *PauseBit;
71
72 GdkPixmap *PausedPix;
73 GdkBitmap *PausedBit;
74
75 #define COLORBOX_X 640
76 #define COLORBOX_Y 480
77
78 GtkWidget *ColorBox;
79 GtkStyle *ColorBox_default_style, *ColorBox_new_style;
80 GdkColor ColorBox_new_color = {0, 0x8000, 0x0, 0x8000};
81 gint ColorBoxTOhandle;
82
83 #ifdef COLORBOX_DEFAULT_ON
84 int ColorBoxX = COLORBOX_X;
85 int ColorBoxY = COLORBOX_Y;
86
87 #else
88 int ColorBoxX = 0;
89 int ColorBoxY = 0;
90 #endif
91
92 gint volTOhandle;
93
94 char bQuit=0;
95
96 ////////////////////////////////////////////////////////////////////////
97 //
98 // Pixmaps for controls
99 //
100 ////////////////////////////////////////////////////////////////////////
101
102 #include "record.xpm"
103 #include "stop.xpm"
104 #include "play.xpm"
105 #include "lila.xpm"
106 #include "pause.xpm"
107 #include "paused.xpm"
108
109
110 //////////////////////////////////
111 //
112 // Waveform generation
113 //
114 /////////////////////////////////
115
116 #define SAMPLE_RATE 11025
117
118 #define MAX_HARMONICS 10
119 #define DEFAULT_HARMONICS 3
120
121 #define BEAT_MAX 40
122
123 int nHarmonics = DEFAULT_HARMONICS;
124
125 int *WaveTable;
126
127 double curval;
128
129 double harmonic_curtimeL[MAX_HARMONICS];
130 double harmonic_curtimeR[MAX_HARMONICS];
131
132 double curtime;
133 double curtime2;
134
135 volatile double increment=300;
136 volatile double detune=10.0;
137 volatile double volume = 0.0;
138 volatile double phase = 0.0;
139
140 // Volume fade controls.
141 char Starting=1;
142 double VolumeTarget=50.0;
143 double VolumeDelta=0.5;
144 char Stopping=0;
145
146 /* sequencer variables */
147 volatile char playing=0;
148 char paused=0;
149 char *playname = NULL;
150 FILE *fSequence=NULL;
151 char szInstruction[1024];
152 volatile int EndSeconds=0; /* number of seconds when the current instruction expires */
153 double target;
154 double dBeatIncrement;
155 int LastSeconds;
156
157 int count=0;
158 volatile int seconds=0;
159 char tmptime[7] = "00:00";
160
161 // functions
162 gint volTimeOut(gpointer data);
163
164
165
PrintHandler(const char * line)166 void PrintHandler(const char *line)
167 {
168
169 }
170
171
Quit(GtkWidget * widget,gpointer data)172 void Quit (GtkWidget *widget, gpointer data)
173 {
174
175 if(Stopping) {
176 bQuit=1;
177 exit(0);
178 }
179
180 Stopping=1;
181 volTOhandle = gtk_timeout_add(10,volTimeOut,NULL);
182 // bQuit=1;
183 }
184
InitSequencer(const char * fname)185 int InitSequencer(const char *fname)
186 {
187 fSequence = fopen(fname,"r");
188 if(fSequence) {
189 seconds=0; /* so that the nonexistant current instruction is expired */
190 gtk_widget_set_sensitive(GTK_WIDGET(scale_beat),FALSE);
191 gtk_pixmap_set( GTK_PIXMAP(PlayPixWid), PausePix, PauseBit);
192 playing=1;
193 return(1);
194 }
195
196 return(0);
197 }
198
file_ok_sel(GtkWidget * w,GtkFileSelection * fs)199 void file_ok_sel (GtkWidget *w, GtkFileSelection *fs)
200 {
201 InitSequencer(gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs)));
202
203
204 #ifdef DEBUG
205 g_print ("Now playing %s\n",gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs)));
206 #endif
207
208 gtk_object_destroy(GTK_OBJECT(fs));
209
210 }
211
SetPause(void)212 void SetPause(void)
213 {
214
215 if(paused)
216 gtk_pixmap_set( GTK_PIXMAP(PlayPixWid), PausedPix, PausedBit);
217 else
218 gtk_pixmap_set( GTK_PIXMAP(PlayPixWid), PausePix, PauseBit);
219 }
220
Play(GtkWidget * widget,gpointer data)221 void Play (GtkWidget *widget, gpointer data)
222 {
223 GtkWidget *filew;
224
225 if(playing) {
226 paused = 1- paused;
227 SetPause();
228 return;
229 }
230
231 /* Create a new file selection widget */
232 filew = gtk_file_selection_new ("File selection");
233
234 gtk_file_selection_hide_fileop_buttons( GTK_FILE_SELECTION(filew));
235
236 /* Connect the ok_button to file_ok_sel function */
237 gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button),
238 "clicked", (GtkSignalFunc) file_ok_sel, filew );
239
240 /* Connect the cancel_button to destroy the widget */
241 gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION
242 (filew)->cancel_button),
243 "clicked", (GtkSignalFunc) gtk_widget_destroy,
244 GTK_OBJECT (filew));
245
246 /* Lets set the filename, as if this were a save dialog, and we are giving
247 a default filename */
248 gtk_file_selection_set_filename (GTK_FILE_SELECTION(filew),
249 "~/.autozen/*.seq");
250
251 gtk_file_selection_complete( GTK_FILE_SELECTION(filew), "~/.autozen/*.seq");
252 gtk_widget_show(filew);
253 }
254
255
CheckSequencer()256 void CheckSequencer()
257 {
258 char *token;
259 int tmp;
260
261 #ifdef DEBUG
262 printf("CheckSequencer: seconds = %u, EndSeconds = %u,increment = %d\n",seconds,EndSeconds,dBeatIncrement);
263 #endif
264
265 if(seconds >= EndSeconds) { /* if instruction is expired */
266 if(target) {
267 detune = target;
268 gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_beat), (BEAT_MAX - detune));
269 target=0;
270 dBeatIncrement = 0;
271 }
272
273 fgets(szInstruction,sizeof(szInstruction),fSequence); // fetch it in
274 #ifdef DEBUG
275 printf("CheckSequencer: %s\n",szInstruction);
276 #endif
277 token = strtok(szInstruction," ,\n");
278
279 if(!strcmp(token,"SET")) {
280 /* we are to set the frequency */
281 token = strtok(NULL," ,\n");
282 /* token is the frequency */
283 detune = atof(token);
284 #ifdef DEBUG
285 printf("CheckSequencer: SET %d\n",detune);
286 #endif
287 gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_beat), (BEAT_MAX - detune));
288 target = seconds = EndSeconds = 0;
289 return;
290 }
291
292 if(!strcmp(token,"VOLUME")) {
293 token = strtok(NULL," ,\n");
294 /* token is the volume */
295 VolumeTarget = atof(token);
296 #ifdef DEBUG
297 printf("CheckSequencer: VOLUME %d\n",VolumeTarget);
298 #endif
299 if(Starting)
300 gtk_timeout_remove( volTOhandle);
301 gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_vol), (100 - VolumeTarget));
302 return;
303 }
304
305 if(!strcmp(token,"FADE")) {
306 token = strtok(NULL," ,\n");
307 /* token is the volume */
308 VolumeTarget = atof(token);
309 token = strtok(NULL," ,\n");
310 /* token is the duration of the fade */
311 Starting = atoi(token);
312 #ifdef DEBUG
313 printf("CheckSequencer: FADE %f %u\n",VolumeTarget,Starting);
314 #endif
315 VolumeDelta = ((VolumeTarget - volume) / Starting) /50;
316 volTOhandle = gtk_timeout_add(10,volTimeOut,NULL);
317 return;
318 }
319
320 if(!strcmp(token,"BASE")) {
321 /* we are to set the frequency */
322 token = strtok(NULL," ,\n");
323 /* token is the frequency */
324 increment = atof(token);
325 #ifdef DEBUG
326 printf("CheckSequencer: SET %d\n",detune);
327 #endif
328 gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_base), (1000 - increment));
329 return;
330 }
331
332 if(!strcmp(token,"HARMONICS")) {
333 /* we are to set the number of harmonics */
334 token = strtok(NULL," ,\n");
335 tmp = atoi(token);
336 if(tmp < MAX_HARMONICS)
337 nHarmonics = tmp;
338
339 #ifdef DEBUG
340 printf("CheckSequencer: HARMONICS %u\n",nHarmonics);
341 #endif
342 return;
343 }
344
345 if(!strcmp(token,"SLIDE")) {
346 token = strtok(NULL," ,\n");
347 target = atof(token);
348 token = strtok(NULL," ,\n");
349 EndSeconds = atof(token);
350 dBeatIncrement = target - detune;
351 dBeatIncrement/= EndSeconds;
352 seconds = LastSeconds = 0;
353 return;
354 }
355
356 if(!strcmp(token,"HOLD")) {
357 token = strtok(NULL," ,\n");
358 target = detune;
359 EndSeconds = atof(token);
360 dBeatIncrement = 0;
361 seconds = LastSeconds = 0;
362 return;
363 }
364
365 if(!strcmp(token,"PAUSE")) {
366 paused = 1;
367 SetPause();
368 return;
369 }
370
371 if(!strcmp(token,"EXIT")) {
372 Quit(NULL,NULL);
373 StopSequencer();
374 return;
375 }
376
377 if(!strcmp(token,"END")) {
378 StopSequencer();
379 return;
380 }
381 } /* end if seconds >= EndSeconds */
382
383 if(paused) {
384 EndSeconds++; // delay the end!
385 return;
386 } /* end if paused */
387
388 detune += dBeatIncrement;
389 gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_beat), (BEAT_MAX - detune));
390 return;
391 } /* end CheckSequencer */
392
393
StopSequencer(void)394 int StopSequencer(void)
395 {
396
397 if(!playing)
398 return(0);
399
400 playing=0;
401 seconds = LastSeconds = 0;
402
403 target = dBeatIncrement = playing = paused = LastSeconds = seconds = EndSeconds = 0;
404
405 gtk_widget_set_sensitive(GTK_WIDGET(scale_beat),TRUE);
406 gtk_pixmap_set( GTK_PIXMAP(PlayPixWid), PlayPix, PlayBit);
407
408 fclose(fSequence);
409 fSequence = NULL;
410 return(1);
411 }
412
413
414
415
416
InitWaveTable(unsigned int SampleRate)417 int InitWaveTable(unsigned int SampleRate)
418 {
419 unsigned int i;
420 double increment = (2*M_PI) / SampleRate;
421 double Current=0;
422
423 WaveTable = (int *) calloc(SampleRate*2,sizeof(int));
424
425 for(i=0;i<SampleRate;i++,Current += increment) {
426 WaveTable[i]= (int) floor( sin(Current) * 127);
427 }
428
429 return(1);
430 } // end InitWaveTable
431
SoundBytesWritten(int audio_fd)432 int SoundBytesWritten(int audio_fd)
433 {
434 count_info info;
435
436 ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &info);
437
438 return(info.bytes);
439 }
440
SetStereo(int dsp,char Stereo)441 int SetStereo(int dsp,char Stereo)
442 {
443 int stereo = Stereo; /* 0=mono, 1=stereo */
444
445 if (ioctl(dsp, SNDCTL_DSP_STEREO, &stereo)==-1) { /* Fatal error */
446 perror("SNDCTL_DSP_STEREO");
447 return(0);
448 }
449
450 if (stereo != 1) {
451 printf("\aNo sterio support\n");
452 printf("Stereo support is REQUIRED for this to work!\n");
453 return(0);
454 // The device doesn't support stereo mode.
455 }
456
457 return(1);
458 }
459
460
SetSampleRate(int audio_fd,unsigned int rate)461 unsigned int SetSampleRate(int audio_fd, unsigned int rate)
462 {
463 unsigned int SampleRate = rate;
464
465 if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &SampleRate)==-1) { /* Fatal error */
466 perror("SNDCTL_DSP_SPEED");
467 return(FALSE);
468 }
469
470 return(SampleRate); // this is the actual sample rate which SHOULD be near the input value!
471 } // end SetSampleRate
472
473
value_change_no_invert(GtkWidget * widget,gpointer data)474 void value_change_no_invert(GtkWidget *widget, gpointer data)
475 {
476 *((double *)data) = GTK_ADJUSTMENT(widget) ->value;
477
478 #ifdef DEBUG
479 g_print ("Value Change: %f\n",*((double *)data));
480 #endif
481 }
482
value_change(GtkWidget * widget,gpointer data)483 void value_change(GtkWidget *widget, gpointer data)
484 {
485 *((double *)data) = GTK_ADJUSTMENT(widget) ->upper;
486 *((double *)data) -= GTK_ADJUSTMENT(widget) ->value;
487 if(!playing)
488 seconds=0;
489
490 #ifdef DEBUG
491 g_print ("Value Change: %f\n",*((double *)data));
492 #endif
493 }
494
label_change_value(GtkWidget * widget,gpointer label)495 void label_change_value(GtkWidget *widget, gpointer label)
496 {
497 double data;
498 char tmp[10];
499 char **tmp2;
500
501 data = GTK_ADJUSTMENT(widget)->upper;
502 data -= GTK_ADJUSTMENT(widget)->value;
503 sprintf(tmp,"%02.1f",data);
504
505 gtk_label_set(GTK_LABEL(label),tmp);
506
507 #ifdef DEBUG
508 g_print ("Lable Value Change: %s\n",tmp);
509 #endif
510 }
511
512
513
514
delete_event(GtkWidget * widget,GdkEvent * event,gpointer data)515 gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
516 {
517 g_print ("delete event occured\n");
518 /* if you return FALSE in the "delete_event" signal handler,
519 * GTK will emit the "destroy" signal. Returning TRUE means
520 * you don't want the window to be destroyed.
521 * This is useful for popping up 'are you sure you want to quit ?'
522 * type dialogs. */
523
524 /* Change TRUE to FALSE and the main window will be destroyed with
525 * a "delete_event". */
526
527 return (TRUE);
528 }
529
ColorBoxDestroy(GtkWidget * widget,gpointer data)530 void ColorBoxDestroy(GtkWidget *widget, gpointer data)
531 {
532
533 gtk_timeout_remove( ColorBoxTOhandle );
534 }
535
536 /* another callback */
destroy(GtkWidget * widget,gpointer data)537 void destroy (GtkWidget *widget, gpointer data)
538 {
539 gtk_main_quit ();
540 }
541
IncrementCurtimes(double timeval[],int harmonics,double increment,double detune)542 void IncrementCurtimes(double timeval[], int harmonics, double increment, double detune)
543 {
544 int i;
545
546 for(i=0;i<harmonics; i++) {
547 timeval[i] += increment * pow(2,i) + detune;
548 timeval[i] = fmod(timeval[i],SAMPLE_RATE);
549 }
550 }
551
ComputeSummation(double timeval[],int harmonics,double Volume)552 int ComputeSummation(double timeval[], int harmonics, double Volume)
553 {
554 int i;
555 int sigma=0;
556
557 for(i=0; i<harmonics; i++) {
558 sigma += (int) (WaveTable[ (int) floor(timeval[i])] /(1<<i));
559 }
560
561 sigma /=2;
562
563 sigma +=128;
564
565 return( floor( (Volume*sigma)/100));
566 }
567
SetColorBox(double phase)568 void SetColorBox(double phase)
569 {
570
571 ColorBox_new_color.red = floor(0xffff * phase);
572 ColorBox_new_color.green = floor(0xffff * (1-phase));
573 ColorBox_new_color.blue = 0x0;
574
575 ColorBox_default_style = gtk_widget_get_style( GTK_WIDGET(ColorBox));
576
577 ColorBox_new_style = gtk_style_copy(ColorBox_default_style);
578 ColorBox_new_style->bg[GTK_STATE_INSENSITIVE] = ColorBox_new_color;
579 ColorBox_new_style->fg[GTK_STATE_INSENSITIVE] = ColorBox_new_color;
580
581 gtk_widget_set_style(GTK_WIDGET(ColorBox), ColorBox_new_style);
582
583 gtk_widget_queue_draw(GTK_WIDGET(ColorBox));
584
585 // fprintf(stderr, "SetColorBox %f\n", phase);
586 }
587
588
PhaseDifference(double CurtimeL[],double CurtimeR[])589 double PhaseDifference(double CurtimeL[], double CurtimeR[])
590 {
591 double a = CurtimeL[0];
592 double b = CurtimeR[0];
593 double res1, res2;
594
595
596 a = fmod(a + SAMPLE_RATE + phase * SAMPLE_RATE, SAMPLE_RATE);
597 if(a<b) {
598 res1 = b-a;
599 res2 = (a+SAMPLE_RATE)-b;
600 } else {
601 res1 = a-b;
602 res2 = (b+SAMPLE_RATE)-a;
603 }
604
605 if(res1<res2)
606 return(res1 / SAMPLE_RATE);
607
608 return(res2 / SAMPLE_RATE);
609 }
610
ColorBoxTimeOut(gpointer data)611 gint ColorBoxTimeOut(gpointer data) {
612
613 // SetColorBox( fmod( 2 * PhaseDifference(harmonic_curtimeL, harmonic_curtimeR) +phase +1.0, 1.0));
614 SetColorBox( 2 * PhaseDifference(harmonic_curtimeL, harmonic_curtimeR) );
615 return(TRUE);
616 }
617
618
SoundThread(void * v)619 void *SoundThread(void *v)
620 {
621 int dsp;
622 int iCur;
623 int iCur2;
624 int iCharIn;
625 unsigned int SampleRate;
626 int arg;
627 char quit=0;
628 int i,j;
629
630
631 dsp = open("/dev/dsp",O_WRONLY);
632
633 if(dsp <0)
634 fprintf(stderr,"Failed to open the sound card.\n");
635
636 // EXPERIMENTAL, shrink the buffer to improve response time!
637 arg = 0x00800004;
638 ioctl(dsp,SNDCTL_DSP_SETFRAGMENT,&arg); // 128 16byte chunks. about 1/8 sec
639
640 if(!SetStereo(dsp,1))
641 // return((void *) -1);
642 printf("no stereo, might as well quit\n");
643
644 SampleRate = SetSampleRate(dsp,SAMPLE_RATE);
645
646 if(!SampleRate) {
647 fprintf(stderr,"ERROR:\aCannot set a sample rate\n");
648 SampleRate=8000;
649 // return(0);
650 }
651
652 InitWaveTable(SampleRate);
653
654 curtime=curtime2=0;
655
656 while(!bQuit) {
657 for(j=0;j<SAMPLE_RATE;j++) {
658
659 IncrementCurtimes(harmonic_curtimeL, nHarmonics, increment, 0.0);
660 IncrementCurtimes(harmonic_curtimeR, nHarmonics, increment, detune);
661
662 iCur = ComputeSummation(harmonic_curtimeL, nHarmonics, volume);
663 iCur2 = ComputeSummation(harmonic_curtimeR, nHarmonics, volume);
664
665 write(dsp,&iCur,1); // left
666 write(dsp,&iCur2,1); // right!
667
668 count++; // bump the sample counter!
669 }
670
671 seconds++;
672
673 } // end while
674
675 return(NULL);
676 }
677
volTimeOut(gpointer data)678 gint volTimeOut(gpointer data) {
679
680 if(Stopping) {
681 gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_vol), 100 - (volume-0.5));
682 if(volume <= 0.0) {
683 bQuit=1;
684 exit(0);
685 }
686 return(1);
687 }
688
689 if(Starting) {
690 gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_vol), 100 - (volume+VolumeDelta));
691 if(abs(volume-VolumeTarget) <= abs(VolumeDelta)) {
692 Starting=0;
693 gtk_adjustment_set_value(GTK_ADJUSTMENT(adj_vol), 100 - VolumeTarget);
694 }
695 } else {
696 gtk_timeout_remove( volTOhandle);
697 }
698
699 return(1);
700 }
701
TimeOut(gpointer data)702 gint TimeOut(gpointer data)
703 {
704 struct tm *tmst;
705 time_t tttime;
706 char tod[10];
707
708 tttime = time(NULL);
709 tmst = localtime(&tttime);
710
711 sprintf(tod,"%02u:%02u:%02u",tmst->tm_hour,tmst->tm_min,tmst->tm_sec);
712
713
714 sprintf(tmptime,"%02u:%02u",seconds/60,seconds%60);
715 gtk_label_set(GTK_LABEL(data),tmptime);
716 gtk_label_set(GTK_LABEL(ClockTime),tod);
717
718 if(playing)
719 CheckSequencer();
720
721 return(TRUE);
722 }
723
724
create_HelpWindow(const char * text)725 GtkWidget *create_HelpWindow (const char *text)
726 {
727 GtkWidget *HelpWindow;
728 GtkWidget *vbox1;
729 GtkWidget *help_text;
730 GtkWidget *HelpQuit;
731
732 #if GTK_MAJOR_VERSION >= 2
733 GtkTextIter help_text_iter;
734 GtkTextBuffer *help_text_buf;
735 #endif
736
737 HelpWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
738 gtk_object_set_data (GTK_OBJECT (HelpWindow), "HelpWindow", HelpWindow);
739 gtk_window_set_title (GTK_WINDOW (HelpWindow), "AutoZen Help");
740 gtk_window_position (GTK_WINDOW (HelpWindow), GTK_WIN_POS_CENTER);
741 gtk_window_set_policy (GTK_WINDOW (HelpWindow), TRUE, TRUE, FALSE);
742
743 vbox1 = gtk_vbox_new (FALSE, 0);
744 gtk_object_set_data (GTK_OBJECT (HelpWindow), "vbox1", vbox1);
745 gtk_widget_show (vbox1);
746 gtk_container_add (GTK_CONTAINER (HelpWindow), vbox1);
747
748 #if GTK_MAJOR_VERSION >= 2
749 help_text = gtk_text_view_new ();
750 help_text_buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (help_text));
751 gtk_text_buffer_get_iter_at_offset (help_text_buf, &help_text_iter, 0);
752 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW (help_text), GTK_WRAP_WORD);
753 #else
754 help_text = gtk_text_new (NULL, NULL);
755 gtk_text_set_word_wrap( GTK_TEXT( help_text ), TRUE);
756 gtk_text_set_line_wrap( GTK_TEXT( help_text ), TRUE);
757 #endif
758
759
760 gtk_object_set_data (GTK_OBJECT (HelpWindow), "help_text", help_text);
761 gtk_widget_show (help_text);
762 gtk_box_pack_start (GTK_BOX (vbox1), help_text, TRUE, TRUE, 6);
763 // gtk_widget_set_sensitive (help_text, FALSE);
764 GTK_WIDGET_UNSET_FLAGS (help_text, GTK_CAN_FOCUS);
765 gtk_widget_realize (help_text);
766 #if GTK_MAJOR_VERSION >= 2
767 gtk_text_buffer_insert (help_text_buf, &help_text_iter, text, strlen(text));
768 #else
769 gtk_text_insert (GTK_TEXT (help_text), NULL, NULL, NULL, text, strlen(text));
770 #endif
771
772 HelpQuit = gtk_button_new_with_label ("Close");
773 gtk_object_set_data (GTK_OBJECT (HelpWindow), "HelpQuit", HelpQuit);
774 gtk_widget_show (HelpQuit);
775 gtk_box_pack_start (GTK_BOX (vbox1), HelpQuit, FALSE, FALSE, 0);
776 gtk_signal_connect_object (GTK_OBJECT (HelpQuit), "clicked",
777 GTK_SIGNAL_FUNC (gtk_widget_destroy),
778 GTK_OBJECT (HelpWindow));
779
780 return HelpWindow;
781 }
782
Help(GtkWidget * widget,gpointer data)783 void Help(GtkWidget *widget, gpointer data)
784 {
785 GtkWidget *window;
786
787 window = create_HelpWindow("AutoZen is a program to alter your brain waves through sound in order to help you to reach an altered state of consciousness. Full details are available at http://www.linuxlabs.com/autozen.html");
788
789 gtk_widget_show(window);
790 }
791
792 GtkWidget *FreqTime;
793
CreateColorBox()794 GtkWidget *CreateColorBox()
795 {
796 ColorBox = gtk_button_new();
797
798 gtk_widget_set_usize( GTK_WIDGET(ColorBox), ColorBoxX,ColorBoxY);
799
800 ColorBox_default_style = gtk_widget_get_style( GTK_WIDGET(ColorBox));
801
802 ColorBox_new_style = gtk_style_copy(ColorBox_default_style);
803 ColorBox_new_style->bg[GTK_STATE_NORMAL] = ColorBox_new_color;
804 ColorBox_new_style->fg[GTK_STATE_NORMAL] = ColorBox_new_color;
805
806 gtk_widget_set_style(GTK_WIDGET(ColorBox), ColorBox_new_style);
807
808 gtk_widget_set_sensitive(GTK_WIDGET(ColorBox), FALSE);
809
810 gtk_widget_show (ColorBox);
811
812 return(ColorBox);
813 }
814
815
CreateAutoZen(GtkWidget * window)816 GtkWidget *CreateAutoZen(GtkWidget *window)
817 {
818 /* GtkWidget is the storage type for widgets */
819 GtkStyle *wstyle;
820
821 GtkWidget *main_table;
822
823 GtkWidget *button;
824 GtkWidget *beat_label;
825
826 GtkWidget *base_label;
827
828 GtkWidget *scale_vol;
829 GtkWidget *vol_label;
830
831 GtkWidget *lable;
832 GtkWidget *ClockLable;
833 GtkWidget *FreqLable;
834 GtkWidget *ColorBoxPhaseLable;
835
836 GtkWidget *RecordBox;
837
838 GtkWidget *RecordButton;
839 GtkWidget *RecPixWid;
840 GdkPixmap *RecordPix;
841 GdkBitmap *RecordBit;
842
843 GtkWidget *StopButton;
844 GtkWidget *StopPixWid;
845 GdkPixmap *StopPix;
846 GdkBitmap *StopBit;
847
848 GtkWidget *PlayButton;
849
850 GtkWidget *LiLaPixWid;
851 GdkPixmap *LiLaPix;
852 GdkBitmap *LiLaBit;
853
854 GtkWidget *LiLaEvent;
855
856
857 wstyle = gtk_widget_get_style(window);
858
859 // the control layout table
860 main_table = gtk_table_new(9,6,FALSE);
861
862 gtk_table_set_col_spacing(GTK_TABLE(main_table), 0, 5);
863 gtk_table_set_col_spacing(GTK_TABLE(main_table), 1, 5);
864 // gtk_table_set_col_spacing(GTK_TABLE(main_table), 6, 5);
865
866 // app name
867 // lable = gtk_label_new("Autozen 1.1");
868 // gtk_table_attach_defaults(GTK_TABLE(main_table),lable,1,6,0,1);
869 // gtk_widget_show (lable);
870
871 // LiLa Logo
872 LiLaPix = gdk_pixmap_create_from_xpm_d( window->window, &LiLaBit, &(wstyle->bg[GTK_STATE_NORMAL]), (gchar **) &lila );
873
874 LiLaPixWid = gtk_pixmap_new( LiLaPix, LiLaBit );
875
876 gtk_widget_show( LiLaPixWid );
877
878
879 LiLaEvent = gtk_button_new();
880 gtk_button_set_relief( GTK_BUTTON(LiLaEvent), GTK_RELIEF_NONE);
881
882
883 gtk_widget_show( LiLaEvent );
884
885 gtk_container_add( GTK_CONTAINER(LiLaEvent), LiLaPixWid );
886
887 gtk_table_attach_defaults(GTK_TABLE(main_table), LiLaEvent,0,7,0,1);
888
889 gtk_signal_connect (GTK_OBJECT (LiLaEvent), "clicked",
890 GTK_SIGNAL_FUNC (Help), NULL);
891
892 // clock
893 ClockTime = gtk_label_new("00:00:00");
894 gtk_table_attach_defaults(GTK_TABLE(main_table),ClockTime,2,4,1,2);
895 gtk_widget_show (ClockTime);
896
897 ClockLable = gtk_label_new("Time");
898 gtk_table_attach_defaults(GTK_TABLE(main_table),ClockLable,2,4,2,3);
899 gtk_widget_show (ClockLable);
900
901 // freqTime
902 FreqTime = gtk_label_new("00:00:00");
903 gtk_table_attach_defaults(GTK_TABLE(main_table),FreqTime,2,4,3,4);
904 gtk_widget_show (FreqTime);
905
906 FreqLable = gtk_label_new("Time in Freq");
907 gtk_table_attach_defaults(GTK_TABLE(main_table),FreqLable,2,4,4,5);
908 gtk_widget_show (FreqLable);
909
910
911 ////////////////
912 //
913 // The recorder controls
914 //
915 ///////////////
916
917 RecordBox = gtk_hbox_new(FALSE,0);
918 wstyle = gtk_widget_get_style( window );
919
920 RecordPix = gdk_pixmap_create_from_xpm_d( window->window, &RecordBit, &wstyle->bg[GTK_STATE_NORMAL], (gchar **) &xpm_record );
921
922 RecPixWid = gtk_pixmap_new( RecordPix, RecordBit );
923 gtk_widget_show( RecPixWid );
924 // record button
925 RecordButton = gtk_button_new();
926 gtk_container_add( GTK_CONTAINER(RecordButton), RecPixWid );
927
928 gtk_widget_show (RecordButton);
929 gtk_box_pack_start(GTK_BOX(RecordBox),RecordButton,FALSE,FALSE,0);
930
931 // stop button
932 StopPix = gdk_pixmap_create_from_xpm_d( window->window, &StopBit, &wstyle->bg[GTK_STATE_NORMAL], (gchar **) &xpm_stop );
933
934 StopPixWid = gtk_pixmap_new( StopPix, StopBit );
935 gtk_widget_show( StopPixWid );
936 StopButton = gtk_button_new();
937 gtk_signal_connect (GTK_OBJECT (StopButton), "clicked",
938 GTK_SIGNAL_FUNC (StopSequencer), NULL);
939
940 gtk_container_add( GTK_CONTAINER(StopButton), StopPixWid );
941 gtk_widget_show (StopButton);
942
943 gtk_box_pack_start(GTK_BOX(RecordBox),StopButton,FALSE,FALSE,0);
944
945 // play button
946 PlayPix = gdk_pixmap_create_from_xpm_d( window->window, &PlayBit, &wstyle->bg[GTK_STATE_NORMAL], (gchar **) &xpm_play );
947
948 PlayPixWid = gtk_pixmap_new( PlayPix, PlayBit );
949 gtk_widget_show( PlayPixWid );
950 PlayButton = gtk_button_new();
951
952 gtk_signal_connect (GTK_OBJECT (PlayButton), "clicked",
953 GTK_SIGNAL_FUNC (Play), NULL);
954
955 gtk_container_add( GTK_CONTAINER(PlayButton), PlayPixWid );
956 gtk_widget_show (PlayButton);
957 gtk_box_pack_start(GTK_BOX(RecordBox),PlayButton,FALSE,FALSE,0);
958
959 gtk_table_attach_defaults(GTK_TABLE(main_table),RecordBox,2,4,5,6);
960 gtk_widget_show (RecordBox);
961
962 // Pause widget for play button
963 PausePix = gdk_pixmap_create_from_xpm_d( window->window, &PauseBit, &wstyle->bg[GTK_STATE_NORMAL], (gchar **) &xpm_pause );
964 PausedPix = gdk_pixmap_create_from_xpm_d( window->window, &PausedBit, &wstyle->bg[GTK_STATE_NORMAL], (gchar **) &xpm_paused );
965
966
967 // the Quit button
968
969 button = gtk_button_new_with_label ("Quit");
970
971 gtk_signal_connect (GTK_OBJECT (button), "clicked",
972 GTK_SIGNAL_FUNC (Quit), NULL);
973
974 gtk_table_attach_defaults(GTK_TABLE(main_table),button,2,4,6,7);
975
976 gtk_widget_show (button);
977
978 // set up beat slider
979
980 BeatFreq = gtk_label_new("10.0");
981 gtk_table_attach_defaults(GTK_TABLE(main_table),BeatFreq,0,1,1,2);
982 gtk_widget_show (BeatFreq);
983
984 adj_beat = gtk_adjustment_new(BEAT_MAX - 10,0,BEAT_MAX,0.1,0.1,0);
985 gtk_signal_connect (GTK_OBJECT (adj_beat), "value_changed",
986 GTK_SIGNAL_FUNC (value_change), (gpointer) &detune);
987
988 gtk_signal_connect (GTK_OBJECT (adj_beat), "value_changed",
989 GTK_SIGNAL_FUNC (label_change_value), BeatFreq);
990
991 scale_beat = gtk_vscale_new(GTK_ADJUSTMENT(adj_beat));
992 gtk_scale_set_draw_value( GTK_SCALE(scale_beat), FALSE);
993 gtk_table_attach_defaults(GTK_TABLE(main_table),scale_beat,0,1,2,6);
994
995 gtk_widget_show (scale_beat);
996 beat_label = gtk_label_new("Beat");
997 gtk_table_attach_defaults(GTK_TABLE(main_table),beat_label,0,1,6,7);
998 gtk_widget_show (beat_label);
999
1000 // set up base slider
1001 BaseFreq = gtk_label_new("300.0");
1002 gtk_table_attach_defaults(GTK_TABLE(main_table),BaseFreq,1,2,1,2);
1003 gtk_widget_show (BaseFreq);
1004
1005 adj_base = gtk_adjustment_new(700,50,1000,1,10,0);
1006 gtk_signal_connect (GTK_OBJECT (adj_base), "value_changed",
1007 GTK_SIGNAL_FUNC (value_change), (gpointer) &increment);
1008
1009 gtk_signal_connect (GTK_OBJECT (adj_base), "value_changed",
1010 GTK_SIGNAL_FUNC (label_change_value), BaseFreq);
1011
1012 scale_base = gtk_vscale_new(GTK_ADJUSTMENT(adj_base));
1013 gtk_scale_set_draw_value( GTK_SCALE(scale_base), FALSE);
1014 gtk_table_attach_defaults(GTK_TABLE(main_table),scale_base,1,2,2,6);
1015 gtk_widget_show (scale_base);
1016 base_label = gtk_label_new("Base");
1017 gtk_table_attach_defaults(GTK_TABLE(main_table),base_label,1,2,6,7);
1018 gtk_widget_show (base_label);
1019
1020 // set up volume slider
1021 VolLabel = gtk_label_new("50.0");
1022 gtk_table_attach_defaults(GTK_TABLE(main_table),VolLabel,5,6,1,2);
1023 gtk_widget_show (VolLabel);
1024 adj_vol = gtk_adjustment_new(100-volume,0,100,1,10,0);
1025 gtk_signal_connect (GTK_OBJECT (adj_vol), "value_changed",
1026 GTK_SIGNAL_FUNC (value_change), (gpointer) &volume);
1027
1028 gtk_signal_connect (GTK_OBJECT (adj_vol), "value_changed",
1029 GTK_SIGNAL_FUNC (label_change_value), VolLabel);
1030
1031 scale_vol = gtk_vscale_new(GTK_ADJUSTMENT(adj_vol));
1032 gtk_scale_set_draw_value( GTK_SCALE(scale_vol), FALSE);
1033 gtk_table_attach_defaults(GTK_TABLE(main_table),scale_vol,5,6,2,6);
1034 // gtk_container_add (GTK_CONTAINER (window), scale_vol);
1035 gtk_widget_show (scale_vol);
1036 vol_label = gtk_label_new("Vol");
1037 gtk_table_attach_defaults(GTK_TABLE(main_table),vol_label,5,6,6,7);
1038 gtk_widget_show (vol_label);
1039
1040 /* and the window */
1041
1042 // the ColorBox button
1043 if(ColorBoxX && ColorBoxY) {
1044 // PhaseLabel = gtk_label_new("50.0");
1045 // gtk_table_attach_defaults(GTK_TABLE(main_table),VolLabel,5,6,1,2);
1046 // gtk_widget_show (VolLabel);
1047 adj_colorboxphase = gtk_adjustment_new(0,-0.5,0.5,0.01,0.1,0);
1048 gtk_signal_connect (GTK_OBJECT (adj_colorboxphase), "value_changed",
1049 GTK_SIGNAL_FUNC (value_change_no_invert), (gpointer) &phase);
1050
1051 // gtk_signal_connect (GTK_OBJECT (adj_vol), "value_changed",
1052 // GTK_SIGNAL_FUNC (label_change_value), VolLabel);
1053
1054 scale_colorboxphase = gtk_hscale_new(GTK_ADJUSTMENT(adj_colorboxphase));
1055 // gtk_scale_set_draw_value( GTK_SCALE(scale_colorboxphase), FALSE);
1056 gtk_scale_set_digits( GTK_SCALE(scale_colorboxphase), 2);
1057 gtk_table_attach_defaults(GTK_TABLE(main_table),scale_colorboxphase,0,6,7,8);
1058 gtk_widget_show (scale_colorboxphase);
1059 // vol_label = gtk_label_new("Vol");
1060 // gtk_table_attach_defaults(GTK_TABLE(main_table),vol_label,5,6,6,7);
1061 // gtk_widget_show (vol_label);
1062 }
1063
1064
1065 gtk_widget_show (main_table);
1066
1067 return(main_table);
1068 }
1069
SetupSequenceDirs(void)1070 void SetupSequenceDirs(void)
1071 {
1072 struct stat st;
1073 int res;
1074 char fname[500];
1075
1076 sprintf(fname,"%s/.autozen",getenv("HOME"));
1077
1078 res = stat(fname,&st);
1079 if(res<0) {
1080 mkdir(fname,0700);
1081 strcat(fname,"/public.seq");
1082 symlink(PUBLIC_SEQUENCES, fname);
1083 }
1084 }
1085
1086
main(int argc,char * argv[])1087 int main (int argc, char *argv[])
1088 {
1089 GtkWidget *window;
1090 GtkWidget *CBwindow;
1091 pthread_t stp;
1092 int next_arg=1;
1093
1094 gtk_init (&argc, &argv);
1095
1096
1097 while(next_arg < argc && argv[next_arg][0] == '-') {
1098
1099 if(!strcasecmp(argv[next_arg], "-colorbox")) {
1100 next_arg++;
1101 if(argc>next_arg && atoi(argv[next_arg])) {
1102 ColorBoxX = atoi(argv[next_arg++]);
1103 ColorBoxY = atoi(argv[next_arg++]);
1104 } else {
1105 ColorBoxX = COLORBOX_X;
1106 ColorBoxY = COLORBOX_Y;
1107 }
1108 } else if(!strcasecmp(argv[next_arg], "-harmonics")) {
1109 next_arg++;
1110 if(argc>next_arg && atoi(argv[next_arg]))
1111 nHarmonics = atoi(argv[next_arg++]);
1112 if(nHarmonics > MAX_HARMONICS)
1113 nHarmonics = MAX_HARMONICS;
1114 } else if(!strcasecmp(argv[next_arg], "-help") || !strcasecmp(argv[next_arg], "-h")) {
1115 printf("%s [-colorbox [<x> <y>]] [-harmonics <n>] [<sequence>]\n",argv[0]);
1116 exit(0);
1117 }
1118
1119
1120 }
1121
1122 SetupSequenceDirs();
1123
1124 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1125
1126 gtk_window_set_wmclass( GTK_WINDOW(window), "autozen", "AutoZen");
1127
1128 gtk_signal_connect (GTK_OBJECT (window), "delete_event",
1129 GTK_SIGNAL_FUNC (delete_event), NULL);
1130
1131 gtk_signal_connect (GTK_OBJECT (window), "destroy",
1132 GTK_SIGNAL_FUNC (destroy), NULL);
1133
1134 /* sets the border width of the window. */
1135 gtk_container_border_width (GTK_CONTAINER (window), 10);
1136
1137 gtk_window_set_title( GTK_WINDOW(window), "AutoZen 2.1");
1138
1139 gtk_window_set_position( GTK_WINDOW(window) ,GTK_WIN_POS_CENTER);
1140
1141 gtk_widget_show (window);
1142
1143 gtk_container_add (GTK_CONTAINER (window), CreateAutoZen(window));
1144
1145 if(ColorBoxX && ColorBoxY) {
1146 CBwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1147 gtk_signal_connect (GTK_OBJECT (CBwindow), "destroy",
1148 GTK_SIGNAL_FUNC (ColorBoxDestroy), NULL);
1149
1150 gtk_widget_show (CBwindow);
1151 gtk_container_add (GTK_CONTAINER (CBwindow), CreateColorBox());
1152 }
1153
1154 ///////////////////////////////////////////
1155 //
1156 // GUI setup done, now check args for a sequence to play
1157 //
1158 //////////////////////////////////////////
1159
1160 pthread_create(&stp,NULL,SoundThread,NULL);
1161 gtk_timeout_add(1000,TimeOut,FreqTime);
1162 volTOhandle = gtk_timeout_add(10,volTimeOut,FreqTime);
1163
1164 if(ColorBoxX && ColorBoxY)
1165 ColorBoxTOhandle = gtk_timeout_add(10,ColorBoxTimeOut,FreqTime);
1166
1167 if(argc >next_arg) {
1168 InitSequencer(argv[next_arg]);
1169 CheckSequencer();
1170 }
1171
1172 /////////////////// Main Loop ///////////////
1173 gtk_main ();
1174
1175 return 0;
1176 }
1177
1178