2011-10-14 12 views
7

Używam Speex do kodowania nieprzetworzonych danych, ale po dekodowaniu danych dźwięk jest odtwarzany z większą szybkością, ponieważ sprawia, że ​​brzmisz jak wiewiórka. Używam NSpeex i Silverlight 4.Silverlight Speex w szybkim tempie

8kHz Sampling

Kodowanie Funkcja:

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; 
    } 

Dekodowanie Funkcja:

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; 
     } 

    } 

Odtwarzanie audio:

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

to nie jest jasne, co jest pytanie. Czy możesz edytować swoje pytanie? – gioele

+0

Czy możesz dodać źródło dla metody 'SavePcmToWav'? Jeśli wynikowy plik WAV w jakiś sposób ma częstotliwość próbkowania 44,1 kHz zamiast 8 kHz, to wytworzyłby dźwięk chipmunk (który jest zbyt szybkim odtwarzaniem danych audio). – MusiGenesis

Odpowiedz

0

Przepraszam, chłopaki za spóźnioną reakcję, ale zorientowałem się, na czym polega problem.

Wewnątrz funkcji dekodowania przechodzę przez dekodowaną macierz short, ale ja tylko kopiuję połowę bajtów do mojej nowej tablicy byte.

To musi wyglądać następująco:

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]; 
} 
Powiązane problemy