M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions

View File

@ -0,0 +1,49 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
# ---------------------------------------------------------------------------------
# Common definitons
# ---------------------------------------------------------------------------------
mm-audio-native-def := -g -O3
mm-audio-native-def += -DQC_MODIFIED
mm-audio-native-def += -D_ANDROID_
ifeq ($(strip $(TARGET_USES_QCOM_MM_AUDIO)),true)
mm-audio-native-def += -DTARGET_USES_QCOM_MM_AUDIO
endif
# ---------------------------------------------------------------------------------
# Make the apps-test (mm-audio-native-test)
# ---------------------------------------------------------------------------------
include $(CLEAR_VARS)
ifeq ($(strip $(TARGET_USES_QCOM_MM_AUDIO)),true)
mm-audio-native-inc += $(TARGET_OUT_HEADERS)/mm-audio/atu
endif
LOCAL_MODULE := mm-audio-native-test
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := $(mm-audio-native-def)
LOCAL_PRELINK_MODULE := false
ifeq ($(strip $(TARGET_USES_QCOM_MM_AUDIO)),true)
LOCAL_C_INCLUDES := $(mm-audio-native-inc)
LOCAL_SHARED_LIBRARIES := libatu
endif
LOCAL_SRC_FILES := audiotest.c
LOCAL_SRC_FILES += amrnbtest.c
LOCAL_SRC_FILES += mp3test.c
LOCAL_SRC_FILES += pcmtest.c
LOCAL_SRC_FILES += equalizer.c
LOCAL_SRC_FILES += aactest.c
LOCAL_SRC_FILES += audio_ctrl.c
LOCAL_SRC_FILES += atutest.c
LOCAL_SRC_FILES += qcptest.c
include $(BUILD_EXECUTABLE)
# ---------------------------------------------------------------------------------
# END
# ---------------------------------------------------------------------------------

View File

@ -0,0 +1,639 @@
/* aactest.c - native AAC test application
*
* Based on native pcm test application platform/system/extras/sound/playwav.c
*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010, The Linux Foundation. All rights reserved.
*
* 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <linux/ioctl.h>
#include <linux/msm_audio.h>
#include <linux/msm_audio_aac.h>
#include "audiotest_def.h"
typedef unsigned char uint8;
typedef unsigned char byte;
typedef unsigned int uint32;
typedef unsigned int uint16;
#define AUDAAC_MAX_ADIF_HEADER_LENGTH 64
/* ADTS variable frame header, frame length field */
#define AUDAAC_ADTS_FRAME_LENGTH_SIZE 13
/* maximum ADTS frame header length */
#define AUDAAC_MAX_ADTS_HEADER_LENGTH 7
#define AACHDR_LAYER_SIZE 2
#define AACHDR_CRC_SIZE 1
#define AAC_PROFILE_SIZE 2
#define AAC_SAMPLING_FREQ_INDEX_SIZE 4
#define AAC_ORIGINAL_COPY_SIZE 1
#define AAC_HOME_SIZE 1
#define MIN(A,B) (((A) < (B))?(A):(B))
uint8 audaac_header[AUDAAC_MAX_ADTS_HEADER_LENGTH];
unsigned int audaac_hdr_bit_index;
void audaac_rec_install_bits
(
uint8 *input,
byte num_bits_reqd,
uint32 value,
uint16 *hdr_bit_index
)
{
uint32 byte_index;
byte bit_index;
byte bits_avail_in_byte;
byte num_to_copy;
byte byte_to_copy;
byte num_remaining = num_bits_reqd;
uint8 bit_mask;
bit_mask = 0xFF;
while (num_remaining) {
byte_index = (*hdr_bit_index) >> 3;
bit_index = (*hdr_bit_index) & 0x07;
bits_avail_in_byte = 8 - bit_index;
num_to_copy = MIN(bits_avail_in_byte, num_remaining);
byte_to_copy = ((uint8)((value >> (num_remaining - num_to_copy)) & 0xFF) <<
(bits_avail_in_byte - num_to_copy));
input[byte_index] &= ((uint8)(bit_mask << bits_avail_in_byte));
input[byte_index] |= byte_to_copy;
*hdr_bit_index += num_to_copy;
num_remaining -= num_to_copy;
} /* while (num_remaining) */
} /* audaac_rec_install_bits */
void audaac_rec_install_adts_header_variable (uint16 byte_num)
{
//uint16 bit_index=0;
uint32 value;
uint32 sample_index = 44100;
uint8 channel_config = 1;
/* Store Sync word first */
audaac_header[0] = 0xFF;
audaac_header[1] = 0xF0;
audaac_hdr_bit_index = 12;
/* ID field, 1 bit */
value = 1;
audaac_rec_install_bits(audaac_header,
1,
value,
&(audaac_hdr_bit_index));
/* Layer field, 2 bits */
value = 0;
audaac_rec_install_bits(audaac_header,
AACHDR_LAYER_SIZE,
value,
&(audaac_hdr_bit_index));
/* Protection_absent field, 1 bit */
value = 1;
audaac_rec_install_bits(audaac_header,
AACHDR_CRC_SIZE,
value,
&(audaac_hdr_bit_index));
/* profile_ObjectType field, 2 bit */
value = 1;
audaac_rec_install_bits(audaac_header,
AAC_PROFILE_SIZE,
value,
&(audaac_hdr_bit_index));
/* sampling_frequency_index field, 4 bits */
audaac_rec_install_bits(audaac_header,
AAC_SAMPLING_FREQ_INDEX_SIZE,
(uint32)sample_index,
&(audaac_hdr_bit_index));
/* pravate_bit field, 1 bits */
audaac_rec_install_bits(audaac_header,
1,
0,
&(audaac_hdr_bit_index));
/* channel_configuration field, 3 bits */
audaac_rec_install_bits(audaac_header,
3,
channel_config,
&(audaac_hdr_bit_index));
/* original/copy field, 1 bits */
audaac_rec_install_bits(audaac_header,
AAC_ORIGINAL_COPY_SIZE,
0,
&(audaac_hdr_bit_index));
/* home field, 1 bits */
audaac_rec_install_bits(audaac_header,
AAC_HOME_SIZE,
0,
&(audaac_hdr_bit_index));
// bit_index = audaac_hdr_bit_index;
// bit_index += 2;
/* copyr. id. bit, 1 bits */
audaac_rec_install_bits(audaac_header,
1,
0,
&(audaac_hdr_bit_index));
/* copyr. id. start, 1 bits */
audaac_rec_install_bits(audaac_header,
1,
0,
&(audaac_hdr_bit_index));
/* aac_frame_length field, 13 bits */
audaac_rec_install_bits(audaac_header,
AUDAAC_ADTS_FRAME_LENGTH_SIZE,
byte_num,
&audaac_hdr_bit_index);
/* adts_buffer_fullness field, 11 bits */
audaac_rec_install_bits(audaac_header,
11,
0x7FF,
&audaac_hdr_bit_index);
/* number_of_raw_data_blocks_in_frame, 2 bits */
audaac_rec_install_bits(audaac_header,
2,
0,
&audaac_hdr_bit_index);
} /* audaac_rec_install_adts_header_variable */
static int do_aac_play(struct audtest_config *clnt_config, unsigned rate, unsigned channels,
int (*fill)(void *buf, unsigned sz, void *cookie),
void *cookie)
{
struct msm_audio_config config;
struct audio_pvt_data *audio_data = (struct audio_pvt_data *) clnt_config->private_data;
// struct msm_audio_stats stats;
unsigned sz;
char buf[32768];
int afd;
int cntW=0;
int volume = 100;
afd = open("/dev/msm_aac", O_RDWR);
if (afd < 0) {
perror("aac_play: cannot open audio device");
return -1;
}
if (ioctl(afd, AUDIO_GET_CONFIG, &config)) {
perror("could not get config");
return -1;
}
config.channel_count = channels;
config.sample_rate = rate;
/*<peter>
if (ioctl(afd, AUDIO_SET_CONFIG, &config)) {
perror("could not set config");
return -1;
}
*/
sz = config.buffer_size;
printf("aac_play: sz=%d, buffer_count=%d\n",sz,config.buffer_count);
if (sz > sizeof(buf)) {
fprintf(stderr,"too big\n");
return -1;
}
fprintf(stderr,"start\n");
ioctl(afd, AUDIO_START, 0);
for (;;) {
int cnt = 0;
if (fill(buf, sz, cookie) < 0) {
printf(" fill return NON NULL, exit loop \n");
if(fsync(afd) < 0)
printf("fsync failed\n");
break;
}
if (g_terminate_early) {
printf("cancelling...\n");
break;
}
if( audio_data->g_test_volume ) {
printf("volume = %d\n",volume);
if (ioctl(afd, AUDIO_SET_VOLUME, &volume)) {
perror("could not set volume");
}
volume -= 1;
if( volume <= 1 ) {
/* Loop around to max stream volume so volume change is audible. */
volume = 100;
}
}
cnt = write(afd, buf, sz);
printf("write %d bytes, %d bytes reported\n",sz,cnt);
cntW++;
printf(" aac_play: cntW=%d\n",cntW);
}
printf("end of play\n");
/* let audio finish playing before close */
sleep(3);
close(afd);
return 0;
}
/* http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
static int rec_stop;
static char *next;
static unsigned avail;
static int fill_buffer(void *buf, unsigned sz, void *cookie)
{
unsigned cpy_size = (sz < avail?sz:avail);
printf("fill_buffer: avail=%d, next=%p\n",avail,next);
if (avail == 0) {
return -1;
}
memcpy(buf, next, cpy_size);
next += cpy_size;
avail -= cpy_size;
printf("fill_buffer: avail=%d, next=%p\n",avail,next);
return 0;
}
static void play_aac_file(struct audtest_config *config, unsigned rate, unsigned channels,
int fd, unsigned count)
{
next = (char*)malloc(count);
printf(" play_file: count=%d\n", count);
if (!next) {
fprintf(stderr,"could not allocate %d bytes\n", count);
return;
}
if (read(fd, next, count) != count) {
fprintf(stderr,"could not read %d bytes\n", count);
//return;
}
avail = count;
do_aac_play(config, rate, channels, fill_buffer, 0);
}
int aac_play(struct audtest_config *config)
{
struct stat stat_buf;
int fd;
if (config == NULL) {
return -1;
}
fd = open(config->file_name, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "playaac: cannot open '%s'\n", config->file_name);
return -1;
}
(void)fstat(fd, &stat_buf);
play_aac_file(config, 44100, 2, fd, stat_buf.st_size);
return 0;
}
int aac_rec(struct audtest_config *config)
{
//unsigned char buf[8192];
unsigned char buf[2048*10];
struct msm_audio_stream_config str_cfg;
struct msm_audio_aac_enc_config aac_cfg;
struct audio_pvt_data *audio_data = (struct audio_pvt_data *) config->private_data;
unsigned sz ,framesize = 0; //n;
int fd, afd;
unsigned total = 0;
unsigned char tmp;
static unsigned int cnt = 0;
fd = open(config->file_name, O_CREAT | O_RDWR, 0666);
if (fd < 0) {
perror("cannot open output file");
return -1;
}
afd = open("/dev/msm_aac_in", O_RDWR);
if (afd < 0) {
perror("cannot open msm_aac_in");
close(fd);
return -1;
}
if (ioctl(afd, AUDIO_GET_STREAM_CONFIG, &str_cfg)) {
perror("cannot read audio stream config");
goto fail;
}
sz = 1543;
fprintf(stderr,"buffer size %d\n", sz);
if (sz > sizeof(buf)) {
fprintf(stderr,"buffer size %d too large\n", sz);
goto fail;
}
str_cfg.buffer_size = sz;
str_cfg.buffer_count = 2;
if (ioctl(afd, AUDIO_SET_STREAM_CONFIG, &str_cfg)) {
perror("cannot write audio stream config");
goto fail;
}
if (ioctl(afd, AUDIO_GET_AAC_ENC_CONFIG, &aac_cfg)) {
perror("cannot read AAC config");
goto fail;
}
aac_cfg.channels = 1;
aac_cfg.bit_rate = 192000;
aac_cfg.stream_format = AUDIO_AAC_FORMAT_ADTS;
aac_cfg.sample_rate = 48000;
if (ioctl(afd, AUDIO_SET_AAC_ENC_CONFIG, &aac_cfg)) {
perror("cannot set AAC config");
goto fail;
}
if (ioctl(afd, AUDIO_START, 0)) {
perror("cannot start audio");
goto fail;
}
fcntl(0, F_SETFL, O_NONBLOCK);
fprintf(stderr,"\n*** RECORDING * USE 'STOP' CONTROL COMMAND TO STOP***\n");
rec_stop = 0;
for (;(rec_stop!=1);) {
if (g_terminate_early || (rec_stop==1)) {
printf("cancelling...\n");
break;
}
framesize = read(afd, buf, sz);
if(write(fd, buf, framesize) != framesize) {
perror("cannot write buffer");
goto fail;
}
total += framesize;
}
done:
printf("end of recording\n");
close(afd);
close(fd);
return 0;
fail:
close(afd);
close(fd);
unlink(config->file_name);
return -1;
}
static void audiotest_alarm_handler(int sig)
{
printf("Alarm handler\n");
g_terminate_early = 1;
sleep(1);
}
void* playaac_thread(void* arg) {
struct audiotest_thread_context *context =
(struct audiotest_thread_context*) arg;
int ret_val;
ret_val = aac_play(&context->config);
free_context(context);
pthread_exit((void*) ret_val);
return NULL;
}
int aacplay_read_params(void) {
struct audiotest_thread_context *context;
struct itimerspec ts;
char *token;
int ret_val = 0;
printf("This option is not supported currently\n");
return -1;
if ((context = get_free_context()) == NULL) {
ret_val = -1;
} else {
context->config.file_name = "/data/test.aac";
g_terminate_early = 0;
struct audio_pvt_data *audio_data;
audio_data = (struct audio_pvt_data *) malloc(sizeof(struct audio_pvt_data));
if(!audio_data) {
printf("error allocating audio instance structure \n");
free_context(context);
ret_val = -1;
} else {
token = strtok(NULL, " ");
while (token != NULL) {
if (!memcmp(token,"-id=", (sizeof("-id=")-1))) {
context->cxt_id = atoi(&token[sizeof("-id=") - 1]);
} else if (!memcmp(token,"-volume=", (sizeof("-volume=") - 1))) {
audio_data->g_test_volume = atoi(&token[sizeof("-volume=") - 1]);
} else if (!memcmp(token,"-timeout=", (sizeof("-timeout=") - 1))) {
audio_data->g_rec_timeout = atoi(&token[sizeof("-timeout=") - 1]);
memset(&ts, 0, sizeof(struct itimerspec));
printf("setting rec timeout to %d secs\n", audio_data->g_rec_timeout);
ts.it_value.tv_sec = audio_data->g_rec_timeout;
signal(SIGALRM, audiotest_alarm_handler);
setitimer(ITIMER_REAL, &ts, NULL);
} else {
context->config.file_name = token;
}
token = strtok(NULL, " ");
}
context->type = AUDIOTEST_TEST_MOD_AAC_DEC;
context->config.private_data = (struct audio_pvt_data *) audio_data;
pthread_create( &context->thread, NULL,
playaac_thread, (void*) context);
}
}
return ret_val;
}
void* recaac_thread(void* arg) {
struct audiotest_thread_context *context =
(struct audiotest_thread_context*) arg;
int ret_val;
ret_val = aac_rec(&context->config);
free_context(context);
pthread_exit((void*) ret_val);
return NULL;
}
int aacrec_read_params(void) {
struct audiotest_thread_context *context;
struct itimerspec ts;
char *token;
int ret_val = 0;
if ((context = get_free_context()) == NULL) {
ret_val = -1;
} else {
context->config.file_name = "/data/rec.aac";
context->type = AUDIOTEST_TEST_MOD_AAC_ENC;
g_terminate_early = 0;
struct audio_pvt_data *audio_data;
audio_data = (struct audio_pvt_data *) malloc(sizeof(struct audio_pvt_data));
if(!audio_data) {
printf("error allocating audio instance structure \n");
free_context(context);
ret_val = -1;
} else {
token = strtok(NULL, " ");
while (token != NULL) {
printf("%s \n", token);
if (!memcmp(token,"-id=", (sizeof("-id=") - 1))) {
context->cxt_id = atoi(&token[sizeof("-id=") - 1]);
} else if (!memcmp(token,"-timeout=", (sizeof("-timeout=") - 1))) {
audio_data->g_rec_timeout = atoi(&token[sizeof("-timeout=") - 1]);
memset(&ts, 0, sizeof(struct itimerspec));
printf("setting rec timeout to %d secs\n", audio_data->g_rec_timeout);
ts.it_value.tv_sec = audio_data->g_rec_timeout;
signal(SIGALRM, audiotest_alarm_handler);
setitimer(ITIMER_REAL, &ts, NULL);
} else {
context->config.file_name = token;
}
token = strtok(NULL, " ");
}
context->config.private_data = (struct audio_pvt_data *) audio_data;
pthread_create( &context->thread, NULL, recaac_thread, (void*) context);
}
}
return ret_val;
}
int aac_play_control_handler(void* private_data) {
int /* drvfd ,*/ ret_val = 0;
char *token;
token = strtok(NULL, " ");
if ((private_data != NULL) &&
(token != NULL)) {
/* drvfd = (int) private_data */
if(!memcmp(token,"-cmd=", (sizeof("-cmd=") -1))) {
token = &token[sizeof("-id=") - 1];
printf("%s: cmd %s\n", __FUNCTION__, token);
}
} else {
ret_val = -1;
}
return ret_val;
}
int aac_rec_control_handler(void* private_data) {
int /* drvfd ,*/ ret_val = 0;
char *token;
token = strtok(NULL, " ");
if ((private_data != NULL) &&
(token != NULL)) {
/* drvfd = (int) private_data */
if(!memcmp(token,"-cmd=", (sizeof("-cmd=") -1))) {
token = &token[sizeof("-cmd=") - 1];
printf("%s: cmd %s\n", __FUNCTION__, token);
if (!strcmp(token, "stop"))
printf("Rec stop command\n");
rec_stop = 1;
}
} else {
ret_val = -1;
}
return ret_val;
}
const char *aacplay_help_txt =
"Play AAC file: type \n\
echo \"playaac path_of_file -id=xxx timeout=x -volume=x\" > /data/audio_test \n\
timeout = x (value in seconds) \n\
Volume = 0 (default, volume=100), 1 (test different volumes continuously) \n\
Bits per sample = 16 bits \n ";
void aacplay_help_menu(void) {
printf("%s\n", aacplay_help_txt);
}
const char *aacrec_help_txt =
"Record aac file: type \n\
echo \"recaac path_of_file -id=xxx -timeout=x\" > tmp/audio_test \n\
sample rate: 48000 constant\n\
timeout = x (value in seconds) \n\
channel mode: 1 constant \n ";
void aacrec_help_menu(void) {
printf("%s\n", aacrec_help_txt);
}

