#include #include enum { C = 40, D = 42, E = 44, F = 45, G = 47, A = 49, B = 51, C0 = C - 12, D0 = D - 12, E0 = E - 12, F0 = F - 12, G0 = G - 12, A0 = A - 12, B0 = B - 12, }; #define NPLAYER 3 mutex_t lk = MUTEX_INIT(); int n = -1; // current beat int done = NPLAYER; // players finished current beat (init = all done) int NOTES[3][8] = { {C, G0, A0, E0, F0, C0, F0, G0}, {E, B0, C0, G0, A0, E0, A0, B0}, {G, D, E, B0, C0, G0, C0, D0}, }; void T_player(int id) { int *notes, expect = 0; char cmd[128]; switch (id) { case 1: notes = NOTES[0]; break; case 2: notes = NOTES[1]; break; case 3: notes = NOTES[2]; break; } while (1) { int ready; do { mutex_lock(&lk); ready = (n == expect); mutex_unlock(&lk); } while (!ready); int note = notes[expect % 8]; sprintf(cmd, "ffplay -nodisp -autoexit" " -loglevel quiet" " piano_key_%d.wav", note); printf("player %d is playing note %d\n", id, expect); system(cmd); printf("player %d finished playing note %d\n", id, expect); mutex_lock(&lk); done++; mutex_unlock(&lk); expect++; } } void T_conductor() { char buf[32]; while (1) { printf("\n(Ready) > "); fflush(stdout); fgets(buf, sizeof(buf), stdin); int all_done; do { mutex_lock(&lk); all_done = (done == NPLAYER); mutex_unlock(&lk); } while (!all_done); mutex_lock(&lk); done = 0; n++; mutex_unlock(&lk); } } int main() { for (int i = 0; i < NPLAYER; i++) { spawn(T_player); } spawn(T_conductor); }