From 8f3d17fdf8f240c23bbc917872231ee913309932 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Fri, 27 Feb 2015 21:07:17 +0100 Subject: [PATCH] [DEV] many internal change and add linker alsa flow --- airtaudio/Api.cpp | 102 ++++++++++++++++++------------------ airtaudio/Api.h | 11 ++-- airtaudio/Interface.cpp | 23 ++++++-- airtaudio/Interface.h | 3 +- airtaudio/StreamOptions.cpp | 45 ++++++++++++++++ airtaudio/StreamOptions.h | 5 +- airtaudio/api/Alsa.cpp | 99 ++++++++++++++++++++++++++++------ airtaudio/api/Alsa.h | 6 ++- airtaudio/api/Android.cpp | 2 +- airtaudio/api/Android.h | 2 +- airtaudio/api/Asio.cpp | 2 +- airtaudio/api/Asio.h | 2 +- airtaudio/api/Core.cpp | 5 +- airtaudio/api/Core.h | 2 +- airtaudio/api/CoreIos.h | 2 +- airtaudio/api/CoreIos.mm | 2 +- airtaudio/api/Ds.cpp | 9 ++-- airtaudio/api/Ds.h | 2 +- airtaudio/api/Dummy.cpp | 2 +- airtaudio/api/Dummy.h | 2 +- airtaudio/api/Jack.cpp | 6 +-- airtaudio/api/Jack.h | 2 +- airtaudio/api/Oss.cpp | 12 ++--- airtaudio/api/Oss.h | 2 +- airtaudio/api/Pulse.cpp | 2 +- airtaudio/api/Pulse.h | 2 +- airtaudio/status.cpp | 2 +- lutin_airtaudio.py | 1 + 28 files changed, 244 insertions(+), 113 deletions(-) create mode 100644 airtaudio/StreamOptions.cpp diff --git a/airtaudio/Api.cpp b/airtaudio/Api.cpp index 6e18429..d0ac6b6 100644 --- a/airtaudio/Api.cpp +++ b/airtaudio/Api.cpp @@ -62,49 +62,51 @@ enum airtaudio::error airtaudio::Api::startStream() { return airtaudio::error_none; } -enum airtaudio::error airtaudio::Api::openStream(airtaudio::StreamParameters *oParams, - airtaudio::StreamParameters *iParams, - enum audio::format format, - uint32_t sampleRate, - uint32_t *bufferFrames, - airtaudio::AirTAudioCallback callback, - airtaudio::StreamOptions *options) { +enum airtaudio::error airtaudio::Api::openStream(airtaudio::StreamParameters* _oParams, + airtaudio::StreamParameters* _iParams, + enum audio::format _format, + uint32_t _sampleRate, + uint32_t* _bufferFrames, + airtaudio::AirTAudioCallback _callback, + const airtaudio::StreamOptions& _options) { if (m_state != airtaudio::state_closed) { ATA_ERROR("a stream is already open!"); return airtaudio::error_invalidUse; } - if (oParams && oParams->nChannels < 1) { + if ( _oParams != nullptr + && _oParams->nChannels < 1) { ATA_ERROR("a non-nullptr output StreamParameters structure cannot have an nChannels value less than one."); return airtaudio::error_invalidUse; } - if (iParams && iParams->nChannels < 1) { + if ( _iParams != nullptr + && _iParams->nChannels < 1) { ATA_ERROR("a non-nullptr input StreamParameters structure cannot have an nChannels value less than one."); return airtaudio::error_invalidUse; } - if ( oParams == nullptr - && iParams == nullptr) { + if ( _oParams == nullptr + && _iParams == nullptr) { ATA_ERROR("input and output StreamParameters structures are both nullptr!"); return airtaudio::error_invalidUse; } - if (audio::getFormatBytes(format) == 0) { + if (audio::getFormatBytes(_format) == 0) { ATA_ERROR("'format' parameter value is undefined."); return airtaudio::error_invalidUse; } uint32_t nDevices = getDeviceCount(); uint32_t oChannels = 0; - if (oParams) { - oChannels = oParams->nChannels; - if ( oParams->deviceId >= nDevices - && oParams->deviceName == "") { + if (_oParams != nullptr) { + oChannels = _oParams->nChannels; + if ( _oParams->deviceId >= nDevices + && _oParams->deviceName == "") { ATA_ERROR("output device parameter value is invalid."); return airtaudio::error_invalidUse; } } uint32_t iChannels = 0; - if (iParams) { - iChannels = iParams->nChannels; - if ( iParams->deviceId >= nDevices - && iParams->deviceName == "") { + if (_iParams != nullptr) { + iChannels = _iParams->nChannels; + if ( _iParams->deviceId >= nDevices + && _iParams->deviceName == "") { ATA_ERROR("input device parameter value is invalid."); return airtaudio::error_invalidUse; } @@ -112,24 +114,24 @@ enum airtaudio::error airtaudio::Api::openStream(airtaudio::StreamParameters *oP clearStreamInfo(); bool result; if (oChannels > 0) { - if (oParams->deviceId == -1) { - result = probeDeviceOpenName(oParams->deviceName, + if (_oParams->deviceId == -1) { + result = probeDeviceOpenName(_oParams->deviceName, airtaudio::mode_output, oChannels, - oParams->firstChannel, - sampleRate, - format, - bufferFrames, - options); + _oParams->firstChannel, + _sampleRate, + _format, + _bufferFrames, + _options); } else { - result = probeDeviceOpen(oParams->deviceId, + result = probeDeviceOpen(_oParams->deviceId, airtaudio::mode_output, oChannels, - oParams->firstChannel, - sampleRate, - format, - bufferFrames, - options); + _oParams->firstChannel, + _sampleRate, + _format, + _bufferFrames, + _options); } if (result == false) { ATA_ERROR("system ERROR"); @@ -137,24 +139,24 @@ enum airtaudio::error airtaudio::Api::openStream(airtaudio::StreamParameters *oP } } if (iChannels > 0) { - if (iParams->deviceId == -1) { - result = probeDeviceOpenName(iParams->deviceName, + if (_iParams->deviceId == -1) { + result = probeDeviceOpenName(_iParams->deviceName, airtaudio::mode_input, iChannels, - iParams->firstChannel, - sampleRate, - format, - bufferFrames, - options); + _iParams->firstChannel, + _sampleRate, + _format, + _bufferFrames, + _options); } else { - result = probeDeviceOpen(iParams->deviceId, + result = probeDeviceOpen(_iParams->deviceId, airtaudio::mode_input, iChannels, - iParams->firstChannel, - sampleRate, - format, - bufferFrames, - options); + _iParams->firstChannel, + _sampleRate, + _format, + _bufferFrames, + _options); } if (result == false) { if (oChannels > 0) { @@ -164,10 +166,8 @@ enum airtaudio::error airtaudio::Api::openStream(airtaudio::StreamParameters *oP return airtaudio::error_systemError; } } - m_callback = callback; - if (options != nullptr) { - options->numberOfBuffers = m_nBuffers; - } + m_callback = _callback; + //_options.numberOfBuffers = m_nBuffers; m_state = airtaudio::state_stopped; return airtaudio::error_none; } @@ -195,7 +195,7 @@ bool airtaudio::Api::probeDeviceOpen(uint32_t /*device*/, uint32_t /*sampleRate*/, audio::format /*format*/, uint32_t * /*bufferSize*/, - airtaudio::StreamOptions * /*options*/) { + const airtaudio::StreamOptions& /*options*/) { // MUST be implemented in subclasses! return false; } diff --git a/airtaudio/Api.h b/airtaudio/Api.h index 2e87e25..86c14f8 100644 --- a/airtaudio/Api.h +++ b/airtaudio/Api.h @@ -68,7 +68,7 @@ namespace airtaudio { uint32_t _sampleRate, uint32_t* _nbChunk, airtaudio::AirTAudioCallback _callback, - airtaudio::StreamOptions* _options); + const airtaudio::StreamOptions& _options); virtual enum airtaudio::error closeStream(); virtual enum airtaudio::error startStream(); virtual enum airtaudio::error stopStream() = 0; @@ -123,7 +123,7 @@ namespace airtaudio { uint32_t _sampleRate, enum audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options); + const airtaudio::StreamOptions& _options); virtual bool probeDeviceOpenName(const std::string& _deviceName, airtaudio::mode _mode, uint32_t _channels, @@ -131,7 +131,7 @@ namespace airtaudio { uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options) { return false; } + const airtaudio::StreamOptions& _options) { return false; } /** * @brief Increment the stream time. */ @@ -163,6 +163,11 @@ namespace airtaudio { */ void setConvertInfo(enum airtaudio::mode _mode, uint32_t _firstChannel); + + public: + virtual bool isMasterOf(airtaudio::Api* _api) { + return false; + }; }; }; /** diff --git a/airtaudio/Interface.cpp b/airtaudio/Interface.cpp index bbd1878..3f32f06 100644 --- a/airtaudio/Interface.cpp +++ b/airtaudio/Interface.cpp @@ -149,7 +149,7 @@ enum airtaudio::error airtaudio::Interface::openStream(airtaudio::StreamParamete uint32_t _sampleRate, uint32_t* _bufferFrames, airtaudio::AirTAudioCallback _callback, - airtaudio::StreamOptions* _options) { + const airtaudio::StreamOptions& _options) { if (m_rtapi == nullptr) { return airtaudio::error_inputNull; } @@ -162,6 +162,23 @@ enum airtaudio::error airtaudio::Interface::openStream(airtaudio::StreamParamete _options); } - - +bool airtaudio::Interface::isMasterOf(airtaudio::Interface& _interface) { + if (m_rtapi == nullptr) { + ATA_ERROR("Current Master API is nullptr ..."); + return false; + } + if (_interface.m_rtapi == nullptr) { + ATA_ERROR("Current Slave API is nullptr ..."); + return false; + } + if (m_rtapi->getCurrentApi() != _interface.m_rtapi->getCurrentApi()) { + ATA_ERROR("Can not link 2 Interface with not the same Low level type (???)");//" << _interface.m_adac->getCurrentApi() << " != " << m_adac->getCurrentApi() << ")"); + return false; + } + if (m_rtapi->getCurrentApi() != airtaudio::type_alsa) { + ATA_ERROR("Link 2 device together work only if the interafec is ????");// << airtaudio::type_alsa << " not for " << m_rtapi->getCurrentApi()); + return false; + } + return m_rtapi->isMasterOf(_interface.m_rtapi); +} diff --git a/airtaudio/Interface.h b/airtaudio/Interface.h index de8ea98..f54d0b5 100644 --- a/airtaudio/Interface.h +++ b/airtaudio/Interface.h @@ -198,7 +198,7 @@ namespace airtaudio { uint32_t _sampleRate, uint32_t* _bufferFrames, airtaudio::AirTAudioCallback _callback, - airtaudio::StreamOptions *_options = nullptr); + const airtaudio::StreamOptions& _options = airtaudio::StreamOptions()); /** * @brief A function that closes a stream and frees any associated stream memory. @@ -308,6 +308,7 @@ namespace airtaudio { } return m_rtapi->getStreamSampleRate(); } + bool isMasterOf(airtaudio::Interface& _interface); protected: void openRtApi(enum airtaudio::type _api); }; diff --git a/airtaudio/StreamOptions.cpp b/airtaudio/StreamOptions.cpp new file mode 100644 index 0000000..bcc4ea5 --- /dev/null +++ b/airtaudio/StreamOptions.cpp @@ -0,0 +1,45 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2011, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + * @fork from RTAudio + */ + +#include +#include +#include + +static const char* listValue[] = { + "hardware", + "trigered", + "soft" +}; + +std::ostream& airtaudio::operator <<(std::ostream& _os, enum airtaudio::timestampMode _obj) { + _os << listValue[_obj]; + return _os; +} + +namespace etk { + template <> bool from_string(enum airtaudio::timestampMode& _variableRet, const std::string& _value) { + if (_value == "hardware") { + _variableRet = airtaudio::timestampMode_Hardware; + return true; + } + if (_value == "trigered") { + _variableRet = airtaudio::timestampMode_trigered; + return true; + } + if (_value == "soft") { + _variableRet = airtaudio::timestampMode_soft; + return true; + } + return false; + } + + template std::string to_string(const enum airtaudio::timestampMode& _variable) { + return listValue[_variable]; + } +} + + diff --git a/airtaudio/StreamOptions.h b/airtaudio/StreamOptions.h index e456ee6..7056879 100644 --- a/airtaudio/StreamOptions.h +++ b/airtaudio/StreamOptions.h @@ -8,13 +8,16 @@ #ifndef __AIRTAUDIO_STREAM_OPTION_H__ #define __AIRTAUDIO_STREAM_OPTION_H__ -namespace airtaudio { +#include +namespace airtaudio { enum timestampMode { timestampMode_Hardware, //!< enable harware timestamp timestampMode_trigered, //!< get harware triger time stamp and ingrement with duration timestampMode_soft, //!< Simulate all timestamp. }; + std::ostream& operator <<(std::ostream& _os, enum airtaudio::timestampMode _obj); + class StreamOptions { public: airtaudio::Flags flags; //!< A bit-mask of stream flags diff --git a/airtaudio/api/Alsa.cpp b/airtaudio/api/Alsa.cpp index da044ac..7b12264 100644 --- a/airtaudio/api/Alsa.cpp +++ b/airtaudio/api/Alsa.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #undef __class__ #define __class__ "api::Alsa" @@ -33,13 +34,13 @@ namespace airtaudio { bool runnable; std11::thread* thread; bool threadRunning; - bool isMonotonic; //!< the timestamp of the flow came from the harware. + enum timestampMode timeMode; //!< the timestamp of the flow came from the harware. AlsaPrivate() : synchronized(false), runnable(false), thread(nullptr), threadRunning(false), - isMonotonic(false) { + timeMode(timestampMode_soft) { handles[0] = nullptr; handles[1] = nullptr; xrun[0] = false; @@ -406,7 +407,7 @@ bool airtaudio::api::Alsa::probeDeviceOpen(uint32_t _device, uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options) { + const airtaudio::StreamOptions& _options) { // I'm not using the "plug" interface ... too much inconsistent behavior. unsigned nDevices = 0; int32_t result, subdevice, card; @@ -461,7 +462,7 @@ bool airtaudio::api::Alsa::probeDeviceOpenName(const std::string& _deviceName, uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options) { + const airtaudio::StreamOptions& _options) { // I'm not using the "plug" interface ... too much inconsistent behavior. unsigned nDevices = 0; int32_t result, subdevice, card; @@ -608,14 +609,12 @@ bool airtaudio::api::Alsa::probeDeviceOpenName(const std::string& _deviceName, *_bufferSize = periodSize; // Set the buffer number, which in ALSA is referred to as the "period". uint32_t periods = 0; - if ( _options != nullptr - && _options->flags.m_minimizeLatency == true) { + if (_options.flags.m_minimizeLatency == true) { periods = 2; } /* TODO : Chouse the number of low level buffer ... - if ( _options != nullptr - && _options->numberOfBuffers > 0) { - periods = _options->numberOfBuffers; + if (_options.numberOfBuffers > 0) { + periods = _options.numberOfBuffers; } */ if (periods < 2) { @@ -639,11 +638,16 @@ bool airtaudio::api::Alsa::probeDeviceOpenName(const std::string& _deviceName, m_bufferSize = *_bufferSize; // check if the hardware provide hardware clock : if (snd_pcm_hw_params_is_monotonic(hw_params) == 0) { - m_private->isMonotonic = false; - ATA_WARNING("ALSA Audio timestamp is NOT monotonic (Generate with the start timestamp)"); + ATA_INFO("ALSA Audio timestamp is NOT monotonic (Generate with the start timestamp)"); + if (_options.mode == timestampMode_Hardware) { + ATA_WARNING("Can not select Harware timeStamp ==> the IO is not monotonic ==> select "); + m_private->timeMode = timestampMode_trigered; + } else { + m_private->timeMode = _options.mode; + } } else { - m_private->isMonotonic = true; - ATA_DEBUG("ALSA Audio timestamp is monotonic (came from harware)"); + ATA_DEBUG("ALSA Audio timestamp is monotonic (can came from harware)"); + m_private->timeMode = _options.mode; } // Install the hardware configuration @@ -976,7 +980,7 @@ void airtaudio::api::Alsa::callbackEvent() { } std11::chrono::system_clock::time_point airtaudio::api::Alsa::getStreamTime() { - if (m_private->isMonotonic == true) { + if (m_private->timeMode == timestampMode_Hardware) { snd_pcm_status_t *status = nullptr; snd_pcm_status_alloca(&status); // get harware timestamp all the time: @@ -988,9 +992,6 @@ std11::chrono::system_clock::time_point airtaudio::api::Alsa::getStreamTime() { ATA_WARNING(" get time of the signal error ..."); return m_startTime + m_duration; } - // get start time: - //snd_pcm_status_get_trigger_tstamp(status, ×tamp); - //m_startTime = std11::chrono::system_clock::from_time_t(timestamp.tv_sec) + std11::chrono::microseconds(timestamp.tv_usec); #if 0 snd_timestamp_t timestamp; snd_pcm_status_get_tstamp(status, ×tamp); @@ -1013,7 +1014,28 @@ std11::chrono::system_clock::time_point airtaudio::api::Alsa::getStreamTime() { m_startTime -= timeDelay; } return m_startTime; + } else if (m_private->timeMode == timestampMode_trigered) { + if (m_startTime == std11::chrono::system_clock::time_point()) { + snd_pcm_status_t *status = nullptr; + snd_pcm_status_alloca(&status); + // get harware timestamp all the time: + if (m_private->handles[0] != nullptr) { + snd_pcm_status(m_private->handles[0], status); + } else if (m_private->handles[1] != nullptr) { + snd_pcm_status(m_private->handles[1], status); + } else { + ATA_WARNING(" get time of the signal error ..."); + return m_startTime + m_duration; + } + // get start time: + snd_timestamp_t timestamp; + snd_pcm_status_get_trigger_tstamp(status, ×tamp); + m_startTime = std11::chrono::system_clock::from_time_t(timestamp.tv_sec) + std11::chrono::microseconds(timestamp.tv_usec); + ATA_VERBOSE("snd_pcm_status_get_trigger_tstamp : " << m_startTime); + } + return m_startTime + m_duration; } else { + // softaware mode ... if (m_startTime == std11::chrono::system_clock::time_point()) { m_startTime = std11::chrono::system_clock::now(); std11::chrono::nanoseconds timeDelay(m_bufferSize*1000000000LL/int64_t(m_sampleRate)); @@ -1209,5 +1231,48 @@ unlock: } } +bool airtaudio::api::Alsa::isMasterOf(airtaudio::Api* _api) { + airtaudio::api::Alsa* slave = dynamic_cast(_api); + if (slave == nullptr) { + ATA_ERROR("NULL ptr API (not ALSA ...)"); + return false; + } + if (m_state == airtaudio::state_running) { + ATA_ERROR("The MASTER stream is already running! ==> can not synchronize ..."); + return false; + } + if (slave->m_state == airtaudio::state_running) { + ATA_ERROR("The SLAVE stream is already running! ==> can not synchronize ..."); + return false; + } + snd_pcm_t * master = nullptr; + if (m_private->handles[0] != nullptr) { + master = m_private->handles[0]; + } + if (m_private->handles[1] != nullptr) { + master = m_private->handles[1]; + } + if (master == nullptr) { + ATA_ERROR("No ALSA handles ..."); + return false; + } + ATA_INFO(" ==> plop"); + if (slave->m_private->handles[0] != nullptr) { + if (snd_pcm_link(master, slave->m_private->handles[0]) != 0) { + ATA_ERROR("Can not syncronize handle output"); + } else { + ATA_INFO(" -------------------- LINK 0 --------------------"); + } + } + if (slave->m_private->handles[1] != nullptr) { + if (snd_pcm_link(master, slave->m_private->handles[1]) != 0) { + ATA_ERROR("Can not syncronize handle input"); + } else { + ATA_INFO(" -------------------- LINK 1 --------------------"); + } + } + return true; +} + #endif diff --git a/airtaudio/api/Alsa.h b/airtaudio/api/Alsa.h index 5c88307..82bc3bf 100644 --- a/airtaudio/api/Alsa.h +++ b/airtaudio/api/Alsa.h @@ -55,7 +55,7 @@ namespace airtaudio { uint32_t _sampleRate, enum audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options); + const airtaudio::StreamOptions& _options); virtual bool probeDeviceOpenName(const std::string& _deviceName, airtaudio::mode _mode, @@ -64,8 +64,10 @@ namespace airtaudio { uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options); + const airtaudio::StreamOptions& _options); virtual std11::chrono::system_clock::time_point getStreamTime(); + public: + bool isMasterOf(airtaudio::Api* _api); }; }; }; diff --git a/airtaudio/api/Android.cpp b/airtaudio/api/Android.cpp index 6acb793..ae67545 100644 --- a/airtaudio/api/Android.cpp +++ b/airtaudio/api/Android.cpp @@ -153,7 +153,7 @@ bool airtaudio::api::Android::probeDeviceOpen(uint32_t _device, uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options) { + const airtaudio::StreamOptions& _options) { ATA_INFO("Probe : device=" << _device << " channels=" << _channels << " firstChannel=" << _firstChannel << " sampleRate=" << _sampleRate); if (_mode != airtaudio::mode_output) { ATA_ERROR("Can not start a device input or duplex for Android ..."); diff --git a/airtaudio/api/Android.h b/airtaudio/api/Android.h index 4f58d4f..8d27682 100644 --- a/airtaudio/api/Android.h +++ b/airtaudio/api/Android.h @@ -40,7 +40,7 @@ namespace airtaudio { uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options); + const airtaudio::StreamOptions& _options); private: void callBackEvent(void* _data, int32_t _frameRate); diff --git a/airtaudio/api/Asio.cpp b/airtaudio/api/Asio.cpp index 1b2109d..c6277b9 100644 --- a/airtaudio/api/Asio.cpp +++ b/airtaudio/api/Asio.cpp @@ -224,7 +224,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device, uint32_t _sampleRate, audio::format _format, uint32_t* _bufferSize, - airtaudio::StreamOptions *_options) { + const airtaudio::StreamOptions& _options) { // For ASIO, a duplex stream MUST use the same driver. if ( _mode == airtaudio::mode_input && m_mode == airtaudio::mode_output diff --git a/airtaudio/api/Asio.h b/airtaudio/api/Asio.h index 9dd2076..bc599c9 100644 --- a/airtaudio/api/Asio.h +++ b/airtaudio/api/Asio.h @@ -44,7 +44,7 @@ namespace airtaudio { uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options); + const airtaudio.::StreamOptions& _options); }; }; }; diff --git a/airtaudio/api/Core.cpp b/airtaudio/api/Core.cpp index 3142df4..fb02060 100644 --- a/airtaudio/api/Core.cpp +++ b/airtaudio/api/Core.cpp @@ -428,7 +428,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device, uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options) { + const airtaudio.::StreamOptions& _options) { // Get device ID uint32_t nDevices = getDeviceCount(); if (nDevices == 0) { @@ -569,8 +569,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device, } else if (bufferRange.mMaximum < *_bufferSize) { *_bufferSize = (uint64_t) bufferRange.mMaximum; } - if ( _options != nullptr - && _options->flags.m_minimizeLatency == true) { + if (_options.flags.m_minimizeLatency == true) { *_bufferSize = (uint64_t) bufferRange.mMinimum; } // Set the buffer size. For multiple streams, I'm assuming we only diff --git a/airtaudio/api/Core.h b/airtaudio/api/Core.h index 4ed1115..332fa90 100644 --- a/airtaudio/api/Core.h +++ b/airtaudio/api/Core.h @@ -53,7 +53,7 @@ namespace airtaudio { uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options); + const airtaudio.::StreamOptions& _options); static const char* getErrorCode(OSStatus _code); static OSStatus xrunListener(AudioObjectID _inDevice, uint32_t _nAddresses, diff --git a/airtaudio/api/CoreIos.h b/airtaudio/api/CoreIos.h index 6d0c80e..c8dd4af 100644 --- a/airtaudio/api/CoreIos.h +++ b/airtaudio/api/CoreIos.h @@ -41,7 +41,7 @@ namespace airtaudio { uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options); + const airtaudio.::StreamOptions& _options); public: void callBackEvent(void* _data, int32_t _frameRate); diff --git a/airtaudio/api/CoreIos.mm b/airtaudio/api/CoreIos.mm index ba55b71..2cc5907 100644 --- a/airtaudio/api/CoreIos.mm +++ b/airtaudio/api/CoreIos.mm @@ -182,7 +182,7 @@ bool airtaudio::api::CoreIos::probeDeviceOpen(uint32_t _device, uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options) { + const airtaudio.::StreamOptions& _options) { ATA_INFO("Probe : device=" << _device << " channels=" << _channels << " firstChannel=" << _firstChannel << " sampleRate=" << _sampleRate); if (_mode != airtaudio::mode_output) { ATA_ERROR("Can not start a device input or duplex for CoreIos ..."); diff --git a/airtaudio/api/Ds.cpp b/airtaudio/api/Ds.cpp index 33db3e7..1342053 100644 --- a/airtaudio/api/Ds.cpp +++ b/airtaudio/api/Ds.cpp @@ -361,7 +361,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device, uint32_t _sampleRate, enum audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options) { + const airtaudio.::StreamOptions& _options) { if (_channels + _firstChannel > 2) { ATA_ERROR("DirectSound does not support more than 2 channels per device."); return false; @@ -402,12 +402,9 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device, // low for capture, but it should work for playback. int32_t nBuffers = 0; /* - if (_options != nullptr) { - nBuffers = _options->numberOfBuffers; - } + nBuffers = _options.numberOfBuffers; */ - if ( _options!= nullptr - && _options->flags.m_minimizeLatency == true) { + if (_options.flags.m_minimizeLatency == true) { nBuffers = 2; } if (nBuffers < 2) { diff --git a/airtaudio/api/Ds.h b/airtaudio/api/Ds.h index ab39c28..094f5c8 100644 --- a/airtaudio/api/Ds.h +++ b/airtaudio/api/Ds.h @@ -47,7 +47,7 @@ namespace airtaudio { uint32_t _sampleRate, enum audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options); + const airtaudio.::StreamOptions& _options); }; }; }; diff --git a/airtaudio/api/Dummy.cpp b/airtaudio/api/Dummy.cpp index 4f474dc..674ab59 100644 --- a/airtaudio/api/Dummy.cpp +++ b/airtaudio/api/Dummy.cpp @@ -55,7 +55,7 @@ bool airtaudio::api::Dummy::probeDeviceOpen(uint32_t _device, uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options) { + const airtaudio::StreamOptions& _options) { return false; } diff --git a/airtaudio/api/Dummy.h b/airtaudio/api/Dummy.h index 03f3a62..077a20e 100644 --- a/airtaudio/api/Dummy.h +++ b/airtaudio/api/Dummy.h @@ -34,7 +34,7 @@ namespace airtaudio { uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options); + const airtaudio::StreamOptions& _options); }; }; }; diff --git a/airtaudio/api/Jack.cpp b/airtaudio/api/Jack.cpp index f8b3d8e..d5a1548 100644 --- a/airtaudio/api/Jack.cpp +++ b/airtaudio/api/Jack.cpp @@ -268,7 +268,7 @@ bool airtaudio::api::Jack::probeDeviceOpen(uint32_t _device, uint32_t _sampleRate, audio::format _format, uint32_t* _bufferSize, - airtaudio::StreamOptions* _options) { + const airtaudio.::StreamOptions& _options) { // Look for jack server and try to become a client (only do once per stream). jack_client_t *client = 0; if ( _mode == airtaudio::mode_output @@ -276,8 +276,8 @@ bool airtaudio::api::Jack::probeDeviceOpen(uint32_t _device, && m_mode != airtaudio::mode_output)) { jack_options_t jackoptions = (jack_options_t) (JackNoStartServer); //JackNullOption; jack_status_t *status = nullptr; - if (_options && !_options->streamName.empty()) { - client = jack_client_open(_options->streamName.c_str(), jackoptions, status); + if (!_options.streamName.empty()) { + client = jack_client_open(_options.streamName.c_str(), jackoptions, status); } else { client = jack_client_open("airtaudioJack", jackoptions, status); } diff --git a/airtaudio/api/Jack.h b/airtaudio/api/Jack.h index 539a1ff..34611c1 100644 --- a/airtaudio/api/Jack.h +++ b/airtaudio/api/Jack.h @@ -47,7 +47,7 @@ namespace airtaudio { uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options); + const airtaudio.::StreamOptions& _options); }; }; }; diff --git a/airtaudio/api/Oss.cpp b/airtaudio/api/Oss.cpp index 91b7b77..1f91613 100644 --- a/airtaudio/api/Oss.cpp +++ b/airtaudio/api/Oss.cpp @@ -187,7 +187,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device, uint32_t _sampleRate, rtaudio::format _format, uint32_t* _bufferSize, - rtaudio::StreamOptions* _options) { + const airtaudio.::StreamOptions& _options) { int32_t mixerfd = open("/dev/mixer", O_RDWR, 0); if (mixerfd == -1) { ATA_ERROR("error opening '/dev/mixer'."); @@ -257,8 +257,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device, } } // Set exclusive access if specified. - if ( _options != nullptr - && _options->flags & RTAUDIO_HOG_DEVICE) { + if (_options.flags & RTAUDIO_HOG_DEVICE) { flags |= O_EXCL; } // Try to open the device. @@ -400,11 +399,8 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device, ossBufferBytes = 16; } int32_t buffers = 0; - if (_options != nullptr) { - buffers = _options->numberOfBuffers; - } - if ( _options != nullptr - && _options->flags.m_minimizeLatency == true) { + buffers = _options.numberOfBuffers; + if (_options.flags.m_minimizeLatency == true) { buffers = 2; } if (buffers < 2) { diff --git a/airtaudio/api/Oss.h b/airtaudio/api/Oss.h index 1abacca..69e8fbe 100644 --- a/airtaudio/api/Oss.h +++ b/airtaudio/api/Oss.h @@ -40,7 +40,7 @@ namespace airtaudio { uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options); + const airtaudio.::StreamOptions& _options); }; }; }; diff --git a/airtaudio/api/Pulse.cpp b/airtaudio/api/Pulse.cpp index cc7f453..03b88ce 100644 --- a/airtaudio/api/Pulse.cpp +++ b/airtaudio/api/Pulse.cpp @@ -285,7 +285,7 @@ bool airtaudio::api::Pulse::probeDeviceOpen(uint32_t _device, uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options) { + const airtaudio.::StreamOptions& _options) { uint64_t bufferBytes = 0; pa_sample_spec ss; if (_device != 0) { diff --git a/airtaudio/api/Pulse.h b/airtaudio/api/Pulse.h index 42d85c2..70fec99 100644 --- a/airtaudio/api/Pulse.h +++ b/airtaudio/api/Pulse.h @@ -43,7 +43,7 @@ namespace airtaudio { uint32_t _sampleRate, audio::format _format, uint32_t *_bufferSize, - airtaudio::StreamOptions *_options); + const airtaudio.::StreamOptions& _options); }; }; }; diff --git a/airtaudio/status.cpp b/airtaudio/status.cpp index 82a9cb5..638716f 100644 --- a/airtaudio/status.cpp +++ b/airtaudio/status.cpp @@ -7,7 +7,7 @@ #include #include -const char* listValue[] = { +static const char* listValue[] = { "ok", "overflow", "underflow" diff --git a/lutin_airtaudio.py b/lutin_airtaudio.py index c809d9f..b867ab9 100644 --- a/lutin_airtaudio.py +++ b/lutin_airtaudio.py @@ -22,6 +22,7 @@ def create(target): 'airtaudio/Flags.cpp', 'airtaudio/Api.cpp', 'airtaudio/DeviceInfo.cpp', + 'airtaudio/StreamOptions.cpp', 'airtaudio/api/Dummy.cpp' ]) myModule.add_module_depend(['audio', 'etk'])