[DEV] many internal change and add linker alsa flow

This commit is contained in:
Edouard DUPIN 2015-02-27 21:07:17 +01:00
parent a5dbe5a607
commit 8f3d17fdf8
28 changed files with 244 additions and 113 deletions

View File

@ -62,49 +62,51 @@ enum airtaudio::error airtaudio::Api::startStream() {
return airtaudio::error_none; return airtaudio::error_none;
} }
enum airtaudio::error airtaudio::Api::openStream(airtaudio::StreamParameters *oParams, enum airtaudio::error airtaudio::Api::openStream(airtaudio::StreamParameters* _oParams,
airtaudio::StreamParameters *iParams, airtaudio::StreamParameters* _iParams,
enum audio::format format, enum audio::format _format,
uint32_t sampleRate, uint32_t _sampleRate,
uint32_t *bufferFrames, uint32_t* _bufferFrames,
airtaudio::AirTAudioCallback callback, airtaudio::AirTAudioCallback _callback,
airtaudio::StreamOptions *options) { const airtaudio::StreamOptions& _options) {
if (m_state != airtaudio::state_closed) { if (m_state != airtaudio::state_closed) {
ATA_ERROR("a stream is already open!"); ATA_ERROR("a stream is already open!");
return airtaudio::error_invalidUse; 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."); ATA_ERROR("a non-nullptr output StreamParameters structure cannot have an nChannels value less than one.");
return airtaudio::error_invalidUse; 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."); ATA_ERROR("a non-nullptr input StreamParameters structure cannot have an nChannels value less than one.");
return airtaudio::error_invalidUse; return airtaudio::error_invalidUse;
} }
if ( oParams == nullptr if ( _oParams == nullptr
&& iParams == nullptr) { && _iParams == nullptr) {
ATA_ERROR("input and output StreamParameters structures are both nullptr!"); ATA_ERROR("input and output StreamParameters structures are both nullptr!");
return airtaudio::error_invalidUse; return airtaudio::error_invalidUse;
} }
if (audio::getFormatBytes(format) == 0) { if (audio::getFormatBytes(_format) == 0) {
ATA_ERROR("'format' parameter value is undefined."); ATA_ERROR("'format' parameter value is undefined.");
return airtaudio::error_invalidUse; return airtaudio::error_invalidUse;
} }
uint32_t nDevices = getDeviceCount(); uint32_t nDevices = getDeviceCount();
uint32_t oChannels = 0; uint32_t oChannels = 0;
if (oParams) { if (_oParams != nullptr) {
oChannels = oParams->nChannels; oChannels = _oParams->nChannels;
if ( oParams->deviceId >= nDevices if ( _oParams->deviceId >= nDevices
&& oParams->deviceName == "") { && _oParams->deviceName == "") {
ATA_ERROR("output device parameter value is invalid."); ATA_ERROR("output device parameter value is invalid.");
return airtaudio::error_invalidUse; return airtaudio::error_invalidUse;
} }
} }
uint32_t iChannels = 0; uint32_t iChannels = 0;
if (iParams) { if (_iParams != nullptr) {
iChannels = iParams->nChannels; iChannels = _iParams->nChannels;
if ( iParams->deviceId >= nDevices if ( _iParams->deviceId >= nDevices
&& iParams->deviceName == "") { && _iParams->deviceName == "") {
ATA_ERROR("input device parameter value is invalid."); ATA_ERROR("input device parameter value is invalid.");
return airtaudio::error_invalidUse; return airtaudio::error_invalidUse;
} }
@ -112,24 +114,24 @@ enum airtaudio::error airtaudio::Api::openStream(airtaudio::StreamParameters *oP
clearStreamInfo(); clearStreamInfo();
bool result; bool result;
if (oChannels > 0) { if (oChannels > 0) {
if (oParams->deviceId == -1) { if (_oParams->deviceId == -1) {
result = probeDeviceOpenName(oParams->deviceName, result = probeDeviceOpenName(_oParams->deviceName,
airtaudio::mode_output, airtaudio::mode_output,
oChannels, oChannels,
oParams->firstChannel, _oParams->firstChannel,
sampleRate, _sampleRate,
format, _format,
bufferFrames, _bufferFrames,
options); _options);
} else { } else {
result = probeDeviceOpen(oParams->deviceId, result = probeDeviceOpen(_oParams->deviceId,
airtaudio::mode_output, airtaudio::mode_output,
oChannels, oChannels,
oParams->firstChannel, _oParams->firstChannel,
sampleRate, _sampleRate,
format, _format,
bufferFrames, _bufferFrames,
options); _options);
} }
if (result == false) { if (result == false) {
ATA_ERROR("system ERROR"); ATA_ERROR("system ERROR");
@ -137,24 +139,24 @@ enum airtaudio::error airtaudio::Api::openStream(airtaudio::StreamParameters *oP
} }
} }
if (iChannels > 0) { if (iChannels > 0) {
if (iParams->deviceId == -1) { if (_iParams->deviceId == -1) {
result = probeDeviceOpenName(iParams->deviceName, result = probeDeviceOpenName(_iParams->deviceName,
airtaudio::mode_input, airtaudio::mode_input,
iChannels, iChannels,
iParams->firstChannel, _iParams->firstChannel,
sampleRate, _sampleRate,
format, _format,
bufferFrames, _bufferFrames,
options); _options);
} else { } else {
result = probeDeviceOpen(iParams->deviceId, result = probeDeviceOpen(_iParams->deviceId,
airtaudio::mode_input, airtaudio::mode_input,
iChannels, iChannels,
iParams->firstChannel, _iParams->firstChannel,
sampleRate, _sampleRate,
format, _format,
bufferFrames, _bufferFrames,
options); _options);
} }
if (result == false) { if (result == false) {
if (oChannels > 0) { if (oChannels > 0) {
@ -164,10 +166,8 @@ enum airtaudio::error airtaudio::Api::openStream(airtaudio::StreamParameters *oP
return airtaudio::error_systemError; return airtaudio::error_systemError;
} }
} }
m_callback = callback; m_callback = _callback;
if (options != nullptr) { //_options.numberOfBuffers = m_nBuffers;
options->numberOfBuffers = m_nBuffers;
}
m_state = airtaudio::state_stopped; m_state = airtaudio::state_stopped;
return airtaudio::error_none; return airtaudio::error_none;
} }
@ -195,7 +195,7 @@ bool airtaudio::Api::probeDeviceOpen(uint32_t /*device*/,
uint32_t /*sampleRate*/, uint32_t /*sampleRate*/,
audio::format /*format*/, audio::format /*format*/,
uint32_t * /*bufferSize*/, uint32_t * /*bufferSize*/,
airtaudio::StreamOptions * /*options*/) { const airtaudio::StreamOptions& /*options*/) {
// MUST be implemented in subclasses! // MUST be implemented in subclasses!
return false; return false;
} }

View File

@ -68,7 +68,7 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
uint32_t* _nbChunk, uint32_t* _nbChunk,
airtaudio::AirTAudioCallback _callback, airtaudio::AirTAudioCallback _callback,
airtaudio::StreamOptions* _options); const airtaudio::StreamOptions& _options);
virtual enum airtaudio::error closeStream(); virtual enum airtaudio::error closeStream();
virtual enum airtaudio::error startStream(); virtual enum airtaudio::error startStream();
virtual enum airtaudio::error stopStream() = 0; virtual enum airtaudio::error stopStream() = 0;
@ -123,7 +123,7 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
enum audio::format _format, enum audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options); const airtaudio::StreamOptions& _options);
virtual bool probeDeviceOpenName(const std::string& _deviceName, virtual bool probeDeviceOpenName(const std::string& _deviceName,
airtaudio::mode _mode, airtaudio::mode _mode,
uint32_t _channels, uint32_t _channels,
@ -131,7 +131,7 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options) { return false; } const airtaudio::StreamOptions& _options) { return false; }
/** /**
* @brief Increment the stream time. * @brief Increment the stream time.
*/ */
@ -163,6 +163,11 @@ namespace airtaudio {
*/ */
void setConvertInfo(enum airtaudio::mode _mode, void setConvertInfo(enum airtaudio::mode _mode,
uint32_t _firstChannel); uint32_t _firstChannel);
public:
virtual bool isMasterOf(airtaudio::Api* _api) {
return false;
};
}; };
}; };
/** /**

View File

@ -149,7 +149,7 @@ enum airtaudio::error airtaudio::Interface::openStream(airtaudio::StreamParamete
uint32_t _sampleRate, uint32_t _sampleRate,
uint32_t* _bufferFrames, uint32_t* _bufferFrames,
airtaudio::AirTAudioCallback _callback, airtaudio::AirTAudioCallback _callback,
airtaudio::StreamOptions* _options) { const airtaudio::StreamOptions& _options) {
if (m_rtapi == nullptr) { if (m_rtapi == nullptr) {
return airtaudio::error_inputNull; return airtaudio::error_inputNull;
} }
@ -162,6 +162,23 @@ enum airtaudio::error airtaudio::Interface::openStream(airtaudio::StreamParamete
_options); _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);
}

View File

@ -198,7 +198,7 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
uint32_t* _bufferFrames, uint32_t* _bufferFrames,
airtaudio::AirTAudioCallback _callback, 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. * @brief A function that closes a stream and frees any associated stream memory.
@ -308,6 +308,7 @@ namespace airtaudio {
} }
return m_rtapi->getStreamSampleRate(); return m_rtapi->getStreamSampleRate();
} }
bool isMasterOf(airtaudio::Interface& _interface);
protected: protected:
void openRtApi(enum airtaudio::type _api); void openRtApi(enum airtaudio::type _api);
}; };

View File

@ -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 <airtaudio/StreamOptions.h>
#include <etk/stdTools.h>
#include <airtaudio/debug.h>
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>(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 <enum airtaudio::timestampMode> std::string to_string(const enum airtaudio::timestampMode& _variable) {
return listValue[_variable];
}
}

View File

@ -8,13 +8,16 @@
#ifndef __AIRTAUDIO_STREAM_OPTION_H__ #ifndef __AIRTAUDIO_STREAM_OPTION_H__
#define __AIRTAUDIO_STREAM_OPTION_H__ #define __AIRTAUDIO_STREAM_OPTION_H__
namespace airtaudio { #include <airtaudio/Flags.h>
namespace airtaudio {
enum timestampMode { enum timestampMode {
timestampMode_Hardware, //!< enable harware timestamp timestampMode_Hardware, //!< enable harware timestamp
timestampMode_trigered, //!< get harware triger time stamp and ingrement with duration timestampMode_trigered, //!< get harware triger time stamp and ingrement with duration
timestampMode_soft, //!< Simulate all timestamp. timestampMode_soft, //!< Simulate all timestamp.
}; };
std::ostream& operator <<(std::ostream& _os, enum airtaudio::timestampMode _obj);
class StreamOptions { class StreamOptions {
public: public:
airtaudio::Flags flags; //!< A bit-mask of stream flags airtaudio::Flags flags; //!< A bit-mask of stream flags

View File

@ -14,6 +14,7 @@
#include <airtaudio/debug.h> #include <airtaudio/debug.h>
#include <etk/stdTools.h> #include <etk/stdTools.h>
#include <limits.h> #include <limits.h>
#include <airtaudio/api/Alsa.h>
#undef __class__ #undef __class__
#define __class__ "api::Alsa" #define __class__ "api::Alsa"
@ -33,13 +34,13 @@ namespace airtaudio {
bool runnable; bool runnable;
std11::thread* thread; std11::thread* thread;
bool threadRunning; 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() : AlsaPrivate() :
synchronized(false), synchronized(false),
runnable(false), runnable(false),
thread(nullptr), thread(nullptr),
threadRunning(false), threadRunning(false),
isMonotonic(false) { timeMode(timestampMode_soft) {
handles[0] = nullptr; handles[0] = nullptr;
handles[1] = nullptr; handles[1] = nullptr;
xrun[0] = false; xrun[0] = false;
@ -406,7 +407,7 @@ bool airtaudio::api::Alsa::probeDeviceOpen(uint32_t _device,
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options) { const airtaudio::StreamOptions& _options) {
// I'm not using the "plug" interface ... too much inconsistent behavior. // I'm not using the "plug" interface ... too much inconsistent behavior.
unsigned nDevices = 0; unsigned nDevices = 0;
int32_t result, subdevice, card; int32_t result, subdevice, card;
@ -461,7 +462,7 @@ bool airtaudio::api::Alsa::probeDeviceOpenName(const std::string& _deviceName,
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options) { const airtaudio::StreamOptions& _options) {
// I'm not using the "plug" interface ... too much inconsistent behavior. // I'm not using the "plug" interface ... too much inconsistent behavior.
unsigned nDevices = 0; unsigned nDevices = 0;
int32_t result, subdevice, card; int32_t result, subdevice, card;
@ -608,14 +609,12 @@ bool airtaudio::api::Alsa::probeDeviceOpenName(const std::string& _deviceName,
*_bufferSize = periodSize; *_bufferSize = periodSize;
// Set the buffer number, which in ALSA is referred to as the "period". // Set the buffer number, which in ALSA is referred to as the "period".
uint32_t periods = 0; uint32_t periods = 0;
if ( _options != nullptr if (_options.flags.m_minimizeLatency == true) {
&& _options->flags.m_minimizeLatency == true) {
periods = 2; periods = 2;
} }
/* TODO : Chouse the number of low level buffer ... /* TODO : Chouse the number of low level buffer ...
if ( _options != nullptr if (_options.numberOfBuffers > 0) {
&& _options->numberOfBuffers > 0) { periods = _options.numberOfBuffers;
periods = _options->numberOfBuffers;
} }
*/ */
if (periods < 2) { if (periods < 2) {
@ -639,11 +638,16 @@ bool airtaudio::api::Alsa::probeDeviceOpenName(const std::string& _deviceName,
m_bufferSize = *_bufferSize; m_bufferSize = *_bufferSize;
// check if the hardware provide hardware clock : // check if the hardware provide hardware clock :
if (snd_pcm_hw_params_is_monotonic(hw_params) == 0) { if (snd_pcm_hw_params_is_monotonic(hw_params) == 0) {
m_private->isMonotonic = false; ATA_INFO("ALSA Audio timestamp is NOT monotonic (Generate with the start timestamp)");
ATA_WARNING("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 { } else {
m_private->isMonotonic = true; ATA_DEBUG("ALSA Audio timestamp is monotonic (can came from harware)");
ATA_DEBUG("ALSA Audio timestamp is monotonic (came from harware)"); m_private->timeMode = _options.mode;
} }
// Install the hardware configuration // Install the hardware configuration
@ -976,7 +980,7 @@ void airtaudio::api::Alsa::callbackEvent() {
} }
std11::chrono::system_clock::time_point airtaudio::api::Alsa::getStreamTime() { 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_t *status = nullptr;
snd_pcm_status_alloca(&status); snd_pcm_status_alloca(&status);
// get harware timestamp all the time: // 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 ..."); ATA_WARNING(" get time of the signal error ...");
return m_startTime + m_duration; return m_startTime + m_duration;
} }
// get start time:
//snd_pcm_status_get_trigger_tstamp(status, &timestamp);
//m_startTime = std11::chrono::system_clock::from_time_t(timestamp.tv_sec) + std11::chrono::microseconds(timestamp.tv_usec);
#if 0 #if 0
snd_timestamp_t timestamp; snd_timestamp_t timestamp;
snd_pcm_status_get_tstamp(status, &timestamp); snd_pcm_status_get_tstamp(status, &timestamp);
@ -1013,7 +1014,28 @@ std11::chrono::system_clock::time_point airtaudio::api::Alsa::getStreamTime() {
m_startTime -= timeDelay; m_startTime -= timeDelay;
} }
return m_startTime; 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, &timestamp);
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 { } else {
// softaware mode ...
if (m_startTime == std11::chrono::system_clock::time_point()) { if (m_startTime == std11::chrono::system_clock::time_point()) {
m_startTime = std11::chrono::system_clock::now(); m_startTime = std11::chrono::system_clock::now();
std11::chrono::nanoseconds timeDelay(m_bufferSize*1000000000LL/int64_t(m_sampleRate)); 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<airtaudio::api::Alsa*>(_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 #endif

View File

@ -55,7 +55,7 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
enum audio::format _format, enum audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options); const airtaudio::StreamOptions& _options);
virtual bool probeDeviceOpenName(const std::string& _deviceName, virtual bool probeDeviceOpenName(const std::string& _deviceName,
airtaudio::mode _mode, airtaudio::mode _mode,
@ -64,8 +64,10 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options); const airtaudio::StreamOptions& _options);
virtual std11::chrono::system_clock::time_point getStreamTime(); virtual std11::chrono::system_clock::time_point getStreamTime();
public:
bool isMasterOf(airtaudio::Api* _api);
}; };
}; };
}; };

