summaryrefslogtreecommitdiff
authorChe Song <che.song@amlogic.com>2017-04-07 06:49:04 (GMT)
committer Che Song <che.song@amlogic.com>2017-04-07 06:49:04 (GMT)
commit51cb5136ec88ba956bfa9c7a225ad80291c1e3a3 (patch)
tree34ae3204f8e8e7e0650ec74be58da43d68c32a91
parent28d9ab4a724faf4911919c8f055f7070a299f158 (diff)
downloadaudio-51cb5136ec88ba956bfa9c7a225ad80291c1e3a3.zip
audio-51cb5136ec88ba956bfa9c7a225ad80291c1e3a3.tar.gz
audio-51cb5136ec88ba956bfa9c7a225ad80291c1e3a3.tar.bz2
PD#141914: add a new audio effect Virtualizer in hal
Change-Id: I44e604b5354e38df6bf9dbe59315ad1faea24b28
Diffstat
-rw-r--r--Android.mk7
-rw-r--r--audio_hw.c28
-rw-r--r--audio_hw.h1
-rw-r--r--audio_virtual_effect.c143
-rw-r--r--audio_virtual_effect.h17
-rw-r--r--libTVaudio/Android.mk7
-rw-r--r--libTVaudio/audio/aml_audio.c38
-rw-r--r--libTVaudio/audio/audio_amaudio.cpp8
8 files changed, 247 insertions, 2 deletions
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 <cutils/log.h>
+#include <cutils/properties.h>
+#include <pthread.h>
+
+#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;
}