View File

@ -0,0 +1,452 @@
/* amrnbtest.c - native AMRNB test application
*
* Based on native pcm test application platform/system/extras/sound/playwav.c
*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010, The Linux Foundation. All rights reserved.
*
* 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <errno.h>
#include <linux/msm_audio_amrnb.h>
#include "audiotest_def.h"
/* http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
struct wav_header { /* Simple wave header */
char Chunk_ID[4]; /* Store "RIFF" */
unsigned int Chunk_size;
char Riff_type[4]; /* Store "WAVE" */
char Chunk_ID1[4]; /* Store "fmt " */
unsigned int Chunk_fmt_size;
unsigned short Compression_code; /*1 - 65,535, 1 - pcm */
unsigned short Number_Channels; /* 1 - 65,535 */
unsigned int Sample_rate; /* 1 - 0xFFFFFFFF */
unsigned int Bytes_Sec; /*1 - 0xFFFFFFFF */
unsigned short Block_align; /* 1 - 65,535 */
unsigned short Significant_Bits_sample; /* 1 - 65,535 */
char Chunk_ID2[4]; /* Store "data" */
unsigned int Chunk_data_size;
} __attribute__ ((packed));
static char *next;
static unsigned avail;
static int do_amr_play(struct audtest_config *clnt_config, unsigned rate, unsigned channels,
int (*fill)(void *buf, unsigned sz, void *cookie),
void *cookie)
{
struct msm_audio_config config;
struct audio_pvt_data *audio_data = (struct audio_pvt_data *) clnt_config->private_data;
// struct msm_audio_stats stats;
unsigned sz;
char buf[32768];
int afd;
int cntW=0;
int volume = 1200;
afd = open("/dev/msm_amr", O_RDWR);
if (afd < 0) {
perror("amr_play: cannot open audio device");
return -1;
}
if (ioctl(afd, AUDIO_GET_CONFIG, &config)) {
perror("could not get config");
return -1;
}
config.channel_count = channels;
config.sample_rate = rate;
/*<peter>
if (ioctl(afd, AUDIO_SET_CONFIG, &config)) {
perror("could not set config");
return -1;
}
*/
sz = 4096;//config.buffer_size;
printf("amr_play: sz=%d, buffer_count=%d\n",sz,config.buffer_count);
if (sz > sizeof(buf)) {
fprintf(stderr,"too big\n");
return -1;
}
fprintf(stderr,"start\n");
ioctl(afd, AUDIO_START, 0);
for (;;) {
int cnt = 0;
if (fill(buf, sz, cookie)) {
printf(" fill return NON NULL, exit loop \n");
break;
}
if( audio_data->g_test_volume ) {
printf("volume = %d\n",volume);
if (ioctl(afd, AUDIO_SET_VOLUME, &volume)) {
perror("could not set volume");
}
volume -= 40;
}
cnt = write(afd, buf, sz);
printf("write %d bytes, %d bytes reported\n",sz,cnt);
cntW++;
printf("amr_play: cntW=%d\n",cntW);
}
printf("end of play\n");
/* let audio finish playing before close */
sleep(3);
close(afd);
return 0;
}
static int rec_stop;
static char *next;
static unsigned avail;
static int fill_buffer(void *buf, unsigned sz, void *cookie)
{
unsigned cpy_size = (sz < avail?sz:avail);
printf("fill_buffer: avail=%d, next=%p\n",avail,next);
if (avail == 0) {
return -1;
}
memcpy(buf, next, cpy_size);
next += cpy_size;
avail -= cpy_size;
printf("fill_buffer: avail=%d, next=%p\n",avail,next);
return 0;
}
static void play_amr_file(struct audtest_config *config, unsigned rate, unsigned channels,
int fd, unsigned count)
{
next = (char*)malloc(count);
printf(" play_file: count=%d\n", count);
if (!next) {
fprintf(stderr,"could not allocate %d bytes\n", count);
return;
}
if (read(fd, next, count) != count) {
fprintf(stderr,"could not read %d bytes\n", count);
//return;
}
avail = count;
do_amr_play(config, rate, channels, fill_buffer, 0);
}
int amrnb_play(struct audtest_config *config)
{
struct stat stat_buf;
int fd;
if (config == NULL) {
return -1;
}
fd = open(config->file_name, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "playamr: cannot open '%s'\n", config->file_name);
return -1;
}
(void)fstat(fd, &stat_buf);
play_amr_file(config, 48000, 1, fd, stat_buf.st_size);
return 0;
}
int amrnb_rec(struct audtest_config *config)
{
unsigned char buf[2048*10];
struct msm_audio_stream_config amrnb_str_cfg;
struct msm_audio_amrnb_enc_config_v2 amrnb_cfg;
struct msm_voicerec_mode voicerec_mode;
struct audio_pvt_data *audio_data = (struct audio_pvt_data *) config->private_data;
unsigned sz ,framesize = 0;
int fd, afd;
unsigned char tmp;
static unsigned int cnt = 0;
fd = open(config->file_name, O_CREAT | O_RDWR, 0666);
if (fd < 0) {
perror("cannot open output file");
return -1;
}
afd = open("/dev/msm_amr_in", O_RDWR);
if (afd < 0) {
perror("cannot open msm_amr_in");
close(fd);
return -1;
}
sz = 768;
fprintf(stderr,"buffer size %d\n", sz);
if (sz > sizeof(buf)) {
fprintf(stderr,"buffer size %d too large\n", sz);
goto fail;
}
amrnb_str_cfg.buffer_size = sz;
amrnb_str_cfg.buffer_count=2;
if (ioctl(afd, AUDIO_SET_STREAM_CONFIG, &amrnb_str_cfg)) {
perror("cannot write audio config");
goto fail;
}
amrnb_cfg.band_mode = 7;
amrnb_cfg.dtx_enable = 0;
if (ioctl(afd, AUDIO_SET_AMRNB_ENC_CONFIG, &amrnb_cfg)) {
perror("cannot write audio config");
goto fail;
}
voicerec_mode.rec_mode=2;
if (ioctl(afd, AUDIO_SET_INCALL, &voicerec_mode)) {
perror("cannot set incall mode");
goto fail;
}
if (ioctl(afd, AUDIO_START, 0)) {
perror("cannot start audio");
goto fail;
}
fcntl(0, F_SETFL, O_NONBLOCK);
fprintf(stderr,"\n*** RECORDING * USE 'STOP' CONTROL COMMAND TO STOP***\n");
if(write(fd, "#!AMR\n", 6) != 6) {
perror("cannot write AMR header");
goto fail;
}
for (;(rec_stop!=1);) {
framesize = read(afd, buf, sz);
printf("AMR decoded frame num = %d , size = %d \n",++cnt,framesize);
if(write(fd, buf, framesize) != framesize) {
perror("cannot write buffer");
goto fail;
}
}
done:
close(afd);
close(fd);
return 0;
fail:
close(afd);
close(fd);
unlink(config->file_name);
return -1;
}
static void audiotest_alarm_handler(int sig)
{
g_terminate_early = 1;
sleep(1);
}
void* playamrnb_thread(void* arg) {
struct audiotest_thread_context *context =
(struct audiotest_thread_context*) arg;
int ret_val;
ret_val = amrnb_play(&context->config);
free_context(context);
pthread_exit((void*) ret_val);
return NULL;
}
int amrnbplay_read_params(void) {
struct audiotest_thread_context *context;
struct itimerspec ts;
char *token;
int ret_val = 0;
printf("This option is not supported currently\n");
return -1;
if ((context = get_free_context()) == NULL) {
ret_val = -1;
} else {
context->config.file_name = "/data/data.amr";
g_terminate_early = 0;
struct audio_pvt_data *audio_data;
audio_data = (struct audio_pvt_data *) malloc(sizeof(struct audio_pvt_data));
if(!audio_data) {
printf("error allocating audio instance structure \n");
free_context(context);
ret_val = -1;
} else {
token = strtok(NULL, " ");
while (token != NULL) {
if (!memcmp(token,"-id=", (sizeof("-id=")-1))) {
context->cxt_id = atoi(&token[sizeof("-id=") - 1]);
} else if (!memcmp(token,"-volume=", (sizeof("-volume=") - 1))) {
audio_data->g_test_volume = atoi(&token[sizeof("-volume=") - 1]);
} else if (!memcmp(token,"-timeout=", (sizeof("-timeout=") - 1))) {
audio_data->g_rec_timeout = atoi(&token[sizeof("-timeout=") - 1]);
memset(&ts, 0, sizeof(struct itimerspec));
printf("setting rec timeout to %d secs\n", audio_data->g_rec_timeout);
ts.it_value.tv_sec = audio_data->g_rec_timeout;
signal(SIGALRM, audiotest_alarm_handler);
setitimer(ITIMER_REAL, &ts, NULL);
} else {
context->config.file_name = token;
}
token = strtok(NULL, " ");
}
context->type = AUDIOTEST_TEST_MOD_AMRNB_DEC;
context->config.private_data = (struct audio_pvt_data *) audio_data;
pthread_create( &context->thread, NULL,
playamrnb_thread, (void*) context);
}
}
return ret_val;
}
void* recamrnb_thread(void* arg) {
struct audiotest_thread_context *context =
(struct audiotest_thread_context*) arg;
int ret_val;
ret_val = amrnb_rec(&context->config);
free_context(context);
pthread_exit((void*) ret_val);
return NULL;
}
int amrnbrec_read_params(void) {
struct audiotest_thread_context *context;
struct itimerspec ts;
char *token;
int ret_val = 0;
if ((context = get_free_context()) == NULL) {
ret_val = -1;
} else {
context->config.file_name = "/data/record.amr";
context->type = AUDIOTEST_TEST_MOD_AMRNB_ENC;
g_terminate_early = 0;
struct audio_pvt_data *audio_data;
audio_data = (struct audio_pvt_data *) malloc(sizeof(struct audio_pvt_data));
if(!audio_data) {
printf("error allocating audio instance structure \n");
free_context(context);
ret_val = -1;
} else {
token = strtok(NULL, " ");
while (token != NULL) {
printf("%s \n", token);
if (!memcmp(token,"-id=", (sizeof("-id=") - 1))) {
context->cxt_id = atoi(&token[sizeof("-id=") - 1]);
} else if (!memcmp(token,"-timeout=", (sizeof("-timeout=") - 1))) {
audio_data->g_rec_timeout = atoi(&token[sizeof("-timeout=") - 1]);
memset(&ts, 0, sizeof(struct itimerspec));
printf("setting rec timeout to %d secs\n", audio_data->g_rec_timeout);
ts.it_value.tv_sec = audio_data->g_rec_timeout;
signal(SIGALRM, audiotest_alarm_handler);
setitimer(ITIMER_REAL, &ts, NULL);
} else {
context->config.file_name = token;
}
token = strtok(NULL, " ");
}
printf("%s \n", __FUNCTION__);
context->config.private_data = (struct audio_pvt_data *) audio_data;
pthread_create( &context->thread, NULL, recamrnb_thread, (void*) context);
}
}
return ret_val;
}
int amrnb_play_control_handler(void* private_data) {
int /* drvfd ,*/ ret_val = 0;
char *token;
token = strtok(NULL, " ");
if ((private_data != NULL) &&
(token != NULL)) {
/* drvfd = (int) private_data */
if(!memcmp(token,"-cmd=", (sizeof("-cmd=") -1))) {
token = &token[sizeof("-id=") - 1];
printf("%s: cmd %s\n", __FUNCTION__, token);
}
} else {
ret_val = -1;
}
return ret_val;
}
int amrnb_rec_control_handler(void* private_data) {
int /* drvfd ,*/ ret_val = 0;
char *token;
token = strtok(NULL, " ");
if ((private_data != NULL) &&
(token != NULL)) {
/* drvfd = (int) private_data */
if(!memcmp(token,"-cmd=", (sizeof("-cmd=") -1))) {
token = &token[sizeof("-cmd=") - 1];
printf("%s: cmd %s\n", __FUNCTION__, token);
if (!strcmp(token, "stop"))
printf("Rec stop command\n");
rec_stop = 1;
}
} else {
ret_val = -1;
}
return ret_val;
}
const char *amrnbplay_help_txt =
"Play AMR file: type \n\
echo \"playamrnb path_of_file -id=xxx timeout=x -volume=x\" > /data/audio_test \n\
timeout = x (value in seconds) \n\
Volume = 0 (default, volume=100), 1 (test different volumes continuously) \n\
Bits per sample = 16 bits \n ";
void amrnbplay_help_menu(void) {
printf("%s\n", amrnbplay_help_txt);
}
const char *amrnbrec_help_txt =
"Record amrnb file: type \n\
echo \"recamrnb path_of_file -id=xxx -timeout=x\" > /data/audio_test \n\
timeout = x (value in seconds) \n ";
void amrnbrec_help_menu(void) {
printf("%s\n", amrnbrec_help_txt);
}

