/* Copyright (C) 2013 Waves Audio Ltd. 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "waves_midi_device_manager.h" #include "waves_audiobackend.h" #ifdef PLATFORM_WINDOWS #include "windows.h" #include "mmsystem.h" #else if defined(__APPLE__) #include #define midiInGetNumDevs MIDIGetNumberOfSources #define midiOutGetNumDevs MIDIGetNumberOfDestinations #endif using namespace ARDOUR; WavesMidiDeviceManager::WavesMidiDeviceManager (WavesAudioBackend& audiobackend) : _active (false) , _streaming (false) , _input_device_count (0) , _output_device_count (0) , _audiobackend (audiobackend) { } WavesMidiDeviceManager::~WavesMidiDeviceManager () { } int WavesMidiDeviceManager::start () { // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::stream ():" << std::endl; if ( _active == true ) { return -1; } if (Pm_Initialize () != pmNoError) { return -1; } _create_devices (); _input_device_count = midiInGetNumDevs (); _output_device_count = midiOutGetNumDevs (); _active = true; return 0; } int WavesMidiDeviceManager::stream (bool yn) { // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::stream ():" << std::endl; if (!_active) { std::cerr << "WavesMidiDeviceManager::stream (): the midi device manager is not started up !" << std::endl; return -1; } if (_streaming == yn) { return 0; } if (yn) { if ( Pt_Start (1, __portmidi_callback, this) != ptNoError) { std::cerr << "WavesMidiDeviceManager::stream (): Pt_Start () failed!" << std::endl; return -1; } } else { if (Pt_Stop () != ptNoError) { std::cerr << "WavesMidiDeviceManager::stream (): Pt_Stop () failed!" << std::endl; return -1; } } _streaming = yn; return 0; } int WavesMidiDeviceManager::stop () { // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::stop ():" << std::endl; if ( _active == false ) return 0; stream (false); _close_devices (); _active = false; if (Pm_Terminate () != pmNoError) { std::cerr << "WavesMidiDeviceManager::stop (): Pt_Terminate () failed!" << std::endl; return -1; } return 0; } void WavesMidiDeviceManager::__portmidi_callback (PtTimestamp timestamp, void * userData) { // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::__portmidi_callback ():" << std::endl; WavesMidiDeviceManager *dm = (WavesMidiDeviceManager *)userData; if (dm == NULL) { return; } dm->_portmidi_callback (timestamp); } void WavesMidiDeviceManager::_portmidi_callback (PtTimestamp timestamp) { if ((!_active) || (!_streaming)) { return; } if ((_input_device_count != midiInGetNumDevs ()) || (_output_device_count != midiOutGetNumDevs ())) { _audiobackend._changed_midi_devices (); return; } } void WavesMidiDeviceManager::do_read () { for (std::vector::const_iterator it = _devices.begin (); it != _devices.end (); ++it) { (*it)->read_midi (); } } void WavesMidiDeviceManager::do_write () { for (std::vector::const_iterator it = _devices.begin (); it != _devices.end (); ++it) { (*it)->write_midi (); } } PmTimestamp WavesMidiDeviceManager::__get_time_ms (void *time_info) { return ((WavesAudioBackend*)time_info)->sample_time (); } WavesMidiDevice* WavesMidiDeviceManager::_get_device (const std::string& name) { for (size_t i = 0; i < _devices.size (); i++) { if (name == _devices[i]->name ()) { return _devices[i]; } } return NULL; } int WavesMidiDeviceManager::_create_devices () { int count = Pm_CountDevices (); for (int i = 0; i < count; i++) { const PmDeviceInfo* pm_device_info = Pm_GetDeviceInfo (i); if (pm_device_info == NULL) { std::cerr << "WavesMidiDeviceManager::_create_devices (): Pm_GetDeviceInfo (" << i << ") failed!" << std::endl; continue; } WavesMidiDevice *device = _get_device (pm_device_info->name); if (device) { device->validate (); } else { device = new WavesMidiDevice (pm_device_info->name); _devices.push_back (device); } if (device->open (__get_time_ms, (void*)&_audiobackend)) { std::cerr << "WavesMidiDeviceManager::_create_devices (): [" << device->name () << "]->open () failed!" << std::endl; } } return 0; } int WavesMidiDeviceManager::_delete_devices () { // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::_delete_devices ():" << std::endl; while (!_devices.empty ()) { WavesMidiDevice * device = _devices.back (); _devices.pop_back (); delete device; } return 0; } void WavesMidiDeviceManager::_close_devices () { // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::_delete_devices ():" << std::endl; for (size_t i = 0; i < _devices.size (); i++) { _devices[i]->close (); } }