2013-01-18 9 views
8

Ich versuche, ein aufgezeichnetes Audio mit Nspeex zu kodieren und dann über das Internet zu übertragen und am anderen Ende zu dekodieren. Ich mache das alles in Windows Phone 7/8. Zum Codieren und Decodieren verwende ich folgenden Code. Aber während der Dekodierung bekomme ich das Ergebnis nicht richtig zurück, was ich wieder spielen kann. Kann mir jemand mit Codierung und Decodierung von Code bereitzustellen, die auf WP7/8 aufgezeichneten Audio läuft:Windows Phone Codierung und Decodierung von Audio mit NSpeex. Haben Sie Probleme mit der Dekodierung?

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; 

     } 

Antwort

0

Ich denke, Ihr Problem sein kann, dass Sie jedes Mal, wenn Sie wollen ein neues SpeexEncoder newing sind up-Audio kodieren. Sie sollten versuchen, dies zu einem Mitglied Ihrer Klasse zu machen und es erneut zu verwenden.

Ich schaute auf den Code für Nspeex Ich bemerkte, dass SpeexEncoderNbEncoder für die Schmalband verwendet. In dieser Klasse sieht es so aus, als ob es einen Verlauf einiger vorheriger Audiodaten behält, um die Codierung durchzuführen. Dies sollte bedeuten, dass die Ausgabe für verschiedene Encoder-Instanzen nicht zusammenpasst.

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; 

     ... 
Verwandte Themen