View File

@ -0,0 +1,165 @@
/* atutest.c - native ATU test application
*
* Based on native pcm test application platform/system/extras/sound/playwav.c
*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010, 2012 The Linux Foundation. All rights reserved.
*
* 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include<unistd.h>
#include<string.h>
#include <errno.h>
#include <linux/msm_audio.h>
#include "audiotest_def.h"
#if defined(TARGET_USES_QCOM_MM_AUDIO)
#include "msm8k_atu.h"
#else
enum atu_path{
ATU_TONE_PATH_LOCAL,
ATU_TONE_PATH_TX,
ATU_TONE_PATH_BOTH,
ATU_TONE_PATH_32BIT_DUMMY = 0xFFFFFFFF
};
enum atu_status{
ATU_REPEAT,
ATU_STOP_DONE
};
#define atu_set_device(device) (-EPERM)
#define atu_set_rx_volume(rx_vol) (-EPERM)
#define atu_set_tx_volume(rx_vol) (-EPERM)
#define atu_start_sound_id(sound_id, repeat_cnt, tone_path, cb_ptr, client_data) (-EPERM)
#define atu_start_dtmf(f_hi_hz, f_low_hz, tone_duration_ms, tone_path, cb_ptr, client_data) (-EPERM)
#define atu_stop() (-EPERM)
#define atu_init() (-EPERM)
#define atu_dinit() (-EPERM)
#endif
int tone, repeat, device;
void atu_callback_function(enum atu_status status, const void *client_data)
{
printf("ATU status %d \n", status);
}
void play_tone(int tone_id, unsigned int repeatCnt, unsigned int deviceId)
{
int sleep_time_sec = 10;
unsigned int repeat_cnt = 0;
unsigned int id = 0;
unsigned int device_id = 2;
enum atu_path tone_path = ATU_TONE_PATH_BOTH;
printf("toneID=%d, deviceId=%d, repeat=%d\n",tone_id, deviceId, repeatCnt);
atu_init();
if(deviceId != 2)
device_id = deviceId;
atu_set_device(device_id);
atu_set_rx_volume(2000);
atu_set_tx_volume(2000);
id = tone_id;
if(repeatCnt > 0)
repeat_cnt = repeatCnt;
if (atu_start_sound_id(id, repeat_cnt, tone_path, atu_callback_function, NULL) < 0) {
printf("Test case not supported\n");
return;
}
sleep(sleep_time_sec);
atu_stop();
sleep(1);
atu_dinit();
return;
}
void* atutest_thread(void* arg) {
struct audiotest_thread_context *context =
(struct audiotest_thread_context*) arg;
int ret_val;
play_tone(tone, repeat, device);
free_context(context);
pthread_exit((void*) ret_val);
return NULL;
}
int atutest_read_params(void) {
struct audiotest_thread_context *context;
char *token;
int ret_val = 0;
if ((context = get_free_context()) == NULL) {
ret_val = -1;
} else {
struct audio_pvt_data *audio_data;
audio_data = (struct audio_pvt_data *) malloc(sizeof(struct audio_pvt_data));
if(!audio_data) {
printf("error allocating audio instance structure \n");
free_context(context);
ret_val = -1;
} else {
token = strtok(NULL, " ");
while (token != NULL) {
if (!memcmp(token,"-id=", (sizeof("-id=")-1))) {
context->cxt_id = atoi(&token[sizeof("-id=") - 1]);
} else if (!memcmp(token,"-tone=", (sizeof("-tone=") - 1))) {
tone = atoi(&token[sizeof("-tone=") - 1]);
} else if (!memcmp(token,"-repeat=", (sizeof("-repeat=") - 1))) {
repeat = atoi(&token[sizeof("-repeat=") - 1]);
} else if (!memcmp(token,"-device=", (sizeof("-device=") - 1))) {
device = atoi(&token[sizeof("-device=") - 1]);
} else {
context->config.file_name = token;
}
token = strtok(NULL, " ");
}
context->type = AUDIOTEST_TEST_MOD_ATUTEST;
context->config.private_data = (struct audio_pvt_data *) audio_data;
pthread_create( &context->thread, NULL,
atutest_thread, (void*) context);
}
}
return ret_val;
}
int atutest_control_handler(void *private_data)
{
int ret_val = 0;
/* Nothing to do */
return ret_val;
}
const char *atutest_help_txt =
"Play tone test: toneid, deviceid, repeatcnt \n\
echo \"playtone -id=xxx -tone=x -device=x -repeat=x\" > /data/audio_test \n\
tone = tone_id, device = device_id, repeat = repeat count\n\ ";
void atutest_help_menu(void) {
printf("%s\n", atutest_help_txt);
}

View File

