예제 #1
0
static int wait_event_time(void *p)
{
	MidiEvent *ev = (MidiEvent *)p;
	int rc, ch;

	for(;;){
		if(ev->time - (current_tick()*play_mode->rate+30)/60 < 0)
			break;
		trace_loop();
		YieldToAnyThread();
		rc = check_apply_control();
		if(RC_IS_SKIP_FILE(rc)){
			prescan = 0;
			for(ch = 0; ch < MAX_CHANNELS; ch++){
				if(note_channel[ch] != NULL){
					NADisposeNoteChannel(gNoteAllocator, note_channel[ch]);
					note_channel[ch] = NULL;
				}
				channel[ch].bank_lsb = 0;
				channel[ch].bank_msb = 0;
			}
			trace_flush();
			return rc;
		}
	}
	return RC_NONE;
}
예제 #2
0
static void play_event_prescan(void *p)
{
	MidiEvent *ev = (MidiEvent *)p;
	int ch;

	for(ch = 0; ch < MAX_CHANNELS; ch++){
		if(note_channel[ch] != NULL){
			NADisposeNoteChannel(gNoteAllocator, note_channel[ch]);
			note_channel[ch] = NULL;
		}
		instrument_number[ch] = -1;
		instrument_name[ch][0] = '\0';
		drum_part[ch] = false;
		channel[ch].bank_lsb = 0;
		channel[ch].bank_msb = 0;
	}
	drum_part[9] = true;
		for(;; ev++){
			ch = ev->channel;
		if(ev->type == ME_NOTEON && note_channel[ch] == NULL){
			//MidiEvent *ev;

			ev->channel = ch;
			ev->a = 0;
			set_instrument(ev);
		}
		else if(ev->type == ME_PROGRAM){
			set_instrument(ev);
		}
		else if(ev->type == ME_TONE_BANK_LSB && ev->a != channel[ch].bank_lsb){
			channel[ch].bank_lsb = ev->a;
		}
		else if(ev->type == ME_TONE_BANK_MSB && ev->a != channel[ch].bank_msb){
			channel[ch].bank_msb = ev->a;
			if(play_system_mode == XG_SYSTEM_MODE && (ev->a == 126 || ev->a == 127) && !drum_part[ch])
				drum_part[ch] = true;
		}
		else if(ev->type == ME_DRUMPART && !drum_part[ch]){
			//MidiEvent *ev;

			ev->channel = ch;
			ev->a = channel[ch].program;
			set_instrument(ev);
			drum_part[ch] = true;
			}
			else if(ev->type == ME_RESET){
				play_system_mode = ev->a;
			}
			else if(ev->type == ME_EOT){
				prescan = 1;
				for(ch = 0; ch < MAX_CHANNELS; ch++){
				channel[ch].bank_lsb = 0;
				channel[ch].bank_msb = 0;
			}
			init_variable();
			break;
		}
	}
}
예제 #3
0
void closeQuicktimeMIDIPort(void) {
	int i;

	if (!na) return;
	for (i = 0; i < 16; i++) {
		/* dispose of note channels */
		if (channel[i]) NADisposeNoteChannel(na, channel[i]);
		channel[i] = nil;
	}
	CloseComponent(na);  /* close note allocator */
}
예제 #4
0
static void set_instrument(MidiEvent *ev)
{
	long instrumentNumber;
	int ch = ev->channel;

	channel[ch].program = ev->a;
	if(drum_part[ch]){
		if(play_system_mode == GS_SYSTEM_MODE && channel[ch].bank_lsb == 2)				// SC-88 Map
			instrumentNumber = kFirstDrumkit + sc88_drum_kit[ev->a] + 1;
		else if(play_system_mode == GS_SYSTEM_MODE && channel[ch].bank_lsb == 3)		// SC-88Pro Map
			instrumentNumber = kFirstDrumkit + sc88pro_drum_kit[ev->a] + 1;
		else
			instrumentNumber = kFirstDrumkit + ev->a + 1;
	}
	else {
		if(play_system_mode == GS_SYSTEM_MODE)
			instrumentNumber = kFirstGSInstrument + (channel[ch].bank_msb<<7) + ev->a;
		else if(play_system_mode == XG_SYSTEM_MODE)
			instrumentNumber = xg_instrument_number(ch, ev->a);
		else
			instrumentNumber = kFirstGMInstrument + ev->a;
	}
	if(instrument_number[ch] != instrumentNumber){
		NoteRequest	nr;
		long index,  part;
		OSType synthType;
		Str31 name;
		SynthesizerConnections connections;
		MusicComponent mc;

		instrument_number[ch] = instrumentNumber;
		if(note_channel[ch] != NULL)
			NADisposeNoteChannel(gNoteAllocator, note_channel[ch]);
		nr.info.flags = 0;
		nr.info.reserved = 0;
		*(short *)(&nr.info.polyphony) = EndianS16_NtoB(8);			// 8 voices poliphonic
		*(Fixed *)(&nr.info.typicalPolyphony) = EndianU32_NtoB(0x00010000);
		NAStuffToneDescription(gNoteAllocator, instrumentNumber, &nr.tone);
		NANewNoteChannel(gNoteAllocator, &nr, &note_channel[ch]);
		NAGetNoteChannelInfo(gNoteAllocator, note_channel[ch], &index, &part);
		NAGetRegisteredMusicDevice(gNoteAllocator, index, &synthType, name, &connections, &mc);
		MusicGetPartName(mc, part, name);
		p2cstrcpy(instrument_name[ch], name);
	}
	ctl_prog_event(ch, ev->a);
}
예제 #5
0
static int acntl(int request, void *arg)
{
 	int rc, ch;

    switch(request)
    {
      case PM_REQ_MIDI:
		if(!prescan)
			play_event_prescan(arg);
		rc = wait_event_time(arg);
		if(RC_IS_SKIP_FILE(rc))
			return rc;
		qt_play_event(arg);
		return RC_NONE;
	case PM_REQ_INST_NAME:
		ch = (int)*(char **)arg;
		*(char **)arg = instrument_name[ch];
		return 0;
      case PM_REQ_GETSAMPLES:
	*(int32 *)arg = current_samples();
	return 0;
	case PM_REQ_PLAY_START:
		init_variable();
      case PM_REQ_DISCARD:
      case PM_REQ_FLUSH:
		for(ch = 0; ch < MAX_CHANNELS; ch++){
			if(note_channel[ch] != NULL){
				NADisposeNoteChannel(gNoteAllocator, note_channel[ch]);
				note_channel[ch] = NULL;
			}
			channel[ch].bank_lsb = 0;
			channel[ch].bank_msb = 0;
		}
		trace_flush();
	return 0;
    }
    return -1;
}