|
From: <pst...@us...> - 2008-05-26 23:38:38
|
Revision: 568
http://jazzplusplus.svn.sourceforge.net/jazzplusplus/?rev=568&view=rev
Author: pstieber
Date: 2008-05-26 16:38:36 -0700 (Mon, 26 May 2008)
Log Message:
-----------
Added a portmidi player.
Added Paths:
-----------
trunk/jazz/src/PortMidiPlayer.cpp
trunk/jazz/src/PortMidiPlayer.h
Added: trunk/jazz/src/PortMidiPlayer.cpp
===================================================================
--- trunk/jazz/src/PortMidiPlayer.cpp (rev 0)
+++ trunk/jazz/src/PortMidiPlayer.cpp 2008-05-26 23:38:36 UTC (rev 568)
@@ -0,0 +1,414 @@
+#include "WxWidgets.h"
+
+#include "PortMidiPlayer.h"
+#include "TrackWindow.h"
+#include "Song.h"
+#include "Globals.h"
+
+JZPortMidiPlayer::JZPortMidiPlayer(JZSong* pSong)
+ : JZPlayer(pSong),
+ mInputDevices(),
+ mOutputDevices(),
+ mpStream(0),
+ mInitialized(false),
+ mStartTime(0),
+ mStartClock(0),
+ mTicksPerMinute(100),
+ mInputDevice(),
+ mOutputDevice(),
+ mInDev(-1),
+ mOutDev(-1)
+{
+ InitPM();
+ mInDev = Pm_GetDefaultOutputDeviceID();
+ mOutDev = Pm_GetDefaultOutputDeviceID();
+ TermPM();
+
+ Pt_Start(1, 0, 0);
+
+// mOutputQueue = Pm_QueueCreate(1024, sizeof(PmEvent));
+}
+
+JZPortMidiPlayer::~JZPortMidiPlayer()
+{
+// Pm_QueueDestroy(mOutputQueue);
+ TermPM();
+}
+
+int
+JZPortMidiPlayer::Installed()
+{
+ return true;
+}
+
+wxString
+JZPortMidiPlayer::GetInputDeviceName()
+{
+ return mInputDevice;
+}
+
+wxString
+JZPortMidiPlayer::GetOutputDeviceName()
+{
+ return mOutputDevice;
+}
+
+
+void
+JZPortMidiPlayer::SetInputDevice(const wxString & name)
+{
+ bool term = InitPM();
+ PmDeviceID id = FindDevice(name, true);
+
+ if (id != pmNoDevice)
+ {
+ mInputDevice = name;
+ }
+
+ if (term)
+ {
+ TermPM();
+ }
+}
+
+void
+JZPortMidiPlayer::SetOutputDevice(const wxString& name)
+{
+ bool term = InitPM();
+ PmDeviceID id = FindDevice(name, false);
+
+ if (id != pmNoDevice)
+ {
+ mOutputDevice = name;
+ }
+
+ if (term)
+ {
+ TermPM();
+ }
+}
+
+int
+JZPortMidiPlayer::SupportsMultipleDevices()
+{
+ return true;
+}
+
+tDeviceList&
+JZPortMidiPlayer::GetOutputDevices()
+{
+ bool term = InitPM();
+ int cnt;
+
+ cnt = Pm_CountDevices();
+
+ mOutputDevices.Clear();
+
+ for (int i = 0; i < cnt; i++)
+ {
+ const PmDeviceInfo *di = Pm_GetDeviceInfo(i);
+
+ if (di && di->output)
+ {
+ wxString name =
+ wxString(di->interf, wxConvISO8859_1) +
+ wxT(", ") +
+ wxString(di->name, wxConvISO8859_1);
+ mOutputDevices.Add(name);
+ }
+ }
+
+ if (term)
+ {
+ TermPM();
+ }
+
+ return mOutputDevices;
+}
+
+tDeviceList&
+JZPortMidiPlayer::GetInputDevices()
+{
+ bool term = InitPM();
+ int cnt;
+
+ cnt = Pm_CountDevices();
+
+ mInputDevices.Clear();
+
+ for (int i = 0; i < cnt; i++)
+ {
+ const PmDeviceInfo *di = Pm_GetDeviceInfo(i);
+
+ if (di && di->input)
+ {
+ wxString name =
+ wxString(di->interf, wxConvISO8859_1) +
+ wxT(", ") +
+ wxString(di->name, wxConvISO8859_1);
+ mInputDevices.Add(name);
+ }
+ }
+
+ if (term)
+ {
+ TermPM();
+ }
+
+ return mInputDevices;
+}
+
+PmDeviceID
+JZPortMidiPlayer::FindDevice(const wxString & name, bool input)
+{
+ int cnt = Pm_CountDevices();
+
+ for (int i = 0; i < cnt; i++)
+ {
+ const PmDeviceInfo *di = Pm_GetDeviceInfo(i);
+
+ if (di && (input ? di->input : di->output))
+ {
+ wxString n =
+ wxString(di->interf, wxConvISO8859_1) +
+ wxT(", ") +
+ wxString(di->name, wxConvISO8859_1);
+
+ if (name == n)
+ {
+ return i;
+ }
+ }
+ }
+
+ return pmNoDevice;
+}
+
+int
+JZPortMidiPlayer::Clock2Time(int clock)
+{
+ if (clock < mStartClock)
+ {
+ return mStartTime;
+ }
+
+ return (int)((double)(clock - mStartClock) * 60000.0 / (double) mTicksPerMinute + mStartTime);
+}
+
+int
+JZPortMidiPlayer::Time2Clock(int time)
+{
+ if (time < mStartTime)
+ {
+ return mStartClock;
+ }
+
+ return (int)((double)(time - mStartTime) * (double) mTicksPerMinute / 60000.0 + mStartClock);
+}
+
+void
+JZPortMidiPlayer::SetTempo(int bpm, int clock)
+{
+ int t1 = Clock2Time(clock);
+ mTicksPerMinute = bpm * Song->GetTicksPerQuarter();
+ int t2 = Clock2Time(clock);
+ mStartTime += (t1 - t2);
+}
+
+void
+JZPortMidiPlayer::OutBreak()
+{
+}
+
+int
+JZPortMidiPlayer::OutEvent(JZEvent* pEvent, int now)
+{
+ PmError rc = pmNoError;
+ PmTimestamp t = (now ? 0 : pEvent->GetClock());
+
+ t = Clock2Time(t);
+
+#define WSHORT(a, b) \
+ rc = Pm_WriteShort(mpStream, t, Pm_Message(pEvent->GetStat() | k->GetChannel(), a, b))
+
+ switch (pEvent->GetStat())
+ {
+ case StatKeyOn:
+ {
+ tKeyOn *k = pEvent->IsKeyOn();
+
+ WSHORT(k->GetKey(), k->GetVelocity());
+ }
+ break;
+
+ case StatKeyOff:
+ {
+ tKeyOff *k = pEvent->IsKeyOff();
+
+ WSHORT(k->GetKey(), k->GetOffVelocity());
+ }
+ break;
+
+ case StatProgram:
+ {
+ tProgram *k = pEvent->IsProgram();
+
+ WSHORT(k->GetProgram(), 0);
+ }
+ break;
+
+ case StatKeyPressure:
+ {
+ tKeyPressure *k = pEvent->IsKeyPressure();
+
+ WSHORT(k->GetKey(), k->GetValue());
+ }
+ break;
+
+ case StatChnPressure:
+ {
+ tChnPressure *k = pEvent->IsChnPressure();
+
+ WSHORT(k->GetValue(), 0);
+ }
+ break;
+
+ case StatControl:
+ {
+ tControl *k = pEvent->IsControl();
+
+ WSHORT(k->GetControl(), k->GetValue());
+ }
+ break;
+
+ case StatPitch:
+ {
+ tPitch *k = pEvent->IsPitch();
+
+ WSHORT(k->GetValue(), 0);
+ }
+ break;
+
+ case StatSetTempo:
+ {
+ tSetTempo *k = pEvent->IsSetTempo();
+ if (k->GetClock() > 0)
+ {
+ SetTempo(k->GetBPM(), k->GetClock());
+ }
+ }
+ break;
+
+ case StatSysEx:
+ {
+ tSysEx *s = pEvent->IsSysEx();
+
+ unsigned char *buf = new unsigned char[s->GetLength() + 2];
+
+ buf[0] = 0xF0;
+ memcpy(&buf[1], s->GetData(), s->GetLength());
+ buf[s->GetLength() + 2] = 0xf7;
+ rc = Pm_WriteSysEx(mpStream, t, buf);
+
+ delete[] buf;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return rc != pmNoError;
+}
+
+int
+JZPortMidiPlayer::OutEvent(JZEvent* pEvent)
+{
+ return OutEvent(pEvent, 0);
+}
+
+void
+JZPortMidiPlayer::OutNow(JZEvent*pEvent)
+{
+ OutEvent(pEvent, 1);
+}
+
+void
+JZPortMidiPlayer::StartPlay(int clock, int loopClock, int cont)
+{
+ bool term = InitPM();
+ PmDeviceID id = FindDevice(mOutputDevice, false);
+
+ if (id == pmNoDevice)
+ {
+ if (term)
+ {
+ TermPM();
+ }
+
+ return;
+ }
+
+ printf("rc = %d %d\n", Pm_OpenOutput(&mpStream, id, NULL, 0, NULL, NULL, 100), id);
+
+ mStartTime = Pt_Time() + 500;
+ mStartClock = clock;
+ mTicksPerMinute = Song->GetTicksPerQuarter() * Song->Speed();
+
+ JZPlayer::StartPlay(clock, loopClock, cont);
+}
+
+void
+JZPortMidiPlayer::StopPlay()
+{
+ JZPlayer::StopPlay();
+
+ if (mpStream)
+ {
+ Pm_Abort(mpStream);
+ Pm_Close(mpStream);
+ mpStream = NULL;
+ }
+
+ TermPM();
+}
+
+long
+JZPortMidiPlayer::GetRealTimeClock()
+{
+ long t = Pt_Time();
+
+ gpTrackWindow->NewPlayPosition(PlayLoop->Ext2IntClock(Time2Clock(t) / 48 * 48));
+
+ return Time2Clock(t);
+}
+
+bool
+JZPortMidiPlayer::InitPM()
+{
+ if (mInitialized)
+ {
+ return false;
+ }
+
+ Pm_Initialize();
+
+ mInitialized = true;
+
+ return true;
+}
+
+bool
+JZPortMidiPlayer::TermPM()
+{
+ if (!mInitialized)
+ {
+ return false;
+ }
+
+ Pm_Terminate();
+
+ mInitialized = false;
+
+ return true;
+}
Added: trunk/jazz/src/PortMidiPlayer.h
===================================================================
--- trunk/jazz/src/PortMidiPlayer.h (rev 0)
+++ trunk/jazz/src/PortMidiPlayer.h 2008-05-26 23:38:36 UTC (rev 568)
@@ -0,0 +1,67 @@
+#ifndef JZ_PORTMIDIDRIVER_H
+#define JZ_PORTMIDIDRIVER_H
+
+#include "Player.h"
+
+#include "../portmidi/pm_common/portmidi.h"
+#include "../portmidi/porttime/porttime.h"
+
+class JZSong;
+class JZEvent;
+
+class JZPortMidiPlayer : public JZPlayer
+{
+ public:
+
+ JZPortMidiPlayer(JZSong* pSong);
+
+ virtual ~JZPortMidiPlayer();
+
+ int Installed();
+ int SupportsMultipleDevices();
+
+ virtual tDeviceList& GetInputDevices();
+ wxString GetInputDeviceName();
+ void SetInputDevice(const wxString& Name);
+
+ virtual tDeviceList& GetOutputDevices();
+ wxString GetOutputDeviceName();
+ void SetOutputDevice(const wxString& Name);
+
+ int OutEvent(JZEvent* pEvent, int now);
+ int OutEvent(JZEvent* pEvent);
+ void OutNow(JZEvent* pEvent);
+ void OutBreak();
+
+ void StartPlay(int Clock, int LoopClock = 0, int Continue = 0);
+ void StopPlay();
+
+ long GetRealTimeClock();
+ int Clock2Time(int clock);
+ int Time2Clock(int time);
+ void SetTempo(int bpm, int clock);
+
+ private:
+
+ bool InitPM();
+ bool TermPM();
+ PmDeviceID FindDevice(const wxString & name, bool input);
+
+ private:
+
+ tDeviceList mInputDevices;
+ tDeviceList mOutputDevices;
+
+ PortMidiStream* mpStream;
+
+ bool mInitialized;
+ int mStartTime;
+ int mStartClock;
+ int mTicksPerMinute;
+ wxString mInputDevice;
+ wxString mOutputDevice;
+ int mInDev;
+ int mOutDev;
+};
+
+#endif // !defined(JZ_PORTMIDIDRIVER_H)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|