@ -0,0 +1,454 @@
/* audio_ctrl.c - native audio control test application
*
* Based on native pcm test application platform/system/extras/sound/playwav.c
*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010, The Linux Foundation. All rights reserved.
*
* 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.
*/
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <linux/ioctl.h>
#include <linux/msm_audio.h>
#include "audiotest_def.h"
#define HA_MIC 0x107ac8d
#define HA_SPKR 0x107ac88
#define HE_MIC 0x1081510
#define HE_SPKR_MONO 0x1081511
#define HE_SPKR_STEREO 0x107ac8a
#define SP_PHONE_MIC 0x1081512
#define SP_PHONE_MONO 0x1081513
#define SP_PHONE_STEREO 0x1081514
#define BT_SCO_MIC_DEVICE 0x1081518
#define BT_SCO_SPKR_DEVICE 0x1081519
#define BT_A2DP_SPKR_DEVICE 0x108151a
#define TTY_HE_MIC 0x108151b
#define TTY_HE_SPKR 0x108151c
#define HE_MONO_PLUS_SPKR_MONO_RX 0x108c508
#define HE_MONO_PLUS_SPKR_STEREO_RX 0x108c895
#define HE_STEREO_PLUS_SPKR_MONO_RX 0x108c894
#define HE_STEREO_PLUS_SPKR_STEREO_RX 0x108c509
#define I2S_RX_DEVICE 0x1089bf4
#define I2S_TX_DEVICE 0x1089bf3
int switch_to_device(int rxdev, int txdev)
{
int fd;
int rc = 0;
unsigned long tx_device;
unsigned long rx_device;
int arr[2] = {0, 0};
fd = open("/dev/msm_audio_ctl", O_RDWR);
if (fd < 0) {
perror("audio_ctrl: cannot open audio control device");
return -1;
}
switch (rxdev) {
case 2:
printf("switching to HANDSET_SPKR\n");
rx_device = HA_SPKR;
break;
case 4:
printf("switching to HEADSET_SPKR_MONO\n");
rx_device = HE_SPKR_MONO;
break;
case 5:
printf("switching to HEADSET_SPKR_STEREO\n");
rx_device = HE_SPKR_STEREO;
break;
case 7:
printf("switching to SPKR_PHONE_MONO\n");
rx_device = SP_PHONE_MONO;
break;
case 8:
printf("switching to SPKR_PHONE_STEREO\n");
rx_device = SP_PHONE_STEREO;
break;
case 10:
printf("switching to BT_SCO_SPKR\n");
rx_device = BT_SCO_SPKR_DEVICE;
break;
case 11:
printf("switching to BT_A2DP_SPKR\n");
rx_device = BT_A2DP_SPKR_DEVICE;
break;
case 13:
printf("switching to TTY_HEADSET_SPKR\n");
rx_device = TTY_HE_SPKR;
break;
case 14:
printf("switching to TTY HCO\n");
tx_device = TTY_HE_MIC;
rx_device = HA_SPKR;
break;
case 15:
printf("switching to TTY VCO\n");
tx_device = HA_MIC;
rx_device = TTY_HE_SPKR;
break;
case 16:
printf("headset mono plus speaker phone mono\n");
tx_device = SP_PHONE_MIC;
rx_device = HE_MONO_PLUS_SPKR_MONO_RX;
break;
case 17:
printf("headset mono plus speaker phone stereo\n");
tx_device = SP_PHONE_MIC;
rx_device = HE_MONO_PLUS_SPKR_STEREO_RX;
break;
case 18:
printf("headset stereo plus speaker phone mono\n");
tx_device = SP_PHONE_MIC;
rx_device = HE_STEREO_PLUS_SPKR_MONO_RX;
break;
case 19:
printf("headset stereo plus speaker phone stereo\n");
tx_device = SP_PHONE_MIC;
rx_device = HE_STEREO_PLUS_SPKR_STEREO_RX;
break;
case 32:
printf("switching to I2S_RX_DEVICE\n");
rx_device = I2S_RX_DEVICE;
break;
default:
printf("switching to rx device %d\n", rxdev);
rx_device = rxdev;
break;
}
switch (txdev) {
case 1:
printf("switching to HANDSET_MIC\n");
tx_device = HA_MIC;
break;
case 3:
printf("switching to HEADSET_MIC\n");
tx_device = HE_MIC;
break;
case 6:
printf("switching to SPKR_PHONE_MIC\n");
tx_device = SP_PHONE_MIC;
break;
case 9:
printf("switching to BT_SCO_MIC\n");
tx_device = BT_SCO_MIC_DEVICE;
break;
case 12:
printf("switching to TTY_HEADSET_MIC\n");
tx_device = TTY_HE_MIC;
break;
case 33:
printf("switching to I2S_TX_DEVICE\n");
tx_device = I2S_TX_DEVICE;
break;
default:
printf("switching to tx device %d\n", txdev);
tx_device = txdev;
break;
}
printf("rx device = %d\n",(int)rx_device);
arr[0] = rx_device;
if (ioctl(fd, AUDIO_SWITCH_DEVICE, arr)) {
perror("could not switch device");
rc = -1;
goto done;
}
printf("tx device = %d\n",(int)tx_device);
arr[0] = tx_device;
if (ioctl(fd, AUDIO_SWITCH_DEVICE, arr)) {
perror("could not switch device");
rc = -1;
goto done;
}
done:
close(fd);
return rc;
}
int master_vol(uint32_t volume)
{
int fd;
int rc = 0;
fd = open("/dev/msm_audio_ctl", O_RDWR);
if (fd < 0) {
perror("audio_ctrl: cannot open audio control device");
return -1;
}
volume *= 20; //percentage
printf("Setting in-call volume to %d\n", volume);
if (ioctl(fd, AUDIO_SET_VOLUME, &volume)) {
perror("could not set volume");
rc = -1;
goto done;
}
done:
close(fd);
return rc;
}
int master_mute(uint32_t mute)
{
int fd;
int rc = 0;
printf("set mute: %d\n", mute);
fd = open("/dev/msm_audio_ctl", O_RDWR);
if (fd < 0) {
perror("audio_ctrl: cannot open audio control device");
return -1;
}
if (ioctl(fd, AUDIO_SET_MUTE, &mute)) {
perror("could not set mute");
rc = -1;
goto done;
}
done:
close(fd);
return rc;
}
int txdev, rxdev;
uint32_t volume, mute;
void* switchdev_thread(void* arg) {
struct audiotest_thread_context *context =
(struct audiotest_thread_context*) arg;
int ret_val;
ret_val = switch_to_device(rxdev, txdev);
free_context(context);
pthread_exit((void*) ret_val);
return NULL;
}
void* mastervol_thread(void* arg) {
struct audiotest_thread_context *context =
(struct audiotest_thread_context*) arg;
int ret_val;
ret_val = master_vol(volume);
free_context(context);
pthread_exit((void*) ret_val);
return NULL;
}
void* mastermute_thread(void* arg) {
struct audiotest_thread_context *context =
(struct audiotest_thread_context*) arg;
int ret_val;
ret_val = master_mute(mute);
free_context(context);
pthread_exit((void*) ret_val);
return NULL;
}
int switchdev_read_params(void) {
struct audiotest_thread_context *context;
char *token;
int ret_val = 0;
if ((context = get_free_context()) == NULL) {
ret_val = -1;
} else {
struct audio_pvt_data *audio_data;
audio_data = (struct audio_pvt_data *) malloc(sizeof(struct audio_pvt_data));
if(!audio_data) {
printf("error allocating audio instance structure \n");
free_context(context);
ret_val = -1;
} else {
token = strtok(NULL, " ");
while (token != NULL) {
if (!memcmp(token,"-id=", (sizeof("-id=")-1))) {
context->cxt_id = atoi(&token[sizeof("-id=") - 1]);
} else if (!memcmp(token,"-txdev=", (sizeof("-txdev=") - 1))) {
txdev = atoi(&token[sizeof("-txdev=") - 1]);
} else if (!memcmp(token,"-rxdev=", (sizeof("-rxdev=") - 1))) {
rxdev = atoi(&token[sizeof("-rxdev=") - 1]);
} else {
context->config.file_name = token;
}
token = strtok(NULL, " ");
}
context->type = AUDIOTEST_TEST_MOD_SWITCH_DEV;
context->config.private_data = (struct audio_pvt_data *) audio_data;
pthread_create( &context->thread, NULL,
switchdev_thread, (void*) context);
}
}
return ret_val;
}
int mastervol_read_params(void) {
struct audiotest_thread_context *context;
char *token;
int ret_val = 0;
if ((context = get_free_context()) == NULL) {
ret_val = -1;
} else {
struct audio_pvt_data *audio_data;
audio_data = (struct audio_pvt_data *) malloc(sizeof(struct audio_pvt_data));
if(!audio_data) {
printf("error allocating audio instance structure \n");
free_context(context);
ret_val = -1;
} else {
token = strtok(NULL, " ");
while (token != NULL) {
if (!memcmp(token,"-id=", (sizeof("-id=")-1))) {
context->cxt_id = atoi(&token[sizeof("-id=") - 1]);
} else if (!memcmp(token,"-volume=", (sizeof("-volume=") - 1))) {
volume = atoi(&token[sizeof("-volume=") - 1]);
} else {
context->config.file_name = token;
}
token = strtok(NULL, " ");
}
context->type = AUDIOTEST_TEST_MOD_MASTER_VOL;
context->config.private_data = (struct audio_pvt_data *) audio_data;
pthread_create( &context->thread, NULL,
mastervol_thread, (void*) context);
}
}
return ret_val;
}
int mastermute_read_params(void) {
struct audiotest_thread_context *context;
char *token;
int ret_val = 0;
if ((context = get_free_context()) == NULL) {
ret_val = -1;
} else {
struct audio_pvt_data *audio_data;
audio_data = (struct audio_pvt_data *) malloc(sizeof(struct audio_pvt_data));
if(!audio_data) {
printf("error allocating audio instance structure \n");
free_context(context);
ret_val = -1;
} else {
token = strtok(NULL, " ");
while (token != NULL) {
if (!memcmp(token,"-id=", (sizeof("-id=")-1))) {
context->cxt_id = atoi(&token[sizeof("-id=") - 1]);
} else if (!memcmp(token,"-mute=", (sizeof("-mute=") - 1))) {
mute = atoi(&token[sizeof("-mute=") - 1]);
} else {
context->config.file_name = token;
}
token = strtok(NULL, " ");
}
context->type = AUDIOTEST_TEST_MOD_MASTER_MUTE;
context->config.private_data = (struct audio_pvt_data *) audio_data;
pthread_create( &context->thread, NULL,
mastermute_thread, (void*) context);
}
}
return ret_val;
}
/*int switchdev_control_handler(void* private_data) {
int ret_val = 0;
char *token;
token = strtok(NULL, " ");
if ((private_data != NULL) &&
(token != NULL)) {
if(!memcmp(token,"-cmd=", (sizeof("-cmd=") -1))) {
token = &token[sizeof("-cmd=") - 1];
printf("%s: cmd %s\n", __FUNCTION__, token);
}
} else {
ret_val = -1;
}
return ret_val;
}*/
const char *switchdev_help_txt =
"Switch device: txdev rxdev \n\
echo \"switchdev -id=xxx -txdev=x -rxdev=x\" > /data/audio_test \n\
txdev = device no, rxdev = device no \n\
\t\tdevices:\n\
\t\t1 = handset mic\n\
\t\t2 = handset speaker\n\
\t\t3 = headset mic\n\
\t\t4 = headset speaker mono\n\
\t\t5 = headset speaker stereo\n\
\t\t6 = speaker phone mic\n\
\t\t7 = speaker phone mono\n\
\t\t8 = speaker phone stereo\n\
\t\t9 = bt sco mic\n\
\t\t10 = bt sco speaker\n\
\t\t11 = bt a2dp speaker\n\
\t\t12 = tty headset mic\n\
\t\t13 = tty headset speaker\n\
\t\t14 = tty HCO\n\
\t\t15 = tty VCO\n\
\t\t16 = headset mono plus speaker phone mono\n\
\t\t17 = headset mono plus speaker phone stereo\n\
\t\t18 = headset stereo plus speaker phone mono\n\
\t\t19 = headset stereo plus speaker phone stereo\n\
\t\t20 = headset stereo plus speaker stereo rx\n\
\t\t32 = i2s rx\n\
\t\t33 = i2s tx\n";
const char *mastervol_help_txt =
"Master volume: volume \n\
echo \"mastervol -id=xxx -volume=x \" > /data/audio_test \n\
volume = 0 to 5 \n ";
const char *mastermute_help_txt =
"Master mute: mute \n\
echo \"mastermute -id=xxx -mute=x \" > /data/audio_test \n\
mute = 0 or 1 \n ";
void switchdev_help_menu(void) {
printf("%s\n", switchdev_help_txt);
}
void mastervol_help_menu(void) {
printf("%s\n", mastervol_help_txt);
}
void mastermute_help_menu(void) {
printf("%s\n", mastermute_help_txt);
}

View File

