如何增加原始音频字节的音量/幅度
Posted
技术标签:
【中文标题】如何增加原始音频字节的音量/幅度【英文标题】:How to increase volume/amplitude on raw audio bytes 【发布时间】:2016-04-01 12:09:45 【问题描述】:我正在处理电话原始电话声音和录音,我想在 .Net C# 项目中将它们标准化为某个音量级别。
声音是原始音频字节的集合(单声道无头 16 位有符号 PCM 音频 16000Hz)。
音频被分成 3200 字节 == 100 毫秒的块。
有什么建议可以提高音量/振幅以使声音更大吗?
我不知道是否需要添加一个常量或乘法值,或者是否需要每 1、2、3.... 字节执行一次?也许已经有一个开源解决方案?
【问题讨论】:
每两个字节是一个有符号的 16 位值。只需将 then 乘以某个固定常数即可避免溢出。 @RomanR。感谢您的评论。当我将两个字节转换为 Int16 并将它们乘以 10 并将其转换为两个字节时,我听到了声音,但它确实失真了。 我写过你应该注意溢出,乘以十可能会得到很多。尝试 1.1 让初学者见证该方法运行良好。 @RomanR。哦,作为乘数的 2 或 3 没有任何可听见的失真。但是分贝的增加并不明显。所以我(也许很快)认为它不起作用。我再试一次,谢谢回复。 @RomanR。感谢您的信息,我想通了。 【参考方案1】:回答我自己的问题(为他人)。
解决方案是将每个样本(当 16 位 PCM 为 2 个字节时)乘以一个常数值。
避免溢出\增加太多,您可以通过查找最高样本值来计算可以使用的最高常数值,并计算乘法因子以使其达到可能的最高样本值,在 16 位 PCM 情况下,即 32676 或其他值。
这是一个小例子:
public byte[] IncreaseDecibel(byte[] audioBuffer, float multiplier)
// Max range -32768 and 32767
var highestValue = GetHighestAbsoluteSample(audioBuffer);
var highestPosibleMultiplier = (float)Int16.MaxValue/highestValue; // Int16.MaxValue = 32767
if (multiplier > highestPosibleMultiplier)
multiplier = highestPosibleMultiplier;
for (var i = 0; i < audioBuffer.Length; i = i + 2)
Int16 sample = BitConverter.ToInt16(audioBuffer, i);
sample *= (Int16)(sample * multiplier);
byte[] sampleBytes = GetLittleEndianBytesFromShort(sample);
audioBuffer[i] = sampleBytes[sampleBytes.Length-2];
audioBuffer[i+1] = sampleBytes[sampleBytes.Length-1];
return audioBuffer;
// 添加了 GetHighestAbsoluteSample,希望它仍然正确,因为代码随着时间的推移发生了变化
/// <summary>
/// Peak sample value
/// </summary>
/// <param name="audioBuffer">audio</param>
/// <returns>0 - 32768</returns>
public static short GetHighestAbsoluteSample(byte[] audioBuffer)
Int16 highestAbsoluteValue = 0;
for (var i = 0; i < (audioBuffer.Length-1); i = i + 2)
Int16 sample = ByteConverter.GetShortFromLittleEndianBytes(audioBuffer, i);
// prevent Math.Abs overflow exception
if (sample == Int16.MinValue)
sample += 1;
var absoluteValue = Math.Abs(sample);
if (absoluteValue > highestAbsoluteValue)
highestAbsoluteValue = absoluteValue;
return (highestAbsoluteValue > LowestPossibleAmplitude) ?
highestAbsoluteValue : LowestPossibleAmplitude;
【讨论】:
感谢您的回答,我也在寻找您回答的解决方案,您能否使用完整代码编辑您的答案。我的意思是 GetHighestAbsoluteSample(audioBuffer) 方法。 @sebu 代码随着时间的推移发生了变化,但我认为添加的方法是您正在寻找的方法。 PS:注意以这种方式增加音量,因为它不一定是正确的,例如这不是语音到文本内容的好习惯以上是关于如何增加原始音频字节的音量/幅度的主要内容,如果未能解决你的问题,请参考以下文章