View File

@ -153,7 +153,7 @@ bool airtaudio::api::Android::probeDeviceOpen(uint32_t _device,
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options) { const airtaudio::StreamOptions& _options) {
ATA_INFO("Probe : device=" << _device << " channels=" << _channels << " firstChannel=" << _firstChannel << " sampleRate=" << _sampleRate); ATA_INFO("Probe : device=" << _device << " channels=" << _channels << " firstChannel=" << _firstChannel << " sampleRate=" << _sampleRate);
if (_mode != airtaudio::mode_output) { if (_mode != airtaudio::mode_output) {
ATA_ERROR("Can not start a device input or duplex for Android ..."); ATA_ERROR("Can not start a device input or duplex for Android ...");

View File

@ -40,7 +40,7 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options); const airtaudio::StreamOptions& _options);
private: private:
void callBackEvent(void* _data, void callBackEvent(void* _data,
int32_t _frameRate); int32_t _frameRate);

View File

@ -224,7 +224,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t* _bufferSize, uint32_t* _bufferSize,
airtaudio::StreamOptions *_options) { const airtaudio::StreamOptions& _options) {
// For ASIO, a duplex stream MUST use the same driver. // For ASIO, a duplex stream MUST use the same driver.
if ( _mode == airtaudio::mode_input if ( _mode == airtaudio::mode_input
&& m_mode == airtaudio::mode_output && m_mode == airtaudio::mode_output

View File

@ -44,7 +44,7 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options); const airtaudio.::StreamOptions& _options);
}; };
}; };
}; };