@ -0,0 +1,316 @@
/* audiotest.c - native audio test server
*
* Based on native pcm test application platform/system/extras/sound/playwav.c
*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010, 2012 The Linux Foundation. All rights reserved.
*
* 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.
*/
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <linux/ioctl.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <signal.h>
#include <linux/msm_audio.h>
#include "audiotest_cases.h"
#include "audiotest_def.h"
#define AUDIOTEST_DEFAULT_ID 65523
const char *help_txt =
"After running audio_test without arguments, one can find audio_test file in /data or /tmp\n\
Test case is ran by writting a command string into this file\n\
Format of command string depends on the test case you intend to run\n\
Quit audio_test app: type echo \"quit\" > /data/audio_test\n\
If there are test cases still in executing stage, audio_test exits upon \n\
all test cases finishes. \n\
Audio_test app supports concurrency. If one wishes to issue playback \n\
control command to a particular test case(e.g play mp3), one must specify \n\
an id by giving argument -id=xxx (e.g 123 must be a number) so audio_test \n\
knows how to dispatch control command to a particular test case. \n\
Issue control command: echo \"control_cmd -id=xxx -cmd=xxx\" > /data/audio_test \n\
command can be pause, flush, and etc. \n\
Format of command string is test case specific. Run audio_test -format test_case \n\
to see the format of command string for the desired test case. \n";
char cmdstr[256];
volatile int g_terminate_early = 0;
#define AUDIOTEST_MAX_TH_CXT 10 /* Maximum number of thread context */
struct audiotest_thread_context thread_context[AUDIOTEST_MAX_TH_CXT];
pthread_mutex_t audiotest_mutex = PTHREAD_MUTEX_INITIALIZER;
struct audiotest_thread_context* get_free_context(void) {
unsigned char i;
struct audiotest_thread_context *ret_val = NULL;
pthread_mutex_lock(&audiotest_mutex);
for (i=0; i < AUDIOTEST_MAX_TH_CXT; i++) {
if (thread_context[i].used == false) {
thread_context[i].used = true;
ret_val = &thread_context[i];
break;
}
}
pthread_mutex_unlock(&audiotest_mutex);
if (i == AUDIOTEST_MAX_TH_CXT) {
fprintf(stderr, "%s : no free context struct\n", __FUNCTION__);
}
return ret_val;
}
void free_context(struct audiotest_thread_context *context) {
unsigned char i;
pthread_mutex_lock(&audiotest_mutex);
for (i=0; i < AUDIOTEST_MAX_TH_CXT; i++) {
if (&thread_context[i] == context) {
thread_context[i].used = false;
thread_context[i].cxt_id = AUDIOTEST_DEFAULT_ID;
thread_context[i].config.private_data = NULL;
break;
}
}
pthread_mutex_unlock(&audiotest_mutex);
}
struct audiotest_thread_context* find_context(int id) {
unsigned char i;
struct audiotest_thread_context *ret_val = NULL;
pthread_mutex_lock(&audiotest_mutex);
for (i=0; i < AUDIOTEST_MAX_TH_CXT; i++) {
if (thread_context[i].cxt_id == id) {
ret_val = &thread_context[i];
break;
}
}
pthread_mutex_unlock(&audiotest_mutex);
return ret_val;
}
void wait_child_threads(void) {
unsigned char i;
for (i=0; i < AUDIOTEST_MAX_TH_CXT; i++) {
if (thread_context[i].used == true)
pthread_join(thread_context[i].thread, NULL);
}
}
/* Index by test module ID */
pb_control_func audiotest_pb_controllers[AUDIOTEST_MAX_TEST_MOD] = {
pcm_play_control_handler, pcm_rec_control_handler,
mp3_play_control_handler, aac_play_control_handler,
aac_rec_control_handler, amrnb_play_control_handler,
amrnb_rec_control_handler, qcp_rec_control_handler,
NULL, NULL, NULL, atutest_control_handler,
NULL
};
int pb_control_read_params(void) {
char *token;
int ret_val = 0, id = 0;
struct audiotest_thread_context *context;
/* Look for ID and cmd */
token = strtok(NULL, " ");
if ((token != NULL) &&
(!memcmp(token,"-id=", (sizeof("-id=") -1)))) {
id = atoi(&token[sizeof("-id=") - 1]);
printf("Context id =%d\n", id);
if (((context = find_context(id)) != NULL) &&
(audiotest_pb_controllers[context->type] != NULL)) {
/* Call control function of test module */
ret_val = audiotest_pb_controllers[context->type](
context->config.private_data);
} else {
ret_val = -1;
}
} else {
ret_val = -1;
}
return ret_val;
}
struct audiotest_case_type {
const char *case_str;
case_hd_func case_hd;
case_help_menu help_menu;
case_deinit deinit;
};
struct audiotest_case_type audiotest_case_list[] = {
{ "playpcm", pcmplay_read_params, pcmplay_help_menu, NULL },
{ "recpcm", pcmrec_read_params, pcmrec_help_menu, NULL },
{ "playmp3", mp3play_read_params, mp3play_help_menu, NULL },
{ "playaac", aacplay_read_params, aacplay_help_menu, NULL },
{ "recaac", aacrec_read_params, aacrec_help_menu, NULL },
{ "playamrnb", amrnbplay_read_params, amrnbplay_help_menu, NULL },
{ "recamrnb", amrnbrec_read_params, amrnbrec_help_menu, NULL },
{ "recqcp", qcprec_read_params, qcprec_help_menu, NULL },
{ "switchdev", switchdev_read_params, switchdev_help_menu, NULL },
{ "mastervol", mastervol_read_params, mastervol_help_menu, NULL },
{ "mastermute", mastermute_read_params, mastermute_help_menu, NULL },
{ "playtone", atutest_read_params, atutest_help_menu, NULL },
{ "control_cmd", pb_control_read_params, NULL, NULL },
};
#define AUDIOTEST_MAX_NUM_CASES \
(sizeof(audiotest_case_list) / sizeof(struct audiotest_case_type))
void audiotest_case_deinit(void) {
unsigned char i;
for (i=0; i < AUDIOTEST_MAX_NUM_CASES; i++) {
if (audiotest_case_list[i].deinit != NULL) {
audiotest_case_list[i].deinit();
}
}
}
void audiotest_cmd_svr(void) {
const char *exit_str = "quit";
int fd;
ssize_t read_count;
char *token;
#ifdef AUDIOV2
int control = 0;
#endif
#ifdef _ANDROID_
if (mknod("/data/audio_test", S_IFIFO | 0666, 0) == 0) {
fd = open("/data/audio_test", O_RDONLY);
#else
if (mknod("/tmp/audio_test", S_IFIFO | 0666, 0) == 0) {
fd = open("/tmp/audio_test", O_RDONLY);
#endif
#if defined(TARGET_USES_QCOM_MM_AUDIO) && defined(AUDIOV2)
audiotest_init_devmgr();
#endif
while (1) {
cmdstr[0] = '\0';
read_count = read(fd, cmdstr, 255);
if (read_count == 0) {
/* end of stream */
sleep(2);
} else if (read_count < 0) {
fprintf(stderr, "audio_test: error reading cmd\n");
break;
} else {
cmdstr[read_count-1] = ' ';
cmdstr[read_count] = '\0'; /* make last byte
zero to terminate
sucessfully */
printf("%s\n", cmdstr);
token = strtok(cmdstr, " ");
if (!strcmp(token, exit_str)) {
break; /* given command to quit */
} else {
unsigned char i;
for (i=0; i < AUDIOTEST_MAX_NUM_CASES; i++) {
if ((!strcmp(token, audiotest_case_list[i].case_str)) &&
(audiotest_case_list[i].case_hd != NULL)) {
audiotest_case_list[i].case_hd();
break;
}
}
if (i == AUDIOTEST_MAX_NUM_CASES) {
fprintf(stderr, "audio_test: cmd not found\n");
}
}
}
};
printf("audio_test: exit server mode\n");
close(fd);
#ifdef _ANDROID_
remove("/data/audio_test");
#else
remove("/tmp/audio_test");
#endif
#if defined(TARGET_USES_QCOM_MM_AUDIO) && defined(AUDIOV2)
audiotest_deinit_devmgr();
#endif
wait_child_threads();
audiotest_case_deinit();
} else {
fprintf(stderr, "audio_test: Failed to create server\n");
}
}
void print_help_menu(void) {
unsigned char i;
printf("%s\n", help_txt);
printf("list of test cases:\n");
for (i=0; i < AUDIOTEST_MAX_NUM_CASES; i++) {
printf("%s\n", audiotest_case_list[i].case_str);
}
}
void printf_format_menu(char *case_name) {
unsigned char i;
for (i=0; i < AUDIOTEST_MAX_NUM_CASES; i++) {
if ((!strcmp(case_name, audiotest_case_list[i].case_str)) &&
(audiotest_case_list[i].help_menu != NULL)) {
audiotest_case_list[i].help_menu();
break;
}
}
if (i == AUDIOTEST_MAX_NUM_CASES) {
fprintf(stderr, "audio_test: test case does not exist\n");
}
}
int main(int argc, char **argv)
{
argc--;
argv++;
if (argc > 0) {
if (!strcmp(argv[0], "-help")) {
print_help_menu();
} else if ((!strcmp(argv[0], "-format")) &&
(argc > 1)) {
printf_format_menu(argv[1]);
}
} else {
unsigned int i;
for (i=0; i < AUDIOTEST_MAX_TH_CXT; i++) {
thread_context[i].used = false;
thread_context[i].cxt_id = AUDIOTEST_DEFAULT_ID;
}
audiotest_cmd_svr();
}
return 0;
}

View File

@ -0,0 +1,71 @@
/* audiotest_cases.h - native audio test application header
*
* Based on native pcm test application platform/system/extras/sound/playwav.c
*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010, The Linux Foundation. All rights reserved.
*
* 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.
*/
#ifndef AUDIOTEST_CASE_H
#define AUDIOTEST_CASE_H
/* Mp3 Test Module Interface Definition */
int mp3play_read_params(void);
int mp3_play_control_handler(void* private_data);
void mp3play_help_menu(void);
/* AMRNB Test Module Interface Definition */
int amrnbplay_read_params(void);
int amrnb_play_control_handler(void* private_data);
void amrnbplay_help_menu(void);
int amrnbrec_read_params(void);
int amrnb_rec_control_handler(void* private_data);
void amrnbrec_help_menu(void);
/* PCM Test Module Interface Definition */
int pcmplay_read_params(void);
int pcm_play_control_handler(void* private_data);
void pcmplay_help_menu(void);
int pcmrec_read_params(void);
int pcm_rec_control_handler(void* private_data);
void pcmrec_help_menu(void);
/* QCP Test Module Interface Definition */
int qcprec_read_params(void);
int qcp_rec_control_handler(void *private_data);
void qcprec_help_menu(void);
/* AAC Test Module Interface Definition */
int aacplay_read_params(void);
int aac_play_control_handler(void* private_data);
void aacplay_help_menu(void);
int aacrec_read_params(void);
int aac_rec_control_handler(void* private_data);
void aacrec_help_menu(void);
int switchdev_read_params(void);
void switchdev_help_menu(void);
int mastervol_read_params(void);
void mastervol_help_menu(void);
int mastermute_read_params(void);
void mastermute_help_menu(void);
/* ATUTEST Module Interface Definition */
int atutest_read_params(void);
int atutest_control_handler(void* private_data);
void atutest_help_menu(void);
#endif /* AUDIOTEST_CASE_H */

View File

@ -0,0 +1,112 @@
/* audiotest_def.h - native audio test application header
*
* Based on native pcm test application platform/system/extras/sound/playwav.c
*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010, The Linux Foundation. All rights reserved.
*
* 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.
*/
#ifndef AUDIOTEST_DEFS_H
#define AUDIOTEST_DEFS_H
#include <pthread.h>
#define AUDIOTEST_TEST_MOD_PCM_DEC 0
#define AUDIOTEST_TEST_MOD_PCM_ENC 1
#define AUDIOTEST_TEST_MOD_MP3_DEC 2
#define AUDIOTEST_TEST_MOD_AAC_DEC 3
#define AUDIOTEST_TEST_MOD_AAC_ENC 4
#define AUDIOTEST_TEST_MOD_AMRNB_DEC 5
#define AUDIOTEST_TEST_MOD_AMRNB_ENC 6
#define AUDIOTEST_TEST_MOD_QCP_ENC 7
#define AUDIOTEST_TEST_MOD_SWITCH_DEV 8
#define AUDIOTEST_TEST_MOD_MASTER_VOL 9
#define AUDIOTEST_TEST_MOD_MASTER_MUTE 10
#define AUDIOTEST_TEST_MOD_ATUTEST 11
/* If added new module, need to update this number */
#define AUDIOTEST_MAX_TEST_MOD 12
#define false 0
#define true (!false)
#define AUDIOTEST_DEFAULT_ID 65523
#define AUDIOTEST_MAX_TH_CXT 10 /* Maximum number of thread context */
extern volatile int g_terminate_early;
struct audtest_aac_config_type {
unsigned short format_type;
unsigned short sbr_flag;
unsigned short sbr_ps_flag;
};
union audtest_fmt_config_type {
struct audtest_aac_config_type aac;
};
struct audtest_config {
const char *file_name;
unsigned sample_rate;
unsigned short channel_mode;
unsigned short rec_codec_type; /* Recording type */
unsigned short rec_mode;
union audtest_fmt_config_type fmt_config;
void *private_data; /* given to individual test module
to store its private data */
};
struct audtest_qcp_config {
const char *file_name;
unsigned short cdma_rate;
unsigned short min_bit_rate;
unsigned short max_bit_rate;
unsigned short flags;
unsigned short rec_mode;
unsigned short format; /* 0 = evrc, 1 = qcelp */
};
struct audio_pvt_data {
int format;
int g_test_volume;
int g_test_equalizer;
int g_rec_timeout;
int g_rec_buf_size;
int g_play_buf_size;
};
struct audiotest_thread_context {
int cxt_id; /* specify by the client */
pthread_t thread;
struct audtest_config config;
unsigned char type;
unsigned int used;
};
/* Function prototype that each test module would
* provide for playback control commands */
typedef int (*pb_control_func)(void* private_data);
/* Function prototype that each test module would
provide for parsing of test case and paramter */
typedef int (*case_hd_func)(void);
typedef void (*case_help_menu)(void);
typedef void (*case_deinit)(void);
/* Thread context management functions */
struct audiotest_thread_context* get_free_context(void);
void free_context(struct audiotest_thread_context *context);
#endif /* AUDIOTEST_DEFS_H */

View File

@ -0,0 +1,174 @@
/* equalizer.c - native equalizer test application
*
* Based on native pcm test application platform/system/extras/sound/playwav.c
*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010, The Linux Foundation. All rights reserved.
*
* 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.
*/
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <linux/ioctl.h>
#include <linux/msm_audio.h>
#include "equalizer.h"
static struct adsp_audio_eq_cfg eq_cfg;
uint32_t band_count = 0;
uint16_t band_id = 0;
uint32_t centre_freq[MAX_PRESETS][MAX_BAND_COUNT]=
{{310,600,1000,3000,6000,0,0,0,0,0,0,0},
{60,170,310,3000,6000,12000,14000,0,0,0,0,0},
{60,170,310,600,1000,3000,6000,12000,0,0,0,0},
{60,170,310,600,1000,3000,6000,12000,14000,16000,0,0},
{310,600,1000,3000,6000,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0}};
uint32_t filter_type[MAX_PRESETS][MAX_BAND_COUNT]=
{{NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE},
{BASS_BOOST,BAND_BOOST,BAND_BOOST,BAND_CUT,BAND_CUT,BAND_CUT,TREBLE_CUT,NONE,NONE,NONE,NONE,NONE},
{BASS_BOOST,BAND_BOOST,BAND_BOOST,BAND_CUT,BAND_CUT,BAND_BOOST,BAND_BOOST,TREBLE_BOOST,NONE,NONE,NONE,NONE},
{BASS_CUT,BAND_BOOST,BAND_BOOST,BAND_BOOST,BAND_BOOST,BAND_BOOST,BAND_BOOST,BAND_BOOST,BAND_BOOST,TREBLE_BOOST,NONE,NONE},
{BAND_CUT,BAND_CUT,BAND_BOOST,BAND_BOOST,BAND_BOOST,NONE,NONE,NONE,NONE,NONE,NONE,NONE},
{NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE},
{NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE},
{NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE},
{NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE},
{NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE},
{NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE},
{NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE}};
int32_t filter_gain[MAX_PRESETS][MAX_BAND_COUNT] =
{{3,4,4,4,3,0,0,0,0,0,0,0},
{5,4,2,3,4,4,2,0,0,0,0,0},
{5,3,0,-3,-2,0,5,6,0,0,0,0},
{3,0,2,2,3,3,3,2,2,1,0,0},
{1,3,0,4,4,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0}};
int32_t q_factor[MAX_PRESETS][MAX_BAND_COUNT] =
{{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0}};
void set_pcm_eq_center_freq(uint32_t eq_center_freq, uint16_t eq_band_id)
{
eq_cfg.eq_bands[eq_band_id].center_freq_hz = eq_center_freq;
}
void set_pcm_eq_filter_gain(int32_t eq_filter_gain, uint16_t eq_band_id)
{
if ((eq_filter_gain >= FILTER_GAIN_MIN) || (eq_filter_gain <= FILTER_GAIN_MAX))
eq_cfg.eq_bands[eq_band_id].filter_gain = eq_filter_gain;
else
printf("invalid filter gain: %d\n", eq_filter_gain);
}
void set_pcm_eq_filter_type(uint32_t eq_filter_type, uint16_t eq_band_id)
{
switch (eq_filter_type)
{
case 0:
eq_cfg.eq_bands[eq_band_id].filter_type = BASS_BOOST;
break;
case 1:
eq_cfg.eq_bands[eq_band_id].filter_type = BASS_CUT;
break;
case 2:
eq_cfg.eq_bands[eq_band_id].filter_type = BAND_BOOST;
break;
case 3:
eq_cfg.eq_bands[eq_band_id].filter_type = BAND_CUT;
break;
case 4:
eq_cfg.eq_bands[eq_band_id].filter_type = TREBLE_BOOST;
break;
case 5:
eq_cfg.eq_bands[eq_band_id].filter_type = TREBLE_CUT;
break;
case 6:
eq_cfg.eq_bands[eq_band_id].filter_type = NONE;
break;
}
}
void set_pcm_eq_q_factor(int32_t eq_q_factor, uint16_t eq_band_id)
{
eq_cfg.eq_bands[eq_band_id].q_factor = eq_q_factor;
}
int set_pcm_default_eq_values(int fd, uint32_t band_value, int32_t i)
{
int rc = 0;
eq_cfg.enable = 1;
band_count = band_value;
if (band_count < MAX_BAND_COUNT)
{
eq_cfg.num_bands = band_count;
for (band_id = 0; band_id < band_count; band_id++)
{
set_pcm_eq_center_freq(centre_freq[i][band_id], band_id);
set_pcm_eq_filter_gain(filter_gain[i][band_id], band_id);
set_pcm_eq_filter_type(filter_type[i][band_id], band_id);
set_pcm_eq_q_factor(q_factor[i][band_id], band_id);
}
}
if (ioctl(fd, AUDIO_SET_EQ, &eq_cfg)) {
perror("could not set eq params");
rc = -1;
}
return rc;
}

View File

@ -0,0 +1,77 @@
/* equalizer.h - native equalizer test application header
*
* Based on native pcm test application platform/system/extras/sound/playwav.c
*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010, The Linux Foundation. All rights reserved.
*
* 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.
*/
#include <sys/ioctl.h>
#include <linux/ioctl.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#define BASS_BOOST 0
#define BASS_CUT 1
#define BAND_BOOST 2
#define BAND_CUT 3
#define TREBLE_BOOST 4
#define TREBLE_CUT 5
#define NONE 6
#define FILTER_GAIN_MAX 6
#define FILTER_GAIN_MIN -6
#define MAX_PRESETS 12
#define MAX_BAND_COUNT 12
#define PRESET_COUNT 5
#define BAND_CLUB 5
#define BAND_DANCE 7
#define BAND_TECHNO 8
#define BAND_LIVE 10
#define BAND_REGGAE 5
#define ADSP_AUDIO_MAX_EQ_BANDS 12
struct adsp_audio_eq_band {
/* The band index, 0 .. 11 */
uint16_t band_idx;
/* Filter band type */
uint32_t filter_type;
/* Filter band center frequency */
uint32_t center_freq_hz;
/* Filter band initial gain (dB) */
/* Range is +12 dB to -12 dB with 1dB increments. */
int32_t filter_gain;
/* Filter band quality factor expressed as q-8 number, */
/* i.e. fixed point number with q factor of 8, */
/* e.g. 3000/(2^8) */
int32_t q_factor;
} __attribute__ ((packed));
struct adsp_audio_eq_cfg {
uint32_t enable;
/* Number of consequtive bands specified */
uint32_t num_bands;
struct adsp_audio_eq_band eq_bands[ADSP_AUDIO_MAX_EQ_BANDS];
} __attribute__ ((packed));
int set_pcm_default_eq_values(int fd, uint32_t band_value, int32_t i);

View File

@ -0,0 +1,274 @@
/* mp3test.c - native MP3 test application
*
* Based on native pcm test application platform/system/extras/sound/playwav.c
*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010, The Linux Foundation. All rights reserved.
*
* 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <linux/ioctl.h>
#include <linux/msm_audio.h>
#include "audiotest_def.h"
static int initiate_play(struct audtest_config *clnt_config, unsigned rate, unsigned channels,
int (*fill)(void *buf, unsigned sz, void *cookie),
void *cookie)
{
struct msm_audio_config config;
struct audio_pvt_data *audio_data = (struct audio_pvt_data *) clnt_config->private_data;
// struct msm_audio_stats stats;
unsigned sz;
char buf[32768];
int afd;
int cntW=0;
int volume = 100;
afd = open("/dev/msm_mp3", O_RDWR);
if (afd < 0) {
perror("mp3_play: cannot open MP3 device");
return -1;
}
if (ioctl(afd, AUDIO_GET_CONFIG, &config)) {
perror("could not get config");
return -1;
}
config.channel_count = channels;
config.sample_rate = rate;
if (ioctl(afd, AUDIO_SET_CONFIG, &config)) {
perror("could not set config");
return -1;
}
sz = config.buffer_size;
printf("initiate_play: sz=%d, buffer_count=%d\n",sz,config.buffer_count);
if (sz > sizeof(buf)) {
fprintf(stderr,"too big\n");
return -1;
}
fprintf(stderr,"start\n");
ioctl(afd, AUDIO_START, 0);
for (;;) {
if (g_terminate_early) {
printf("cancelling...\n");
break;
}
#if 0
if (ioctl(afd, AUDIO_GET_STATS, &stats) == 0)
fprintf(stderr,"%10d\n", stats.out_bytes);
#endif
if (fill(buf, sz, cookie) < 0) {
printf(" fill return NON NULL, exit loop \n");
if(fsync(afd) < 0)
printf("fsync failed\n");
break;
}
if( audio_data->g_test_volume ) {
printf("volume = %d\n",volume);
if (ioctl(afd, AUDIO_SET_VOLUME, &volume)) {
perror("could not set volume");
}
volume -= 1;
if( volume <= 1 ) {
/* Loop around to max stream volume so volume change is audible. */
volume = 100;
}
}
if (write(afd, buf, sz) != sz) {
printf(" write return not equal to sz, exit loop\n");
break;
} else {
cntW++;
printf(" mp3_play: cntW=%d\n",cntW);
}
}
printf("end of play\n");
//done:
/* let audio finish playing before close */
sleep(3);
close(afd);
return 0;
}
/* http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
static char *next;
static unsigned avail;
static int fill_buffer(void *buf, unsigned sz, void *cookie)
{
unsigned cpy_size = (sz < avail?sz:avail);
printf("fill_buffer: avail=%d, next=%p\n",avail,next);
if (avail == 0) {
return -1;
}
memcpy(buf, next, cpy_size);
next += cpy_size;
avail -= cpy_size;
printf("fill_buffer: avail=%d, next=%p\n",avail,next);
return 0;
}
static void play_file(struct audtest_config *config, unsigned rate, unsigned channels,
int fd, unsigned count)
{
next = (char*)malloc(count);
printf(" play_file: count=%d,next=%s\n", count,next);
if (!next) {
fprintf(stderr,"could not allocate %d bytes\n", count);
return;
}
if (read(fd, next, count) != count) {
fprintf(stderr,"could not read %d bytes\n", count);
return;
}
avail = count;
initiate_play(config, rate, channels, fill_buffer, 0);
}
int mp3_play(struct audtest_config *config)
{
struct stat stat_buf;
int fd;
fd = open(config->file_name, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "playmp3: cannot open '%s'\n", config->file_name);
return -1;
}
(void) fstat(fd, &stat_buf);
play_file(config, 44100, 2, fd, stat_buf.st_size);
return 0;
}
static void audiotest_alarm_handler(int sig)
{
g_terminate_early = 1;
sleep(1);
}
void* playmp3_thread(void* arg) {
struct audiotest_thread_context *context =
(struct audiotest_thread_context*) arg;
int ret_val;
ret_val = mp3_play(&context->config);
free_context(context);
pthread_exit((void*) ret_val);
return NULL;
}
int mp3play_read_params(void) {
struct audiotest_thread_context *context;
struct itimerspec ts;
char *token;
int ret_val = 0;
printf("This option is not supported currently\n");
return -1;
if ((context = get_free_context()) == NULL) {
ret_val = -1;
} else {
context->config.file_name = "/data/test.mp3";
g_terminate_early = 0;
struct audio_pvt_data *audio_data;
audio_data = (struct audio_pvt_data *) malloc(sizeof(struct audio_pvt_data));
if(!audio_data) {
printf("error allocating audio instance structure \n");
free_context(context);
ret_val = -1;
} else {
token = strtok(NULL, " ");
while (token != NULL) {
if (!memcmp(token,"-id=", (sizeof("-id=")-1))) {
context->cxt_id = atoi(&token[sizeof("-id=") - 1]);
} else if (!memcmp(token,"-volume=", (sizeof("-volume=") - 1))) {
audio_data->g_test_volume = atoi(&token[sizeof("-volume=") - 1]);
} else if (!memcmp(token,"-timeout=", (sizeof("-timeout=") - 1))) {
audio_data->g_rec_timeout = atoi(&token[sizeof("-timeout=") - 1]);
memset(&ts, 0, sizeof(struct itimerspec));
printf("setting rec timeout to %d secs\n", audio_data->g_rec_timeout);
ts.it_value.tv_sec = audio_data->g_rec_timeout;
signal(SIGALRM, audiotest_alarm_handler);
setitimer(ITIMER_REAL, &ts, NULL);
} else {
context->config.file_name = token;
}
token = strtok(NULL, " ");
}
context->type = AUDIOTEST_TEST_MOD_MP3_DEC;
context->config.private_data = (struct audio_pvt_data *) audio_data;
pthread_create( &context->thread, NULL,
playmp3_thread, (void*) context);
}
}
return ret_val;
}
int mp3_play_control_handler(void* private_data) {
int /* drvfd ,*/ ret_val = 0;
char *token;
token = strtok(NULL, " ");
if ((private_data != NULL) &&
(token != NULL)) {
/* drvfd = (int) private_data */
if(!memcmp(token,"-cmd=", (sizeof("-cmd=") -1))) {
token = &token[sizeof("-id=") - 1];
printf("%s: cmd %s\n", __FUNCTION__, token);
}
} else {
ret_val = -1;
}
return ret_val;
}
const char *mp3play_help_txt =
"Play MP3 file: type \n\
echo \"playmp3 path_of_file -id=xxx -timeout=x -volume=x\" > /data/audio_test \n\
Volume = 0 (default, volume=100), 1 (test different volumes continuously) \n\
timeout = x (value in seconds) \n ";
void mp3play_help_menu(void) {
printf("%s\n", mp3play_help_txt);
}

