From b2cf028fcba055110a9b1bf36af0fb6bd443c1af Mon Sep 17 00:00:00 2001 From: Tim Mayberry Date: Fri, 4 Dec 2015 22:23:01 +1000 Subject: Implement MIDI device enumeration and latency offset/calibration in portaudio backend --- libs/backends/portaudio/portaudio_backend.cc | 102 +++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) (limited to 'libs/backends/portaudio/portaudio_backend.cc') diff --git a/libs/backends/portaudio/portaudio_backend.cc b/libs/backends/portaudio/portaudio_backend.cc index 4f74992adf..0f816c991f 100644 --- a/libs/backends/portaudio/portaudio_backend.cc +++ b/libs/backends/portaudio/portaudio_backend.cc @@ -156,6 +156,7 @@ PortAudioBackend::set_driver (const std::string& name) bool PortAudioBackend::update_devices () { + // update midi device info? return _pcmio->update_devices(); } @@ -329,6 +330,24 @@ PortAudioBackend::set_systemic_output_latency (uint32_t sl) return 0; } +int +PortAudioBackend::set_systemic_midi_input_latency (std::string const device, uint32_t sl) +{ + MidiDeviceInfo* nfo = midi_device_info (device); + if (!nfo) return -1; + nfo->systemic_input_latency = sl; + return 0; +} + +int +PortAudioBackend::set_systemic_midi_output_latency (std::string const device, uint32_t sl) +{ + MidiDeviceInfo* nfo = midi_device_info (device); + if (!nfo) return -1; + nfo->systemic_output_latency = sl; + return 0; +} + /* Retrieving parameters */ std::string PortAudioBackend::device_name () const @@ -390,6 +409,22 @@ PortAudioBackend::systemic_output_latency () const return _systemic_audio_output_latency; } +uint32_t +PortAudioBackend::systemic_midi_input_latency (std::string const device) const +{ + MidiDeviceInfo* nfo = midi_device_info (device); + if (!nfo) return 0; + return nfo->systemic_input_latency; +} + +uint32_t +PortAudioBackend::systemic_midi_output_latency (std::string const device) const +{ + MidiDeviceInfo* nfo = midi_device_info (device); + if (!nfo) return 0; + return nfo->systemic_output_latency; +} + std::string PortAudioBackend::control_app_name () const { @@ -431,6 +466,61 @@ PortAudioBackend::midi_option () const return _midi_driver_option; } +std::vector +PortAudioBackend::enumerate_midi_devices () const +{ + std::vector midi_device_status; + std::vector device_info; + + if (_midi_driver_option == winmme_driver_name) { + _midiio->update_device_info (); + device_info = _midiio->get_device_info (); + } + + for (std::vector::const_iterator i = device_info.begin(); + i != device_info.end(); + ++i) { + midi_device_status.push_back(DeviceStatus((*i)->device_name, true)); + } + return midi_device_status; +} + +MidiDeviceInfo* +PortAudioBackend::midi_device_info (const std::string& device_name) const +{ + std::vector dev_info; + + if (_midi_driver_option == winmme_driver_name) { + dev_info = _midiio->get_device_info(); + + for (std::vector::const_iterator i = dev_info.begin(); + i != dev_info.end(); + ++i) { + if ((*i)->device_name == device_name) { + return *i; + } + } + } + return 0; +} + +int +PortAudioBackend::set_midi_device_enabled (std::string const device, bool enable) +{ + MidiDeviceInfo* nfo = midi_device_info(device); + if (!nfo) return -1; + nfo->enable = enable; + return 0; +} + +bool +PortAudioBackend::midi_device_enabled (std::string const device) const +{ + MidiDeviceInfo* nfo = midi_device_info(device); + if (!nfo) return false; + return nfo->enable; +} + /* State Control */ static void * blocking_thread_func (void *arg) @@ -1309,7 +1399,13 @@ PortAudioBackend::register_system_midi_ports() DataType::MIDI, static_cast(IsOutput | IsPhysical | IsTerminal)); if (!p) return -1; + + MidiDeviceInfo* info = _midiio->get_device_info((*i)->name()); + if (info) { // assert? + lr.min = lr.max = _samples_per_period + info->systemic_input_latency; + } set_latency_range (p, false, lr); + PortMidiPort* midi_port = static_cast(p); midi_port->set_pretty_name ((*i)->name()); _system_midi_in.push_back (midi_port); @@ -1327,7 +1423,13 @@ PortAudioBackend::register_system_midi_ports() DataType::MIDI, static_cast(IsInput | IsPhysical | IsTerminal)); if (!p) return -1; + + MidiDeviceInfo* info = _midiio->get_device_info((*i)->name()); + if (info) { // assert? + lr.min = lr.max = _samples_per_period + info->systemic_output_latency; + } set_latency_range (p, false, lr); + PortMidiPort* midi_port = static_cast(p); midi_port->set_n_periods(2); midi_port->set_pretty_name ((*i)->name()); -- cgit v1.2.3