View File

@ -428,7 +428,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options) { const airtaudio.::StreamOptions& _options) {
// Get device ID // Get device ID
uint32_t nDevices = getDeviceCount(); uint32_t nDevices = getDeviceCount();
if (nDevices == 0) { if (nDevices == 0) {
@ -569,8 +569,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
} else if (bufferRange.mMaximum < *_bufferSize) { } else if (bufferRange.mMaximum < *_bufferSize) {
*_bufferSize = (uint64_t) bufferRange.mMaximum; *_bufferSize = (uint64_t) bufferRange.mMaximum;
} }
if ( _options != nullptr if (_options.flags.m_minimizeLatency == true) {
&& _options->flags.m_minimizeLatency == true) {
*_bufferSize = (uint64_t) bufferRange.mMinimum; *_bufferSize = (uint64_t) bufferRange.mMinimum;
} }
// Set the buffer size. For multiple streams, I'm assuming we only // Set the buffer size. For multiple streams, I'm assuming we only

View File

@ -53,7 +53,7 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options); const airtaudio.::StreamOptions& _options);
static const char* getErrorCode(OSStatus _code); static const char* getErrorCode(OSStatus _code);
static OSStatus xrunListener(AudioObjectID _inDevice, static OSStatus xrunListener(AudioObjectID _inDevice,
uint32_t _nAddresses, uint32_t _nAddresses,

View File

@ -41,7 +41,7 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options); const airtaudio.::StreamOptions& _options);
public: public:
void callBackEvent(void* _data, void callBackEvent(void* _data,
int32_t _frameRate); int32_t _frameRate);

