#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <stdbool.h>
#include "tizen-audio-internal.h"
#include "tizen-audio-impl.h"
+#ifndef __USE_TINYALSA__
+#define DEVICE_NAME_MAX 32
+#endif
+
#ifdef __USE_TINYALSA__
/* Convert pcm format from pulse to alsa */
static const uint32_t g_format_convert_table[] = {
}
#ifdef __USE_TINYALSA__
-static struct pcm *__tinyalsa_open_device(audio_pcm_sample_spec_t *ss, size_t period_size, size_t period_count, uint32_t direction)
+static int __parse_card_device_number(const char *card, const char *device, unsigned int *card_u, unsigned int *device_u) {
+ AUDIO_RETURN_VAL_IF_FAIL(card, AUDIO_ERR_PARAMETER);
+ AUDIO_RETURN_VAL_IF_FAIL(device, AUDIO_ERR_PARAMETER);
+ AUDIO_RETURN_VAL_IF_FAIL(card_u, AUDIO_ERR_PARAMETER);
+ AUDIO_RETURN_VAL_IF_FAIL(device_u, AUDIO_ERR_PARAMETER);
+
+ AUDIO_LOG_DEBUG("card : %s, device : %s", card, device);
+
+ *card_u = (unsigned int) strtol(card, NULL, 10);
+ *device_u = (unsigned int) strtol(device, NULL, 10);
+
+ return 0;
+}
+
+static struct pcm *__tinyalsa_open_device(const char *card, const char *device, audio_pcm_sample_spec_t *ss, size_t period_size, size_t period_count, uint32_t direction)
{
struct pcm *pcm = NULL;
struct pcm_config config;
+ unsigned int card_u, device_u;
+ AUDIO_RETURN_NULL_IF_FAIL(device);
AUDIO_RETURN_NULL_IF_FAIL(ss);
config.channels = ss->channels;
config.stop_threshold = 0xFFFFFFFF;
config.silence_threshold = 0;
- AUDIO_LOG_INFO("direction %d, channels %d, rate %d, format %d, period_size %d, period_count %d", direction, ss->channels, ss->rate, ss->format, period_size, period_count);
+ AUDIO_LOG_INFO("card %s, device %s, direction %d, channels %d, rate %d, format %d, period_size %d, period_count %d",
+ card, device, direction, ss->channels, ss->rate, ss->format, period_size, period_count);
+
+ if (__parse_card_device_number(card, device, &card_u, &device_u) < 0) {
+ AUDIO_LOG_ERROR("Failed to get card device number from %s", device);
+ return NULL;
+ }
- pcm = pcm_open((direction == AUDIO_DIRECTION_OUT) ? PLAYBACK_CARD_ID : CAPTURE_CARD_ID,
- (direction == AUDIO_DIRECTION_OUT) ? PLAYBACK_PCM_DEVICE_ID : CAPTURE_PCM_DEVICE_ID,
- (direction == AUDIO_DIRECTION_OUT) ? PCM_OUT : PCM_IN,
- &config);
+ pcm = pcm_open(card_u, device_u, (direction == AUDIO_DIRECTION_OUT) ? PCM_OUT : PCM_IN, &config);
if (!pcm || !pcm_is_ready(pcm)) {
AUDIO_LOG_ERROR("Unable to open device (%s)", pcm_get_error(pcm));
pcm_close(pcm);
return audio_ret;
}
-audio_return_t _pcm_open(void **pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods)
+#ifndef __USE_TINYALSA__
+static int __make_alsa_device_name(const char *card, const char *device, char device_name[])
{
+ AUDIO_RETURN_VAL_IF_FAIL(card, AUDIO_ERR_PARAMETER);
+ AUDIO_RETURN_VAL_IF_FAIL(device, AUDIO_ERR_PARAMETER);
+ AUDIO_RETURN_VAL_IF_FAIL(device_name, AUDIO_ERR_PARAMETER);
+
+ snprintf(device_name, DEVICE_NAME_MAX, "hw:%s,%s", card, device);
+ return 0;
+}
+#endif
+
+audio_return_t _pcm_open(const char *card, const char *device, uint32_t direction, void *sample_spec,
+ uint32_t period_size, uint32_t periods, void **pcm_handle)
+{
+ int err;
+
+ AUDIO_RETURN_VAL_IF_FAIL(card, AUDIO_ERR_PARAMETER);
+ AUDIO_RETURN_VAL_IF_FAIL(device, AUDIO_ERR_PARAMETER);
+ AUDIO_RETURN_VAL_IF_FAIL((direction == AUDIO_DIRECTION_OUT) || (direction == AUDIO_DIRECTION_IN),
+ AUDIO_ERR_PARAMETER);
+
+ AUDIO_LOG_INFO("card(%s) device(%s) direction(%u) period_size(%u) periods(%u)",
+ card, device, direction, period_size, periods);
#ifdef __USE_TINYALSA__
audio_pcm_sample_spec_t *ss;
- int err;
ss = (audio_pcm_sample_spec_t *)sample_spec;
ss->format = __convert_format((audio_sample_format_t)ss->format);
- *pcm_handle = __tinyalsa_open_device(ss, (size_t)period_size, (size_t)periods, direction);
+ *pcm_handle = __tinyalsa_open_device(card, device, ss, (size_t)period_size, (size_t)periods, direction);
if (*pcm_handle == NULL) {
AUDIO_LOG_ERROR("Error opening PCM device");
return AUDIO_ERR_RESOURCE;
}
#else /* alsa-lib */
- int err, mode;
- char *device_name = NULL;
+ int mode;
+ audio_return_t ret;
+ char device_name[DEVICE_NAME_MAX];
+ __make_alsa_device_name(card, device, device_name);
mode = SND_PCM_NONBLOCK | SND_PCM_NO_AUTO_RESAMPLE | SND_PCM_NO_AUTO_CHANNELS | SND_PCM_NO_AUTO_FORMAT;
- if (direction == AUDIO_DIRECTION_OUT)
- device_name = PLAYBACK_PCM_DEVICE;
- else if (direction == AUDIO_DIRECTION_IN)
- device_name = CAPTURE_PCM_DEVICE;
- else {
- AUDIO_LOG_ERROR("Error get device_name, direction : %d", direction);
- return AUDIO_ERR_RESOURCE;
- }
-
if ((err = snd_pcm_open((snd_pcm_t **)pcm_handle, device_name, (direction == AUDIO_DIRECTION_OUT) ? SND_PCM_STREAM_PLAYBACK : SND_PCM_STREAM_CAPTURE, mode)) < 0) {
AUDIO_LOG_ERROR("Error opening PCM device %s : %s", device_name, snd_strerror(err));
return AUDIO_ERR_RESOURCE;
}
- if ((err = _pcm_set_params(*pcm_handle, direction, sample_spec, period_size, periods)) != AUDIO_RET_OK) {
- AUDIO_LOG_ERROR("Failed to set pcm parameters : %d", err);
- return err;
+ if ((ret = _pcm_set_params(*pcm_handle, direction, sample_spec, period_size, periods)) != AUDIO_RET_OK) {
+ AUDIO_LOG_ERROR("Failed to set pcm parameters : %d", ret);
+ return ret;
}
AUDIO_LOG_INFO("PCM device %s", device_name);
}
#endif
- AUDIO_LOG_INFO("PCM handle 0x%x start", pcm_handle);
+ AUDIO_LOG_INFO("PCM handle %p start", pcm_handle);
return AUDIO_RET_OK;
}
}
#endif
- AUDIO_LOG_INFO("PCM handle 0x%x stop", pcm_handle);
+ AUDIO_LOG_INFO("PCM handle %p stop", pcm_handle);
return AUDIO_RET_OK;
}
{
int err;
- AUDIO_LOG_INFO("Try to close PCM handle 0x%x", pcm_handle);
+ AUDIO_LOG_INFO("Try to close PCM handle %p", pcm_handle);
#ifdef __USE_TINYALSA__
if ((err = pcm_close(pcm_handle)) < 0) {
err = pcm_get_htimestamp(pcm_handle, &frames_avail, &tspec);
if (err < 0) {
- AUDIO_LOG_ERROR("Could not get avail and timespec at PCM handle 0x%x : %d", pcm_handle, err);
+ AUDIO_LOG_ERROR("Could not get avail and timespec at PCM handle %p : %d", pcm_handle, err);
return AUDIO_ERR_IOCTL;
}
snd_pcm_sframes_t frames_avail;
if ((frames_avail = snd_pcm_avail(pcm_handle)) < 0) {
- AUDIO_LOG_ERROR("Could not get avail at PCM handle 0x%x : %d", pcm_handle, frames_avail);
+ AUDIO_LOG_ERROR("Could not get avail at PCM handle %p : %ld", pcm_handle, frames_avail);
return AUDIO_ERR_IOCTL;
}
frames_written = snd_pcm_writei(pcm_handle, buffer, (snd_pcm_uframes_t) frames);
if (frames_written < 0) {
- AUDIO_LOG_ERROR("Failed to write pcm : %d", frames_written);
+ AUDIO_LOG_ERROR("Failed to write pcm : %ld", frames_written);
return AUDIO_ERR_IOCTL;
}
frames_read = snd_pcm_readi(pcm_handle, buffer, (snd_pcm_uframes_t)frames);
if (frames_read < 0) {
- AUDIO_LOG_ERROR("Failed to read pcm : %d", frames_read);
+ AUDIO_LOG_ERROR("Failed to read pcm : %ld", frames_read);
return AUDIO_ERR_IOCTL;
}
_stop_threshold = config->stop_threshold;
_silence_threshold = config->silence_threshold;
- AUDIO_LOG_DEBUG("_pcm_get_params (handle 0x%x, format %d, rate %d, channels %d, period_size %d, periods %d, buffer_size %d)", pcm_handle, config->format, config->rate, config->channels, config->period_size, config->period_count, _buffer_size);
+ AUDIO_LOG_DEBUG("_pcm_get_params (handle %p, format %d, rate %u, channels %u, period_size %u, periods %u, buffer_size %u)",
+ pcm_handle, config->format, config->rate, config->channels, config->period_size, config->period_count, _buffer_size);
#else /* alsa-lib */
int err;
audio_pcm_sample_spec_t *ss;
(err = snd_pcm_hw_params_get_format(hwparams, &_format)) < 0 ||
(err = snd_pcm_hw_params_get_rate(hwparams, &_rate, &dir)) < 0 ||
(err = snd_pcm_hw_params_get_channels(hwparams, &_channels)) < 0) {
- AUDIO_LOG_ERROR("snd_pcm_hw_params_get_{period_size|buffer_size|periods|format|rate|channels}() failed : %s", err);
+ AUDIO_LOG_ERROR("snd_pcm_hw_params_get_{period_size|buffer_size|periods|format|rate|channels}() failed : %d", err);
return AUDIO_ERR_PARAMETER;
}
(err = snd_pcm_sw_params_get_stop_threshold(swparams, &_stop_threshold)) < 0 ||
(err = snd_pcm_sw_params_get_silence_threshold(swparams, &_silence_threshold)) < 0 ||
(err = snd_pcm_sw_params_get_avail_min(swparams, &_avail_min)) < 0) {
- AUDIO_LOG_ERROR("snd_pcm_sw_params_get_{start_threshold|stop_threshold|silence_threshold|avail_min}() failed : %s", err);
+ AUDIO_LOG_ERROR("snd_pcm_sw_params_get_{start_threshold|stop_threshold|silence_threshold|avail_min}() failed : %d", err);
}
- AUDIO_LOG_DEBUG("_pcm_get_params (handle 0x%x, format %d, rate %d, channels %d, period_size %d, periods %d, buffer_size %d)", pcm_handle, _format, _rate, _channels, _period_size, _periods, _buffer_size);
+ AUDIO_LOG_DEBUG("_pcm_get_params (handle %p, format %d, rate %u, channels %u, period_size %lu, periods %u, buffer_size %lu)",
+ pcm_handle, _format, _rate, _channels, _period_size, _periods, _buffer_size);
#endif
return AUDIO_RET_OK;
_buffer_size = period_size * periods;
if ((err = snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, _buffer_size)) < 0) {
- AUDIO_LOG_ERROR("snd_pcm_hw_params_set_buffer_size(%u) failed : %d", periods * periods, err);
+ AUDIO_LOG_ERROR("snd_pcm_hw_params_set_buffer_size(%lu) failed : %d", _buffer_size, err);
return AUDIO_ERR_PARAMETER;
}
return AUDIO_ERR_IOCTL;
}
- AUDIO_LOG_DEBUG("_pcm_set_params (handle 0x%x, format %d, rate %d, channels %d, period_size %d, periods %d, buffer_size %d)", pcm_handle, ss.format, ss.rate, ss.channels, period_size, periods, _buffer_size);
+ AUDIO_LOG_DEBUG("_pcm_set_params (handle %p, format %d, rate %u, channels %u, period_size %u, periods %u, buffer_size %lu)",
+ pcm_handle, ss.format, ss.rate, ss.channels, period_size, periods, _buffer_size);
#endif
return AUDIO_RET_OK;