/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * MIDI driver routines for MacOS. * * * See readme.txt for copyright information. */ #include "allegro.h" #include "allegro/internal/aintern.h" #include "allegro/platform/aintmac.h" #include #ifndef ALLEGRO_MPW #error something is wrong with the makefile #endif static NoteAllocator qtna=0; static struct{ NoteChannel channel; int note; int inst; int vol; int pan; }macmidivoices[17]; static int mac_midi_detect(int input); static int mac_midi_init(int input, int voices); static void mac_midi_exit(int input); static int mac_midi_mixer_volume(int volume); static void mac_midi_key_on(int inst, int note, int bend, int vol, int pan); static void mac_midi_key_off(int voice); static void mac_midi_set_volume(int voice, int vol); static void mac_midi_set_pitch(int voice, int note, int bend); static void mac_midi_set_pan(int voice, int pan); MIDI_DRIVER midi_quicktime = { MIDI_QUICKTIME, /* driver ID code */ empty_string, /* driver name */ empty_string, /* description string */ "QuickTime Midi", /* ASCII format name string */ 16, /* available voices */ 0, /* voice number offset */ 16, /* maximum voices we can support */ 0, /* default number of voices to use */ 10, 10, /* reserved voice range */ mac_midi_detect, /* AL_METHOD(int, detect, (int input)); */ mac_midi_init, /* AL_METHOD(int, init, (int input, int voices)); */ mac_midi_exit, /* AL_METHOD(void, exit, (int input)); */ mac_midi_mixer_volume, /* AL_METHOD(int, mixer_volume, (int volume)); */ NULL, /* AL_METHOD(void, raw_midi, (int data)); */ _dummy_load_patches, /* AL_METHOD(int, load_patches, (AL_CONST char *patches, AL_CONST char *drums)); */ _dummy_adjust_patches, /* AL_METHOD(void, adjust_patches, (AL_CONST char *patches, AL_CONST char *drums)); */ mac_midi_key_on, /* AL_METHOD(void, key_on, (int inst, int note, int bend, int vol, int pan)); */ mac_midi_key_off, /* AL_METHOD(void, key_off, (int voice)); */ mac_midi_set_volume, /* AL_METHOD(void, set_volume, (int voice, int vol)); */ mac_midi_set_pitch, /* AL_METHOD(void, set_pitch, (int voice, int note, int bend)); */ mac_midi_set_pan, /* AL_METHOD(void, set_pan, (int voice, int pan)); */ _dummy_noop2, /* AL_METHOD(void, set_vibrato, (int voice, int amount)); */ }; /* mac_midi_detect: * MacOS MIDI detection. */ static int mac_midi_detect(int input) { if (input) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); return FALSE; } return TRUE; } /* mac_midi_init: * Initializes the MacOS MIDI driver. */ static int mac_midi_init(int input, int voices) { NoteRequest nr; ComponentResult thisError; int i; qtna = OpenDefaultComponent(kNoteAllocatorComponentType, 0); printf("na=%d",qtna); if(!qtna){ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("open NoteAllocator failed")); printf("open NoteAllocator failed\n"); return -1; } for(i=1;i<17;i++){ nr.info.flags = 0; nr.info.reserved = 0; nr.info.polyphony = 2; nr.info.typicalPolyphony = 0x00010000; macmidivoices[i].inst = (i==10)?16385:1; macmidivoices[i].vol = -1; macmidivoices[i].pan = -1; macmidivoices[i].note = 0; thisError = NAStuffToneDescription(qtna, macmidivoices[i].inst, &nr.tone); thisError = NANewNoteChannel(qtna, &nr, &macmidivoices[i].channel); if(thisError || !macmidivoices[i].channel){ mac_midi_exit(input); ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("failed on channel initialization")); printf("failed on init %s channel",i); return -1; } } return 0; } /* mac_midi_exit: * Shuts down MIDI subsystem. */ static void mac_midi_exit(int input) { int i; if (qtna){ for(i=1; (i<17) && macmidivoices[i].channel;i++){ mac_midi_key_off(i); NADisposeNoteChannel(qtna, macmidivoices[i].channel); macmidivoices[i].channel = 0; } CloseComponent(qtna); qtna=0; } } /* mac_midi_mixer_volume: * Sets MIDI mixer output volume. */ static int mac_midi_mixer_volume(int volume) { return 0; } /* mac_midi_key_on: * Triggers a specified voice. */ static void mac_midi_key_on(int inst, int note, int bend, int vol, int pan) { int voice; NoteChannel ch; ComponentResult thisError; printf("keyon(%d,%d,%d,%d,%d)\n",inst, note, bend, vol,pan); if (inst < 128) { voice = _midi_allocate_voice(1, 16); } else { inst = inst+16385-128; voice = _midi_allocate_voice(10,10); } ch = macmidivoices[voice].channel; if(!ch) return; mac_midi_key_off(voice); if(macmidivoices[voice].inst!=inst){ thisError = NASetInstrumentNumber/*InterruptSafe*/(qtna,ch,inst); macmidivoices[voice].inst=inst; }; if(macmidivoices[voice].vol!=vol){ thisError = NASetNoteChannelVolume(qtna,ch,vol<<8); macmidivoices[voice].vol=vol; }; if(macmidivoices[voice].pan!=pan){ thisError = NASetNoteChannelBalance(qtna,ch,pan-128); macmidivoices[voice].pan=pan; }; thisError = NAPlayNote(qtna,ch,note,80); macmidivoices[voice].note=note; } /* mac_midi_key_off: * Turns off specified voice. */ static void mac_midi_key_off(int voice) { if(macmidivoices[voice].channel) NAPlayNote(qtna,macmidivoices[voice].channel,macmidivoices[voice].note,0); } /* mac_midi_set_volume: * Sets volume for a specified voice. */ static void mac_midi_set_volume(int voice, int vol) { } /* mac_midi_set_pitch: * Sets pitch of specified voice. */ static void mac_midi_set_pitch(int voice, int note, int bend) { } /* mac_midi_set_pan: * Sets pan value on specified voice. */ static void mac_midi_set_pan(int voice, int pan) { }