2013-01-18 19 views
8

Tôi đang cố mã hóa âm thanh đã ghi bằng Nspeex rồi chuyển nó qua internet và giải mã ở đầu kia. Tôi đang làm tất cả điều này trong Windows Phone 7/8. Để mã hóa và giải mã, tôi đang sử dụng mã sau đây. Nhưng trong khi giải mã tôi không nhận được kết quả một cách chính xác mà tôi có thể chơi một lần nữa. bất cứ ai có thể cung cấp cho tôi với mã hóa và mã giải mã mà chạy trên âm thanh WP7/8 ghi:Mã hóa điện thoại Windows và giải mã âm thanh bằng NSpeex. Có vấn đề với giải mã?

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; 

     } 

Trả lời

0

Tôi nghĩ vấn đề của bạn có thể là bạn đang newing lên một SpeexEncoder mới mỗi khi bạn muốn để mã hóa âm thanh. Bạn nên thử làm cho một thành viên cho lớp của bạn và tái sử dụng nó.

Tôi đã xem mã cho Nspeex Tôi nhận thấy rằng SpeexEncoder sử dụng NbEncoder cho dải hẹp. Trong lớp đó có vẻ như nó giữ một lịch sử của một số dữ liệu âm thanh trước đó để thực hiện mã hóa. Điều này có nghĩa là đầu ra cho các bộ mã hóa khác nhau sẽ không đi cùng nhau.

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; 

     ... 
Các vấn đề liên quan