Merge "hal: fix for surround sound recording"

This commit is contained in:
Linux Build Service Account 2013-12-28 12:03:04 -08:00 committed by Gerrit - the friendly Code Review server
commit 3c1980a975
4 changed files with 69 additions and 192 deletions

View File

@ -61,13 +61,6 @@ void audio_extn_hfp_set_parameters(adev, parms) (0)
void audio_extn_hfp_set_parameters(struct audio_device *adev,
struct str_parms *parms);
#endif
#ifndef SSR_ENABLED
#define audio_extn_ssr_get_parameters(query, reply) (0)
#else
void audio_extn_ssr_get_parameters(struct str_parms *query,
struct str_parms *reply);
#endif
#ifndef ANC_HEADSET_ENABLED
#define audio_extn_set_anc_parameters(adev, parms) (0)
@ -335,7 +328,6 @@ void audio_extn_get_parameters(const struct audio_device *adev,
struct str_parms *reply)
{
audio_extn_get_afe_proxy_parameters(query, reply);
audio_extn_ssr_get_parameters(query, reply);
ALOGD("%s: returns %s", __func__, str_parms_to_str(reply));
}

View File

@ -70,14 +70,14 @@ bool audio_extn_usb_is_proxy_inuse();
#ifndef SSR_ENABLED
#define audio_extn_ssr_init(adev, in) (0)
#define audio_extn_ssr_deinit() (0)
#define audio_extn_ssr_update_enabled(adev) (0)
#define audio_extn_ssr_update_enabled() (0)
#define audio_extn_ssr_get_enabled() (0)
#define audio_extn_ssr_read(stream, buffer, bytes) (0)
#else
int32_t audio_extn_ssr_init(struct audio_device *adev,
struct stream_in *in);
int32_t audio_extn_ssr_deinit();
int32_t audio_extn_ssr_update_enabled(struct audio_device *adev);
void audio_extn_ssr_update_enabled();
bool audio_extn_ssr_get_enabled();
int32_t audio_extn_ssr_read(struct audio_stream_in *stream,
void *buffer, size_t bytes);

View File

