[DEV] alsa poll mode availlable ...

This commit is contained in:
Edouard DUPIN 2015-06-11 21:33:32 +02:00
parent dbd3c18ac3
commit bb16adc099
3 changed files with 104 additions and 141 deletions

View File

@ -152,7 +152,7 @@ bool audio::orchestra::api::Alsa::getNamedDeviceInfoLocal(const std::string& _de
} }
result = snd_pcm_open(&phandle, _deviceName.c_str(), stream, openMode | SND_PCM_NONBLOCK); result = snd_pcm_open(&phandle, _deviceName.c_str(), stream, openMode | SND_PCM_NONBLOCK);
if (result < 0) { if (result < 0) {
ATA_ERROR("snd_pcm_open error for device (" << _deviceName << "), " << snd_strerror(result) << "."); ATA_ERROR("snd_pcm_open error for device (" << _deviceName << "), " << snd_strerror(result) << ". (seems to be already open)");
// TODO : Return audio::orchestra::error_warning; // TODO : Return audio::orchestra::error_warning;
goto captureProbe; goto captureProbe;
} }
@ -173,6 +173,7 @@ bool audio::orchestra::api::Alsa::getNamedDeviceInfoLocal(const std::string& _de
// TODO : Return audio::orchestra::error_warning; // TODO : Return audio::orchestra::error_warning;
goto captureProbe; goto captureProbe;
} }
ATA_ERROR("Output channel = " << value);
_info.outputChannels = value; _info.outputChannels = value;
snd_pcm_close(phandle); snd_pcm_close(phandle);
@ -193,7 +194,7 @@ captureProbe:
} }
result = snd_pcm_open(&phandle, _deviceName.c_str(), stream, openMode | SND_PCM_NONBLOCK); result = snd_pcm_open(&phandle, _deviceName.c_str(), stream, openMode | SND_PCM_NONBLOCK);
if (result < 0) { if (result < 0) {
ATA_ERROR("snd_pcm_open error for device (" << _deviceName << "), " << snd_strerror(result) << "."); ATA_ERROR("snd_pcm_open error for device (" << _deviceName << "), " << snd_strerror(result) << ". (seems to be already open)");
// TODO : Return audio::orchestra::error_warning; // TODO : Return audio::orchestra::error_warning;
if (_info.outputChannels == 0) { if (_info.outputChannels == 0) {
return true; return true;
@ -221,13 +222,11 @@ captureProbe:
} }
goto probeParameters; goto probeParameters;
} }
ATA_ERROR("Input channel = " << value);
_info.inputChannels = value; _info.inputChannels = value;
snd_pcm_close(phandle); snd_pcm_close(phandle);
// If device opens for both playback and capture, we determine the channels. // ALSA does not support duplex, but synchronization between I/Os
if ( _info.outputChannels > 0 _info.duplexChannels = 0;
&& _info.inputChannels > 0) {
_info.duplexChannels = (_info.outputChannels > _info.inputChannels) ? _info.inputChannels : _info.outputChannels;
}
// ALSA doesn't provide default devices so we'll use the first available one. // ALSA doesn't provide default devices so we'll use the first available one.
if ( _localDeviceId == 0 if ( _localDeviceId == 0
&& _info.outputChannels > 0) { && _info.outputChannels > 0) {
@ -510,9 +509,10 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
} else { } else {
stream = SND_PCM_STREAM_CAPTURE; stream = SND_PCM_STREAM_CAPTURE;
} }
snd_pcm_t *phandle; //int32_t openMode = SND_PCM_NONBLOCK;
int32_t openMode = SND_PCM_ASYNC; int32_t openMode = SND_PCM_ASYNC;
result = snd_pcm_open(&phandle, _deviceName.c_str(), stream, openMode); //int32_t openMode = SND_PCM_ASYNC | SND_PCM_NONBLOCK;
result = snd_pcm_open(&m_private->handle, _deviceName.c_str(), stream, openMode);
ATA_DEBUG("Configure Mode : SND_PCM_ASYNC"); ATA_DEBUG("Configure Mode : SND_PCM_ASYNC");
if (result < 0) { if (result < 0) {
if (_mode == audio::orchestra::mode_output) { if (_mode == audio::orchestra::mode_output) {
@ -525,33 +525,33 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
// Fill the parameter structure. // Fill the parameter structure.
snd_pcm_hw_params_t *hw_params; snd_pcm_hw_params_t *hw_params;
snd_pcm_hw_params_alloca(&hw_params); snd_pcm_hw_params_alloca(&hw_params);
result = snd_pcm_hw_params_any(phandle, hw_params); result = snd_pcm_hw_params_any(m_private->handle, hw_params);
if (result < 0) { if (result < 0) {
snd_pcm_close(phandle); snd_pcm_close(m_private->handle);
ATA_ERROR("error getting pcm device (" << _deviceName << ") parameters, " << snd_strerror(result) << "."); ATA_ERROR("error getting pcm device (" << _deviceName << ") parameters, " << snd_strerror(result) << ".");
return false; return false;
} }
#if 1 #if 1
ATA_DEBUG("configure Acces: SND_PCM_ACCESS_MMAP_INTERLEAVED"); ATA_DEBUG("configure Acces: SND_PCM_ACCESS_MMAP_INTERLEAVED");
result = snd_pcm_hw_params_set_access(phandle, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED); result = snd_pcm_hw_params_set_access(m_private->handle, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED);
if (result >= 0) { if (result >= 0) {
m_deviceInterleaved[modeToIdTable(_mode)] = true; m_deviceInterleaved[modeToIdTable(_mode)] = true;
m_private->mmapInterface = true; m_private->mmapInterface = true;
} else { } else {
ATA_DEBUG("configure Acces: SND_PCM_ACCESS_MMAP_NONINTERLEAVED"); ATA_DEBUG("configure Acces: SND_PCM_ACCESS_MMAP_NONINTERLEAVED");
result = snd_pcm_hw_params_set_access(phandle, hw_params, SND_PCM_ACCESS_MMAP_NONINTERLEAVED); result = snd_pcm_hw_params_set_access(m_private->handle, hw_params, SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
if (result >= 0) { if (result >= 0) {
m_deviceInterleaved[modeToIdTable(_mode)] = false; m_deviceInterleaved[modeToIdTable(_mode)] = false;
m_private->mmapInterface = true; m_private->mmapInterface = true;
} else { } else {
ATA_DEBUG("configure Acces: SND_PCM_ACCESS_RW_INTERLEAVED"); ATA_DEBUG("configure Acces: SND_PCM_ACCESS_RW_INTERLEAVED");
result = snd_pcm_hw_params_set_access(phandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); result = snd_pcm_hw_params_set_access(m_private->handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
if (result >= 0) { if (result >= 0) {
m_deviceInterleaved[modeToIdTable(_mode)] = true; m_deviceInterleaved[modeToIdTable(_mode)] = true;
m_private->mmapInterface = false; m_private->mmapInterface = false;
} else { } else {
ATA_DEBUG("configure Acces: SND_PCM_ACCESS_RW_NONINTERLEAVED"); ATA_DEBUG("configure Acces: SND_PCM_ACCESS_RW_NONINTERLEAVED");
result = snd_pcm_hw_params_set_access(phandle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED); result = snd_pcm_hw_params_set_access(m_private->handle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED);
if (result >= 0) { if (result >= 0) {
m_deviceInterleaved[modeToIdTable(_mode)] = false; m_deviceInterleaved[modeToIdTable(_mode)] = false;
m_private->mmapInterface = false; m_private->mmapInterface = false;
@ -564,13 +564,13 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
} }
#else #else
ATA_DEBUG("configure Acces: SND_PCM_ACCESS_RW_INTERLEAVED"); ATA_DEBUG("configure Acces: SND_PCM_ACCESS_RW_INTERLEAVED");
result = snd_pcm_hw_params_set_access(phandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); result = snd_pcm_hw_params_set_access(m_private->handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
if (result >= 0) { if (result >= 0) {
m_deviceInterleaved[modeToIdTable(_mode)] = true; m_deviceInterleaved[modeToIdTable(_mode)] = true;
m_private->mmapInterface = false; m_private->mmapInterface = false;
} else { } else {
ATA_DEBUG("configure Acces: SND_PCM_ACCESS_RW_NONINTERLEAVED"); ATA_DEBUG("configure Acces: SND_PCM_ACCESS_RW_NONINTERLEAVED");
result = snd_pcm_hw_params_set_access(phandle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED); result = snd_pcm_hw_params_set_access(m_private->handle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED);
if (result >= 0) { if (result >= 0) {
m_deviceInterleaved[modeToIdTable(_mode)] = false; m_deviceInterleaved[modeToIdTable(_mode)] = false;
m_private->mmapInterface = false; m_private->mmapInterface = false;
@ -581,7 +581,7 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
} }
#endif #endif
if (result < 0) { if (result < 0) {
snd_pcm_close(phandle); snd_pcm_close(m_private->handle);
ATA_ERROR("error setting pcm device (" << _deviceName << ") access, " << snd_strerror(result) << "."); ATA_ERROR("error setting pcm device (" << _deviceName << ") access, " << snd_strerror(result) << ".");
return false; return false;
} }
@ -601,19 +601,19 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
} else if (_format == audio::format_double) { } 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(m_private->handle, hw_params, deviceFormat) == 0) {
m_deviceFormat[modeToIdTable(_mode)] = _format; m_deviceFormat[modeToIdTable(_mode)] = _format;
} else { } else {
// 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(m_private->handle);
ATA_ERROR("pcm device " << _deviceName << " data format not supported: " << _format); ATA_ERROR("pcm device " << _deviceName << " data format not supported: " << _format);
// TODO : display list of all supported format .. // TODO : display list of all supported format ..
return false; return false;
} }
ATA_DEBUG("configure format: " << _format); ATA_DEBUG("configure format: " << _format);
result = snd_pcm_hw_params_set_format(phandle, hw_params, deviceFormat); result = snd_pcm_hw_params_set_format(m_private->handle, hw_params, deviceFormat);
if (result < 0) { if (result < 0) {
snd_pcm_close(phandle); snd_pcm_close(m_private->handle);
ATA_ERROR("error setting pcm device (" << _deviceName << ") data format, " << snd_strerror(result) << "."); ATA_ERROR("error setting pcm device (" << _deviceName << ") data format, " << snd_strerror(result) << ".");
return false; return false;
} }
@ -625,16 +625,16 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
ATA_DEBUG("configure swap Byte"); ATA_DEBUG("configure swap Byte");
m_doByteSwap[modeToIdTable(_mode)] = true; m_doByteSwap[modeToIdTable(_mode)] = true;
} else if (result < 0) { } else if (result < 0) {
snd_pcm_close(phandle); snd_pcm_close(m_private->handle);
ATA_ERROR("error getting pcm device (" << _deviceName << ") endian-ness, " << snd_strerror(result) << "."); ATA_ERROR("error getting pcm device (" << _deviceName << ") endian-ness, " << snd_strerror(result) << ".");
return false; return false;
} }
} }
ATA_DEBUG("Set frequency " << _sampleRate); ATA_DEBUG("Set frequency " << _sampleRate);
// Set the sample rate. // Set the sample rate.
result = snd_pcm_hw_params_set_rate_near(phandle, hw_params, (uint32_t*) &_sampleRate, 0); result = snd_pcm_hw_params_set_rate_near(m_private->handle, hw_params, (uint32_t*) &_sampleRate, 0);
if (result < 0) { if (result < 0) {
snd_pcm_close(phandle); snd_pcm_close(m_private->handle);
ATA_ERROR("error setting sample rate on device (" << _deviceName << "), " << snd_strerror(result) << "."); ATA_ERROR("error setting sample rate on device (" << _deviceName << "), " << snd_strerror(result) << ".");
return false; return false;
} }
@ -645,18 +645,18 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
result = snd_pcm_hw_params_get_channels_max(hw_params, &value); result = snd_pcm_hw_params_get_channels_max(hw_params, &value);
uint32_t deviceChannels = value; uint32_t deviceChannels = value;
if (result < 0) { if (result < 0) {
snd_pcm_close(phandle); snd_pcm_close(m_private->handle);
ATA_ERROR("requested channel parameters not supported by device (" << _deviceName << "), " << snd_strerror(result) << "."); ATA_ERROR("requested channel parameters not supported by device (" << _deviceName << "), " << snd_strerror(result) << ".");
return false; return false;
} }
if (deviceChannels < _channels + _firstChannel) { if (deviceChannels < _channels + _firstChannel) {
snd_pcm_close(phandle); snd_pcm_close(m_private->handle);
ATA_ERROR("requested channel " << _channels << " have : " << deviceChannels ); ATA_ERROR("requested channel " << _channels << " have : " << deviceChannels );
return false; return false;
} }
result = snd_pcm_hw_params_get_channels_min(hw_params, &value); result = snd_pcm_hw_params_get_channels_min(hw_params, &value);
if (result < 0) { if (result < 0) {
snd_pcm_close(phandle); snd_pcm_close(m_private->handle);
ATA_ERROR("error getting minimum channels for device (" << _deviceName << "), " << snd_strerror(result) << "."); ATA_ERROR("error getting minimum channels for device (" << _deviceName << "), " << snd_strerror(result) << ".");
return false; return false;
} }
@ -668,9 +668,9 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
ATA_DEBUG("snd_pcm_hw_params_set_channels: " << deviceChannels); ATA_DEBUG("snd_pcm_hw_params_set_channels: " << deviceChannels);
m_nDeviceChannels[modeToIdTable(_mode)] = deviceChannels; m_nDeviceChannels[modeToIdTable(_mode)] = deviceChannels;
// Set the device channels. // Set the device channels.
result = snd_pcm_hw_params_set_channels(phandle, hw_params, deviceChannels); result = snd_pcm_hw_params_set_channels(m_private->handle, hw_params, deviceChannels);
if (result < 0) { if (result < 0) {
snd_pcm_close(phandle); snd_pcm_close(m_private->handle);
ATA_ERROR("error setting channels for device (" << _deviceName << "), " << snd_strerror(result) << "."); ATA_ERROR("error setting channels for device (" << _deviceName << "), " << snd_strerror(result) << ".");
return false; return false;
} }
@ -678,9 +678,9 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
// Set the buffer (or period) size. // Set the buffer (or period) size.
int32_t dir = 0; int32_t dir = 0;
snd_pcm_uframes_t periodSize = *_bufferSize; snd_pcm_uframes_t periodSize = *_bufferSize;
result = snd_pcm_hw_params_set_period_size_near(phandle, hw_params, &periodSize, &dir); result = snd_pcm_hw_params_set_period_size_near(m_private->handle, hw_params, &periodSize, &dir);
if (result < 0) { if (result < 0) {
snd_pcm_close(phandle); snd_pcm_close(m_private->handle);
ATA_ERROR("error setting period size for device (" << _deviceName << "), " << snd_strerror(result) << "."); ATA_ERROR("error setting period size for device (" << _deviceName << "), " << snd_strerror(result) << ".");
return false; return false;
} }
@ -700,9 +700,9 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
if (periods < 2) { if (periods < 2) {
periods = 4; // a fairly safe default value periods = 4; // a fairly safe default value
} }
result = snd_pcm_hw_params_set_periods_near(phandle, hw_params, &periods, &dir); result = snd_pcm_hw_params_set_periods_near(m_private->handle, hw_params, &periods, &dir);
if (result < 0) { if (result < 0) {
snd_pcm_close(phandle); snd_pcm_close(m_private->handle);
ATA_ERROR("error setting periods for device (" << _deviceName << "), " << snd_strerror(result) << "."); ATA_ERROR("error setting periods for device (" << _deviceName << "), " << snd_strerror(result) << ".");
return false; return false;
} }
@ -713,7 +713,7 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
if ( m_mode == audio::orchestra::mode_output if ( m_mode == audio::orchestra::mode_output
&& _mode == audio::orchestra::mode_input && _mode == audio::orchestra::mode_input
&& *_bufferSize != m_bufferSize) { && *_bufferSize != m_bufferSize) {
snd_pcm_close(phandle); snd_pcm_close(m_private->handle);
ATA_ERROR("system error setting buffer size for duplex stream on device (" << _deviceName << ")."); ATA_ERROR("system error setting buffer size for duplex stream on device (" << _deviceName << ").");
return false; return false;
} }
@ -734,9 +734,9 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
} }
// Install the hardware configuration // Install the hardware configuration
result = snd_pcm_hw_params(phandle, hw_params); result = snd_pcm_hw_params(m_private->handle, hw_params);
if (result < 0) { if (result < 0) {
snd_pcm_close(phandle); snd_pcm_close(m_private->handle);
ATA_ERROR("error installing hardware configuration on device (" << _deviceName << "), " << snd_strerror(result) << "."); ATA_ERROR("error installing hardware configuration on device (" << _deviceName << "), " << snd_strerror(result) << ".");
return false; return false;
} }
@ -744,39 +744,40 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
// Set the software configuration to fill buffers with zeros and prevent device stopping on xruns. // Set the software configuration to fill buffers with zeros and prevent device stopping on xruns.
snd_pcm_sw_params_t *swParams = nullptr; snd_pcm_sw_params_t *swParams = nullptr;
snd_pcm_sw_params_alloca(&swParams); snd_pcm_sw_params_alloca(&swParams);
snd_pcm_sw_params_current(phandle, swParams); snd_pcm_sw_params_current(m_private->handle, swParams);
#if 0 #if 0
ATA_DEBUG("configure start_threshold: " << int64_t(*_bufferSize)); ATA_DEBUG("configure start_threshold: " << int64_t(*_bufferSize));
snd_pcm_sw_params_set_start_threshold(phandle, swParams, *_bufferSize); snd_pcm_sw_params_set_start_threshold(m_private->handle, swParams, *_bufferSize);
#else #else
//ATA_DEBUG("configure start_threshold: " << int64_t(1)); //ATA_DEBUG("configure start_threshold: " << int64_t(1));
//snd_pcm_sw_params_set_start_threshold(phandle, swParams, 1); //snd_pcm_sw_params_set_start_threshold(m_private->handle, swParams, 1);
ATA_DEBUG("configure start_threshold: " << int64_t(0)); ATA_DEBUG("configure start_threshold: " << int64_t(0));
snd_pcm_sw_params_set_start_threshold(phandle, swParams, 0); snd_pcm_sw_params_set_start_threshold(m_private->handle, swParams, 0);
#endif #endif
#if 1 #if 1
ATA_DEBUG("configure stop_threshold: " << ULONG_MAX); ATA_DEBUG("configure stop_threshold: " << ULONG_MAX);
snd_pcm_sw_params_set_stop_threshold(phandle, swParams, ULONG_MAX); snd_pcm_sw_params_set_stop_threshold(m_private->handle, swParams, ULONG_MAX);
#else #else
ATA_DEBUG("configure stop_threshold: " << m_bufferSize*periods); ATA_DEBUG("configure stop_threshold: " << m_bufferSize*periods);
snd_pcm_sw_params_set_stop_threshold(phandle, swParams, m_bufferSize*periods); snd_pcm_sw_params_set_stop_threshold(m_private->handle, swParams, m_bufferSize*periods);
#endif #endif
//ATA_DEBUG("configure silence_threshold: " << 0); //ATA_DEBUG("configure silence_threshold: " << 0);
//snd_pcm_sw_params_set_silence_threshold(phandle, swParams, 0); //snd_pcm_sw_params_set_silence_threshold(m_private->handle, swParams, 0);
// The following two settings were suggested by Theo Veenker // The following two settings were suggested by Theo Veenker
#if 0 #if 1
snd_pcm_sw_params_set_avail_min(phandle, swParams, *_bufferSize*periods/2); snd_pcm_sw_params_set_avail_min(m_private->handle, swParams, *_bufferSize*periods/2);
snd_pcm_sw_params_get_avail_min(swParams, &val); snd_pcm_sw_params_get_avail_min(swParams, &val);
ATA_DEBUG("configure set availlable min: " << *_bufferSize*periods/2 << " really set: " << val); ATA_DEBUG("configure set availlable min: " << *_bufferSize*periods/2 << " really set: " << val);
#endif #endif
//int valInt; #if 0
//snd_pcm_sw_params_get_period_event(swParams, &valInt); int valInt;
//ATA_DEBUG("configure get period_event: " << valInt); snd_pcm_sw_params_get_period_event(swParams, &valInt);
//snd_pcm_sw_params_set_xfer_align(phandle, swParams, 1); ATA_DEBUG("configure get period_event: " << valInt);
snd_pcm_sw_params_set_xfer_align(m_private->handle, swParams, 1);
// here are two options for a fix // here are two options for a fix
//snd_pcm_sw_params_set_silence_size(phandle, swParams, ULONG_MAX); //snd_pcm_sw_params_set_silence_size(m_private->handle, swParams, ULONG_MAX);
#endif
//snd_pcm_sw_params_set_tstamp_mode(phandle, swParams, SND_PCM_TSTAMP_ENABLE); //snd_pcm_sw_params_set_tstamp_mode(m_private->handle, swParams, SND_PCM_TSTAMP_ENABLE);
ATA_DEBUG("configuration: "); ATA_DEBUG("configuration: ");
//ATA_DEBUG(" start_mode: " << snd_pcm_start_mode_name(snd_pcm_sw_params_get_start_mode(swParams))); //ATA_DEBUG(" start_mode: " << snd_pcm_start_mode_name(snd_pcm_sw_params_get_start_mode(swParams)));
@ -791,8 +792,8 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
//ATA_DEBUG(" sleep_min: " << swParams->sleep_min); //ATA_DEBUG(" sleep_min: " << swParams->sleep_min);
snd_pcm_sw_params_get_avail_min(swParams, &val); snd_pcm_sw_params_get_avail_min(swParams, &val);
ATA_DEBUG(" avail_min: " << val); ATA_DEBUG(" avail_min: " << val);
snd_pcm_sw_params_get_xfer_align(swParams, &val); //snd_pcm_sw_params_get_xfer_align(swParams, &val);
ATA_DEBUG(" xfer_align: " << val); //ATA_DEBUG(" xfer_align: " << val);
snd_pcm_sw_params_get_silence_threshold(swParams, &val); snd_pcm_sw_params_get_silence_threshold(swParams, &val);
ATA_DEBUG(" silence_threshold: " << val); ATA_DEBUG(" silence_threshold: " << val);
@ -800,9 +801,9 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
ATA_DEBUG(" silence_size: " << val); ATA_DEBUG(" silence_size: " << val);
snd_pcm_sw_params_get_boundary(swParams, &val); snd_pcm_sw_params_get_boundary(swParams, &val);
ATA_DEBUG(" boundary: " << val); ATA_DEBUG(" boundary: " << val);
result = snd_pcm_sw_params(phandle, swParams); result = snd_pcm_sw_params(m_private->handle, swParams);
if (result < 0) { if (result < 0) {
snd_pcm_close(phandle); snd_pcm_close(m_private->handle);
ATA_ERROR("error installing software configuration on device (" << _deviceName << "), " << snd_strerror(result) << "."); ATA_ERROR("error installing software configuration on device (" << _deviceName << "), " << snd_strerror(result) << ".");
return false; return false;
} }
@ -827,8 +828,6 @@ bool audio::orchestra::api::Alsa::probeDeviceOpenName(const std::string& _device
&& m_nUserChannels[modeToIdTable(_mode)] > 1) { && m_nUserChannels[modeToIdTable(_mode)] > 1) {
m_doConvertBuffer[modeToIdTable(_mode)] = true; m_doConvertBuffer[modeToIdTable(_mode)] = true;
} }
m_private->handle = phandle;
phandle = 0;
// Allocate necessary internal buffers. // Allocate necessary internal buffers.
uint64_t bufferBytes; uint64_t bufferBytes;
bufferBytes = m_nUserChannels[modeToIdTable(_mode)] * *_bufferSize * audio::getFormatBytes(m_userFormat); bufferBytes = m_nUserChannels[modeToIdTable(_mode)] * *_bufferSize * audio::getFormatBytes(m_userFormat);
@ -883,9 +882,6 @@ error:
snd_pcm_close(m_private->handle); snd_pcm_close(m_private->handle);
m_private->handle = nullptr; m_private->handle = nullptr;
} }
if (phandle) {
snd_pcm_close(phandle);
}
for (int32_t iii=0; iii<2; ++iii) { for (int32_t iii=0; iii<2; ++iii) {
m_userBuffer[iii].clear(); m_userBuffer[iii].clear();
} }
@ -1040,46 +1036,40 @@ static int32_t wait_for_poll(snd_pcm_t* _handle, struct pollfd* _ufds, unsigned
if (revents & POLLOUT) { if (revents & POLLOUT) {
return 0; return 0;
} }
if (revents & POLLIN) {
return 0;
}
} }
} }
void audio::orchestra::api::Alsa::callbackEvent() { void audio::orchestra::api::Alsa::callbackEvent() {
// Lock while the system is not started ...
if (m_state == audio::orchestra::state_stopped) {
std11::unique_lock<std11::mutex> lck(m_mutex);
while (!m_private->runnable) {
m_private->runnable_cv.wait(lck);
}
if (m_state != audio::orchestra::state_running) {
return;
}
}
etk::thread::setName("Alsa IO-" + m_name); etk::thread::setName("Alsa IO-" + m_name);
//Wait data with poll //Wait data with poll
/* std::vector<struct pollfd> ufds;
snd_pcm_channel_area_t *areas = nullptr;
areas = (snd_pcm_channel_area_t *)calloc(chennels, sizeof(snd_pcm_channel_area_t));
if (areas == nullptr) {
ATA_CRITICAL("No enough memory");
}
for (chn = 0; chn < channels; chn++) {
areas[chn].addr = samples;
areas[chn].first = chn * snd_pcm_format_physical_width(format);
areas[chn].step = channels * snd_pcm_format_physical_width(format);
}
*/
struct pollfd *ufds;
signed short *ptr; signed short *ptr;
int32_t err, count, cptr, init; int32_t err, count, cptr, init;
count = snd_pcm_poll_descriptors_count(m_private->handle); count = snd_pcm_poll_descriptors_count(m_private->handle);
if (count <= 0) { if (count <= 0) {
ATA_CRITICAL("Invalid poll descriptors count"); ATA_CRITICAL("Invalid poll descriptors count");
} }
ufds = (struct pollfd*)malloc(sizeof(struct pollfd) * count); ufds.resize(count);
if (ufds == nullptr) { if (ufds.size() == 0) {
ATA_CRITICAL("No enough memory\n"); ATA_CRITICAL("No enough memory\n");
} }
if ((err = snd_pcm_poll_descriptors(m_private->handle, ufds, count)) < 0) { if ((err = snd_pcm_poll_descriptors(m_private->handle, &(ufds[0]), count)) < 0) {
ATA_CRITICAL("Unable to obtain poll descriptors for playback: "<< snd_strerror(err)); ATA_CRITICAL("Unable to obtain poll descriptors for playback: "<< snd_strerror(err));
} }
while (m_private->threadRunning == true) { while (m_private->threadRunning == true) {
ATA_INFO("Poll [Start] " << count);
err = wait_for_poll(m_private->handle, ufds, count);
ATA_INFO("Poll [STOP] " << err);
if (err < 0) {
ATA_ERROR(" POLL timeout ...");
return;
}
// have data or need data ... // have data or need data ...
if (m_private->mmapInterface == false) { if (m_private->mmapInterface == false) {
if (m_mode == audio::orchestra::mode_input) { if (m_mode == audio::orchestra::mode_input) {
@ -1094,8 +1084,15 @@ void audio::orchestra::api::Alsa::callbackEvent() {
callbackEventOneCycleMMAPWrite(); callbackEventOneCycleMMAPWrite();
} }
} }
ATA_VERBOSE("Poll [Start] " << count);
err = wait_for_poll(m_private->handle, &(ufds[0]), count);
ATA_VERBOSE("Poll [STOP] " << err);
if (err < 0) {
ATA_ERROR(" POLL timeout ...");
return;
} }
ATA_ERROR("End of thread"); }
ATA_DEBUG("End of thread");
} }
audio::Time audio::orchestra::api::Alsa::getStreamTime() { audio::Time audio::orchestra::api::Alsa::getStreamTime() {
@ -1168,19 +1165,6 @@ audio::Time audio::orchestra::api::Alsa::getStreamTime() {
} }
void audio::orchestra::api::Alsa::callbackEventOneCycleRead() { void audio::orchestra::api::Alsa::callbackEventOneCycleRead() {
if (m_state == audio::orchestra::state_stopped) {
std11::unique_lock<std11::mutex> lck(m_mutex);
// TODO : Set this back ....
/*
while (!m_private->runnable) {
m_private->runnable_cv.wait(lck);
}
*/
usleep(1000);
if (m_state != audio::orchestra::state_running) {
return;
}
}
if (m_state == audio::orchestra::state_closed) { if (m_state == audio::orchestra::state_closed) {
ATA_CRITICAL("the stream is closed ... this shouldn't happen!"); ATA_CRITICAL("the stream is closed ... this shouldn't happen!");
return; // TODO : notify appl: audio::orchestra::error_warning; return; // TODO : notify appl: audio::orchestra::error_warning;
@ -1297,19 +1281,6 @@ unlock:
} }
void audio::orchestra::api::Alsa::callbackEventOneCycleWrite() { void audio::orchestra::api::Alsa::callbackEventOneCycleWrite() {
if (m_state == audio::orchestra::state_stopped) {
std11::unique_lock<std11::mutex> lck(m_mutex);
// TODO : Set this back ....
/*
while (!m_private->runnable) {
m_private->runnable_cv.wait(lck);
}
*/
usleep(1000);
if (m_state != audio::orchestra::state_running) {
return;
}
}
if (m_state == audio::orchestra::state_closed) { if (m_state == audio::orchestra::state_closed) {
ATA_CRITICAL("the stream is closed ... this shouldn't happen!"); ATA_CRITICAL("the stream is closed ... this shouldn't happen!");
return; // TODO : notify appl: audio::orchestra::error_warning; return; // TODO : notify appl: audio::orchestra::error_warning;
@ -1412,20 +1383,6 @@ unlock:
} }
void audio::orchestra::api::Alsa::callbackEventOneCycleMMAPWrite() { void audio::orchestra::api::Alsa::callbackEventOneCycleMMAPWrite() {
if (m_state == audio::orchestra::state_stopped) {
std11::unique_lock<std11::mutex> lck(m_mutex);
// TODO : Set this back ....
/*
while (!m_private->runnable) {
m_private->runnable_cv.wait(lck);
}
*/
usleep(1000);
if (m_state != audio::orchestra::state_running) {
return;
}
}
if (m_state == audio::orchestra::state_closed) { if (m_state == audio::orchestra::state_closed) {
ATA_CRITICAL("the stream is closed ... this shouldn't happen!"); ATA_CRITICAL("the stream is closed ... this shouldn't happen!");
return; // TODO : notify appl: audio::orchestra::error_warning; return; // TODO : notify appl: audio::orchestra::error_warning;
@ -1561,19 +1518,6 @@ unlock:
} }
} }
void audio::orchestra::api::Alsa::callbackEventOneCycleMMAPRead() { void audio::orchestra::api::Alsa::callbackEventOneCycleMMAPRead() {
if (m_state == audio::orchestra::state_stopped) {
std11::unique_lock<std11::mutex> lck(m_mutex);
// TODO : Set this back ....
/*
while (!m_private->runnable) {
m_private->runnable_cv.wait(lck);
}
*/
usleep(1000);
if (m_state != audio::orchestra::state_running) {
return;
}
}
if (m_state == audio::orchestra::state_closed) { if (m_state == audio::orchestra::state_closed) {
ATA_CRITICAL("the stream is closed ... this shouldn't happen!"); ATA_CRITICAL("the stream is closed ... this shouldn't happen!");
return; // TODO : notify appl: audio::orchestra::error_warning; return; // TODO : notify appl: audio::orchestra::error_warning;

View File

@ -19,3 +19,21 @@ int32_t audio::orchestra::modeToIdTable(enum mode _mode) {
} }
return 0; return 0;
} }
std::ostream& audio::operator <<(std::ostream& _os, enum audio::orchestra::mode _obj) {
switch (_obj) {
case audio::orchestra::mode_unknow:
_os << "unknow";
break;
case audio::orchestra::mode_duplex:
_os << "duplex";
break;
case audio::orchestra::mode_output:
_os << "output";
break;
case audio::orchestra::mode_input:
_os << "input";
break;
}
return _os;
}

View File

@ -21,6 +21,7 @@ namespace audio {
}; };
int32_t modeToIdTable(enum mode _mode); int32_t modeToIdTable(enum mode _mode);
} }
std::ostream& operator <<(std::ostream& _os, enum audio::orchestra::mode _obj);
} }
#endif #endif