[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;
}
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;
}

View File

@ -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;
};
};
};
/**

View File

@ -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);
}

View File

@ -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);
};

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__
#define __AIRTAUDIO_STREAM_OPTION_H__
namespace airtaudio {
#include <airtaudio/Flags.h>
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

View File

@ -14,6 +14,7 @@
#include <airtaudio/debug.h>
#include <etk/stdTools.h>
#include <limits.h>
#include <airtaudio/api/Alsa.h>
#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, &timestamp);
//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, &timestamp);
@ -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, &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 {
// 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<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

View File

@ -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);
};
};
};

View File

@ -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 ...");

View File

@ -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);

View File

@ -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

View File

@ -44,7 +44,7 @@ namespace airtaudio {
uint32_t _sampleRate,
audio::format _format,
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,
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

View File

@ -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,

View File

@ -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);

View File

@ -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 ...");

View File

@ -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) {

View File

@ -47,7 +47,7 @@ namespace airtaudio {
uint32_t _sampleRate,
enum audio::format _format,
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,
audio::format _format,
uint32_t *_bufferSize,
airtaudio::StreamOptions *_options) {
const airtaudio::StreamOptions& _options) {
return false;
}

View File

@ -34,7 +34,7 @@ namespace airtaudio {
uint32_t _sampleRate,
audio::format _format,
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,
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);
}

View File

@ -47,7 +47,7 @@ namespace airtaudio {
uint32_t _sampleRate,
audio::format _format,
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,
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) {

View File

@ -40,7 +40,7 @@ namespace airtaudio {
uint32_t _sampleRate,
audio::format _format,
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,
audio::format _format,
uint32_t *_bufferSize,
airtaudio::StreamOptions *_options) {
const airtaudio.::StreamOptions& _options) {
uint64_t bufferBytes = 0;
pa_sample_spec ss;
if (_device != 0) {

View File

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

View File

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

View File

@ -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'])