ardour/libs/backends/wavesaudio/waves_midi_device_manager.cc

243 lines
5.8 KiB
C++

/*
Copyright (C) 2013 Paul Davis
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 <CoreMIDI/MIDIServices.h>
#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<WavesMidiDevice *>::const_iterator it = _devices.begin (); it != _devices.end (); ++it) {
(*it)->read_midi ();
}
}
void WavesMidiDeviceManager::do_write ()
{
for (std::vector<WavesMidiDevice *>::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 ();
}
}