2013-01-18 72 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; 

     ...