View File

@ -182,7 +182,7 @@ bool airtaudio::api::CoreIos::probeDeviceOpen(uint32_t _device,
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options) { const airtaudio.::StreamOptions& _options) {
ATA_INFO("Probe : device=" << _device << " channels=" << _channels << " firstChannel=" << _firstChannel << " sampleRate=" << _sampleRate); ATA_INFO("Probe : device=" << _device << " channels=" << _channels << " firstChannel=" << _firstChannel << " sampleRate=" << _sampleRate);
if (_mode != airtaudio::mode_output) { if (_mode != airtaudio::mode_output) {
ATA_ERROR("Can not start a device input or duplex for CoreIos ..."); ATA_ERROR("Can not start a device input or duplex for CoreIos ...");

View File

@ -361,7 +361,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
uint32_t _sampleRate, uint32_t _sampleRate,
enum audio::format _format, enum audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options) { const airtaudio.::StreamOptions& _options) {
if (_channels + _firstChannel > 2) { if (_channels + _firstChannel > 2) {
ATA_ERROR("DirectSound does not support more than 2 channels per device."); ATA_ERROR("DirectSound does not support more than 2 channels per device.");
return false; return false;
@ -402,12 +402,9 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
// low for capture, but it should work for playback. // low for capture, but it should work for playback.
int32_t nBuffers = 0; int32_t nBuffers = 0;
/* /*
if (_options != nullptr) { nBuffers = _options.numberOfBuffers;
nBuffers = _options->numberOfBuffers;
}
*/ */
if ( _options!= nullptr if (_options.flags.m_minimizeLatency == true) {
&& _options->flags.m_minimizeLatency == true) {
nBuffers = 2; nBuffers = 2;
} }
if (nBuffers < 2) { if (nBuffers < 2) {

View File

@ -47,7 +47,7 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
enum audio::format _format, enum audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options); const airtaudio.::StreamOptions& _options);
}; };
}; };
}; };

