Skip to content

Instantly share code, notes, and snippets.

@ogazitt
Created August 16, 2012 17:57
Show Gist options
  • Save ogazitt/3372119 to your computer and use it in GitHub Desktop.
Save ogazitt/3372119 to your computer and use it in GitHub Desktop.
Decoding a Speex stream
private Stream DecodeSpeexStream(Stream stream)
{
// Log function entrance
TraceLog.TraceFunction();
try
{
int totalEncoded = 0;
int totalDecoded = 0;
// decode all the speex-encoded chunks
// each chunk is laid out as follows:
// | 4-byte total chunk size | 4-byte encoded buffer size | <encoded-bytes> |
MemoryStream ms = new MemoryStream();
byte[] lenBytes = new byte[sizeof(int)];
// get the length prefix
int len = stream.Read(lenBytes, 0, lenBytes.Length);
// loop through all the chunks
while (len == lenBytes.Length)
{
// convert the length to an int
int count = BitConverter.ToInt32(lenBytes, 0);
byte[] speexBuffer = new byte[count];
totalEncoded += count + len;
// read the chunk
len = stream.Read(speexBuffer, 0, count);
if (len < count)
{
TraceLog.TraceError(String.Format("Corrupted speex stream: len {0}, count {1}", len, count));
return ms;
}
// get the size of the buffer that the encoder used
// we need that exact size in order to properly decode
// the size is the first four bytes of the speexBuffer
int inDataSize = BitConverter.ToInt32(speexBuffer, 0);
// decode the chunk (starting at an offset of sizeof(int))
short[] decodedFrame = new short[inDataSize];
var speexDecoder = new SpeexDecoder(BandMode.Wide);
count = speexDecoder.Decode(speexBuffer, sizeof(int), len - sizeof(int), decodedFrame, 0, false);
// copy to a byte array
byte[] decodedBuffer = new byte[2 * count];
for (int i = 0, bufIndex = 0; i < count; i++, bufIndex += 2)
{
byte[] frame = BitConverter.GetBytes(decodedFrame[i]);
frame.CopyTo(decodedBuffer, bufIndex);
}
// write decoded buffer to the memory stream
ms.Write(decodedBuffer, 0, 2 * count);
totalDecoded += 2 * count;
// get the next length prefix
len = stream.Read(lenBytes, 0, lenBytes.Length);
}
// Log decoding stats
TraceLog.TraceDetail(String.Format("Decoded {0} bytes into {1} bytes", totalEncoded, totalDecoded));
// reset and return the new memory stream
ms.Position = 0;
return ms;
}
catch (Exception ex)
{
TraceLog.TraceException("Corrupted speex stream", ex);
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment