/*************************************************************************** * * * LinuxSampler - modular, streaming capable sampler * * * * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * * Copyright (C) 2005 - 2012 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); } // *************** ParameterPorts *************** // * // *************** ParameterPorts *************** // * MidiInputDeviceMme::ParameterPorts::ParameterPorts() : DeviceCreationParameterInt() { InitWithDefault(); } MidiInputDeviceMme::ParameterPorts::ParameterPorts(String val) : DeviceCreationParameterInt(val) { } String MidiInputDeviceMme::ParameterPorts::Description() { return "Number of ports"; } bool MidiInputDeviceMme::ParameterPorts::Fix() { return true; } bool MidiInputDeviceMme::ParameterPorts::Mandatory() { return false; } std::map MidiInputDeviceMme::ParameterPorts::DependsAsParameters() { return std::map(); } // the MME driver supports only one port so to manage multiple MME MIDI ports the user just creates several MME drivers and connects each one to the desired MME port optional MidiInputDeviceMme::ParameterPorts::DefaultAsInt(std::map Parameters) { return 1; } optional MidiInputDeviceMme::ParameterPorts::RangeMinAsInt(std::map Parameters) { return 1; } optional MidiInputDeviceMme::ParameterPorts::RangeMaxAsInt(std::map Parameters) { return 1; } std::vector MidiInputDeviceMme::ParameterPorts::PossibilitiesAsInt(std::map Parameters) { return std::vector(); } void MidiInputDeviceMme::ParameterPorts::OnSetValue(int i) throw (Exception) { if (i != 1) throw Exception("MME only supports one MIDI port per device"); } String MidiInputDeviceMme::ParameterPorts::Name() { return "PORTS"; } // the MME driver supports only one port so to manage multiple MME MIDI ports the user just creates several MME drivers and connects each one to the desired MME port // *************** 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;ilpData); 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() { 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.5 $"; return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword } } // namespace LinuxSampler