[DEV] start remove some uneeded element in the airtaudio lib
This commit is contained in:
parent
6de9bac0fc
commit
3629886590
@ -74,29 +74,29 @@ airtaudio::Api::~Api() {
|
|||||||
|
|
||||||
enum airtaudio::errorType airtaudio::Api::openStream(airtaudio::StreamParameters *oParams,
|
enum airtaudio::errorType airtaudio::Api::openStream(airtaudio::StreamParameters *oParams,
|
||||||
airtaudio::StreamParameters *iParams,
|
airtaudio::StreamParameters *iParams,
|
||||||
airtaudio::format format,
|
audio::format format,
|
||||||
uint32_t sampleRate,
|
uint32_t sampleRate,
|
||||||
uint32_t *bufferFrames,
|
uint32_t *bufferFrames,
|
||||||
airtaudio::AirTAudioCallback callback,
|
airtaudio::AirTAudioCallback callback,
|
||||||
airtaudio::StreamOptions *options) {
|
airtaudio::StreamOptions *options) {
|
||||||
if (m_stream.state != airtaudio::api::STREAM_CLOSED) {
|
if (m_stream.state != airtaudio::api::STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::Api::openStream: a stream is already open!");
|
ATA_ERROR("a stream is already open!");
|
||||||
return airtaudio::errorInvalidUse;
|
return airtaudio::errorInvalidUse;
|
||||||
}
|
}
|
||||||
if (oParams && oParams->nChannels < 1) {
|
if (oParams && oParams->nChannels < 1) {
|
||||||
ATA_ERROR("airtaudio::Api::openStream: 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::errorInvalidUse;
|
return airtaudio::errorInvalidUse;
|
||||||
}
|
}
|
||||||
if (iParams && iParams->nChannels < 1) {
|
if (iParams && iParams->nChannels < 1) {
|
||||||
ATA_ERROR("airtaudio::Api::openStream: 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::errorInvalidUse;
|
return airtaudio::errorInvalidUse;
|
||||||
}
|
}
|
||||||
if (oParams == nullptr && iParams == nullptr) {
|
if (oParams == nullptr && iParams == nullptr) {
|
||||||
ATA_ERROR("airtaudio::Api::openStream: input and output StreamParameters structures are both nullptr!");
|
ATA_ERROR("input and output StreamParameters structures are both nullptr!");
|
||||||
return airtaudio::errorInvalidUse;
|
return airtaudio::errorInvalidUse;
|
||||||
}
|
}
|
||||||
if (formatBytes(format) == 0) {
|
if (audio::getFormatBytes(format) == 0) {
|
||||||
ATA_ERROR("airtaudio::Api::openStream: 'format' parameter value is undefined.");
|
ATA_ERROR("'format' parameter value is undefined.");
|
||||||
return airtaudio::errorInvalidUse;
|
return airtaudio::errorInvalidUse;
|
||||||
}
|
}
|
||||||
uint32_t nDevices = getDeviceCount();
|
uint32_t nDevices = getDeviceCount();
|
||||||
@ -104,7 +104,7 @@ enum airtaudio::errorType airtaudio::Api::openStream(airtaudio::StreamParameters
|
|||||||
if (oParams) {
|
if (oParams) {
|
||||||
oChannels = oParams->nChannels;
|
oChannels = oParams->nChannels;
|
||||||
if (oParams->deviceId >= nDevices) {
|
if (oParams->deviceId >= nDevices) {
|
||||||
ATA_ERROR("airtaudio::Api::openStream: output device parameter value is invalid.");
|
ATA_ERROR("output device parameter value is invalid.");
|
||||||
return airtaudio::errorInvalidUse;
|
return airtaudio::errorInvalidUse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,7 +112,7 @@ enum airtaudio::errorType airtaudio::Api::openStream(airtaudio::StreamParameters
|
|||||||
if (iParams) {
|
if (iParams) {
|
||||||
iChannels = iParams->nChannels;
|
iChannels = iParams->nChannels;
|
||||||
if (iParams->deviceId >= nDevices) {
|
if (iParams->deviceId >= nDevices) {
|
||||||
ATA_ERROR("airtaudio::Api::openStream: input device parameter value is invalid.");
|
ATA_ERROR("input device parameter value is invalid.");
|
||||||
return airtaudio::errorInvalidUse;
|
return airtaudio::errorInvalidUse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -177,7 +177,7 @@ bool airtaudio::Api::probeDeviceOpen(uint32_t /*device*/,
|
|||||||
uint32_t /*channels*/,
|
uint32_t /*channels*/,
|
||||||
uint32_t /*firstChannel*/,
|
uint32_t /*firstChannel*/,
|
||||||
uint32_t /*sampleRate*/,
|
uint32_t /*sampleRate*/,
|
||||||
airtaudio::format /*format*/,
|
audio::format /*format*/,
|
||||||
uint32_t * /*bufferSize*/,
|
uint32_t * /*bufferSize*/,
|
||||||
airtaudio::StreamOptions * /*options*/) {
|
airtaudio::StreamOptions * /*options*/) {
|
||||||
// MUST be implemented in subclasses!
|
// MUST be implemented in subclasses!
|
||||||
@ -241,7 +241,7 @@ uint32_t airtaudio::Api::getStreamSampleRate() {
|
|||||||
|
|
||||||
enum airtaudio::errorType airtaudio::Api::verifyStream() {
|
enum airtaudio::errorType airtaudio::Api::verifyStream() {
|
||||||
if (m_stream.state == airtaudio::api::STREAM_CLOSED) {
|
if (m_stream.state == airtaudio::api::STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::Api:: a stream is not open!");
|
ATA_ERROR("a stream is not open!");
|
||||||
return airtaudio::errorInvalidUse;
|
return airtaudio::errorInvalidUse;
|
||||||
}
|
}
|
||||||
return airtaudio::errorNone;
|
return airtaudio::errorNone;
|
||||||
@ -253,7 +253,7 @@ void airtaudio::Api::clearStreamInfo() {
|
|||||||
m_stream.sampleRate = 0;
|
m_stream.sampleRate = 0;
|
||||||
m_stream.bufferSize = 0;
|
m_stream.bufferSize = 0;
|
||||||
m_stream.nBuffers = 0;
|
m_stream.nBuffers = 0;
|
||||||
m_stream.userFormat = 0;
|
m_stream.userFormat = audio::format_unknow;
|
||||||
m_stream.userInterleaved = true;
|
m_stream.userInterleaved = true;
|
||||||
m_stream.streamTime = 0.0;
|
m_stream.streamTime = 0.0;
|
||||||
m_stream.apiHandle = 0;
|
m_stream.apiHandle = 0;
|
||||||
@ -268,38 +268,19 @@ void airtaudio::Api::clearStreamInfo() {
|
|||||||
m_stream.nUserChannels[iii] = 0;
|
m_stream.nUserChannels[iii] = 0;
|
||||||
m_stream.nDeviceChannels[iii] = 0;
|
m_stream.nDeviceChannels[iii] = 0;
|
||||||
m_stream.channelOffset[iii] = 0;
|
m_stream.channelOffset[iii] = 0;
|
||||||
m_stream.deviceFormat[iii] = 0;
|
m_stream.deviceFormat[iii] = audio::format_unknow;
|
||||||
m_stream.latency[iii] = 0;
|
m_stream.latency[iii] = 0;
|
||||||
m_stream.userBuffer[iii] = 0;
|
m_stream.userBuffer[iii] = 0;
|
||||||
m_stream.convertInfo[iii].channels = 0;
|
m_stream.convertInfo[iii].channels = 0;
|
||||||
m_stream.convertInfo[iii].inJump = 0;
|
m_stream.convertInfo[iii].inJump = 0;
|
||||||
m_stream.convertInfo[iii].outJump = 0;
|
m_stream.convertInfo[iii].outJump = 0;
|
||||||
m_stream.convertInfo[iii].inFormat = 0;
|
m_stream.convertInfo[iii].inFormat = audio::format_unknow;
|
||||||
m_stream.convertInfo[iii].outFormat = 0;
|
m_stream.convertInfo[iii].outFormat = audio::format_unknow;
|
||||||
m_stream.convertInfo[iii].inOffset.clear();
|
m_stream.convertInfo[iii].inOffset.clear();
|
||||||
m_stream.convertInfo[iii].outOffset.clear();
|
m_stream.convertInfo[iii].outOffset.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t airtaudio::Api::formatBytes(airtaudio::format _format)
|
|
||||||
{
|
|
||||||
if (_format == airtaudio::SINT16) {
|
|
||||||
return 2;
|
|
||||||
} else if ( _format == airtaudio::SINT32
|
|
||||||
|| _format == airtaudio::FLOAT32) {
|
|
||||||
return 4;
|
|
||||||
} else if (_format == airtaudio::FLOAT64) {
|
|
||||||
return 8;
|
|
||||||
} else if (_format == airtaudio::SINT24) {
|
|
||||||
return 3;
|
|
||||||
} else if (_format == airtaudio::SINT8) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
ATA_ERROR("airtaudio::Api::formatBytes: undefined format.");
|
|
||||||
// TODO : airtaudio::errorWarning;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void airtaudio::Api::setConvertInfo(airtaudio::api::StreamMode _mode, uint32_t _firstChannel) {
|
void airtaudio::Api::setConvertInfo(airtaudio::api::StreamMode _mode, uint32_t _firstChannel) {
|
||||||
if (_mode == airtaudio::api::INPUT) { // convert device to user buffer
|
if (_mode == airtaudio::api::INPUT) { // convert device to user buffer
|
||||||
m_stream.convertInfo[_mode].inJump = m_stream.nDeviceChannels[1];
|
m_stream.convertInfo[_mode].inJump = m_stream.nDeviceChannels[1];
|
||||||
@ -386,431 +367,19 @@ void airtaudio::Api::convertBuffer(char *_outBuffer, char *_inBuffer, airtaudio:
|
|||||||
if ( _outBuffer == m_stream.deviceBuffer
|
if ( _outBuffer == m_stream.deviceBuffer
|
||||||
&& m_stream.mode == airtaudio::api::DUPLEX
|
&& m_stream.mode == airtaudio::api::DUPLEX
|
||||||
&& m_stream.nDeviceChannels[0] < m_stream.nDeviceChannels[1]) {
|
&& m_stream.nDeviceChannels[0] < m_stream.nDeviceChannels[1]) {
|
||||||
memset(_outBuffer, 0, m_stream.bufferSize * _info.outJump * formatBytes(_info.outFormat));
|
memset(_outBuffer, 0, m_stream.bufferSize * _info.outJump * audio::getFormatBytes(_info.outFormat));
|
||||||
}
|
}
|
||||||
int32_t jjj;
|
int32_t jjj;
|
||||||
if (_info.outFormat == airtaudio::FLOAT64) {
|
if (_info.outFormat != _info.outFormat) {
|
||||||
double scale;
|
ATA_CRITICAL("not manage anymore the format changing ...");
|
||||||
double *out = (double *)_outBuffer;
|
|
||||||
|
|
||||||
if (_info.inFormat == airtaudio::SINT8) {
|
|
||||||
signed char *in = (signed char *)_inBuffer;
|
|
||||||
scale = 1.0 / 127.5;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (double) in[_info.inOffset[jjj]];
|
|
||||||
out[_info.outOffset[jjj]] += 0.5;
|
|
||||||
out[_info.outOffset[jjj]] *= scale;
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT16) {
|
|
||||||
int16_t *in = (int16_t *)_inBuffer;
|
|
||||||
scale = 1.0 / 32767.5;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (double) in[_info.inOffset[jjj]];
|
|
||||||
out[_info.outOffset[jjj]] += 0.5;
|
|
||||||
out[_info.outOffset[jjj]] *= scale;
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT24) {
|
|
||||||
int24_t *in = (int24_t *)_inBuffer;
|
|
||||||
scale = 1.0 / 8388607.5;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (double) (in[_info.inOffset[jjj]].asInt());
|
|
||||||
out[_info.outOffset[jjj]] += 0.5;
|
|
||||||
out[_info.outOffset[jjj]] *= scale;
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT32) {
|
|
||||||
int32_t *in = (int32_t *)_inBuffer;
|
|
||||||
scale = 1.0 / 2147483647.5;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (double) in[_info.inOffset[jjj]];
|
|
||||||
out[_info.outOffset[jjj]] += 0.5;
|
|
||||||
out[_info.outOffset[jjj]] *= scale;
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::FLOAT32) {
|
|
||||||
float *in = (float *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (double) in[_info.inOffset[jjj]];
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::FLOAT64) {
|
|
||||||
// Channel compensation and/or (de)interleaving only.
|
|
||||||
double *in = (double *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = in[_info.inOffset[jjj]];
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.outFormat == airtaudio::FLOAT32) {
|
|
||||||
float scale;
|
|
||||||
float *out = (float *)_outBuffer;
|
|
||||||
if (_info.inFormat == airtaudio::SINT8) {
|
|
||||||
signed char *in = (signed char *)_inBuffer;
|
|
||||||
scale = (float) (1.0 / 127.5);
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (float) in[_info.inOffset[jjj]];
|
|
||||||
out[_info.outOffset[jjj]] += 0.5;
|
|
||||||
out[_info.outOffset[jjj]] *= scale;
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT16) {
|
|
||||||
int16_t *in = (int16_t *)_inBuffer;
|
|
||||||
scale = (float) (1.0 / 32767.5);
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (float) in[_info.inOffset[jjj]];
|
|
||||||
out[_info.outOffset[jjj]] += 0.5;
|
|
||||||
out[_info.outOffset[jjj]] *= scale;
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT24) {
|
|
||||||
int24_t *in = (int24_t *)_inBuffer;
|
|
||||||
scale = (float) (1.0 / 8388607.5);
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (float) (in[_info.inOffset[jjj]].asInt());
|
|
||||||
out[_info.outOffset[jjj]] += 0.5;
|
|
||||||
out[_info.outOffset[jjj]] *= scale;
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT32) {
|
|
||||||
int32_t *in = (int32_t *)_inBuffer;
|
|
||||||
scale = (float) (1.0 / 2147483647.5);
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (float) in[_info.inOffset[jjj]];
|
|
||||||
out[_info.outOffset[jjj]] += 0.5;
|
|
||||||
out[_info.outOffset[jjj]] *= scale;
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::FLOAT32) {
|
|
||||||
// Channel compensation and/or (de)interleaving only.
|
|
||||||
float *in = (float *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = in[_info.inOffset[jjj]];
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::FLOAT64) {
|
|
||||||
double *in = (double *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (float) in[_info.inOffset[jjj]];
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.outFormat == airtaudio::SINT32) {
|
|
||||||
int32_t *out = (int32_t *)_outBuffer;
|
|
||||||
if (_info.inFormat == airtaudio::SINT8) {
|
|
||||||
signed char *in = (signed char *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int32_t) in[_info.inOffset[jjj]];
|
|
||||||
out[_info.outOffset[jjj]] <<= 24;
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT16) {
|
|
||||||
int16_t *in = (int16_t *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int32_t) in[_info.inOffset[jjj]];
|
|
||||||
out[_info.outOffset[jjj]] <<= 16;
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT24) {
|
|
||||||
int24_t *in = (int24_t *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int32_t) in[_info.inOffset[jjj]].asInt();
|
|
||||||
out[_info.outOffset[jjj]] <<= 8;
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT32) {
|
|
||||||
// Channel compensation and/or (de)interleaving only.
|
|
||||||
int32_t *in = (int32_t *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = in[_info.inOffset[jjj]];
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::FLOAT32) {
|
|
||||||
float *in = (float *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int32_t) (in[_info.inOffset[jjj]] * 2147483647.5 - 0.5);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::FLOAT64) {
|
|
||||||
double *in = (double *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int32_t) (in[_info.inOffset[jjj]] * 2147483647.5 - 0.5);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.outFormat == airtaudio::SINT24) {
|
|
||||||
int24_t *out = (int24_t *)_outBuffer;
|
|
||||||
if (_info.inFormat == airtaudio::SINT8) {
|
|
||||||
signed char *in = (signed char *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int32_t) (in[_info.inOffset[jjj]] << 16);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT16) {
|
|
||||||
int16_t *in = (int16_t *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int32_t) (in[_info.inOffset[jjj]] << 8);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT24) {
|
|
||||||
// Channel compensation and/or (de)interleaving only.
|
|
||||||
int24_t *in = (int24_t *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = in[_info.inOffset[jjj]];
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT32) {
|
|
||||||
int32_t *in = (int32_t *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int32_t) (in[_info.inOffset[jjj]] >> 8);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::FLOAT32) {
|
|
||||||
float *in = (float *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int32_t) (in[_info.inOffset[jjj]] * 8388607.5 - 0.5);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::FLOAT64) {
|
|
||||||
double *in = (double *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int32_t) (in[_info.inOffset[jjj]] * 8388607.5 - 0.5);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.outFormat == airtaudio::SINT16) {
|
|
||||||
int16_t *out = (int16_t *)_outBuffer;
|
|
||||||
if (_info.inFormat == airtaudio::SINT8) {
|
|
||||||
signed char *in = (signed char *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int16_t) in[_info.inOffset[jjj]];
|
|
||||||
out[_info.outOffset[jjj]] <<= 8;
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT16) {
|
|
||||||
// Channel compensation and/or (de)interleaving only.
|
|
||||||
int16_t *in = (int16_t *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = in[_info.inOffset[jjj]];
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT24) {
|
|
||||||
int24_t *in = (int24_t *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int16_t) (in[_info.inOffset[jjj]].asInt() >> 8);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT32) {
|
|
||||||
int32_t *in = (int32_t *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int16_t) ((in[_info.inOffset[jjj]] >> 16) & 0x0000ffff);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::FLOAT32) {
|
|
||||||
float *in = (float *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int16_t) (in[_info.inOffset[jjj]] * 32767.5 - 0.5);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::FLOAT64) {
|
|
||||||
double *in = (double *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (int16_t) (in[_info.inOffset[jjj]] * 32767.5 - 0.5);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.outFormat == airtaudio::SINT8) {
|
|
||||||
signed char *out = (signed char *)_outBuffer;
|
|
||||||
if (_info.inFormat == airtaudio::SINT8) {
|
|
||||||
// Channel compensation and/or (de)interleaving only.
|
|
||||||
signed char *in = (signed char *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = in[_info.inOffset[jjj]];
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_info.inFormat == airtaudio::SINT16) {
|
|
||||||
int16_t *in = (int16_t *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (signed char) ((in[_info.inOffset[jjj]] >> 8) & 0x00ff);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT24) {
|
|
||||||
int24_t *in = (int24_t *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (signed char) (in[_info.inOffset[jjj]].asInt() >> 16);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::SINT32) {
|
|
||||||
int32_t *in = (int32_t *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (signed char) ((in[_info.inOffset[jjj]] >> 24) & 0x000000ff);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::FLOAT32) {
|
|
||||||
float *in = (float *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (signed char) (in[_info.inOffset[jjj]] * 127.5 - 0.5);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_info.inFormat == airtaudio::FLOAT64) {
|
|
||||||
double *in = (double *)_inBuffer;
|
|
||||||
for (uint32_t iii=0; iii<m_stream.bufferSize; ++iii) {
|
|
||||||
for (jjj=0; jjj<_info.channels; ++jjj) {
|
|
||||||
out[_info.outOffset[jjj]] = (signed char) (in[_info.inOffset[jjj]] * 127.5 - 0.5);
|
|
||||||
}
|
|
||||||
in += _info.inJump;
|
|
||||||
out += _info.outJump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void airtaudio::Api::byteSwapBuffer(char *_buffer, uint32_t _samples, airtaudio::format _format) {
|
void airtaudio::Api::byteSwapBuffer(char *_buffer, uint32_t _samples, audio::format _format) {
|
||||||
char val;
|
char val;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
ptr = _buffer;
|
ptr = _buffer;
|
||||||
if (_format == airtaudio::SINT16) {
|
if (_format == audio::format_int16) {
|
||||||
for (uint32_t iii=0; iii<_samples; ++iii) {
|
for (uint32_t iii=0; iii<_samples; ++iii) {
|
||||||
// Swap 1st and 2nd bytes.
|
// Swap 1st and 2nd bytes.
|
||||||
val = *(ptr);
|
val = *(ptr);
|
||||||
@ -820,8 +389,8 @@ void airtaudio::Api::byteSwapBuffer(char *_buffer, uint32_t _samples, airtaudio:
|
|||||||
// Increment 2 bytes.
|
// Increment 2 bytes.
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
}
|
}
|
||||||
} else if ( _format == airtaudio::SINT32
|
} else if ( _format == audio::format_int32
|
||||||
|| _format == airtaudio::FLOAT32) {
|
|| _format == audio::format_float) {
|
||||||
for (uint32_t iii=0; iii<_samples; ++iii) {
|
for (uint32_t iii=0; iii<_samples; ++iii) {
|
||||||
// Swap 1st and 4th bytes.
|
// Swap 1st and 4th bytes.
|
||||||
val = *(ptr);
|
val = *(ptr);
|
||||||
@ -837,7 +406,7 @@ void airtaudio::Api::byteSwapBuffer(char *_buffer, uint32_t _samples, airtaudio:
|
|||||||
// Increment 3 more bytes.
|
// Increment 3 more bytes.
|
||||||
ptr += 3;
|
ptr += 3;
|
||||||
}
|
}
|
||||||
} else if (_format == airtaudio::SINT24) {
|
} else if (_format == audio::format_int24) {
|
||||||
for (uint32_t iii=0; iii<_samples; ++iii) {
|
for (uint32_t iii=0; iii<_samples; ++iii) {
|
||||||
// Swap 1st and 3rd bytes.
|
// Swap 1st and 3rd bytes.
|
||||||
val = *(ptr);
|
val = *(ptr);
|
||||||
@ -847,7 +416,7 @@ void airtaudio::Api::byteSwapBuffer(char *_buffer, uint32_t _samples, airtaudio:
|
|||||||
// Increment 2 more bytes.
|
// Increment 2 more bytes.
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
}
|
}
|
||||||
} else if (_format == airtaudio::FLOAT64) {
|
} else if (_format == audio::format_double) {
|
||||||
for (uint32_t iii=0; iii<_samples; ++iii) {
|
for (uint32_t iii=0; iii<_samples; ++iii) {
|
||||||
// Swap 1st and 8th bytes
|
// Swap 1st and 8th bytes
|
||||||
val = *(ptr);
|
val = *(ptr);
|
||||||
|
@ -56,7 +56,7 @@ namespace airtaudio {
|
|||||||
struct ConvertInfo {
|
struct ConvertInfo {
|
||||||
int32_t channels;
|
int32_t channels;
|
||||||
int32_t inJump, outJump;
|
int32_t inJump, outJump;
|
||||||
airtaudio::format inFormat, outFormat;
|
audio::format inFormat, outFormat;
|
||||||
std::vector<int> inOffset;
|
std::vector<int> inOffset;
|
||||||
std::vector<int> outOffset;
|
std::vector<int> outOffset;
|
||||||
};
|
};
|
||||||
@ -81,8 +81,8 @@ namespace airtaudio {
|
|||||||
uint32_t nDeviceChannels[2]; // Playback and record channels, respectively.
|
uint32_t nDeviceChannels[2]; // Playback and record channels, respectively.
|
||||||
uint32_t channelOffset[2]; // Playback and record, respectively.
|
uint32_t channelOffset[2]; // Playback and record, respectively.
|
||||||
uint64_t latency[2]; // Playback and record, respectively.
|
uint64_t latency[2]; // Playback and record, respectively.
|
||||||
airtaudio::format userFormat;
|
audio::format userFormat;
|
||||||
airtaudio::format deviceFormat[2]; // Playback and record, respectively.
|
audio::format deviceFormat[2]; // Playback and record, respectively.
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
airtaudio::CallbackInfo callbackInfo;
|
airtaudio::CallbackInfo callbackInfo;
|
||||||
airtaudio::api::ConvertInfo convertInfo[2];
|
airtaudio::api::ConvertInfo convertInfo[2];
|
||||||
@ -122,7 +122,7 @@ namespace airtaudio {
|
|||||||
virtual uint32_t getDefaultOutputDevice();
|
virtual uint32_t getDefaultOutputDevice();
|
||||||
enum airtaudio::errorType openStream(airtaudio::StreamParameters *_outputParameters,
|
enum airtaudio::errorType openStream(airtaudio::StreamParameters *_outputParameters,
|
||||||
airtaudio::StreamParameters *_inputParameters,
|
airtaudio::StreamParameters *_inputParameters,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
uint32_t *_bufferFrames,
|
uint32_t *_bufferFrames,
|
||||||
airtaudio::AirTAudioCallback _callback,
|
airtaudio::AirTAudioCallback _callback,
|
||||||
@ -156,7 +156,7 @@ namespace airtaudio {
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options);
|
airtaudio::StreamOptions *_options);
|
||||||
|
|
||||||
@ -178,10 +178,7 @@ namespace airtaudio {
|
|||||||
void convertBuffer(char *_outBuffer, char *_inBuffer, airtaudio::api::ConvertInfo& _info);
|
void convertBuffer(char *_outBuffer, char *_inBuffer, airtaudio::api::ConvertInfo& _info);
|
||||||
|
|
||||||
//! Protected common method used to perform byte-swapping on buffers.
|
//! Protected common method used to perform byte-swapping on buffers.
|
||||||
void byteSwapBuffer(char *_buffer, uint32_t _samples, airtaudio::format _format);
|
void byteSwapBuffer(char *_buffer, uint32_t _samples, audio::format _format);
|
||||||
|
|
||||||
//! Protected common method that returns the number of bytes for a given format.
|
|
||||||
uint32_t formatBytes(airtaudio::format _format);
|
|
||||||
|
|
||||||
//! Protected common method that sets up the parameters for buffer conversion.
|
//! Protected common method that sets up the parameters for buffer conversion.
|
||||||
void setConvertInfo(airtaudio::api::StreamMode _mode, uint32_t _firstChannel);
|
void setConvertInfo(airtaudio::api::StreamMode _mode, uint32_t _firstChannel);
|
||||||
|
@ -23,7 +23,7 @@ namespace airtaudio {
|
|||||||
bool isDefaultOutput; //!< true if this is the default output device.
|
bool isDefaultOutput; //!< true if this is the default output device.
|
||||||
bool isDefaultInput; //!< true if this is the default input device.
|
bool isDefaultInput; //!< true if this is the default input device.
|
||||||
std::vector<uint32_t> sampleRates; //!< Supported sample rates (queried from list of standard rates).
|
std::vector<uint32_t> sampleRates; //!< Supported sample rates (queried from list of standard rates).
|
||||||
airtaudio::format nativeFormats; //!< Bit mask of supported data formats.
|
std::vector<audio::format> nativeFormats; //!< Bit mask of supported data formats.
|
||||||
// Default constructor.
|
// Default constructor.
|
||||||
DeviceInfo() :
|
DeviceInfo() :
|
||||||
probed(false),
|
probed(false),
|
||||||
@ -32,7 +32,7 @@ namespace airtaudio {
|
|||||||
duplexChannels(0),
|
duplexChannels(0),
|
||||||
isDefaultOutput(false),
|
isDefaultOutput(false),
|
||||||
isDefaultInput(false),
|
isDefaultInput(false),
|
||||||
nativeFormats(0) {}
|
nativeFormats() {}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ airtaudio::Interface::~Interface() {
|
|||||||
enum airtaudio::errorType airtaudio::Interface::openStream(
|
enum airtaudio::errorType airtaudio::Interface::openStream(
|
||||||
airtaudio::StreamParameters* _outputParameters,
|
airtaudio::StreamParameters* _outputParameters,
|
||||||
airtaudio::StreamParameters* _inputParameters,
|
airtaudio::StreamParameters* _inputParameters,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
uint32_t* _bufferFrames,
|
uint32_t* _bufferFrames,
|
||||||
airtaudio::AirTAudioCallback _callback,
|
airtaudio::AirTAudioCallback _callback,
|
||||||
|
@ -164,7 +164,7 @@ namespace airtaudio {
|
|||||||
* and starting channel number. For output-only streams, this
|
* and starting channel number. For output-only streams, this
|
||||||
* argument should be nullptr. The device ID is an index value between
|
* argument should be nullptr. The device ID is an index value between
|
||||||
* 0 and getDeviceCount() - 1.
|
* 0 and getDeviceCount() - 1.
|
||||||
* @param _format An airtaudio::format specifying the desired sample data format.
|
* @param _format An audio::format specifying the desired sample data format.
|
||||||
* @param _sampleRate The desired sample rate (sample frames per second).
|
* @param _sampleRate The desired sample rate (sample frames per second).
|
||||||
* @param *_bufferFrames A pointer to a value indicating the desired
|
* @param *_bufferFrames A pointer to a value indicating the desired
|
||||||
* internal buffer size in sample frames. The actual value
|
* internal buffer size in sample frames. The actual value
|
||||||
@ -187,7 +187,7 @@ namespace airtaudio {
|
|||||||
*/
|
*/
|
||||||
enum airtaudio::errorType openStream(airtaudio::StreamParameters *_outputParameters,
|
enum airtaudio::errorType openStream(airtaudio::StreamParameters *_outputParameters,
|
||||||
airtaudio::StreamParameters *_inputParameters,
|
airtaudio::StreamParameters *_inputParameters,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
uint32_t *_bufferFrames,
|
uint32_t *_bufferFrames,
|
||||||
airtaudio::AirTAudioCallback _callback,
|
airtaudio::AirTAudioCallback _callback,
|
||||||
|
@ -308,33 +308,33 @@ probeParameters:
|
|||||||
}
|
}
|
||||||
// Probe the supported data formats ... we don't care about endian-ness just yet
|
// Probe the supported data formats ... we don't care about endian-ness just yet
|
||||||
snd_pcm_format_t format;
|
snd_pcm_format_t format;
|
||||||
info.nativeFormats = 0;
|
info.nativeFormats.clear();
|
||||||
format = SND_PCM_FORMAT_S8;
|
format = SND_PCM_FORMAT_S8;
|
||||||
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
|
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
|
||||||
info.nativeFormats |= airtaudio::SINT8;
|
info.nativeFormats.push_back(audio::format_int8);
|
||||||
}
|
}
|
||||||
format = SND_PCM_FORMAT_S16;
|
format = SND_PCM_FORMAT_S16;
|
||||||
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
|
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
|
||||||
info.nativeFormats |= airtaudio::SINT16;
|
info.nativeFormats.push_back(audio::format_int16);
|
||||||
}
|
}
|
||||||
format = SND_PCM_FORMAT_S24;
|
format = SND_PCM_FORMAT_S24;
|
||||||
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
|
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
|
||||||
info.nativeFormats |= airtaudio::SINT24;
|
info.nativeFormats.push_back(audio::format_int24);
|
||||||
}
|
}
|
||||||
format = SND_PCM_FORMAT_S32;
|
format = SND_PCM_FORMAT_S32;
|
||||||
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
|
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
|
||||||
info.nativeFormats |= airtaudio::SINT32;
|
info.nativeFormats.push_back(audio::format_int32);
|
||||||
}
|
}
|
||||||
format = SND_PCM_FORMAT_FLOAT;
|
format = SND_PCM_FORMAT_FLOAT;
|
||||||
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
|
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
|
||||||
info.nativeFormats |= airtaudio::FLOAT32;
|
info.nativeFormats.push_back(audio::format_float);
|
||||||
}
|
}
|
||||||
format = SND_PCM_FORMAT_FLOAT64;
|
format = SND_PCM_FORMAT_FLOAT64;
|
||||||
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
|
if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) {
|
||||||
info.nativeFormats |= airtaudio::FLOAT64;
|
info.nativeFormats.push_back(audio::format_double);
|
||||||
}
|
}
|
||||||
// Check that we have at least one supported format
|
// Check that we have at least one supported format
|
||||||
if (info.nativeFormats == 0) {
|
if (info.nativeFormats.size() == 0) {
|
||||||
ATA_ERROR("airtaudio::api::Alsa::getDeviceInfo: pcm device (" << name << ") data format not supported by RtAudio.");
|
ATA_ERROR("airtaudio::api::Alsa::getDeviceInfo: pcm device (" << name << ") data format not supported by RtAudio.");
|
||||||
// TODO : Return airtaudio::errorWarning;
|
// TODO : Return airtaudio::errorWarning;
|
||||||
return info;
|
return info;
|
||||||
@ -366,7 +366,7 @@ bool airtaudio::api::Alsa::probeDeviceOpen(uint32_t _device,
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options) {
|
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.
|
||||||
@ -487,60 +487,28 @@ foundDevice:
|
|||||||
// Determine how to set the device format.
|
// Determine how to set the device format.
|
||||||
m_stream.userFormat = _format;
|
m_stream.userFormat = _format;
|
||||||
snd_pcm_format_t deviceFormat = SND_PCM_FORMAT_UNKNOWN;
|
snd_pcm_format_t deviceFormat = SND_PCM_FORMAT_UNKNOWN;
|
||||||
if (_format == airtaudio::SINT8) {
|
if (_format == audio::format_int8) {
|
||||||
deviceFormat = SND_PCM_FORMAT_S8;
|
deviceFormat = SND_PCM_FORMAT_S8;
|
||||||
} else if (_format == airtaudio::SINT16) {
|
} else if (_format == audio::format_int16) {
|
||||||
deviceFormat = SND_PCM_FORMAT_S16;
|
deviceFormat = SND_PCM_FORMAT_S16;
|
||||||
} else if (_format == airtaudio::SINT24) {
|
} else if (_format == audio::format_int24) {
|
||||||
deviceFormat = SND_PCM_FORMAT_S24;
|
deviceFormat = SND_PCM_FORMAT_S24;
|
||||||
} else if (_format == airtaudio::SINT32) {
|
} else if (_format == audio::format_int32) {
|
||||||
deviceFormat = SND_PCM_FORMAT_S32;
|
deviceFormat = SND_PCM_FORMAT_S32;
|
||||||
} else if (_format == airtaudio::FLOAT32) {
|
} else if (_format == audio::format_float) {
|
||||||
deviceFormat = SND_PCM_FORMAT_FLOAT;
|
deviceFormat = SND_PCM_FORMAT_FLOAT;
|
||||||
} else if (_format == airtaudio::FLOAT64) {
|
} else if (_format == audio::format_double) {
|
||||||
deviceFormat = SND_PCM_FORMAT_FLOAT64;
|
deviceFormat = SND_PCM_FORMAT_FLOAT64;
|
||||||
}
|
}
|
||||||
if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) {
|
if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) {
|
||||||
m_stream.deviceFormat[_mode] = _format;
|
m_stream.deviceFormat[_mode] = _format;
|
||||||
goto setFormat;
|
} else {
|
||||||
}
|
|
||||||
// The user requested format is not natively supported by the device.
|
|
||||||
deviceFormat = SND_PCM_FORMAT_FLOAT64;
|
|
||||||
if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) {
|
|
||||||
m_stream.deviceFormat[_mode] = airtaudio::FLOAT64;
|
|
||||||
goto setFormat;
|
|
||||||
}
|
|
||||||
deviceFormat = SND_PCM_FORMAT_FLOAT;
|
|
||||||
if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) {
|
|
||||||
m_stream.deviceFormat[_mode] = airtaudio::FLOAT32;
|
|
||||||
goto setFormat;
|
|
||||||
}
|
|
||||||
deviceFormat = SND_PCM_FORMAT_S32;
|
|
||||||
if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) {
|
|
||||||
m_stream.deviceFormat[_mode] = airtaudio::SINT32;
|
|
||||||
goto setFormat;
|
|
||||||
}
|
|
||||||
deviceFormat = SND_PCM_FORMAT_S24;
|
|
||||||
if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) {
|
|
||||||
m_stream.deviceFormat[_mode] = airtaudio::SINT24;
|
|
||||||
goto setFormat;
|
|
||||||
}
|
|
||||||
deviceFormat = SND_PCM_FORMAT_S16;
|
|
||||||
if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) {
|
|
||||||
m_stream.deviceFormat[_mode] = airtaudio::SINT16;
|
|
||||||
goto setFormat;
|
|
||||||
}
|
|
||||||
deviceFormat = SND_PCM_FORMAT_S8;
|
|
||||||
if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) {
|
|
||||||
m_stream.deviceFormat[_mode] = airtaudio::SINT8;
|
|
||||||
goto setFormat;
|
|
||||||
}
|
|
||||||
// If we get here, no supported format was found.
|
// If we get here, no supported format was found.
|
||||||
snd_pcm_close(phandle);
|
snd_pcm_close(phandle);
|
||||||
ATA_ERROR("airtaudio::api::Alsa::probeDeviceOpen: pcm device " << _device << " data format not supported by RtAudio.");
|
ATA_ERROR("pcm device " << _device << " data format not supported: " << _format);
|
||||||
|
// TODO : display list of all supported format ..
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
setFormat:
|
|
||||||
result = snd_pcm_hw_params_set_format(phandle, hw_params, deviceFormat);
|
result = snd_pcm_hw_params_set_format(phandle, hw_params, deviceFormat);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
snd_pcm_close(phandle);
|
snd_pcm_close(phandle);
|
||||||
@ -683,7 +651,7 @@ setFormat:
|
|||||||
phandle = 0;
|
phandle = 0;
|
||||||
// Allocate necessary internal buffers.
|
// Allocate necessary internal buffers.
|
||||||
uint64_t bufferBytes;
|
uint64_t bufferBytes;
|
||||||
bufferBytes = m_stream.nUserChannels[_mode] * *_bufferSize * formatBytes(m_stream.userFormat);
|
bufferBytes = m_stream.nUserChannels[_mode] * *_bufferSize * audio::getFormatBytes(m_stream.userFormat);
|
||||||
m_stream.userBuffer[_mode] = (char *) calloc(bufferBytes, 1);
|
m_stream.userBuffer[_mode] = (char *) calloc(bufferBytes, 1);
|
||||||
if (m_stream.userBuffer[_mode] == nullptr) {
|
if (m_stream.userBuffer[_mode] == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Alsa::probeDeviceOpen: error allocating user buffer memory.");
|
ATA_ERROR("airtaudio::api::Alsa::probeDeviceOpen: error allocating user buffer memory.");
|
||||||
@ -691,10 +659,10 @@ setFormat:
|
|||||||
}
|
}
|
||||||
if (m_stream.doConvertBuffer[_mode]) {
|
if (m_stream.doConvertBuffer[_mode]) {
|
||||||
bool makeBuffer = true;
|
bool makeBuffer = true;
|
||||||
bufferBytes = m_stream.nDeviceChannels[_mode] * formatBytes(m_stream.deviceFormat[_mode]);
|
bufferBytes = m_stream.nDeviceChannels[_mode] * audio::getFormatBytes(m_stream.deviceFormat[_mode]);
|
||||||
if (_mode == INPUT) {
|
if (_mode == INPUT) {
|
||||||
if (m_stream.mode == OUTPUT && m_stream.deviceBuffer) {
|
if (m_stream.mode == OUTPUT && m_stream.deviceBuffer) {
|
||||||
uint64_t bytesOut = m_stream.nDeviceChannels[0] * formatBytes(m_stream.deviceFormat[0]);
|
uint64_t bytesOut = m_stream.nDeviceChannels[0] * audio::getFormatBytes(m_stream.deviceFormat[0]);
|
||||||
if (bufferBytes <= bytesOut) {
|
if (bufferBytes <= bytesOut) {
|
||||||
makeBuffer = false;
|
makeBuffer = false;
|
||||||
}
|
}
|
||||||
@ -1001,7 +969,7 @@ void airtaudio::api::Alsa::callbackEvent() {
|
|||||||
int32_t channels;
|
int32_t channels;
|
||||||
snd_pcm_t **handle;
|
snd_pcm_t **handle;
|
||||||
snd_pcm_sframes_t frames;
|
snd_pcm_sframes_t frames;
|
||||||
airtaudio::format format;
|
audio::format format;
|
||||||
handle = (snd_pcm_t **) apiInfo->handles;
|
handle = (snd_pcm_t **) apiInfo->handles;
|
||||||
if ( m_stream.mode == airtaudio::api::INPUT
|
if ( m_stream.mode == airtaudio::api::INPUT
|
||||||
|| m_stream.mode == airtaudio::api::DUPLEX) {
|
|| m_stream.mode == airtaudio::api::DUPLEX) {
|
||||||
@ -1020,7 +988,7 @@ void airtaudio::api::Alsa::callbackEvent() {
|
|||||||
result = snd_pcm_readi(handle[1], buffer, m_stream.bufferSize);
|
result = snd_pcm_readi(handle[1], buffer, m_stream.bufferSize);
|
||||||
} else {
|
} else {
|
||||||
void *bufs[channels];
|
void *bufs[channels];
|
||||||
size_t offset = m_stream.bufferSize * formatBytes(format);
|
size_t offset = m_stream.bufferSize * audio::getFormatBytes(format);
|
||||||
for (int32_t i=0; i<channels; i++)
|
for (int32_t i=0; i<channels; i++)
|
||||||
bufs[i] = (void *) (buffer + (i * offset));
|
bufs[i] = (void *) (buffer + (i * offset));
|
||||||
result = snd_pcm_readn(handle[1], bufs, m_stream.bufferSize);
|
result = snd_pcm_readn(handle[1], bufs, m_stream.bufferSize);
|
||||||
@ -1082,7 +1050,7 @@ tryOutput:
|
|||||||
result = snd_pcm_writei(handle[0], buffer, m_stream.bufferSize);
|
result = snd_pcm_writei(handle[0], buffer, m_stream.bufferSize);
|
||||||
} else {
|
} else {
|
||||||
void *bufs[channels];
|
void *bufs[channels];
|
||||||
size_t offset = m_stream.bufferSize * formatBytes(format);
|
size_t offset = m_stream.bufferSize * audio::getFormatBytes(format);
|
||||||
for (int32_t i=0; i<channels; i++) {
|
for (int32_t i=0; i<channels; i++) {
|
||||||
bufs[i] = (void *) (buffer + (i * offset));
|
bufs[i] = (void *) (buffer + (i * offset));
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ namespace airtaudio {
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options);
|
airtaudio::StreamOptions *_options);
|
||||||
};
|
};
|
||||||
|
@ -56,23 +56,7 @@ airtaudio::api::Android::Android() {
|
|||||||
tmp.isDefaultInput = true;
|
tmp.isDefaultInput = true;
|
||||||
tmp.duplexChannels = etk::string_to_int32_t(listProperty[3]);
|
tmp.duplexChannels = etk::string_to_int32_t(listProperty[3]);
|
||||||
}
|
}
|
||||||
std::vector<std::string> listFormat = etk::split(listProperty[4], ',');
|
tmp.nativeFormats = audio::getListFormatFromString(listProperty[4]);
|
||||||
tmp.nativeFormats = 0;
|
|
||||||
for(size_t fff=0; fff<listFormat.size(); ++fff) {
|
|
||||||
if (listFormat[fff] == "float") {
|
|
||||||
tmp.nativeFormats |= FLOAT32;
|
|
||||||
} else if (listFormat[fff] == "double") {
|
|
||||||
tmp.nativeFormats |= FLOAT64;
|
|
||||||
} else if (listFormat[fff] == "s32") {
|
|
||||||
tmp.nativeFormats |= SINT32;
|
|
||||||
} else if (listFormat[fff] == "s24") {
|
|
||||||
tmp.nativeFormats |= SINT24;
|
|
||||||
} else if (listFormat[fff] == "s16") {
|
|
||||||
tmp.nativeFormats |= SINT16;
|
|
||||||
} else if (listFormat[fff] == "s8") {
|
|
||||||
tmp.nativeFormats |= SINT8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_devices.push_back(tmp);
|
m_devices.push_back(tmp);
|
||||||
}
|
}
|
||||||
ATA_INFO("Create Android interface (end)");
|
ATA_INFO("Create Android interface (end)");
|
||||||
@ -162,7 +146,7 @@ bool airtaudio::api::Android::probeDeviceOpen(uint32_t _device,
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options) {
|
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);
|
||||||
|
@ -37,7 +37,7 @@ namespace airtaudio {
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options);
|
airtaudio::StreamOptions *_options);
|
||||||
private:
|
private:
|
||||||
|
@ -73,7 +73,7 @@ airtaudio::api::Asio::Asio() {
|
|||||||
m_coInitialized = false;
|
m_coInitialized = false;
|
||||||
HRESULT hr = CoInitialize(nullptr);
|
HRESULT hr = CoInitialize(nullptr);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::ASIO requires a single-threaded appartment. Call CoInitializeEx(0,COINIT_APARTMENTTHREADED)");
|
ATA_ERROR("requires a single-threaded appartment. Call CoInitializeEx(0,COINIT_APARTMENTTHREADED)");
|
||||||
}
|
}
|
||||||
m_coInitialized = true;
|
m_coInitialized = true;
|
||||||
drivers.removeCurrentDriver();
|
drivers.removeCurrentDriver();
|
||||||
@ -101,17 +101,17 @@ rtaudio::DeviceInfo airtaudio::api::Asio::getDeviceInfo(uint32_t _device) {
|
|||||||
// Get device ID
|
// Get device ID
|
||||||
uint32_t nDevices = getDeviceCount();
|
uint32_t nDevices = getDeviceCount();
|
||||||
if (nDevices == 0) {
|
if (nDevices == 0) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::getDeviceInfo: no devices found!");
|
ATA_ERROR("no devices found!");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
if (_device >= nDevices) {
|
if (_device >= nDevices) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::getDeviceInfo: device ID is invalid!");
|
ATA_ERROR("device ID is invalid!");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
// If a stream is already open, we cannot probe other devices. Thus, use the saved results.
|
// If a stream is already open, we cannot probe other devices. Thus, use the saved results.
|
||||||
if (m_stream.state != STREAM_CLOSED) {
|
if (m_stream.state != STREAM_CLOSED) {
|
||||||
if (_device >= m_devices.size()) {
|
if (_device >= m_devices.size()) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::getDeviceInfo: device ID was not present before stream was opened.");
|
ATA_ERROR("device ID was not present before stream was opened.");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
return m_devices[ _device ];
|
return m_devices[ _device ];
|
||||||
@ -119,17 +119,17 @@ rtaudio::DeviceInfo airtaudio::api::Asio::getDeviceInfo(uint32_t _device) {
|
|||||||
char driverName[32];
|
char driverName[32];
|
||||||
ASIOError result = drivers.asioGetDriverName((int) _device, driverName, 32);
|
ASIOError result = drivers.asioGetDriverName((int) _device, driverName, 32);
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::getDeviceInfo: unable to get driver name (" << getAsioErrorString(result) << ").");
|
ATA_ERROR("unable to get driver name (" << getAsioErrorString(result) << ").");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
info.name = driverName;
|
info.name = driverName;
|
||||||
if (!drivers.loadDriver(driverName)) {
|
if (!drivers.loadDriver(driverName)) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::getDeviceInfo: unable to load driver (" << driverName << ").");
|
ATA_ERROR("unable to load driver (" << driverName << ").");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
result = ASIOInit(&driverInfo);
|
result = ASIOInit(&driverInfo);
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::getDeviceInfo: error (" << getAsioErrorString(result) << ") initializing driver (" << driverName << ").");
|
ATA_ERROR("error (" << getAsioErrorString(result) << ") initializing driver (" << driverName << ").");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
// Determine the device channel information.
|
// Determine the device channel information.
|
||||||
@ -137,7 +137,7 @@ rtaudio::DeviceInfo airtaudio::api::Asio::getDeviceInfo(uint32_t _device) {
|
|||||||
result = ASIOGetChannels(&inputChannels, &outputChannels);
|
result = ASIOGetChannels(&inputChannels, &outputChannels);
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
drivers.removeCurrentDriver();
|
drivers.removeCurrentDriver();
|
||||||
ATA_ERROR("airtaudio::api::Asio::getDeviceInfo: error (" << getAsioErrorString(result) << ") getting channel count (" << driverName << ").");
|
ATA_ERROR("error (" << getAsioErrorString(result) << ") getting channel count (" << driverName << ").");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
info.outputChannels = outputChannels;
|
info.outputChannels = outputChannels;
|
||||||
@ -163,25 +163,25 @@ rtaudio::DeviceInfo airtaudio::api::Asio::getDeviceInfo(uint32_t _device) {
|
|||||||
result = ASIOGetChannelInfo(&channelInfo);
|
result = ASIOGetChannelInfo(&channelInfo);
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
drivers.removeCurrentDriver();
|
drivers.removeCurrentDriver();
|
||||||
ATA_ERROR("airtaudio::api::Asio::getDeviceInfo: error (" << getAsioErrorString(result) << ") getting driver channel info (" << driverName << ").");
|
ATA_ERROR("error (" << getAsioErrorString(result) << ") getting driver channel info (" << driverName << ").");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
info.nativeFormats = 0;
|
info.nativeFormats.clear();
|
||||||
if ( channelInfo.type == ASIOSTInt16MSB
|
if ( channelInfo.type == ASIOSTInt16MSB
|
||||||
|| channelInfo.type == ASIOSTInt16LSB) {
|
|| channelInfo.type == ASIOSTInt16LSB) {
|
||||||
info.nativeFormats |= SINT16;
|
info.nativeFormats.push_back(audio::format_int16);
|
||||||
} else if ( channelInfo.type == ASIOSTInt32MSB
|
} else if ( channelInfo.type == ASIOSTInt32MSB
|
||||||
|| channelInfo.type == ASIOSTInt32LSB) {
|
|| channelInfo.type == ASIOSTInt32LSB) {
|
||||||
info.nativeFormats |= SINT32;
|
info.nativeFormats.push_back(audio::format_int32);
|
||||||
} else if ( channelInfo.type == ASIOSTFloat32MSB
|
} else if ( channelInfo.type == ASIOSTFloat32MSB
|
||||||
|| channelInfo.type == ASIOSTFloat32LSB) {
|
|| channelInfo.type == ASIOSTFloat32LSB) {
|
||||||
info.nativeFormats |= FLOAT32;
|
info.nativeFormats.push_back(audio::format_float);
|
||||||
} else if ( channelInfo.type == ASIOSTFloat64MSB
|
} else if ( channelInfo.type == ASIOSTFloat64MSB
|
||||||
|| channelInfo.type == ASIOSTFloat64LSB) {
|
|| channelInfo.type == ASIOSTFloat64LSB) {
|
||||||
info.nativeFormats |= FLOAT64;
|
info.nativeFormats.push_back(audio::format_double);
|
||||||
} else if ( channelInfo.type == ASIOSTInt24MSB
|
} else if ( channelInfo.type == ASIOSTInt24MSB
|
||||||
|| channelInfo.type == ASIOSTInt24LSB) {
|
|| channelInfo.type == ASIOSTInt24LSB) {
|
||||||
info.nativeFormats |= SINT24;
|
info.nativeFormats.push_back(audio::format_int24);
|
||||||
}
|
}
|
||||||
if (info.outputChannels > 0){
|
if (info.outputChannels > 0){
|
||||||
if (getDefaultOutputDevice() == _device) {
|
if (getDefaultOutputDevice() == _device) {
|
||||||
@ -217,20 +217,20 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t* _bufferSize,
|
uint32_t* _bufferSize,
|
||||||
airtaudio::StreamOptions *_options) {
|
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 == INPUT
|
if ( _mode == INPUT
|
||||||
&& m_stream.mode == OUTPUT
|
&& m_stream.mode == OUTPUT
|
||||||
&& m_stream.device[0] != _device) {
|
&& m_stream.device[0] != _device) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: an ASIO duplex stream must use the same device for input and output!");
|
ATA_ERROR("an ASIO duplex stream must use the same device for input and output!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
char driverName[32];
|
char driverName[32];
|
||||||
ASIOError result = drivers.asioGetDriverName((int) _device, driverName, 32);
|
ASIOError result = drivers.asioGetDriverName((int) _device, driverName, 32);
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: unable to get driver name (" << getAsioErrorString(result) << ").");
|
ATA_ERROR("unable to get driver name (" << getAsioErrorString(result) << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Only load the driver once for duplex stream.
|
// Only load the driver once for duplex stream.
|
||||||
@ -242,12 +242,12 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
// save the results for use by getDeviceInfo().
|
// save the results for use by getDeviceInfo().
|
||||||
this->saveDeviceInfo();
|
this->saveDeviceInfo();
|
||||||
if (!drivers.loadDriver(driverName)) {
|
if (!drivers.loadDriver(driverName)) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: unable to load driver (" << driverName << ").");
|
ATA_ERROR("unable to load driver (" << driverName << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
result = ASIOInit(&driverInfo);
|
result = ASIOInit(&driverInfo);
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: error (" << getAsioErrorString(result) << ") initializing driver (" << driverName << ").");
|
ATA_ERROR("error (" << getAsioErrorString(result) << ") initializing driver (" << driverName << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,7 +256,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
result = ASIOGetChannels(&inputChannels, &outputChannels);
|
result = ASIOGetChannels(&inputChannels, &outputChannels);
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
drivers.removeCurrentDriver();
|
drivers.removeCurrentDriver();
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: error (" << getAsioErrorString(result) << ") getting channel count (" << driverName << ").");
|
ATA_ERROR("error (" << getAsioErrorString(result) << ") getting channel count (" << driverName << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( ( _mode == OUTPUT
|
if ( ( _mode == OUTPUT
|
||||||
@ -264,7 +264,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
|| ( _mode == INPUT
|
|| ( _mode == INPUT
|
||||||
&& (_channels+_firstChannel) > (uint32_t) inputChannels)) {
|
&& (_channels+_firstChannel) > (uint32_t) inputChannels)) {
|
||||||
drivers.removeCurrentDriver();
|
drivers.removeCurrentDriver();
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: driver (" << driverName << ") does not support requested channel count (" << _channels << ") + offset (" << _firstChannel << ").");
|
ATA_ERROR("driver (" << driverName << ") does not support requested channel count (" << _channels << ") + offset (" << _firstChannel << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_stream.nDeviceChannels[_mode] = _channels;
|
m_stream.nDeviceChannels[_mode] = _channels;
|
||||||
@ -274,7 +274,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
result = ASIOCanSampleRate((ASIOSampleRate) _sampleRate);
|
result = ASIOCanSampleRate((ASIOSampleRate) _sampleRate);
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
drivers.removeCurrentDriver();
|
drivers.removeCurrentDriver();
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: driver (" << driverName << ") does not support requested sample rate (" << _sampleRate << ").");
|
ATA_ERROR("driver (" << driverName << ") does not support requested sample rate (" << _sampleRate << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Get the current sample rate
|
// Get the current sample rate
|
||||||
@ -282,7 +282,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
result = ASIOGetSampleRate(¤tRate);
|
result = ASIOGetSampleRate(¤tRate);
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
drivers.removeCurrentDriver();
|
drivers.removeCurrentDriver();
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate.");
|
ATA_ERROR("driver (" << driverName << ") error getting sample rate.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Set the sample rate only if necessary
|
// Set the sample rate only if necessary
|
||||||
@ -290,7 +290,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
result = ASIOSetSampleRate((ASIOSampleRate) _sampleRate);
|
result = ASIOSetSampleRate((ASIOSampleRate) _sampleRate);
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
drivers.removeCurrentDriver();
|
drivers.removeCurrentDriver();
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << _sampleRate << ").");
|
ATA_ERROR("driver (" << driverName << ") error setting sample rate (" << _sampleRate << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -305,7 +305,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
result = ASIOGetChannelInfo(&channelInfo);
|
result = ASIOGetChannelInfo(&channelInfo);
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
drivers.removeCurrentDriver();
|
drivers.removeCurrentDriver();
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString(result) << ") getting data format.");
|
ATA_ERROR("driver (" << driverName << ") error (" << getAsioErrorString(result) << ") getting data format.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Assuming WINDOWS host is always little-endian.
|
// Assuming WINDOWS host is always little-endian.
|
||||||
@ -345,7 +345,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
}
|
}
|
||||||
if (m_stream.deviceFormat[_mode] == 0) {
|
if (m_stream.deviceFormat[_mode] == 0) {
|
||||||
drivers.removeCurrentDriver();
|
drivers.removeCurrentDriver();
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: driver (" << driverName << ") data format not supported by RtAudio.");
|
ATA_ERROR("driver (" << driverName << ") data format not supported by RtAudio.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Set the buffer size. For a duplex stream, this will end up
|
// Set the buffer size. For a duplex stream, this will end up
|
||||||
@ -355,7 +355,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
result = ASIOGetBufferSize(&minSize, &maxSize, &preferSize, &granularity);
|
result = ASIOGetBufferSize(&minSize, &maxSize, &preferSize, &granularity);
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
drivers.removeCurrentDriver();
|
drivers.removeCurrentDriver();
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString(result) << ") getting buffer size.");
|
ATA_ERROR("driver (" << driverName << ") error (" << getAsioErrorString(result) << ") getting buffer size.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (*_bufferSize < (uint32_t) minSize) {
|
if (*_bufferSize < (uint32_t) minSize) {
|
||||||
@ -397,7 +397,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
&& m_stream.mode == OUTPUT
|
&& m_stream.mode == OUTPUT
|
||||||
&& m_stream.bufferSize != *_bufferSize) {
|
&& m_stream.bufferSize != *_bufferSize) {
|
||||||
drivers.removeCurrentDriver();
|
drivers.removeCurrentDriver();
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: input/output buffersize discrepancy!");
|
ATA_ERROR("input/output buffersize discrepancy!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_stream.bufferSize = *_bufferSize;
|
m_stream.bufferSize = *_bufferSize;
|
||||||
@ -416,7 +416,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
handle = new AsioHandle;
|
handle = new AsioHandle;
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
drivers.removeCurrentDriver();
|
drivers.removeCurrentDriver();
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: error allocating AsioHandle memory.");
|
ATA_ERROR("error allocating AsioHandle memory.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
handle->bufferInfos = 0;
|
handle->bufferInfos = 0;
|
||||||
@ -444,7 +444,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
uint32_t i, nChannels = m_stream.nDeviceChannels[0] + m_stream.nDeviceChannels[1];
|
uint32_t i, nChannels = m_stream.nDeviceChannels[0] + m_stream.nDeviceChannels[1];
|
||||||
handle->bufferInfos = (ASIOBufferInfo *) malloc(nChannels * sizeof(ASIOBufferInfo));
|
handle->bufferInfos = (ASIOBufferInfo *) malloc(nChannels * sizeof(ASIOBufferInfo));
|
||||||
if (handle->bufferInfos == nullptr) {
|
if (handle->bufferInfos == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: error allocating bufferInfo memory for driver (" << driverName << ").");
|
ATA_ERROR("error allocating bufferInfo memory for driver (" << driverName << ").");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
ASIOBufferInfo *infos;
|
ASIOBufferInfo *infos;
|
||||||
@ -466,7 +466,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
asioCallbacks.bufferSwitchTimeInfo = nullptr;
|
asioCallbacks.bufferSwitchTimeInfo = nullptr;
|
||||||
result = ASIOCreateBuffers(handle->bufferInfos, nChannels, m_stream.bufferSize, &asioCallbacks);
|
result = ASIOCreateBuffers(handle->bufferInfos, nChannels, m_stream.bufferSize, &asioCallbacks);
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString(result) << ") creating buffers.");
|
ATA_ERROR("driver (" << driverName << ") error (" << getAsioErrorString(result) << ") creating buffers.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
buffersAllocated = true;
|
buffersAllocated = true;
|
||||||
@ -484,7 +484,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
bufferBytes = m_stream.nUserChannels[_mode] * *_bufferSize * formatBytes(m_stream.userFormat);
|
bufferBytes = m_stream.nUserChannels[_mode] * *_bufferSize * formatBytes(m_stream.userFormat);
|
||||||
m_stream.userBuffer[_mode] = (char *) calloc(bufferBytes, 1);
|
m_stream.userBuffer[_mode] = (char *) calloc(bufferBytes, 1);
|
||||||
if (m_stream.userBuffer[_mode] == nullptr) {
|
if (m_stream.userBuffer[_mode] == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: error allocating user buffer memory.");
|
ATA_ERROR("error allocating user buffer memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (m_stream.doConvertBuffer[_mode]) {
|
if (m_stream.doConvertBuffer[_mode]) {
|
||||||
@ -506,7 +506,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
}
|
}
|
||||||
m_stream.deviceBuffer = (char *) calloc(bufferBytes, 1);
|
m_stream.deviceBuffer = (char *) calloc(bufferBytes, 1);
|
||||||
if (m_stream.deviceBuffer == nullptr) {
|
if (m_stream.deviceBuffer == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: error allocating device buffer memory.");
|
ATA_ERROR("error allocating device buffer memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -526,7 +526,7 @@ bool airtaudio::api::Asio::probeDeviceOpen(uint32_t _device,
|
|||||||
// Determine device latencies
|
// Determine device latencies
|
||||||
result = ASIOGetLatencies(&inputLatency, &outputLatency);
|
result = ASIOGetLatencies(&inputLatency, &outputLatency);
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString(result) << ") getting latency.");
|
ATA_ERROR("driver (" << driverName << ") error (" << getAsioErrorString(result) << ") getting latency.");
|
||||||
} else {
|
} else {
|
||||||
m_stream.latency[0] = outputLatency;
|
m_stream.latency[0] = outputLatency;
|
||||||
m_stream.latency[1] = inputLatency;
|
m_stream.latency[1] = inputLatency;
|
||||||
@ -568,7 +568,7 @@ error:
|
|||||||
|
|
||||||
enum airtaudio::errorType airtaudio::api::Asio::closeStream() {
|
enum airtaudio::errorType airtaudio::api::Asio::closeStream() {
|
||||||
if (m_stream.state == STREAM_CLOSED) {
|
if (m_stream.state == STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::closeStream(): no open stream to close!");
|
ATA_ERROR("no open stream to close!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_RUNNING) {
|
if (m_stream.state == STREAM_RUNNING) {
|
||||||
@ -608,13 +608,13 @@ enum airtaudio::errorType airtaudio::api::Asio::startStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_RUNNING) {
|
if (m_stream.state == STREAM_RUNNING) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::startStream(): the stream is already running!");
|
ATA_ERROR("the stream is already running!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
AsioHandle *handle = (AsioHandle *) m_stream.apiHandle;
|
AsioHandle *handle = (AsioHandle *) m_stream.apiHandle;
|
||||||
ASIOError result = ASIOStart();
|
ASIOError result = ASIOStart();
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::startStream: error (" << getAsioErrorString(result) << ") starting device.");
|
ATA_ERROR("error (" << getAsioErrorString(result) << ") starting device.");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
handle->drainCounter = 0;
|
handle->drainCounter = 0;
|
||||||
@ -635,7 +635,7 @@ enum airtaudio::errorType airtaudio::api::Asio::stopStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_STOPPED) {
|
if (m_stream.state == STREAM_STOPPED) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::stopStream(): the stream is already stopped!");
|
ATA_ERROR("the stream is already stopped!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
AsioHandle *handle = (AsioHandle *) m_stream.apiHandle;
|
AsioHandle *handle = (AsioHandle *) m_stream.apiHandle;
|
||||||
@ -648,7 +648,7 @@ enum airtaudio::errorType airtaudio::api::Asio::stopStream() {
|
|||||||
m_stream.state = STREAM_STOPPED;
|
m_stream.state = STREAM_STOPPED;
|
||||||
ASIOError result = ASIOStop();
|
ASIOError result = ASIOStop();
|
||||||
if (result != ASE_OK) {
|
if (result != ASE_OK) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::stopStream: error (" << getAsioErrorString(result) << ") stopping device.");
|
ATA_ERROR("error (" << getAsioErrorString(result) << ") stopping device.");
|
||||||
}
|
}
|
||||||
if (result == ASE_OK) {
|
if (result == ASE_OK) {
|
||||||
return airtaudio::errorNone;
|
return airtaudio::errorNone;
|
||||||
@ -661,7 +661,7 @@ enum airtaudio::errorType airtaudio::api::Asio::abortStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_STOPPED) {
|
if (m_stream.state == STREAM_STOPPED) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::abortStream(): the stream is already stopped!");
|
ATA_ERROR("the stream is already stopped!");
|
||||||
error(airtaudio::errorWarning);
|
error(airtaudio::errorWarning);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -694,7 +694,7 @@ bool airtaudio::api::Asio::callbackEvent(long bufferIndex) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_CLOSED) {
|
if (m_stream.state == STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::api::Asio::callbackEvent(): the stream is closed ... this shouldn't happen!");
|
ATA_ERROR("the stream is closed ... this shouldn't happen!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CallbackInfo *info = (CallbackInfo *) &m_stream.callbackInfo;
|
CallbackInfo *info = (CallbackInfo *) &m_stream.callbackInfo;
|
||||||
@ -842,9 +842,9 @@ static void sampleRateChanged(ASIOSampleRate _sRate) {
|
|||||||
RtApi* object = (RtApi*)asioCallbackInfo->object;
|
RtApi* object = (RtApi*)asioCallbackInfo->object;
|
||||||
enum airtaudio::errorType ret = object->stopStream()
|
enum airtaudio::errorType ret = object->stopStream()
|
||||||
if (ret != airtaudio::errorNone) {
|
if (ret != airtaudio::errorNone) {
|
||||||
ATA_ERROR("airtaudio::api::Asio:: sampleRateChanged() error!");
|
ATA_ERROR("error stop stream!");
|
||||||
} else {
|
} else {
|
||||||
ATA_ERROR("airtaudio::api::Asio:: driver reports sample rate changed to " << _sRate << " ... stream stopped!!!");
|
ATA_ERROR("driver reports sample rate changed to " << _sRate << " ... stream stopped!!!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -871,7 +871,7 @@ static long asioMessages(long _selector, long _value, void* _message, double* _o
|
|||||||
// done by completely destruct is. I.e. ASIOStop(),
|
// done by completely destruct is. I.e. ASIOStop(),
|
||||||
// ASIODisposeBuffers(), Destruction Afterwards you initialize the
|
// ASIODisposeBuffers(), Destruction Afterwards you initialize the
|
||||||
// driver again.
|
// driver again.
|
||||||
ATA_ERROR("airtaudio::api::Asio:: driver reset requested!!!");
|
ATA_ERROR("driver reset requested!!!");
|
||||||
ret = 1L;
|
ret = 1L;
|
||||||
break;
|
break;
|
||||||
case kAsioResyncRequest:
|
case kAsioResyncRequest:
|
||||||
@ -882,7 +882,7 @@ static long asioMessages(long _selector, long _value, void* _message, double* _o
|
|||||||
// which could lose data because the Mutex was held too long by
|
// which could lose data because the Mutex was held too long by
|
||||||
// another thread. However a driver can issue it in other
|
// another thread. However a driver can issue it in other
|
||||||
// situations, too.
|
// situations, too.
|
||||||
// ATA_ERROR("airtaudio::api::Asio:: driver resync requested!!!");
|
// ATA_ERROR("driver resync requested!!!");
|
||||||
asioXRun = true;
|
asioXRun = true;
|
||||||
ret = 1L;
|
ret = 1L;
|
||||||
break;
|
break;
|
||||||
@ -891,7 +891,7 @@ static long asioMessages(long _selector, long _value, void* _message, double* _o
|
|||||||
// latencies changed. Beware, it this does not mean that the
|
// latencies changed. Beware, it this does not mean that the
|
||||||
// buffer sizes have changed! You might need to update internal
|
// buffer sizes have changed! You might need to update internal
|
||||||
// delay data.
|
// delay data.
|
||||||
ATA_ERROR("airtaudio::api::Asio:: driver latency may have changed!!!");
|
ATA_ERROR("driver latency may have changed!!!");
|
||||||
ret = 1L;
|
ret = 1L;
|
||||||
break;
|
break;
|
||||||
case kAsioEngineVersion:
|
case kAsioEngineVersion:
|
||||||
|
@ -41,7 +41,7 @@ namespace airtaudio {
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options);
|
airtaudio::StreamOptions *_options);
|
||||||
};
|
};
|
||||||
|
@ -86,7 +86,7 @@ airtaudio::api::Core::Core() {
|
|||||||
sizeof(CFRunLoopRef),
|
sizeof(CFRunLoopRef),
|
||||||
&theRunLoop);
|
&theRunLoop);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::RtApiCore: error setting run loop property!");
|
ATA_ERROR("error setting run loop property!");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ uint32_t airtaudio::api::Core::getDeviceCount() {
|
|||||||
};
|
};
|
||||||
OSStatus result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, nullptr, &dataSize);
|
OSStatus result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, nullptr, &dataSize);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::getDeviceCount: OS-X error getting device info!");
|
ATA_ERROR("OS-X error getting device info!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return dataSize / sizeof(AudioDeviceID);
|
return dataSize / sizeof(AudioDeviceID);
|
||||||
@ -135,7 +135,7 @@ uint32_t airtaudio::api::Core::getDefaultInputDevice() {
|
|||||||
&dataSize,
|
&dataSize,
|
||||||
&id);
|
&id);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::getDefaultInputDevice: OS-X system error getting device.");
|
ATA_ERROR("OS-X system error getting device.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dataSize *= nDevices;
|
dataSize *= nDevices;
|
||||||
@ -148,7 +148,7 @@ uint32_t airtaudio::api::Core::getDefaultInputDevice() {
|
|||||||
&dataSize,
|
&dataSize,
|
||||||
(void*)&deviceList);
|
(void*)&deviceList);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::getDefaultInputDevice: OS-X system error getting device IDs.");
|
ATA_ERROR("OS-X system error getting device IDs.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (uint32_t iii=0; iii<nDevices; iii++) {
|
for (uint32_t iii=0; iii<nDevices; iii++) {
|
||||||
@ -156,7 +156,7 @@ uint32_t airtaudio::api::Core::getDefaultInputDevice() {
|
|||||||
return iii;
|
return iii;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ATA_ERROR("airtaudio::api::Core::getDefaultInputDevice: No default device found!");
|
ATA_ERROR("No default device found!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ uint32_t airtaudio::api::Core::getDefaultOutputDevice() {
|
|||||||
&dataSize,
|
&dataSize,
|
||||||
&id);
|
&id);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::getDefaultOutputDevice: OS-X system error getting device.");
|
ATA_ERROR("OS-X system error getting device.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dataSize = sizeof(AudioDeviceID) * nDevices;
|
dataSize = sizeof(AudioDeviceID) * nDevices;
|
||||||
@ -192,7 +192,7 @@ uint32_t airtaudio::api::Core::getDefaultOutputDevice() {
|
|||||||
&dataSize,
|
&dataSize,
|
||||||
(void*)&deviceList);
|
(void*)&deviceList);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::getDefaultOutputDevice: OS-X system error getting device IDs.");
|
ATA_ERROR("OS-X system error getting device IDs.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (uint32_t iii=0; iii<nDevices; iii++) {
|
for (uint32_t iii=0; iii<nDevices; iii++) {
|
||||||
@ -200,7 +200,7 @@ uint32_t airtaudio::api::Core::getDefaultOutputDevice() {
|
|||||||
return iii;
|
return iii;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ATA_ERROR("airtaudio::api::Core::getDefaultOutputDevice: No default device found!");
|
ATA_ERROR("No default device found!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,11 +210,11 @@ airtaudio::DeviceInfo airtaudio::api::Core::getDeviceInfo(uint32_t _device) {
|
|||||||
// Get device ID
|
// Get device ID
|
||||||
uint32_t nDevices = getDeviceCount();
|
uint32_t nDevices = getDeviceCount();
|
||||||
if (nDevices == 0) {
|
if (nDevices == 0) {
|
||||||
ATA_ERROR("airtaudio::api::Core::getDeviceInfo: no devices found!");
|
ATA_ERROR("no devices found!");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
if (_device >= nDevices) {
|
if (_device >= nDevices) {
|
||||||
ATA_ERROR("airtaudio::api::Core::getDeviceInfo: device ID is invalid!");
|
ATA_ERROR("device ID is invalid!");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
AudioDeviceID deviceList[ nDevices ];
|
AudioDeviceID deviceList[ nDevices ];
|
||||||
@ -231,7 +231,7 @@ airtaudio::DeviceInfo airtaudio::api::Core::getDeviceInfo(uint32_t _device) {
|
|||||||
&dataSize,
|
&dataSize,
|
||||||
(void*)&deviceList);
|
(void*)&deviceList);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::getDeviceInfo: OS-X system error getting device IDs.");
|
ATA_ERROR("OS-X system error getting device IDs.");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
AudioDeviceID id = deviceList[ _device ];
|
AudioDeviceID id = deviceList[ _device ];
|
||||||
@ -242,7 +242,7 @@ airtaudio::DeviceInfo airtaudio::api::Core::getDeviceInfo(uint32_t _device) {
|
|||||||
property.mSelector = kAudioObjectPropertyManufacturer;
|
property.mSelector = kAudioObjectPropertyManufacturer;
|
||||||
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &cfname);
|
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &cfname);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceInfo: system error (" << getErrorCode(result) << ") getting device manufacturer.");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting device manufacturer.");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
//const char *mname = CFStringGetCStringPtr(cfname, CFStringGetSystemEncoding());
|
//const char *mname = CFStringGetCStringPtr(cfname, CFStringGetSystemEncoding());
|
||||||
@ -256,7 +256,7 @@ airtaudio::DeviceInfo airtaudio::api::Core::getDeviceInfo(uint32_t _device) {
|
|||||||
property.mSelector = kAudioObjectPropertyName;
|
property.mSelector = kAudioObjectPropertyName;
|
||||||
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &cfname);
|
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &cfname);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceInfo: system error (" << getErrorCode(result) << ") getting device name.");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting device name.");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
//const char *name = CFStringGetCStringPtr(cfname, CFStringGetSystemEncoding());
|
//const char *name = CFStringGetCStringPtr(cfname, CFStringGetSystemEncoding());
|
||||||
@ -274,20 +274,20 @@ airtaudio::DeviceInfo airtaudio::api::Core::getDeviceInfo(uint32_t _device) {
|
|||||||
dataSize = 0;
|
dataSize = 0;
|
||||||
result = AudioObjectGetPropertyDataSize(id, &property, 0, nullptr, &dataSize);
|
result = AudioObjectGetPropertyDataSize(id, &property, 0, nullptr, &dataSize);
|
||||||
if (result != noErr || dataSize == 0) {
|
if (result != noErr || dataSize == 0) {
|
||||||
ATA_ERROR("airtaudio::api::Core::getDeviceInfo: system error (" << getErrorCode(result) << ") getting output stream configuration info for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting output stream configuration info for device (" << _device << ").");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
// Allocate the AudioBufferList.
|
// Allocate the AudioBufferList.
|
||||||
bufferList = (AudioBufferList *) malloc(dataSize);
|
bufferList = (AudioBufferList *) malloc(dataSize);
|
||||||
if (bufferList == nullptr) {
|
if (bufferList == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::getDeviceInfo: memory error allocating output AudioBufferList.");
|
ATA_ERROR("memory error allocating output AudioBufferList.");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, bufferList);
|
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, bufferList);
|
||||||
if ( result != noErr
|
if ( result != noErr
|
||||||
|| dataSize == 0) {
|
|| dataSize == 0) {
|
||||||
free(bufferList);
|
free(bufferList);
|
||||||
ATA_ERROR("airtaudio::api::Core::getDeviceInfo: system error (" << getErrorCode(result) << ") getting output stream configuration for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting output stream configuration for device (" << _device << ").");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
// Get output channel information.
|
// Get output channel information.
|
||||||
@ -301,19 +301,19 @@ airtaudio::DeviceInfo airtaudio::api::Core::getDeviceInfo(uint32_t _device) {
|
|||||||
result = AudioObjectGetPropertyDataSize(id, &property, 0, nullptr, &dataSize);
|
result = AudioObjectGetPropertyDataSize(id, &property, 0, nullptr, &dataSize);
|
||||||
if ( result != noErr
|
if ( result != noErr
|
||||||
|| dataSize == 0) {
|
|| dataSize == 0) {
|
||||||
ATA_ERROR("airtaudio::api::Core::getDeviceInfo: system error (" << getErrorCode(result) << ") getting input stream configuration info for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting input stream configuration info for device (" << _device << ").");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
// Allocate the AudioBufferList.
|
// Allocate the AudioBufferList.
|
||||||
bufferList = (AudioBufferList *) malloc(dataSize);
|
bufferList = (AudioBufferList *) malloc(dataSize);
|
||||||
if (bufferList == nullptr) {
|
if (bufferList == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::getDeviceInfo: memory error allocating input AudioBufferList.");
|
ATA_ERROR("memory error allocating input AudioBufferList.");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, bufferList);
|
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, bufferList);
|
||||||
if (result != noErr || dataSize == 0) {
|
if (result != noErr || dataSize == 0) {
|
||||||
free(bufferList);
|
free(bufferList);
|
||||||
ATA_ERROR("airtaudio::api::Core::getDeviceInfo: system error (" << getErrorCode(result) << ") getting input stream configuration for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting input stream configuration for device (" << _device << ").");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
// Get input channel information.
|
// Get input channel information.
|
||||||
@ -338,14 +338,14 @@ airtaudio::DeviceInfo airtaudio::api::Core::getDeviceInfo(uint32_t _device) {
|
|||||||
result = AudioObjectGetPropertyDataSize(id, &property, 0, nullptr, &dataSize);
|
result = AudioObjectGetPropertyDataSize(id, &property, 0, nullptr, &dataSize);
|
||||||
if ( result != kAudioHardwareNoError
|
if ( result != kAudioHardwareNoError
|
||||||
|| dataSize == 0) {
|
|| dataSize == 0) {
|
||||||
ATA_ERROR("airtaudio::api::Core::getDeviceInfo: system error (" << getErrorCode(result) << ") getting sample rate info.");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting sample rate info.");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
uint32_t nRanges = dataSize / sizeof(AudioValueRange);
|
uint32_t nRanges = dataSize / sizeof(AudioValueRange);
|
||||||
AudioValueRange rangeList[ nRanges ];
|
AudioValueRange rangeList[ nRanges ];
|
||||||
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &rangeList);
|
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &rangeList);
|
||||||
if (result != kAudioHardwareNoError) {
|
if (result != kAudioHardwareNoError) {
|
||||||
ATA_ERROR("airtaudio::api::Core::getDeviceInfo: system error (" << getErrorCode(result) << ") getting sample rates.");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting sample rates.");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
double minimumRate = 100000000.0, maximumRate = 0.0;
|
double minimumRate = 100000000.0, maximumRate = 0.0;
|
||||||
@ -364,13 +364,13 @@ airtaudio::DeviceInfo airtaudio::api::Core::getDeviceInfo(uint32_t _device) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (info.sampleRates.size() == 0) {
|
if (info.sampleRates.size() == 0) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceInfo: No supported sample rates found for device (" << _device << ").");
|
ATA_ERROR("No supported sample rates found for device (" << _device << ").");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
// CoreAudio always uses 32-bit floating point data for PCM streams.
|
// CoreAudio always uses 32-bit floating point data for PCM streams.
|
||||||
// Thus, any other "physical" formats supported by the device are of
|
// Thus, any other "physical" formats supported by the device are of
|
||||||
// no interest to the client.
|
// no interest to the client.
|
||||||
info.nativeFormats = FLOAT32;
|
info.nativeFormats.push_back(audio::format_float);
|
||||||
if (info.outputChannels > 0) {
|
if (info.outputChannels > 0) {
|
||||||
if (getDefaultOutputDevice() == _device) {
|
if (getDefaultOutputDevice() == _device) {
|
||||||
info.isDefaultOutput = true;
|
info.isDefaultOutput = true;
|
||||||
@ -438,19 +438,19 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options) {
|
airtaudio::StreamOptions *_options) {
|
||||||
// Get device ID
|
// Get device ID
|
||||||
uint32_t nDevices = getDeviceCount();
|
uint32_t nDevices = getDeviceCount();
|
||||||
if (nDevices == 0) {
|
if (nDevices == 0) {
|
||||||
// This should not happen because a check is made before this function is called.
|
// This should not happen because a check is made before this function is called.
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: no devices found!");
|
ATA_ERROR("no devices found!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_device >= nDevices) {
|
if (_device >= nDevices) {
|
||||||
// This should not happen because a check is made before this function is called.
|
// This should not happen because a check is made before this function is called.
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: device ID is invalid!");
|
ATA_ERROR("device ID is invalid!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
AudioDeviceID deviceList[ nDevices ];
|
AudioDeviceID deviceList[ nDevices ];
|
||||||
@ -467,7 +467,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
&dataSize,
|
&dataSize,
|
||||||
(void *) &deviceList);
|
(void *) &deviceList);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: OS-X system error getting device IDs.");
|
ATA_ERROR("OS-X system error getting device IDs.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
AudioDeviceID id = deviceList[ _device ];
|
AudioDeviceID id = deviceList[ _device ];
|
||||||
@ -486,19 +486,19 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
result = AudioObjectGetPropertyDataSize(id, &property, 0, nullptr, &dataSize);
|
result = AudioObjectGetPropertyDataSize(id, &property, 0, nullptr, &dataSize);
|
||||||
if ( result != noErr
|
if ( result != noErr
|
||||||
|| dataSize == 0) {
|
|| dataSize == 0) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting stream configuration info for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream configuration info for device (" << _device << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Allocate the AudioBufferList.
|
// Allocate the AudioBufferList.
|
||||||
bufferList = (AudioBufferList *) malloc(dataSize);
|
bufferList = (AudioBufferList *) malloc(dataSize);
|
||||||
if (bufferList == nullptr) {
|
if (bufferList == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: memory error allocating AudioBufferList.");
|
ATA_ERROR("memory error allocating AudioBufferList.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, bufferList);
|
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, bufferList);
|
||||||
if ( result != noErr
|
if ( result != noErr
|
||||||
|| dataSize == 0) {
|
|| dataSize == 0) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting stream configuration for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream configuration for device (" << _device << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Search for one or more streams that contain the desired number of
|
// Search for one or more streams that contain the desired number of
|
||||||
@ -521,7 +521,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
}
|
}
|
||||||
if (deviceChannels < (_channels + _firstChannel)) {
|
if (deviceChannels < (_channels + _firstChannel)) {
|
||||||
free(bufferList);
|
free(bufferList);
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: the device (" << _device << ") does not support the requested channel count.");
|
ATA_ERROR("the device (" << _device << ") does not support the requested channel count.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Look for a single stream meeting our needs.
|
// Look for a single stream meeting our needs.
|
||||||
@ -573,7 +573,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
property.mSelector = kAudioDevicePropertyBufferFrameSizeRange;
|
property.mSelector = kAudioDevicePropertyBufferFrameSizeRange;
|
||||||
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &bufferRange);
|
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &bufferRange);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting buffer size range for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting buffer size range for device (" << _device << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (bufferRange.mMinimum > *_bufferSize) {
|
if (bufferRange.mMinimum > *_bufferSize) {
|
||||||
@ -592,7 +592,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
property.mSelector = kAudioDevicePropertyBufferFrameSize;
|
property.mSelector = kAudioDevicePropertyBufferFrameSize;
|
||||||
result = AudioObjectSetPropertyData(id, &property, 0, nullptr, dataSize, &theSize);
|
result = AudioObjectSetPropertyData(id, &property, 0, nullptr, dataSize, &theSize);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error (" << getErrorCode(result) << ") setting the buffer size for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") setting the buffer size for device (" << _device << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// If attempting to setup a duplex stream, the bufferSize parameter
|
// If attempting to setup a duplex stream, the bufferSize parameter
|
||||||
@ -601,7 +601,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
if ( m_stream.mode == OUTPUT
|
if ( m_stream.mode == OUTPUT
|
||||||
&& _mode == INPUT
|
&& _mode == INPUT
|
||||||
&& *_bufferSize != m_stream.bufferSize) {
|
&& *_bufferSize != m_stream.bufferSize) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error setting buffer size for duplex stream on device (" << _device << ").");
|
ATA_ERROR("system error setting buffer size for duplex stream on device (" << _device << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_stream.bufferSize = *_bufferSize;
|
m_stream.bufferSize = *_bufferSize;
|
||||||
@ -614,14 +614,14 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
property.mSelector = kAudioDevicePropertyHogMode;
|
property.mSelector = kAudioDevicePropertyHogMode;
|
||||||
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &hog_pid);
|
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &hog_pid);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting 'hog' state!");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting 'hog' state!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (hog_pid != getpid()) {
|
if (hog_pid != getpid()) {
|
||||||
hog_pid = getpid();
|
hog_pid = getpid();
|
||||||
result = AudioObjectSetPropertyData(id, &property, 0, nullptr, dataSize, &hog_pid);
|
result = AudioObjectSetPropertyData(id, &property, 0, nullptr, dataSize, &hog_pid);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error (" << getErrorCode(result) << ") setting 'hog' state!");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") setting 'hog' state!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -632,7 +632,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
property.mSelector = kAudioDevicePropertyNominalSampleRate;
|
property.mSelector = kAudioDevicePropertyNominalSampleRate;
|
||||||
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &nominalRate);
|
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &nominalRate);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting current sample rate.");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting current sample rate.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Only change the sample rate if off by more than 1 Hz.
|
// Only change the sample rate if off by more than 1 Hz.
|
||||||
@ -642,13 +642,13 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
AudioObjectPropertyAddress tmp = { kAudioDevicePropertyNominalSampleRate, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
|
AudioObjectPropertyAddress tmp = { kAudioDevicePropertyNominalSampleRate, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
|
||||||
result = AudioObjectAddPropertyListener(id, &tmp, rateListener, (void *) &reportedRate);
|
result = AudioObjectAddPropertyListener(id, &tmp, rateListener, (void *) &reportedRate);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error (" << getErrorCode(result) << ") setting sample rate property listener for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") setting sample rate property listener for device (" << _device << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
nominalRate = (double) _sampleRate;
|
nominalRate = (double) _sampleRate;
|
||||||
result = AudioObjectSetPropertyData(id, &property, 0, nullptr, dataSize, &nominalRate);
|
result = AudioObjectSetPropertyData(id, &property, 0, nullptr, dataSize, &nominalRate);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error (" << getErrorCode(result) << ") setting sample rate for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") setting sample rate for device (" << _device << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Now wait until the reported nominal rate is what we just set.
|
// Now wait until the reported nominal rate is what we just set.
|
||||||
@ -663,7 +663,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
// Remove the property listener.
|
// Remove the property listener.
|
||||||
AudioObjectRemovePropertyListener(id, &tmp, rateListener, (void *) &reportedRate);
|
AudioObjectRemovePropertyListener(id, &tmp, rateListener, (void *) &reportedRate);
|
||||||
if (microCounter > 5000000) {
|
if (microCounter > 5000000) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: timeout waiting for sample rate update for device (" << _device << ").");
|
ATA_ERROR("timeout waiting for sample rate update for device (" << _device << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -674,7 +674,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
property.mSelector = kAudioStreamPropertyVirtualFormat;
|
property.mSelector = kAudioStreamPropertyVirtualFormat;
|
||||||
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &description);
|
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &description);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting stream format for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream format for device (" << _device << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Set the sample rate and data format id. However, only make the
|
// Set the sample rate and data format id. However, only make the
|
||||||
@ -692,7 +692,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
if (updateFormat) {
|
if (updateFormat) {
|
||||||
result = AudioObjectSetPropertyData(id, &property, 0, nullptr, dataSize, &description);
|
result = AudioObjectSetPropertyData(id, &property, 0, nullptr, dataSize, &description);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error (" << getErrorCode(result) << ") setting sample rate or data format for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") setting sample rate or data format for device (" << _device << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -700,7 +700,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
property.mSelector = kAudioStreamPropertyPhysicalFormat;
|
property.mSelector = kAudioStreamPropertyPhysicalFormat;
|
||||||
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &description);
|
result = AudioObjectGetPropertyData(id, &property, 0, nullptr, &dataSize, &description);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting stream physical format for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting stream physical format for device (" << _device << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//std::cout << "Current physical stream format:" << std::endl;
|
//std::cout << "Current physical stream format:" << std::endl;
|
||||||
@ -752,7 +752,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!setPhysicalFormat) {
|
if (!setPhysicalFormat) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error (" << getErrorCode(result) << ") setting physical data format for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") setting physical data format for device (" << _device << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // done setting virtual/physical formats.
|
} // done setting virtual/physical formats.
|
||||||
@ -765,7 +765,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
if (result == kAudioHardwareNoError) {
|
if (result == kAudioHardwareNoError) {
|
||||||
m_stream.latency[ _mode ] = latency;
|
m_stream.latency[ _mode ] = latency;
|
||||||
} else {
|
} else {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting device latency for device (" << _device << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") getting device latency for device (" << _device << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -816,7 +816,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
if (m_stream.apiHandle == 0) {
|
if (m_stream.apiHandle == 0) {
|
||||||
handle = new CoreHandle;
|
handle = new CoreHandle;
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: error allocating CoreHandle memory.");
|
ATA_ERROR("error allocating CoreHandle memory.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_stream.apiHandle = (void *) handle;
|
m_stream.apiHandle = (void *) handle;
|
||||||
@ -833,7 +833,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
m_stream.userBuffer[_mode] = (char *) malloc(bufferBytes * sizeof(char));
|
m_stream.userBuffer[_mode] = (char *) malloc(bufferBytes * sizeof(char));
|
||||||
memset(m_stream.userBuffer[_mode], 0, bufferBytes * sizeof(char));
|
memset(m_stream.userBuffer[_mode], 0, bufferBytes * sizeof(char));
|
||||||
if (m_stream.userBuffer[_mode] == nullptr) {
|
if (m_stream.userBuffer[_mode] == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: error allocating user buffer memory.");
|
ATA_ERROR("error allocating user buffer memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
// If possible, we will make use of the CoreAudio stream buffers as
|
// If possible, we will make use of the CoreAudio stream buffers as
|
||||||
@ -860,7 +860,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
}
|
}
|
||||||
m_stream.deviceBuffer = (char *) calloc(bufferBytes, 1);
|
m_stream.deviceBuffer = (char *) calloc(bufferBytes, 1);
|
||||||
if (m_stream.deviceBuffer == nullptr) {
|
if (m_stream.deviceBuffer == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: error allocating device buffer memory.");
|
ATA_ERROR("error allocating device buffer memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -890,7 +890,7 @@ bool airtaudio::api::Core::probeDeviceOpen(uint32_t _device,
|
|||||||
result = AudioDeviceAddIOProc(id, callbackHandler, (void *) &m_stream.callbackInfo);
|
result = AudioDeviceAddIOProc(id, callbackHandler, (void *) &m_stream.callbackInfo);
|
||||||
#endif
|
#endif
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::probeDeviceOpen: system error setting callback for device (" << _device << ").");
|
ATA_ERROR("system error setting callback for device (" << _device << ").");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if ( m_stream.mode == OUTPUT
|
if ( m_stream.mode == OUTPUT
|
||||||
@ -925,7 +925,7 @@ error:
|
|||||||
|
|
||||||
enum airtaudio::errorType airtaudio::api::Core::closeStream() {
|
enum airtaudio::errorType airtaudio::api::Core::closeStream() {
|
||||||
if (m_stream.state == STREAM_CLOSED) {
|
if (m_stream.state == STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::api::Core::closeStream(): no open stream to close!");
|
ATA_ERROR("no open stream to close!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
CoreHandle *handle = (CoreHandle *) m_stream.apiHandle;
|
CoreHandle *handle = (CoreHandle *) m_stream.apiHandle;
|
||||||
@ -976,7 +976,7 @@ enum airtaudio::errorType airtaudio::api::Core::startStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_RUNNING) {
|
if (m_stream.state == STREAM_RUNNING) {
|
||||||
ATA_ERROR("airtaudio::api::Core::startStream(): the stream is already running!");
|
ATA_ERROR("the stream is already running!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
OSStatus result = noErr;
|
OSStatus result = noErr;
|
||||||
@ -985,7 +985,7 @@ enum airtaudio::errorType airtaudio::api::Core::startStream() {
|
|||||||
|| m_stream.mode == DUPLEX) {
|
|| m_stream.mode == DUPLEX) {
|
||||||
result = AudioDeviceStart(handle->id[0], callbackHandler);
|
result = AudioDeviceStart(handle->id[0], callbackHandler);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::startStream: system error (" << getErrorCode(result) << ") starting callback procedure on device (" << m_stream.device[0] << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") starting callback procedure on device (" << m_stream.device[0] << ").");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -994,7 +994,7 @@ enum airtaudio::errorType airtaudio::api::Core::startStream() {
|
|||||||
&& m_stream.device[0] != m_stream.device[1])) {
|
&& m_stream.device[0] != m_stream.device[1])) {
|
||||||
result = AudioDeviceStart(handle->id[1], callbackHandler);
|
result = AudioDeviceStart(handle->id[1], callbackHandler);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::startStream: system error starting input callback procedure on device (" << m_stream.device[1] << ").");
|
ATA_ERROR("system error starting input callback procedure on device (" << m_stream.device[1] << ").");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1013,7 +1013,7 @@ enum airtaudio::errorType airtaudio::api::Core::stopStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_STOPPED) {
|
if (m_stream.state == STREAM_STOPPED) {
|
||||||
ATA_ERROR("airtaudio::api::Core::stopStream(): the stream is already stopped!");
|
ATA_ERROR("the stream is already stopped!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
OSStatus result = noErr;
|
OSStatus result = noErr;
|
||||||
@ -1027,7 +1027,7 @@ enum airtaudio::errorType airtaudio::api::Core::stopStream() {
|
|||||||
}
|
}
|
||||||
result = AudioDeviceStop(handle->id[0], callbackHandler);
|
result = AudioDeviceStop(handle->id[0], callbackHandler);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::stopStream: system error (" << getErrorCode(result) << ") stopping callback procedure on device (" << m_stream.device[0] << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") stopping callback procedure on device (" << m_stream.device[0] << ").");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1036,7 +1036,7 @@ enum airtaudio::errorType airtaudio::api::Core::stopStream() {
|
|||||||
&& m_stream.device[0] != m_stream.device[1])) {
|
&& m_stream.device[0] != m_stream.device[1])) {
|
||||||
result = AudioDeviceStop(handle->id[1], callbackHandler);
|
result = AudioDeviceStop(handle->id[1], callbackHandler);
|
||||||
if (result != noErr) {
|
if (result != noErr) {
|
||||||
ATA_ERROR("airtaudio::api::Core::stopStream: system error (" << getErrorCode(result) << ") stopping input callback procedure on device (" << m_stream.device[1] << ").");
|
ATA_ERROR("system error (" << getErrorCode(result) << ") stopping input callback procedure on device (" << m_stream.device[1] << ").");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1053,7 +1053,7 @@ enum airtaudio::errorType airtaudio::api::Core::abortStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_STOPPED) {
|
if (m_stream.state == STREAM_STOPPED) {
|
||||||
ATA_ERROR("airtaudio::api::Core::abortStream(): the stream is already stopped!");
|
ATA_ERROR("the stream is already stopped!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
CoreHandle* handle = (CoreHandle*)m_stream.apiHandle;
|
CoreHandle* handle = (CoreHandle*)m_stream.apiHandle;
|
||||||
@ -1080,7 +1080,7 @@ bool airtaudio::api::Core::callbackEvent(AudioDeviceID _deviceId,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_CLOSED) {
|
if (m_stream.state == STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::api::Core::callbackEvent(): the stream is closed ... this shouldn't happen!");
|
ATA_ERROR("the stream is closed ... this shouldn't happen!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CallbackInfo *info = (CallbackInfo *) &m_stream.callbackInfo;
|
CallbackInfo *info = (CallbackInfo *) &m_stream.callbackInfo;
|
||||||
|
@ -45,7 +45,7 @@ namespace airtaudio {
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options);
|
airtaudio::StreamOptions *_options);
|
||||||
static const char* getErrorCode(OSStatus _code);
|
static const char* getErrorCode(OSStatus _code);
|
||||||
|
@ -38,7 +38,7 @@ namespace airtaudio {
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options);
|
airtaudio::StreamOptions *_options);
|
||||||
public:
|
public:
|
||||||
|
@ -50,7 +50,7 @@ airtaudio::api::CoreIos::CoreIos(void) :
|
|||||||
tmp.duplexChannels = 0;
|
tmp.duplexChannels = 0;
|
||||||
tmp.isDefaultOutput = true;
|
tmp.isDefaultOutput = true;
|
||||||
tmp.isDefaultInput = false;
|
tmp.isDefaultInput = false;
|
||||||
tmp.nativeFormats = SINT16;
|
tmp.nativeFormats.push_back(audio::format_int16);
|
||||||
m_devices.push_back(tmp);
|
m_devices.push_back(tmp);
|
||||||
// add default input format:
|
// add default input format:
|
||||||
tmp.name = "in";
|
tmp.name = "in";
|
||||||
@ -60,9 +60,8 @@ airtaudio::api::CoreIos::CoreIos(void) :
|
|||||||
tmp.duplexChannels = 0;
|
tmp.duplexChannels = 0;
|
||||||
tmp.isDefaultOutput = false;
|
tmp.isDefaultOutput = false;
|
||||||
tmp.isDefaultInput = true;
|
tmp.isDefaultInput = true;
|
||||||
tmp.nativeFormats = SINT16;
|
tmp.nativeFormats.push_back(audio::format_int16);
|
||||||
m_devices.push_back(tmp);
|
m_devices.push_back(tmp);
|
||||||
|
|
||||||
ATA_INFO("Create CoreIOs interface (end)");
|
ATA_INFO("Create CoreIOs interface (end)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +176,7 @@ bool airtaudio::api::CoreIos::probeDeviceOpen(uint32_t _device,
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options) {
|
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);
|
||||||
@ -215,7 +214,7 @@ bool airtaudio::api::CoreIos::probeDeviceOpen(uint32_t _device,
|
|||||||
uint64_t bufferBytes = m_stream.nUserChannels[_mode] * m_stream.bufferSize * formatBytes(m_stream.userFormat);
|
uint64_t bufferBytes = m_stream.nUserChannels[_mode] * m_stream.bufferSize * formatBytes(m_stream.userFormat);
|
||||||
m_stream.userBuffer[_mode] = (char *) calloc(bufferBytes, 1);
|
m_stream.userBuffer[_mode] = (char *) calloc(bufferBytes, 1);
|
||||||
if (m_stream.userBuffer[_mode] == nullptr) {
|
if (m_stream.userBuffer[_mode] == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Android::probeDeviceOpen: error allocating user buffer memory.");
|
ATA_ERROR("error allocating user buffer memory.");
|
||||||
}
|
}
|
||||||
setConvertInfo(_mode, _firstChannel);
|
setConvertInfo(_mode, _firstChannel);
|
||||||
}
|
}
|
||||||
|
@ -154,14 +154,14 @@ uint32_t airtaudio::api::Ds::getDeviceCount() {
|
|||||||
probeInfo.dsDevices = &dsDevices;
|
probeInfo.dsDevices = &dsDevices;
|
||||||
HRESULT result = DirectSoundEnumerate((LPDSENUMCALLBACK) deviceQueryCallback, &probeInfo);
|
HRESULT result = DirectSoundEnumerate((LPDSENUMCALLBACK) deviceQueryCallback, &probeInfo);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::getDeviceCount: error (" << getErrorString(result) << ") enumerating output devices!");
|
ATA_ERROR("error (" << getErrorString(result) << ") enumerating output devices!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Query DirectSoundCapture devices.
|
// Query DirectSoundCapture devices.
|
||||||
probeInfo.isInput = true;
|
probeInfo.isInput = true;
|
||||||
result = DirectSoundCaptureEnumerate((LPDSENUMCALLBACK) deviceQueryCallback, &probeInfo);
|
result = DirectSoundCaptureEnumerate((LPDSENUMCALLBACK) deviceQueryCallback, &probeInfo);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::getDeviceCount: error (" << getErrorString(result) << ") enumerating input devices!");
|
ATA_ERROR("error (" << getErrorString(result) << ") enumerating input devices!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Clean out any devices that may have disappeared.
|
// Clean out any devices that may have disappeared.
|
||||||
@ -185,12 +185,12 @@ rtaudio::DeviceInfo airtaudio::api::Ds::getDeviceInfo(uint32_t _device) {
|
|||||||
// Force a query of all devices
|
// Force a query of all devices
|
||||||
getDeviceCount();
|
getDeviceCount();
|
||||||
if (dsDevices.size() == 0) {
|
if (dsDevices.size() == 0) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::getDeviceInfo: no devices found!");
|
ATA_ERROR("no devices found!");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_device >= dsDevices.size()) {
|
if (_device >= dsDevices.size()) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::getDeviceInfo: device ID is invalid!");
|
ATA_ERROR("device ID is invalid!");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
@ -201,14 +201,14 @@ rtaudio::DeviceInfo airtaudio::api::Ds::getDeviceInfo(uint32_t _device) {
|
|||||||
DSCAPS outCaps;
|
DSCAPS outCaps;
|
||||||
result = DirectSoundCreate(dsDevices[ _device ].id[0], &output, nullptr);
|
result = DirectSoundCreate(dsDevices[ _device ].id[0], &output, nullptr);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::getDeviceInfo: error (" << getErrorString(result) << ") opening output device (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") opening output device (" << dsDevices[ _device ].name << ")!");
|
||||||
goto probeInput;
|
goto probeInput;
|
||||||
}
|
}
|
||||||
outCaps.dwSize = sizeof(outCaps);
|
outCaps.dwSize = sizeof(outCaps);
|
||||||
result = output->GetCaps(&outCaps);
|
result = output->GetCaps(&outCaps);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
output->Release();
|
output->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::getDeviceInfo: error (" << getErrorString(result) << ") getting capabilities!");
|
ATA_ERROR("error (" << getErrorString(result) << ") getting capabilities!");
|
||||||
goto probeInput;
|
goto probeInput;
|
||||||
}
|
}
|
||||||
// Get output channel information.
|
// Get output channel information.
|
||||||
@ -223,10 +223,10 @@ rtaudio::DeviceInfo airtaudio::api::Ds::getDeviceInfo(uint32_t _device) {
|
|||||||
}
|
}
|
||||||
// Get format information.
|
// Get format information.
|
||||||
if (outCaps.dwFlags & DSCAPS_PRIMARY16BIT) {
|
if (outCaps.dwFlags & DSCAPS_PRIMARY16BIT) {
|
||||||
info.nativeFormats |= RTAUDIO_SINT16;
|
info.nativeFormats.push_back(audio::format_int16);
|
||||||
}
|
}
|
||||||
if (outCaps.dwFlags & DSCAPS_PRIMARY8BIT) {
|
if (outCaps.dwFlags & DSCAPS_PRIMARY8BIT) {
|
||||||
info.nativeFormats |= RTAUDIO_SINT8;
|
info.nativeFormats.push_back(audio::format_int8);
|
||||||
}
|
}
|
||||||
output->Release();
|
output->Release();
|
||||||
if (getDefaultOutputDevice() == _device) {
|
if (getDefaultOutputDevice() == _device) {
|
||||||
@ -241,7 +241,7 @@ probeInput:
|
|||||||
LPDIRECTSOUNDCAPTURE input;
|
LPDIRECTSOUNDCAPTURE input;
|
||||||
result = DirectSoundCaptureCreate(dsDevices[ _device ].id[1], &input, nullptr);
|
result = DirectSoundCaptureCreate(dsDevices[ _device ].id[1], &input, nullptr);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::getDeviceInfo: error (" << getErrorString(result) << ") opening input device (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") opening input device (" << dsDevices[ _device ].name << ")!");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
DSCCAPS inCaps;
|
DSCCAPS inCaps;
|
||||||
@ -249,7 +249,7 @@ probeInput:
|
|||||||
result = input->GetCaps(&inCaps);
|
result = input->GetCaps(&inCaps);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
input->Release();
|
input->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::getDeviceInfo: error (" << getErrorString(result) << ") getting object capabilities (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") getting object capabilities (" << dsDevices[ _device ].name << ")!");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
// Get input channel information.
|
// Get input channel information.
|
||||||
@ -403,28 +403,28 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
rtaudio::StreamOptions *_options) {
|
rtaudio::StreamOptions *_options) {
|
||||||
if (_channels + _firstChannel > 2) {
|
if (_channels + _firstChannel > 2) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: 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;
|
||||||
}
|
}
|
||||||
uint32_t nDevices = dsDevices.size();
|
uint32_t nDevices = dsDevices.size();
|
||||||
if (nDevices == 0) {
|
if (nDevices == 0) {
|
||||||
// This should not happen because a check is made before this function is called.
|
// This should not happen because a check is made before this function is called.
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: no devices found!");
|
ATA_ERROR("no devices found!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_device >= nDevices) {
|
if (_device >= nDevices) {
|
||||||
// This should not happen because a check is made before this function is called.
|
// This should not happen because a check is made before this function is called.
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: device ID is invalid!");
|
ATA_ERROR("device ID is invalid!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_mode == OUTPUT) {
|
if (_mode == OUTPUT) {
|
||||||
if (dsDevices[ _device ].validId[0] == false) {
|
if (dsDevices[ _device ].validId[0] == false) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: device (" << _device << ") does not support output!");
|
ATA_ERROR("device (" << _device << ") does not support output!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else { // _mode == INPUT
|
} else { // _mode == INPUT
|
||||||
if (dsDevices[ _device ].validId[1] == false) {
|
if (dsDevices[ _device ].validId[1] == false) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: device (" << _device << ") does not support input!");
|
ATA_ERROR("device (" << _device << ") does not support input!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -474,7 +474,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
LPDIRECTSOUND output;
|
LPDIRECTSOUND output;
|
||||||
result = DirectSoundCreate(dsDevices[ _device ].id[0], &output, nullptr);
|
result = DirectSoundCreate(dsDevices[ _device ].id[0], &output, nullptr);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") opening output device (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") opening output device (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
DSCAPS outCaps;
|
DSCAPS outCaps;
|
||||||
@ -482,12 +482,12 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
result = output->GetCaps(&outCaps);
|
result = output->GetCaps(&outCaps);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
output->Release();
|
output->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") getting capabilities (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") getting capabilities (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Check channel information.
|
// Check channel information.
|
||||||
if (_channels + _firstChannel == 2 && !(outCaps.dwFlags & DSCAPS_PRIMARYSTEREO)) {
|
if (_channels + _firstChannel == 2 && !(outCaps.dwFlags & DSCAPS_PRIMARYSTEREO)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::getDeviceInfo: the output device (" << dsDevices[ _device ].name << ") does not support stereo playback.");
|
ATA_ERROR("the output device (" << dsDevices[ _device ].name << ") does not support stereo playback.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Check format information. Use 16-bit format unless not
|
// Check format information. Use 16-bit format unless not
|
||||||
@ -516,7 +516,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
result = output->SetCooperativeLevel(hWnd, DSSCL_PRIORITY);
|
result = output->SetCooperativeLevel(hWnd, DSSCL_PRIORITY);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
output->Release();
|
output->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") setting cooperative level (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") setting cooperative level (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Even though we will write to the secondary buffer, we need to
|
// Even though we will write to the secondary buffer, we need to
|
||||||
@ -532,14 +532,14 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
result = output->CreateSoundBuffer(&bufferDescription, &buffer, nullptr);
|
result = output->CreateSoundBuffer(&bufferDescription, &buffer, nullptr);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
output->Release();
|
output->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") accessing primary buffer (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") accessing primary buffer (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Set the primary DS buffer sound format.
|
// Set the primary DS buffer sound format.
|
||||||
result = buffer->SetFormat(&waveFormat);
|
result = buffer->SetFormat(&waveFormat);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
output->Release();
|
output->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") setting primary buffer format (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") setting primary buffer format (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Setup the secondary DS buffer description.
|
// Setup the secondary DS buffer description.
|
||||||
@ -562,7 +562,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
result = output->CreateSoundBuffer(&bufferDescription, &buffer, nullptr);
|
result = output->CreateSoundBuffer(&bufferDescription, &buffer, nullptr);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
output->Release();
|
output->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") creating secondary buffer (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") creating secondary buffer (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -573,7 +573,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
output->Release();
|
output->Release();
|
||||||
buffer->Release();
|
buffer->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") getting buffer settings (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") getting buffer settings (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
dsBufferSize = dsbcaps.dwBufferBytes;
|
dsBufferSize = dsbcaps.dwBufferBytes;
|
||||||
@ -584,7 +584,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
output->Release();
|
output->Release();
|
||||||
buffer->Release();
|
buffer->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") locking buffer (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") locking buffer (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Zero the DS buffer
|
// Zero the DS buffer
|
||||||
@ -594,7 +594,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
output->Release();
|
output->Release();
|
||||||
buffer->Release();
|
buffer->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") unlocking buffer (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") unlocking buffer (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ohandle = (void *) output;
|
ohandle = (void *) output;
|
||||||
@ -604,7 +604,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
LPDIRECTSOUNDCAPTURE input;
|
LPDIRECTSOUNDCAPTURE input;
|
||||||
result = DirectSoundCaptureCreate(dsDevices[ _device ].id[1], &input, nullptr);
|
result = DirectSoundCaptureCreate(dsDevices[ _device ].id[1], &input, nullptr);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") opening input device (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") opening input device (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
DSCCAPS inCaps;
|
DSCCAPS inCaps;
|
||||||
@ -612,12 +612,12 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
result = input->GetCaps(&inCaps);
|
result = input->GetCaps(&inCaps);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
input->Release();
|
input->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") getting input capabilities (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") getting input capabilities (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Check channel information.
|
// Check channel information.
|
||||||
if (inCaps.dwChannels < _channels + _firstChannel) {
|
if (inCaps.dwChannels < _channels + _firstChannel) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::getDeviceInfo: the input device does not support requested input channels.");
|
ATA_ERROR("the input device does not support requested input channels.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Check format information. Use 16-bit format unless user
|
// Check format information. Use 16-bit format unless user
|
||||||
@ -665,7 +665,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
result = input->CreateCaptureBuffer(&bufferDescription, &buffer, nullptr);
|
result = input->CreateCaptureBuffer(&bufferDescription, &buffer, nullptr);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
input->Release();
|
input->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") creating input buffer (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") creating input buffer (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Get the buffer size ... might be different from what we specified.
|
// Get the buffer size ... might be different from what we specified.
|
||||||
@ -675,7 +675,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
input->Release();
|
input->Release();
|
||||||
buffer->Release();
|
buffer->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") getting buffer settings (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") getting buffer settings (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
dsBufferSize = dscbcaps.dwBufferBytes;
|
dsBufferSize = dscbcaps.dwBufferBytes;
|
||||||
@ -690,7 +690,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
input->Release();
|
input->Release();
|
||||||
buffer->Release();
|
buffer->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") locking input buffer (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") locking input buffer (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Zero the buffer
|
// Zero the buffer
|
||||||
@ -700,7 +700,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
input->Release();
|
input->Release();
|
||||||
buffer->Release();
|
buffer->Release();
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error (" << getErrorString(result) << ") unlocking input buffer (" << dsDevices[ _device ].name << ")!");
|
ATA_ERROR("error (" << getErrorString(result) << ") unlocking input buffer (" << dsDevices[ _device ].name << ")!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ohandle = (void *) input;
|
ohandle = (void *) input;
|
||||||
@ -735,7 +735,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
long bufferBytes = m_stream.nUserChannels[_mode] * *_bufferSize * formatBytes(m_stream.userFormat);
|
long bufferBytes = m_stream.nUserChannels[_mode] * *_bufferSize * formatBytes(m_stream.userFormat);
|
||||||
m_stream.userBuffer[_mode] = (char *) calloc(bufferBytes, 1);
|
m_stream.userBuffer[_mode] = (char *) calloc(bufferBytes, 1);
|
||||||
if (m_stream.userBuffer[_mode] == nullptr) {
|
if (m_stream.userBuffer[_mode] == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error allocating user buffer memory.");
|
ATA_ERROR("error allocating user buffer memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (m_stream.doConvertBuffer[_mode]) {
|
if (m_stream.doConvertBuffer[_mode]) {
|
||||||
@ -756,7 +756,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
}
|
}
|
||||||
m_stream.deviceBuffer = (char *) calloc(bufferBytes, 1);
|
m_stream.deviceBuffer = (char *) calloc(bufferBytes, 1);
|
||||||
if (m_stream.deviceBuffer == nullptr) {
|
if (m_stream.deviceBuffer == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error allocating device buffer memory.");
|
ATA_ERROR("error allocating device buffer memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -765,7 +765,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
if (m_stream.apiHandle == 0) {
|
if (m_stream.apiHandle == 0) {
|
||||||
handle = new DsHandle;
|
handle = new DsHandle;
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error allocating AsioHandle memory.");
|
ATA_ERROR("error allocating AsioHandle memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
// Create a manual-reset event.
|
// Create a manual-reset event.
|
||||||
@ -808,7 +808,7 @@ bool airtaudio::api::Ds::probeDeviceOpen(uint32_t _device,
|
|||||||
0,
|
0,
|
||||||
&threadId);
|
&threadId);
|
||||||
if (m_stream.callbackInfo.thread == 0) {
|
if (m_stream.callbackInfo.thread == 0) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::probeDeviceOpen: error creating callback thread!");
|
ATA_ERROR("error creating callback thread!");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
// Boost DS thread priority
|
// Boost DS thread priority
|
||||||
@ -853,7 +853,7 @@ error:
|
|||||||
|
|
||||||
enum airtaudio::errorType airtaudio::api::Ds::closeStream() {
|
enum airtaudio::errorType airtaudio::api::Ds::closeStream() {
|
||||||
if (m_stream.state == STREAM_CLOSED) {
|
if (m_stream.state == STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::closeStream(): no open stream to close!");
|
ATA_ERROR("no open stream to close!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
// Stop the callback thread.
|
// Stop the callback thread.
|
||||||
@ -903,7 +903,7 @@ enum airtaudio::errorType airtaudio::api::Ds::startStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_RUNNING) {
|
if (m_stream.state == STREAM_RUNNING) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::startStream(): the stream is already running!");
|
ATA_ERROR("the stream is already running!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
DsHandle *handle = (DsHandle *) m_stream.apiHandle;
|
DsHandle *handle = (DsHandle *) m_stream.apiHandle;
|
||||||
@ -923,7 +923,7 @@ enum airtaudio::errorType airtaudio::api::Ds::startStream() {
|
|||||||
LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
|
LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
|
||||||
result = buffer->Play(0, 0, DSBPLAY_LOOPING);
|
result = buffer->Play(0, 0, DSBPLAY_LOOPING);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::startStream: error (" << getErrorString(result) << ") starting output buffer!");
|
ATA_ERROR("error (" << getErrorString(result) << ") starting output buffer!");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -932,7 +932,7 @@ enum airtaudio::errorType airtaudio::api::Ds::startStream() {
|
|||||||
LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
|
LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
|
||||||
result = buffer->Start(DSCBSTART_LOOPING);
|
result = buffer->Start(DSCBSTART_LOOPING);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::startStream: error (" << getErrorString(result) << ") starting input buffer!");
|
ATA_ERROR("error (" << getErrorString(result) << ") starting input buffer!");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -952,7 +952,7 @@ enum airtaudio::errorType airtaudio::api::Ds::stopStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_STOPPED) {
|
if (m_stream.state == STREAM_STOPPED) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::stopStream(): the stream is already stopped!");
|
ATA_ERROR("the stream is already stopped!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
HRESULT result = 0;
|
HRESULT result = 0;
|
||||||
@ -970,14 +970,14 @@ enum airtaudio::errorType airtaudio::api::Ds::stopStream() {
|
|||||||
LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
|
LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
|
||||||
result = buffer->Stop();
|
result = buffer->Stop();
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::stopStream: error (" << getErrorString(result) << ") stopping output buffer!");
|
ATA_ERROR("error (" << getErrorString(result) << ") stopping output buffer!");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
// Lock the buffer and clear it so that if we start to play again,
|
// Lock the buffer and clear it so that if we start to play again,
|
||||||
// we won't have old data playing.
|
// we won't have old data playing.
|
||||||
result = buffer->Lock(0, handle->dsBufferSize[0], &audioPtr, &dataLen, nullptr, nullptr, 0);
|
result = buffer->Lock(0, handle->dsBufferSize[0], &audioPtr, &dataLen, nullptr, nullptr, 0);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::stopStream: error (" << getErrorString(result) << ") locking output buffer!");
|
ATA_ERROR("error (" << getErrorString(result) << ") locking output buffer!");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
// Zero the DS buffer
|
// Zero the DS buffer
|
||||||
@ -985,7 +985,7 @@ enum airtaudio::errorType airtaudio::api::Ds::stopStream() {
|
|||||||
// Unlock the DS buffer
|
// Unlock the DS buffer
|
||||||
result = buffer->Unlock(audioPtr, dataLen, nullptr, 0);
|
result = buffer->Unlock(audioPtr, dataLen, nullptr, 0);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::stopStream: error (" << getErrorString(result) << ") unlocking output buffer!");
|
ATA_ERROR("error (" << getErrorString(result) << ") unlocking output buffer!");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
// If we start playing again, we must begin at beginning of buffer.
|
// If we start playing again, we must begin at beginning of buffer.
|
||||||
@ -999,14 +999,14 @@ enum airtaudio::errorType airtaudio::api::Ds::stopStream() {
|
|||||||
m_stream.state = STREAM_STOPPED;
|
m_stream.state = STREAM_STOPPED;
|
||||||
result = buffer->Stop();
|
result = buffer->Stop();
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::stopStream: error (" << getErrorString(result) << ") stopping input buffer!");
|
ATA_ERROR("error (" << getErrorString(result) << ") stopping input buffer!");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
// Lock the buffer and clear it so that if we start to play again,
|
// Lock the buffer and clear it so that if we start to play again,
|
||||||
// we won't have old data playing.
|
// we won't have old data playing.
|
||||||
result = buffer->Lock(0, handle->dsBufferSize[1], &audioPtr, &dataLen, nullptr, nullptr, 0);
|
result = buffer->Lock(0, handle->dsBufferSize[1], &audioPtr, &dataLen, nullptr, nullptr, 0);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::stopStream: error (" << getErrorString(result) << ") locking input buffer!");
|
ATA_ERROR("error (" << getErrorString(result) << ") locking input buffer!");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
// Zero the DS buffer
|
// Zero the DS buffer
|
||||||
@ -1014,7 +1014,7 @@ enum airtaudio::errorType airtaudio::api::Ds::stopStream() {
|
|||||||
// Unlock the DS buffer
|
// Unlock the DS buffer
|
||||||
result = buffer->Unlock(audioPtr, dataLen, nullptr, 0);
|
result = buffer->Unlock(audioPtr, dataLen, nullptr, 0);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::stopStream: error (" << getErrorString(result) << ") unlocking input buffer!");
|
ATA_ERROR("error (" << getErrorString(result) << ") unlocking input buffer!");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
// If we start recording again, we must begin at beginning of buffer.
|
// If we start recording again, we must begin at beginning of buffer.
|
||||||
@ -1033,7 +1033,7 @@ enum airtaudio::errorType airtaudio::api::Ds::abortStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_STOPPED) {
|
if (m_stream.state == STREAM_STOPPED) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::abortStream(): the stream is already stopped!");
|
ATA_ERROR("the stream is already stopped!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
DsHandle *handle = (DsHandle *) m_stream.apiHandle;
|
DsHandle *handle = (DsHandle *) m_stream.apiHandle;
|
||||||
@ -1047,7 +1047,7 @@ void airtaudio::api::Ds::callbackEvent() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_CLOSED) {
|
if (m_stream.state == STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::callbackEvent(): the stream is closed ... this shouldn't happen!");
|
ATA_ERROR("the stream is closed ... this shouldn't happen!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CallbackInfo *info = (CallbackInfo *) &m_stream.callbackInfo;
|
CallbackInfo *info = (CallbackInfo *) &m_stream.callbackInfo;
|
||||||
@ -1122,23 +1122,23 @@ void airtaudio::api::Ds::callbackEvent() {
|
|||||||
DWORD startSafeWritePointer, startSafeReadPointer;
|
DWORD startSafeWritePointer, startSafeReadPointer;
|
||||||
result = dsWriteBuffer->GetCurrentPosition(nullptr, &startSafeWritePointer);
|
result = dsWriteBuffer->GetCurrentPosition(nullptr, &startSafeWritePointer);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::callbackEvent: error (" << getErrorString(result) << ") getting current write position!");
|
ATA_ERROR("error (" << getErrorString(result) << ") getting current write position!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
result = dsCaptureBuffer->GetCurrentPosition(nullptr, &startSafeReadPointer);
|
result = dsCaptureBuffer->GetCurrentPosition(nullptr, &startSafeReadPointer);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::callbackEvent: error (" << getErrorString(result) << ") getting current read position!");
|
ATA_ERROR("error (" << getErrorString(result) << ") getting current read position!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
result = dsWriteBuffer->GetCurrentPosition(nullptr, &safeWritePointer);
|
result = dsWriteBuffer->GetCurrentPosition(nullptr, &safeWritePointer);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::callbackEvent: error (" << getErrorString(result) << ") getting current write position!");
|
ATA_ERROR("error (" << getErrorString(result) << ") getting current write position!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
result = dsCaptureBuffer->GetCurrentPosition(nullptr, &safeReadPointer);
|
result = dsCaptureBuffer->GetCurrentPosition(nullptr, &safeReadPointer);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::callbackEvent: error (" << getErrorString(result) << ") getting current read position!");
|
ATA_ERROR("error (" << getErrorString(result) << ") getting current read position!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( safeWritePointer != startSafeWritePointer
|
if ( safeWritePointer != startSafeWritePointer
|
||||||
@ -1158,7 +1158,7 @@ void airtaudio::api::Ds::callbackEvent() {
|
|||||||
LPDIRECTSOUNDBUFFER dsWriteBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
|
LPDIRECTSOUNDBUFFER dsWriteBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
|
||||||
result = dsWriteBuffer->GetCurrentPosition(¤tWritePointer, &safeWritePointer);
|
result = dsWriteBuffer->GetCurrentPosition(¤tWritePointer, &safeWritePointer);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::callbackEvent: error (" << getErrorString(result) << ") getting current write position!");
|
ATA_ERROR("error (" << getErrorString(result) << ") getting current write position!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handle->bufferPointer[0] = safeWritePointer + handle->dsPointerLeadTime[0];
|
handle->bufferPointer[0] = safeWritePointer + handle->dsPointerLeadTime[0];
|
||||||
@ -1203,7 +1203,7 @@ void airtaudio::api::Ds::callbackEvent() {
|
|||||||
// Find out where the read and "safe write" pointers are.
|
// Find out where the read and "safe write" pointers are.
|
||||||
result = dsBuffer->GetCurrentPosition(¤tWritePointer, &safeWritePointer);
|
result = dsBuffer->GetCurrentPosition(¤tWritePointer, &safeWritePointer);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::callbackEvent: error (" << getErrorString(result) << ") getting current write position!");
|
ATA_ERROR("error (" << getErrorString(result) << ") getting current write position!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// We will copy our output buffer into the region between
|
// We will copy our output buffer into the region between
|
||||||
@ -1252,7 +1252,7 @@ void airtaudio::api::Ds::callbackEvent() {
|
|||||||
&bufferSize2,
|
&bufferSize2,
|
||||||
0);
|
0);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::callbackEvent: error (" << getErrorString(result) << ") locking buffer during playback!");
|
ATA_ERROR("error (" << getErrorString(result) << ") locking buffer during playback!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Copy our buffer into the DS buffer
|
// Copy our buffer into the DS buffer
|
||||||
@ -1263,7 +1263,7 @@ void airtaudio::api::Ds::callbackEvent() {
|
|||||||
// Update our buffer offset and unlock sound buffer
|
// Update our buffer offset and unlock sound buffer
|
||||||
dsBuffer->Unlock(buffer1, bufferSize1, buffer2, bufferSize2);
|
dsBuffer->Unlock(buffer1, bufferSize1, buffer2, bufferSize2);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::callbackEvent: error (" << getErrorString(result) << ") unlocking buffer during playback!");
|
ATA_ERROR("error (" << getErrorString(result) << ") unlocking buffer during playback!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nextWritePointer = (nextWritePointer + bufferSize1 + bufferSize2) % dsBufferSize;
|
nextWritePointer = (nextWritePointer + bufferSize1 + bufferSize2) % dsBufferSize;
|
||||||
@ -1291,7 +1291,7 @@ void airtaudio::api::Ds::callbackEvent() {
|
|||||||
// Find out where the write and "safe read" pointers are.
|
// Find out where the write and "safe read" pointers are.
|
||||||
result = dsBuffer->GetCurrentPosition(¤tReadPointer, &safeReadPointer);
|
result = dsBuffer->GetCurrentPosition(¤tReadPointer, &safeReadPointer);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::callbackEvent: error (" << getErrorString(result) << ") getting current read position!");
|
ATA_ERROR("error (" << getErrorString(result) << ") getting current read position!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (safeReadPointer < (DWORD)nextReadPointer) {
|
if (safeReadPointer < (DWORD)nextReadPointer) {
|
||||||
@ -1351,7 +1351,7 @@ void airtaudio::api::Ds::callbackEvent() {
|
|||||||
// Wake up and find out where we are now.
|
// Wake up and find out where we are now.
|
||||||
result = dsBuffer->GetCurrentPosition(¤tReadPointer, &safeReadPointer);
|
result = dsBuffer->GetCurrentPosition(¤tReadPointer, &safeReadPointer);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::callbackEvent: error (" << getErrorString(result) << ") getting current read position!");
|
ATA_ERROR("error (" << getErrorString(result) << ") getting current read position!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (safeReadPointer < (DWORD)nextReadPointer) {
|
if (safeReadPointer < (DWORD)nextReadPointer) {
|
||||||
@ -1369,7 +1369,7 @@ void airtaudio::api::Ds::callbackEvent() {
|
|||||||
&bufferSize2,
|
&bufferSize2,
|
||||||
0);
|
0);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::callbackEvent: error (" << getErrorString(result) << ") locking capture buffer!");
|
ATA_ERROR("error (" << getErrorString(result) << ") locking capture buffer!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_duplexPrerollBytes <= 0) {
|
if (m_duplexPrerollBytes <= 0) {
|
||||||
@ -1389,7 +1389,7 @@ void airtaudio::api::Ds::callbackEvent() {
|
|||||||
nextReadPointer = (nextReadPointer + bufferSize1 + bufferSize2) % dsBufferSize;
|
nextReadPointer = (nextReadPointer + bufferSize1 + bufferSize2) % dsBufferSize;
|
||||||
dsBuffer->Unlock(buffer1, bufferSize1, buffer2, bufferSize2);
|
dsBuffer->Unlock(buffer1, bufferSize1, buffer2, bufferSize2);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
ATA_ERROR("airtaudio::api::Ds::callbackEvent: error (" << getErrorString(result) << ") unlocking capture buffer!");
|
ATA_ERROR("error (" << getErrorString(result) << ") unlocking capture buffer!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handle->bufferPointer[1] = nextReadPointer;
|
handle->bufferPointer[1] = nextReadPointer;
|
||||||
|
@ -44,7 +44,7 @@ namespace airtaudio {
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options);
|
airtaudio::StreamOptions *_options);
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,7 @@ airtaudio::Api* airtaudio::api::Dummy::Create() {
|
|||||||
|
|
||||||
|
|
||||||
airtaudio::api::Dummy::Dummy() {
|
airtaudio::api::Dummy::Dummy() {
|
||||||
m_errorText = "airtaudio::api::Dummy: This class provides no functionality.";
|
m_errorText = "This class provides no functionality.";
|
||||||
error(airtaudio::errorWarning);
|
error(airtaudio::errorWarning);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ uint32_t airtaudio::api::Dummy::getDeviceCount() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rtaudio::DeviceInfo airtaudio::api::Dummy::getDeviceInfo(uint32_t _device) {
|
rtaudio::DeviceInfo airtaudio::api::Dummy::getDeviceInfo(uint32_t _device) {
|
||||||
()_device;
|
(void)_device;
|
||||||
rtaudio::DeviceInfo info;
|
rtaudio::DeviceInfo info;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ bool airtaudio::api::Dummy::probeDeviceOpen(uint32_t _device,
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options) {
|
airtaudio::StreamOptions *_options) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -33,7 +33,7 @@ namespace airtaudio {
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options);
|
airtaudio::StreamOptions *_options);
|
||||||
};
|
};
|
||||||
|
@ -127,7 +127,7 @@ airtaudio::DeviceInfo airtaudio::api::Jack::getDeviceInfo(uint32_t _device) {
|
|||||||
jack_status_t *status = nullptr;
|
jack_status_t *status = nullptr;
|
||||||
jack_client_t *client = jack_client_open("RtApiJackInfo", options, status);
|
jack_client_t *client = jack_client_open("RtApiJackInfo", options, status);
|
||||||
if (client == nullptr) {
|
if (client == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::getDeviceInfo: Jack server not found or connection error!");
|
ATA_ERROR("Jack server not found or connection error!");
|
||||||
// TODO : airtaudio::errorWarning;
|
// TODO : airtaudio::errorWarning;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@ -156,7 +156,7 @@ airtaudio::DeviceInfo airtaudio::api::Jack::getDeviceInfo(uint32_t _device) {
|
|||||||
}
|
}
|
||||||
if (_device >= nDevices) {
|
if (_device >= nDevices) {
|
||||||
jack_client_close(client);
|
jack_client_close(client);
|
||||||
ATA_ERROR("airtaudio::api::Jack::getDeviceInfo: device ID is invalid!");
|
ATA_ERROR("device ID is invalid!");
|
||||||
// TODO : airtaudio::errorInvalidUse;
|
// TODO : airtaudio::errorInvalidUse;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@ -186,7 +186,7 @@ airtaudio::DeviceInfo airtaudio::api::Jack::getDeviceInfo(uint32_t _device) {
|
|||||||
}
|
}
|
||||||
if (info.outputChannels == 0 && info.inputChannels == 0) {
|
if (info.outputChannels == 0 && info.inputChannels == 0) {
|
||||||
jack_client_close(client);
|
jack_client_close(client);
|
||||||
ATA_ERROR("airtaudio::api::Jack::getDeviceInfo: error determining Jack input/output channels!");
|
ATA_ERROR("error determining Jack input/output channels!");
|
||||||
// TODO : airtaudio::errorWarning;
|
// TODO : airtaudio::errorWarning;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ airtaudio::DeviceInfo airtaudio::api::Jack::getDeviceInfo(uint32_t _device) {
|
|||||||
info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
|
info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
|
||||||
}
|
}
|
||||||
// Jack always uses 32-bit floats.
|
// Jack always uses 32-bit floats.
|
||||||
info.nativeFormats = airtaudio::FLOAT32;
|
info.nativeFormats.push_back(audio::format_float);
|
||||||
// Jack doesn't provide default devices so we'll use the first available one.
|
// Jack doesn't provide default devices so we'll use the first available one.
|
||||||
if ( _device == 0
|
if ( _device == 0
|
||||||
&& info.outputChannels > 0) {
|
&& info.outputChannels > 0) {
|
||||||
@ -260,7 +260,7 @@ bool airtaudio::api::Jack::probeDeviceOpen(uint32_t _device,
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t* _bufferSize,
|
uint32_t* _bufferSize,
|
||||||
airtaudio::StreamOptions* _options) {
|
airtaudio::StreamOptions* _options) {
|
||||||
JackHandle *handle = (JackHandle *) m_stream.apiHandle;
|
JackHandle *handle = (JackHandle *) m_stream.apiHandle;
|
||||||
@ -277,7 +277,7 @@ bool airtaudio::api::Jack::probeDeviceOpen(uint32_t _device,
|
|||||||
client = jack_client_open("RtApiJack", jackoptions, status);
|
client = jack_client_open("RtApiJack", jackoptions, status);
|
||||||
}
|
}
|
||||||
if (client == 0) {
|
if (client == 0) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::probeDeviceOpen: Jack server not found or connection error!");
|
ATA_ERROR("Jack server not found or connection error!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -308,7 +308,7 @@ bool airtaudio::api::Jack::probeDeviceOpen(uint32_t _device,
|
|||||||
free(ports);
|
free(ports);
|
||||||
}
|
}
|
||||||
if (_device >= nDevices) {
|
if (_device >= nDevices) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::probeDeviceOpen: device ID is invalid!");
|
ATA_ERROR("device ID is invalid!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Count the available ports containing the client name as device
|
// Count the available ports containing the client name as device
|
||||||
@ -325,14 +325,14 @@ bool airtaudio::api::Jack::probeDeviceOpen(uint32_t _device,
|
|||||||
}
|
}
|
||||||
// Compare the jack ports for specified client to the requested number of channels.
|
// Compare the jack ports for specified client to the requested number of channels.
|
||||||
if (nChannels < (_channels + _firstChannel)) {
|
if (nChannels < (_channels + _firstChannel)) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::probeDeviceOpen: requested number of channels (" << _channels << ") + offset (" << _firstChannel << ") not found for specified device (" << _device << ":" << deviceName << ").");
|
ATA_ERROR("requested number of channels (" << _channels << ") + offset (" << _firstChannel << ") not found for specified device (" << _device << ":" << deviceName << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Check the jack server sample rate.
|
// Check the jack server sample rate.
|
||||||
uint32_t jackRate = jack_get_sample_rate(client);
|
uint32_t jackRate = jack_get_sample_rate(client);
|
||||||
if (_sampleRate != jackRate) {
|
if (_sampleRate != jackRate) {
|
||||||
jack_client_close(client);
|
jack_client_close(client);
|
||||||
ATA_ERROR("airtaudio::api::Jack::probeDeviceOpen: the requested sample rate (" << _sampleRate << ") is different than the JACK server rate (" << jackRate << ").");
|
ATA_ERROR("the requested sample rate (" << _sampleRate << ") is different than the JACK server rate (" << jackRate << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_stream.sampleRate = jackRate;
|
m_stream.sampleRate = jackRate;
|
||||||
@ -381,7 +381,7 @@ bool airtaudio::api::Jack::probeDeviceOpen(uint32_t _device,
|
|||||||
if (handle == 0) {
|
if (handle == 0) {
|
||||||
handle = new JackHandle;
|
handle = new JackHandle;
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::probeDeviceOpen: error allocating JackHandle memory.");
|
ATA_ERROR("error allocating JackHandle memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
m_stream.apiHandle = (void *) handle;
|
m_stream.apiHandle = (void *) handle;
|
||||||
@ -393,7 +393,7 @@ bool airtaudio::api::Jack::probeDeviceOpen(uint32_t _device,
|
|||||||
bufferBytes = m_stream.nUserChannels[_mode] * *_bufferSize * formatBytes(m_stream.userFormat);
|
bufferBytes = m_stream.nUserChannels[_mode] * *_bufferSize * formatBytes(m_stream.userFormat);
|
||||||
m_stream.userBuffer[_mode] = (char *) calloc(bufferBytes, 1);
|
m_stream.userBuffer[_mode] = (char *) calloc(bufferBytes, 1);
|
||||||
if (m_stream.userBuffer[_mode] == nullptr) {
|
if (m_stream.userBuffer[_mode] == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::probeDeviceOpen: error allocating user buffer memory.");
|
ATA_ERROR("error allocating user buffer memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (m_stream.doConvertBuffer[_mode]) {
|
if (m_stream.doConvertBuffer[_mode]) {
|
||||||
@ -414,7 +414,7 @@ bool airtaudio::api::Jack::probeDeviceOpen(uint32_t _device,
|
|||||||
if (m_stream.deviceBuffer) free(m_stream.deviceBuffer);
|
if (m_stream.deviceBuffer) free(m_stream.deviceBuffer);
|
||||||
m_stream.deviceBuffer = (char *) calloc(bufferBytes, 1);
|
m_stream.deviceBuffer = (char *) calloc(bufferBytes, 1);
|
||||||
if (m_stream.deviceBuffer == nullptr) {
|
if (m_stream.deviceBuffer == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::probeDeviceOpen: error allocating device buffer memory.");
|
ATA_ERROR("error allocating device buffer memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -422,7 +422,7 @@ bool airtaudio::api::Jack::probeDeviceOpen(uint32_t _device,
|
|||||||
// Allocate memory for the Jack ports (channels) identifiers.
|
// Allocate memory for the Jack ports (channels) identifiers.
|
||||||
handle->ports[_mode] = (jack_port_t **) malloc (sizeof (jack_port_t *) * _channels);
|
handle->ports[_mode] = (jack_port_t **) malloc (sizeof (jack_port_t *) * _channels);
|
||||||
if (handle->ports[_mode] == nullptr) {
|
if (handle->ports[_mode] == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::probeDeviceOpen: error allocating port memory.");
|
ATA_ERROR("error allocating port memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
m_stream.device[_mode] = _device;
|
m_stream.device[_mode] = _device;
|
||||||
@ -494,7 +494,7 @@ error:
|
|||||||
|
|
||||||
enum airtaudio::errorType airtaudio::api::Jack::closeStream() {
|
enum airtaudio::errorType airtaudio::api::Jack::closeStream() {
|
||||||
if (m_stream.state == STREAM_CLOSED) {
|
if (m_stream.state == STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::closeStream(): no open stream to close!");
|
ATA_ERROR("no open stream to close!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
JackHandle *handle = (JackHandle *) m_stream.apiHandle;
|
JackHandle *handle = (JackHandle *) m_stream.apiHandle;
|
||||||
@ -534,13 +534,13 @@ enum airtaudio::errorType airtaudio::api::Jack::startStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_RUNNING) {
|
if (m_stream.state == STREAM_RUNNING) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::startStream(): the stream is already running!");
|
ATA_ERROR("the stream is already running!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
JackHandle *handle = (JackHandle *) m_stream.apiHandle;
|
JackHandle *handle = (JackHandle *) m_stream.apiHandle;
|
||||||
int32_t result = jack_activate(handle->client);
|
int32_t result = jack_activate(handle->client);
|
||||||
if (result) {
|
if (result) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::startStream(): unable to activate JACK client!");
|
ATA_ERROR("unable to activate JACK client!");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
const char **ports;
|
const char **ports;
|
||||||
@ -550,7 +550,7 @@ enum airtaudio::errorType airtaudio::api::Jack::startStream() {
|
|||||||
result = 1;
|
result = 1;
|
||||||
ports = jack_get_ports(handle->client, handle->deviceName[0].c_str(), nullptr, JackPortIsInput);
|
ports = jack_get_ports(handle->client, handle->deviceName[0].c_str(), nullptr, JackPortIsInput);
|
||||||
if (ports == nullptr) {
|
if (ports == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::startStream(): error determining available JACK input ports!");
|
ATA_ERROR("error determining available JACK input ports!");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
// Now make the port connections. Since RtAudio wasn't designed to
|
// Now make the port connections. Since RtAudio wasn't designed to
|
||||||
@ -562,7 +562,7 @@ enum airtaudio::errorType airtaudio::api::Jack::startStream() {
|
|||||||
result = jack_connect(handle->client, jack_port_name(handle->ports[0][i]), ports[ m_stream.channelOffset[0] + i ]);
|
result = jack_connect(handle->client, jack_port_name(handle->ports[0][i]), ports[ m_stream.channelOffset[0] + i ]);
|
||||||
if (result) {
|
if (result) {
|
||||||
free(ports);
|
free(ports);
|
||||||
ATA_ERROR("airtaudio::api::Jack::startStream(): error connecting output ports!");
|
ATA_ERROR("error connecting output ports!");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -573,7 +573,7 @@ enum airtaudio::errorType airtaudio::api::Jack::startStream() {
|
|||||||
result = 1;
|
result = 1;
|
||||||
ports = jack_get_ports(handle->client, handle->deviceName[1].c_str(), nullptr, JackPortIsOutput);
|
ports = jack_get_ports(handle->client, handle->deviceName[1].c_str(), nullptr, JackPortIsOutput);
|
||||||
if (ports == nullptr) {
|
if (ports == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::startStream(): error determining available JACK output ports!");
|
ATA_ERROR("error determining available JACK output ports!");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
// Now make the port connections. See note above.
|
// Now make the port connections. See note above.
|
||||||
@ -584,7 +584,7 @@ enum airtaudio::errorType airtaudio::api::Jack::startStream() {
|
|||||||
}
|
}
|
||||||
if (result) {
|
if (result) {
|
||||||
free(ports);
|
free(ports);
|
||||||
ATA_ERROR("airtaudio::api::Jack::startStream(): error connecting input ports!");
|
ATA_ERROR("error connecting input ports!");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -605,7 +605,7 @@ enum airtaudio::errorType airtaudio::api::Jack::stopStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_STOPPED) {
|
if (m_stream.state == STREAM_STOPPED) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::stopStream(): the stream is already stopped!");
|
ATA_ERROR("the stream is already stopped!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
JackHandle *handle = (JackHandle *) m_stream.apiHandle;
|
JackHandle *handle = (JackHandle *) m_stream.apiHandle;
|
||||||
@ -627,7 +627,7 @@ enum airtaudio::errorType airtaudio::api::Jack::abortStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_STOPPED) {
|
if (m_stream.state == STREAM_STOPPED) {
|
||||||
ATA_ERROR("airtaudio::api::Jack::abortStream(): the stream is already stopped!");
|
ATA_ERROR("the stream is already stopped!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
JackHandle *handle = (JackHandle *) m_stream.apiHandle;
|
JackHandle *handle = (JackHandle *) m_stream.apiHandle;
|
||||||
|
@ -38,7 +38,7 @@ namespace airtaudio {
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options);
|
airtaudio::StreamOptions *_options);
|
||||||
};
|
};
|
||||||
|
@ -57,13 +57,13 @@ airtaudio::api::Oss::~Oss() {
|
|||||||
uint32_t airtaudio::api::Oss::getDeviceCount() {
|
uint32_t airtaudio::api::Oss::getDeviceCount() {
|
||||||
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("airtaudio::api::Oss::getDeviceCount: error opening '/dev/mixer'.");
|
ATA_ERROR("error opening '/dev/mixer'.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
oss_sysinfo sysinfo;
|
oss_sysinfo sysinfo;
|
||||||
if (ioctl(mixerfd, SNDCTL_SYSINFO, &sysinfo) == -1) {
|
if (ioctl(mixerfd, SNDCTL_SYSINFO, &sysinfo) == -1) {
|
||||||
close(mixerfd);
|
close(mixerfd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::getDeviceCount: error getting sysinfo, OSS version >= 4.0 is required.");
|
ATA_ERROR("error getting sysinfo, OSS version >= 4.0 is required.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
close(mixerfd);
|
close(mixerfd);
|
||||||
@ -75,25 +75,25 @@ airtaudio::DeviceInfo airtaudio::api::Oss::getDeviceInfo(uint32_t _device) {
|
|||||||
info.probed = false;
|
info.probed = false;
|
||||||
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("airtaudio::api::Oss::getDeviceInfo: error opening '/dev/mixer'.");
|
ATA_ERROR("error opening '/dev/mixer'.");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
oss_sysinfo sysinfo;
|
oss_sysinfo sysinfo;
|
||||||
int32_t result = ioctl(mixerfd, SNDCTL_SYSINFO, &sysinfo);
|
int32_t result = ioctl(mixerfd, SNDCTL_SYSINFO, &sysinfo);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
close(mixerfd);
|
close(mixerfd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::getDeviceInfo: error getting sysinfo, OSS version >= 4.0 is required.");
|
ATA_ERROR("error getting sysinfo, OSS version >= 4.0 is required.");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
unsigned nDevices = sysinfo.numaudios;
|
unsigned nDevices = sysinfo.numaudios;
|
||||||
if (nDevices == 0) {
|
if (nDevices == 0) {
|
||||||
close(mixerfd);
|
close(mixerfd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::getDeviceInfo: no devices found!");
|
ATA_ERROR("no devices found!");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
if (_device >= nDevices) {
|
if (_device >= nDevices) {
|
||||||
close(mixerfd);
|
close(mixerfd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::getDeviceInfo: device ID is invalid!");
|
ATA_ERROR("device ID is invalid!");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
oss_audioinfo ainfo;
|
oss_audioinfo ainfo;
|
||||||
@ -101,7 +101,7 @@ airtaudio::DeviceInfo airtaudio::api::Oss::getDeviceInfo(uint32_t _device) {
|
|||||||
result = ioctl(mixerfd, SNDCTL_AUDIOINFO, &ainfo);
|
result = ioctl(mixerfd, SNDCTL_AUDIOINFO, &ainfo);
|
||||||
close(mixerfd);
|
close(mixerfd);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::getDeviceInfo: error getting device (" << ainfo.name << ") info.");
|
ATA_ERROR("error getting device (" << ainfo.name << ") info.");
|
||||||
error(airtaudio::errorWarning);
|
error(airtaudio::errorWarning);
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@ -123,25 +123,25 @@ airtaudio::DeviceInfo airtaudio::api::Oss::getDeviceInfo(uint32_t _device) {
|
|||||||
uint64_t mask = ainfo.iformats;
|
uint64_t mask = ainfo.iformats;
|
||||||
if ( mask & AFMT_S16_LE
|
if ( mask & AFMT_S16_LE
|
||||||
|| mask & AFMT_S16_BE) {
|
|| mask & AFMT_S16_BE) {
|
||||||
info.nativeFormats |= RTAUDIO_SINT16;
|
info.nativeFormats.push_back(audio::format_int16);
|
||||||
}
|
}
|
||||||
if (mask & AFMT_S8) {
|
if (mask & AFMT_S8) {
|
||||||
info.nativeFormats |= RTAUDIO_SINT8;
|
info.nativeFormats.push_back(audio::format_int8);
|
||||||
}
|
}
|
||||||
if ( mask & AFMT_S32_LE
|
if ( mask & AFMT_S32_LE
|
||||||
|| mask & AFMT_S32_BE) {
|
|| mask & AFMT_S32_BE) {
|
||||||
info.nativeFormats |= RTAUDIO_SINT32;
|
info.nativeFormats.push_back(audio::format_int32);
|
||||||
}
|
}
|
||||||
if (mask & AFMT_FLOAT) {
|
if (mask & AFMT_FLOAT) {
|
||||||
info.nativeFormats |= RTAUDIO_FLOAT32;
|
info.nativeFormats.push_back(audio::format_float);
|
||||||
}
|
}
|
||||||
if ( mask & AFMT_S24_LE
|
if ( mask & AFMT_S24_LE
|
||||||
|| mask & AFMT_S24_BE) {
|
|| mask & AFMT_S24_BE) {
|
||||||
info.nativeFormats |= RTAUDIO_SINT24;
|
info.nativeFormats.push_back(audio::format_int24);
|
||||||
}
|
}
|
||||||
// Check that we have at least one supported format
|
// Check that we have at least one supported format
|
||||||
if (info.nativeFormats == 0) {
|
if (info.nativeFormats == 0) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::getDeviceInfo: device (" << ainfo.name << ") data format not supported by RtAudio.");
|
ATA_ERROR("device (" << ainfo.name << ") data format not supported by RtAudio.");
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
// Probe the supported sample rates.
|
// Probe the supported sample rates.
|
||||||
@ -165,7 +165,7 @@ airtaudio::DeviceInfo airtaudio::api::Oss::getDeviceInfo(uint32_t _device) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (info.sampleRates.size() == 0) {
|
if (info.sampleRates.size() == 0) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::getDeviceInfo: no supported sample rates found for device (" << ainfo.name << ").");
|
ATA_ERROR("no supported sample rates found for device (" << ainfo.name << ").");
|
||||||
} else {
|
} else {
|
||||||
info.probed = true;
|
info.probed = true;
|
||||||
info.name = ainfo.name;
|
info.name = ainfo.name;
|
||||||
@ -183,27 +183,27 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
rtaudio::StreamOptions* _options) {
|
rtaudio::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("airtaudio::api::Oss::probeDeviceOpen: error opening '/dev/mixer'.");
|
ATA_ERROR("error opening '/dev/mixer'.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
oss_sysinfo sysinfo;
|
oss_sysinfo sysinfo;
|
||||||
int32_t result = ioctl(mixerfd, SNDCTL_SYSINFO, &sysinfo);
|
int32_t result = ioctl(mixerfd, SNDCTL_SYSINFO, &sysinfo);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
close(mixerfd);
|
close(mixerfd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: error getting sysinfo, OSS version >= 4.0 is required.");
|
ATA_ERROR("error getting sysinfo, OSS version >= 4.0 is required.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
unsigned nDevices = sysinfo.numaudios;
|
unsigned nDevices = sysinfo.numaudios;
|
||||||
if (nDevices == 0) {
|
if (nDevices == 0) {
|
||||||
// This should not happen because a check is made before this function is called.
|
// This should not happen because a check is made before this function is called.
|
||||||
close(mixerfd);
|
close(mixerfd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: no devices found!");
|
ATA_ERROR("no devices found!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_device >= nDevices) {
|
if (_device >= nDevices) {
|
||||||
// This should not happen because a check is made before this function is called.
|
// This should not happen because a check is made before this function is called.
|
||||||
close(mixerfd);
|
close(mixerfd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: device ID is invalid!");
|
ATA_ERROR("device ID is invalid!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
oss_audioinfo ainfo;
|
oss_audioinfo ainfo;
|
||||||
@ -211,7 +211,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
result = ioctl(mixerfd, SNDCTL_AUDIOINFO, &ainfo);
|
result = ioctl(mixerfd, SNDCTL_AUDIOINFO, &ainfo);
|
||||||
close(mixerfd);
|
close(mixerfd);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::getDeviceInfo: error getting device (" << ainfo.name << ") info.");
|
ATA_ERROR("error getting device (" << ainfo.name << ") info.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Check if device supports input or output
|
// Check if device supports input or output
|
||||||
@ -220,9 +220,9 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
|| ( _mode == INPUT
|
|| ( _mode == INPUT
|
||||||
&& !(ainfo.caps & PCM_CAP_INPUT))) {
|
&& !(ainfo.caps & PCM_CAP_INPUT))) {
|
||||||
if (_mode == OUTPUT) {
|
if (_mode == OUTPUT) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: device (" << ainfo.name << ") does not support output.");
|
ATA_ERROR("device (" << ainfo.name << ") does not support output.");
|
||||||
} else {
|
} else {
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: device (" << ainfo.name << ") does not support input.");
|
ATA_ERROR("device (" << ainfo.name << ") does not support input.");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -237,12 +237,12 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
close(handle->id[0]);
|
close(handle->id[0]);
|
||||||
handle->id[0] = 0;
|
handle->id[0] = 0;
|
||||||
if (!(ainfo.caps & PCM_CAP_DUPLEX)) {
|
if (!(ainfo.caps & PCM_CAP_DUPLEX)) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: device (" << ainfo.name << ") does not support duplex mode.");
|
ATA_ERROR("device (" << ainfo.name << ") does not support duplex mode.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Check that the number previously set channels is the same.
|
// Check that the number previously set channels is the same.
|
||||||
if (m_stream.nUserChannels[0] != _channels) {
|
if (m_stream.nUserChannels[0] != _channels) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: input/output channels must be equal for OSS duplex device (" << ainfo.name << ").");
|
ATA_ERROR("input/output channels must be equal for OSS duplex device (" << ainfo.name << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
flags |= O_RDWR;
|
flags |= O_RDWR;
|
||||||
@ -260,9 +260,9 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
fd = open(ainfo.devnode, flags, 0);
|
fd = open(ainfo.devnode, flags, 0);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
if (errno == EBUSY) {
|
if (errno == EBUSY) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: device (" << ainfo.name << ") is busy.");
|
ATA_ERROR("device (" << ainfo.name << ") is busy.");
|
||||||
} else {
|
} else {
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: error opening device (" << ainfo.name << ").");
|
ATA_ERROR("error opening device (" << ainfo.name << ").");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
if (flags | O_RDWR) {
|
if (flags | O_RDWR) {
|
||||||
result = ioctl(fd, SNDCTL_DSP_SETDUPLEX, nullptr);
|
result = ioctl(fd, SNDCTL_DSP_SETDUPLEX, nullptr);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
m_errorStream << "airtaudio::api::Oss::probeDeviceOpen: error setting duplex mode for device (" << ainfo.name << ").";
|
m_errorStream << "error setting duplex mode for device (" << ainfo.name << ").";
|
||||||
m_errorText = m_errorStream.str();
|
m_errorText = m_errorStream.str();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -281,7 +281,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
m_stream.nUserChannels[_mode] = _channels;
|
m_stream.nUserChannels[_mode] = _channels;
|
||||||
if (ainfo.max_channels < (int)(_channels + _firstChannel)) {
|
if (ainfo.max_channels < (int)(_channels + _firstChannel)) {
|
||||||
close(fd);
|
close(fd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: the device (" << ainfo.name << ") does not support requested channel parameters.");
|
ATA_ERROR("the device (" << ainfo.name << ") does not support requested channel parameters.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Set the number of channels.
|
// Set the number of channels.
|
||||||
@ -290,7 +290,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
if ( result == -1
|
if ( result == -1
|
||||||
|| deviceChannels < (int)(_channels + _firstChannel)) {
|
|| deviceChannels < (int)(_channels + _firstChannel)) {
|
||||||
close(fd);
|
close(fd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: error setting channel parameters on device (" << ainfo.name << ").");
|
ATA_ERROR("error setting channel parameters on device (" << ainfo.name << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_stream.nDeviceChannels[_mode] = deviceChannels;
|
m_stream.nDeviceChannels[_mode] = deviceChannels;
|
||||||
@ -299,7 +299,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
result = ioctl(fd, SNDCTL_DSP_GETFMTS, &mask);
|
result = ioctl(fd, SNDCTL_DSP_GETFMTS, &mask);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
close(fd);
|
close(fd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: error getting device (" << ainfo.name << ") data formats.");
|
ATA_ERROR("error getting device (" << ainfo.name << ") data formats.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Determine how to set the device format.
|
// Determine how to set the device format.
|
||||||
@ -370,7 +370,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
if (m_stream.deviceFormat[_mode] == 0) {
|
if (m_stream.deviceFormat[_mode] == 0) {
|
||||||
// This really shouldn't happen ...
|
// This really shouldn't happen ...
|
||||||
close(fd);
|
close(fd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: device (" << ainfo.name << ") data format not supported by RtAudio.");
|
ATA_ERROR("device (" << ainfo.name << ") data format not supported by RtAudio.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Set the data format.
|
// Set the data format.
|
||||||
@ -379,7 +379,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
if ( result == -1
|
if ( result == -1
|
||||||
|| deviceFormat != temp) {
|
|| deviceFormat != temp) {
|
||||||
close(fd);
|
close(fd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: error setting data format on device (" << ainfo.name << ").");
|
ATA_ERROR("error setting data format on device (" << ainfo.name << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Attempt to set the buffer size. According to OSS, the minimum
|
// Attempt to set the buffer size. According to OSS, the minimum
|
||||||
@ -408,7 +408,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
result = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &temp);
|
result = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &temp);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
close(fd);
|
close(fd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: error setting buffer size on device (" << ainfo.name << ").");
|
ATA_ERROR("error setting buffer size on device (" << ainfo.name << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_stream.nBuffers = buffers;
|
m_stream.nBuffers = buffers;
|
||||||
@ -420,13 +420,13 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
result = ioctl(fd, SNDCTL_DSP_SPEED, &srate);
|
result = ioctl(fd, SNDCTL_DSP_SPEED, &srate);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
close(fd);
|
close(fd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: error setting sample rate (" << _sampleRate << ") on device (" << ainfo.name << ").");
|
ATA_ERROR("error setting sample rate (" << _sampleRate << ") on device (" << ainfo.name << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Verify the sample rate setup worked.
|
// Verify the sample rate setup worked.
|
||||||
if (abs(srate - _sampleRate) > 100) {
|
if (abs(srate - _sampleRate) > 100) {
|
||||||
close(fd);
|
close(fd);
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: device (" << ainfo.name << ") does not support sample rate (" << _sampleRate << ").");
|
ATA_ERROR("device (" << ainfo.name << ") does not support sample rate (" << _sampleRate << ").");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_stream.sampleRate = _sampleRate;
|
m_stream.sampleRate = _sampleRate;
|
||||||
@ -459,7 +459,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
if (m_stream.apiHandle == 0) {
|
if (m_stream.apiHandle == 0) {
|
||||||
handle = new OssHandle;
|
handle = new OssHandle;
|
||||||
if handle == nullptr) {
|
if handle == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: error allocating OssHandle memory.");
|
ATA_ERROR("error allocating OssHandle memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
m_stream.apiHandle = (void *) handle;
|
m_stream.apiHandle = (void *) handle;
|
||||||
@ -472,7 +472,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
bufferBytes = m_stream.nUserChannels[_mode] * *_bufferSize * formatBytes(m_stream.userFormat);
|
bufferBytes = m_stream.nUserChannels[_mode] * *_bufferSize * formatBytes(m_stream.userFormat);
|
||||||
m_stream.userBuffer[_mode] = (char *) calloc(bufferBytes, 1);
|
m_stream.userBuffer[_mode] = (char *) calloc(bufferBytes, 1);
|
||||||
if (m_stream.userBuffer[_mode] == nullptr) {
|
if (m_stream.userBuffer[_mode] == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: error allocating user buffer memory.");
|
ATA_ERROR("error allocating user buffer memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (m_stream.doConvertBuffer[_mode]) {
|
if (m_stream.doConvertBuffer[_mode]) {
|
||||||
@ -494,7 +494,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
}
|
}
|
||||||
m_stream.deviceBuffer = (char *) calloc(bufferBytes, 1);
|
m_stream.deviceBuffer = (char *) calloc(bufferBytes, 1);
|
||||||
if (m_stream.deviceBuffer == nullptr) {
|
if (m_stream.deviceBuffer == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::probeDeviceOpen: error allocating device buffer memory.");
|
ATA_ERROR("error allocating device buffer memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -520,7 +520,7 @@ bool airtaudio::api::Oss::probeDeviceOpen(uint32_t _device,
|
|||||||
m_stream.callbackInfo.thread = new std::thread(ossCallbackHandler, &m_stream.callbackInfo);
|
m_stream.callbackInfo.thread = new std::thread(ossCallbackHandler, &m_stream.callbackInfo);
|
||||||
if (m_stream.callbackInfo.thread == nullptr) {
|
if (m_stream.callbackInfo.thread == nullptr) {
|
||||||
m_stream.callbackInfo.isRunning = false;
|
m_stream.callbackInfo.isRunning = false;
|
||||||
ATA_ERROR("airtaudio::api::Oss::error creating callback thread!");
|
ATA_ERROR("creating callback thread!");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -551,7 +551,7 @@ error:
|
|||||||
|
|
||||||
enum airtaudio::errorType airtaudio::api::Oss::closeStream() {
|
enum airtaudio::errorType airtaudio::api::Oss::closeStream() {
|
||||||
if (m_stream.state == STREAM_CLOSED) {
|
if (m_stream.state == STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::closeStream(): no open stream to close!");
|
ATA_ERROR("no open stream to close!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
OssHandle *handle = (OssHandle *) m_stream.apiHandle;
|
OssHandle *handle = (OssHandle *) m_stream.apiHandle;
|
||||||
@ -600,7 +600,7 @@ enum airtaudio::errorType airtaudio::api::Oss::startStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_RUNNING) {
|
if (m_stream.state == STREAM_RUNNING) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::startStream(): the stream is already running!");
|
ATA_ERROR("the stream is already running!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
m_stream.mutex.lock();
|
m_stream.mutex.lock();
|
||||||
@ -617,7 +617,7 @@ enum airtaudio::errorType airtaudio::api::Oss::stopStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_STOPPED) {
|
if (m_stream.state == STREAM_STOPPED) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::stopStream(): the stream is already stopped!");
|
ATA_ERROR("the stream is already stopped!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_stream.mutex.lock();
|
m_stream.mutex.lock();
|
||||||
@ -633,7 +633,7 @@ enum airtaudio::errorType airtaudio::api::Oss::stopStream() {
|
|||||||
// Flush the output with zeros a few times.
|
// Flush the output with zeros a few times.
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int32_t samples;
|
int32_t samples;
|
||||||
airtaudio::format format;
|
audio::format format;
|
||||||
if (m_stream.doConvertBuffer[0]) {
|
if (m_stream.doConvertBuffer[0]) {
|
||||||
buffer = m_stream.deviceBuffer;
|
buffer = m_stream.deviceBuffer;
|
||||||
samples = m_stream.bufferSize * m_stream.nDeviceChannels[0];
|
samples = m_stream.bufferSize * m_stream.nDeviceChannels[0];
|
||||||
@ -647,13 +647,13 @@ enum airtaudio::errorType airtaudio::api::Oss::stopStream() {
|
|||||||
for (uint32_t i=0; i<m_stream.nBuffers+1; i++) {
|
for (uint32_t i=0; i<m_stream.nBuffers+1; i++) {
|
||||||
result = write(handle->id[0], buffer, samples * formatBytes(format));
|
result = write(handle->id[0], buffer, samples * formatBytes(format));
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::stopStream: audio write error.");
|
ATA_ERROR("audio write error.");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = ioctl(handle->id[0], SNDCTL_DSP_HALT, 0);
|
result = ioctl(handle->id[0], SNDCTL_DSP_HALT, 0);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::stopStream: system error stopping callback procedure on device (" << m_stream.device[0] << ").");
|
ATA_ERROR("system error stopping callback procedure on device (" << m_stream.device[0] << ").");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
handle->triggered = false;
|
handle->triggered = false;
|
||||||
@ -663,7 +663,7 @@ enum airtaudio::errorType airtaudio::api::Oss::stopStream() {
|
|||||||
&& handle->id[0] != handle->id[1])) {
|
&& handle->id[0] != handle->id[1])) {
|
||||||
result = ioctl(handle->id[1], SNDCTL_DSP_HALT, 0);
|
result = ioctl(handle->id[1], SNDCTL_DSP_HALT, 0);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::stopStream: system error stopping input callback procedure on device (" << m_stream.device[0] << ").");
|
ATA_ERROR("system error stopping input callback procedure on device (" << m_stream.device[0] << ").");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -681,7 +681,7 @@ enum airtaudio::errorType airtaudio::api::Oss::abortStream() {
|
|||||||
return airtaudio::errorFail;
|
return airtaudio::errorFail;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_STOPPED) {
|
if (m_stream.state == STREAM_STOPPED) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::abortStream(): the stream is already stopped!");
|
ATA_ERROR("the stream is already stopped!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
m_stream.mutex.lock();
|
m_stream.mutex.lock();
|
||||||
@ -695,7 +695,7 @@ enum airtaudio::errorType airtaudio::api::Oss::abortStream() {
|
|||||||
if (m_stream.mode == OUTPUT || m_stream.mode == DUPLEX) {
|
if (m_stream.mode == OUTPUT || m_stream.mode == DUPLEX) {
|
||||||
result = ioctl(handle->id[0], SNDCTL_DSP_HALT, 0);
|
result = ioctl(handle->id[0], SNDCTL_DSP_HALT, 0);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::abortStream: system error stopping callback procedure on device (" << m_stream.device[0] << ").");
|
ATA_ERROR("system error stopping callback procedure on device (" << m_stream.device[0] << ").");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
handle->triggered = false;
|
handle->triggered = false;
|
||||||
@ -703,7 +703,7 @@ enum airtaudio::errorType airtaudio::api::Oss::abortStream() {
|
|||||||
if (m_stream.mode == INPUT || (m_stream.mode == DUPLEX && handle->id[0] != handle->id[1])) {
|
if (m_stream.mode == INPUT || (m_stream.mode == DUPLEX && handle->id[0] != handle->id[1])) {
|
||||||
result = ioctl(handle->id[1], SNDCTL_DSP_HALT, 0);
|
result = ioctl(handle->id[1], SNDCTL_DSP_HALT, 0);
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::abortStream: system error stopping input callback procedure on device (" << m_stream.device[0] << ").");
|
ATA_ERROR("system error stopping input callback procedure on device (" << m_stream.device[0] << ").");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -726,7 +726,7 @@ void airtaudio::api::Oss::callbackEvent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_CLOSED) {
|
if (m_stream.state == STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::api::Oss::callbackEvent(): the stream is closed ... this shouldn't happen!");
|
ATA_ERROR("the stream is closed ... this shouldn't happen!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
// Invoke user callback to get fresh output data.
|
// Invoke user callback to get fresh output data.
|
||||||
@ -760,7 +760,7 @@ void airtaudio::api::Oss::callbackEvent() {
|
|||||||
int32_t result;
|
int32_t result;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int32_t samples;
|
int32_t samples;
|
||||||
airtaudio::format format;
|
audio::format format;
|
||||||
if ( m_stream.mode == OUTPUT
|
if ( m_stream.mode == OUTPUT
|
||||||
|| m_stream.mode == DUPLEX) {
|
|| m_stream.mode == DUPLEX) {
|
||||||
// Setup parameters and do buffer conversion if necessary.
|
// Setup parameters and do buffer conversion if necessary.
|
||||||
@ -794,7 +794,7 @@ void airtaudio::api::Oss::callbackEvent() {
|
|||||||
// We'll assume this is an underrun, though there isn't a
|
// We'll assume this is an underrun, though there isn't a
|
||||||
// specific means for determining that.
|
// specific means for determining that.
|
||||||
handle->xrun[0] = true;
|
handle->xrun[0] = true;
|
||||||
ATA_ERROR("airtaudio::api::Oss::callbackEvent: audio write error.");
|
ATA_ERROR("audio write error.");
|
||||||
//error(airtaudio::errorWarning);
|
//error(airtaudio::errorWarning);
|
||||||
// Continue on to input section.
|
// Continue on to input section.
|
||||||
}
|
}
|
||||||
@ -817,7 +817,7 @@ void airtaudio::api::Oss::callbackEvent() {
|
|||||||
// We'll assume this is an overrun, though there isn't a
|
// We'll assume this is an overrun, though there isn't a
|
||||||
// specific means for determining that.
|
// specific means for determining that.
|
||||||
handle->xrun[1] = true;
|
handle->xrun[1] = true;
|
||||||
ATA_ERROR("airtaudio::api::Oss::callbackEvent: audio read error.");
|
ATA_ERROR("audio read error.");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
// Do byte swapping if necessary.
|
// Do byte swapping if necessary.
|
||||||
|
@ -37,7 +37,7 @@ namespace airtaudio {
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options);
|
airtaudio::StreamOptions *_options);
|
||||||
};
|
};
|
||||||
|
@ -40,14 +40,14 @@ static const uint32_t SUPPORTED_SAMPLERATES[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct rtaudio_pa_format_mapping_t {
|
struct rtaudio_pa_format_mapping_t {
|
||||||
airtaudio::format airtaudio_format;
|
audio::format airtaudio_format;
|
||||||
pa_sample_format_t pa_format;
|
pa_sample_format_t pa_format;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const rtaudio_pa_format_mapping_t supported_sampleformats[] = {
|
static const rtaudio_pa_format_mapping_t supported_sampleformats[] = {
|
||||||
{airtaudio::SINT16, PA_SAMPLE_S16LE},
|
{audio::format_int16, PA_SAMPLE_S16LE},
|
||||||
{airtaudio::SINT32, PA_SAMPLE_S32LE},
|
{audio::format_int32, PA_SAMPLE_S32LE},
|
||||||
{airtaudio::FLOAT32, PA_SAMPLE_FLOAT32LE},
|
{audio::format_float, PA_SAMPLE_FLOAT32LE},
|
||||||
{0, PA_SAMPLE_INVALID}};
|
{0, PA_SAMPLE_INVALID}};
|
||||||
|
|
||||||
struct PulseAudioHandle {
|
struct PulseAudioHandle {
|
||||||
@ -86,7 +86,9 @@ airtaudio::DeviceInfo airtaudio::api::Pulse::getDeviceInfo(uint32_t _device) {
|
|||||||
for (const uint32_t *sr = SUPPORTED_SAMPLERATES; *sr; ++sr) {
|
for (const uint32_t *sr = SUPPORTED_SAMPLERATES; *sr; ++sr) {
|
||||||
info.sampleRates.push_back(*sr);
|
info.sampleRates.push_back(*sr);
|
||||||
}
|
}
|
||||||
info.nativeFormats = SINT16 | SINT32 | FLOAT32;
|
info.nativeFormats.push_back(audio::format_int16);
|
||||||
|
info.nativeFormats.push_back(audio::format_int32);
|
||||||
|
info.nativeFormats.push_back(audio::format_float);
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +148,7 @@ void airtaudio::api::Pulse::callbackEvent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_CLOSED) {
|
if (m_stream.state == STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::callbackEvent(): the stream is closed ... this shouldn't happen!");
|
ATA_ERROR("the stream is closed ... this shouldn't happen!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
double streamTime = getStreamTime();
|
double streamTime = getStreamTime();
|
||||||
@ -179,7 +181,7 @@ void airtaudio::api::Pulse::callbackEvent() {
|
|||||||
bytes = m_stream.nUserChannels[OUTPUT] * m_stream.bufferSize * formatBytes(m_stream.userFormat);
|
bytes = m_stream.nUserChannels[OUTPUT] * m_stream.bufferSize * formatBytes(m_stream.userFormat);
|
||||||
}
|
}
|
||||||
if (pa_simple_write(pah->s_play, pulse_out, bytes, &pa_error) < 0) {
|
if (pa_simple_write(pah->s_play, pulse_out, bytes, &pa_error) < 0) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::callbackEvent: audio write error, " << pa_strerror(pa_error) << ".");
|
ATA_ERROR("audio write error, " << pa_strerror(pa_error) << ".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -190,7 +192,7 @@ void airtaudio::api::Pulse::callbackEvent() {
|
|||||||
bytes = m_stream.nUserChannels[INPUT] * m_stream.bufferSize * formatBytes(m_stream.userFormat);
|
bytes = m_stream.nUserChannels[INPUT] * m_stream.bufferSize * formatBytes(m_stream.userFormat);
|
||||||
}
|
}
|
||||||
if (pa_simple_read(pah->s_rec, pulse_in, bytes, &pa_error) < 0) {
|
if (pa_simple_read(pah->s_rec, pulse_in, bytes, &pa_error) < 0) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::callbackEvent: audio read error, " << pa_strerror(pa_error) << ".");
|
ATA_ERROR("audio read error, " << pa_strerror(pa_error) << ".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_stream.doConvertBuffer[INPUT]) {
|
if (m_stream.doConvertBuffer[INPUT]) {
|
||||||
@ -212,11 +214,11 @@ unlock:
|
|||||||
enum airtaudio::errorType airtaudio::api::Pulse::startStream() {
|
enum airtaudio::errorType airtaudio::api::Pulse::startStream() {
|
||||||
PulseAudioHandle *pah = static_cast<PulseAudioHandle *>(m_stream.apiHandle);
|
PulseAudioHandle *pah = static_cast<PulseAudioHandle *>(m_stream.apiHandle);
|
||||||
if (m_stream.state == STREAM_CLOSED) {
|
if (m_stream.state == STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::startStream(): the stream is not open!");
|
ATA_ERROR("the stream is not open!");
|
||||||
return airtaudio::errorInvalidUse;
|
return airtaudio::errorInvalidUse;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_RUNNING) {
|
if (m_stream.state == STREAM_RUNNING) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::startStream(): the stream is already running!");
|
ATA_ERROR("the stream is already running!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
m_stream.mutex.lock();
|
m_stream.mutex.lock();
|
||||||
@ -230,11 +232,11 @@ enum airtaudio::errorType airtaudio::api::Pulse::startStream() {
|
|||||||
enum airtaudio::errorType airtaudio::api::Pulse::stopStream() {
|
enum airtaudio::errorType airtaudio::api::Pulse::stopStream() {
|
||||||
PulseAudioHandle *pah = static_cast<PulseAudioHandle *>(m_stream.apiHandle);
|
PulseAudioHandle *pah = static_cast<PulseAudioHandle *>(m_stream.apiHandle);
|
||||||
if (m_stream.state == STREAM_CLOSED) {
|
if (m_stream.state == STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::stopStream(): the stream is not open!");
|
ATA_ERROR("the stream is not open!");
|
||||||
return airtaudio::errorInvalidUse;
|
return airtaudio::errorInvalidUse;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_STOPPED) {
|
if (m_stream.state == STREAM_STOPPED) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::stopStream(): the stream is already stopped!");
|
ATA_ERROR("the stream is already stopped!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
m_stream.state = STREAM_STOPPED;
|
m_stream.state = STREAM_STOPPED;
|
||||||
@ -242,7 +244,7 @@ enum airtaudio::errorType airtaudio::api::Pulse::stopStream() {
|
|||||||
if (pah && pah->s_play) {
|
if (pah && pah->s_play) {
|
||||||
int32_t pa_error;
|
int32_t pa_error;
|
||||||
if (pa_simple_drain(pah->s_play, &pa_error) < 0) {
|
if (pa_simple_drain(pah->s_play, &pa_error) < 0) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::stopStream: error draining output device, " << pa_strerror(pa_error) << ".");
|
ATA_ERROR("error draining output device, " << pa_strerror(pa_error) << ".");
|
||||||
m_stream.mutex.unlock();
|
m_stream.mutex.unlock();
|
||||||
return airtaudio::errorSystemError;
|
return airtaudio::errorSystemError;
|
||||||
}
|
}
|
||||||
@ -255,11 +257,11 @@ enum airtaudio::errorType airtaudio::api::Pulse::stopStream() {
|
|||||||
enum airtaudio::errorType airtaudio::api::Pulse::abortStream() {
|
enum airtaudio::errorType airtaudio::api::Pulse::abortStream() {
|
||||||
PulseAudioHandle *pah = static_cast<PulseAudioHandle*>(m_stream.apiHandle);
|
PulseAudioHandle *pah = static_cast<PulseAudioHandle*>(m_stream.apiHandle);
|
||||||
if (m_stream.state == STREAM_CLOSED) {
|
if (m_stream.state == STREAM_CLOSED) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::abortStream(): the stream is not open!");
|
ATA_ERROR("the stream is not open!");
|
||||||
return airtaudio::errorInvalidUse;
|
return airtaudio::errorInvalidUse;
|
||||||
}
|
}
|
||||||
if (m_stream.state == STREAM_STOPPED) {
|
if (m_stream.state == STREAM_STOPPED) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::abortStream(): the stream is already stopped!");
|
ATA_ERROR("the stream is already stopped!");
|
||||||
return airtaudio::errorWarning;
|
return airtaudio::errorWarning;
|
||||||
}
|
}
|
||||||
m_stream.state = STREAM_STOPPED;
|
m_stream.state = STREAM_STOPPED;
|
||||||
@ -267,7 +269,7 @@ enum airtaudio::errorType airtaudio::api::Pulse::abortStream() {
|
|||||||
if (pah && pah->s_play) {
|
if (pah && pah->s_play) {
|
||||||
int32_t pa_error;
|
int32_t pa_error;
|
||||||
if (pa_simple_flush(pah->s_play, &pa_error) < 0) {
|
if (pa_simple_flush(pah->s_play, &pa_error) < 0) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::abortStream: error flushing output device, " << pa_strerror(pa_error) << ".");
|
ATA_ERROR("error flushing output device, " << pa_strerror(pa_error) << ".");
|
||||||
m_stream.mutex.unlock();
|
m_stream.mutex.unlock();
|
||||||
return airtaudio::errorSystemError;
|
return airtaudio::errorSystemError;
|
||||||
}
|
}
|
||||||
@ -282,7 +284,7 @@ bool airtaudio::api::Pulse::probeDeviceOpen(uint32_t _device,
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options) {
|
airtaudio::StreamOptions *_options) {
|
||||||
PulseAudioHandle *pah = 0;
|
PulseAudioHandle *pah = 0;
|
||||||
@ -295,7 +297,7 @@ bool airtaudio::api::Pulse::probeDeviceOpen(uint32_t _device,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_channels != 1 && _channels != 2) {
|
if (_channels != 1 && _channels != 2) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::probeDeviceOpen: unsupported number of channels.");
|
ATA_ERROR("unsupported number of channels.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ss.channels = _channels;
|
ss.channels = _channels;
|
||||||
@ -312,7 +314,7 @@ bool airtaudio::api::Pulse::probeDeviceOpen(uint32_t _device,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!sr_found) {
|
if (!sr_found) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::probeDeviceOpen: unsupported sample rate.");
|
ATA_ERROR("unsupported sample rate.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool sf_found = 0;
|
bool sf_found = 0;
|
||||||
@ -327,7 +329,7 @@ bool airtaudio::api::Pulse::probeDeviceOpen(uint32_t _device,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!sf_found) {
|
if (!sf_found) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::probeDeviceOpen: unsupported sample format.");
|
ATA_ERROR("unsupported sample format.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Set interleaving parameters.
|
// Set interleaving parameters.
|
||||||
@ -348,7 +350,7 @@ bool airtaudio::api::Pulse::probeDeviceOpen(uint32_t _device,
|
|||||||
bufferBytes = m_stream.nUserChannels[_mode] * *_bufferSize * formatBytes(m_stream.userFormat);
|
bufferBytes = m_stream.nUserChannels[_mode] * *_bufferSize * formatBytes(m_stream.userFormat);
|
||||||
m_stream.userBuffer[_mode] = (char *) calloc(bufferBytes, 1);
|
m_stream.userBuffer[_mode] = (char *) calloc(bufferBytes, 1);
|
||||||
if (m_stream.userBuffer[_mode] == nullptr) {
|
if (m_stream.userBuffer[_mode] == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::probeDeviceOpen: error allocating user buffer memory.");
|
ATA_ERROR("error allocating user buffer memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
m_stream.bufferSize = *_bufferSize;
|
m_stream.bufferSize = *_bufferSize;
|
||||||
@ -366,7 +368,7 @@ bool airtaudio::api::Pulse::probeDeviceOpen(uint32_t _device,
|
|||||||
if (m_stream.deviceBuffer) free(m_stream.deviceBuffer);
|
if (m_stream.deviceBuffer) free(m_stream.deviceBuffer);
|
||||||
m_stream.deviceBuffer = (char *) calloc(bufferBytes, 1);
|
m_stream.deviceBuffer = (char *) calloc(bufferBytes, 1);
|
||||||
if (m_stream.deviceBuffer == nullptr) {
|
if (m_stream.deviceBuffer == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::probeDeviceOpen: error allocating device buffer memory.");
|
ATA_ERROR("error allocating device buffer memory.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -379,7 +381,7 @@ bool airtaudio::api::Pulse::probeDeviceOpen(uint32_t _device,
|
|||||||
if (!m_stream.apiHandle) {
|
if (!m_stream.apiHandle) {
|
||||||
PulseAudioHandle *pah = new PulseAudioHandle;
|
PulseAudioHandle *pah = new PulseAudioHandle;
|
||||||
if (!pah) {
|
if (!pah) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::probeDeviceOpen: error allocating memory for handle.");
|
ATA_ERROR("error allocating memory for handle.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
m_stream.apiHandle = pah;
|
m_stream.apiHandle = pah;
|
||||||
@ -390,14 +392,14 @@ bool airtaudio::api::Pulse::probeDeviceOpen(uint32_t _device,
|
|||||||
case INPUT:
|
case INPUT:
|
||||||
pah->s_rec = pa_simple_new(nullptr, "airtAudio", PA_STREAM_RECORD, nullptr, "Record", &ss, nullptr, nullptr, &error);
|
pah->s_rec = pa_simple_new(nullptr, "airtAudio", PA_STREAM_RECORD, nullptr, "Record", &ss, nullptr, nullptr, &error);
|
||||||
if (!pah->s_rec) {
|
if (!pah->s_rec) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::probeDeviceOpen: error connecting input to PulseAudio server.");
|
ATA_ERROR("error connecting input to PulseAudio server.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OUTPUT:
|
case OUTPUT:
|
||||||
pah->s_play = pa_simple_new(nullptr, "airtAudio", PA_STREAM_PLAYBACK, nullptr, "Playback", &ss, nullptr, nullptr, &error);
|
pah->s_play = pa_simple_new(nullptr, "airtAudio", PA_STREAM_PLAYBACK, nullptr, "Playback", &ss, nullptr, nullptr, &error);
|
||||||
if (!pah->s_play) {
|
if (!pah->s_play) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::probeDeviceOpen: error connecting output to PulseAudio server.");
|
ATA_ERROR("error connecting output to PulseAudio server.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -416,7 +418,7 @@ bool airtaudio::api::Pulse::probeDeviceOpen(uint32_t _device,
|
|||||||
m_stream.callbackInfo.isRunning = true;
|
m_stream.callbackInfo.isRunning = true;
|
||||||
pah->thread = new std::thread(pulseaudio_callback, (void *)&m_stream.callbackInfo);
|
pah->thread = new std::thread(pulseaudio_callback, (void *)&m_stream.callbackInfo);
|
||||||
if (pah->thread == nullptr) {
|
if (pah->thread == nullptr) {
|
||||||
ATA_ERROR("airtaudio::api::Pulse::probeDeviceOpen: error creating thread.");
|
ATA_ERROR("error creating thread.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ namespace airtaudio {
|
|||||||
uint32_t _channels,
|
uint32_t _channels,
|
||||||
uint32_t _firstChannel,
|
uint32_t _firstChannel,
|
||||||
uint32_t _sampleRate,
|
uint32_t _sampleRate,
|
||||||
airtaudio::format _format,
|
audio::format _format,
|
||||||
uint32_t *_bufferSize,
|
uint32_t *_bufferSize,
|
||||||
airtaudio::StreamOptions *_options);
|
airtaudio::StreamOptions *_options);
|
||||||
};
|
};
|
||||||
|
@ -35,7 +35,7 @@ std::ostream& airtaudio::operator <<(std::ostream& _os, enum errorType _obj) {
|
|||||||
return _os;
|
return _os;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& airtaudio::operator <<(std::ostream& _os, const airtaudio::format& _obj) {
|
std::ostream& airtaudio::operator <<(std::ostream& _os, const audio::format& _obj) {
|
||||||
switch(_obj) {
|
switch(_obj) {
|
||||||
case SINT8:
|
case SINT8:
|
||||||
_os << "SINT8";
|
_os << "SINT8";
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <audio/channel.h>
|
||||||
|
#include <audio/format.h>
|
||||||
|
|
||||||
// defien type : uintXX_t and intXX_t
|
// defien type : uintXX_t and intXX_t
|
||||||
#define __STDC_LIMIT_MACROS
|
#define __STDC_LIMIT_MACROS
|
||||||
@ -37,35 +39,6 @@ namespace airtaudio {
|
|||||||
// airtaudio version
|
// airtaudio version
|
||||||
static const std::string VERSION("4.0.12");
|
static const std::string VERSION("4.0.12");
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Debug operator To display the curent element in a Human redeable information
|
|
||||||
*/
|
|
||||||
//std::ostream& operator <<(std::ostream& _os, enum errorType _obj);
|
|
||||||
/**
|
|
||||||
* @typedef typedef uint64_t format;
|
|
||||||
* @brief airtaudio data format type.
|
|
||||||
*
|
|
||||||
* Support for signed integers and floats. Audio data fed to/from an
|
|
||||||
* airtaudio stream is assumed to ALWAYS be in host byte order. The
|
|
||||||
* internal routines will automatically take care of any necessary
|
|
||||||
* byte-swapping between the host format and the soundcard. Thus,
|
|
||||||
* endian-ness is not a concern in the following format definitions.
|
|
||||||
*
|
|
||||||
* - \e SINT8: 8-bit signed integer.
|
|
||||||
* - \e SINT16: 16-bit signed integer.
|
|
||||||
* - \e SINT24: 24-bit signed integer.
|
|
||||||
* - \e SINT32: 32-bit signed integer.
|
|
||||||
* - \e FLOAT32: Normalized between plus/minus 1.0.
|
|
||||||
* - \e FLOAT64: Normalized between plus/minus 1.0.
|
|
||||||
*/
|
|
||||||
typedef uint64_t format;
|
|
||||||
static const format SINT8 = 0x1; // 8-bit signed integer.
|
|
||||||
static const format SINT16 = 0x2; // 16-bit signed integer.
|
|
||||||
static const format SINT24 = 0x4; // 24-bit signed integer.
|
|
||||||
static const format SINT32 = 0x8; // 32-bit signed integer.
|
|
||||||
static const format FLOAT32 = 0x10; // Normalized between plus/minus 1.0.
|
|
||||||
static const format FLOAT64 = 0x20; // Normalized between plus/minus 1.0.
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef typedef uint64_t streamFlags;
|
* @typedef typedef uint64_t streamFlags;
|
||||||
* @brief RtAudio stream option flags.
|
* @brief RtAudio stream option flags.
|
||||||
|
@ -17,6 +17,7 @@ def create(target):
|
|||||||
'airtaudio/Api.cpp',
|
'airtaudio/Api.cpp',
|
||||||
'airtaudio/api/Dummy.cpp',
|
'airtaudio/api/Dummy.cpp',
|
||||||
])
|
])
|
||||||
|
myModule.add_module_depend(['audio'])
|
||||||
|
|
||||||
myModule.add_export_flag_CC(['-D__AIRTAUDIO_API_DUMMY_H__'])
|
myModule.add_export_flag_CC(['-D__AIRTAUDIO_API_DUMMY_H__'])
|
||||||
if target.name=="Windows":
|
if target.name=="Windows":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user