/* * * ao_example.c * * Written by Stan Seibert - July 2001 * * Legal Terms: * * This source file is released into the public domain. It is * distributed without any warranty; without even the implied * warranty * of merchantability or fitness for a particular * purpose. * * Function: * * This program opens the default driver and plays a 440 Hz tone for * one second. * * Compilation command line (for Linux systems): * * gcc -o ao_example ao_example.c -lao -ldl -lm -lpthread * */ #include #include #include #include #include #define BUF_SIZE 4096 /* struct to hpold info for second thread */ struct pass_ptr { ao_device *device2; ao_sample_format format2; }; /* function called by second thread */ void *play2(void *play_ptr) { char *buffer2; int buf_size2; int sample2; float freq2 = 120.0; int i2; struct pass_ptr *play = (struct pass_ptr*) play_ptr; /* -- Fill buffer -- */ buf_size2 = play->format2.bits/8 * play->format2.channels * play->format2.rate; buffer2 = calloc(buf_size2, sizeof(char)); for (i2 = 0; i2 < play->format2.rate; i2++) { sample2 = (int)(0.75 * 32768.0 * sin(2 * M_PI * freq2 * ((float) i2/play->format2.rate))); /* Put the same stuff in left and right channel */ buffer2[4*i2] = buffer2[4*i2+2] = sample2 & 0xff; buffer2[4*i2+1] = buffer2[4*i2+3] = (sample2 >> 8) & 0xff; } /* play from second thread */ ao_play(play->device2, buffer2, buf_size2); } int main(int argc, char **argv) { ao_device *device; ao_sample_format format; int default_driver; char *buffer; int buf_size; int sample; float freq = 360.0; int i; int default_driver2; pthread_t play2_thread; struct pass_ptr play_ptr; /* -- Initialize -- */ fprintf(stderr, "libao example program\n"); ao_initialize(); /* -- Setup for default driver -- */ default_driver = ao_default_driver_id(); memset(&format, 0, sizeof(format)); format.bits = 16; format.channels = 2; format.rate = 44100; format.byte_format = AO_FMT_LITTLE; /* -- Open first device -- */ device = ao_open_live(default_driver, &format, NULL /* no options */); if (device == NULL) { fprintf(stderr, "Error opening device.\n"); return 1; } memset(&play_ptr.format2, 0, sizeof(play_ptr.format2)); play_ptr.format2.bits = 16; play_ptr.format2.channels = 2; play_ptr.format2.rate = 44100; play_ptr.format2.byte_format = AO_FMT_LITTLE; /* -- Open second device -- */ play_ptr.device2 = ao_open_live(default_driver, &play_ptr.format2, NULL /* no options */); if (play_ptr.device2 == NULL) { fprintf(stderr, "Error opening device2.\n"); return 1; } /* create second thread to play, pass struct pointer with device and format info */ if(pthread_create(&play2_thread, NULL, play2, &play_ptr)) { fprintf(stderr, "Error creating thread\n"); return 1; } /* -- Fill buffer with stuff -- */ buf_size = format.bits/8 * format.channels * format.rate; buffer = calloc(buf_size, sizeof(char)); for (i = 0; i < format.rate; i++) { sample = (int)(0.75 * 32768.0 * sin(2 * M_PI * freq * ((float) i/format.rate))); /* Put the same stuff in left and right channel */ buffer[4*i] = buffer[4*i+2] = sample & 0xff; buffer[4*i+1] = buffer[4*i+3] = (sample >> 8) & 0xff; } /* play in main thread */ ao_play(device, buffer, buf_size); /* wait for the second thread to finish */ if(pthread_join(play2_thread, NULL)) { fprintf(stderr, "Error joining thread\n"); return 2; } /* -- Close and shutdown -- */ ao_close(device); ao_close(play_ptr.device2); ao_shutdown(); return (0); }