summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2015-05-13 19:11:27 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2015-06-29 14:18:14 -0400
commit237f255fb51d02bf312c04900ecd9a37579ff9f8 (patch)
treebb58b63d398de97f327656981f6a2201058cc0b9 /libs
parent0fca07fa9df93d9bcbf516be2824247b39a1aeff (diff)
meld-driven unification of current ardour-ish WavesAudio backend and current tracks WavesAudio backend.
May be incomplete, and may not compile (testing to follow)
Diffstat (limited to 'libs')
-rw-r--r--libs/backends/wavesaudio/waves_audiobackend.cc42
-rw-r--r--libs/backends/wavesaudio/waves_audiobackend.h2
-rw-r--r--libs/backends/wavesaudio/waves_audioport.cc47
-rw-r--r--libs/backends/wavesaudio/waves_audioport.h4
-rw-r--r--libs/backends/wavesaudio/waves_dataport.cc15
-rw-r--r--libs/backends/wavesaudio/waves_dataport.h1
-rw-r--r--libs/backends/wavesaudio/waves_midi_device.cc229
-rw-r--r--libs/backends/wavesaudio/waves_midi_device_manager.cc12
-rw-r--r--libs/backends/wavesaudio/waves_midi_event.cc177
-rw-r--r--libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp9
-rw-r--r--libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp116
-rw-r--r--libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h1
-rw-r--r--libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp81
-rw-r--r--libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h1
14 files changed, 487 insertions, 250 deletions
diff --git a/libs/backends/wavesaudio/waves_audiobackend.cc b/libs/backends/wavesaudio/waves_audiobackend.cc
index 7fd6da2f39..2a5ddba991 100644
--- a/libs/backends/wavesaudio/waves_audiobackend.cc
+++ b/libs/backends/wavesaudio/waves_audiobackend.cc
@@ -99,8 +99,8 @@ void WavesAudioBackend::AudioDeviceManagerNotification (NotificationReason reaso
}
-WavesAudioBackend::WavesAudioBackend (AudioEngine& e)
- : AudioBackend (e, __backend_info)
+WavesAudioBackend::WavesAudioBackend (AudioEngine& e, AudioBackendInfo& info)
+ : AudioBackend (e, info)
, _audio_device_manager (this)
, _midi_device_manager (*this)
, _device (NULL)
@@ -420,7 +420,11 @@ WavesAudioBackend::set_sample_rate (float sample_rate)
return -1;
}
- _sample_rate_change(sample_rate);
+ // if call to set sample rate is successful
+ // but device sample rate differs from the value we tried to set
+ // this means we are driven by device for buffer size
+ sample_rate = _device->CurrentSamplingRate ();
+ _sample_rate_change(sample_rate);
if (device_needs_restart) {
// COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetStreaming (true);"<< std::endl;
@@ -499,8 +503,6 @@ WavesAudioBackend::reset_device ()
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_reset_device ():" << std::endl;
- WTErr retVal = eNoErr;
-
if (!_device) {
std::cerr << "WavesAudioBackend::set_buffer_size (): No device is set!" << std::endl;
return -1;
@@ -829,11 +831,23 @@ WavesAudioBackend::freewheel (bool start_stop)
}
_call_thread_init_callback = true;
_freewheel_thread ();
- engine.freewheel_callback (start_stop);
+
+ while (!engine.freewheeling()) {
+ sleep(0);
+ }
+
+ // freewheel thread was not activated successfully
+ if (_freewheel_thread_active == false) {
+ engine.freewheel_callback(false);
+ }
}
else {
_freewheel_thread_active = false; // stop _freewheel_thread ()
- engine.freewheel_callback (start_stop);
+
+ while (engine.freewheeling()) {
+ sleep(0);
+ }
+
_call_thread_init_callback = true;
WTErr retval = _device->SetStreaming (true);
if (retval != eNoErr) {
@@ -873,6 +887,10 @@ WavesAudioBackend::_freewheel_thread ()
_freewheel_thread_active = true;
if ((pthread_create (&thread_id, &attributes, __start_process_thread, thread_data))) {
_freewheel_thread_active = false;
+
+ // release invoking thread
+ engine.freewheel_callback(true);
+
std::cerr << "WavesAudioBackend::freewheel_thread (): pthread_create () failed!" << std::endl;
return;
}
@@ -881,6 +899,9 @@ WavesAudioBackend::_freewheel_thread ()
return;
}
+ // notify angine that freewheeling is started
+ engine.freewheel_callback(true);
+
if (_call_thread_init_callback) {
_call_thread_init_callback = false;
AudioEngine::thread_init_callback (this);
@@ -889,6 +910,10 @@ WavesAudioBackend::_freewheel_thread ()
while (_freewheel_thread_active) {
engine.process_callback (_buffer_size);
}
+
+ // notify angine that freewheeling is stopped
+ engine.freewheel_callback(false);
+
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_freewheel_thread (): FINISHED" << std::endl;
return;
}
@@ -1238,7 +1263,7 @@ WavesAudioBackend::__waves_backend_factory (AudioEngine& e)
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__waves_backend_factory ():" << std::endl;
if (!__instance) {
- __instance.reset (new WavesAudioBackend (e));
+ __instance.reset (new WavesAudioBackend (e, *(descriptor())));
}
return __instance;
}
@@ -1260,7 +1285,6 @@ WavesAudioBackend::__instantiate (const std::string& arg1, const std::string& ar
LARGE_INTEGER Frequency;
QueryPerformanceFrequency(&Frequency);
__performance_counter_frequency = Frequency.QuadPart;
- std::cout << "__performance_counter_frequency:" << __performance_counter_frequency << std::endl;
#endif
return 0;
diff --git a/libs/backends/wavesaudio/waves_audiobackend.h b/libs/backends/wavesaudio/waves_audiobackend.h
index ad40d094df..68af4b2a04 100644
--- a/libs/backends/wavesaudio/waves_audiobackend.h
+++ b/libs/backends/wavesaudio/waves_audiobackend.h
@@ -70,7 +70,7 @@ class WavesMidiPort;
class WavesAudioBackend : public AudioBackend, WCMRAudioDeviceManagerClient
{
public:
- WavesAudioBackend (AudioEngine& e);
+ WavesAudioBackend (AudioEngine& e, AudioBackendInfo&);
virtual ~WavesAudioBackend ();
/* AUDIOBACKEND API */
diff --git a/libs/backends/wavesaudio/waves_audioport.cc b/libs/backends/wavesaudio/waves_audioport.cc
index 1249f4d31e..8f967f0a57 100644
--- a/libs/backends/wavesaudio/waves_audioport.cc
+++ b/libs/backends/wavesaudio/waves_audioport.cc
@@ -18,13 +18,21 @@
*/
#include "waves_audioport.h"
+#include "ardour/runtime_functions.h"
+#include "pbd/malign.h"
using namespace ARDOUR;
WavesAudioPort::WavesAudioPort (const std::string& port_name, PortFlags flags)
: WavesDataPort (port_name, flags)
{
- memset (_buffer, 0, sizeof (_buffer));
+ aligned_malloc ((void**)&_buffer, MAX_BUFFER_SIZE_BYTES, 32 /*32 byte alignment*/);
+ memset (_buffer, 0, MAX_BUFFER_SIZE_BYTES);
+}
+
+WavesAudioPort::~WavesAudioPort ()
+{
+ aligned_free (_buffer);
}
@@ -35,24 +43,25 @@ void* WavesAudioPort::get_buffer (pframes_t nframes)
std::vector<WavesDataPort*>::const_iterator it = get_connections ().begin ();
if (it != get_connections ().end ()) {
- /* In fact, the static casting to (const WavesAudioPort*) is not that safe.
- * However, mixing the buffers is assumed in the time critical conditions.
- * Base class WavesDataPort takes is supposed to provide enough consistentcy
- * of the connections.
- */
- // get first buffer data
- // use optimized function to fill the buffer intialy
- ARDOUR::copy_vector (_buffer, ((const WavesAudioPort*)*it)->const_buffer (), nframes);
- ++it;
-
- // mix the rest
- for (; it != get_connections ().end (); ++it) {
- Sample* tgt = buffer ();
- const Sample* src = ((const WavesAudioPort*)*it)->const_buffer ();
- for (uint32_t frame = 0; frame < nframes; ++frame, ++tgt, ++src) {
- *tgt += *src;
- }
- }
+ /* In fact, the static casting to (const WavesAudioPort*) is not that safe.
+ * However, mixing the buffers is assumed in the time critical conditions.
+ * Base class WavesDataPort takes is supposed to provide enough consistentcy
+ * of the connections.
+ */
+
+ // get first buffer data
+ // use optimized function to fill the buffer intialy
+ ARDOUR::copy_vector (_buffer, ((const WavesAudioPort*)*it)->const_buffer (), nframes);
+ ++it;
+
+ // mix the rest
+ for (; it != get_connections ().end (); ++it) {
+ Sample* tgt = buffer ();
+ const Sample* src = ((const WavesAudioPort*)*it)->const_buffer ();
+
+ // use otimized function to mix the buffers
+ ARDOUR::mix_buffers_no_gain (tgt, src, nframes);
+ }
}
}
return _buffer;
diff --git a/libs/backends/wavesaudio/waves_audioport.h b/libs/backends/wavesaudio/waves_audioport.h
index 5b4ab52449..d658dba868 100644
--- a/libs/backends/wavesaudio/waves_audioport.h
+++ b/libs/backends/wavesaudio/waves_audioport.h
@@ -35,7 +35,7 @@ public:
WavesAudioPort (const std::string& port_name, PortFlags flags);
- virtual ~WavesAudioPort () { };
+ virtual ~WavesAudioPort ();
virtual DataType type () const { return DataType::AUDIO; };
@@ -49,7 +49,7 @@ protected:
private:
- Sample _buffer[MAX_BUFFER_SIZE_SAMPLES];
+ Sample *_buffer;
};
} // namespace
diff --git a/libs/backends/wavesaudio/waves_dataport.cc b/libs/backends/wavesaudio/waves_dataport.cc
index d1dacc90eb..ffdc9865f3 100644
--- a/libs/backends/wavesaudio/waves_dataport.cc
+++ b/libs/backends/wavesaudio/waves_dataport.cc
@@ -67,7 +67,7 @@ int WavesDataPort::connect (WavesDataPort *port)
}
if (is_connected (port)) {
- std::cerr << "WavesDataPort::connect (): the ports are already connected!" << std::endl;
+ // std::cerr << "WavesDataPort::connect (): the ports are already connected!" << std::endl;
return -1;
}
@@ -115,8 +115,7 @@ void WavesDataPort::_disconnect (WavesDataPort *port, bool api_call)
port->_disconnect (this, false);
}
- if (is_input() && _connections.empty())
- {
+ if (is_input() && _connections.empty()) {
_wipe_buffer();
}
}
@@ -124,13 +123,21 @@ void WavesDataPort::_disconnect (WavesDataPort *port, bool api_call)
void WavesDataPort::disconnect_all ()
{
+ _disconnect_all ();
+
+ if (is_input()) {
+ _wipe_buffer();
+ }
+}
+
+void WavesDataPort::_disconnect_all ()
+{
while (!_connections.empty ()) {
_connections.back ()->_disconnect (this, false);
_connections.pop_back ();
}
}
-
bool WavesDataPort::is_physically_connected () const
{
for (std::vector<WavesDataPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) {
diff --git a/libs/backends/wavesaudio/waves_dataport.h b/libs/backends/wavesaudio/waves_dataport.h
index 1b2f26f3f1..a5b8243bbe 100644
--- a/libs/backends/wavesaudio/waves_dataport.h
+++ b/libs/backends/wavesaudio/waves_dataport.h
@@ -106,6 +106,7 @@ private:
std::vector<WavesDataPort*> _connections;
void _connect (WavesDataPort* port, bool api_call);
+ void _disconnect_all ();
void _disconnect (WavesDataPort* port, bool api_call);
};
diff --git a/libs/backends/wavesaudio/waves_midi_device.cc b/libs/backends/wavesaudio/waves_midi_device.cc
index 25d06da481..9bb6661136 100644
--- a/libs/backends/wavesaudio/waves_midi_device.cc
+++ b/libs/backends/wavesaudio/waves_midi_device.cc
@@ -18,6 +18,12 @@
*/
#include <iostream>
+
+#include "pbd/error.h"
+#include "pbd/debug.h"
+#include "pbd/compose.h"
+#include "pbd/stacktrace.h"
+
#include "waves_midi_device.h"
#include "waves_midi_event.h"
@@ -27,6 +33,7 @@
#define QUEUE_LENGTH 1024
using namespace ARDOUR;
+using namespace PBD;
WavesMidiDevice::WavesMidiDevice (const std::string& device_name)
: _pm_input_id (pmNoDevice)
@@ -61,14 +68,16 @@ WavesMidiDevice::WavesMidiDevice (const std::string& device_name)
WavesMidiDevice::~WavesMidiDevice ()
{
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::~WavesMidiDevice ():" << name () << std::endl;
- close ();
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::~WavesMidiDevice (): %1\n", name()));
+ close ();
}
int
WavesMidiDevice::open (PmTimeProcPtr time_proc, void* time_info)
{
- if (is_input () ) {
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::open (): %1", name ()));
+
+ if (is_input () ) {
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::open (): INPUT" << _pm_input_id << "-[" << name () << "]" << std::endl;
if (!_input_pm_stream) {
@@ -78,26 +87,26 @@ WavesMidiDevice::open (PmTimeProcPtr time_proc, void* time_info)
_input_queue = Pm_QueueCreate (QUEUE_LENGTH, sizeof (const WavesMidiEvent*));
// COMMENTED DBG LOGS */ std::cout << " DONE : " << std::endl;
if (NULL == _input_queue) {
- std::cerr << "WavesMidiDevice::open (): _input_queue = Pm_QueueCreate () failed for " << _pm_input_id << "-[" << name () << "]!" << std::endl;
- return -1;
+ std::cerr << "WavesMidiDevice::open (): _input_queue = Pm_QueueCreate () failed for " << _pm_input_id << "-[" << name () << "]!" << std::endl;
+ return -1;
}
}
// create stream
// COMMENTED DBG LOGS */ std::cout << " going to Pm_OpenInput : " << std::endl;
- if (pmNoError != Pm_OpenInput (&_input_pm_stream,
- _pm_input_id,
- NULL,
- 1024,
- time_proc,
- time_info)) {
- // COMMENTED DBG LOGS */ std::cout << " DONE : " << std::endl;
- char* err_msg = new char[256];
- Pm_GetHostErrorText(err_msg, 256);
- std::cerr << "WavesMidiDevice::open (): Pm_OpenInput () failed for " << _pm_input_id << "-[" << name () << "]!" << std::endl;
- std::cerr << " Port Midi Host Error: " << err_msg << std::endl;
- close ();
- return -1;
- }
+ if (pmNoError != Pm_OpenInput (&_input_pm_stream,
+ _pm_input_id,
+ NULL,
+ 1024,
+ time_proc,
+ time_info)) {
+ // COMMENTED DBG LOGS */ std::cout << " DONE : " << std::endl;
+ char* err_msg = new char[256];
+ Pm_GetHostErrorText(err_msg, 256);
+ std::cerr << "WavesMidiDevice::open (): Pm_OpenInput () failed for " << _pm_input_id << "-[" << name () << "]!" << std::endl;
+ std::cerr << " Port Midi Host Error: " << err_msg << std::endl;
+ close ();
+ return -1;
+ }
// COMMENTED DBG LOGS */ std::cout << " DONE : " << std::endl;
}
}
@@ -142,6 +151,7 @@ WavesMidiDevice::open (PmTimeProcPtr time_proc, void* time_info)
void
WavesMidiDevice::close ()
{
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::close (): %1\n", name ()));
WavesMidiEvent *waves_midi_event;
// save _input_pm_stream and _output_pm_stream to local buf
@@ -197,114 +207,123 @@ WavesMidiDevice::close ()
void
WavesMidiDevice::do_io ()
{
- read_midi ();
- write_midi ();
+ read_midi ();
+ write_midi ();
}
void
WavesMidiDevice::read_midi ()
{
- if (NULL == _input_pm_stream) {
- return;
- }
-
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "]" << std::endl;
-
- while (Pm_Poll (_input_pm_stream) > 0) {
- PmEvent pm_event; // just one message at a time
- int result = Pm_Read (_input_pm_stream, &pm_event, 1);
- if (result < 0) {
- std::cerr << "WavesMidiDevice::_read_midi (): Pm_Read () failed (" << result << ") for [" << name () << "]!" << std::endl;
- break;
- }
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] evt-tm:" << pm_event.timestamp << std::endl;
- if (_incomplete_waves_midi_event == NULL ) {
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] : new _incomplete_waves_midi_event" << std::endl;
- _incomplete_waves_midi_event = new WavesMidiEvent (pm_event.timestamp);
+ if (NULL == _input_pm_stream) {
+ return;
}
- WavesMidiEvent *nested_pm_event = _incomplete_waves_midi_event->append_data (pm_event);
- if (nested_pm_event) {
- Pm_Enqueue (_input_queue, &nested_pm_event);
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] : Pm_Enqueue (_input_queue, nested_pm_event)" << std::endl;
+ while (Pm_Poll (_input_pm_stream) > 0) {
+
+ PmEvent pm_event; // just one message at a time
+ int result = Pm_Read (_input_pm_stream, &pm_event, 1);
+
+ if (result < 0) {
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("Pm_Read failed for (): [%1]\n", name()));
+ break;
+ }
+
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_read_midi (): [%1] evt-tm: %2\n", name(), pm_event.timestamp));
+
+ if (_incomplete_waves_midi_event == NULL ) {
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_read_midi (): [%1] new incomplete_waves_midi_event\n", name()));
+ _incomplete_waves_midi_event = new WavesMidiEvent (pm_event.timestamp);
+ }
+
+ WavesMidiEvent *nested_pm_event = _incomplete_waves_midi_event->append_data (pm_event);
+
+ if (nested_pm_event) {
+ Pm_Enqueue (_input_queue, &nested_pm_event);
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_read_midi (): [%1] : Pm_Enqueue (_input_queue, nested_pm_event)\n", name()));
+ }
+
+ switch ( _incomplete_waves_midi_event->state ()) {
+ case WavesMidiEvent::BROKEN:
+ delete _incomplete_waves_midi_event;
+ _incomplete_waves_midi_event = NULL;
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_read_midi (): [%1] : case WavesMidiEvent::BROKEN:\n", name()));
+ break;
+ case WavesMidiEvent::COMPLETE:
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_read_midi (): [%1] : Pm_Enqueue (_input_queue, _incomplete_waves_midi_event); %3\n", name (), _incomplete_waves_midi_event));
+
+ if (pmNoError != Pm_Enqueue (_input_queue, &_incomplete_waves_midi_event) ) {
+ char* err_msg = new char[256];
+ Pm_GetHostErrorText(err_msg, 256);
+ std::cerr << "WavesMidiDevice::read_midi (): Pm_Enqueue () failed for [" << name () << "]!" << std::endl;
+ std::cerr << "Error: " << err_msg << std::endl;
+ }
+
+ _incomplete_waves_midi_event = NULL;
+ break;
+ default:
+ break;
+ }
}
- switch ( _incomplete_waves_midi_event->state ()) {
- case WavesMidiEvent::BROKEN:
- delete _incomplete_waves_midi_event;
- _incomplete_waves_midi_event = NULL;
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] : case WavesMidiEvent::BROKEN:" << std::endl;
- break;
- case WavesMidiEvent::COMPLETE:
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] : Pm_Enqueue (_input_queue, _incomplete_waves_midi_event); " << std::hex << (void*)_incomplete_waves_midi_event << std::dec << std::endl;
- Pm_Enqueue (_input_queue, &_incomplete_waves_midi_event);
- _incomplete_waves_midi_event = NULL;
- break;
- default:
- break;
- }
- }
}
-
void
WavesMidiDevice::write_midi ()
{
- if (NULL == _output_pm_stream) {
- return;
- }
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_write_midi (): " << _pm_device_id << "-[" << name () << "]" << std::endl;
-
- PmError err;
- WavesMidiEvent *waves_midi_event;
-
- while (1 == Pm_Dequeue (_output_queue, &waves_midi_event)) {
- if (waves_midi_event->sysex ()) {
- // LATENCY compensation
- err = Pm_WriteSysEx (_output_pm_stream, waves_midi_event->timestamp () - LATENCY, waves_midi_event->data ());
- if (0 > err) {
- std::cout << "WavesMidiDevice::write_event_to_device (): [" << name () << "] Pm_WriteSysEx () failed (" << err << ")!" << std::endl;
- };
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_write_midi (): SYSEX used, ev->tm:" << waves_midi_event->timestamp () - LATENCY << std::endl;
+ if (NULL == _output_pm_stream) {
+ return;
}
- else
- {
- err = Pm_WriteShort (_output_pm_stream, waves_midi_event->timestamp () - LATENCY, * (PmMessage*)waves_midi_event->data ());
- if (0 > err) {
- std::cout << "WavesMidiDevice::write_event_to_device (): [" << name () << "] Pm_WriteShort () failed (" << err << ")!" << std::endl;
- }
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_write_midi (): SHORTMSG used, ev->tm:" << waves_midi_event->timestamp () - LATENCY << std::endl;
+
+ PmError err;
+ WavesMidiEvent *waves_midi_event;
+
+ while (1 == Pm_Dequeue (_output_queue, &waves_midi_event)) {
+ if (waves_midi_event->sysex ()) {
+ // LATENCY compensation
+ err = Pm_WriteSysEx (_output_pm_stream, waves_midi_event->timestamp () - LATENCY, waves_midi_event->data ());
+ if (0 > err) {
+ std::cerr << "WavesMidiDevice::write_event_to_device (): [" << name () << "] Pm_WriteSysEx () failed (" << err << ")!" << std::endl;
+ };
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_write_midi (): SYSEX used, ev->tm: %1", waves_midi_event->timestamp () - LATENCY));
+ }
+ else
+ {
+ err = Pm_WriteShort (_output_pm_stream, waves_midi_event->timestamp () - LATENCY, * (PmMessage*)waves_midi_event->data ());
+ if (0 > err) {
+ error << "WavesMidiDevice::write_event_to_device (): [" << name () << "] Pm_WriteShort () failed (" << err << ")!" << endmsg;
+ }
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_write_midi (): SHORTMSG used, ev->tm: %1\n", waves_midi_event->timestamp () - LATENCY));
+ }
}
- }
- return;
-}
+ return;
+}
+
int
WavesMidiDevice::enqueue_output_waves_midi_event (const WavesMidiEvent* waves_midi_event)
{
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::enqueue_output_waves_midi_event (): " << _pm_device_id << "-[" << name () << "]" << std::endl;
-
- if (waves_midi_event == NULL) {
- std::cerr << "WavesMidiDevice::put_event_to_callback (): 'waves_midi_event' is NULL!" << std::endl;
- return -1;
- }
-
- PmError err = Pm_Enqueue (_output_queue, &waves_midi_event);
-
- if (0 > err) {
- std::cerr << "WavesMidiDevice::put_event_to_callback (): Pm_Enqueue () failed (" << err << ")!" << std::endl;
- return -1;
- };
-
- return 0;
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::enqueue_output_waves_midi_event () [%1]\n", name()));
+
+ if (waves_midi_event == NULL) {
+ error << "WavesMidiDevice::put_event_to_callback (): 'waves_midi_event' is NULL!" << endmsg;
+ return -1;
+ }
+
+ PmError err = Pm_Enqueue (_output_queue, &waves_midi_event);
+
+ if (0 > err) {
+ error << "WavesMidiDevice::put_event_to_callback (): Pm_Enqueue () failed (" << err << ")!" << endmsg;
+ return -1;
+ };
+
+ return 0;
}
WavesMidiEvent*
WavesMidiDevice::dequeue_input_waves_midi_event ()
{
- WavesMidiEvent* waves_midi_event;
- if (Pm_Dequeue (_input_queue, &waves_midi_event) == 1) {
- return waves_midi_event;
- }
- return NULL;
+ WavesMidiEvent* waves_midi_event;
+ if (Pm_Dequeue (_input_queue, &waves_midi_event) == 1) {
+ return waves_midi_event;
+ }
+ return NULL;
}
-
diff --git a/libs/backends/wavesaudio/waves_midi_device_manager.cc b/libs/backends/wavesaudio/waves_midi_device_manager.cc
index dcc5fa0f03..317f1ec257 100644
--- a/libs/backends/wavesaudio/waves_midi_device_manager.cc
+++ b/libs/backends/wavesaudio/waves_midi_device_manager.cc
@@ -195,7 +195,17 @@ WavesMidiDeviceManager::_create_devices ()
for (int i = 0; i < count; i++) {
const PmDeviceInfo* pm_device_info = Pm_GetDeviceInfo (i);
-
+ // COMMENTED DBG LOGS */ std::cout << " interf : " << pm_device_info->interf << std::endl;
+ // COMMENTED DBG LOGS */ std::cout << " name : " << pm_device_info->name << std::endl;
+ // COMMENTED DBG LOGS */ std::cout << " input : " << pm_device_info->input << std::endl;
+ // COMMENTED DBG LOGS */ std::cout << " output : " << pm_device_info->output << std::endl;
+ // COMMENTED DBG LOGS */ std::cout << " opened : " << pm_device_info->opened << std::endl;
+#if defined (PLATFORM_WINDOWS)
+ if (strncmp (pm_device_info->name, "Microsoft", strlen ("Microsoft")) == 0) {
+ // COMMENTED DBG LOGS */ std::cout << " skipping anything from Microsoft :" << pm_device_info->name << std::endl;
+ continue;
+ }
+#endif
if (pm_device_info == NULL) {
std::cerr << "WavesMidiDeviceManager::_create_devices (): Pm_GetDeviceInfo (" << i << ") failed!" << std::endl;
continue;
diff --git a/libs/backends/wavesaudio/waves_midi_event.cc b/libs/backends/wavesaudio/waves_midi_event.cc
index 7960cb4871..0afe168c92 100644
--- a/libs/backends/wavesaudio/waves_midi_event.cc
+++ b/libs/backends/wavesaudio/waves_midi_event.cc
@@ -16,10 +16,15 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+
+#include "pbd/debug.h"
+#include "pbd/compose.h"
+
#include "memory.h"
#include "waves_midi_event.h"
using namespace ARDOUR;
+using namespace PBD;
WavesMidiEvent::WavesMidiEvent (PmTimestamp timestamp)
: _size (0)
@@ -37,13 +42,27 @@ WavesMidiEvent::WavesMidiEvent (PmTimestamp timestamp, const uint8_t* data, size
, _data (data && datalen ? new uint8_t[ (datalen < sizeof (PmMessage)) ? sizeof (PmMessage) : datalen] : NULL)
, _state (data && datalen ? COMPLETE : BROKEN)
{
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source) : Size=" << _size << "---" << datalen << std::endl;
- if (_state == COMPLETE) {
- // COMMENTED DBG LOGS */ std::cout << "\t\t\t Allocated Size=" << ((datalen < sizeof (PmMessage)) ? sizeof (PmMessage) : datalen) << std::endl;
- memcpy (_data, data, datalen);
- }
-}
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source) : Size=%1---%2\n", _size, datalen));
+ if (_state == COMPLETE) {
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "\t\t\t Allocated Size=%1\n", ((datalen < sizeof (PmMessage)) ? sizeof (PmMessage) : datalen)));
+ memcpy (_data, data, datalen);
+
+#ifndef NDEBUG
+ if (DEBUG::WavesMIDI & PBD::debug_bits) {
+ DEBUG_STR_DECL(a);
+ for (size_t i=0; i < datalen; ++i) {
+ DEBUG_STR_APPEND(a,std::hex);
+ DEBUG_STR_APPEND(a,"0x");
+ DEBUG_STR_APPEND(a,(int)data[i]);
+ DEBUG_STR_APPEND(a,' ');
+ }
+ DEBUG_STR_APPEND(a,'\n');
+ DEBUG_TRACE (DEBUG::WavesMIDI, DEBUG_STR(a).str());
+ }
+#endif
+ }
+}
WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source)
: _size (source.size ())
@@ -51,11 +70,25 @@ WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source)
, _data ((source.size () && source.const_data ()) ? new uint8_t[ (source.size () < sizeof (PmMessage)) ? sizeof (PmMessage) : source.size ()] : NULL)
, _state (source.state () )
{
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source) : Size=" << _size << "---" << source.size () << std::endl;
- // COMMENTED DBG LOGS */ std::cout << "\t\t\t Allocated Size=" << ((source.size () < sizeof (PmMessage)) ? sizeof (PmMessage) : source.size ()) << std::endl;
- if (_data && source.const_data ()) {
- memcpy (_data, source.const_data (), source.size ());
- }
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source) : Size=%1---%2\n", _size, source.size ()));
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "\t\t\t Allocated Size=%1\n", ((source.size () < sizeof (PmMessage)) ? sizeof (PmMessage) : source.size ())));
+ if (_data && source.const_data ()) {
+ memcpy (_data, source.const_data (), source.size ());
+
+#ifndef NDEBUG
+ if (DEBUG::WavesMIDI & PBD::debug_bits) {
+ DEBUG_STR_DECL(a);
+ for (size_t i=0; i < source.size(); ++i) {
+ DEBUG_STR_APPEND(a,std::hex);
+ DEBUG_STR_APPEND(a,"0x");
+ DEBUG_STR_APPEND(a,(int)source.const_data()[i]);
+ DEBUG_STR_APPEND(a,' ');
+ }
+ DEBUG_STR_APPEND(a,'\n');
+ DEBUG_TRACE (DEBUG::WavesMIDI, DEBUG_STR(a).str());
+ }
+#endif
+ }
}
@@ -67,74 +100,78 @@ WavesMidiEvent::~WavesMidiEvent ()
WavesMidiEvent *WavesMidiEvent::append_data (const PmEvent &midi_event)
{
- switch ( _state ) {
+ switch ( _state ) {
case INCOMPLETE:
- break;
- default:
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiEvent::append_data (): NO case INCOMPLETE" << std::endl;
- _state = BROKEN;
- return NULL;
- }
-
- size_t message_size = _midi_message_size (midi_event.message);
- uint8_t message_status = Pm_MessageStatus (midi_event.message);
-
- if (_data == NULL) { // This is a first event to add
- bool sysex = (message_status == SYSEX);
- _data = new unsigned char [sysex ? PM_DEFAULT_SYSEX_BUFFER_SIZE : sizeof (PmMessage)];
- if (!sysex)
- {
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiEvent::append_data (): SHORT MSG" << std::endl;
- * (PmMessage*)_data = 0;
- switch (message_size) {
- case 1:
- case 3:
- _size = message_size;
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiEvent::append_data (): size = " << _size << std::endl;
break;
- default:
- // COMMENTED DBG LOGS */ std::cout << "WavesMidiEvent::append_data (): WRONG MESSAGE SIZE (" << message_size << ") in the message: ";
- // COMMENTED DBG LOGS */ std::cout << std::hex << (int) ((unsigned char*)&midi_event)[0] << " " << (int) ((unsigned char*)&midi_event)[1] << " " << (int) ((unsigned char*)&midi_event)[2] << " " << (int) ((unsigned char*)&midi_event)[3] << std::dec << std::endl;
- _state = BROKEN;
+ default:
+ DEBUG_TRACE (DEBUG::WavesMIDI, "WavesMidiEvent::append_data (): NO case INCOMPLETE\n");
+ _state = BROKEN;
return NULL;
- }
- // COMMENTED DBG LOGS */ std::cout << "\t size = " << _size << std::endl;
- memcpy (_data, &midi_event.message, _size);
- // COMMENTED DBG LOGS */ std::cout << "\t\t size = " << _size << std::endl;
- _state = COMPLETE;
- // COMMENTED DBG LOGS */ std::cout << "\t\t\t size = " << _size << std::endl;
- return NULL;
}
- }
-
- // Now let's parse to sysex msg
- if (message_status >= REAL_TIME_FIRST) { // Nested Real Time MIDI event
- WavesMidiEvent *waves_midi_message = new WavesMidiEvent (midi_event.timestamp);
- waves_midi_message->append_data (midi_event);
- return waves_midi_message;
- }
-
- if (message_status >= STATUS_FIRST && (message_status != EOX) && _size) { // Certainly it's a broken SYSEX case
- WavesMidiEvent *waves_midi_message = new WavesMidiEvent (midi_event.timestamp);
- waves_midi_message->append_data (midi_event);
- return waves_midi_message;
- }
+
+ size_t message_size = _midi_message_size (midi_event.message);
+ uint8_t message_status = Pm_MessageStatus (midi_event.message);
+
+ if (_data == NULL) { // This is a first event to add
+ bool sysex = (message_status == SYSEX);
+ _data = new unsigned char [sysex ? PM_DEFAULT_SYSEX_BUFFER_SIZE : sizeof (PmMessage)];
+ if (!sysex)
+ {
+ DEBUG_TRACE (DEBUG::WavesMIDI, "WavesMidiEvent::append_data (): SHORT MSG\n");
+ * (PmMessage*)_data = 0;
+ switch (message_size) {
+ case 1:
+ case 2:
+ case 3:
+ _size = message_size;
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "WavesMidiEvent::append_data (): size = %1\n", _size));
+ break;
+ default:
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "WavesMidiEvent::append_data (): WRONG MESSAGE SIZE (%1 not %2) %3 [%4 %5 %6 %7] %8\n",
+ message_size,
+ std::hex,
+ (int) ((unsigned char*)&midi_event)[0],
+ (int) ((unsigned char*)&midi_event)[1],
+ (int) ((unsigned char*)&midi_event)[2],
+ (int) ((unsigned char*)&midi_event)[3],
+ std::dec));
+ _state = BROKEN;
+ return NULL;
+ }
+ memcpy (_data, &midi_event.message, _size);
+ _state = COMPLETE;
+ DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "\t\t\t size = %1\n", _size));
+ return NULL;
+ }
+ }
+
+ // Now let's parse to sysex msg
+ if (message_status >= REAL_TIME_FIRST) { // Nested Real Time MIDI event
+ WavesMidiEvent *waves_midi_message = new WavesMidiEvent (midi_event.timestamp);
+ waves_midi_message->append_data (midi_event);
+ return waves_midi_message;
+ }
+
+ if (message_status >= STATUS_FIRST && (message_status != EOX) && _size) { // Certainly it's a broken SYSEX case
+ WavesMidiEvent *waves_midi_message = new WavesMidiEvent (midi_event.timestamp);
+ waves_midi_message->append_data (midi_event);
+ return waves_midi_message;
+ }
- const uint8_t* source_data ((uint8_t*)&midi_event.message);
-
- for (size_t i = 0; i < sizeof (midi_event.message); ++i) {
- _data[_size] = source_data[i];
- _size++;
+ const uint8_t* source_data ((uint8_t*)&midi_event.message);
- if (source_data[i] == EOX) { // Ended SYSEX message
- _state = COMPLETE;
- return NULL;
+ for (size_t i = 0; i < sizeof (midi_event.message); ++i) {
+ _data[_size] = source_data[i];
+ _size++;
+
+ if (source_data[i] == EOX) { // Ended SYSEX message
+ _state = COMPLETE;
+ return NULL;
+ }
}
- }
- return NULL;
+ return NULL;
}
-
size_t WavesMidiEvent::_midi_message_size (PmMessage midi_message)
{
static int high_lengths[] = {
diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp
index ee8dba5028..1b18fc3cfa 100644
--- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp
+++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp
@@ -361,13 +361,14 @@ WTErr WCMRAudioDevice::ResetDevice ()
WTErr err = SetStreaming(false);
if (err == eNoErr)
- SetActive(false);
+ err = SetActive(false);
if (err == eNoErr && wasActive)
- SetActive(true);
+ err = SetActive(true);
- if (err == eNoErr && wasStreaming)
- SetStreaming(true);
+ if (err == eNoErr && wasStreaming) {
+ err = SetStreaming(true);
+ }
return err;
}
diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp
index 8cfa096c2a..9c97e6181a 100644
--- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp
+++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp
@@ -248,6 +248,9 @@ WTErr WCMRCoreAudioDevice::UpdateDeviceInfo ()
WTErr retVal = eNoErr;
+ // Some devices change the ID during restart
+ WTErr errId = UpdateDeviceId();
+
// Update all devices parts regardless of errors
WTErr errName = UpdateDeviceName();
WTErr errIn = UpdateDeviceInputs();
@@ -258,7 +261,7 @@ WTErr WCMRCoreAudioDevice::UpdateDeviceInfo ()
errSR = UpdateDeviceSampleRates();
errBS = UpdateDeviceBufferSizes();
- if(errName != eNoErr || errIn != eNoErr || errOut != eNoErr || errSR != eNoErr || errBS != eNoErr)
+ if(errId != eNoErr || errName != eNoErr || errIn != eNoErr || errOut != eNoErr || errSR != eNoErr || errBS != eNoErr)
{
retVal = eCoreAudioFailed;
}
@@ -266,6 +269,70 @@ WTErr WCMRCoreAudioDevice::UpdateDeviceInfo ()
return retVal;
}
+
+WTErr WCMRCoreAudioDevice::UpdateDeviceId()
+{
+ //Get device count...
+ UInt32 propSize = 0;
+ WTErr retVal = eNoErr;
+ OSStatus osErr = AudioHardwareGetPropertyInfo (kAudioHardwarePropertyDevices, &propSize, NULL);
+ ASSERT_ERROR(osErr, "AudioHardwareGetProperty 1");
+ if (WUIsError(osErr))
+ throw osErr;
+
+ size_t numDevices = propSize / sizeof (AudioDeviceID);
+ AudioDeviceID* deviceIDs = new AudioDeviceID[numDevices];
+
+ //retrieve the device IDs
+ propSize = numDevices * sizeof (AudioDeviceID);
+ osErr = AudioHardwareGetProperty (kAudioHardwarePropertyDevices, &propSize, deviceIDs);
+ ASSERT_ERROR(osErr, "Error while getting audio devices: AudioHardwareGetProperty 2");
+ if (WUIsError(osErr))
+ throw osErr;
+
+ //now add the ones that are not there...
+ for (size_t deviceIndex = 0; deviceIndex < numDevices; deviceIndex++)
+ {
+ DeviceInfo* pDevInfo = 0;
+
+ //Get device name and create new DeviceInfo entry
+ //Get property name size.
+ osErr = AudioDeviceGetPropertyInfo(deviceIDs[deviceIndex], 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL);
+ if (osErr == kAudioHardwareNoError)
+ {
+ //Get property: name.
+ char* deviceName = new char[propSize];
+ osErr = AudioDeviceGetProperty(deviceIDs[deviceIndex], 0, 0, kAudioDevicePropertyDeviceName, &propSize, deviceName);
+ if (osErr == kAudioHardwareNoError)
+ {
+ if ( (m_DeviceName == deviceName) &&
+ (m_DeviceID != deviceIDs[deviceIndex]) ) {
+
+ m_DeviceID = deviceIDs[deviceIndex];
+
+ m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Current device has changed it's id.");
+ }
+ }
+ else
+ {
+ retVal = eCoreAudioFailed;
+ DEBUG_MSG("Failed to get device name. Device ID: " << m_DeviceID);
+ }
+
+ delete [] deviceName;
+ }
+ else
+ {
+ retVal = eCoreAudioFailed;
+ DEBUG_MSG("Failed to get device name prop Info. Device ID: " << m_DeviceID);
+ }
+ }
+
+ delete [] deviceIDs;
+ return retVal;
+}
+
+
//**********************************************************************************************
// WCMRCoreAudioDevice::UpdateDeviceName
//
@@ -881,8 +948,6 @@ WTErr WCMRCoreAudioDevice::SetAndCheckCurrentSamplingRate (int newRate)
propSize = sizeof (Float64);
err = AudioDeviceSetProperty(m_DeviceID, NULL, 0, 0, kAudioDevicePropertyNominalSampleRate, propSize, &newNominalRate);
- m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Changed the Sampling Rate.");
-
if (err != kAudioHardwareNoError)
{
retVal = eCoreAudioFailed;
@@ -926,6 +991,8 @@ WTErr WCMRCoreAudioDevice::SetAndCheckCurrentSamplingRate (int newRate)
// If sample rate actually changed
if (tryAgain != 0)
{
+ m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Changed the Sampling Rate.");
+
// Update member with new rate
m_CurrentSamplingRate = newRate;
@@ -936,12 +1003,28 @@ WTErr WCMRCoreAudioDevice::SetAndCheckCurrentSamplingRate (int newRate)
// If sample rate did not change after time out
else
{
- // Update member with last read value
- m_CurrentSamplingRate = static_cast<int>(actualSamplingRate);
+ // Check if current device sample rate is supported
+ bool found = false;
+ for(int i = 0; gAllSampleRates[i] > 0; i++)
+ {
+ if (fabs(gAllSampleRates[i] - actualSamplingRate) < 0.01) {
+ found = true;
+ }
+ }
- char debugMsg[128];
- snprintf (debugMsg, sizeof(debugMsg), "Unable to change SR, even after waiting for %d milliseconds", actualWait * PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS);
- m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)debugMsg);
+ if (found) {
+ // Update member with last read value
+ m_CurrentSamplingRate = static_cast<int>(actualSamplingRate);
+
+ char debugMsg[128];
+ snprintf (debugMsg, sizeof(debugMsg), "Unable to change SR, even after waiting for %d milliseconds", actualWait * PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS);
+ m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)debugMsg);
+
+ float sample_rate_update = actualSamplingRate;
+ m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::SamplingRateChanged, (void *)&sample_rate_update);
+ } else {
+ retVal = eGenericErr;
+ }
}
}
@@ -1731,7 +1814,6 @@ WTErr WCMRCoreAudioDevice::TearDownAUHAL()
}
-
//**********************************************************************************************
// WCMRCoreAudioDevice::SetActive
//
@@ -1799,7 +1881,6 @@ WTErr WCMRCoreAudioDevice::SetActive (bool newState)
m_IgnoreThisDrop = true;
UpdateDeviceInfo();
-
}
m_IsActive = newState;
@@ -1909,6 +1990,9 @@ WTErr WCMRCoreAudioDevice::SetStreaming (bool newState)
m_IOProcThreadPort = 0;
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Starting AUHAL.");
+ // Prepare for streaming - tell Engine to do the initialization for process callback
+ m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming);
+
if (m_UseMultithreading)
{
//set thread constraints...
@@ -1924,6 +2008,7 @@ WTErr WCMRCoreAudioDevice::SetStreaming (bool newState)
if(err)
{
DEBUG_MSG( "Failed to start AudioUnit, err " << err );
+ m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Failed to start AudioUnit.");
retVal = eGenericErr;
goto Exit;
}
@@ -2554,7 +2639,7 @@ WTErr WCMRCoreAudioDeviceManager::getDeviceAvailableSampleRates(DeviceID deviceI
return retVal;
}
-
+
WTErr WCMRCoreAudioDeviceManager::getDeviceMaxInputChannels(DeviceID deviceId, unsigned int& inputChannels)
{
@@ -2876,6 +2961,15 @@ WTErr WCMRCoreAudioDeviceManager::updateDeviceListImpl()
NotifyClient (WCMRAudioDeviceManagerClient::IODeviceDisconnected);
return err;
}
+
+ WCMRCoreAudioDevice* current_device = dynamic_cast<WCMRCoreAudioDevice*>(m_CurrentDevice);
+
+ if ( current_device &&
+ (current_device->DeviceID() != devInfo.m_DeviceId ) )
+ {
+ NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
+ return err;
+ }
}
NotifyClient (WCMRAudioDeviceManagerClient::DeviceListChanged);
diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h
index a3269f63fb..cd4797a000 100644
--- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h
+++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h
@@ -138,6 +138,7 @@ protected:
#endif //WV_USE_TONE_GEN
WTErr UpdateDeviceInfo ();
+ WTErr UpdateDeviceId ();
WTErr UpdateDeviceName();
WTErr UpdateDeviceInputs();
WTErr UpdateDeviceOutputs();
diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp
index 7816fcb470..67c170d565 100644
--- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp
+++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp
@@ -901,6 +901,9 @@ void WCMRPortAudioDevice::startStreaming (bool callerIsWaiting/*=false*/)
unsigned int inChannelCount = pDeviceInfo->maxInputChannels;
unsigned int outChannelCount = pDeviceInfo->maxOutputChannels;
+ // Prepare for streaming - tell Engine to do the initialization for process callback
+ m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming);
+
paErr = Pa_StartStream( m_PortAudioStream );
if(paErr == paNoError)
@@ -1082,13 +1085,19 @@ long WCMRPortAudioDevice::ASIOMessageHook (long selector, long WCUNUSEDPARAM(val
case kAsioLatenciesChanged:
m_BufferSizeChangeRequested++;
std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- kAsioLatenciesChanged" << std::endl;
- m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
+ if (m_ResetRequested == 0) {
+ m_ResetRequested++;
+ m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
+ }
break;
case kAsioBufferSizeChange:
m_BufferSizeChangeRequested++;
std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- m_BufferSizeChangeRequested" << std::endl;
- m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
+ if (m_ResetRequested == 0) {
+ m_ResetRequested++;
+ m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
+ }
break;
case kAsioResetRequest:
@@ -1540,6 +1549,32 @@ WTErr WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(DeviceID deviceI
}
+WTErr WCMRPortAudioDeviceManager::getDeviceAvailableBufferSizes(DeviceID deviceId, std::vector<int>& buffers)
+{
+ WTErr retVal = eNoErr;
+
+ buffers.clear();
+
+ //make PA request to get actual device buffer sizes
+ long minSize, maxSize, preferredSize, granularity;
+
+ PaError paErr = PaAsio_GetAvailableBufferSizes(deviceId, &minSize, &maxSize, &preferredSize, &granularity);
+
+ //for Windows ASIO devices we always use prefferes buffer size ONLY
+ if (paNoError == paErr )
+ {
+ buffers.push_back(preferredSize);
+ }
+ else
+ {
+ retVal = eAsioFailed;
+ std::cout << "API::PortAudioDeviceManager::GetBufferSizes: error: " << Pa_GetErrorText (paErr) << " getting buffer sizes for device: "<< deviceId << std::endl;
+ }
+
+ return retVal;
+}
+
+
WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
{
std::cout << "API::PortAudioDeviceManager::Generating device list" << std::endl;
@@ -1586,6 +1621,7 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
DeviceInfo *pDevInfo = new DeviceInfo(thisDeviceID, pPaDeviceInfo->name);
if (pDevInfo)
{
+ //Get available sample rates
std::vector<int> availableSampleRates;
WTErr wErr = WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(thisDeviceID, availableSampleRates);
@@ -1600,6 +1636,19 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
pDevInfo->m_MaxInputChannels = pPaDeviceInfo->maxInputChannels;
pDevInfo->m_MaxOutputChannels = pPaDeviceInfo->maxOutputChannels;
+ //Get available buffer sizes
+ std::vector<int> availableBuffers;
+ wErr = getDeviceAvailableBufferSizes(thisDeviceID, availableBuffers);
+
+ if (wErr != eNoErr)
+ {
+ DEBUG_MSG ("Failed to get device available buffer sizes. Device ID: " << m_DeviceID);
+ delete pDevInfo;
+ continue; //proceed to the next device
+ }
+
+ pDevInfo->m_AvailableBufferSizes = availableBuffers;
+
//Now check if this device is acceptable according to current input/output settings
bool bRejectDevice = false;
switch(m_eAudioDeviceFilter)
@@ -1681,7 +1730,7 @@ WTErr WCMRPortAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & d
if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() )
{
- sampleRates.assign(m_CurrentDevice->SamplingRates().begin(), m_CurrentDevice->SamplingRates().end() );
+ sampleRates=m_CurrentDevice->SamplingRates();
return retVal;
}
@@ -1690,7 +1739,7 @@ WTErr WCMRPortAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & d
if (eNoErr == retVal)
{
- sampleRates.assign(devInfo.m_AvailableSampleRates.begin(), devInfo.m_AvailableSampleRates.end() );
+ sampleRates=devInfo.m_AvailableSampleRates;
}
else
{
@@ -1710,44 +1759,28 @@ WTErr WCMRPortAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & d
//first check if the request has been made for None device
if (deviceName == m_NoneDevice->DeviceName() )
{
- buffers.assign(m_NoneDevice->BufferSizes().begin(), m_NoneDevice->BufferSizes().end() );
+ buffers=m_NoneDevice->BufferSizes();
return retVal;
}
if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() )
{
- buffers.assign(m_CurrentDevice->BufferSizes().begin(), m_CurrentDevice->BufferSizes().end() );
+ buffers=m_CurrentDevice->BufferSizes();
return retVal;
}
- Pa_Initialize();
-
DeviceInfo devInfo;
retVal = GetDeviceInfoByName(deviceName, devInfo);
if (eNoErr == retVal)
{
- //make PA request to get actual device buffer sizes
- long minSize, maxSize, preferredSize, granularity;
- PaError paErr = PaAsio_GetAvailableBufferSizes(devInfo.m_DeviceId, &minSize, &maxSize, &preferredSize, &granularity);
-
- //for Windows ASIO devices we always use prefferes buffer size ONLY
- if (paNoError == paErr )
- {
- buffers.push_back(preferredSize);
- }
- else
- {
- retVal = eAsioFailed;
- std::cout << "API::PortAudioDeviceManager::GetBufferSizes: error: " << Pa_GetErrorText (paErr) << " getting buffer sizes for device: "<< deviceName << std::endl;
- }
+ std::cout << "API::PortAudioDeviceManager::GetBufferSizes: got buffer :"<< devInfo.m_AvailableBufferSizes.front() << std::endl;
+ buffers = devInfo.m_AvailableBufferSizes;
}
else
{
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: Device not found: "<< deviceName << std::endl;
}
- Pa_Terminate();
-
return retVal;
}
diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h
index 8f099ec9b5..da2027466e 100644
--- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h
+++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h
@@ -172,6 +172,7 @@ protected:
private:
// helper functions for this class only
WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates);
+ WTErr getDeviceAvailableBufferSizes(DeviceID deviceId, std::vector<int>& buffers);
WCMRAudioDevice* m_NoneDevice;
};