2013-01-18 36 views
8

我试图使用Nspeex编码录制的音频,然后通过互联网传输并在另一端解码。我在Windows Phone 7/8中完成了这一切。编码和解码我使用下面的代码。但是在解码的时候,我没有正确地得到我能够再次玩的结果。任何人都可以向我提供编码和解码的代码运行在WP7/8录音:使用NSpeex的Windows Phone编码和解码音频。解码有问题吗?

private static Microphone mic = Microphone.Default; 

     private static byte[] EncodeSpeech(byte[] buf, int len) 
     { 
      BandMode mode = GetBandMode(mic.SampleRate); 
      SpeexEncoder encoder = new SpeexEncoder(mode); 

      // set encoding quality to lowest (which will generate the smallest size in the fastest time) 
      encoder.Quality = 1; 
      int inDataSize = len/2; 

      // convert to short array 
      short[] data = new short[inDataSize]; 
      int sampleIndex = 0; 
      for (int index = 0; index < len; index += 2, sampleIndex++) 
      { 
       data[sampleIndex] = BitConverter.ToInt16(buf, index); 
      } 

      // note: the number of samples per frame must be a multiple of encoder.FrameSize 
      inDataSize = inDataSize - inDataSize % encoder.FrameSize; 
      var encodedData = new byte[len]; 
      int encodedBytes = encoder.Encode(data, 0, inDataSize, encodedData, 0, len); 
      if (encodedBytes != 0) 
      { 
       // each chunk is laid out as follows: 
       // | 4-byte total chunk size | 4-byte encoded buffer size | <encoded-bytes> | 
       byte[] inDataSizeBuf = BitConverter.GetBytes(inDataSize); 
       byte[] sizeBuf = BitConverter.GetBytes(encodedBytes + inDataSizeBuf.Length); 
       byte[] returnBuf = new byte[encodedBytes + sizeBuf.Length + inDataSizeBuf.Length]; 
       sizeBuf.CopyTo(returnBuf, 0); 
       inDataSizeBuf.CopyTo(returnBuf, sizeBuf.Length); 
       Array.Copy(encodedData, 0, returnBuf, sizeBuf.Length + inDataSizeBuf.Length, encodedBytes); 
       return returnBuf; 
      } 
      else 
       return buf; 
     } 


     private byte[] DecodeSpeech(byte[] buf) 
     { 
      BandMode mode = GetBandMode(mic.SampleRate); 
      SpeexDecoder decoder = new SpeexDecoder(mode); 

      byte[] inDataSizeBuf = new byte[4]; 
      byte[] sizeBuf = new byte[4]; 
      byte[] encodedBuf = new byte[buf.Length - 8]; 
      Array.Copy(buf, 0, sizeBuf, 0, 4); 
      Array.Copy(buf, 4, inDataSizeBuf, 0, 4); 
      Array.Copy(buf, 8, encodedBuf, 0, buf.Length - 8); 

      int inDataSize = BitConverter.ToInt32(inDataSizeBuf, 0); 
      int size = BitConverter.ToInt32(sizeBuf, 0); 
      short[] decodedBuf = new short[inDataSize]; 
      int decodedSize = decoder.Decode(encodedBuf, 0, encodedBuf.Length, decodedBuf, 0, false); 

      byte[] returnBuf = new byte[inDataSize * 2]; 
      for (int index = 0; index < decodedBuf.Length; index++) 
      { 
       byte[] temp = BitConverter.GetBytes(decodedBuf[index]); 
       Array.Copy(temp, 0, returnBuf, index * 2, 2); 
      } 

      return returnBuf; 
     } 


     private static BandMode GetBandMode(int sampleRate) 
     { 

      if (sampleRate <= 8000) 

       return BandMode.Narrow; 

      if (sampleRate <= 16000) 

       return BandMode.Wide; 

      return BandMode.UltraWide; 

     } 

回答

0

我认为你的问题可能是,你是newing您想要对音频编码每一次新的SpeexEncoder。你应该尝试让你的班级成员重新使用它。

我看了Nspeex的代码我注意到SpeexEncoder对于窄带使用NbEncoder。在该类中,它看起来像保留了一些先前的音频数据的历史,以便执行编码。这应该意味着不同编码器实例的输出不会在一起。

private static Microphone mic = Microphone.Default; 
private static SpeexEncoder encoder = CreateEncoder(); 

    private static SpeexEncoder CreateEncoder() 
    { 
     BandMode mode = GetBandMode(mic.SampleRate); 
     SpeexEncoder encoder = new SpeexEncoder(mode); 

     // set encoding quality to lowest (which will generate the smallest size in the fastest time) 
     encoder.Quality = 1; 
     return encoder; 
    } 

    private static byte[] EncodeSpeech(byte[] buf, int len) 
    { 
     int inDataSize = len/2; 

     ...