2011-10-14 5 views
7

Sto usando Speex per codificare i dati grezzi ma dopo decodificare i dati l'audio viene riprodotto a una velocità maggiore perché ti fa sembrare uno scoiattolo. Sto usando NSpeex e Silverlight 4.Silverlight Speex che gioca a una velocità elevata

8kHz Sampling

codifica Funzione:

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

decodifica Funzione:

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

    } 

Giocare l'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

Non è chiaro ciò che la domanda è. Potresti modificare la tua domanda? – gioele

+0

Puoi aggiungere il sorgente per il tuo metodo 'SavePcmToWav'? Se il file WAV risultante in qualche modo ha una frequenza di campionamento di 44.1kHz anziché di 8kHz, ciò produrrebbe il suono chipmunk (ovvero i dati audio riprodotti troppo velocemente). – MusiGenesis

risposta

0

Scusate ragazzi per la risposta in ritardo ma ho capito qual era il problema.

Dentro il mio ciclo funzione di decodifica I attraverso la decodificato short serie, ma sto solo copiare la metà dei byte nella mia nuova byte array.

Ha bisogno di essere simile a questa:

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