diff options
author | Niranjan Yadla <nyadla@cadence.com> | 2018-05-08 16:27:06 -0700 |
---|---|---|
committer | Dmitry Shmidt <dimitrysh@google.com> | 2018-05-15 11:16:45 -0700 |
commit | 672a34606145dc3d34ec8ee2f4853b9bddd293e3 (patch) | |
tree | a8430500e90cbdaebdbccb88ba8ffd19925bb703 /audio | |
parent | a13f816f0862ca67c7f363981f5ce0ed08f4c668 (diff) | |
download | hikey-672a34606145dc3d34ec8ee2f4853b9bddd293e3.tar.gz |
hikey960: Enable Audio DSP in Audio HAL
Enable XAF in Audio HAL if TARGET_ENABLE_DSP_DEVICE=true
is set in the build
Disable host side XAF logs
To see DSP logs push device/linaro/hifi/xaf/host-apf/tools/dhifimesg
to /system/bin
then run adb shell dhifimesg
Bug: 64395692
Test: Manual
Change-Id: Iff35ac78deb39c1801a5318074eb0fed28506937
Signed-off-by: Niranjan Yadla <nyadla@cadence.com>
Diffstat (limited to 'audio')
-rw-r--r-- | audio/Android.mk | 11 | ||||
-rw-r--r-- | audio/audio_hw.c | 199 |
2 files changed, 205 insertions, 5 deletions
diff --git a/audio/Android.mk b/audio/Android.mk index fe091a84..c1ba5640 100644 --- a/audio/Android.mk +++ b/audio/Android.mk @@ -33,5 +33,16 @@ LOCAL_C_INCLUDES += \ system/media/audio_utils/include \ system/media/audio_effects/include +ifeq ($(TARGET_ENABLE_DSP_DEVICE), true) +LOCAL_CFLAGS += -DENABLE_XAF_DSP_DEVICE +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../hifi/xaf/host-apf/include \ + $(LOCAL_PATH)/../hifi/xaf/host-apf/include/os/android \ + $(LOCAL_PATH)/../hifi/xaf/host-apf/include/sys/fio\ + $(LOCAL_PATH)/../hifi/xaf/host-apf/include/audio \ + $(LOCAL_PATH)/../hifi/xaf/host-apf/utest/include + +LOCAL_STATIC_LIBRARIES := libxtensa_proxy +endif include $(BUILD_SHARED_LIBRARY) diff --git a/audio/audio_hw.c b/audio/audio_hw.c index 7b66a1a3..ceeea8c9 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -59,6 +59,33 @@ #define CHANNEL_STEREO 2 #define MIN_WRITE_SLEEP_US 5000 +#ifdef ENABLE_XAF_DSP_DEVICE +#include "xaf-utils-test.h" +#include "audio/xa_vorbis_dec_api.h" +#include "audio/xa-audio-decoder-api.h" +#define NUM_COMP_IN_GRAPH 1 + +struct alsa_audio_device; + +struct xaf_dsp_device { + void *p_adev; + void *p_decoder; + xaf_info_t comp_info; + /* ...playback format */ + xaf_format_t pb_format; + xaf_comp_status dec_status; + int dec_info[4]; + void *dec_inbuf[2]; + int read_length; + xf_id_t dec_id; + int xaf_started; + mem_obj_t* mem_handle; + int num_comp; + int (*dec_setup)(void *p_comp, struct alsa_audio_device *audio_device); + int xafinitdone; +}; +#endif + struct stub_stream_in { struct audio_stream_in stream; }; @@ -71,6 +98,10 @@ struct alsa_audio_device { struct alsa_stream_in *active_input; struct alsa_stream_out *active_output; bool mic_mute; +#ifdef ENABLE_XAF_DSP_DEVICE + struct xaf_dsp_device dsp_device; + int hifi_dsp_fd; +#endif }; struct alsa_stream_out { @@ -86,6 +117,134 @@ struct alsa_stream_out { unsigned int written; }; +#ifdef ENABLE_XAF_DSP_DEVICE +static int pcm_setup(void *p_pcm, struct alsa_audio_device *audio_device) +{ + int param[6]; + + param[0] = XA_CODEC_CONFIG_PARAM_SAMPLE_RATE; + param[1] = audio_device->dsp_device.pb_format.sample_rate; + param[2] = XA_CODEC_CONFIG_PARAM_CHANNELS; + param[3] = audio_device->dsp_device.pb_format.channels; + param[4] = XA_CODEC_CONFIG_PARAM_PCM_WIDTH; + param[5] = audio_device->dsp_device.pb_format.pcm_width; + + XF_CHK_API(xaf_comp_set_config(p_pcm, 3, ¶m[0])); + + return 0; +} + +void xa_thread_exit_handler(int sig) +{ + /* ...unused arg */ + (void) sig; + + pthread_exit(0); +} + +/*xtensa audio device init*/ +static int xa_device_init(struct alsa_audio_device *audio_device) +{ + /* ...initialize playback format */ + audio_device->dsp_device.p_adev = NULL; + audio_device->dsp_device.pb_format.sample_rate = 48000; + audio_device->dsp_device.pb_format.channels = 2; + audio_device->dsp_device.pb_format.pcm_width = 16; + audio_device->dsp_device.xafinitdone = 0; + audio_frmwk_buf_size = 0; //unused + audio_comp_buf_size = 0; //unused + audio_device->dsp_device.num_comp = NUM_COMP_IN_GRAPH; + struct sigaction actions; + memset(&actions, 0, sizeof(actions)); + sigemptyset(&actions.sa_mask); + actions.sa_flags = 0; + actions.sa_handler = xa_thread_exit_handler; + sigaction(SIGUSR1,&actions,NULL); + /* ...initialize tracing facility */ + audio_device->dsp_device.xaf_started =1; + audio_device->dsp_device.dec_id = "audio-decoder/pcm"; + audio_device->dsp_device.dec_setup = pcm_setup; + audio_device->dsp_device.mem_handle = mem_init(); //initialize memory handler + XF_CHK_API(xaf_adev_open(&audio_device->dsp_device.p_adev, audio_frmwk_buf_size, audio_comp_buf_size, mem_malloc, mem_free)); + /* ...create decoder component */ + XF_CHK_API(xaf_comp_create(audio_device->dsp_device.p_adev, &audio_device->dsp_device.p_decoder, audio_device->dsp_device.dec_id, 1, 1, &audio_device->dsp_device.dec_inbuf[0], XAF_DECODER)); + XF_CHK_API(audio_device->dsp_device.dec_setup(audio_device->dsp_device.p_decoder,audio_device)); + + /* ...start decoder component */ + XF_CHK_API(xaf_comp_process(audio_device->dsp_device.p_adev, audio_device->dsp_device.p_decoder, NULL, 0, XAF_START_FLAG)); + return 0; +} + +static int xa_device_run(struct audio_stream_out *stream, const void *buffer, size_t frame_size, size_t out_frames, size_t bytes) +{ + struct alsa_stream_out *out = (struct alsa_stream_out *)stream; + struct alsa_audio_device *adev = out->dev; + int ret=0; + void *p_comp=adev->dsp_device.p_decoder; + xaf_comp_status comp_status; + memcpy(adev->dsp_device.dec_inbuf[0],buffer,bytes); + adev->dsp_device.read_length=bytes; + + if (adev->dsp_device.xafinitdone == 0) { + XF_CHK_API(xaf_comp_process(adev->dsp_device.p_adev, adev->dsp_device.p_decoder, adev->dsp_device.dec_inbuf[0], adev->dsp_device.read_length, XAF_INPUT_READY_FLAG)); + XF_CHK_API(xaf_comp_get_status(adev->dsp_device.p_adev, adev->dsp_device.p_decoder, &adev->dsp_device.dec_status, &adev->dsp_device.comp_info)); + ALOGE("PROXY:%s xaf_comp_get_status %d\n",__func__,adev->dsp_device.dec_status); + if (adev->dsp_device.dec_status == XAF_INIT_DONE) { + adev->dsp_device.xafinitdone = 1; + out->written += out_frames; + XF_CHK_API(xaf_comp_process(NULL, p_comp, NULL, 0, XAF_EXEC_FLAG)); + } + } else { + XF_CHK_API(xaf_comp_process(NULL, adev->dsp_device.p_decoder, adev->dsp_device.dec_inbuf[0], adev->dsp_device.read_length, XAF_INPUT_READY_FLAG)); + while (1) { + XF_CHK_API(xaf_comp_get_status(NULL, p_comp, &comp_status, &adev->dsp_device.comp_info)); + if (comp_status == XAF_EXEC_DONE) break; + if (comp_status == XAF_NEED_INPUT) { + ALOGV("PROXY:%s loop:XAF_NEED_INPUT\n",__func__); + break; + } + if (comp_status == XAF_OUTPUT_READY) { + void *p_buf = (void *)adev->dsp_device.comp_info.buf; + int size = adev->dsp_device.comp_info.length; + ret = pcm_mmap_write(out->pcm, p_buf, size); + if (ret == 0) { + out->written += out_frames; + } + XF_CHK_API(xaf_comp_process(NULL, adev->dsp_device.p_decoder, (void *)adev->dsp_device.comp_info.buf, adev->dsp_device.comp_info.length, XAF_NEED_OUTPUT_FLAG)); + } + } + } + return ret; +} + +static int xa_device_close(struct alsa_audio_device *audio_device) +{ + if (audio_device->dsp_device.xaf_started) { + xaf_comp_status comp_status; + audio_device->dsp_device.xaf_started=0; + while (1) { + XF_CHK_API(xaf_comp_get_status(NULL, audio_device->dsp_device.p_decoder, &comp_status, &audio_device->dsp_device.comp_info)); + ALOGV("PROXY:comp_status:%d,audio_device->dsp_device.comp_info.length:%d\n",(int)comp_status,audio_device->dsp_device.comp_info.length); + if (comp_status == XAF_EXEC_DONE) + break; + if (comp_status == XAF_NEED_INPUT) { + XF_CHK_API(xaf_comp_process(NULL, audio_device->dsp_device.p_decoder, NULL, 0, XAF_INPUT_OVER_FLAG)); + } + + if (comp_status == XAF_OUTPUT_READY) { + XF_CHK_API(xaf_comp_process(NULL, audio_device->dsp_device.p_decoder, (void *)audio_device->dsp_device.comp_info.buf, audio_device->dsp_device.comp_info.length, XAF_NEED_OUTPUT_FLAG)); + } + } + + /* ...exec done, clean-up */ + XF_CHK_API(xaf_comp_delete(audio_device->dsp_device.p_decoder)); + XF_CHK_API(xaf_adev_close(audio_device->dsp_device.p_adev, 0 /*unused*/)); + mem_exit(); + XF_CHK_API(print_mem_mcps_info(audio_device->dsp_device.mem_handle, audio_device->dsp_device.num_comp)); + } + return 0; +} +#endif /* must be called with hw device and output stream mutexes locked */ static int start_output_stream(struct alsa_stream_out *out) @@ -180,6 +339,9 @@ static int out_standby(struct audio_stream *stream) pthread_mutex_lock(&out->dev->lock); pthread_mutex_lock(&out->lock); +#ifdef ENABLE_XAF_DSP_DEVICE + xa_device_close(out->dev); +#endif status = do_output_standby(out); pthread_mutex_unlock(&out->lock); pthread_mutex_unlock(&out->dev->lock); @@ -256,6 +418,11 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, pthread_mutex_lock(&adev->lock); pthread_mutex_lock(&out->lock); if (out->standby) { +#ifdef ENABLE_XAF_DSP_DEVICE + if (adev->hifi_dsp_fd >= 0) { + xa_device_init(adev); + } +#endif ret = start_output_stream(out); if (ret != 0) { pthread_mutex_unlock(&adev->lock); @@ -266,11 +433,19 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, pthread_mutex_unlock(&adev->lock); - - ret = pcm_mmap_write(out->pcm, buffer, out_frames * frame_size); - if (ret == 0) { - out->written += out_frames; +#ifdef ENABLE_XAF_DSP_DEVICE + /*fallback to original audio processing*/ + if (adev->dsp_device.p_adev != NULL) { + ret = xa_device_run(stream, buffer,frame_size, out_frames, bytes); + } else { +#endif + ret = pcm_mmap_write(out->pcm, buffer, out_frames * frame_size); + if (ret == 0) { + out->written += out_frames; + } +#ifdef ENABLE_XAF_DSP_DEVICE } +#endif exit: pthread_mutex_unlock(&out->lock); @@ -628,7 +803,14 @@ static int adev_dump(const audio_hw_device_t *device, int fd) static int adev_close(hw_device_t *device) { +#ifdef ENABLE_XAF_DSP_DEVICE + struct alsa_audio_device *adev = (struct alsa_audio_device *)device; +#endif ALOGV("adev_close"); +#ifdef ENABLE_XAF_DSP_DEVICE + if (adev->hifi_dsp_fd >= 0) + close(adev->hifi_dsp_fd); +#endif free(device); return 0; } @@ -672,7 +854,14 @@ static int adev_open(const hw_module_t* module, const char* name, adev->devices = AUDIO_DEVICE_NONE; *device = &adev->hw_device.common; - +#ifdef ENABLE_XAF_DSP_DEVICE + adev->hifi_dsp_fd = open(HIFI_DSP_MISC_DRIVER, O_WRONLY, 0); + if (adev->hifi_dsp_fd < 0) { + ALOGW("hifi_dsp: Error opening device %d", errno); + } else { + ALOGI("hifi_dsp: Open device"); + } +#endif return 0; } |