diff options
| -rw-r--r-- | backends/midi/adlib.cpp | 21 | ||||
| -rw-r--r-- | backends/midi/alsa.cpp | 82 | ||||
| -rw-r--r-- | backends/midi/coreaudio.cpp | 15 | ||||
| -rw-r--r-- | backends/midi/null.cpp | 6 | ||||
| -rw-r--r-- | backends/midi/quicktime.cpp | 30 | ||||
| -rw-r--r-- | backends/midi/windows.cpp | 196 | ||||
| -rw-r--r-- | scumm/imuse.cpp | 4 | ||||
| -rw-r--r-- | simon/midi.cpp | 4 | ||||
| -rw-r--r-- | simon/midi.h | 3 | ||||
| -rw-r--r-- | sound/mididrv.cpp | 212 | ||||
| -rw-r--r-- | sound/mididrv.h | 41 | ||||
| -rw-r--r-- | sound/midistreamer.cpp | 20 | ||||
| -rw-r--r-- | sound/midistreamer.h | 20 | 
13 files changed, 123 insertions, 531 deletions
| diff --git a/backends/midi/adlib.cpp b/backends/midi/adlib.cpp index affa88afd8..dfa3d9aab1 100644 --- a/backends/midi/adlib.cpp +++ b/backends/midi/adlib.cpp @@ -488,11 +488,9 @@ class MidiDriver_ADLIB : public MidiDriver {  public:  	MidiDriver_ADLIB(); -	int open(int mode); +	int open();  	void close();  	void send(uint32 b); -	void pause(bool p) { } -	void set_stream_callback(void *param, StreamCallback *sc) { } // No streaming support. Use MidiStreamer wrapper  	uint32 property (int prop, uint32 param);  	void setPitchBendRange (byte channel, uint range);  @@ -511,7 +509,7 @@ public:  	MidiChannel *getPercussionChannel() { return NULL; } // Percussion currently not supported  private: -	int _mode; +	bool _isOpen;  	bool _game_SmallHeader;  	FM_OPL *_opl; @@ -720,15 +718,14 @@ MidiDriver_ADLIB::MidiDriver_ADLIB()  		_parts[i].init (this);  	}  	_game_SmallHeader = false; +	_isOpen = false;  } -int MidiDriver_ADLIB::open (int mode) +int MidiDriver_ADLIB::open ()  { -	if (_mode != 0) +	if (_isOpen)  		return MERR_ALREADY_OPEN; -	if (mode != MO_SIMPLE) -		return MERR_STREAMING_NOT_AVAILABLE; -	_mode = mode; +	_isOpen = true;  	int i;  	MidiChannelAdl *mc; @@ -750,6 +747,7 @@ int MidiDriver_ADLIB::open (int mode)  	_mixer = g_mixer;  	_mixer->setupPremix(this, premix_proc); +	  	return 0;  } @@ -763,13 +761,12 @@ void MidiDriver_ADLIB::close()  	// Detach the premix callback handler  	_mixer->setupPremix (0, 0); + +	_isOpen = false;  }  void MidiDriver_ADLIB::send (uint32 b)  { -	if (_mode != MO_SIMPLE) -		error("MidiDriver_ADLIB::send called but driver is not in simple mode"); -  	//byte param3 = (byte) ((b >> 24) & 0xFF);  	byte param2 = (byte) ((b >> 16) & 0xFF);  	byte param1 = (byte) ((b >>  8) & 0xFF); diff --git a/backends/midi/alsa.cpp b/backends/midi/alsa.cpp index 538b0cd74b..c150dc11a8 100644 --- a/backends/midi/alsa.cpp +++ b/backends/midi/alsa.cpp @@ -51,72 +51,33 @@  class MidiDriver_ALSA:public MidiDriver_MPU401 {  public:  	MidiDriver_ALSA(); -	int open(int mode); +	int open();  	void close();  	void send(uint32 b); -	void pause(bool p); -	void set_stream_callback(void *param, StreamCallback *sc); -	// void setPitchBendRange (byte channel, uint range);  private:  	void send_event(int do_flush); +	bool _isOpen;  	snd_seq_event_t ev; -	StreamCallback *_stream_proc; -	void *_stream_param; -	int _mode;  	snd_seq_t *seq_handle;  	int seq_client, seq_port;  	int my_client, my_port;  	static int parse_addr(char *arg, int *client, int *port);  }; -MidiDriver_ALSA::MidiDriver_ALSA():_mode(0), seq_handle(0), seq_client(0), seq_port(0), my_client(0), -my_port(0) +MidiDriver_ALSA::MidiDriver_ALSA() + : _isOpen(false), seq_handle(0), seq_client(0), seq_port(0), my_client(0), my_port(0)  {  } -int MidiDriver_ALSA::parse_addr(char *arg, int *client, int *port) -{ -	char *p; - -	if (isdigit(*arg)) { -		if ((p = strpbrk(arg, ADDR_DELIM)) == NULL) -			return -1; -		*client = atoi(arg); -		*port = atoi(p + 1); -	} else { -		if (*arg == 's' || *arg == 'S') { -			*client = SND_SEQ_ADDRESS_SUBSCRIBERS; -			*port = 0; -		} else -			return -1; -	} -	return 0; -} - -void MidiDriver_ALSA::send_event(int do_flush) -{ -	snd_seq_ev_set_direct(&ev); -	snd_seq_ev_set_source(&ev, my_port); -	snd_seq_ev_set_dest(&ev, seq_client, seq_port); - -	snd_seq_event_output(seq_handle, &ev); -	if (do_flush) -		snd_seq_flush_output(seq_handle); -} - -int MidiDriver_ALSA::open(int mode) +int MidiDriver_ALSA::open()  {  	char *var;  	unsigned int caps; -	if (_mode != 0) +	if (_isOpen)  		return MERR_ALREADY_OPEN; - -	if (mode != MO_SIMPLE) -		return MERR_STREAMING_NOT_AVAILABLE; - -	_mode = mode; +	_isOpen = true;  	if (!(var = getenv("SCUMMVM_PORT"))) {  		// default alsa port if none specified @@ -225,17 +186,34 @@ void MidiDriver_ALSA::send(uint32 b)  	}  } -void MidiDriver_ALSA::pause(bool p) +int MidiDriver_ALSA::parse_addr(char *arg, int *client, int *port)  { -	if (_mode == MO_STREAMING) { -		/* Err... and what? */ +	char *p; + +	if (isdigit(*arg)) { +		if ((p = strpbrk(arg, ADDR_DELIM)) == NULL) +			return -1; +		*client = atoi(arg); +		*port = atoi(p + 1); +	} else { +		if (*arg == 's' || *arg == 'S') { +			*client = SND_SEQ_ADDRESS_SUBSCRIBERS; +			*port = 0; +		} else +			return -1;  	} +	return 0;  } -void MidiDriver_ALSA::set_stream_callback(void *param, StreamCallback *sc) +void MidiDriver_ALSA::send_event(int do_flush)  { -	_stream_param = param; -	_stream_proc = sc; +	snd_seq_ev_set_direct(&ev); +	snd_seq_ev_set_source(&ev, my_port); +	snd_seq_ev_set_dest(&ev, seq_client, seq_port); + +	snd_seq_event_output(seq_handle, &ev); +	if (do_flush) +		snd_seq_flush_output(seq_handle);  }  MidiDriver *MidiDriver_ALSA_create() diff --git a/backends/midi/coreaudio.cpp b/backends/midi/coreaudio.cpp index 00cc81e4f5..879162290e 100644 --- a/backends/midi/coreaudio.cpp +++ b/backends/midi/coreaudio.cpp @@ -39,30 +39,21 @@  class MidiDriver_CORE : public MidiDriver_MPU401 {  public:  	MidiDriver_CORE() : au_MusicDevice(0), au_output(0) { } -	int open(int mode); +	int open();  	void close();  	void send(uint32 b); -	void pause(bool p) { } -	void set_stream_callback(void *param, StreamCallback *sc) { }  private:  	AudioUnit au_MusicDevice;  	AudioUnit au_output; - -	int _mode;  }; -int MidiDriver_CORE::open(int mode) +int MidiDriver_CORE::open()  {  	if (au_output != NULL)  		return MERR_ALREADY_OPEN; -	if (mode == MO_STREAMING) -		return MERR_STREAMING_NOT_AVAILABLE; - -	_mode = mode; -  	int err;  	AudioUnitConnection auconnect;  	ComponentDescription compdesc; @@ -106,8 +97,6 @@ void MidiDriver_CORE::close()  	// Cleanup  	CloseComponent(au_output);  	CloseComponent(au_MusicDevice); - -	_mode = 0;  }  void MidiDriver_CORE::send(uint32 b) diff --git a/backends/midi/null.cpp b/backends/midi/null.cpp index 80e30735c2..74612d18cf 100644 --- a/backends/midi/null.cpp +++ b/backends/midi/null.cpp @@ -25,14 +25,12 @@  /* NULL driver */  class MidiDriver_NULL : public MidiDriver_MPU401 {  public: -	int open(int mode); +	int open();  	void close() { }  	void send(uint32 b) { } -	void pause(bool p) { } -	void set_stream_callback(void *param, StreamCallback *sc) { }  }; -int MidiDriver_NULL::open(int mode) +int MidiDriver_NULL::open()  {  	warning("Music not enabled - MIDI support selected with no MIDI driver available. Try Adlib");  	return 0; diff --git a/backends/midi/quicktime.cpp b/backends/midi/quicktime.cpp index f08f3e2d79..e447208bf0 100644 --- a/backends/midi/quicktime.cpp +++ b/backends/midi/quicktime.cpp @@ -46,11 +46,11 @@   */  class MidiDriver_QT : public MidiDriver_MPU401 {  public: -	int open(int mode); +	MidiDriver_QT(); +	 +	int open();  	void close();  	void send(uint32 b); -	void pause(bool p) { } -	void set_stream_callback(void *param, StreamCallback *sc);  	void setPitchBendRange (byte channel, uint range);  private: @@ -58,33 +58,24 @@ private:  	NoteChannel qtNoteChannel[16];  	NoteRequest simpleNoteRequest; -	StreamCallback *_stream_proc; -	void *_stream_param; -	int _mode; -  	// Pitch bend tracking. Necessary since QTMA handles  	// pitch bending so differently from MPU401.  	uint16 _pitchbend [16];  	byte _pitchbend_range [16];  }; -void MidiDriver_QT::set_stream_callback(void *param, StreamCallback *sc) +MidiDriver_QT::MidiDriver_QT()  { -	_stream_param = param; -	_stream_proc = sc; +	qtNoteAllocator = NULL;  } -int MidiDriver_QT::open(int mode) +int MidiDriver_QT::open()  {  	ComponentResult qtErr = noErr;  	int i; -	qtNoteAllocator = NULL; - -	if (mode == MO_STREAMING) -		return MERR_STREAMING_NOT_AVAILABLE; - -	_mode = mode; +	if (qtNoteAllocator != NULL) +		return MERR_ALREADY_OPEN;  	for (i = 0; i < 15; i++)  		qtNoteChannel[i] = NULL; @@ -126,8 +117,6 @@ bail:  void MidiDriver_QT::close()  { -	_mode = 0; -  	for (int i = 0; i < 15; i++) {  		if (qtNoteChannel[i] != NULL)  			NADisposeNoteChannel(qtNoteAllocator, qtNoteChannel[i]); @@ -142,9 +131,6 @@ void MidiDriver_QT::close()  void MidiDriver_QT::send(uint32 b)  { -	if (_mode != MO_SIMPLE) -		error("MidiDriver_QT:send called but driver is not in simple mode"); -  	MusicMIDIPacket midPacket;  	unsigned char *midiCmd = midPacket.data;  	midPacket.length = 3; diff --git a/backends/midi/windows.cpp b/backends/midi/windows.cpp index e49c62bf27..10653eb928 100644 --- a/backends/midi/windows.cpp +++ b/backends/midi/windows.cpp @@ -32,189 +32,41 @@  class MidiDriver_WIN : public MidiDriver_MPU401 {  public: +	MidiDriver_WIN();  	int open(int mode);  	void close();  	void send(uint32 b); -	void pause(bool p); -	void set_stream_callback(void *param, StreamCallback *sc);  private: -	struct MyMidiHdr { -		MIDIHDR hdr; -	}; - -	enum { -		NUM_PREPARED_HEADERS = 2, -		MIDI_EVENT_SIZE = 64, -		BUFFER_SIZE = MIDI_EVENT_SIZE * 12, -	}; - -	StreamCallback *_stream_proc; -	void *_stream_param; -	int _mode; -  	HMIDIOUT _mo; -	HMIDISTRM _ms; - -	MyMidiHdr *_prepared_headers; -	uint16 _time_div; - -	void unprepare(); -	void prepare();  	void check_error(MMRESULT result); -	void fill_all();  	uint32 property(int prop, uint32 param); - -	static void CALLBACK midi_callback(HMIDIOUT hmo, UINT wMsg, -	                                   DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);  }; -void MidiDriver_WIN::set_stream_callback(void *param, StreamCallback *sc) -{ -	_stream_param = param; -	_stream_proc = sc; -} - -void CALLBACK MidiDriver_WIN::midi_callback(HMIDIOUT hmo, UINT wMsg, -                                            DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) +MidiDriver_WIN::MidiDriver_WIN()  { -	switch (wMsg) { -	case MM_MOM_DONE:{ -			MidiDriver_WIN *md = ((MidiDriver_WIN *) dwInstance); -			if (md->_mode) -				md->fill_all(); -			break; -		} -	} +	_isOpen = false;  } -int MidiDriver_WIN::open(int mode) +int MidiDriver_WIN::open()  { -	if (_mode != 0) +	if (_isOpen)  		return MERR_ALREADY_OPEN; -	_mode = mode; - -	if (mode == MO_SIMPLE) { -		MMRESULT res = midiOutOpen((HMIDIOUT *) & _mo, MIDI_MAPPER, 0, 0, 0); -		if (res != MMSYSERR_NOERROR) -			check_error(res); -	} else { -		// Streaming mode -		MIDIPROPTIMEDIV mptd; -		UINT _midi_device_id = 0; - -		check_error(midiStreamOpen(&_ms, &_midi_device_id, 1, -                                   (uint32)midi_callback, (uint32)this, CALLBACK_FUNCTION)); - -		prepare(); - -		mptd.cbStruct = sizeof(mptd); -		mptd.dwTimeDiv = _time_div; +	_isOpen = true; -		check_error(midiStreamProperty(_ms, (byte *)&mptd, MIDIPROP_SET | MIDIPROP_TIMEDIV)); - -		fill_all(); -	} +	MMRESULT res = midiOutOpen((HMIDIOUT *) &_mo, MIDI_MAPPER, 0, 0, 0); +	if (res != MMSYSERR_NOERROR) +		check_error(res);  	return 0;  } -void MidiDriver_WIN::fill_all() -{ -	if (_stream_proc == NULL) { -		error("MidiDriver_WIN::fill_all() called, but _stream_proc==NULL"); -	} - -	uint i; -	MyMidiHdr *mmh = _prepared_headers; -	MidiEvent my_evs[64]; - -	for (i = 0; i != NUM_PREPARED_HEADERS; i++, mmh++) { -		if (!(mmh->hdr.dwFlags & MHDR_INQUEUE)) { -			int num = _stream_proc(_stream_param, my_evs, 64); -			int i; - -			// End of stream? -			if (num == 0) -				break; - -			MIDIEVENT *ev = (MIDIEVENT *)mmh->hdr.lpData; -			MidiEvent *my_ev = my_evs; - -			for (i = 0; i != num; i++, my_ev++) { -				ev->dwStreamID = 0; -				ev->dwDeltaTime = my_ev->delta; - -				switch (my_ev->event >> 24) { -				case 0: -					ev->dwEvent = my_ev->event; -					break; -				case ME_TEMPO: -					// Change tempo event -					ev->dwEvent = (ME_TEMPO << 24) | (my_ev->event & 0xFFFFFF); -					break; -				default: -					error("Invalid event type passed"); -				} - -				// Increase stream pointer by 12 bytes. -				// (Need to be 12 bytes, and sizeof(MIDIEVENT) is 16) -				ev = (MIDIEVENT *)((byte *)ev + 12); -			} - -			mmh->hdr.dwBytesRecorded = num * 12; -			check_error(midiStreamOut(_ms, &mmh->hdr, sizeof(mmh->hdr))); -		} -	} -} - -void MidiDriver_WIN::prepare() -{ -	int i; -	MyMidiHdr *mmh; - -	_prepared_headers = (MyMidiHdr *) calloc(sizeof(MyMidiHdr), 2); - -	for (i = 0, mmh = _prepared_headers; i != NUM_PREPARED_HEADERS; i++, mmh++) { -		mmh->hdr.dwBufferLength = BUFFER_SIZE; -		mmh->hdr.lpData = (LPSTR) calloc(BUFFER_SIZE, 1); - -		check_error(midiOutPrepareHeader((HMIDIOUT) _ms, &mmh->hdr, sizeof(mmh->hdr))); -	} -} - -void MidiDriver_WIN::unprepare() -{ -	uint i; -	MyMidiHdr *mmh = _prepared_headers; - -	for (i = 0; i != NUM_PREPARED_HEADERS; i++, mmh++) { -		check_error(midiOutUnprepareHeader((HMIDIOUT) _ms, &mmh->hdr, sizeof(mmh->hdr))); -		free(mmh->hdr.lpData); -		mmh->hdr.lpData = NULL; -	} - -	free(_prepared_headers); -} -  void MidiDriver_WIN::close()  { -	int mode_was = _mode; -	_mode = 0; - -	switch (mode_was) { -	case MO_SIMPLE: -		check_error(midiOutClose(_mo)); -		break; -	case MO_STREAMING:; -		check_error(midiStreamStop(_ms)); -		check_error(midiOutReset((HMIDIOUT) _ms)); -		unprepare(); -		check_error(midiStreamClose(_ms)); -		break; -	} +	_isOpen = false; +	check_error(midiOutClose(_mo));  }  void MidiDriver_WIN::send(uint32 b) @@ -224,9 +76,6 @@ void MidiDriver_WIN::send(uint32 b)  		BYTE bData[4];  	} u; -	if (_mode != MO_SIMPLE) -		error("MidiDriver_WIN:send called but driver is not in simple mode"); -  	u.bData[3] = (byte)((b & 0xFF000000) >> 24);  	u.bData[2] = (byte)((b & 0x00FF0000) >> 16);  	u.bData[1] = (byte)((b & 0x0000FF00) >> 8); @@ -236,16 +85,6 @@ void MidiDriver_WIN::send(uint32 b)  	check_error(midiOutShortMsg(_mo, u.dwData));  } -void MidiDriver_WIN::pause(bool p) -{ -	if (_mode == MO_STREAMING) { -		if (p) -			check_error(midiStreamPause(_ms)); -		else -			check_error(midiStreamRestart(_ms)); -	} -} -  void MidiDriver_WIN::check_error(MMRESULT result)  {  	char buf[200]; @@ -255,19 +94,6 @@ void MidiDriver_WIN::check_error(MMRESULT result)  	}  } -uint32 MidiDriver_WIN::property(int prop, uint32 param) -{ -	switch (prop) { - -	// 16-bit time division per the standard MIDI specification -	case PROP_TIMEDIV: -		_time_div = (uint16)param; -		return 1; -	} - -	return 0; -} -  MidiDriver *MidiDriver_WIN_create()  {  	return new MidiDriver_WIN(); diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp index d46cfe336d..36d2b9cef8 100644 --- a/scumm/imuse.cpp +++ b/scumm/imuse.cpp @@ -3743,9 +3743,9 @@ void IMuseGM::init(IMuseInternal *eng, OSystem *syst)  	_system = syst;  	// Open MIDI driver -	int result = _md->open(MidiDriver::MO_SIMPLE); +	int result = _md->open();  	if (result) -		error("IMuseGM::error = %s", MidiDriver::get_error_name(result)); +		error("IMuseGM::error = %s", MidiDriver::getErrorName(result));  	// Connect to the driver's timer  	_se = eng; diff --git a/simon/midi.cpp b/simon/midi.cpp index 134c03d688..e80021d6a9 100644 --- a/simon/midi.cpp +++ b/simon/midi.cpp @@ -185,9 +185,9 @@ void MidiPlayer::initialize()  	_midiDriver->property(MidiDriver::PROP_TIMEDIV, _songs[0].ppqn); -	res = _midiDriver->open(MidiDriver::MO_STREAMING); +	res = _midiDriver->open();  	if (res != 0) -		error("MidiPlayer::initializer, got %s", MidiDriver::get_error_name(res)); +		error("MidiPlayer::initializer, got %s", MidiDriver::getErrorName(res));  	if (_paused)  		_midiDriver->pause (true); diff --git a/simon/midi.h b/simon/midi.h index 3653a37316..9b3cfc7a6a 100644 --- a/simon/midi.h +++ b/simon/midi.h @@ -23,6 +23,7 @@  #define SIMON_MIDI_H  class MidiDriver; +class MidiStreamer;  class File;  struct MidiEvent; @@ -67,7 +68,7 @@ private:  		byte *sysex_data;  	}; -	MidiDriver *_midiDriver; +	MidiStreamer *_midiDriver;  	uint _lastDelay;  	Song *_currentSong;  	Song _songs[8]; diff --git a/sound/mididrv.cpp b/sound/mididrv.cpp index d473ed128b..d8d0db83ac 100644 --- a/sound/mididrv.cpp +++ b/sound/mididrv.cpp @@ -42,7 +42,7 @@ uint32 MidiDriver::property(int prop, uint32 param)  /* retrieve a string representation of an error code */ -const char *MidiDriver::get_error_name(int error_code) +const char *MidiDriver::getErrorName(int error_code)  {  	static const char *const midi_errors[] = {  		"No error", @@ -69,14 +69,12 @@ const char *MidiDriver::get_error_name(int error_code)  #include "morphos_sound.h"  /* MorphOS MIDI driver */ -class MidiDriver_ETUDE:public MidiDriver_MPU401 { +class MidiDriver_ETUDE : public MidiDriver_MPU401 {  public: +	MidiDriver_ETUDE();  	int open(int mode);  	void close();  	void send(uint32 b); -	void pause(bool p); -	void set_stream_callback(void *param, StreamCallback *sc); -	// void setPitchBendRange (byte channel, uint range);  private:  	enum { @@ -85,88 +83,37 @@ private:  		BUFFER_SIZE = MIDI_EVENT_SIZE * 12,  	}; -	static void midi_callback(ULONG msg, struct IOMidiRequest *req, APTR user_data); -	void fill_all();  	uint32 property(int prop, uint32 param); -	StreamCallback *_stream_proc; -	void *_stream_param; -	IOMidiRequest *_stream_req[NUM_BUFFERS]; -	void *_stream_buf[NUM_BUFFERS]; -	bool _req_sent[NUM_BUFFERS]; -	int _mode; -	uint16 _time_div; +	bool _isOpen;  }; -void MidiDriver_ETUDE::set_stream_callback(void *param, StreamCallback *sc) +MidiDriver_ETUDE::MidiDriver_ETUDE()  { -	_stream_param = param; -	_stream_proc = sc; +	_isOpen = false;  } -int MidiDriver_ETUDE::open(int mode) +int MidiDriver_ETUDE::open()  { -	if (_mode != 0) +	if (_isOpen)  		return MERR_ALREADY_OPEN; -	_mode = mode; -	if (!init_morphos_music(0, _mode == MO_STREAMING ? ETUDEF_STREAMING : ETUDEF_DIRECT)) +	_isOpen = true; +	if (!init_morphos_music(0, ETUDEF_DIRECT))  		return MERR_DEVICE_NOT_AVAILABLE; -	if (_mode == MO_STREAMING && ScummMidiRequest) { -		_stream_req[0] = ScummMidiRequest; -		_stream_req[1] = (IOMidiRequest *) AllocVec(sizeof (IOMidiRequest), MEMF_PUBLIC); -		_stream_buf[0] = AllocVec(BUFFER_SIZE, MEMF_PUBLIC); -		_stream_buf[1] = AllocVec(BUFFER_SIZE, MEMF_PUBLIC); -		_req_sent[0] = _req_sent[1] = false; - -		if (_stream_req[1] == NULL || _stream_buf[0] == NULL || _stream_buf[1] == NULL) { -			close(); -			return MERR_DEVICE_NOT_AVAILABLE; -		} - -		if (ScummMidiRequest) -		{ -			memcpy(_stream_req[1], _stream_req[0], sizeof (IOMidiRequest)); -			struct TagItem MidiStreamTags[] = { { ESA_Callback, (ULONG) &midi_callback }, -															{ ESA_UserData, (ULONG) this }, -															{ ESA_TimeDiv, _time_div }, -															{ TAG_DONE, 0 } -														 }; -			SetMidiStreamAttrsA(ScummMidiRequest, MidiStreamTags); -			fill_all(); -		} -	} -  	return 0;  }  void MidiDriver_ETUDE::close()  { -	if (_mode == MO_STREAMING) { -		if (_req_sent[0]) { -			AbortIO((IORequest *) _stream_req[0]); -			WaitIO((IORequest *) _stream_req[0]); -			_req_sent[0] = false; -		} -		if (_req_sent[1]) { -			AbortIO((IORequest *) _stream_req[1]); -			WaitIO((IORequest *) _stream_req[1]); -			_req_sent[1] = false; -		} - -		if (_stream_req[1]) FreeVec(_stream_req[1]); -		if (_stream_buf[0]) FreeVec(_stream_buf[0]); -		if (_stream_buf[1]) FreeVec(_stream_buf[1]); -	} -  	exit_morphos_music(); -	_mode = 0; +	_isOpen = false;  }  void MidiDriver_ETUDE::send(uint32 b)  { -	if (_mode != MO_SIMPLE) -		error("MidiDriver_ETUDE::send called but driver is not in simple mode"); +	if (_isOpen) +		error("MidiDriver_ETUDE::send called but driver was no opened");  	if (ScummMidiRequest) {  		ULONG midi_data = READ_LE_UINT32(&b); @@ -174,103 +121,12 @@ void MidiDriver_ETUDE::send(uint32 b)  	}  } -void MidiDriver_ETUDE::midi_callback(ULONG msg, struct IOMidiRequest *req, APTR user_data) -{ -	switch (msg) { -		case ETUDE_STREAM_MSG_BLOCKEND: { -			MidiDriver_ETUDE *md = ((MidiDriver_ETUDE *) user_data); -			if (md && md->_mode) -				md->fill_all(); -			break; -		} -	} -} - -void MidiDriver_ETUDE::fill_all() -{ -	if (_stream_proc == NULL) { -		error("MidiDriver_ETUDE::fill_all() called, but _stream_proc == NULL"); -	} - -	uint buf; -	MidiEvent my_evs[64]; - -	for (buf = 0; buf < NUM_BUFFERS; buf++) { -		if (!_req_sent[buf] || CheckIO((IORequest *) _stream_req[buf])) { -			int num = _stream_proc(_stream_param, my_evs, 64); - -			if (_req_sent[buf]) { -				WaitIO((IORequest *) _stream_req[buf]); -				_req_sent[buf] = false; -			} - -			/* end of stream? */ -			if (num == 0) -				break; - -			MIDIEVENT *ev = (MIDIEVENT *) _stream_buf[buf]; -			MidiEvent *my_ev = my_evs; - -			for (int i = 0; i < num; i++, my_ev++) { -				ev->me_StreamID = 0; -				ev->me_DeltaTime = my_ev->delta; - -				switch (my_ev->event >> 24) { -				case 0: -					ev->me_Event = my_ev->event; -					break; -				case ME_TEMPO: -					/* change tempo event */ -					ev->me_Event = (MEVT_TEMPO << 24) | (my_ev->event & 0xFFFFFF); -					break; -				default: -					error("Invalid event type passed"); -				} - -				/* increase stream pointer by 12 bytes  -				 * (need to be 12 bytes, and sizeof(MIDIEVENT) is 16)  -				 */ -				ev = (MIDIEVENT *)((byte *)ev + 12); -			} - -			ConvertWindowsMidiStream(_stream_buf[buf], num * 12); - -			_stream_req[buf]->emr_Std.io_Command = CMD_WRITE; -			_stream_req[buf]->emr_Std.io_Data = _stream_buf[buf]; -			_stream_req[buf]->emr_Std.io_Length = num * 12; -		   SendIO((IORequest *) _stream_req[buf]); -			_req_sent[buf] = true; -		} -	} -} - -void MidiDriver_ETUDE::pause(bool p) -{ -	if (_mode == MO_STREAMING && ScummMidiRequest) { -		if (p) -			PauseMidiStream(ScummMidiRequest); -		else -			RestartMidiStream(ScummMidiRequest); -	} -} - -uint32 MidiDriver_ETUDE::property(int prop, uint32 param) -{ -	switch (prop) { -		/* 16-bit time division according to standard midi specification */ -		case PROP_TIMEDIV: -			_time_div = (uint16)param; -			return 1; -	} - -	return 0; -} - -extern MidiDriver* EtudeMidiDriver; +extern MidiDriver* EtudeMidiDriver = NULL;  MidiDriver *MidiDriver_ETUDE_create()  { -	EtudeMidiDriver = new MidiDriver_ETUDE(); +	if (!EtudeMidiDriver) +		EtudeMidiDriver = new MidiDriver_ETUDE();  	return EtudeMidiDriver;  } @@ -280,39 +136,31 @@ MidiDriver *MidiDriver_ETUDE_create()  #define SEQ_MIDIPUTC    5  #define SPECIAL_CHANNEL 9 -class MidiDriver_SEQ:public MidiDriver_MPU401 { +class MidiDriver_SEQ : public MidiDriver_MPU401 {  public:  	MidiDriver_SEQ(); -	int open(int mode); +	int open();  	void close();  	void send(uint32 b); -	void pause(bool p); -	void set_stream_callback(void *param, StreamCallback *sc); -	// void setPitchBendRange (byte channel, uint range);  private: -	StreamCallback *_stream_proc; -	void *_stream_param; -	int _mode; +	bool _isOpen;  	int device, _device_num;  };  MidiDriver_SEQ::MidiDriver_SEQ()  { -	_mode = 0; +	_isOpen = false;  	device = 0;  	_device_num = 0;  } -int MidiDriver_SEQ::open(int mode) +int MidiDriver_SEQ::open()  { -	if (_mode != 0) +	if (_isOpen)  		return MERR_ALREADY_OPEN; +	_isOpen = true;  	device = 0; -	if (mode != MO_SIMPLE) -		return MERR_STREAMING_NOT_AVAILABLE; - -	_mode = mode;  	char *device_name = getenv("SCUMMVM_MIDI");  	if (device_name != NULL) { @@ -339,7 +187,7 @@ int MidiDriver_SEQ::open(int mode)  void MidiDriver_SEQ::close()  {  	::close(device); -	_mode = 0; +	_isOpen = false;  } @@ -385,18 +233,6 @@ void MidiDriver_SEQ::send(uint32 b)  	write(device, buf, position);  } -void MidiDriver_SEQ::pause(bool p) -{ -	if (_mode == MO_STREAMING) { -	} -} - -void MidiDriver_SEQ::set_stream_callback(void *param, StreamCallback *sc) -{ -	_stream_param = param; -	_stream_proc = sc; -} -  MidiDriver *MidiDriver_SEQ_create()  {  	return new MidiDriver_SEQ(); diff --git a/sound/mididrv.h b/sound/mididrv.h index 2783b6c651..e503aef0cd 100644 --- a/sound/mididrv.h +++ b/sound/mididrv.h @@ -36,19 +36,6 @@ struct MidiEvent {  class MidiDriver {  public: -	/* called whenever the midi driver is in streaming mode, -	 * and more midi commands need to be generated -	 * return 0 to tell the mididriver that the end of stream was reached -	 */ -	typedef int StreamCallback (void *param, MidiEvent * ev, int num); - - -	/* open modes, pass one of those to open() */ -	enum { -		MO_SIMPLE = 1, -		MO_STREAMING = 2, -	}; -  	/* Special events that can be inserted in a MidiEvent.  	 * event = (ME_xxx<<24) | <24-bit data associated with event>  	 */ @@ -58,11 +45,11 @@ public:  	};  	/* error codes returned by open. -	 * can be converted to a string with get_error_name() +	 * can be converted to a string with getErrorName()  	 */  	enum {  		MERR_CANNOT_CONNECT = 1, -		MERR_STREAMING_NOT_AVAILABLE = 2, +//		MERR_STREAMING_NOT_AVAILABLE = 2,  		MERR_DEVICE_NOT_AVAILABLE = 3,  		MERR_ALREADY_OPEN = 4,  	}; @@ -73,33 +60,21 @@ public:  	}; -	/* open the midi driver. -	 * returns 0 if successful. -	 * otherwise an error code. */ -	virtual int open(int mode) = 0; +	// open the midi driver. +	// returns 0 if successful, otherwise an error code. +	virtual int open() = 0; -	/* close the midi driver */ +	// close the midi driver  	virtual void close() = 0; -	/* output a packed midi command to the midi stream -	 * valid only if mode is MO_SIMPLE -	 */ +	// output a packed midi command to the midi stream  	virtual void send(uint32 b) = 0; -	/* set callback when more streams need to be generated. -	 * valid only when mode==MO_STREAMING -	 */ -	virtual void set_stream_callback(void *param, StreamCallback *sc) = 0; - -	/* Pause or resume streaming MIDI */ -	virtual void pause(bool pause) = 0; - -  	/* Get or set a property */  	virtual uint32 property(int prop, uint32 param);  	/* retrieve a string representation of an error code */ -	static const char *get_error_name(int error_code); +	static const char *getErrorName(int error_code);  	// HIGH-LEVEL SEMANTIC METHODS  	virtual void setPitchBendRange (byte channel, uint range) diff --git a/sound/midistreamer.cpp b/sound/midistreamer.cpp index ed32ef7934..c8863028ab 100644 --- a/sound/midistreamer.cpp +++ b/sound/midistreamer.cpp @@ -27,7 +27,7 @@ MidiStreamer::MidiStreamer (MidiDriver *target) :  _target (target),  _stream_proc (0),  _stream_param (0), -_mode (0), +_isOpen (false),  _paused (false),  _event_count (0),  _event_index (0), @@ -41,7 +41,7 @@ void MidiStreamer::set_stream_callback (void *param, StreamCallback *sc)  	_stream_param = param;  	_stream_proc = sc; -	if (_mode) { +	if (_isOpen) {  		_event_count = _stream_proc (_stream_param, _events, ARRAYSIZE (_events));  		_event_index = 0;  	} @@ -80,23 +80,19 @@ void MidiStreamer::on_timer()  	} // end while  } -int MidiStreamer::open (int mode) +int MidiStreamer::open()  { -	if (_mode != 0) +	if (_isOpen)  		close(); -	int res = _target->open (MidiDriver::MO_SIMPLE); +	int res = _target->open();  	if (res && res != MERR_ALREADY_OPEN)  		return res;  	_event_index = _event_count = _delay = 0; -	_mode = mode; +	_isOpen = true;  	_paused = false; -	if (mode == MO_SIMPLE) -		return 0; - -//	g_system->create_thread (timer_thread, this);  	_driver_tempo = _target->getBaseTempo() / 500;  	_target->setTimerCallback (this, &timer_thread); @@ -105,7 +101,7 @@ int MidiStreamer::open (int mode)  void MidiStreamer::close()  { -	if (!_mode) +	if (!_isOpen)  		return;  	_target->setTimerCallback (NULL, NULL); @@ -116,7 +112,7 @@ void MidiStreamer::close()  	for (i = 0; i < 16; ++i)  		_target->send ((0x7B << 8) | 0xB0 | i); -	_mode = 0; +	_isOpen = false;  	_paused = true;  } diff --git a/sound/midistreamer.h b/sound/midistreamer.h index d2b70bed86..f1158e8b45 100644 --- a/sound/midistreamer.h +++ b/sound/midistreamer.h @@ -27,11 +27,19 @@ class MidiStreamer;  #include "mididrv.h"  class MidiStreamer : public MidiDriver { +public: +	/* called whenever the midi driver is in streaming mode, +	 * and more midi commands need to be generated +	 * return 0 to tell the mididriver that the end of stream was reached +	 */ +	typedef int StreamCallback (void *param, MidiEvent * ev, int num); +  private: +  	MidiDriver *_target;  	StreamCallback *_stream_proc;  	void *_stream_param; -	int _mode; +	bool _isOpen;  	bool _paused;  	MidiEvent _events [64]; @@ -43,19 +51,21 @@ private:  	uint16 _ticks_per_beat;  	long _delay; -	uint32 property(int prop, uint32 param);  	static void timer_thread (void *param);  	void on_timer();  public: +  	MidiStreamer (MidiDriver *target); -	int open(int mode); +	int open();  	void close(); -	void send(uint32 b) { if (_mode) _target->send (b); } +	void send(uint32 b) { if (_isOpen) _target->send (b); } +	uint32 property(int prop, uint32 param); +	void setPitchBendRange (byte channel, uint range) { _target->setPitchBendRange (channel, range); } +  	void pause(bool p) { _paused = p; }  	void set_stream_callback(void *param, StreamCallback *sc); -	void setPitchBendRange (byte channel, uint range) { _target->setPitchBendRange (channel, range); }  	void setTimerCallback (void *timer_param, void (*timer_proc) (void *)) { }  	uint32 getBaseTempo (void) { return _target->getBaseTempo(); } | 
