// multiple threads generating musical notes // // POSIX version // #include #include #include #include #include // // compile flags: -pthread #define Pthread_create(a,b,c,d) assert(pthread_create(a,b,c,d) == 0) #define N 2 // number of threads int notes0[] = { 44, 6, 42, 6, 40, 12, -1 }; int notes1[] = { 47, 2, 52, 4, 52, 2, 51, 2, 49, 2, 51, 2, 52, 4, 47, 2, 47, 4, -1 }; typedef struct { int wait; // 0 = play() should wait, 1 = main() should wait, -1 = done int *notes; // key, duration pairs, end with -1 double value; // output value } Data; Data D[N] = { { 1, notes0, 0 }, { 1, notes1, 0 } }; double pi, ratio; void play( int key, int duration, Data *d) { double r, w = (2*pi*440*pow(ratio,key-49))/8000.0; int n = (duration/10.0)*8000.0; for( int i = 0; i < n; ++i) { r = sin(w*i) + 0.5*sin(2*w*i) + 0.25*sin(3*w*i); while( d->wait == 0) sched_yield(); d->value = r; d->wait = 0; } } void *f( void *v) { Data *d = v; for( int i = 0; d->notes[i] >= 0; i += 2) play( d->notes[i], d->notes[i+1], d); while( d->wait == 0) sched_yield(); d->wait = -1; // done return 0; } int main( void) { int done; double sum; pthread_t t[N]; pi = 4*atan(1); ratio = pow(2,1.0/12.0); for( int i = 0; i < N; ++i) Pthread_create( t+i, 0, f, D+i); while( 1) { done = 1; sum = 0; for( int i = 0; i < N; ++i) { while( D[i].wait == 1) sched_yield(); if( D[i].wait == 0) { done = 0; sum += D[i].value; D[i].wait = 1; } } if( done) break; printf( "%g\n", sum); } return 0; }