124 lines
4.5 KiB
C#
Raw Permalink Normal View History

2025-06-07 17:43:34 +08:00
/* 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;
}
}
}