View File

@ -55,7 +55,7 @@ bool airtaudio::api::Dummy::probeDeviceOpen(uint32_t _device,
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options) { const airtaudio::StreamOptions& _options) {
return false; return false;
} }

View File

@ -34,7 +34,7 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options); const airtaudio::StreamOptions& _options);
}; };
}; };
}; };

View File

@ -268,7 +268,7 @@ bool airtaudio::api::Jack::probeDeviceOpen(uint32_t _device,
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t* _bufferSize, 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). // Look for jack server and try to become a client (only do once per stream).
jack_client_t *client = 0; jack_client_t *client = 0;
if ( _mode == airtaudio::mode_output if ( _mode == airtaudio::mode_output
@ -276,8 +276,8 @@ bool airtaudio::api::Jack::probeDeviceOpen(uint32_t _device,
&& m_mode != airtaudio::mode_output)) { && m_mode != airtaudio::mode_output)) {
jack_options_t jackoptions = (jack_options_t) (JackNoStartServer); //JackNullOption; jack_options_t jackoptions = (jack_options_t) (JackNoStartServer); //JackNullOption;
jack_status_t *status = nullptr; jack_status_t *status = nullptr;
if (_options && !_options->streamName.empty()) { if (!_options.streamName.empty()) {
client = jack_client_open(_options->streamName.c_str(), jackoptions, status); client = jack_client_open(_options.streamName.c_str(), jackoptions, status);
} else { } else {
client = jack_client_open("airtaudioJack", jackoptions, status); client = jack_client_open("airtaudioJack", jackoptions, status);
} }

View File

@ -47,7 +47,7 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options); const airtaudio.::StreamOptions& _options);
}; };
}; };
}; };

