From 51cb5136ec88ba956bfa9c7a225ad80291c1e3a3 Mon Sep 17 00:00:00 2001 From: Che Song Date: Fri, 07 Apr 2017 06:49:04 +0000 Subject: PD#141914: add a new audio effect Virtualizer in hal Change-Id: I44e604b5354e38df6bf9dbe59315ad1faea24b28 --- diff --git a/Android.mk b/Android.mk index 12cd68c..64ab04d 100644 --- a/Android.mk +++ b/Android.mk @@ -28,6 +28,7 @@ ifeq ($(strip $(BOARD_ALSA_AUDIO)),tiny) LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_SRC_FILES := \ audio_hw.c \ + audio_virtual_effect.c \ libTVaudio/audio/audio_effect_control.c \ audio_hw_utils.c \ audio_hwsync.c \ @@ -38,8 +39,14 @@ ifeq ($(strip $(BOARD_ALSA_AUDIO)),tiny) system/media/audio_utils/include \ system/media/audio_effects/include \ system/media/audio_route/include \ + frameworks/av/media/libeffects/lvm/lib/StereoWidening/lib \ + frameworks/av/media/libeffects/lvm/lib/StereoWidening/src \ + frameworks/av/media/libeffects/lvm/lib/Common/lib \ + frameworks/av/media/libeffects/lvm/lib/Common/src \ libTVaudio/audio + LOCAL_STATIC_LIBRARIES += libmusicbundle + LOCAL_SHARED_LIBRARIES := \ liblog libcutils libtinyalsa \ libaudioutils libdl libaudioroute libutils \ diff --git a/audio_hw.c b/audio_hw.c index 8a8152c..338a492 100644 --- a/audio_hw.c +++ b/audio_hw.c @@ -1103,6 +1103,22 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) srs_truebass_enable(SRS_switch[2]); goto exit; } + char tmp2[3]; + int Virtualizer_parm[2] = {0, 0}; + ret = str_parms_get_str(parms, "AML_VIRTUALIZER", value, sizeof(value)); + if (ret >= 0) { + for (i; i < 2; i++) { + tmp2[0] = value[3*i]; + tmp2[1] = value[3*i + 1]; + tmp2[2] = value[3*i + 2]; + Virtualizer_parm[i] = atoi(tmp2); + } + ALOGI("audio effect Virtualizer enable: %d, strength: %d\n", + Virtualizer_parm[0], Virtualizer_parm[1]); + ret = 0; + Virtualizer_control(Virtualizer_parm[0], Virtualizer_parm[1]); + goto exit; + } ret = str_parms_get_str(parms, "hw_av_sync", value, sizeof(value)); if (ret >= 0) { int hw_sync_id = atoi(value); @@ -1309,6 +1325,9 @@ static int audio_effect_process(struct audio_stream_out *stream, if (out->has_SRS_lib) { output_size = srs_process(buffer, buffer, frame_size); } + if (out->has_Virtualizer) { + Virtualizer_process(buffer, buffer, frame_size); + } if (out->has_EQ_lib) { HPEQ_process(buffer, buffer, frame_size); } @@ -3355,6 +3374,14 @@ static int adev_open_output_stream(struct audio_hw_device *dev, aml_IIR_init(paramter); out->has_aml_IIR_lib = 1; } + + ret = Virtualizer_init(); + if (ret == 0) { + out->has_Virtualizer = 1; + } else { + ALOGE("%s, init Virtualizer fail!\n", __FUNCTION__); + out->has_Virtualizer = 0; + } } return 0; @@ -3374,6 +3401,7 @@ static void adev_close_output_stream(struct audio_hw_device *dev, if (out->is_tv_platform == 1) { free(out->tmp_buffer_8ch); free(out->audioeffect_tmp_buffer); + Virtualizer_release(); } hwsync_lpcm = (out->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC && out->config.rate <= 48000 && audio_is_linear_pcm(out->hal_format)); diff --git a/audio_hw.h b/audio_hw.h index 6bd599c..2044270 100644 --- a/audio_hw.h +++ b/audio_hw.h @@ -119,6 +119,7 @@ struct aml_stream_out { unsigned char pause_status; bool hw_sync_mode; int has_aml_IIR_lib; + int has_Virtualizer; float volume_l; float volume_r; int last_codec_type; diff --git a/audio_virtual_effect.c b/audio_virtual_effect.c new file mode 100644 index 0000000..5b97716 --- a/dev/null +++ b/audio_virtual_effect.c @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "audio_virtual_effect" + +#include +#include +#include + +#include "LVCS.h" +#include "InstAlloc.h" +#include "LVCS_Private.h" + +#include "audio_virtual_effect.h" + +LVCS_Handle_t hCSInstance = LVM_NULL; /* Concert Sound instance handle */ +LVCS_Instance_t CS_Instance; /* Concert Soun= d instance */ + +LVCS_MemTab_t CS_MemTab; /* Memory table */ +LVCS_Capabilities_t CS_Capabilities; /* Initial capabilities */ + +static pthread_mutex_t audio_vir_mutex = PTHREAD_MUTEX_INITIALIZER; + +int Virtualizer_init(void) { + LVCS_ReturnStatus_en LVCS_Status; + LVCS_Params_t *CS_Params = &CS_Instance.Params; + int i = 0; + + pthread_mutex_lock(&audio_vir_mutex); + + CS_Capabilities.MaxBlockSize = 2048; + CS_Capabilities.pBundleInstance = (void*)hCSInstance; + + LVCS_Status = LVCS_Memory(LVM_NULL, + &CS_MemTab, + &CS_Capabilities); + + CS_MemTab.Region[LVCS_MEMREGION_PERSISTENT_SLOW_DATA].pBaseAddress = &CS_Instance; + + /* Allocate memory */ + for (i = 0; i < LVM_NR_MEMORY_REGIONS; i++) { + if (CS_MemTab.Region[i].Size != 0) { + CS_MemTab.Region[i].pBaseAddress = malloc(CS_MemTab.Region[i].Size); + + if (CS_MemTab.Region[i].pBaseAddress == LVM_NULL) { + ALOGV("\tLVM_ERROR :LvmBundle_init CreateInstance Failed to allocate %" + " bytes for region %u\n", CS_MemTab.Region[i].Size, i ); + return LVCS_NULLADDRESS; + } else { + ALOGV("\tLvmBundle_init CreateInstance allocated %" + " bytes for region %u at %p\n", + CS_MemTab.Region[i].Size, i, CS_MemTab.Region[i].pBaseAddress); + } + } + } + + hCSInstance = LVM_NULL; + LVCS_Status = LVCS_Init(&hCSInstance, + &CS_MemTab, + &CS_Capabilities); + + CS_Params->OperatingMode = LVCS_OFF; + CS_Params->CompressorMode = LVM_MODE_ON; + CS_Params->SourceFormat = LVCS_STEREO; + CS_Params->SpeakerType = LVCS_HEADPHONES; + CS_Params->SampleRate = LVM_FS_48000; + CS_Params->ReverbLevel = 100; + CS_Params->EffectLevel = 0; /* 0~32767 */ + + pthread_mutex_unlock(&audio_vir_mutex); + return LVCS_Status; +} + +int Virtualizer_release(void) { + int i; + pthread_mutex_lock(&audio_vir_mutex); + for (i = 0; i < LVM_NR_MEMORY_REGIONS; i++) { + if (CS_MemTab.Region[i].pBaseAddress != 0) { + free(CS_MemTab.Region[i].pBaseAddress); + CS_MemTab.Region[i].pBaseAddress = NULL; + } + } + hCSInstance = LVM_NULL; + pthread_mutex_unlock(&audio_vir_mutex); + return 0; +} + +// enable: 1; disable:0, EffectLevel:0~100 +int Virtualizer_control(int enable, int EffectLevel) { + + LVCS_ReturnStatus_en CS_Status; + LVCS_Params_t *CS_Params = &CS_Instance.Params; + + if (hCSInstance == LVM_NULL) + return LVCS_NULLADDRESS; + + pthread_mutex_lock(&audio_vir_mutex); + if (enable == 1) + CS_Params->OperatingMode = LVCS_ON; + else + CS_Params->OperatingMode = LVCS_OFF; + + if (EffectLevel > 100) + CS_Params->EffectLevel = 32700; + else if (EffectLevel < 0) + CS_Params->EffectLevel = 0; + else + CS_Params->EffectLevel = EffectLevel * 327; + + CS_Status = LVCS_Control(hCSInstance, + CS_Params); + + pthread_mutex_unlock(&audio_vir_mutex); + return CS_Status; +} + +int Virtualizer_process(int16_t *pInData, int16_t *pOutData, uint16_t NumSamples) { + LVCS_ReturnStatus_en CS_Status; + + if (hCSInstance == LVM_NULL) + return LVCS_NULLADDRESS; + + pthread_mutex_lock(&audio_vir_mutex); + CS_Status = LVCS_Process(hCSInstance, + pInData, + pOutData, + NumSamples); + pthread_mutex_unlock(&audio_vir_mutex); + return CS_Status; +} diff --git a/audio_virtual_effect.h b/audio_virtual_effect.h new file mode 100644 index 0000000..e7262e0 --- a/dev/null +++ b/audio_virtual_effect.h @@ -0,0 +1,17 @@ +#ifndef _AUDIO_HW_EFFECT_H_ +#define _AUDIO_HW_EFFECT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +int Virtualizer_init(void); +int Virtualizer_control(int enable, int EffectLevel); +int Virtualizer_process(int16_t *pInData, int16_t *pOutData, uint16_t NumSamples); +int Virtualizer_release(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libTVaudio/Android.mk b/libTVaudio/Android.mk index 88eee9e..77ec96b 100644 --- a/libTVaudio/Android.mk +++ b/libTVaudio/Android.mk @@ -20,6 +20,10 @@ LOCAL_C_INCLUDES := \ frameworks/av/include/media/stagefright \ frameworks/av/include/media \ frameworks/native/include/media/openmax \ + frameworks/av/media/libeffects/lvm/lib/StereoWidening/lib \ + frameworks/av/media/libeffects/lvm/lib/StereoWidening/src \ + frameworks/av/media/libeffects/lvm/lib/Common/lib \ + frameworks/av/media/libeffects/lvm/lib/Common/src \ $(LOCAL_PATH)/ \ $(LOCAL_PATH)/audio \ @@ -33,6 +37,9 @@ LOCAL_SRC_FILES := \ audio/DDP_media_source.cpp \ audio/aml_shelf.c \ audio/DTSHD_media_source.cpp \ + ../audio_virtual_effect.c + +LOCAL_STATIC_LIBRARIES += libmusicbundle LOCAL_CFLAGS := -DANDROID_PLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) -DUSE_SYS_WRITE_SERVICE=1 diff --git a/libTVaudio/audio/aml_audio.c b/libTVaudio/audio/aml_audio.c index 3df3700..ccb2b47 100644 --- a/libTVaudio/audio/aml_audio.c +++ b/libTVaudio/audio/aml_audio.c @@ -31,6 +31,7 @@ #include "aml_shelf.h" #include "android_out.h" #include "aml_audio.h" +#include "../../audio_virtual_effect.h" #define ANDROID_OUT_BUFFER_SIZE (2048*8*2) //in byte #define DDP_OUT_BUFFER_SIZE (2048*8*2*2*2) //in byte @@ -126,6 +127,7 @@ struct aml_dev { int has_EQ_lib; int has_SRS_lib; int has_aml_IIR_lib; + int has_Virtualizer; int output_mode; pthread_t android_check_ThreadID; }; @@ -205,6 +207,7 @@ static struct aml_dev gmAmlDevice = { .has_EQ_lib = 0, .has_SRS_lib = 0, .has_aml_IIR_lib = 0, + .has_Virtualizer = 0, .output_mode = MODEAMAUDIO, .android_check_ThreadID = 0, }; @@ -282,9 +285,12 @@ static int digital_raw_enable = 0; int output_record_enable = 0; int spdif_audio_type = LPCM; int type_AUDIO_IN = -1; +extern int virtual_para_buf[2]; +extern int eq_gain_buf[5]; static void DoDumpData(void *data_buf, int size, int aud_src_type); static int audio_effect_process(short* buffer, int frame_size); +static int audio_effect_load_para(struct aml_dev *device); static int getprop_bool(const char * path) { @@ -1185,6 +1191,7 @@ static int audio_effect_release() { unload_EQ_lib(); unload_SRS_lib(); unload_aml_IIR_lib(); + Virtualizer_release(); return 0; } @@ -1316,8 +1323,16 @@ static int aml_device_init(struct aml_dev *device) { device->has_aml_IIR_lib = 1; } - audio_IIR_init(); + ret = Virtualizer_init(); + if (ret == 0) { + device->has_Virtualizer = 1; + } else { + ALOGE("%s, init Virtualizer fail!\n", __FUNCTION__); + device->has_Virtualizer = 0; + } + audio_IIR_init(); + audio_effect_load_para(device); ALOGD("%s, exiting...\n", __FUNCTION__); return 0; @@ -1330,6 +1345,24 @@ static int aml_device_init(struct aml_dev *device) { } +static int audio_effect_load_para(struct aml_dev *device) { + int i; + int temp_eq_buf[5] = {0,0,0,0,0}; + int temp_virtual_buf[2] = {0, 0}; + for (i = 0; i < 5; ++i) { + temp_eq_buf[i] = eq_gain_buf[i]; + } + temp_virtual_buf[0] = virtual_para_buf[0]; + temp_virtual_buf[1] = virtual_para_buf[1]; + + if (device->has_EQ_lib) + HPEQ_setParameter(temp_eq_buf[0], temp_eq_buf[1], temp_eq_buf[2], temp_eq_buf[3], temp_eq_buf[4]); + if (device->has_Virtualizer) + Virtualizer_control(temp_virtual_buf[0], temp_virtual_buf[1]); + + return 0; +} + static int aml_device_close(struct aml_dev *device) { struct aml_stream_in *in = &device->in; struct aml_stream_out *out = &device->out; @@ -1592,6 +1625,9 @@ static int audio_effect_process(short* buffer, int frame_size) { if (gpAmlDevice->has_SRS_lib) { output_size = srs_process(buffer, buffer, frame_size); } + if (gpAmlDevice->has_Virtualizer) { + Virtualizer_process(buffer, buffer, frame_size); + } if (gpAmlDevice->has_EQ_lib) { HPEQ_process(buffer, buffer, frame_size); } diff --git a/libTVaudio/audio/audio_amaudio.cpp b/libTVaudio/audio/audio_amaudio.cpp index b46cc87..a2119cb 100644 --- a/libTVaudio/audio/audio_amaudio.cpp +++ b/libTVaudio/audio/audio_amaudio.cpp @@ -23,6 +23,7 @@ #include "audio_usb_check.h" #include "audio_effect_control.h" #include "../audio_amaudio.h" +#include "../../audio_virtual_effect.h" int amSetAudioDelay(int delay_ms) { return set_audio_delay(delay_ms); @@ -80,12 +81,14 @@ int amAudioSetRightGain(int gain) { return set_right_gain(gain); } +int eq_gain_buf[5] = {0,0,0,0,0}; int amAudioSetEQGain(int gain_val_buf[], int buf_item_cnt __unused) { int i = 0, ret = 0; int tmp_buf[5] = { 0, 0, 0, 0, 0}; for (i = 0; i < 5; i++) { tmp_buf[i] = gain_val_buf[i]; + eq_gain_buf[i] = gain_val_buf[i]; } HPEQ_setParameter(tmp_buf[0], tmp_buf[1], tmp_buf[2], tmp_buf[3], @@ -241,12 +244,15 @@ int amAudioGetPreMute(uint *mute) { return aml_audio_get_pre_mute(mute); } +int virtual_para_buf[2] = {0,0}; int amAudioVirtualizer(int enable, int EffectLevel) { int ret = 0; char param[10]; + virtual_para_buf[0] = enable; + virtual_para_buf[1] = EffectLevel; char parm_key[] = "AML_VIRTUALIZER"; sprintf(param, "%03d%03d", enable, EffectLevel); ret = set_parameters(param, parm_key); - //Virtualizer_control(enable, EffectLevel); + Virtualizer_control(enable, EffectLevel); return ret; } -- cgit