如何转换音频数据格式1

news/2024/10/19 3:26:24/

原文在此:http://www.codeproject.com/Articles/501521/How-to-convert-between-most-audio-formats-in-NET


前面的音频处理背景知识就先跳过,需要的请自行脑补。

直接上干货。

一、声道转换

1、单声道转立体声

原理,双声道的16位采样,每16位是一个声道,也就是两字节;下一个16位是另外一个声道,交错进行。

private byte[] MonoToStereo(byte[] input)
{byte[] output = new byte[input.Length * 2];int outputIndex = 0;for (int n = 0; n < input.Length; n+=2){// copy in the first 16 bit sampleoutput[outputIndex++] = input[n];output[outputIndex++] = input[n+1];// now copy it in againoutput[outputIndex++] = input[n];output[outputIndex++] = input[n+1];        }return output;
}

2、立体声转单声道

原理,去掉一半的数据即可。

private byte[] StereoToMono(byte[] input)
{byte[] output = new byte[input.Length / 2];int outputIndex = 0;for (int n = 0; n < input.Length; n+=4){// copy in the first 16 bit sampleoutput[outputIndex++] = input[n];output[outputIndex++] = input[n+1];}return output;
}

3、混合立体声转单声道

如果是混合立体声,则可以把左右声道的数据求平均,得到单声道的值

private byte[] MixStereoToMono(byte[] input)
{byte[] output = new byte[input.Length / 2];int outputIndex = 0;for (int n = 0; n < input.Length; n+=4){int leftChannel = BitConverter.ToInt16(input,n);int rightChannel = BitConverter.ToInt16(input,n+2);int mixed = (leftChannel + rightChannel) / 2;byte[] outSample = BitConverter.GetBytes((short)mixed);// copy in the first 16 bit sampleoutput[outputIndex++] = outSample[0];output[outputIndex++] = outSample[1];}return output;
}

二、位宽转换

4、16位转32位float

相对简单,把每个16bit(两个byte,合成一个short)除以16位的最大值,得到一个相对的float值(介于0-1之间)。

public float[] Convert16BitToFloat(byte[] input)
{int inputSamples = input.Length / 2; // 16 bit input, so 2 bytes per samplefloat[] output = new float[inputSamples];int outputIndex = 0;for(int n = 0; n < inputSamples; n++){short sample = BitConverter.ToInt16(input,n*2);output[outputIndex++] = sample / 32768f;}return output;
}

5、24位转32位float

这个就稍微麻烦了,从原数据中每次取24位,即3个byte,补上一个0,折合成一个int,然后除以3个byte组成的数据最大值,得到一个相对float值(介于0-1之间)。

public float[] Convert24BitToFloat(byte[] input)
{int inputSamples = input.Length / 3; // 24 bit inputfloat[] output = new float[inputSamples];int outputIndex = 0;var temp = new byte[4];for(int n = 0; n < inputSamples; n++){// copy 3 bytes inArray.Copy(input,n*3,temp,0,3);int sample = BitConverter.ToInt32(temp,0);output[outputIndex++] = sample / 16777216f;}return output;
}
这种方式其实也相当于把3个采样点,线性拟合变成了2个了。

6、还原数据

两种方式还原的代码一样(后一种多的一个点信息已经丢失,还原也只有2个byte了):

for (int sample = 0; sample < sourceSamples; sample++)
{// adjust volumefloat sample32 = sourceBuffer[sample] * volume;// clipif (sample32 > 1.0f)sample32 = 1.0f;if (sample32 < -1.0f)sample32 = -1.0f;destBuffer[destOffset++] = (short)(sample32 * 32767);
}

三、重采样

采样是这个文章中比较复杂的部分。

=================== 占坑,以后讲原理====================

7、一个简单的重采样算法

原理就是,拉大或缩小采样点的间距。当然,明显的是,如果如果新采样率大于旧的,其实没有意义,造成很多点只会简单重复。

新采样率小于旧的,就会在现有的点上,等比例往后拉。

// Just about worst resampling algorithm possible:
private float[] ResampleNaive(float[] inBuffer, int inputSampleRate, int outputSampleRate)
{var outBuffer = new List<float>();double ratio = (double) inputSampleRate / outputSampleRate;int outSample = 0;while (true){int inBufferIndex = (int)(outSample++ * ratio);if (inBufferIndex < read)writer.WriteSample(inBuffer[inBufferIndex]);elsebreak;    } return outBuffer.ToArray();    
}

========== 留坑,讲重采样的测试==========


下一部分,音频文件格式的转换








http://www.ppmy.cn/news/375917.html

相关文章

音频格式及转换代码

音频信号的读写、播放及录音 python已经支持WAV格式的书写&#xff0c;而实时的声音输入输出需要安装pyAudio(http://people.csail.mit.edu/hubert/pyaudio)。最后我们还将使用pyMedia(http://pymedia.org)进行Mp3的解码和播放。 音频信号是模拟信号&#xff0c;我们需要将其…

如何转换音频格式mp3,可以免费音频格式转换的软件

不知小伙伴们有没有遇到过这种情况呢&#xff0c;从网上或别人那里下载来一首歌&#xff0c;想要播放却被提示该音频格式不支持播放。其实这是因为有些音频格式比较少见&#xff0c;播放器无法兼容识别&#xff0c;这时就需要把音频格式转换为我们最常用的mp3了。那如何转换音频…

音频如何转换格式?手把手教你如何转换

一般常接触音频处理的小伙伴都知道&#xff0c;音频文件同文档一样拥有非常多种不同的格式&#xff0c;每种格式各有各的有点。但是&#xff0c;当我们需要使用其中某种格式的时候&#xff0c;要怎么将音频格式进行转换呢&#xff1f;今天&#xff0c;就教大家几种简单快速的方…

音频转换通项目案例简单过程分享

文章目录 音频通转换 1、要求 2、BUG分享 3、问题 4、总结 5、二轮测试 6、音屏转换通项目收获 音频通转换 1、要求 测试音频转换通软件&#xff0c;采用尽可能的测试方法去测试软件&#xff0c;找出更多的缺陷不少于10条缺陷把缺陷记录下来&#xff0c;记录到本地文件…

springCloud 中,openFeign 使用说明

文章目录 1、openFeign 中的每个方法中的参数和注解不能少。2、开启日志打印功能3、超时 1、openFeign 中的每个方法中的参数和注解不能少。 如果服务端方法中的数据含有注解&#xff0c;则 客户端 openFeign 中的每个方法中的参数和注解一个不能少&#xff0c;比较完全一致。…

模拟电话交换机和IPPBX之间进行连接

模拟电话交换马机&#xff0c;也最就原来老型号的机器&#xff0c;它们使用的信号是模拟信号&#xff0c;也就是普通的RJ11的电话机&#xff0c;如果公司新增加了一台IPPBX那么可以在节省成本的情况下&#xff0c;让模拟和网络互联&#xff0c;这样就可以让原来的电话机和交换机…

电话交换机tdmx2000dx硬件配置说明

威谱电话交换机TDMX2000DX硬件配置指南 TDMx-2000 型DX 系列电话交换机增强型主机DXM 基本配置4 外线24 分机&#xff0c;4 路数字话机&#xff0c;20 个通用扩展槽位&#xff0c;最大194 端口&#xff08;DXM主机基本配置为4 外线8 分机2 路数字话机&#xff0c;最大10 个通用…

CSPS服务器电源转ATX 抄作业(KICAD7.0)

抄作业对象&#xff1a; 1. KCORES&#xff0c;github 2. Harry_2005&#xff0c;oshwhub.com 3. 炽羽渡尘&#xff0c;oshwhub.com 纯抄作业&#xff0c;不过还是追求最佳布局布线&#xff0c;实现更大的通流能力。从立创EDA又回到了起初KCORES用的KICAD。参考了Harry_200…