View File

@ -187,7 +187,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
uint32_t _sampleRate, uint32_t _sampleRate,
rtaudio::format _format, rtaudio::format _format,
uint32_t* _bufferSize, uint32_t* _bufferSize,
rtaudio::StreamOptions* _options) { const airtaudio.::StreamOptions& _options) {
int32_t mixerfd = open("/dev/mixer", O_RDWR, 0); int32_t mixerfd = open("/dev/mixer", O_RDWR, 0);
if (mixerfd == -1) { if (mixerfd == -1) {
ATA_ERROR("error opening '/dev/mixer'."); ATA_ERROR("error opening '/dev/mixer'.");
@ -257,8 +257,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
} }
} }
// Set exclusive access if specified. // Set exclusive access if specified.
if ( _options != nullptr if (_options.flags & RTAUDIO_HOG_DEVICE) {
&& _options->flags & RTAUDIO_HOG_DEVICE) {
flags |= O_EXCL; flags |= O_EXCL;
} }
// Try to open the device. // Try to open the device.
@ -400,11 +399,8 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
ossBufferBytes = 16; ossBufferBytes = 16;
} }
int32_t buffers = 0; int32_t buffers = 0;
if (_options != nullptr) { buffers = _options.numberOfBuffers;
buffers = _options->numberOfBuffers; if (_options.flags.m_minimizeLatency == true) {
}
if ( _options != nullptr
&& _options->flags.m_minimizeLatency == true) {
buffers = 2; buffers = 2;
} }
if (buffers < 2) { if (buffers < 2) {

View File

@ -40,7 +40,7 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options); const airtaudio.::StreamOptions& _options);
}; };
}; };
}; };

