/** * This program continuously plays a scale, but the timing is based on the * System Clock UTC. * * This means that if this program is executed on two different machines which * have their System Clocks synchronised (eg. by NTP) then playback of the two * scales should be perfectly in sync. * * Author: adambuckley@gmx.net * Version: $Id: synctest.c,v 1.2 2002/05/23 12:13:55 adam Exp $ */ /** * This source code is copyright (c) 2002 Adam Buckley, . * * This source code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This source code is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * The GNU General Public License can be found at * http://www.gnu.org/licenses/gpl.html */ #include "utc.c" #include "beep.c" #include "midi.c" #include #include // Constant definitions // -------------------- #define USE_PC_SPEAKER 0 #define USE_MIDI 1 // Global variables // ---------------- // Which mode are we in? PC speaker or MIDI? int mode = USE_MIDI; /** * Finish */ void finish() { if(mode==USE_PC_SPEAKER) beepOff(); // ToDo: if(mode==USE_MIDI) {Some MIDI clean-up} exit(0); } /** * main */ int main(int argc, char **argv) { int i; unsigned char previousNote = 0; char* dev = "/dev/sequencer2"; char command; // How long do we pause between playing notes? long pause = 400000; // 0.4 second // Which notes do we play? int notes[] = {60, 62, 64, 65, 67, 69, 71, 72}; int numberOfNotes = sizeof(notes) / sizeof(notes[0]); // If we use MIDI, what settings do we use? int device = 0, channel = 0, velocity = 100; // The onset time in microseconds UTC of the next note // This code sets t to the beginning of the bar which is playing 'now' long long t = (long long) (getUtc() / (long long) (pause*numberOfNotes))*pause*numberOfNotes; // Trap exit conditions signal(SIGINT, finish); // Trap CTRL-C signal(SIGTERM, finish); // Trap 'kill pid' // Process command line while((command = getopt(argc, argv, "?mb")) != -1) { switch(command) { case 'm': mode = USE_MIDI; break; case 'b': mode = USE_PC_SPEAKER; break; case '?': printf("synctest -[m|b]\n\t-m use MIDI playback\n\t-b use the PC speaker (must have root privileges)\n"); exit(0); break; default: break; } } // Start MIDI if(mode==USE_MIDI) { startMidi(dev, device); // ToDo: Reset? } // Start the test while(1) { for(i=0; i getUtc()) { waitUntil(t); if(mode==USE_PC_SPEAKER) { beepNote(notes[i], 100000); } else if(mode==USE_MIDI) { sendVoiceMessage(device, MIDI_NOTEOFF, channel, previousNote, velocity, FALSE); sendVoiceMessage(device, MIDI_NOTEON, channel, notes[i], velocity, TRUE); previousNote = notes[i]; } } t = t + pause; } } // Superflous code? if(mode==USE_MIDI) stopMidi(); return 0; }