PCM 单双声道转换

 2023-09-05 阅读 67 评论 0

摘要:现有PCM数据,要进行如下转换, 对于16位采样的PCM来说, 单声道存储方式很好理解,一段连续内存,一个个int16_t排排站。以A表示一个int16_t,内存排列如下: AAAAAAAAAAAAAAA 双声道的话,L表示左声道,R表示右声道&

现有PCM数据,要进行如下转换,

对于16位采样的PCM来说,

单声道存储方式很好理解,一段连续内存,一个个int16_t排排站。以A表示一个int16_t,内存排列如下:

AAAAAAAAAAAAAAA

双声道的话,L表示左声道,R表示右声道,最常见的形式如下:

LRLRLRLRLRLRLRLR

也有LLLLLLLLRRRRRRRR这种排列的,比较少见,这里不做分析。

先定义一个宏作为通用代码:

#define COMBINE(l,r) (((int32_t)(l) + (r)) >> 1)

注意上述代码,考虑到两个int16_t相加容易造成数据溢出,所以先做类型转换。

1. 假设为44100Hz,16位采样,双声道;转换为44100Hz, 16位采样,单声道:

void stereo_2_mono(const int16_t *src_audio,int sapmples_per_channel, int16_t *dst_audio) {for (int i = 0; i < sapmples_per_channel; i++) {dst_audio[i] = COMBINE(src_audio[2*i], src_audio[2*i+1]);}
}

2. 假设为44100Hz,16位采样,单声道;转换为44100Hz, 16位采样,双声道:

void mono_2_stereo(const int16_t *src_audio,int sapmples_per_channel, int16_t *dst_audio) {for (int i = 0; i < sapmples_per_channel; i++) {dst_audio[2*i] = dst_audio[2*i+1] = src_audio[i]);}
}

3. 将两个单声道合并位一个双声道,均为44100Hz,16位采样:

void combine_2_stereo(const int16_t *main_audio,const int16_t *extn_audio,int sapmples_per_channel, int16_t *dst_audio) {for (int i = 0; i < sapmples_per_channel; i++) {// left channeldst_audio[2*i] = main_audio[i];// right channeldst_audio[2*i+1] = extn_audio[i];}
}

4. 将两个双声道合并位一个双声道,单左右声道分开,即左声道为声音A,右声道为声音B,均为44100Hz,16位采样:

合并调用下1和3的两个函数即可,若不想有过多的内存拷贝,可以合并如下:

void combine_2_stereo2(const int16_t *main_audio,const int16_t *extn_audio,int sapmples_per_channel, int16_t *dst_audio) {for (int i = 0; i < sapmples_per_channel; i++) {// left channeldst_audio[2*i] = COMBINE(main_audio[2*i], main_audio[2*i+1]);// right channeldst_audio[2*i+1] = COMBINE(extn_audio[2*i], extn_audio[2*i+1]);}
}

以上,作为记录和技术储备。

 

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/762.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息