View File

@ -285,7 +285,7 @@ bool airtaudio::api::Pulse::probeDeviceOpen(uint32_t _device,
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options) { const airtaudio.::StreamOptions& _options) {
uint64_t bufferBytes = 0; uint64_t bufferBytes = 0;
pa_sample_spec ss; pa_sample_spec ss;
if (_device != 0) { if (_device != 0) {

View File

@ -43,7 +43,7 @@ namespace airtaudio {
uint32_t _sampleRate, uint32_t _sampleRate,
audio::format _format, audio::format _format,
uint32_t *_bufferSize, uint32_t *_bufferSize,
airtaudio::StreamOptions *_options); const airtaudio.::StreamOptions& _options);
}; };
}; };
}; };

View File

@ -7,7 +7,7 @@
#include <airtaudio/status.h> #include <airtaudio/status.h>
#include <airtaudio/debug.h> #include <airtaudio/debug.h>
const char* listValue[] = { static const char* listValue[] = {
"ok", "ok",
"overflow", "overflow",
"underflow" "underflow"

View File

@ -22,6 +22,7 @@ def create(target):
'airtaudio/Flags.cpp', 'airtaudio/Flags.cpp',
'airtaudio/Api.cpp', 'airtaudio/Api.cpp',
'airtaudio/DeviceInfo.cpp', 'airtaudio/DeviceInfo.cpp',
'airtaudio/StreamOptions.cpp',
'airtaudio/api/Dummy.cpp' 'airtaudio/api/Dummy.cpp'
]) ])
myModule.add_module_depend(['audio', 'etk']) myModule.add_module_depend(['audio', 'etk'])