2013-01-18 9 views
8

Nspeex kullanarak kaydedilmiş bir sesi kodlamaya çalışıyorum ve daha sonra internet üzerinden aktarmaya ve diğer ucun kodunu çözmeye çalışıyorum. Windows Phone 7/8'de tüm bunları yapıyorum. Kodlamak ve kodunu çözmek için aşağıdaki kodu kullanıyorum. Ancak, kod çözme sırasında sonucu tekrar oynayamayacağım sonucu geri almıyorum. Herkes WP7/8 kaydedilmiş ses üzerinde çalışan kodlama ve kod çözme kodu ile beni sağlayabilir:Windows Phone NSpeex kullanarak ses kodlama ve kod çözme. Kod çözme ile ilgili sorun mu yaşıyorsunuz?

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; 

     } 

cevap

0

Ben senin sorunun yeni bir SpeexEncoder Sesi kodlamak istediğiniz her zaman yukarıya newing olduklarını olabilir düşünüyorum. Bunu dersiniz için bir üye yapmaya çalışmalı ve tekrar kullanmalısınız.

Nspeex koduna baktım. SpeexEncoder'un dar bant için NbEncoder kullandığını fark ettim. Bu sınıfta, kodlamayı gerçekleştirmek için önceki bazı ses verilerinin geçmişini tutar gibi görünüyor. Bu, kodlayıcıların farklı örneklerinin çıktısının birlikte gitmeyeceği anlamına gelmelidir.

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; 

     ...