View File

@ -0,0 +1,568 @@
/* pcmtest.c - native PCM test application
*
* Based on native pcm test application platform/system/extras/sound/playwav.c
*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010, The Linux Foundation. All rights reserved.
*
* 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <string.h>
#include <linux/ioctl.h>
#include <linux/msm_audio.h>
#include "audiotest_def.h"
#include "equalizer.h"
static int pcm_play(struct audtest_config *clnt_config, unsigned rate, unsigned channels,
int (*fill)(void *buf, unsigned sz, void *cookie),
void *cookie)
{
struct msm_audio_config config;
struct audio_pvt_data *audio_data = (struct audio_pvt_data *) clnt_config->private_data;
int sz;
char * buf;
int afd;
int cntW=0;
int volume = 100;
afd = open("/dev/msm_pcm_out", O_RDWR);
if (afd < 0) {
perror("pcm_play: cannot open audio device");
return -1;
}
if (ioctl(afd, AUDIO_GET_CONFIG, &config)) {
perror("could not get config");
return -1;
}
// config.buffer_size = g_play_buf_size;
config.channel_count = channels;
config.sample_rate = rate;
if (ioctl(afd, AUDIO_SET_CONFIG, &config)) {
perror("could not set config");
close(afd);
return -1;
}
buf = (char*) malloc(sizeof(char) * config.buffer_size);
if (buf == NULL) {
perror("fail to allocate buffer\n");
close(afd);
return -1;
}
sz = config.buffer_size;
printf("pcm_play: sz=%d, buffer_count=%d\n",sz,config.buffer_count);
ioctl(afd, AUDIO_START, 0);
for (;;) {
#if 0
if (ioctl(afd, AUDIO_GET_STATS, &stats) == 0)
fprintf(stderr,"%10d\n", stats.out_bytes);
#endif
if ((sz = fill(buf, config.buffer_size, cookie)) < 0) {
printf(" fill return NON NULL, exit loop \n");
//fsync(afd);
break;
}
if (g_terminate_early) {
printf("cancelling...\n");
break;
}
if( audio_data->g_test_volume ) {
printf("volume = %d\n",volume);
if (ioctl(afd, AUDIO_SET_VOLUME, &volume)) {
perror("could not set volume");
}
volume -= 1;
if( volume <= 1 ) {
// Loop around to max stream volume so volume change is audible.
volume = 100;
}
}
if( audio_data->g_test_equalizer ) {
if (cntW == 150) {
printf("********** club ***********\n");
set_pcm_default_eq_values(afd, BAND_CLUB, 0);
}
else if (cntW == 350) {
printf("********** dance ***********\n");
set_pcm_default_eq_values(afd, BAND_DANCE, 1);
}
else if (cntW == 575) {
printf("********** techno ***********\n");
set_pcm_default_eq_values(afd, BAND_TECHNO, 2);
}
else if (cntW == 700) {
printf("********** live ***********\n");
set_pcm_default_eq_values(afd, BAND_LIVE, 3);
}
else if (cntW == 825) {
printf("********** reggae ***********\n");
set_pcm_default_eq_values(afd, BAND_REGGAE, 4);
}
}
if (write(afd, buf, sz) != sz) {
printf(" write return not equal to sz, exit loop\n");
break;
} else {
cntW++;
printf(" pcm_play: cntW=%d\n",cntW);
}
}
printf("end of play\n");
/* let audio finish playing before close */
sleep(3);
close(afd);
return 0;
}
/* http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
#define ID_RIFF 0x46464952
#define ID_WAVE 0x45564157
#define ID_FMT 0x20746d66
#define ID_DATA 0x61746164
#define FORMAT_PCM 1
struct wav_header {
uint32_t riff_id;
uint32_t riff_sz;
uint32_t riff_fmt;
uint32_t fmt_id;
uint32_t fmt_sz;
uint16_t audio_format;
uint16_t num_channels;
uint32_t sample_rate;
uint32_t byte_rate; /* sample_rate * num_channels * bps / 8 */
uint16_t block_align; /* num_channels * bps / 8 */
uint16_t bits_per_sample;
uint32_t data_id;
uint32_t data_sz;
};
static int rec_stop;
static char *next;
static unsigned avail;
static int fill_buffer(void *buf, unsigned sz, void *cookie)
{
unsigned cpy_size = (sz < avail?sz:avail);
if (avail == 0)
return -1;
memcpy(buf, next, cpy_size);
next += cpy_size;
avail -= cpy_size;
return cpy_size;
}
static void play_file(struct audtest_config *config, unsigned rate, unsigned channels,
int fd, unsigned count)
{
next = (char*)malloc(count);
printf(" play_file: count=%d,next=%p\n", count,next);
if (!next) {
fprintf(stderr,"could not allocate %d bytes\n", count);
return;
}
if (read(fd, next, count) != count) {
fprintf(stderr,"could not read %d bytes\n", count);
return;
}
avail = count;
pcm_play(config, rate, channels, fill_buffer, 0);
}
int wav_play(struct audtest_config *config)
{
struct wav_header hdr;
int fd;
if (config == NULL) {
return -1;
}
fd = open(config->file_name, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "playwav: cannot open '%s'\n", config->file_name);
return -1;
}
if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
fprintf(stderr, "playwav: cannot read header\n");
return -1;
}
fprintf(stderr,"playwav: %d ch, %d hz, %d bit, %s\n",
hdr.num_channels, hdr.sample_rate, hdr.bits_per_sample,
hdr.audio_format == FORMAT_PCM ? "PCM" : "unknown");
if ((hdr.riff_id != ID_RIFF) ||
(hdr.riff_fmt != ID_WAVE) ||
(hdr.fmt_id != ID_FMT)) {
fprintf(stderr, "playwav: '%s' is not a riff/wave file\n", config->file_name);
return -1;
}
if ((hdr.audio_format != FORMAT_PCM) /*||
(hdr.fmt_sz != 16)*/) {
fprintf(stderr, "playwav: '%s' is not pcm format\n", config->file_name);
return -1;
}
if (hdr.bits_per_sample != 16) {
fprintf(stderr, "playwav: '%s' is not 16bit per sample\n", config->file_name);
return -1;
}
play_file(config, hdr.sample_rate, hdr.num_channels,
fd, hdr.data_sz);
return 0;
}
int wav_rec(struct audtest_config *config)
{
struct audio_pvt_data *audio_data = (struct audio_pvt_data *) config->private_data;
struct wav_header hdr;
unsigned char buf[10240];
struct msm_audio_config cfg;
struct msm_voicerec_mode voicerec_mode;
unsigned sz;
int fd, afd;
unsigned total = 0;
int read_size = 0;
hdr.riff_id = ID_RIFF;
hdr.riff_sz = 0;
hdr.riff_fmt = ID_WAVE;
hdr.fmt_id = ID_FMT;
hdr.fmt_sz = 16;
hdr.audio_format = FORMAT_PCM;
hdr.num_channels = 1;
hdr.sample_rate = config->sample_rate;
hdr.byte_rate = hdr.sample_rate * hdr.num_channels * 2;
hdr.block_align = hdr.num_channels * 2;
hdr.bits_per_sample = 16;
hdr.data_id = ID_DATA;
hdr.data_sz = 0;
voicerec_mode.rec_mode = config->rec_mode;
fd = open(config->file_name, O_CREAT | O_RDWR, 0666);
if (fd < 0) {
perror("cannot open output file");
return -1;
}
write(fd, &hdr, sizeof(hdr));
afd = open("/dev/msm_pcm_in", O_RDWR);
if (afd < 0) {
perror("cannot open msm_pcm_in");
close(fd);
return -1;
}
if (ioctl(afd, AUDIO_GET_CONFIG, &cfg)) {
perror("cannot read audio config");
goto fail;
}
cfg.buffer_size = audio_data->g_rec_buf_size;
sz = cfg.buffer_size;
fprintf(stderr,"buffer size %d\n", sz);
if (sz > sizeof(buf)) {
fprintf(stderr,"buffer size %d too large\n", sz);
goto fail;
}
else if (sz <= 0) {
fprintf(stderr,"buffer size %d too small\n", sz);
goto fail;
}
cfg.channel_count = hdr.num_channels;
cfg.sample_rate = hdr.sample_rate;
if (ioctl(afd, AUDIO_SET_CONFIG, &cfg)) {
perror("cannot write audio config");
goto fail;
}
if (ioctl(afd, AUDIO_SET_INCALL, &voicerec_mode)) {
perror("cannot set incall mode");
goto fail;
}
if (ioctl(afd, AUDIO_START, 0)) {
perror("cannot start audio");
goto fail;
}
fcntl(0, F_SETFL, O_NONBLOCK);
fprintf(stderr,"\n*** RECORDING * USE 'STOP' CONTROL COMMAND TO STOP***\n");
while (rec_stop!=1){
read_size = read(afd, buf, sz);
if (write(fd, buf, read_size) != read_size) {
perror("cannot write buffer");
goto fail;
}
total += read_size;
if (g_terminate_early) {
printf("done...\n");
break;
}
}
close(afd);
/* update lengths in header */
hdr.data_sz = total;
hdr.riff_sz = total + 8 + 16 + 8;
lseek(fd, 0, SEEK_SET);
write(fd, &hdr, sizeof(hdr));
close(fd);
return 0;
fail:
close(afd);
close(fd);
unlink(config->file_name);
return -1;
}
static void audiotest_alarm_handler(int sig)
{
g_terminate_early = 1;
sleep(1);
}
void* playpcm_thread(void* arg) {
struct audiotest_thread_context *context =
(struct audiotest_thread_context*) arg;
int ret_val;
ret_val = wav_play(&context->config);
free_context(context);
pthread_exit((void*) ret_val);
return NULL;
}
int pcmplay_read_params(void) {
struct audiotest_thread_context *context;
struct itimerspec ts;
char *token;
int ret_val = 0;
if ((context = get_free_context()) == NULL) {
ret_val = -1;
} else {
context->config.file_name = "/data/test.wav";
g_terminate_early = 0;
struct audio_pvt_data *audio_data;
audio_data = (struct audio_pvt_data *) malloc(sizeof(struct audio_pvt_data));
if(!audio_data) {
printf("error allocating audio instance structure \n");
free_context(context);
ret_val = -1;
} else {
audio_data->g_play_buf_size = 4096;
token = strtok(NULL, " ");
while (token != NULL) {
if (!memcmp(token,"-id=", (sizeof("-id=")-1))) {
context->cxt_id = atoi(&token[sizeof("-id=") - 1]);
} else if (!memcmp(token,"-eq=", (sizeof("-eq=") - 1))) {
audio_data->g_test_equalizer = atoi(&token[sizeof("-eq=") - 1]);
} else if (!memcmp(token,"-volume=", (sizeof("-volume=") - 1))) {
audio_data->g_test_volume = atoi(&token[sizeof("-volume=") - 1]);
} else if (!memcmp(token,"-playbufsize=", (sizeof("-playbufsize=") - 1))) {
audio_data->g_play_buf_size = atoi(&token[sizeof("-playbufsize=") - 1]);
} else if (!memcmp(token,"-timeout=", (sizeof("-timeout=") - 1))) {
audio_data->g_rec_timeout = atoi(&token[sizeof("-timeout=") - 1]);
memset(&ts, 0, sizeof(struct itimerspec));
printf("setting rec timeout to %d secs\n", audio_data->g_rec_timeout);
ts.it_value.tv_sec = audio_data->g_rec_timeout;
signal(SIGALRM, audiotest_alarm_handler);
setitimer(ITIMER_REAL, &ts, NULL);
} else {
context->config.file_name = token;
}
token = strtok(NULL, " ");
}
context->type = AUDIOTEST_TEST_MOD_PCM_DEC;
context->config.private_data = (struct audio_pvt_data *) audio_data;
pthread_create( &context->thread, NULL,
playpcm_thread, (void*) context);
}
}
return ret_val;
}
void* recpcm_thread(void* arg) {
struct audiotest_thread_context *context =
(struct audiotest_thread_context*) arg;
int ret_val;
ret_val = wav_rec(&context->config);
free_context(context);
pthread_exit((void*) ret_val);
return NULL;
}
int pcmrec_read_params(void) {
struct audiotest_thread_context *context;
struct itimerspec ts;
char *token;
int ret_val = 0;
if ((context = get_free_context()) == NULL) {
ret_val = -1;
} else {
context->config.sample_rate = 8000;
context->config.file_name = "/data/rec.wav";
context->config.rec_mode = 1;
context->type = AUDIOTEST_TEST_MOD_PCM_ENC;
g_terminate_early = 0;
struct audio_pvt_data *audio_data;
audio_data = (struct audio_pvt_data *) malloc(sizeof(struct audio_pvt_data));
if(!audio_data) {
printf("error allocating audio instance structure \n");
free_context(context);
ret_val = -1;
} else {
audio_data->g_rec_buf_size = 4096;
token = strtok(NULL, " ");
while (token != NULL) {
printf("%s \n", token);
if (!memcmp(token,"-rate=", (sizeof("-rate=") - 1))) {
context->config.sample_rate =
atoi(&token[sizeof("-rate=") - 1]);
} else if (!memcmp(token,"-rec_mode=", (sizeof("-rec_mode=") - 1))) {
context->config.rec_mode =
atoi(&token[sizeof("-rec_mode=") - 1]);
} else if (!memcmp(token,"-recbufsize=", (sizeof("-recbufsize=") - 1))) {
audio_data->g_rec_buf_size = atoi(&token[sizeof("-recbufsize=") - 1]);
} else if (!memcmp(token,"-id=", (sizeof("-id=") - 1))) {
context->cxt_id = atoi(&token[sizeof("-id=") - 1]);
} else if (!memcmp(token,"-timeout=", (sizeof("-timeout=") - 1))) {
audio_data->g_rec_timeout = atoi(&token[sizeof("-timeout=") - 1]);
memset(&ts, 0, sizeof(struct itimerspec));
printf("setting rec timeout to %d secs\n", audio_data->g_rec_timeout);
ts.it_value.tv_sec = audio_data->g_rec_timeout;
signal(SIGALRM, audiotest_alarm_handler);
setitimer(ITIMER_REAL, &ts, NULL);
} else {
context->config.file_name = token;
}
token = strtok(NULL, " ");
}
context->config.private_data = (struct audio_pvt_data *) audio_data;
printf("%s : sample_rate=%d rec_mode=%d\n",
__FUNCTION__, context->config.sample_rate,
context->config.rec_mode);
pthread_create( &context->thread, NULL, recpcm_thread, (void*) context);
}
}
return ret_val;
}
int pcm_play_control_handler(void* private_data) {
int /* drvfd ,*/ ret_val = 0;
char *token;
token = strtok(NULL, " ");
if ((private_data != NULL) &&
(token != NULL)) {
/* drvfd = (int) private_data */
if(!memcmp(token,"-cmd=", (sizeof("-cmd=") -1))) {
token = &token[sizeof("-id=") - 1];
printf("%s: cmd %s\n", __FUNCTION__, token);
}
} else {
ret_val = -1;
}
return ret_val;
}
int pcm_rec_control_handler(void* private_data) {
int /* drvfd ,*/ ret_val = 0;
char *token;
token = strtok(NULL, " ");
if ((private_data != NULL) &&
(token != NULL)) {
/* drvfd = (int) private_data */
if(!memcmp(token,"-cmd=", (sizeof("-cmd=") -1))) {
token = &token[sizeof("-cmd=") - 1];
printf("%s: cmd %s\n", __FUNCTION__, token);
if (!strcmp(token, "stop"))
printf("Rec stop command\n");
rec_stop = 1;
}
} else {
ret_val = -1;
}
return ret_val;
}
const char *pcmplay_help_txt =
"Play PCM file: type \n\
echo \"playpcm path_of_file -id=xxx -eq=x -timeout=x -playbufsize=xxx -volume=x\" > /data/audio_test \n\
sample rate: 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000 \n\
Equalizer (-eq) = 1 (enable) \n\
Volume = 0 (default, volume=100), 1 (test different volumes continuously) \n\
timeout = x (value in seconds) \n\
playbufsize = xxx (play buffer size value) \n\
Bits per sample = 16 bits \n ";
void pcmplay_help_menu(void) {
printf("%s\n", pcmplay_help_txt);
}
const char *pcmrec_help_txt =
"Record pcm file: type \n\
echo \"recpcm path_of_file -rate=xxx -rec_mode=x -id=xxx -timeout=x -recbufsize=xxx\" > tmp/audio_test \n\
sample rate: 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000 \n\
recbufsize = xxx (record buffer size value) \n\
timeout = x (value in seconds) \n\
record mode: 0=txonly 1=rxonly 2=mixed)\n ";
void pcmrec_help_menu(void) {
printf("%s\n", pcmrec_help_txt);
}

