aboutsummaryrefslogtreecommitdiff
path: root/backends/midi
diff options
context:
space:
mode:
Diffstat (limited to 'backends/midi')
-rw-r--r--backends/midi/ypa1.cpp132
1 files changed, 132 insertions, 0 deletions
diff --git a/backends/midi/ypa1.cpp b/backends/midi/ypa1.cpp
new file mode 100644
index 0000000000..6766af341f
--- /dev/null
+++ b/backends/midi/ypa1.cpp
@@ -0,0 +1,132 @@
+#include "stdafx.h"
+#include "sound/mpu401.h"
+#include "common/engine.h" // for warning/error/debug
+
+#include "Pa1Lib.h"
+
+class MidiDriver_YamahaPa1:public MidiDriver_MPU401 {
+public:
+ MidiDriver_YamahaPa1();
+ int open();
+ void close();
+ void send(uint32 b);
+
+private:
+ UInt8 _midiHandle;
+ Boolean _isOpen;
+ };
+
+MidiDriver_YamahaPa1::MidiDriver_YamahaPa1() {
+ _isOpen = false;
+ _midiHandle = 0;
+}
+
+int MidiDriver_YamahaPa1::open()
+{
+ if (!(_isOpen = Pa1Lib_midiOpen(NULL, &_midiHandle)))
+ return MERR_DEVICE_NOT_AVAILABLE;
+
+ Pa1Lib_midiControlChange(_midiHandle,0,120,0); // all sound off
+ Pa1Lib_midiControlChange(_midiHandle,0,121,0); // reset all controller
+ Pa1Lib_midiControlChange(_midiHandle,0,123,0); // all not off
+
+ return 0;
+}
+
+void MidiDriver_YamahaPa1::close()
+{
+ if (_isOpen) {
+ Pa1Lib_midiControlChange(_midiHandle,0,120,0); // all sound off
+ Pa1Lib_midiControlChange(_midiHandle,0,121,0); // reset all controller
+ Pa1Lib_midiControlChange(_midiHandle,0,123,0); // all not off
+ Pa1Lib_midiClose(_midiHandle);
+ }
+}
+
+void MidiDriver_YamahaPa1::send(uint32 b)
+{
+ if (!_isOpen)
+ return;
+
+ UInt8 midiCmd[4];
+ UInt8 chanID,mdCmd;
+
+ midiCmd[3] = (b & 0xFF000000) >> 24;
+ midiCmd[2] = (b & 0x00FF0000) >> 16;
+ midiCmd[1] = (b & 0x0000FF00) >> 8;
+ midiCmd[0] = (b & 0x000000FF);
+
+ chanID = (midiCmd[0] & 0x0F) ;
+ mdCmd = midiCmd[0] & 0xF0;
+
+ switch (mdCmd) {
+ case 0x80: // note off
+ Pa1Lib_midiNoteOff(_midiHandle, chanID, midiCmd[1], 0);
+ break;
+
+ case 0x90: // note on
+ Pa1Lib_midiNoteOn(_midiHandle, chanID, midiCmd[1], midiCmd[2]);
+ break;
+
+ case 0xB0: // control change
+ Pa1Lib_midiControlChange(_midiHandle, chanID, midiCmd[1], midiCmd[2]);
+ break;
+
+ case 0xC0: // progam change
+ Pa1Lib_midiProgramChange(_midiHandle, chanID, midiCmd[1]);
+ break;
+
+ case 0xE0: // pitchBend
+ Pa1Lib_midiPitchBend(_midiHandle, chanID, (short)(midiCmd[1] | (midiCmd[2] << 8)));
+ break;
+ }
+}
+
+MidiDriver *MidiDriver_YamahaPa1_create()
+{
+ return new MidiDriver_YamahaPa1();
+}
+
+//////////////////////////////////////////
+// thread emu
+static struct {
+ bool active;
+ int old_time;
+ int sleep;
+
+} g_thread;
+
+static bool t_first_call = false;
+
+int MidiDriver_MPU401::midi_driver_thread(void *param) {
+ MidiDriver_MPU401 *mid = (MidiDriver_MPU401 *)param;
+ int cur_time;
+
+ if (!t_first_call)
+ {
+ g_thread.active = false;
+ g_thread.old_time = g_system->get_msecs();
+ g_thread.sleep = 10;
+ t_first_call = true;
+ }
+
+ cur_time = g_system->get_msecs();
+ if (cur_time - g_thread.old_time >= g_thread.sleep)
+ g_thread.active = true;
+
+ if (g_thread.active)
+ {
+ cur_time = g_system->get_msecs();
+ while (g_thread.old_time < cur_time) {
+ g_thread.old_time += 10;
+ // Don't use mid->_se_on_timer()
+ // We must come in through IMuseMonitor to protect
+ // against conflicts with script access to IMuse.
+ if (mid->_timer_proc)
+ (*(mid->_timer_proc)) (mid->_timer_param);
+ }
+ g_thread.active = false;
+ }
+
+ return 0;
+} \ No newline at end of file