/*************************************************************************** * * * LinuxSampler - modular, streaming capable sampler * * * * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * * Copyright (C) 2005 - 2007 Christian Schoenebeck * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * * MA 02111-1307 USA * ***************************************************************************/ #include "MidiInputDeviceMme.h" #include "MidiInputDeviceFactory.h" namespace LinuxSampler { void CALLBACK MidiInputDeviceMme::MidiInputPortMme::win32_midiin_callback(HMIDIIN handle, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { MidiInputDeviceMme::MidiInputPortMme* p = (MidiInputDeviceMme::MidiInputPortMme*)dwInstance; p->MmeCallbackDispatcher(handle, uMsg, dwParam1, dwParam2); } // *************** ParameterPort *************** // * MidiInputDeviceMme::MidiInputPortMme::ParameterPort::ParameterPort(MidiInputPortMme* pPort) : DeviceRuntimeParameterString("") { this->pPort = pPort; } String MidiInputDeviceMme::MidiInputPortMme::ParameterPort::Description() { return "MME Destination MIDI Port"; } bool MidiInputDeviceMme::MidiInputPortMme::ParameterPort::Fix() { return false; } std::vector MidiInputDeviceMme::MidiInputPortMme::ParameterPort::PossibilitiesAsString() { // returns a list of the available MME Input MIDI ports you can connect to std::vector ports; MIDIINCAPS midiincaps; int NumDevs = midiInGetNumDevs(); for(int i=0;iConnectToMmeMidiSource(s.c_str()); } // *************** MidiInputPortMme *************** // * MidiInputDeviceMme::MidiInputPortMme::MidiInputPortMme(MidiInputDeviceMme* pDevice) throw (MidiInputException) : MidiInputPort(pDevice, ((DeviceCreationParameterInt*)pDevice->Parameters["PORTS"])->ValueAsInt() - 1) { this->pDevice = pDevice; MidiInOpened = false; SysExBuf = new char[MME_MAX_SYSEX_BUF_SIZE]; TmpSysExBuf = new char[MME_MAX_SYSEX_BUF_SIZE]; ExitFlag = false; FirstSysExBlock = true; SysExMsgComplete = false; dmsg(3,("created MME port %d\n", this->portNumber)); Parameters["PORT"] = new ParameterPort(this); } MidiInputDeviceMme::MidiInputPortMme::~MidiInputPortMme() { delete TmpSysExBuf; delete SysExBuf; } /*** * Closes the MME MIDI Input port in a safe way */ void MidiInputDeviceMme::MidiInputPortMme::CloseMmeMidiPort(void) { int res; if (MidiInOpened == true) { ExitFlag = true; midiInReset(MidiInHandle); while ((res = midiInClose(MidiInHandle)) == MIDIERR_STILLPLAYING) Sleep(100); midiInUnprepareHeader(MidiInHandle, &midiHdr, sizeof(MIDIHDR)); MidiInOpened = false; } } /** * Connects the port with the MME Midi Input port * * @param Name of the MME Midi Input port e.g. "MAUDIO MIDI IN" * @throws MidiInputException if connection cannot be established */ void MidiInputDeviceMme::MidiInputPortMme::ConnectToMmeMidiSource(const char* MidiSource) { // close the old MIDI Input port if it was already opened CloseMmeMidiPort(); MIDIINCAPS midiincaps; int NumDevs = midiInGetNumDevs(); int FoundMidiInDeviceId = -1; for(int i=0;i 0){ DispatchNoteOn(data[1], data[2], data[0] & 0x0F); }else{ DispatchNoteOff(data[1], data[2], data[0] & 0x0F); } } break; case 0x80: if (data[1] < 0x80) { DispatchNoteOff(data[1], data[2], data[0] & 0x0F); } break; case 0xC0: if (data[1] < 0x80) { DispatchProgramChange(data[1], data[0] & 0x0F); } break; } break; case MIM_LONGDATA: if(!ExitFlag) { LPMIDIHDR lpMIDIHeader = (LPMIDIHDR)dwParam1; DataPtr = (unsigned char *)(lpMIDIHeader->lpData); if(lpMIDIHeader->dwBytesRecorded == 0) break; if(FirstSysExBlock) { SysExOffset = 0; FirstSysExBlock = false; } if( DataPtr[lpMIDIHeader->dwBytesRecorded - 1] == 0xF7) { SysExMsgComplete = true; FirstSysExBlock = true; } else { SysExMsgComplete = false; } if(SysExOffset + lpMIDIHeader->dwBytesRecorded <= MME_MAX_SYSEX_BUF_SIZE) { memcpy(&SysExBuf[SysExOffset], DataPtr, lpMIDIHeader->dwBytesRecorded); SysExOffset += lpMIDIHeader->dwBytesRecorded; } if(SysExMsgComplete) DispatchSysex(SysExBuf, SysExOffset); /* Queue the MIDIHDR for more input, only if ExitFlag was not set otherwise we risk an infinite loop because when we call midiInReset() below, Windows will send a final MIM_LONGDATA message to that callback. */ midiInAddBuffer(MidiInHandle, lpMIDIHeader, sizeof(MIDIHDR)); } break; } } // *************** MidiInputDeviceMme *************** // * MidiInputDeviceMme::MidiInputDeviceMme(std::map Parameters, void* pSampler) : MidiInputDevice(Parameters, pSampler) { AcquirePorts(((DeviceCreationParameterInt*)Parameters["PORTS"])->ValueAsInt()); if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) { Listen(); } } MidiInputDeviceMme::~MidiInputDeviceMme() { // free the midi ports (we can't let the base class do this, // as the MidiInputPortMme destructors need access to // hAlsaSeq) for (std::map::iterator iter = Ports.begin(); iter != Ports.end() ; iter++) { delete static_cast(iter->second); } Ports.clear(); } MidiInputDeviceMme::MidiInputPortMme* MidiInputDeviceMme::CreateMidiPort() { dmsg(1,("foo\n")); return new MidiInputPortMme(this); } String MidiInputDeviceMme::Name() { return "MME"; } String MidiInputDeviceMme::Driver() { return Name(); } void MidiInputDeviceMme::Listen() { //TODO: ... } void MidiInputDeviceMme::StopListen() { //TODO: ... } String MidiInputDeviceMme::Description() { return "MultiMedia Extensions"; } String MidiInputDeviceMme::Version() { String s = "$Revision: 1.1 $"; return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword } } // namespace LinuxSampler