View File

@ -0,0 +1,393 @@
/* qcptest.c - native QCP test application
*
* Based on native pcm test application platform/system/extras/sound/playwav.c
*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010, The Linux Foundation. All rights reserved.
*
* 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <string.h>
#include <linux/ioctl.h>
#include <linux/msm_audio_qcp.h>
#include "audiotest_def.h"
struct qcp_header {
/* RIFF Section */
char riff[4];
unsigned int s_riff;
char qlcm[4];
/* Format chunk */
char fmt[4];
unsigned int s_fmt;
char mjr;
char mnr;
unsigned int data1; /* UNIQUE ID of the codec */
unsigned short data2;
unsigned short data3;
char data4[8];
unsigned short ver; /* Codec Info */
char name[80];
unsigned short abps; /* average bits per sec of the codec */
unsigned short bytes_per_pkt;
unsigned short samp_per_block;
unsigned short samp_per_sec;
unsigned short bits_per_samp;
unsigned char vr_num_of_rates; /* Rate Header fmt info */
unsigned char rvd1[3];
unsigned short vr_bytes_per_pkt[8];
unsigned int rvd2[5];
/* Vrat chunk */
unsigned char vrat[4];
unsigned int s_vrat;
unsigned int v_rate;
unsigned int size_in_pkts;
/* Data chunk */
unsigned char data[4];
unsigned int s_data;
} __attribute__ ((packed));
/* Common part */
static struct qcp_header append_header = {
{'R', 'I', 'F', 'F'}, 0, {'Q', 'L', 'C', 'M'}, /* Riff */
{'f', 'm', 't', ' '}, 150, 1, 0, 0, 0, 0,{0}, 0, {0},0,0,160,8000,16,0,{0},{0},{0}, /* Fmt */
{'v','r','a','t'}, 0, 0, 0, /* Vrat */
{'d','a','t','a'},0 /* Data */
};
#define QCP_HEADER_SIZE sizeof(struct qcp_header)
static int rec_stop;
static void create_qcp_header(int Datasize, int Frames, int Format)
{
append_header.s_riff = Datasize + QCP_HEADER_SIZE - 8;
if(!Format) {
append_header.data1 = 0xe689d48d;
append_header.data2 = 0x9076;
append_header.data3 = 0x46b5;
append_header.data4[0] = 0x91;
append_header.data4[1] = 0xef;
append_header.data4[2] = 0x73;
append_header.data4[3] = 0x6a;
append_header.data4[4] = 0x51;
append_header.data4[5] = 0x00;
append_header.data4[6] = 0xce;
append_header.data4[7] = 0xb4;
append_header.ver = 0x0001;
memcpy(append_header.name, "TIA IS-127 Enhanced Variable Rate Codec, Speech Service Option 3", 64);
append_header.abps = 9600;
append_header.bytes_per_pkt = 23;
append_header.vr_num_of_rates = 4;
append_header.vr_bytes_per_pkt[0] = 0x0416;
append_header.vr_bytes_per_pkt[1] = 0x030a;
append_header.vr_bytes_per_pkt[2] = 0x0200;
append_header.vr_bytes_per_pkt[3] = 0x0102;
append_header.s_vrat = 0x00000008;
append_header.v_rate = 0x00000001;
append_header.size_in_pkts = Frames;
append_header.s_data = Datasize;
}
else {
printf("QCELP 13K header\n");
append_header.data1 = 0x5E7F6D41;
append_header.data2 = 0xB115;
append_header.data3 = 0x11D0;
append_header.data4[0] = 0xBA;
append_header.data4[1] = 0x91;
append_header.data4[2] = 0x00;
append_header.data4[3] = 0x80;
append_header.data4[4] = 0x5F;
append_header.data4[5] = 0xB4;
append_header.data4[6] = 0xB9;
append_header.data4[7] = 0x7E;
append_header.ver = 0x0002;
memcpy(append_header.name, "Qcelp 13K", 9);
append_header.abps = 13000;
append_header.bytes_per_pkt = 35;
append_header.vr_num_of_rates = 5;
append_header.vr_bytes_per_pkt[0] = 0x0422;
append_header.vr_bytes_per_pkt[1] = 0x0310;
append_header.vr_bytes_per_pkt[2] = 0x0207;
append_header.vr_bytes_per_pkt[3] = 0x0103;
append_header.s_vrat = 0x00000008;
append_header.v_rate = 0x00000001;
append_header.size_in_pkts = Frames;
}
append_header.s_data = Datasize;
return;
}
int qcp_rec(struct audtest_config *config)
{
struct qcp_header hdr;
unsigned char buf[1024];
struct msm_audio_evrc_enc_config evrc_cfg;
struct msm_audio_qcelp_enc_config qcelp_cfg;
struct msm_audio_stream_config str_cfg;
struct msm_voicerec_mode voicerec_mode;
struct audio_pvt_data *audio_data = (struct audio_pvt_data *) config->private_data;
unsigned sz;
int fd, afd;
int total = 0;
int read_size = 0;
//voicerec_mode.rec_mode = config->rec_mode;
fd = open(config->file_name, O_CREAT | O_RDWR, 0666);
if (fd < 0) {
perror("cannot open output file");
return -1;
}
if(!audio_data->format) {
afd = open("/dev/msm_evrc_in", O_RDWR);
if (afd < 0) {
perror("cannot open msm_evrc_in");
close(fd);
return -1;
}
if (ioctl(afd, AUDIO_GET_STREAM_CONFIG, &str_cfg)) {
perror("cannot read audio stream config");
goto fail;
}
sz = 23;
fprintf(stderr,"buffer size %d\n", sz);
if (sz > sizeof(buf)) {
fprintf(stderr,"buffer size %d too large\n", sz);
goto fail;
}
str_cfg.buffer_size = sz;
str_cfg.buffer_count = 2;
if (ioctl(afd, AUDIO_SET_STREAM_CONFIG, &str_cfg)) {
perror("cannot write audio stream config");
goto fail;
}
if (ioctl(afd, AUDIO_GET_EVRC_ENC_CONFIG, &evrc_cfg)) {
perror("cannot read audio config");
goto fail;
}
evrc_cfg.cdma_rate = CDMA_RATE_FULL;
evrc_cfg.min_bit_rate = 4;
evrc_cfg.max_bit_rate = 4;
if (ioctl(afd, AUDIO_SET_EVRC_ENC_CONFIG, &evrc_cfg)) {
perror("cannot write audio config");
goto fail;
}
}
else {
afd = open("/dev/msm_qcelp_in", O_RDWR);
if (afd < 0) {
perror("cannot open msm_qcp_in");
close(fd);
return -1;
}
if (ioctl(afd, AUDIO_GET_STREAM_CONFIG, &str_cfg)) {
perror("cannot read audio stream config");
goto fail;
}
sz = 35;
fprintf(stderr,"buffer size %d\n", sz);
if (sz > sizeof(buf)) {
fprintf(stderr,"buffer size %d too large\n", sz);
goto fail;
}
str_cfg.buffer_size = sz;
str_cfg.buffer_count = 2;
if (ioctl(afd, AUDIO_SET_STREAM_CONFIG, &str_cfg)) {
perror("cannot write audio stream config");
goto fail;
}
if (ioctl(afd, AUDIO_GET_QCELP_ENC_CONFIG, &qcelp_cfg)) {
perror("cannot read audio config");
goto fail;
}
qcelp_cfg.cdma_rate = CDMA_RATE_FULL;
qcelp_cfg.min_bit_rate = 4;
qcelp_cfg.max_bit_rate = 4;
if (ioctl(afd, AUDIO_SET_QCELP_ENC_CONFIG, &qcelp_cfg)) {
perror("cannot write audio config");
goto fail;
}
}
voicerec_mode.rec_mode=2;
if (ioctl(afd, AUDIO_SET_INCALL, &voicerec_mode)) {
perror("cannot set incall mode");
goto fail;
}
if (ioctl(afd, AUDIO_START, 0)) {
perror("cannot start audio");
goto fail;
}
fcntl(0, F_SETFL, O_NONBLOCK);
fprintf(stderr,"\n*** RECORDING * USE 'STOP' CONTROL COMMAND TO STOP***\n");
lseek(fd, QCP_HEADER_SIZE, SEEK_SET);
rec_stop = 0;
while (rec_stop != 1) {
read_size = read(afd, buf, sz);
if (read_size <= 0) {
printf("cannot read buffer error code =0x%8x", read_size);
goto fail;
}
if (write(fd, buf, read_size) != read_size) {
perror("cannot write buffer");
goto fail;
}
total += read_size;
}
close(afd);
create_qcp_header(total, 1, audio_data->format);
lseek(fd, 0, SEEK_SET);
write(fd, (char *)&append_header, QCP_HEADER_SIZE);
close(fd);
return 0;
fail:
close(afd);
close(fd);
unlink(config->file_name);
return -1;
}
static void audiotest_alarm_handler(int sig)
{
g_terminate_early = 1;
sleep(1);
}
void* recqcp_thread(void* arg) {
struct audiotest_thread_context *context =
(struct audiotest_thread_context*) arg;
int ret_val;
ret_val = qcp_rec(&context->config);
free_context(context);
pthread_exit((void*) ret_val);
return NULL;
}
int qcprec_read_params(void) {
struct audiotest_thread_context *context;
struct itimerspec ts;
char *token;
int ret_val = 0;
if ((context = get_free_context()) == NULL) {
ret_val = -1;
} else {
context->config.file_name = "/data/rec.qcp";
context->config.rec_mode = 2;
context->type = AUDIOTEST_TEST_MOD_QCP_ENC;
g_terminate_early = 0;
struct audio_pvt_data *audio_data;
audio_data = (struct audio_pvt_data *) malloc(sizeof(struct audio_pvt_data));
if(!audio_data) {
printf("error allocating audio instance structure \n");
free_context(context);
ret_val = -1;
} else {
token = strtok(NULL, " ");
while (token != NULL) {
printf("%s \n", token);
if (!memcmp(token,"-rec_mode=", (sizeof("-rec_mode=") - 1))) {
context->config.rec_mode =
atoi(&token[sizeof("-rec_mode=") - 1]);
} else if (!memcmp(token,"-id=", (sizeof("-id=") - 1))) {
context->cxt_id = atoi(&token[sizeof("-id=") - 1]);
} else if (!memcmp(token,"-format=", (sizeof("-format=") - 1))) {
audio_data->format = atoi(&token[sizeof("-format=") - 1]);
} else if (!memcmp(token,"-timeout=", (sizeof("-timeout=") - 1))) {
audio_data->g_rec_timeout = atoi(&token[sizeof("-timeout=") - 1]);
memset(&ts, 0, sizeof(struct itimerspec));
printf("setting rec timeout to %d secs\n", audio_data->g_rec_timeout);
ts.it_value.tv_sec = audio_data->g_rec_timeout;
signal(SIGALRM, audiotest_alarm_handler);
setitimer(ITIMER_REAL, &ts, NULL);
} else {
context->config.file_name = token;
}
token = strtok(NULL, " ");
}
printf("%s : rec_mode=%d\n", __FUNCTION__, context->config.rec_mode);
context->config.private_data = (struct audio_pvt_data *) audio_data;
pthread_create(&context->thread, NULL, recqcp_thread, (void *) context);
}
}
return ret_val;
}
int qcp_rec_control_handler(void *private_data)
{
int /* drvfd ,*/ ret_val = 0;
char *token;
token = strtok(NULL, " ");
if ((private_data != NULL) &&
(token != NULL)) {
/* drvfd = (int) private_data */
if (!memcmp(token, "-cmd=", (sizeof("-cmd=")-1))) {
token = &token[sizeof("-cmd=") - 1];
printf("%s: cmd %s\n", __FUNCTION__, token);
if (!strcmp(token, "stop"))
printf("Rec stop command\n");
rec_stop = 1;
}
} else {
ret_val = -1;
}
return ret_val;
}
const char *qcprec_help_txt =
"Record qcp file: type \n\
echo \"recqcp path_of_file -format=x -rec_mode=x -id=xxx -timeout=x\" > /data/audio_test \n\
timeout = x (value in seconds) \n\
format = 0 (evrc) or 1 (qcelp) \n\
record mode: 0=txonly 1=rxonly 2=mixed)\n ";
void qcprec_help_menu(void)
{
printf("%s\n", qcprec_help_txt);
}