summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimJeongYeon <jeongyeon.kim@samsung.com>2015-10-13 13:44:57 +0900
committerKimJeongYeon <jeongyeon.kim@samsung.com>2015-10-16 08:13:16 +0900
commitbb3ac0f23cf4c5f767e90a793b64e9a89d3213ae (patch)
tree848445abda8e53c0773f72defde972651caf094c
parentb842c760e228a8dfbbebd7ae569a054461e50c47 (diff)
downloadaudio-hal-max98090-bb3ac0f23cf4c5f767e90a793b64e9a89d3213ae.tar.gz
audio-hal-max98090-bb3ac0f23cf4c5f767e90a793b64e9a89d3213ae.tar.bz2
audio-hal-max98090-bb3ac0f23cf4c5f767e90a793b64e9a89d3213ae.zip
[Version] 0.2.10 [Profile] Common [Issue Type] Features [Dependency module] NA [Dependency commit] NA [Comment] Signed-off-by: KimJeongYeon <jeongyeon.kim@samsung.com> Change-Id: Ia63619d6b38b1862c90380398159cc21c04a768a
-rw-r--r--Makefile.am5
-rw-r--r--configure.ac9
-rw-r--r--packaging/audio-hal-max98090.spec5
-rw-r--r--tizen-audio-device.c249
-rw-r--r--tizen-audio-internal.h24
-rw-r--r--tizen-audio-util.c12
-rw-r--r--tizen-audio.h19
7 files changed, 292 insertions, 31 deletions
diff --git a/Makefile.am b/Makefile.am
index 7157918..1145f10 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,7 +6,12 @@ libtizen_audio_la_SOURCES = tizen-audio.c \
tizen-audio-ucm.c \
tizen-audio-util.c
libtizen_audio_la_LDFLAGS = $(AM_LDFLAGS) -disable-static -avoid-version
+if USE_TINYALSA
+libtizen_audio_la_LIBADD = $(AM_LDADD) $(ASOUNDLIB_LIBS) $(TINYALSA_LIBS) $(VCONF_LIBS) $(DLOG_LIBS) $(INIPARSER_LIBS)
+libtizen_audio_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) $(TINYALSA_CFLAGS) $(VCONF_CFLAGS) $(DLOG_CFLAGS) $(INIPARSER_CFLAGS) -D__USE_TINYALSA__
+else
libtizen_audio_la_LIBADD = $(AM_LDADD) $(ASOUNDLIB_LIBS) $(VCONF_LIBS) $(DLOG_LIBS) $(INIPARSER_LIBS)
libtizen_audio_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) $(VCONF_CFLAGS) $(DLOG_CFLAGS) $(INIPARSER_CFLAGS)
+endif
libtizen_audio_la_CFLAGS += -DUSE_DLOG
diff --git a/configure.ac b/configure.ac
index 52de403..af6a735 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,6 +26,15 @@ PKG_CHECK_MODULES(ASOUNDLIB, alsa >= 1.0.24)
AC_SUBST(ASOUNDLIB_CFLAGS)
AC_SUBST(ASOUNDLIB_LIBS)
+if test $USE_TINYALSA = "1"; then
+PKG_CHECK_MODULES(TINYALSA, tinyalsa)
+AC_SUBST(TINYALSA_CFLAGS)
+AC_SUBST(TINYALSA_LIBS)
+AM_CONDITIONAL(USE_TINYALSA, true)
+else
+AM_CONDITIONAL(USE_TINYALSA, false)
+fi
+
PKG_CHECK_MODULES(VCONF, vconf)
AC_SUBST(VCONF_CFLAGS)
AC_SUBST(VCONF_LIBS)
diff --git a/packaging/audio-hal-max98090.spec b/packaging/audio-hal-max98090.spec
index 85463be..dc90ac3 100644
--- a/packaging/audio-hal-max98090.spec
+++ b/packaging/audio-hal-max98090.spec
@@ -1,6 +1,6 @@
Name: audio-hal-max98090
Summary: TIZEN Audio HAL for MAX98090
-Version: 0.2.9
+Version: 0.2.10
Release: 0
Group: System/Libraries
License: Apache-2.0
@@ -10,6 +10,7 @@ BuildRequires: pkgconfig(vconf)
BuildRequires: pkgconfig(iniparser)
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(alsa)
+#BuildRequires: pkgconfig(tinyalsa)
Provides: libtizen-audio.so
%description
@@ -23,6 +24,8 @@ export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+export USE_TINYALSA="0"
+
%autogen
%configure
diff --git a/tizen-audio-device.c b/tizen-audio-device.c
index 2f39fc4..ced1d47 100644
--- a/tizen-audio-device.c
+++ b/tizen-audio-device.c
@@ -28,6 +28,8 @@
#include "tizen-audio-internal.h"
+/* #define DEBUG_TIMING */
+
static device_type_t outDeviceTypes[] = {
{ AUDIO_DEVICE_OUT_SPEAKER, "Speaker" },
{ AUDIO_DEVICE_OUT_JACK, "Headphones" },
@@ -341,19 +343,69 @@ audio_return_t audio_alsa_pcm_close (void *userdata, void *pcm_handle)
return audio_ret;
}
+#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)
+{
+ struct pcm *pcm = NULL;
+ struct pcm_config config;
+
+ config.channels = ss->channels;
+ config.rate = ss->rate;
+ config.period_size = period_size;
+ config.period_count = period_count;
+ config.format = ss->format;
+ config.start_threshold = 1024;
+ config.stop_threshold = 0xFFFFFFFF;
+ config.silence_threshold = 0;
+
+ AUDIO_LOG_INFO("channels %d, rate %d, format %d, period_size %d, period_count %d", ss->channels, ss->rate, ss->format, period_size, period_count);
+
+ 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);
+ if (!pcm || !pcm_is_ready(pcm)) {
+ AUDIO_LOG_ERROR("Unable to open device (%s)", pcm_get_error(pcm));
+ pcm_close(pcm);
+ return NULL;
+ }
+
+ return pcm;
+}
+#endif
+
audio_return_t audio_pcm_open (void *userdata, void **pcm_handle, void *sample_spec, uint32_t direction)
{
- audio_return_t audio_ret = AUDIO_RET_OK;
+#ifdef __USE_TINYALSA__
+ audio_mgr_t *am = (audio_mgr_t *)userdata;
+ audio_pcm_sample_spec_t *ss = (audio_pcm_sample_spec_t *)sample_spec;
+ size_t period_size, buffer_size;
+ ss->format = _convert_format((audio_sample_format_t)ss->format);
+ period_size = (direction == AUDIO_DIRECTION_OUT) ? PERIODSZ_PLAYBACK : PERIODSZ_CAPTURE;
+ buffer_size = (direction == AUDIO_DIRECTION_OUT) ? BUFFERSZ_PLAYBACK : BUFFERSZ_CAPTURE;
+
+ AUDIO_RETURN_VAL_IF_FAIL(am, AUDIO_ERR_PARAMETER);
+
+ *pcm_handle = __tinyalsa_open_device(ss, period_size, (buffer_size / period_size), direction);
+ if (*pcm_handle == NULL) {
+ AUDIO_LOG_ERROR("Error opening PCM device");
+ return AUDIO_ERR_RESOURCE;
+ }
+
+ am->device.pcm_count++;
+ AUDIO_LOG_INFO("Opening PCM handle 0x%x", *pcm_handle);
+#else /* alsa-lib */
char *device_name = NULL;
audio_mgr_t *am = (audio_mgr_t *)userdata;
audio_pcm_sample_spec_t *ss = (audio_pcm_sample_spec_t *)sample_spec;
int err, mode;
- uint8_t use_mmap=0;
- snd_pcm_uframes_t period_size = PERIODSZ_PLAYBACK;
- snd_pcm_uframes_t buffer_size = BUFFERSZ_PLAYBACK;
+ uint8_t use_mmap = 0;
+ snd_pcm_uframes_t period_size, buffer_size;
snd_pcm_uframes_t avail_min = 1024;
ss->format = _convert_format((audio_sample_format_t)ss->format);
mode = SND_PCM_NONBLOCK | SND_PCM_NO_AUTO_RESAMPLE | SND_PCM_NO_AUTO_CHANNELS | SND_PCM_NO_AUTO_FORMAT;
+ period_size = (direction == AUDIO_DIRECTION_OUT) ? PERIODSZ_PLAYBACK : PERIODSZ_CAPTURE;
+ buffer_size = (direction == AUDIO_DIRECTION_OUT) ? BUFFERSZ_PLAYBACK : BUFFERSZ_CAPTURE;
AUDIO_RETURN_VAL_IF_FAIL(am, AUDIO_ERR_PARAMETER);
if(direction == AUDIO_DIRECTION_OUT)
@@ -382,59 +434,212 @@ audio_return_t audio_pcm_open (void *userdata, void **pcm_handle, void *sample_s
AUDIO_LOG_ERROR("Failed to set pcm sw parameters: %s", snd_strerror(err));
return AUDIO_ERR_RESOURCE;
}
- return audio_ret;
+#endif
+
+ return AUDIO_RET_OK;
+}
+
+audio_return_t audio_pcm_start (void *userdata, void *pcm_handle)
+{
+ int err;
+
+#ifdef __USE_TINYALSA__
+ if ((err = pcm_start(pcm_handle)) < 0) {
+ AUDIO_LOG_ERROR("Error starting PCM handle : %d", err);
+ return AUDIO_ERR_RESOURCE;
+ }
+#else /* alsa-lib */
+ if ((err = snd_pcm_start(pcm_handle)) < 0) {
+ AUDIO_LOG_ERROR("Error starting PCM handle : %s", snd_strerror(err));
+ return AUDIO_ERR_RESOURCE;
+ }
+#endif
+
+ AUDIO_LOG_INFO("PCM handle 0x%x start", pcm_handle);
+ return AUDIO_RET_OK;
+}
+
+audio_return_t audio_pcm_stop (void *userdata, void *pcm_handle)
+{
+ int err;
+
+#ifdef __USE_TINYALSA__
+ if ((err = pcm_stop(pcm_handle)) < 0) {
+ AUDIO_LOG_ERROR("Error stopping PCM handle : %d", err);
+ return AUDIO_ERR_RESOURCE;
+ }
+#else /* alsa-lib */
+ if ((err = snd_pcm_drop(pcm_handle)) < 0) {
+ AUDIO_LOG_ERROR("Error stopping PCM handle : %s", snd_strerror(err));
+ return AUDIO_ERR_RESOURCE;
+ }
+#endif
+
+ AUDIO_LOG_INFO("PCM handle 0x%x stop", pcm_handle);
+ return AUDIO_RET_OK;
}
audio_return_t audio_pcm_close (void *userdata, void *pcm_handle)
{
- audio_return_t audio_ret = AUDIO_RET_OK;
audio_mgr_t *am = (audio_mgr_t *)userdata;
int err;
AUDIO_LOG_INFO("Try to close PCM handle 0x%x", pcm_handle);
+
+#ifdef __USE_TINYALSA__
+ if ((err = pcm_close(pcm_handle)) < 0) {
+ AUDIO_LOG_ERROR("Error closing PCM handle : %d", err);
+ return AUDIO_ERR_RESOURCE;
+ }
+#else /* alsa-lib */
if ((err = snd_pcm_close(pcm_handle)) < 0) {
AUDIO_LOG_ERROR("Error closing PCM handle : %s", snd_strerror(err));
pthread_mutex_unlock(&am->device.pcm_lock);
return AUDIO_ERR_RESOURCE;
}
+#endif
+
+ pcm_handle = NULL;
am->device.pcm_count--;
AUDIO_LOG_INFO("PCM handle close success (count:%d)", am->device.pcm_count);
- return audio_ret;
+ return AUDIO_RET_OK;
}
-audio_return_t audio_pcm_avail(void *pcm_handle)
+audio_return_t audio_pcm_avail (void *userdata, void *pcm_handle, uint32_t *avail)
{
- snd_pcm_sframes_t n;
- snd_pcm_sframes_t ret;
+#ifdef __USE_TINYALSA__
+ struct timespec tspec;
+ unsigned int frames_avail = 0;
+ int err;
AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER);
- while(1) {
- n = snd_pcm_avail(pcm_handle);
+ while (1) {
+ err = pcm_get_htimestamp(pcm_handle, &frames_avail, &tspec);
+ if (err < 0) {
+ AUDIO_LOG_ERROR("Could not get avail and timespec");
+ return AUDIO_ERR_IOCTL;
+ }
- if (n <= 0) {
- ret = snd_pcm_wait(pcm_handle, 10);
- if(ret == 0){
- AUDIO_LOG_DEBUG("snd_pcm_wait = %d\n", ret);
+ if (frames_avail <= 0) {
+ err = pcm_wait(pcm_handle, 10);
+ if (err == 0) {
+#ifdef DEBUG_TIMING
+ AUDIO_LOG_DEBUG("pcm_wait = %d", err);
+#endif
continue;
+ } else {
+ break;
}
- else
+ } else {
+#ifdef DEBUG_TIMING
+ AUDIO_LOG_DEBUG("avail = %d", frames_avail);
+#endif
+ break;
+ }
+ }
+
+ *avail = (uint32_t)frames_avail;
+#else /* alsa-lib */
+ snd_pcm_sframes_t frames_avail;
+ snd_pcm_sframes_t err;
+
+ AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER);
+
+ while (1) {
+ frames_avail = snd_pcm_avail(pcm_handle);
+
+ if (frames_avail <= 0) {
+ err = snd_pcm_wait(pcm_handle, 10);
+ if (err == 0) {
+#ifdef DEBUG_TIMING
+ AUDIO_LOG_DEBUG("snd_pcm_wait = %d", err);
+#endif
+ continue;
+ } else {
break;
+ }
+ } else {
+#ifdef DEBUG_TIMING
+ AUDIO_LOG_DEBUG("snd_pcm_avail = %d", frames_avail);
+#endif
+ break;
}
- break;
}
- return 0;
+
+ *avail = (uint32_t)frames_avail;
+#endif
+
+ return AUDIO_RET_OK;
}
-audio_return_t audio_pcm_write(void *pcm_handle, const void *buffer, uint32_t frames)
+
+audio_return_t audio_pcm_write (void *userdata, void *pcm_handle, const void *buffer, uint32_t frames)
{
+#ifdef __USE_TINYALSA__
+ int err;
+
+ AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER);
+
+ err = pcm_write(pcm_handle, buffer, pcm_frames_to_bytes(pcm_handle, (unsigned int)frames));
+ if (err < 0) {
+ AUDIO_LOG_ERROR("Failed to write pcm : %d", err);
+ return AUDIO_ERR_IOCTL;
+ }
+
+#ifdef DEBUG_TIMING
+ AUDIO_LOG_DEBUG("audio_pcm_write = %d", frames);
+#endif
+#else /* alsa-lib */
snd_pcm_sframes_t frames_written;
AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER);
frames_written = snd_pcm_writei(pcm_handle, buffer, (snd_pcm_uframes_t) frames);
if (frames_written < 0) {
- AUDIO_LOG_ERROR("Failed to pcm write: try_recover!!!!");
+ AUDIO_LOG_ERROR("Failed to write pcm : %d", frames_written);
+ return AUDIO_ERR_IOCTL;
}
- return 0;
+
+#ifdef DEBUG_TIMING
+ AUDIO_LOG_DEBUG("audio_pcm_write = (%d / %d)", frames_written, frames);
+#endif
+#endif
+
+ return AUDIO_RET_OK;
+}
+
+audio_return_t audio_pcm_read (void *userdata, void *pcm_handle, void *buffer, uint32_t frames)
+{
+#ifdef __USE_TINYALSA__
+ int err;
+
+ AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER);
+
+ err = pcm_read(pcm_handle, buffer, pcm_frames_to_bytes(pcm_handle, (unsigned int)frames));
+ if (err < 0) {
+ AUDIO_LOG_ERROR("Failed to read pcm : %d", err);
+ return AUDIO_ERR_IOCTL;
+ }
+
+#ifdef DEBUG_TIMING
+ AUDIO_LOG_DEBUG("audio_pcm_read = %d", frames);
+#endif
+#else /* alsa-lib */
+ snd_pcm_sframes_t frames_read;
+
+ AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER);
+
+ 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);
+ return AUDIO_ERR_IOCTL;
+ }
+
+#ifdef DEBUG_TIMING
+ AUDIO_LOG_DEBUG("audio_pcm_read = (%d / %d)", frames_read, frames);
+#endif
+#endif
+
+ return AUDIO_RET_OK;
}
diff --git a/tizen-audio-internal.h b/tizen-audio-internal.h
index fd76bd7..9563fe1 100644
--- a/tizen-audio-internal.h
+++ b/tizen-audio-internal.h
@@ -24,6 +24,9 @@
#include <time.h>
#include <sys/types.h>
#include <asoundlib.h>
+#ifdef __USE_TINYALSA__
+#include <tinyalsa/asoundlib.h>
+#endif
#include <pthread.h>
#include <use-case.h>
#include "tizen-audio.h"
@@ -116,8 +119,25 @@ typedef struct device_type {
#define PLAYBACK_PCM_DEVICE "hw:0,0"
#define CAPTURE_PCM_DEVICE "hw:0,0"
-#define PERIODSZ_PLAYBACK 2048
-#define BUFFERSZ_PLAYBACK 4096
+/* hw:0,0 */
+#define PLAYBACK_CARD_ID 0
+#define PLAYBACK_PCM_DEVICE_ID 0
+#define PLAYBACK_PCM_DEVICE_CHANNELS 2
+#define PLAYBACK_PCM_DEVICE_RATE 48000
+#define PLAYBACK_PCM_DEVICE_FORMAT AUDIO_SAMPLE_S16LE
+
+#define PERIODSZ_PLAYBACK 1920
+#define BUFFERSZ_PLAYBACK 3840
+
+/* hw:0,0 */
+#define CAPTURE_CARD_ID 0
+#define CAPTURE_PCM_DEVICE_ID 0
+#define CAPTURE_PCM_DEVICE_CHANNELS 2
+#define CAPTURE_PCM_DEVICE_RATE 48000
+#define CAPTURE_PCM_DEVICE_FORMAT AUDIO_SAMPLE_S16LE
+
+#define PERIODSZ_CAPTURE 1920
+#define BUFFERSZ_CAPTURE 3840
#define MAX_DEVICES 5
#define MAX_MODIFIERS 5
diff --git a/tizen-audio-util.c b/tizen-audio-util.c
index 181746d..83785c0 100644
--- a/tizen-audio-util.c
+++ b/tizen-audio-util.c
@@ -244,6 +244,15 @@ audio_return_t _audio_mixer_control_get_element(audio_mgr_t *am, const char *ctl
return AUDIO_RET_OK;
}
+#ifdef __USE_TINYALSA__
+/* Convert pcm format from pulse to alsa */
+static const uint32_t g_format_convert_table[] = {
+ [AUDIO_SAMPLE_U8] = PCM_FORMAT_S8,
+ [AUDIO_SAMPLE_S16LE] = PCM_FORMAT_S16_LE,
+ [AUDIO_SAMPLE_S32LE] = PCM_FORMAT_S32_LE,
+ [AUDIO_SAMPLE_S24_32LE] = PCM_FORMAT_S24_LE
+};
+#else /* alsa-lib */
/* Convert pcm format from pulse to alsa */
static const uint32_t g_format_convert_table[] = {
[AUDIO_SAMPLE_U8] = SND_PCM_FORMAT_U8,
@@ -260,6 +269,7 @@ static const uint32_t g_format_convert_table[] = {
[AUDIO_SAMPLE_S24_32LE] = SND_PCM_FORMAT_S24_LE,
[AUDIO_SAMPLE_S24_32BE] = SND_PCM_FORMAT_S24_BE
};
+#endif
uint32_t _convert_format(audio_sample_format_t format)
{
@@ -399,7 +409,7 @@ audio_return_t _audio_pcm_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_
AUDIO_LOG_WARN("Unable to set stop threshold: %s\n", snd_strerror(err));
goto error;
}
- if ((err = snd_pcm_sw_params_set_start_threshold(pcm, swparams, (snd_pcm_uframes_t) -1)) < 0) {
+ if ((err = snd_pcm_sw_params_set_start_threshold(pcm, swparams, (snd_pcm_uframes_t) avail_min)) < 0) {
AUDIO_LOG_WARN("Unable to set start threshold: %s\n", snd_strerror(err));
goto error;
}
diff --git a/tizen-audio.h b/tizen-audio.h
index d838c82..1e25b15 100644
--- a/tizen-audio.h
+++ b/tizen-audio.h
@@ -220,10 +220,16 @@ typedef struct audio_interface {
audio_return_t (*update_stream_connection_info) (void *userdata, audio_stream_info_t *info, uint32_t is_connected);
audio_return_t (*alsa_pcm_open)(void *userdata, void **pcm_handle, char *device_name, uint32_t direction, int mode);
audio_return_t (*alsa_pcm_close)(void *userdata, void *pcm_handle);
+
+ /* Interface of PCM device */
audio_return_t (*pcm_open)(void *userdata, void **pcm_handle, void *sample_spec, uint32_t direction);
+ audio_return_t (*pcm_start)(void *userdata, void *pcm_handle);
+ audio_return_t (*pcm_stop)(void *userdata, void *pcm_handle);
audio_return_t (*pcm_close)(void *userdata, void *pcm_handle);
- audio_return_t (*pcm_avail)(void *pcm_handle);
- audio_return_t (*pcm_write)(void *pcm_handle, const void *buffer, uint32_t frames);
+ audio_return_t (*pcm_avail)(void *userdata, void *pcm_handle, uint32_t *avail);
+ audio_return_t (*pcm_write)(void *userdata, void *pcm_handle, const void *buffer, uint32_t frames);
+ audio_return_t (*pcm_read)(void *userdata, void *pcm_handle, void *buffer, uint32_t frames);
+
audio_return_t (*get_buffer_attr)(void *userdata, uint32_t direction, const char *latency, uint32_t samplerate, audio_sample_format_t format, uint32_t channels, uint32_t *maxlength, uint32_t *tlength, uint32_t *prebuf, uint32_t* minreq, uint32_t *fragsize);
audio_return_t (*set_callback)(void *userdata, audio_cb_interface_t *cb_interface);
} audio_interface_t;
@@ -243,10 +249,13 @@ audio_return_t audio_update_route_option (void *userdata, audio_route_option_t *
audio_return_t audio_update_stream_connection_info (void *userdata, audio_stream_info_t *info, uint32_t is_connected);
audio_return_t audio_alsa_pcm_open (void *userdata, void **pcm_handle, char *device_name, uint32_t direction, int mode);
audio_return_t audio_alsa_pcm_close (void *userdata, void *pcm_handle);
-audio_return_t audio_pcm_open(void *userdata, void **pcm_handle, void *sample_spec, uint32_t direction);
+audio_return_t audio_pcm_open (void *userdata, void **pcm_handle, void *sample_spec, uint32_t direction);
+audio_return_t audio_pcm_start (void *userdata, void *pcm_handle);
+audio_return_t audio_pcm_stop (void *userdata, void *pcm_handle);
audio_return_t audio_pcm_close (void *userdata, void *pcm_handle);
-audio_return_t audio_pcm_avail(void *pcm_handle);
-audio_return_t audio_pcm_write(void *pcm_handle, const void *buffer, uint32_t frames);
+audio_return_t audio_pcm_avail (void *userdata, void *pcm_handle, uint32_t *avail);
+audio_return_t audio_pcm_write (void *userdata, void *pcm_handle, const void *buffer, uint32_t frames);
+audio_return_t audio_pcm_read (void *userdata, void *pcm_handle, void *buffer, uint32_t frames);
audio_return_t audio_get_buffer_attr(void *userdata, uint32_t direction, const char *latency, uint32_t samplerate, audio_sample_format_t format, uint32_t channels, uint32_t *maxlength, uint32_t *tlength, uint32_t *prebuf, uint32_t* minreq, uint32_t *fragsize);
audio_return_t audio_set_callback (void *userdata, audio_cb_interface_t *cb_interface);
#endif