@ -34,14 +34,13 @@
#include "surround_filters_interface.h"
#ifdef SSR_ENABLED
#define COEFF_ARRAY_SIZE 4
#define FILT_SIZE ((512+1)* 6) /* # ((FFT bins)/2+1)*numOutputs */
#define SSR_FRAME_SIZE 512
#define SSR_INPUT_FRAME_SIZE (SSR_FRAME_SIZE * 4)
#define SSR_OUTPUT_FRAME_SIZE (SSR_FRAME_SIZE * 6)
#define SSR_CHANNEL_COUNT 4
#define SSR_PERIOD_SIZE 256
#define SSR_PERIOD_COUNT 8
#define COEFF_ARRAY_SIZE 4
#define FILT_SIZE ((512+1)* 6) /* # ((FFT bins)/2+1)*numOutputs */
#define SSR_CHANNEL_INPUT_NUM 4
#define SSR_CHANNEL_OUTPUT_NUM 6
#define SSR_PERIOD_COUNT 8
#define SSR_PERIOD_SIZE 512
#define SSR_INPUT_FRAME_SIZE (SSR_PERIOD_SIZE * SSR_PERIOD_COUNT)
#define SURROUND_FILE_1R "/system/etc/surround_sound/filter1r.pcm"
#define SURROUND_FILE_2R "/system/etc/surround_sound/filter2r.pcm"
@ -52,7 +51,7 @@
#define SURROUND_FILE_2I "/system/etc/surround_sound/filter2i.pcm"
#define SURROUND_FILE_3I "/system/etc/surround_sound/filter3i.pcm"
#define SURROUND_FILE_4I "/system/etc/surround_sound/filter4i.pcm"
#define AUDIO_PARAMETER_KEY_SSR "ssr"
#define LIB_SURROUND_PROC "libsurround_proc.so"
typedef int (*surround_filters_init_t)(void *, int, int, Word16 **,
@ -67,11 +66,7 @@ struct ssr_module {
int16_t **real_coeffs;
int16_t **imag_coeffs;
void *surround_obj;
int16_t *surround_input_buffer;
int16_t *surround_output_buffer;
int surround_input_bufferIdx;
int surround_output_bufferIdx;
int16_t *surround_raw_buffer;
bool is_ssr_enabled;
void *surround_filters_handle;
@ -81,19 +76,13 @@ struct ssr_module {
surround_filters_intl_process_t surround_filters_intl_process;
};
static int32_t ssr_init_surround_sound_lib(unsigned long buffersize);
static int32_t ssr_read_coeffs_from_file();
static struct ssr_module ssrmod = {
.fp_4ch = NULL,
.fp_6ch= NULL,
.fp_6ch = NULL,
.real_coeffs = NULL,
.imag_coeffs = NULL,
.surround_obj = NULL,
.surround_output_buffer = NULL,
.surround_input_buffer = NULL,
.surround_output_bufferIdx = 0,
.surround_input_bufferIdx= 0,
.surround_raw_buffer = NULL,
.is_ssr_enabled = 0,
.surround_filters_handle = NULL,
@ -230,32 +219,20 @@ static int32_t ssr_init_surround_sound_lib(unsigned long buffersize)
int high_freq = 100;
int i, ret = 0;
ssrmod.surround_input_bufferIdx = 0;
ssrmod.surround_output_bufferIdx = 0;
if ( ssrmod.surround_obj ) {
ALOGE("%s: ola filter library is already initialized", __func__);
return 0;
}
/* Allocate memory for input buffer */
ssrmod.surround_input_buffer = (Word16 *) calloc(2 * SSR_INPUT_FRAME_SIZE,
ssrmod.surround_raw_buffer = (Word16 *) calloc(buffersize,
sizeof(Word16));
if ( !ssrmod.surround_input_buffer ) {
if ( !ssrmod.surround_raw_buffer ) {
ALOGE("%s: Memory allocation failure. Not able to allocate "
"memory for surroundInputBuffer", __func__);
goto init_fail;
}
/* Allocate memory for output buffer */
ssrmod.surround_output_buffer = (Word16 *) calloc(2 * SSR_OUTPUT_FRAME_SIZE,
sizeof(Word16));
if ( !ssrmod.surround_output_buffer ) {
ALOGE("%s: Memory allocation failure. Not able to "
"allocate memory for surroundOutputBuffer", __func__);
goto init_fail;
}
/* Allocate memory for real and imag coeffs array */
ssrmod.real_coeffs = (Word16 **) calloc(COEFF_ARRAY_SIZE, sizeof(Word16 *));
if ( !ssrmod.real_coeffs ) {
@ -353,13 +330,9 @@ init_fail:
free(ssrmod.surround_obj);
ssrmod.surround_obj = NULL;
}
if (ssrmod.surround_output_buffer) {
free(ssrmod.surround_output_buffer);
ssrmod.surround_output_buffer = NULL;
}
if (ssrmod.surround_input_buffer) {
free(ssrmod.surround_input_buffer);
ssrmod.surround_input_buffer = NULL;
if (ssrmod.surround_raw_buffer) {
free(ssrmod.surround_raw_buffer);
ssrmod.surround_raw_buffer = NULL;
}
if (ssrmod.real_coeffs){
for (i =0; i<COEFF_ARRAY_SIZE; i++ ) {
@ -385,7 +358,7 @@ init_fail:
return -ENOMEM;
}
int32_t audio_extn_ssr_update_enabled(struct audio_device *adev)
void audio_extn_ssr_update_enabled()
{
char ssr_enabled[PROPERTY_VALUE_MAX] = "false";
@ -397,7 +370,6 @@ int32_t audio_extn_ssr_update_enabled(struct audio_device *adev)
ALOGD("%s: surround sound recording is not supported", __func__);
ssrmod.is_ssr_enabled = false;
}
return 0;
}
bool audio_extn_ssr_get_enabled()
@ -414,12 +386,13 @@ int32_t audio_extn_ssr_init(struct audio_device *adev,
uint32_t buffer_size;
ALOGD("%s: ssr case ", __func__);
in->config.channels = SSR_CHANNEL_COUNT;
in->config.channels = SSR_CHANNEL_INPUT_NUM;
in->config.period_size = SSR_PERIOD_SIZE;
in->config.period_count = SSR_PERIOD_COUNT;
buffer_size = (SSR_PERIOD_SIZE)*(SSR_PERIOD_COUNT);
ALOGD("%s: buffer_size: %d", __func__, buffer_size);
/* use 4k hardcoded buffer size for ssr*/
buffer_size = SSR_INPUT_FRAME_SIZE;
ALOGV("%s: buffer_size: %d", __func__, buffer_size);
ret = ssr_init_surround_sound_lib(buffer_size);
if (0 != ret) {
@ -429,16 +402,16 @@ int32_t audio_extn_ssr_init(struct audio_device *adev,
}
property_get("ssr.pcmdump",c_multi_ch_dump,"0");
if (0 == strncmp("true",c_multi_ch_dump, sizeof("ssr.dump-pcm"))) {
/* Remember to change file system permission of data(e.g. chmod 777 data/),
otherwise, fopen may fail */
if ( !ssrmod.fp_4ch)
ssrmod.fp_4ch = fopen("/data/media/0/4ch_ssr.pcm", "wb");
if ( !ssrmod.fp_6ch)
ssrmod.fp_6ch = fopen("/data/media/0/6ch_ssr.pcm", "wb");
if ((!ssrmod.fp_4ch) || (!ssrmod.fp_6ch))
ALOGE("%s: mfp_4ch or mfp_6ch open failed: mfp_4ch:%p mfp_6ch:%p",
__func__, ssrmod.fp_4ch, ssrmod.fp_6ch);
if (0 == strncmp("true", c_multi_ch_dump, sizeof("ssr.dump-pcm"))) {
/* Remember to change file system permission of data(e.g. chmod 777 data/),
otherwise, fopen may fail */
if ( !ssrmod.fp_4ch)
ssrmod.fp_4ch = fopen("/data/4ch.pcm", "wb");
if ( !ssrmod.fp_6ch)
ssrmod.fp_6ch = fopen("/data/6ch.pcm", "wb");
if ((!ssrmod.fp_4ch) || (!ssrmod.fp_6ch))
ALOGE("%s: mfp_4ch or mfp_6ch open failed: mfp_4ch:%p mfp_6ch:%p",
__func__, ssrmod.fp_4ch, ssrmod.fp_6ch);
}
return 0;
@ -449,7 +422,7 @@ int32_t audio_extn_ssr_deinit()
int i;
if (ssrmod.surround_obj) {
ALOGD("%s: entry", __func__);
ALOGV("%s: entry", __func__);
ssrmod.surround_filters_release(ssrmod.surround_obj);
if (ssrmod.surround_obj)
free(ssrmod.surround_obj);
@ -474,25 +447,21 @@ int32_t audio_extn_ssr_deinit()
free(ssrmod.imag_coeffs);
ssrmod.imag_coeffs = NULL;
}
if (ssrmod.surround_output_buffer){
free(ssrmod.surround_output_buffer);
ssrmod.surround_output_buffer = NULL;
if (ssrmod.surround_raw_buffer) {
free(ssrmod.surround_raw_buffer);
ssrmod.surround_raw_buffer = NULL;
}
if (ssrmod.surround_input_buffer) {
free(ssrmod.surround_input_buffer);
ssrmod.surround_input_buffer = NULL;
}
if ( ssrmod.fp_4ch ) fclose(ssrmod.fp_4ch);
if ( ssrmod.fp_6ch ) fclose(ssrmod.fp_6ch);
if (ssrmod.fp_4ch)
fclose(ssrmod.fp_4ch);
if (ssrmod.fp_6ch)
fclose(ssrmod.fp_6ch);
}
if(ssrmod.surround_filters_handle)
{
if(ssrmod.surround_filters_handle) {
dlclose(ssrmod.surround_filters_handle);
ssrmod.surround_filters_handle = NULL;
}
ALOGD("%s: exit", __func__);
ALOGV("%s: exit", __func__);
return 0;
}
@ -500,120 +469,36 @@ int32_t audio_extn_ssr_deinit()
int32_t audio_extn_ssr_read(struct audio_stream_in *stream,
void *buffer, size_t bytes)
{
int processed = 0;
int processed_pending;
void *buffer_start = buffer;
unsigned period_bytes;
unsigned period_samples;
int read_pending, n;
size_t read_bytes = 0;
int samples = bytes >> 1;
struct stream_in *in = (struct stream_in *)stream;
struct audio_device *adev = in->dev;
size_t peroid_bytes;
int32_t ret;
period_bytes = in->config.period_size;
ALOGD("%s: period_size: %d", __func__, in->config.period_size);
period_samples = period_bytes >> 1;
/* Convert bytes for 6ch to 4ch*/
peroid_bytes = (bytes / SSR_CHANNEL_OUTPUT_NUM) * SSR_CHANNEL_INPUT_NUM;
if (!ssrmod.surround_obj)
if (!ssrmod.surround_obj) {
ALOGE("%s: surround_obj not initialized", __func__);
return -ENOMEM;
do {
if (ssrmod.surround_output_bufferIdx > 0) {
ALOGV("%s: copy processed output "
"to buffer, surround_output_bufferIdx = %d",
__func__, ssrmod.surround_output_bufferIdx);
/* Copy processed output to buffer */
processed_pending = ssrmod.surround_output_bufferIdx;
if (processed_pending > (samples - processed)) {
processed_pending = (samples - processed);
}
memcpy(buffer, ssrmod.surround_output_buffer, processed_pending * sizeof(Word16));
buffer = (char*)buffer + processed_pending * sizeof(Word16);
processed += processed_pending;
if (ssrmod.surround_output_bufferIdx > processed_pending) {
/* Shift leftover samples to beginning of the buffer */
memcpy(&ssrmod.surround_output_buffer[0],
&ssrmod.surround_output_buffer[processed_pending],
(ssrmod.surround_output_bufferIdx - processed_pending) * sizeof(Word16));
}
ssrmod.surround_output_bufferIdx -= processed_pending;
}
if (processed >= samples) {
ALOGV("%s: done processing buffer, "
"processed = %d", __func__, processed);
/* Done processing this buffer */
break;
}
/* Fill input buffer until there is enough to process */
read_pending = SSR_INPUT_FRAME_SIZE - ssrmod.surround_input_bufferIdx;
read_bytes = ssrmod.surround_input_bufferIdx;
while (in->pcm && read_pending > 0) {
n = pcm_read(in->pcm, &ssrmod.surround_input_buffer[read_bytes],
period_bytes);
ALOGV("%s: pcm_read() returned n = %d buffer:%p size:%d", __func__,
n, &ssrmod.surround_input_buffer[read_bytes], period_bytes);
if (n && n != -EAGAIN) {
/* Recovery part of pcm_read. TODO:split recovery */
return (ssize_t)n;
}
else if (n < 0) {
/* Recovery is part of pcm_write. TODO split is later */
return (ssize_t)n;
}
else {
read_pending -= period_samples;
read_bytes += period_samples;
}
}
if (ssrmod.fp_4ch) {
fwrite( ssrmod.surround_input_buffer, 1,
SSR_INPUT_FRAME_SIZE * sizeof(Word16), ssrmod.fp_4ch);
}
/* apply ssr libs to conver 4ch to 6ch */
ssrmod.surround_filters_intl_process(ssrmod.surround_obj,
&ssrmod.surround_output_buffer[ssrmod.surround_output_bufferIdx],
(Word16 *)ssrmod.surround_input_buffer);
/* Shift leftover samples to beginning of input buffer */
if (read_pending < 0) {
memcpy(&ssrmod.surround_input_buffer[0],
&ssrmod.surround_input_buffer[SSR_INPUT_FRAME_SIZE],
(-read_pending) * sizeof(Word16));
}
ssrmod.surround_input_bufferIdx = -read_pending;
if (ssrmod.fp_6ch) {
fwrite( &ssrmod.surround_output_buffer[ssrmod.surround_output_bufferIdx],
1, SSR_OUTPUT_FRAME_SIZE * sizeof(Word16), ssrmod.fp_6ch);
}
ssrmod.surround_output_bufferIdx += SSR_OUTPUT_FRAME_SIZE;
ALOGV("%s: do_while loop: processed=%d, samples=%d\n", __func__, processed, samples);
} while (in->pcm && processed < samples);
read_bytes = processed * sizeof(Word16);
buffer = buffer_start;
return 0;
}
void audio_extn_ssr_get_parameters(struct str_parms *query,
struct str_parms *reply)
{
int ret, val;
char value[32]={0};
ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_SSR, value, sizeof(value));
if (ret >= 0) {
memcpy(value, "true", 4);
str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SSR, value);
}
ret = pcm_read(in->pcm, ssrmod.surround_raw_buffer, peroid_bytes);
if (ret < 0) {
ALOGE("%s: %s ret:%d", __func__, pcm_get_error(in->pcm),ret);
return ret;
}
/* apply ssr libs to conver 4ch to 6ch */
ssrmod.surround_filters_intl_process(ssrmod.surround_obj,
buffer, ssrmod.surround_raw_buffer);
/*dump for raw pcm data*/
if (ssrmod.fp_4ch)
fwrite(ssrmod.surround_raw_buffer, 1, peroid_bytes, ssrmod.fp_4ch);
if (ssrmod.fp_6ch)
fwrite(buffer, 1, bytes, ssrmod.fp_6ch);
return ret;
}
#endif /* SSR_ENABLED */

View File

@ -561,7 +561,7 @@ void *platform_init(struct audio_device *adev)
audio_extn_usb_set_proxy_sound_card(adev->snd_card);
/* Read one time ssr property */
audio_extn_ssr_update_enabled(adev);
audio_extn_ssr_update_enabled();
audio_extn_spkr_prot_init(adev);
return my_data;
}