1 /* SpiralSynth 2 * Copyleft (C) 2000 David Griffiths <dave@pawfal.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 */ 18 19 #ifndef MIDI 20 #define MIDI 21 22 #include <sys/types.h> 23 #include <stdio.h> 24 #include <fcntl.h> 25 #include <unistd.h> 26 #include <iostream> 27 #include <limits.h> 28 #include <queue> 29 #include <string> 30 #include "../config.h" 31 32 using namespace std; 33 34 #ifdef USE_ALSA_MIDI 35 #include <alsa/asoundlib.h> 36 #endif 37 38 #if __APPLE__ 39 #include <CoreMIDI/MIDIServices.h> 40 #endif 41 42 class MidiEvent 43 { 44 public: 45 enum type{NONE,ON,OFF,AFTERTOUCH,PARAMETER,CHANNELPRESSURE,PITCHBEND}; 46 47 MidiEvent() {m_Type=NONE;} 48 MidiEvent(type t, int note, float v) 49 {m_Type=t; m_Note=note; m_Volume=v;} 50 51 type GetType() const {return m_Type;} 52 float GetVolume() const {return m_Volume;} 53 int GetNote() const {return m_Note;} 54 private: 55 float m_Volume; 56 type m_Type; 57 int m_Note; 58 }; 59 60 class MidiDevice 61 { 62 public: 63 ~MidiDevice(); 64 65 enum Type{READ,WRITE}; 66 67 static void Init(const string &name, Type t); 68 static void SetDeviceName(string s) { 69 #ifdef USE_OSS_MIDI 70 m_DeviceName=s; 71 #endif 72 } 73 static MidiDevice *Get() { return m_Singleton; } 74 static void PackUpAndGoHome() { if (m_Singleton) delete m_Singleton; m_Singleton=NULL; } 75 76 MidiEvent GetEvent(int Device); 77 void SendEvent(int Device,const MidiEvent &Event); 78 79 void SetPoly(int s) { m_Poly=s; } 80 81 float GetClock() { return m_Clock; } 82 83 private: 84 MidiDevice(Type t); 85 86 int m_Poly; 87 float m_Clock; 88 int m_ClockCount; 89 90 queue<MidiEvent> m_EventVec[16]; 91 92 static MidiDevice *m_Singleton; 93 94 pthread_t m_MidiReader; 95 pthread_mutex_t* m_Mutex; 96 97 static string m_AppName; 98 #ifdef USE_ALSA_MIDI 99 static void *MidiReaderCallback (void *o) { ((MidiDevice*)o)->AlsaCollectEvents(); return NULL; } 100 void AlsaCollectEvents(); 101 void AlsaSendEvent(int Device, const MidiEvent &Event); 102 103 void AlsaClose (); 104 105 //snd_seq_t *seq_handle; 106 107 //I appears that ALsa does not support both a read and write handle 108 //so we must have two handle one for each mode 109 snd_seq_t *seq_rhandle; 110 snd_seq_t *seq_whandle; 111 112 void AlsaOpen(); 113 #endif 114 #ifdef USE_OSS_MIDI 115 static void *MidiReaderCallback (void *o) { ((MidiDevice*)o)->OssCollectEvents(); return NULL; } 116 void OssCollectEvents(); 117 void OssAddEvent(unsigned char* midi); 118 void OssReadByte(unsigned char *c); 119 void OssClose(); 120 bool OssOpen(); 121 static string m_DeviceName; 122 int m_MidiFd, m_MidiWrFd; 123 #endif 124 #if __APPLE__ 125 MIDIClientRef mMIDIClient; 126 MIDIEndpointRef mMIDISource; 127 MIDIEndpointRef mMIDIDestination; 128 129 #define midi_ReadSize 4096 130 unsigned char m_ReadBuffer[midi_ReadSize]; 131 volatile int m_ReadFillIndex; 132 volatile int m_ReadReadIndex; 133 134 void MidiDevice::AppleOpen(); 135 void MidiDevice::AppleClose(); 136 int MidiDevice::AppleWrite(int dummy, unsigned char *outbuffer, int maxlen); 137 int MidiDevice::AppleRead(int dummy, unsigned char *outbuffer, int maxlen); 138 139 static void MidiDevice::sMIDIRead(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon); 140 141 #endif 142 }; 143 144 #endif 145