2011-10-14 55 views
7

我使用Speex來編碼原始數據,但是在解碼數據後,音頻以更快的速度播放,因爲它使您聽起來像花栗鼠。我使用NSpeex和Silverlight 4Silverlight Speex以極快的速度播放

8kHz Sampling

編碼功能:

JSpeexEnc encoder = new JSpeexEnc(); 
    int rawDataSize = 0; 
    public byte[] EncodeAudio(byte[] rawData) 
    { 
     var encoder = new SpeexEncoder(BandMode.Narrow); 
     var inDataSize = rawData.Length/2; 
     var inData = new short[inDataSize]; 

     for (var index = 0; index < rawData.Length; index += 2) 
     { 
      inData[index/2] = BitConverter.ToInt16(rawData, index); 
     } 
     inDataSize = inDataSize - inDataSize % encoder.FrameSize; 

     var encodedData = new byte[rawData.Length]; 
     var encodedBytes = encoder.Encode(inData, 0, inDataSize, encodedData, 0, encodedData.Length); 

     byte[] encodedAudioData = null; 
     if (encodedBytes != 0) 
     { 
      encodedAudioData = new byte[encodedBytes]; 
      Array.Copy(encodedData, 0, encodedAudioData, 0, encodedBytes); 
     } 
     rawDataSize = inDataSize; // Count of encoded shorts, for debugging 
     return encodedAudioData; 
    } 

解碼功能:

SpeexDecoder decoder = new SpeexDecoder(BandMode.Narrow); 
    public byte[] Decode(byte[] encodedData) 
    { 
     try 
     { 
      short[] decodedFrame = new short[8000]; // should be the same number of samples as on the capturing side 
      int decoderBytes = decoder.Decode(encodedData, 0, encodedData.Length, decodedFrame, 0, false); 

      byte[] decodedData = new byte[encodedData.Length]; 
      byte[] decodedAudioData = null; 

      decodedAudioData = new byte[decoderBytes * 2]; 
      for (int shortIndex = 0, byteIndex = 0; byteIndex < decoderBytes; shortIndex++) 
      { 
       BitConverter.GetBytes(decodedFrame[shortIndex + byteIndex]).CopyTo(decodedAudioData, byteIndex * 2); 
       byteIndex++; 
      } 

      // todo: do something with the decoded data 
      return decodedAudioData; 
     } 
     catch (Exception ex) 
     { 
      ShowMessageBox(ex.Message.ToString()); 
      return null; 
     } 

    } 

播放音頻:

void PlayWave(byte[] PCMBytes) 
    { 
     byte[] decodedBuffer = Decode(PCMBytes); 
     MemoryStream ms_PCM = new MemoryStream(decodedBuffer); 
     MemoryStream ms_Wave = new MemoryStream(); 

     _pcm.SavePcmToWav(ms_PCM, ms_Wave, 16, 8000, 1); 

     WaveMediaStreamSource WaveStream = new WaveMediaStreamSource(ms_Wave); 
     mediaElement1.SetSource(WaveStream); 
     mediaElement1.Play(); 
    } 
+0

這並不是說清楚的問題是什麼。你能編輯你的問題嗎? – gioele

+0

您可以添加「SavePcmToWav」方法的源代碼嗎?如果由此產生的WAV文件以某種方式具有44.1kHz而不是8kHz的採樣率,則會產生花栗鼠聲音(這是音頻數據被快速播放)。 – MusiGenesis

回答

0

對不起,我遲遲沒有迴應,但我找出了問題所在。

在我的解碼函數中,我遍歷解碼的short數組,但我只將一半的字節複製到我的新的byte數組中。

它必須是這個樣子:

decodedAudioData = new byte[decoderBytes * 2]; 
for (int shortIndex = 0, byteIndex = 0; shortIndex < decodedFrame.Length; shortIndex++, byteIndex += 2) 
{ 
    byte[] temp = BitConverter.GetBytes(decodedFrame[shortIndex]); 
    decodedAudioData[byteIndex] = temp[0]; 
    decodedAudioData[byteIndex + 1] = temp[1]; 
}