meld-driven unification of current ardour-ish WavesAudio backend and current tracks WavesAudio backend.

May be incomplete, and may not compile (testing to follow)
This commit is contained in:
Paul Davis 2015-05-13 19:11:27 -04:00
parent 0fca07fa9d
commit 237f255fb5
14 changed files with 490 additions and 253 deletions

View file

@ -99,8 +99,8 @@ void WavesAudioBackend::AudioDeviceManagerNotification (NotificationReason reaso
} }
WavesAudioBackend::WavesAudioBackend (AudioEngine& e) WavesAudioBackend::WavesAudioBackend (AudioEngine& e, AudioBackendInfo& info)
: AudioBackend (e, __backend_info) : AudioBackend (e, info)
, _audio_device_manager (this) , _audio_device_manager (this)
, _midi_device_manager (*this) , _midi_device_manager (*this)
, _device (NULL) , _device (NULL)
@ -420,6 +420,10 @@ WavesAudioBackend::set_sample_rate (float sample_rate)
return -1; return -1;
} }
// 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); _sample_rate_change(sample_rate);
if (device_needs_restart) { if (device_needs_restart) {
@ -499,8 +503,6 @@ WavesAudioBackend::reset_device ()
{ {
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_reset_device ():" << std::endl; // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_reset_device ():" << std::endl;
WTErr retVal = eNoErr;
if (!_device) { if (!_device) {
std::cerr << "WavesAudioBackend::set_buffer_size (): No device is set!" << std::endl; std::cerr << "WavesAudioBackend::set_buffer_size (): No device is set!" << std::endl;
return -1; return -1;
@ -829,11 +831,23 @@ WavesAudioBackend::freewheel (bool start_stop)
} }
_call_thread_init_callback = true; _call_thread_init_callback = true;
_freewheel_thread (); _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 { else {
_freewheel_thread_active = false; // stop _freewheel_thread () _freewheel_thread_active = false; // stop _freewheel_thread ()
engine.freewheel_callback (start_stop);
while (engine.freewheeling()) {
sleep(0);
}
_call_thread_init_callback = true; _call_thread_init_callback = true;
WTErr retval = _device->SetStreaming (true); WTErr retval = _device->SetStreaming (true);
if (retval != eNoErr) { if (retval != eNoErr) {
@ -873,6 +887,10 @@ WavesAudioBackend::_freewheel_thread ()
_freewheel_thread_active = true; _freewheel_thread_active = true;
if ((pthread_create (&thread_id, &attributes, __start_process_thread, thread_data))) { if ((pthread_create (&thread_id, &attributes, __start_process_thread, thread_data))) {
_freewheel_thread_active = false; _freewheel_thread_active = false;
// release invoking thread
engine.freewheel_callback(true);
std::cerr << "WavesAudioBackend::freewheel_thread (): pthread_create () failed!" << std::endl; std::cerr << "WavesAudioBackend::freewheel_thread (): pthread_create () failed!" << std::endl;
return; return;
} }
@ -881,6 +899,9 @@ WavesAudioBackend::_freewheel_thread ()
return; return;
} }
// notify angine that freewheeling is started
engine.freewheel_callback(true);
if (_call_thread_init_callback) { if (_call_thread_init_callback) {
_call_thread_init_callback = false; _call_thread_init_callback = false;
AudioEngine::thread_init_callback (this); AudioEngine::thread_init_callback (this);
@ -889,6 +910,10 @@ WavesAudioBackend::_freewheel_thread ()
while (_freewheel_thread_active) { while (_freewheel_thread_active) {
engine.process_callback (_buffer_size); 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; // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_freewheel_thread (): FINISHED" << std::endl;
return; return;
} }
@ -1238,7 +1263,7 @@ WavesAudioBackend::__waves_backend_factory (AudioEngine& e)
{ {
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__waves_backend_factory ():" << std::endl; // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__waves_backend_factory ():" << std::endl;
if (!__instance) { if (!__instance) {
__instance.reset (new WavesAudioBackend (e)); __instance.reset (new WavesAudioBackend (e, *(descriptor())));
} }
return __instance; return __instance;
} }
@ -1260,7 +1285,6 @@ WavesAudioBackend::__instantiate (const std::string& arg1, const std::string& ar
LARGE_INTEGER Frequency; LARGE_INTEGER Frequency;
QueryPerformanceFrequency(&Frequency); QueryPerformanceFrequency(&Frequency);
__performance_counter_frequency = Frequency.QuadPart; __performance_counter_frequency = Frequency.QuadPart;
std::cout << "__performance_counter_frequency:" << __performance_counter_frequency << std::endl;
#endif #endif
return 0; return 0;

View file

@ -70,7 +70,7 @@ class WavesMidiPort;
class WavesAudioBackend : public AudioBackend, WCMRAudioDeviceManagerClient class WavesAudioBackend : public AudioBackend, WCMRAudioDeviceManagerClient
{ {
public: public:
WavesAudioBackend (AudioEngine& e); WavesAudioBackend (AudioEngine& e, AudioBackendInfo&);
virtual ~WavesAudioBackend (); virtual ~WavesAudioBackend ();
/* AUDIOBACKEND API */ /* AUDIOBACKEND API */

View file

@ -18,13 +18,21 @@
*/ */
#include "waves_audioport.h" #include "waves_audioport.h"
#include "ardour/runtime_functions.h"
#include "pbd/malign.h"
using namespace ARDOUR; using namespace ARDOUR;
WavesAudioPort::WavesAudioPort (const std::string& port_name, PortFlags flags) WavesAudioPort::WavesAudioPort (const std::string& port_name, PortFlags flags)
: WavesDataPort (port_name, 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);
} }
@ -40,6 +48,7 @@ void* WavesAudioPort::get_buffer (pframes_t nframes)
* Base class WavesDataPort takes is supposed to provide enough consistentcy * Base class WavesDataPort takes is supposed to provide enough consistentcy
* of the connections. * of the connections.
*/ */
// get first buffer data // get first buffer data
// use optimized function to fill the buffer intialy // use optimized function to fill the buffer intialy
ARDOUR::copy_vector (_buffer, ((const WavesAudioPort*)*it)->const_buffer (), nframes); ARDOUR::copy_vector (_buffer, ((const WavesAudioPort*)*it)->const_buffer (), nframes);
@ -49,9 +58,9 @@ void* WavesAudioPort::get_buffer (pframes_t nframes)
for (; it != get_connections ().end (); ++it) { for (; it != get_connections ().end (); ++it) {
Sample* tgt = buffer (); Sample* tgt = buffer ();
const Sample* src = ((const WavesAudioPort*)*it)->const_buffer (); const Sample* src = ((const WavesAudioPort*)*it)->const_buffer ();
for (uint32_t frame = 0; frame < nframes; ++frame, ++tgt, ++src) {
*tgt += *src; // use otimized function to mix the buffers
} ARDOUR::mix_buffers_no_gain (tgt, src, nframes);
} }
} }
} }

View file

@ -35,7 +35,7 @@ public:
WavesAudioPort (const std::string& port_name, PortFlags flags); WavesAudioPort (const std::string& port_name, PortFlags flags);
virtual ~WavesAudioPort () { }; virtual ~WavesAudioPort ();
virtual DataType type () const { return DataType::AUDIO; }; virtual DataType type () const { return DataType::AUDIO; };
@ -49,7 +49,7 @@ protected:
private: private:
Sample _buffer[MAX_BUFFER_SIZE_SAMPLES]; Sample *_buffer;
}; };
} // namespace } // namespace

View file

@ -67,7 +67,7 @@ int WavesDataPort::connect (WavesDataPort *port)
} }
if (is_connected (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; return -1;
} }
@ -115,14 +115,22 @@ void WavesDataPort::_disconnect (WavesDataPort *port, bool api_call)
port->_disconnect (this, false); port->_disconnect (this, false);
} }
if (is_input() && _connections.empty()) if (is_input() && _connections.empty()) {
{
_wipe_buffer(); _wipe_buffer();
} }
} }
void WavesDataPort::disconnect_all () void WavesDataPort::disconnect_all ()
{
_disconnect_all ();
if (is_input()) {
_wipe_buffer();
}
}
void WavesDataPort::_disconnect_all ()
{ {
while (!_connections.empty ()) { while (!_connections.empty ()) {
_connections.back ()->_disconnect (this, false); _connections.back ()->_disconnect (this, false);
@ -130,7 +138,6 @@ void WavesDataPort::disconnect_all ()
} }
} }
bool WavesDataPort::is_physically_connected () const bool WavesDataPort::is_physically_connected () const
{ {
for (std::vector<WavesDataPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) { for (std::vector<WavesDataPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) {

View file

@ -106,6 +106,7 @@ private:
std::vector<WavesDataPort*> _connections; std::vector<WavesDataPort*> _connections;
void _connect (WavesDataPort* port, bool api_call); void _connect (WavesDataPort* port, bool api_call);
void _disconnect_all ();
void _disconnect (WavesDataPort* port, bool api_call); void _disconnect (WavesDataPort* port, bool api_call);
}; };

View file

@ -18,6 +18,12 @@
*/ */
#include <iostream> #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_device.h"
#include "waves_midi_event.h" #include "waves_midi_event.h"
@ -27,6 +33,7 @@
#define QUEUE_LENGTH 1024 #define QUEUE_LENGTH 1024
using namespace ARDOUR; using namespace ARDOUR;
using namespace PBD;
WavesMidiDevice::WavesMidiDevice (const std::string& device_name) WavesMidiDevice::WavesMidiDevice (const std::string& device_name)
: _pm_input_id (pmNoDevice) : _pm_input_id (pmNoDevice)
@ -61,13 +68,15 @@ WavesMidiDevice::WavesMidiDevice (const std::string& device_name)
WavesMidiDevice::~WavesMidiDevice () WavesMidiDevice::~WavesMidiDevice ()
{ {
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::~WavesMidiDevice ():" << name () << std::endl; DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::~WavesMidiDevice (): %1\n", name()));
close (); close ();
} }
int int
WavesMidiDevice::open (PmTimeProcPtr time_proc, void* time_info) WavesMidiDevice::open (PmTimeProcPtr time_proc, void* time_info)
{ {
DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::open (): %1", name ()));
if (is_input () ) { if (is_input () ) {
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::open (): INPUT" << _pm_input_id << "-[" << name () << "]" << std::endl; // COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::open (): INPUT" << _pm_input_id << "-[" << name () << "]" << std::endl;
@ -142,6 +151,7 @@ WavesMidiDevice::open (PmTimeProcPtr time_proc, void* time_info)
void void
WavesMidiDevice::close () WavesMidiDevice::close ()
{ {
DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::close (): %1\n", name ()));
WavesMidiEvent *waves_midi_event; WavesMidiEvent *waves_midi_event;
// save _input_pm_stream and _output_pm_stream to local buf // save _input_pm_stream and _output_pm_stream to local buf
@ -208,35 +218,46 @@ WavesMidiDevice::read_midi ()
return; return;
} }
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "]" << std::endl;
while (Pm_Poll (_input_pm_stream) > 0) { while (Pm_Poll (_input_pm_stream) > 0) {
PmEvent pm_event; // just one message at a time PmEvent pm_event; // just one message at a time
int result = Pm_Read (_input_pm_stream, &pm_event, 1); int result = Pm_Read (_input_pm_stream, &pm_event, 1);
if (result < 0) { if (result < 0) {
std::cerr << "WavesMidiDevice::_read_midi (): Pm_Read () failed (" << result << ") for [" << name () << "]!" << std::endl; DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("Pm_Read failed for (): [%1]\n", name()));
break; break;
} }
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] evt-tm:" << pm_event.timestamp << std::endl;
DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_read_midi (): [%1] evt-tm: %2\n", name(), pm_event.timestamp));
if (_incomplete_waves_midi_event == NULL ) { 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; 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); _incomplete_waves_midi_event = new WavesMidiEvent (pm_event.timestamp);
} }
WavesMidiEvent *nested_pm_event = _incomplete_waves_midi_event->append_data (pm_event); WavesMidiEvent *nested_pm_event = _incomplete_waves_midi_event->append_data (pm_event);
if (nested_pm_event) { if (nested_pm_event) {
Pm_Enqueue (_input_queue, &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; 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 ()) { switch ( _incomplete_waves_midi_event->state ()) {
case WavesMidiEvent::BROKEN: case WavesMidiEvent::BROKEN:
delete _incomplete_waves_midi_event; delete _incomplete_waves_midi_event;
_incomplete_waves_midi_event = NULL; _incomplete_waves_midi_event = NULL;
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] : case WavesMidiEvent::BROKEN:" << std::endl; DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_read_midi (): [%1] : case WavesMidiEvent::BROKEN:\n", name()));
break; break;
case WavesMidiEvent::COMPLETE: 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; 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));
Pm_Enqueue (_input_queue, &_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; _incomplete_waves_midi_event = NULL;
break; break;
default: default:
@ -245,14 +266,12 @@ WavesMidiDevice::read_midi ()
} }
} }
void void
WavesMidiDevice::write_midi () WavesMidiDevice::write_midi ()
{ {
if (NULL == _output_pm_stream) { if (NULL == _output_pm_stream) {
return; return;
} }
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_write_midi (): " << _pm_device_id << "-[" << name () << "]" << std::endl;
PmError err; PmError err;
WavesMidiEvent *waves_midi_event; WavesMidiEvent *waves_midi_event;
@ -262,36 +281,37 @@ WavesMidiDevice::write_midi ()
// LATENCY compensation // LATENCY compensation
err = Pm_WriteSysEx (_output_pm_stream, waves_midi_event->timestamp () - LATENCY, waves_midi_event->data ()); err = Pm_WriteSysEx (_output_pm_stream, waves_midi_event->timestamp () - LATENCY, waves_midi_event->data ());
if (0 > err) { if (0 > err) {
std::cout << "WavesMidiDevice::write_event_to_device (): [" << name () << "] Pm_WriteSysEx () failed (" << err << ")!" << std::endl; std::cerr << "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; DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_write_midi (): SYSEX used, ev->tm: %1", waves_midi_event->timestamp () - LATENCY));
} }
else else
{ {
err = Pm_WriteShort (_output_pm_stream, waves_midi_event->timestamp () - LATENCY, * (PmMessage*)waves_midi_event->data ()); err = Pm_WriteShort (_output_pm_stream, waves_midi_event->timestamp () - LATENCY, * (PmMessage*)waves_midi_event->data ());
if (0 > err) { if (0 > err) {
std::cout << "WavesMidiDevice::write_event_to_device (): [" << name () << "] Pm_WriteShort () failed (" << err << ")!" << std::endl; error << "WavesMidiDevice::write_event_to_device (): [" << name () << "] Pm_WriteShort () failed (" << err << ")!" << endmsg;
} }
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_write_midi (): SHORTMSG used, ev->tm:" << waves_midi_event->timestamp () - LATENCY << std::endl; DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_write_midi (): SHORTMSG used, ev->tm: %1\n", waves_midi_event->timestamp () - LATENCY));
} }
} }
return; return;
} }
int int
WavesMidiDevice::enqueue_output_waves_midi_event (const WavesMidiEvent* waves_midi_event) 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; DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::enqueue_output_waves_midi_event () [%1]\n", name()));
if (waves_midi_event == NULL) { if (waves_midi_event == NULL) {
std::cerr << "WavesMidiDevice::put_event_to_callback (): 'waves_midi_event' is NULL!" << std::endl; error << "WavesMidiDevice::put_event_to_callback (): 'waves_midi_event' is NULL!" << endmsg;
return -1; return -1;
} }
PmError err = Pm_Enqueue (_output_queue, &waves_midi_event); PmError err = Pm_Enqueue (_output_queue, &waves_midi_event);
if (0 > err) { if (0 > err) {
std::cerr << "WavesMidiDevice::put_event_to_callback (): Pm_Enqueue () failed (" << err << ")!" << std::endl; error << "WavesMidiDevice::put_event_to_callback (): Pm_Enqueue () failed (" << err << ")!" << endmsg;
return -1; return -1;
}; };
@ -307,4 +327,3 @@ WavesMidiDevice::dequeue_input_waves_midi_event ()
} }
return NULL; return NULL;
} }

