namespace NSpeex
|
{
|
using System;
|
using System.Runtime.InteropServices;
|
|
public class SpeexDecoder
|
{
|
private readonly Bits bits = new Bits();
|
private float[] decodedData;
|
private readonly IDecoder decoder;
|
private readonly int frameSize;
|
private readonly int sampleRate;
|
|
public SpeexDecoder(BandMode mode, bool enhanced = true)
|
{
|
switch (mode)
|
{
|
case BandMode.Wide:
|
this.decoder = new SbDecoder(false);
|
this.sampleRate = 0x3e80;
|
break;
|
default:
|
this.decoder = new NbDecoder();
|
this.sampleRate = 0x1f40;
|
break;
|
}
|
this.decoder.PerceptualEnhancement = enhanced;
|
this.frameSize = this.decoder.FrameSize;
|
this.decodedData = new float[this.sampleRate * 2];
|
}
|
|
private static short ConvertToShort(float value)
|
{
|
if (value > 32767f)
|
{
|
value = 32767f;
|
}
|
else if (value < -32768f)
|
{
|
value = -32768f;
|
}
|
return (short)Math.Round((double)value);
|
}
|
|
public int Decode(byte[] inData, int inOffset, int inCount, short[] outData, int outOffset, bool lostFrame)
|
{
|
if (this.decodedData.Length < (outData.Length * 2))
|
{
|
this.decodedData = new float[outData.Length * 2];
|
}
|
if (lostFrame || (inData == null))
|
{
|
this.decoder.Decode(null, this.decodedData);
|
int index = 0;
|
while (index < this.frameSize)
|
{
|
outData[outOffset] = ConvertToShort(this.decodedData[index]);
|
index++;
|
outOffset++;
|
}
|
return this.frameSize;
|
}
|
this.bits.ReadFrom(inData, inOffset, inCount);
|
int num2 = 0;
|
while (this.decoder.Decode(this.bits, this.decodedData) == 0)
|
{
|
int num3 = 0;
|
while (num3 < this.frameSize)
|
{
|
outData[outOffset] = ConvertToShort(this.decodedData[num3]);
|
num3++;
|
outOffset++;
|
}
|
num2 += this.frameSize;
|
}
|
return num2;
|
}
|
|
}
|
}
|