2025-06-07 17:43:34 +08:00

124 lines
4.5 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 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;
}
}
}