View file

@ -195,7 +195,17 @@ WavesMidiDeviceManager::_create_devices ()
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
const PmDeviceInfo* pm_device_info = Pm_GetDeviceInfo (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) { if (pm_device_info == NULL) {
std::cerr << "WavesMidiDeviceManager::_create_devices (): Pm_GetDeviceInfo (" << i << ") failed!" << std::endl; std::cerr << "WavesMidiDeviceManager::_create_devices (): Pm_GetDeviceInfo (" << i << ") failed!" << std::endl;
continue; continue;

View file

@ -16,10 +16,15 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include "pbd/debug.h"
#include "pbd/compose.h"
#include "memory.h" #include "memory.h"
#include "waves_midi_event.h" #include "waves_midi_event.h"
using namespace ARDOUR; using namespace ARDOUR;
using namespace PBD;
WavesMidiEvent::WavesMidiEvent (PmTimestamp timestamp) WavesMidiEvent::WavesMidiEvent (PmTimestamp timestamp)
: _size (0) : _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) , _data (data && datalen ? new uint8_t[ (datalen < sizeof (PmMessage)) ? sizeof (PmMessage) : datalen] : NULL)
, _state (data && datalen ? COMPLETE : BROKEN) , _state (data && datalen ? COMPLETE : BROKEN)
{ {
// COMMENTED DBG LOGS */ std::cout << "WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source) : Size=" << _size << "---" << datalen << std::endl; DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source) : Size=%1---%2\n", _size, datalen));
if (_state == COMPLETE) { if (_state == COMPLETE) {
// COMMENTED DBG LOGS */ std::cout << "\t\t\t Allocated Size=" << ((datalen < sizeof (PmMessage)) ? sizeof (PmMessage) : datalen) << std::endl; DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "\t\t\t Allocated Size=%1\n", ((datalen < sizeof (PmMessage)) ? sizeof (PmMessage) : datalen)));
memcpy (_data, data, 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) WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source)
: _size (source.size ()) : _size (source.size ())
@ -51,10 +70,24 @@ WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source)
, _data ((source.size () && source.const_data ()) ? new uint8_t[ (source.size () < sizeof (PmMessage)) ? sizeof (PmMessage) : source.size ()] : NULL) , _data ((source.size () && source.const_data ()) ? new uint8_t[ (source.size () < sizeof (PmMessage)) ? sizeof (PmMessage) : source.size ()] : NULL)
, _state (source.state () ) , _state (source.state () )
{ {
// COMMENTED DBG LOGS */ std::cout << "WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source) : Size=" << _size << "---" << source.size () << std::endl; DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source) : Size=%1---%2\n", _size, source.size ()));
// COMMENTED DBG LOGS */ std::cout << "\t\t\t Allocated Size=" << ((source.size () < sizeof (PmMessage)) ? sizeof (PmMessage) : source.size ()) << std::endl; 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 ()) { if (_data && source.const_data ()) {
memcpy (_data, source.const_data (), source.size ()); 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
} }
} }
@ -71,7 +104,7 @@ WavesMidiEvent *WavesMidiEvent::append_data (const PmEvent &midi_event)
case INCOMPLETE: case INCOMPLETE:
break; break;
default: default:
// COMMENTED DBG LOGS */ std::cout << "WavesMidiEvent::append_data (): NO case INCOMPLETE" << std::endl; DEBUG_TRACE (DEBUG::WavesMIDI, "WavesMidiEvent::append_data (): NO case INCOMPLETE\n");
_state = BROKEN; _state = BROKEN;
return NULL; return NULL;
} }
@ -84,25 +117,30 @@ WavesMidiEvent *WavesMidiEvent::append_data (const PmEvent &midi_event)
_data = new unsigned char [sysex ? PM_DEFAULT_SYSEX_BUFFER_SIZE : sizeof (PmMessage)]; _data = new unsigned char [sysex ? PM_DEFAULT_SYSEX_BUFFER_SIZE : sizeof (PmMessage)];
if (!sysex) if (!sysex)
{ {
// COMMENTED DBG LOGS */ std::cout << "WavesMidiEvent::append_data (): SHORT MSG" << std::endl; DEBUG_TRACE (DEBUG::WavesMIDI, "WavesMidiEvent::append_data (): SHORT MSG\n");
* (PmMessage*)_data = 0; * (PmMessage*)_data = 0;
switch (message_size) { switch (message_size) {
case 1: case 1:
case 2:
case 3: case 3:
_size = message_size; _size = message_size;
// COMMENTED DBG LOGS */ std::cout << "WavesMidiEvent::append_data (): size = " << _size << std::endl; DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "WavesMidiEvent::append_data (): size = %1\n", _size));
break; break;
default: default:
// COMMENTED DBG LOGS */ std::cout << "WavesMidiEvent::append_data (): WRONG MESSAGE SIZE (" << message_size << ") in the message: "; DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "WavesMidiEvent::append_data (): WRONG MESSAGE SIZE (%1 not %2) %3 [%4 %5 %6 %7] %8\n",
// 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; 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; _state = BROKEN;
return NULL; return NULL;
} }
// COMMENTED DBG LOGS */ std::cout << "\t size = " << _size << std::endl;
memcpy (_data, &midi_event.message, _size); memcpy (_data, &midi_event.message, _size);
// COMMENTED DBG LOGS */ std::cout << "\t\t size = " << _size << std::endl;
_state = COMPLETE; _state = COMPLETE;
// COMMENTED DBG LOGS */ std::cout << "\t\t\t size = " << _size << std::endl; DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "\t\t\t size = %1\n", _size));
return NULL; return NULL;
} }
} }
@ -134,7 +172,6 @@ WavesMidiEvent *WavesMidiEvent::append_data (const PmEvent &midi_event)
return NULL; return NULL;
} }
size_t WavesMidiEvent::_midi_message_size (PmMessage midi_message) size_t WavesMidiEvent::_midi_message_size (PmMessage midi_message)
{ {
static int high_lengths[] = { static int high_lengths[] = {

View file

@ -361,13 +361,14 @@ WTErr WCMRAudioDevice::ResetDevice ()
WTErr err = SetStreaming(false); WTErr err = SetStreaming(false);
if (err == eNoErr) if (err == eNoErr)
SetActive(false); err = SetActive(false);
if (err == eNoErr && wasActive) if (err == eNoErr && wasActive)
SetActive(true); err = SetActive(true);
if (err == eNoErr && wasStreaming) if (err == eNoErr && wasStreaming) {
SetStreaming(true); err = SetStreaming(true);
}
return err; return err;
} }

View file

@ -248,6 +248,9 @@ WTErr WCMRCoreAudioDevice::UpdateDeviceInfo ()
WTErr retVal = eNoErr; WTErr retVal = eNoErr;
// Some devices change the ID during restart
WTErr errId = UpdateDeviceId();
// Update all devices parts regardless of errors // Update all devices parts regardless of errors
WTErr errName = UpdateDeviceName(); WTErr errName = UpdateDeviceName();
WTErr errIn = UpdateDeviceInputs(); WTErr errIn = UpdateDeviceInputs();
@ -258,7 +261,7 @@ WTErr WCMRCoreAudioDevice::UpdateDeviceInfo ()
errSR = UpdateDeviceSampleRates(); errSR = UpdateDeviceSampleRates();
errBS = UpdateDeviceBufferSizes(); 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; retVal = eCoreAudioFailed;
} }
@ -266,6 +269,70 @@ WTErr WCMRCoreAudioDevice::UpdateDeviceInfo ()
return retVal; 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 // WCMRCoreAudioDevice::UpdateDeviceName
// //
@ -881,8 +948,6 @@ WTErr WCMRCoreAudioDevice::SetAndCheckCurrentSamplingRate (int newRate)
propSize = sizeof (Float64); propSize = sizeof (Float64);
err = AudioDeviceSetProperty(m_DeviceID, NULL, 0, 0, kAudioDevicePropertyNominalSampleRate, propSize, &newNominalRate); err = AudioDeviceSetProperty(m_DeviceID, NULL, 0, 0, kAudioDevicePropertyNominalSampleRate, propSize, &newNominalRate);
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Changed the Sampling Rate.");
if (err != kAudioHardwareNoError) if (err != kAudioHardwareNoError)
{ {
retVal = eCoreAudioFailed; retVal = eCoreAudioFailed;
@ -926,6 +991,8 @@ WTErr WCMRCoreAudioDevice::SetAndCheckCurrentSamplingRate (int newRate)
// If sample rate actually changed // If sample rate actually changed
if (tryAgain != 0) if (tryAgain != 0)
{ {
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Changed the Sampling Rate.");
// Update member with new rate // Update member with new rate
m_CurrentSamplingRate = newRate; m_CurrentSamplingRate = newRate;
@ -936,12 +1003,28 @@ WTErr WCMRCoreAudioDevice::SetAndCheckCurrentSamplingRate (int newRate)
// If sample rate did not change after time out // If sample rate did not change after time out
else else
{ {
// 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;
}
}
if (found) {
// Update member with last read value // Update member with last read value
m_CurrentSamplingRate = static_cast<int>(actualSamplingRate); m_CurrentSamplingRate = static_cast<int>(actualSamplingRate);
char debugMsg[128]; char debugMsg[128];
snprintf (debugMsg, sizeof(debugMsg), "Unable to change SR, even after waiting for %d milliseconds", actualWait * PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS); 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); 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 // WCMRCoreAudioDevice::SetActive
// //
@ -1799,7 +1881,6 @@ WTErr WCMRCoreAudioDevice::SetActive (bool newState)
m_IgnoreThisDrop = true; m_IgnoreThisDrop = true;
UpdateDeviceInfo(); UpdateDeviceInfo();
} }
m_IsActive = newState; m_IsActive = newState;
@ -1909,6 +1990,9 @@ WTErr WCMRCoreAudioDevice::SetStreaming (bool newState)
m_IOProcThreadPort = 0; m_IOProcThreadPort = 0;
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Starting AUHAL."); 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) if (m_UseMultithreading)
{ {
//set thread constraints... //set thread constraints...
@ -1924,6 +2008,7 @@ WTErr WCMRCoreAudioDevice::SetStreaming (bool newState)
if(err) if(err)
{ {
DEBUG_MSG( "Failed to start AudioUnit, err " << err ); DEBUG_MSG( "Failed to start AudioUnit, err " << err );
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Failed to start AudioUnit.");
retVal = eGenericErr; retVal = eGenericErr;
goto Exit; goto Exit;
} }
@ -2876,6 +2961,15 @@ WTErr WCMRCoreAudioDeviceManager::updateDeviceListImpl()
NotifyClient (WCMRAudioDeviceManagerClient::IODeviceDisconnected); NotifyClient (WCMRAudioDeviceManagerClient::IODeviceDisconnected);
return err; 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); NotifyClient (WCMRAudioDeviceManagerClient::DeviceListChanged);

View file

@ -138,6 +138,7 @@ protected:
#endif //WV_USE_TONE_GEN #endif //WV_USE_TONE_GEN
WTErr UpdateDeviceInfo (); WTErr UpdateDeviceInfo ();
WTErr UpdateDeviceId ();
WTErr UpdateDeviceName(); WTErr UpdateDeviceName();
WTErr UpdateDeviceInputs(); WTErr UpdateDeviceInputs();
WTErr UpdateDeviceOutputs(); WTErr UpdateDeviceOutputs();

View file

@ -901,6 +901,9 @@ void WCMRPortAudioDevice::startStreaming (bool callerIsWaiting/*=false*/)
unsigned int inChannelCount = pDeviceInfo->maxInputChannels; unsigned int inChannelCount = pDeviceInfo->maxInputChannels;
unsigned int outChannelCount = pDeviceInfo->maxOutputChannels; 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 ); paErr = Pa_StartStream( m_PortAudioStream );
if(paErr == paNoError) if(paErr == paNoError)
@ -1082,13 +1085,19 @@ long WCMRPortAudioDevice::ASIOMessageHook (long selector, long WCUNUSEDPARAM(val
case kAsioLatenciesChanged: case kAsioLatenciesChanged:
m_BufferSizeChangeRequested++; m_BufferSizeChangeRequested++;
std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- kAsioLatenciesChanged" << std::endl; std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- kAsioLatenciesChanged" << std::endl;
if (m_ResetRequested == 0) {
m_ResetRequested++;
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset); m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
}
break; break;
case kAsioBufferSizeChange: case kAsioBufferSizeChange:
m_BufferSizeChangeRequested++; m_BufferSizeChangeRequested++;
std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- m_BufferSizeChangeRequested" << std::endl; std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- m_BufferSizeChangeRequested" << std::endl;
if (m_ResetRequested == 0) {
m_ResetRequested++;
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset); m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
}
break; break;
case kAsioResetRequest: 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() WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
{ {
std::cout << "API::PortAudioDeviceManager::Generating device list" << std::endl; std::cout << "API::PortAudioDeviceManager::Generating device list" << std::endl;
@ -1586,6 +1621,7 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
DeviceInfo *pDevInfo = new DeviceInfo(thisDeviceID, pPaDeviceInfo->name); DeviceInfo *pDevInfo = new DeviceInfo(thisDeviceID, pPaDeviceInfo->name);
if (pDevInfo) if (pDevInfo)
{ {
//Get available sample rates
std::vector<int> availableSampleRates; std::vector<int> availableSampleRates;
WTErr wErr = WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(thisDeviceID, availableSampleRates); WTErr wErr = WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(thisDeviceID, availableSampleRates);
@ -1600,6 +1636,19 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
pDevInfo->m_MaxInputChannels = pPaDeviceInfo->maxInputChannels; pDevInfo->m_MaxInputChannels = pPaDeviceInfo->maxInputChannels;
pDevInfo->m_MaxOutputChannels = pPaDeviceInfo->maxOutputChannels; 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 //Now check if this device is acceptable according to current input/output settings
bool bRejectDevice = false; bool bRejectDevice = false;
switch(m_eAudioDeviceFilter) switch(m_eAudioDeviceFilter)
@ -1681,7 +1730,7 @@ WTErr WCMRPortAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & d
if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() ) if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() )
{ {
sampleRates.assign(m_CurrentDevice->SamplingRates().begin(), m_CurrentDevice->SamplingRates().end() ); sampleRates=m_CurrentDevice->SamplingRates();
return retVal; return retVal;
} }
@ -1690,7 +1739,7 @@ WTErr WCMRPortAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & d
if (eNoErr == retVal) if (eNoErr == retVal)
{ {
sampleRates.assign(devInfo.m_AvailableSampleRates.begin(), devInfo.m_AvailableSampleRates.end() ); sampleRates=devInfo.m_AvailableSampleRates;
} }
else else
{ {
@ -1710,44 +1759,28 @@ WTErr WCMRPortAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & d
//first check if the request has been made for None device //first check if the request has been made for None device
if (deviceName == m_NoneDevice->DeviceName() ) if (deviceName == m_NoneDevice->DeviceName() )
{ {
buffers.assign(m_NoneDevice->BufferSizes().begin(), m_NoneDevice->BufferSizes().end() ); buffers=m_NoneDevice->BufferSizes();
return retVal; return retVal;
} }
if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() ) if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() )
{ {
buffers.assign(m_CurrentDevice->BufferSizes().begin(), m_CurrentDevice->BufferSizes().end() ); buffers=m_CurrentDevice->BufferSizes();
return retVal; return retVal;
} }
Pa_Initialize();
DeviceInfo devInfo; DeviceInfo devInfo;
retVal = GetDeviceInfoByName(deviceName, devInfo); retVal = GetDeviceInfoByName(deviceName, devInfo);
if (eNoErr == retVal) if (eNoErr == retVal)
{ {
//make PA request to get actual device buffer sizes std::cout << "API::PortAudioDeviceManager::GetBufferSizes: got buffer :"<< devInfo.m_AvailableBufferSizes.front() << std::endl;
long minSize, maxSize, preferredSize, granularity; buffers = devInfo.m_AvailableBufferSizes;
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;
}
} }
else else
{ {
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: Device not found: "<< deviceName << std::endl; std::cout << "API::PortAudioDeviceManager::GetBufferSizes: Device not found: "<< deviceName << std::endl;
} }
Pa_Terminate();
return retVal; return retVal;
} }

View file

@ -172,6 +172,7 @@ protected:
private: private:
// helper functions for this class only // helper functions for this class only
WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates); WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates);
WTErr getDeviceAvailableBufferSizes(DeviceID deviceId, std::vector<int>& buffers);
WCMRAudioDevice* m_NoneDevice; WCMRAudioDevice* m_NoneDevice;
}; };