#include <sys/time.h>
#endif
+#ifdef COMPILER_MINGW
+#include <sys/time.h>
+#endif
+
#include <glibmm.h>
#include "portaudio_backend.h"
#include "ardour/filesystem_paths.h"
#include "ardour/port_manager.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
#include "audio_utils.h"
, _pcmio (0)
, _run (false)
, _active (false)
+ , _use_blocking_api(false)
, _freewheel (false)
+ , _freewheeling (false)
+ , _freewheel_ack (false)
+ , _reinit_thread_callback (false)
, _measure_latency (false)
- , m_cycle_count(0)
- , m_total_deviation_us(0)
- , m_max_deviation_us(0)
+ , _cycle_count(0)
+ , _total_deviation_us(0)
+ , _max_deviation_us(0)
, _input_audio_device("")
, _output_audio_device("")
, _midi_driver_option(get_standard_device_name(DeviceNone))
{
_instance_name = s_instance_name;
pthread_mutex_init (&_port_callback_mutex, 0);
+ pthread_mutex_init (&_freewheel_mutex, 0);
+ pthread_cond_init (&_freewheel_signal, 0);
_pcmio = new PortAudioIO ();
_midiio = new WinMMEMidiIO ();
delete _midiio; _midiio = 0;
pthread_mutex_destroy (&_port_callback_mutex);
+ pthread_mutex_destroy (&_freewheel_mutex);
+ pthread_cond_destroy (&_freewheel_signal);
}
/* AUDIOBACKEND API */
bool
PortAudioBackend::update_devices ()
{
+ // update midi device info?
return _pcmio->update_devices();
}
+void
+PortAudioBackend::set_use_buffered_io (bool use_buffered_io)
+{
+ DEBUG_AUDIO (string_compose ("Portaudio: use_buffered_io %1 \n", use_buffered_io));
+
+ if (running()) {
+ return;
+ }
+
+ _use_blocking_api = use_buffered_io;
+}
+
std::string
PortAudioBackend::driver_name () const
{
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
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
{
return _midi_driver_option;
}
+std::vector<AudioBackend::DeviceStatus>
+PortAudioBackend::enumerate_midi_devices () const
+{
+ std::vector<AudioBackend::DeviceStatus> midi_device_status;
+ std::vector<MidiDeviceInfo*> device_info;
+
+ if (_midi_driver_option == winmme_driver_name) {
+ _midiio->update_device_info ();
+ device_info = _midiio->get_device_info ();
+ }
+
+ for (std::vector<MidiDeviceInfo*>::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<MidiDeviceInfo*> dev_info;
+
+ if (_midi_driver_option == winmme_driver_name) {
+ dev_info = _midiio->get_device_info();
+
+ for (std::vector<MidiDeviceInfo*>::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 * pthread_process (void *arg)
+static void * blocking_thread_func (void *arg)
{
PortAudioBackend *d = static_cast<PortAudioBackend *>(arg);
- d->main_blocking_process_thread ();
+ d->blocking_process_thread ();
pthread_exit (0);
return 0;
}
if (running()) {
DEBUG_AUDIO("Already started.\n");
- return -1;
+ return BackendReinitializationError;
}
if (_ports.size()) {
_freewheeling = false;
_freewheel = false;
- PortAudioIO::ErrorCode err;
+ PaErrorCode err = paNoError;
- err = _pcmio->open_blocking_stream(name_to_id(_input_audio_device),
- name_to_id(_output_audio_device),
- _samplerate,
- _samples_per_period);
+ if (_use_blocking_api) {
+ DEBUG_AUDIO("Opening blocking audio stream\n");
+ err = _pcmio->open_blocking_stream(name_to_id(_input_audio_device),
+ name_to_id(_output_audio_device),
+ _samplerate,
+ _samples_per_period);
+ } else {
+ DEBUG_AUDIO("Opening callback audio stream\n");
+ err = _pcmio->open_callback_stream(name_to_id(_input_audio_device),
+ name_to_id(_output_audio_device),
+ _samplerate,
+ _samples_per_period,
+ portaudio_callback,
+ this);
+ }
+ // reintepret Portaudio error messages
switch (err) {
- case PortAudioIO::NoError:
+ case paNoError:
break;
- case PortAudioIO::DeviceConfigNotSupportedError:
- PBD::error << get_error_string(DeviceConfigurationNotSupportedError)
- << endmsg;
- return -1;
+ case paBadIODeviceCombination:
+ return DeviceConfigurationNotSupportedError;
+ case paInvalidChannelCount:
+ return ChannelCountNotSupportedError;
+ case paInvalidSampleRate:
+ return SampleRateNotSupportedError;
default:
- PBD::error << get_error_string(AudioDeviceOpenError) << endmsg;
- return -1;
+ return AudioDeviceOpenError;
}
if (_n_outputs != _pcmio->n_playback_channels ()) {
_midiio->start(); // triggers port discovery, callback coremidi_rediscover()
}
- m_cycle_timer.set_samplerate(_samplerate);
- m_cycle_timer.set_samples_per_cycle(_samples_per_period);
+ _cycle_timer.set_samplerate(_samplerate);
+ _cycle_timer.set_samples_per_cycle(_samples_per_period);
- m_dsp_calc.set_max_time_us (m_cycle_timer.get_length_us());
+ _dsp_calc.set_max_time_us (_cycle_timer.get_length_us());
DEBUG_MIDI ("Registering MIDI ports\n");
if (register_system_midi_ports () != 0) {
DEBUG_PORTS("Failed to register system midi ports.\n")
_run = false;
- return -1;
+ return PortRegistrationError;
}
DEBUG_AUDIO ("Registering Audio ports\n");
if (register_system_audio_ports()) {
DEBUG_PORTS("Failed to register system audio ports.\n");
_run = false;
- return -1;
+ return PortRegistrationError;
}
engine.sample_rate_change (_samplerate);
if (engine.reestablish_ports ()) {
DEBUG_PORTS("Could not re-establish ports.\n");
_run = false;
- return -1;
+ return PortReconnectError;
}
engine.reconnect_ports ();
_run = true;
_port_change_flag = false;
- if (!start_blocking_process_thread()) {
- return -1;
+ if (_use_blocking_api) {
+ if (!start_blocking_process_thread()) {
+ return ProcessThreadStartError;
+ }
+ } else {
+ if (_pcmio->start_stream() != paNoError) {
+ DEBUG_AUDIO("Unable to start stream\n");
+ return AudioDeviceOpenError;
+ }
+
+ if (!start_freewheel_process_thread()) {
+ DEBUG_AUDIO("Unable to start freewheel thread\n");
+ stop();
+ return ProcessThreadStartError;
+ }
}
- return 0;
+ return NoError;
+}
+
+int
+PortAudioBackend::portaudio_callback(const void* input,
+ void* output,
+ unsigned long frame_count,
+ const PaStreamCallbackTimeInfo* time_info,
+ PaStreamCallbackFlags status_flags,
+ void* user_data)
+{
+ PortAudioBackend* pa_backend = static_cast<PortAudioBackend*>(user_data);
+
+ if (!pa_backend->process_callback((const float*)input,
+ (float*)output,
+ frame_count,
+ time_info,
+ status_flags)) {
+ return paAbort;
+ }
+
+ return paContinue;
+}
+
+bool
+PortAudioBackend::process_callback(const float* input,
+ float* output,
+ uint32_t frame_count,
+ const PaStreamCallbackTimeInfo* timeInfo,
+ PaStreamCallbackFlags statusFlags)
+{
+ _active = true;
+
+ _dsp_calc.set_start_timestamp_us (PBD::get_microseconds());
+
+ if (_run && _freewheel && !_freewheel_ack) {
+ // acknowledge freewheeling; hand-over thread ID
+ pthread_mutex_lock (&_freewheel_mutex);
+ if (_freewheel) {
+ DEBUG_AUDIO("Setting _freewheel_ack = true;\n");
+ _freewheel_ack = true;
+ }
+ DEBUG_AUDIO("Signalling freewheel thread\n");
+ pthread_cond_signal (&_freewheel_signal);
+ pthread_mutex_unlock (&_freewheel_mutex);
+ }
+
+ if (statusFlags & paInputUnderflow ||
+ statusFlags & paInputOverflow ||
+ statusFlags & paOutputUnderflow ||
+ statusFlags & paOutputOverflow ) {
+ DEBUG_AUDIO("PortAudio: Xrun\n");
+ engine.Xrun();
+ return true;
+ }
+
+ if (!_run || _freewheel) {
+ memset(output, 0, frame_count * sizeof(float) * _system_outputs.size());
+ return true;
+ }
+
+ bool in_main_thread = pthread_equal(_main_thread, pthread_self());
+
+ if (_reinit_thread_callback || !in_main_thread) {
+ _reinit_thread_callback = false;
+ _main_thread = pthread_self();
+ AudioEngine::thread_init_callback (this);
+ }
+
+ process_port_connection_changes();
+
+ return blocking_process_main (input, output);
}
bool
PortAudioBackend::start_blocking_process_thread ()
{
if (_realtime_pthread_create (SCHED_FIFO, -20, 100000,
- &_main_blocking_thread, pthread_process, this))
+ &_main_blocking_thread, blocking_thread_func, this))
{
- if (pthread_create (&_main_blocking_thread, NULL, pthread_process, this))
+ if (pthread_create (&_main_blocking_thread, NULL, blocking_thread_func, this))
{
DEBUG_AUDIO("Failed to create main audio thread\n");
_run = false;
_run = false;
- if (!stop_blocking_process_thread ()) {
- return -1;
+ if (_use_blocking_api) {
+ if (!stop_blocking_process_thread()) {
+ return -1;
+ }
+ } else {
+ _pcmio->close_stream();
+ _active = false;
+
+ if (!stop_freewheel_process_thread()) {
+ return -1;
+ }
}
unregister_ports();
return (_active == false) ? 0 : -1;
}
+static void* freewheel_thread(void* arg)
+{
+ PortAudioBackend* d = static_cast<PortAudioBackend*>(arg);
+ d->freewheel_process_thread ();
+ pthread_exit (0);
+ return 0;
+}
+
+bool
+PortAudioBackend::start_freewheel_process_thread ()
+{
+ if (pthread_create(&_pthread_freewheel, NULL, freewheel_thread, this)) {
+ DEBUG_AUDIO("Failed to create main audio thread\n");
+ return false;
+ }
+
+ int timeout = 5000;
+ while (!_freewheel_thread_active && --timeout > 0) { Glib::usleep (1000); }
+
+ if (timeout == 0 || !_freewheel_thread_active) {
+ DEBUG_AUDIO("Failed to start freewheel thread\n");
+ return false;
+ }
+ return true;
+}
+
+bool
+PortAudioBackend::stop_freewheel_process_thread ()
+{
+ void *status;
+
+ if (!_freewheel_thread_active) {
+ return true;
+ }
+
+ DEBUG_AUDIO("Signaling freewheel thread to stop\n");
+
+ pthread_mutex_lock (&_freewheel_mutex);
+ pthread_cond_signal (&_freewheel_signal);
+ pthread_mutex_unlock (&_freewheel_mutex);
+
+ if (pthread_join (_pthread_freewheel, &status) != 0) {
+ DEBUG_AUDIO("Failed to stop freewheel thread\n");
+ return false;
+ }
+
+ return true;
+}
+
+void*
+PortAudioBackend::freewheel_process_thread()
+{
+ _freewheel_thread_active = true;
+
+ bool first_run = false;
+
+ pthread_mutex_lock (&_freewheel_mutex);
+
+ while(_run) {
+ // check if we should run,
+ if (_freewheeling != _freewheel) {
+ if (!_freewheeling) {
+ DEBUG_AUDIO("Leaving freewheel\n");
+ _freewheel = false; // first mark as disabled
+ _reinit_thread_callback = true; // hand over _main_thread
+ _freewheel_ack = false; // prepare next handshake
+ _midiio->set_enabled(true);
+ engine.freewheel_callback (_freewheeling);
+ } else {
+ first_run = true;
+ _freewheel = true;
+ }
+ }
+
+ if (!_freewheel || !_freewheel_ack) {
+ // wait for a change, we use a timed wait to
+ // terminate early in case some error sets _run = 0
+ struct timeval tv;
+ struct timespec ts;
+ gettimeofday (&tv, NULL);
+ ts.tv_sec = tv.tv_sec + 3;
+ ts.tv_nsec = 0;
+ DEBUG_AUDIO("Waiting for freewheel change\n");
+ pthread_cond_timedwait (&_freewheel_signal, &_freewheel_mutex, &ts);
+ continue;
+ }
+
+ if (first_run) {
+ // tell the engine we're ready to GO.
+ engine.freewheel_callback (_freewheeling);
+ first_run = false;
+ _main_thread = pthread_self();
+ AudioEngine::thread_init_callback (this);
+ _midiio->set_enabled(false);
+ }
+
+ if (!blocking_process_freewheel()) {
+ break;
+ }
+
+ process_port_connection_changes();
+ }
+
+ pthread_mutex_unlock (&_freewheel_mutex);
+
+ _freewheel_thread_active = false;
+
+ if (_run) {
+ // engine.process_callback() returner error
+ engine.halted_callback("CoreAudio Freehweeling aborted.");
+ }
+ return 0;
+}
+
int
PortAudioBackend::freewheel (bool onoff)
{
return 0;
}
_freewheeling = onoff;
+
+ if (0 == pthread_mutex_trylock (&_freewheel_mutex)) {
+ pthread_cond_signal (&_freewheel_signal);
+ pthread_mutex_unlock (&_freewheel_mutex);
+ }
return 0;
}
if (!_active || !_run || _freewheeling || _freewheel) {
return 0;
}
- if (!m_cycle_timer.valid()) {
+ if (!_cycle_timer.valid()) {
return 0;
}
- return m_cycle_timer.samples_since_cycle_start (PBD::get_microseconds());
+ return _cycle_timer.samples_since_cycle_start (PBD::get_microseconds());
}
int
bool
PortAudioBackend::in_process_thread ()
{
- if (pthread_equal (_main_blocking_thread, pthread_self()) != 0) {
- return true;
+ if (_use_blocking_api) {
+ if (pthread_equal(_main_blocking_thread, pthread_self()) != 0) {
+ return true;
+ }
+ } else {
+ if (pthread_equal(_main_thread, pthread_self()) != 0) {
+ return true;
+ }
}
-
for (std::vector<pthread_t>::const_iterator i = _threads.begin (); i != _threads.end (); ++i)
{
if (pthread_equal (*i, pthread_self ()) != 0) {
return -1;
}
+int
+PortAudioBackend::set_port_property (PortHandle port,
+ const std::string& key,
+ const std::string& value,
+ const std::string& type)
+{
+ if (!valid_port (port)) {
+ DEBUG_PORTS("get_port_name: Invalid Port(s)\n");
+ return -1;
+ }
+
+ if (key == "http://jackaudio.org/metadata/pretty-name" && type.empty ()) {
+ static_cast<PamPort*>(port)->set_pretty_name (value);
+ return 0;
+ }
+ return -1;
+}
+
PortEngine::PortHandle
PortAudioBackend::get_port_by_name (const std::string& name) const
{
const uint32_t a_ins = _n_inputs;
const uint32_t a_out = _n_outputs;
- // XXX PA reported stream latencies don't match measurements
- const uint32_t portaudio_reported_input_latency = _samples_per_period ; // _pcmio->capture_latency();
- const uint32_t portaudio_reported_output_latency = /* _samples_per_period + */ _pcmio->playback_latency();
+ uint32_t capture_latency = 0;
+ uint32_t playback_latency = 0;
+
+ // guard against erroneous latency values
+ if (_pcmio->capture_latency() > _samples_per_period) {
+ capture_latency = _pcmio->capture_latency() - _samples_per_period;
+ }
+ if (_pcmio->playback_latency() > _samples_per_period) {
+ playback_latency = _pcmio->playback_latency() - _samples_per_period;
+ }
/* audio ports */
- lr.min = lr.max = portaudio_reported_input_latency + (_measure_latency ? 0 : _systemic_audio_input_latency);
+ lr.min = lr.max = capture_latency + (_measure_latency ? 0 : _systemic_audio_input_latency);
for (uint32_t i = 0; i < a_ins; ++i) {
char tmp[64];
snprintf(tmp, sizeof(tmp), "system:capture_%d", i+1);
_system_inputs.push_back (audio_port);
}
- lr.min = lr.max = portaudio_reported_output_latency + (_measure_latency ? 0 : _systemic_audio_output_latency);
+ lr.min = lr.max = playback_latency + (_measure_latency ? 0 : _systemic_audio_output_latency);
for (uint32_t i = 0; i < a_out; ++i) {
char tmp[64];
snprintf(tmp, sizeof(tmp), "system:playback_%d", i+1);
for (std::vector<WinMMEMidiInputDevice*>::const_iterator i = inputs.begin ();
i != inputs.end ();
++i) {
- std::string port_name = "system_midi:" + (*i)->name() + " capture";
+ std::string port_name = "system:midi_capture_" + (*i)->name();
PortHandle p =
add_port (port_name,
DataType::MIDI,
static_cast<PortFlags>(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<PortMidiPort*>(p);
midi_port->set_pretty_name ((*i)->name());
_system_midi_in.push_back (midi_port);
for (std::vector<WinMMEMidiOutputDevice*>::const_iterator i = outputs.begin ();
i != outputs.end ();
++i) {
- std::string port_name = "system_midi:" + (*i)->name() + " playback";
+ std::string port_name = "system:midi_playback_" + (*i)->name();
PortHandle p =
add_port (port_name,
DataType::MIDI,
static_cast<PortFlags>(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<PortMidiPort*>(p);
midi_port->set_n_periods(2);
midi_port->set_pretty_name ((*i)->name());
void *
-PortAudioBackend::main_blocking_process_thread ()
+PortAudioBackend::blocking_process_thread ()
{
AudioEngine::thread_init_callback (this);
_active = true;
manager.registration_callback();
manager.graph_order_callback();
- if (_pcmio->start_stream() != PortAudioIO::NoError) {
+ if (_pcmio->start_stream() != paNoError) {
_pcmio->close_stream ();
_active = false;
engine.halted_callback(get_error_string(AudioDeviceIOError).c_str());
int64_t min_elapsed_us = 1000000;
int64_t max_elapsed_us = 0;
- m_dsp_calc.set_start_timestamp_us (PBD::get_microseconds());
+ _dsp_calc.set_start_timestamp_us (PBD::get_microseconds());
i = 0;
/* Copy input audio data into input port buffers */
_samples_per_period * sizeof(Sample));
}
- m_last_cycle_start = m_cycle_timer.get_start();
- m_cycle_timer.reset_start(PBD::get_microseconds());
- m_cycle_count++;
+ _last_cycle_start = _cycle_timer.get_start();
+ _cycle_timer.reset_start(PBD::get_microseconds());
+ _cycle_count++;
- uint64_t cycle_diff_us = (m_cycle_timer.get_start() - m_last_cycle_start);
- int64_t deviation_us = (cycle_diff_us - m_cycle_timer.get_length_us());
- m_total_deviation_us += ::llabs(deviation_us);
- m_max_deviation_us =
- std::max(m_max_deviation_us, (uint64_t)::llabs(deviation_us));
+ uint64_t cycle_diff_us = (_cycle_timer.get_start() - _last_cycle_start);
+ int64_t deviation_us = (cycle_diff_us - _cycle_timer.get_length_us());
+ _total_deviation_us += ::llabs(deviation_us);
+ _max_deviation_us =
+ std::max(_max_deviation_us, (uint64_t)::llabs(deviation_us));
- if ((m_cycle_count % 1000) == 0) {
- uint64_t mean_deviation_us = m_total_deviation_us / m_cycle_count;
+ if ((_cycle_count % 1000) == 0) {
+ uint64_t mean_deviation_us = _total_deviation_us / _cycle_count;
DEBUG_TIMING(string_compose("Mean avg cycle deviation: %1(ms), max %2(ms)\n",
mean_deviation_us * 1e-3,
- m_max_deviation_us * 1e-3));
+ _max_deviation_us * 1e-3));
}
- if (::llabs(deviation_us) > m_cycle_timer.get_length_us()) {
+ if (::llabs(deviation_us) > _cycle_timer.get_length_us()) {
DEBUG_TIMING(
string_compose("time between process(ms): %1, Est(ms): %2, Dev(ms): %3\n",
cycle_diff_us * 1e-3,
- m_cycle_timer.get_length_us() * 1e-3,
+ _cycle_timer.get_length_us() * 1e-3,
deviation_us * 1e-3));
}
_processed_samples += _samples_per_period;
/* calculate DSP load */
- m_dsp_calc.set_stop_timestamp_us (PBD::get_microseconds());
- _dsp_load = m_dsp_calc.get_dsp_load();
+ _dsp_calc.set_stop_timestamp_us (PBD::get_microseconds());
+ _dsp_load = _dsp_calc.get_dsp_load();
DEBUG_TIMING(string_compose("DSP Load: %1\n", _dsp_load));
- max_elapsed_us = std::max(m_dsp_calc.elapsed_time_us(), max_elapsed_us);
- min_elapsed_us = std::min(m_dsp_calc.elapsed_time_us(), min_elapsed_us);
- if ((m_cycle_count % 1000) == 0) {
+ max_elapsed_us = std::max(_dsp_calc.elapsed_time_us(), max_elapsed_us);
+ min_elapsed_us = std::min(_dsp_calc.elapsed_time_us(), min_elapsed_us);
+ if ((_cycle_count % 1000) == 0) {
DEBUG_TIMING(string_compose("Elapsed process time(usecs) max: %1, min: %2\n",
max_elapsed_us,
min_elapsed_us));
uint8_t data[256];
size_t size = sizeof(data);
while (_midiio->dequeue_input_event(i,
- m_cycle_timer.get_start(),
- m_cycle_timer.get_next_start(),
+ _cycle_timer.get_start(),
+ _cycle_timer.get_next_start(),
timestamp,
data,
size)) {
- sample_offset = m_cycle_timer.samples_since_cycle_start(timestamp);
+ sample_offset = _cycle_timer.samples_since_cycle_start(timestamp);
midi_event_put(mbuf, sample_offset, data, size);
DEBUG_MIDI(string_compose("Dequeuing incoming MIDI data for device: %1 "
"sample_offset: %2 timestamp: %3, size: %4\n",
for (PortMidiBuffer::const_iterator mit = src->begin(); mit != src->end();
++mit) {
uint64_t timestamp =
- m_cycle_timer.timestamp_from_sample_offset((*mit)->timestamp());
+ _cycle_timer.timestamp_from_sample_offset((*mit)->timestamp());
DEBUG_MIDI(string_compose("Queuing outgoing MIDI data for device: "
"%1 sample_offset: %2 timestamp: %3, size: %4\n",
_midiio->get_outputs()[i]->name(),
static bool available ();
static ARDOUR::AudioBackendInfo _descriptor = {
- "PortAudio",
+ BACKEND_NAME,
instantiate,
deinstantiate,
backend_factory,