124 lines
4.5 KiB
C#
124 lines
4.5 KiB
C#
|
/* Copyright (C) 2014 DaikonForge */
|
|||
|
|
|||
|
namespace DaikonForge.VoIP
|
|||
|
{
|
|||
|
using UnityEngine;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 定义音频采样的频率模式枚举
|
|||
|
/// </summary>
|
|||
|
public enum FrequencyMode
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// 窄频模式
|
|||
|
/// </summary>
|
|||
|
Narrow,
|
|||
|
/// <summary>
|
|||
|
/// 宽频模式
|
|||
|
/// </summary>
|
|||
|
Wide,
|
|||
|
/// <summary>
|
|||
|
/// 超宽频模式
|
|||
|
/// </summary>
|
|||
|
UltraWide
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 定义一个频率提供器接口,用于根据不同的频率模式提供对应的采样频率
|
|||
|
/// </summary>
|
|||
|
public interface IFrequencyProvider
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// 根据指定的频率模式获取对应的采样频率
|
|||
|
/// </summary>
|
|||
|
/// <param name="mode">频率模式</param>
|
|||
|
/// <returns>采样频率</returns>
|
|||
|
int GetFrequency(FrequencyMode mode);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 音频处理的工具类,包含音频重采样、增益调整、获取最大振幅等实用方法
|
|||
|
/// </summary>
|
|||
|
public class AudioUtils
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// 频率提供器实例,使用SpeexCodec中的频率提供器实现
|
|||
|
/// </summary>
|
|||
|
public static IFrequencyProvider FrequencyProvider = new SpeexCodec.FrequencyProvider();
|
|||
|
/// <summary>
|
|||
|
/// 临时存储音频采样数据的快速列表,用于音频重采样时的数据处理
|
|||
|
/// </summary>
|
|||
|
private static FastList<float> temp = new FastList<float>();
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 根据指定的频率模式获取对应的采样频率
|
|||
|
/// </summary>
|
|||
|
/// <param name="mode">频率模式</param>
|
|||
|
/// <returns>采样频率</returns>
|
|||
|
public static int GetFrequency(FrequencyMode mode)
|
|||
|
{
|
|||
|
return FrequencyProvider.GetFrequency(mode);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 对音频采样数据进行重采样,将其从旧的采样频率转换为新的采样频率
|
|||
|
/// </summary>
|
|||
|
/// <param name="samples">音频采样数据数组</param>
|
|||
|
/// <param name="oldFrequency">旧的采样频率</param>
|
|||
|
/// <param name="newFrequency">新的采样频率</param>
|
|||
|
public static void Resample(BigArray<float> samples, int oldFrequency, int newFrequency)
|
|||
|
{
|
|||
|
// 如果新旧采样频率相同,则无需进行重采样操作
|
|||
|
if (oldFrequency == newFrequency) return;
|
|||
|
|
|||
|
// 清空临时存储列表,为新的重采样数据做准备
|
|||
|
temp.Clear();
|
|||
|
// 计算新旧采样频率的比率,用于后续索引计算
|
|||
|
float ratio = (float)oldFrequency / (float)newFrequency;
|
|||
|
int outSample = 0;
|
|||
|
// 循环处理,直到超出原采样数据的长度
|
|||
|
while (true)
|
|||
|
{
|
|||
|
// 根据比率计算在原采样数据中的索引
|
|||
|
int inBufferIndex = (int)(outSample++ * ratio);
|
|||
|
if (inBufferIndex < samples.Length)
|
|||
|
// 如果索引在原采样数据长度范围内,则将对应的数据添加到临时列表中
|
|||
|
temp.Add(samples[inBufferIndex]);
|
|||
|
else
|
|||
|
// 超出原采样数据长度,退出循环
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// 调整采样数据数组的大小,使其与重采样后的数据长度一致
|
|||
|
samples.Resize(temp.Count);
|
|||
|
// 将临时列表中的重采样数据复制回采样数据数组中
|
|||
|
samples.CopyFrom(temp.Items, 0, 0, temp.Count * 4);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 对音频采样数据应用增益,即对每个采样值乘以增益系数
|
|||
|
/// </summary>
|
|||
|
/// <param name="samples">音频采样数据数组</param>
|
|||
|
/// <param name="gain">增益系数</param>
|
|||
|
public static void ApplyGain(float[] samples, float gain)
|
|||
|
{
|
|||
|
// 遍历每个采样值,乘以增益系数
|
|||
|
for (int i = 0; i < samples.Length; i++)
|
|||
|
samples[i] *= gain;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 获取音频采样数据中的最大振幅
|
|||
|
/// </summary>
|
|||
|
/// <param name="samples">音频采样数据数组</param>
|
|||
|
/// <returns>最大振幅</returns>
|
|||
|
public static float GetMaxAmplitude(float[] samples)
|
|||
|
{
|
|||
|
float max = 0f;
|
|||
|
// 遍历每个采样值,更新最大振幅
|
|||
|
for (int i = 0; i < samples.Length; i++)
|
|||
|
max = Mathf.Max(max, Mathf.Abs(samples[i]));
|
|||
|
return max;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|