diff options
author | KimJeongYeon <jeongyeon.kim@samsung.com> | 2015-10-13 13:44:57 +0900 |
---|---|---|
committer | KimJeongYeon <jeongyeon.kim@samsung.com> | 2015-10-16 08:13:16 +0900 |
commit | bb3ac0f23cf4c5f767e90a793b64e9a89d3213ae (patch) | |
tree | 848445abda8e53c0773f72defde972651caf094c | |
parent | b842c760e228a8dfbbebd7ae569a054461e50c47 (diff) | |
download | audio-hal-max98090-bb3ac0f23cf4c5f767e90a793b64e9a89d3213ae.tar.gz audio-hal-max98090-bb3ac0f23cf4c5f767e90a793b64e9a89d3213ae.tar.bz2 audio-hal-max98090-bb3ac0f23cf4c5f767e90a793b64e9a89d3213ae.zip |
audio-hal-max98090: tizenaudio reference sink / sourcesubmit/tizen/20151020.122114submit/tizen/20151016.064158submit/tizen/20151016.062938accepted/tizen/wearable/20151021.013128accepted/tizen/tv/20151021.013105accepted/tizen/mobile/20151021.013057
[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.am | 5 | ||||
-rw-r--r-- | configure.ac | 9 | ||||
-rw-r--r-- | packaging/audio-hal-max98090.spec | 5 | ||||
-rw-r--r-- | tizen-audio-device.c | 249 | ||||
-rw-r--r-- | tizen-audio-internal.h | 24 | ||||
-rw-r--r-- | tizen-audio-util.c | 12 | ||||
-rw-r--r-- | tizen-audio.h | 19 |
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 |