之前使用的方法是用编译好的程序通过命令行转码,效率低了点。本次将SKP_SILK编译成动态库,通过c++接口调用。直接将sikl文件转码为wav格式的byte[]音频数据。可以直接保存即可。
c++ 接口
/// <summary>
/// Silks the decode.
/// </summary>
/// <param name="szAMR">silk文件路径</param>
/// <param name="pWave">接收转码后语音</param>
/// <param name="nMaxLen">接收转码语音长度</param>
/// <param name="nSampleRate">转码后的采样率</param>
/// <returns>返回实际转码后语音长度</returns>
[DllImport(@"Decoder.dll", EntryPoint = "Silk_decode", CallingConvention = CallingConvention.StdCall)]
internal static extern int Silk_decode(string szAMR, short[] pWave, int nMaxLen, int nSampleRate);
c#封装
/// <summary>
/// silk文件转wav
/// </summary>
/// <param name="szAMR">silk文件路径</param>
/// <returns></returns>
public byte[] SilkTransferBytes(string szAMR)
{
int sampleRate = 8000;
byte[] fileBytes = File.ReadAllBytes(szAMR);
int maxLength = fileBytes.Length; //转wav后的文件长度,主要来传入c++接口,申请临时内存空间。实际wav长度就是接口的返回值
short[] outBuffer = new short[maxLength*1000];
byte[] outputByte = null;
var result = SILKAPI.Silk_decode(szAMR, outBuffer, maxLength*1000, sampleRate);
if (result > 0)
{
outputByte = new byte[result * sizeof(short)];
Buffer.BlockCopy(outBuffer, 0, outputByte, 0, outputByte.Length);
}
else
{
Console.WriteLine($"SilkTransfer error;result:{result}");
}
return outputByte;
}
byte[]音频数据保存,引用了NAudio库的WaveFileWriter方法来保存
string outfile="outfile.wav";
WaveFileWriter fileWriter = new WaveFileWriter(outfile, new WaveFormat(8000, 16, 1));
fileWriter.Write(outputByte, 0, outputByte.Length);
fileWriter.Flush();
fileWriter.Dispose();
动态库下载:https://download.csdn.net/download/esiangchioa/11850788