预置条件:采样率:48kHz;通道:8通道;采样深度:16bit;帧长:256
1、获得8通道的两个通道数据时:
static int getTwoChannelsFromEightChannels(struct stream_in *in, void *buffer, size_t bytes)
{
int ret;
int i, j, rd_round, byte_cnt;
int size_in_short = bytes / 2;//因为数据采样深度为16bit所以需要对数据长度做减半处理 2= 16/8
char buf[bytes];
short tmp_buf[bytes];
short tmp_short1[size_in_short];
//short tmp_short2[size_in_short];
void *resam_buf;
byte_cnt = 0;
for (rd_round = 0; rd_round < 4; rd_round++) { //为满足缓存buffer的数据要求,这里选择循环4次
memset(buf, 0x00, bytes);
memset(tmp_buf, 0x00, bytes);
memset(tmp_short1, 0x00, size_in_short);
ret = pcm_read(in->pcm, buf, bytes);//4次从PCM流中读取数据,其中pcm_read为alsa的标准音频流读接口
if (ret) {
ALOGE("%s: pcm_read error %d", __func__, ret);
return ret;
}
memcpy((short *)tmp_buf, (short *)buf, bytes);
for (i = 0, j = 0; i < size_in_short; i++) {
if (i % 8 == 2 || i % 8 == 3) {
tmp_short1[j] = tmp_buf[i];
j++;
}
}
memcpy((char *)buffer + byte_cnt, (char *)tmp_short1, j * 2);
byte_cnt += j * 2;
}
return 0;
}
2、获得8通道数据中的1路数据:
static int getOneChannelFromEightChannels(struct stream_in *in, void *buffer, size_t bytes)
{
int ret;
int i, j, rd_round, byte_cnt;
int size_in_short = bytes / 2;
char buf[bytes];
short tmp_buf[bytes];
short tmp_short1[size_in_short];
//short tmp_short2[size_in_short];
byte_cnt = 0;
for (rd_round = 0; rd_round < 8; rd_round++) {
memset(buf, 0x00, bytes);
memset(tmp_buf, 0x00, bytes);
memset(tmp_short1, 0x00, size_in_short);
ret = pcm_read(in->pcm, buf, bytes);
if (ret) {
ALOGE("%s: pcm_read error %d", __func__, ret);
return ret;
}
memcpy((short *)tmp_buf, (short *)buf, bytes);
for (i = 0, j = 0; i < size_in_short; i++) {
if (i % 8 == 0) {
//tmp_short1[j] = tmp_buf[i];
tmp_short1[j] = timesn_volume(tmp_buf[i]);
j++;
}
}
memcpy((char *)buffer + byte_cnt, (char *)tmp_short1, j * 2);
byte_cnt += j * 2;
//ALOGE("%s: rd_round = %d, j = %d, byte_cnt = %d", __func__, rd_round, j, byte_cnt);
}
return 0;
}
3、如果在音频处理中遇到采样率改变的时候:
static int resampleOneChannelsFrom8Channels(struct stream_in *in, void *buffer,size_t bytes)
{
int ret;
int i, m, s,rd_round, byte_cnt_m,byte_cnt_s,byte_cnt_b;
int size_in_short = bytes / 2;
char buf[bytes];
short tmp_buf[bytes];
short tmp_short1[size_in_short];
short tmp_short2[size_in_short];
short tmp_short3[bytes];
ALOGE("resample1channelfrom8channel == %d bytes == %d", size_in_short,bytes);
byte_cnt_m = 0;
byte_cnt_s = 0;
byte_cnt_b = 0;
for (rd_round = 0; rd_round < 24; rd_round++) {//由于将采样率重48KHZ->16KHZ同时从8通道变成1通道,故需要进行24循环处理
memset(buf, 0x00, bytes);
memset(tmp_buf, 0x00, bytes);
memset(tmp_short1, 0x00, size_in_short);
memset(tmp_short2, 0x00, size_in_short);
memset(tmp_short3, 0x00, bytes);
ret = pcm_read(in->pcm, buf, bytes);
if (ret) {
ALOGE("%s: pcm_read error %d", __func__, ret);
return ret;
}
#if 1
memcpy((short *)tmp_buf, (short *)buf, bytes);
for (i = 0, m = 0, s = 0; i < size_in_short; i++) {
if (i % 8 == 2) {
tmp_short1[m] = tmp_buf[i];
m++;
}
}
unsigned int inlen = bytes/16;
unsigned int outlen = bytes/8;
speex_resampler_process_int(in->dev->resampler_mic,0, (const spx_int16_t *)tmp_short1, &inlen,(short*)in->buffer_mic_16k, &outlen );//调用speex做单通道音频重采样处理48KHZ->16KHZ
byte_cnt_m += m * 2;
#else
for (i = 0; i < bytes; i++) {
if (i % 16 == 8 || i % 16 == 9 || i % 16 == 10 || i % 16 == 11) {
*((char *)buffer + byte_cnt) = buf[i];
byte_cnt++;
}
}
#endif
//ALOGE("%s: rd_round = %d, j = %d, byte_cnt = %d", __func__, rd_round, j, byte_cnt);
}
return 0;
}
4、单通道数据变换成双通道数据处理方式:
static int selectresultTwochannel(void *buffer, size_t bytes,void *buffer_aec)
{
int ret;
int i,j;
int size_in_short = bytes / 2;
short *bufferByshort = (short*)buffer_aec;//buffer_aec为一个全局buffer变量
short *bufferByshort1 = (short*)buffer;
for (i = 0; i < size_in_short; i++) {
bufferByshort[2*i] =bufferByshort1[i];
bufferByshort[2*i+1] =bufferByshort1[i];
}
//ALOGE("selectresultchannel() channel =%d to buffer",channel);
return 0;
}
5、对音量进行简单增益处理:
static short volume = 4;
static void volume_process(const void *buffer, size_t length, short volume)
{
short *buffer_end = (short *)buffer + length / 2;
short *pcmData = (short *)buffer;
int pcmval;
while (pcmData < buffer_end) {
pcmval = (short)*pcmData * volume;
if (pcmval < 32768 && pcmval > -32768) {
*pcmData = pcmval;
} else if (pcmval > 32767) {
*pcmData = 32767;
} else if (pcmval < -32767) {
*pcmData = -32767;
}
++pcmData;
}
}