Decode error: IndexOutOfRangeException

Oct 12, 2011 at 2:17 PM
Edited Oct 12, 2011 at 2:44 PM

I'm using NSpeex Encoder/Decoder but I keep getting IndexOutOfRangeException when trying to decode.

Starting up Audio:

 

        private void StartUpAudio() 
        {
            _sink = new MemoryAudioSink();

            //_source in query
            var query = from format in _capture.AudioCaptureDevice.SupportedFormats
                        where format.SamplesPerSecond == 8000 && format.BitsPerSample == 16 && format.Channels == 1 && format.WaveFormat == WaveFormatType.Pcm
                        select format;
            var videoFormat = query.FirstOrDefault();

            if (videoFormat == null)
            {
                ShowMessageBox("Your sound device may not found or in use also please make sure that it's support (16 bits,8000 samples,1 channel) please tell your system administrator about this problem!");
                return;
            }

            _sink.OnBufferFulfill += new EventHandler(SendVoiceBuffer);
            _capture.AudioCaptureDevice.DesiredFormat = videoFormat;
            _sink.CaptureSource = _capture;
            _sink.StartSending = true;
            _isRecording = true;
        }
 
Encoding/Sending Audio:
        void SendVoiceBuffer(object VoiceBuffer, EventArgs e)
        {
            byte[] PCM_Buffer = (byte[])VoiceBuffer;

            if (PCM_Buffer.Length >= 8000)
            {
                try
                {
                    byte[] buffer = EncodeAudio(PCM_Buffer);
                    Send_Audio_Bytes(buffer); //Send bytes through TCP
                }
                catch (Exception ex)
                {
                    //catch
                }
            }
        }
        int rawDataSize = 0;
        public byte[] EncodeAudio(byte[] rawData)
        {
            var encoder = new SpeexEncoder(BandMode.Wide);
            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;
        }
Decoding:
        SpeexDecoder decoder = new SpeexDecoder(BandMode.Wide);
        private void Decode(byte[] encodedData)
        {
            short[] decodedFrame = new short[8000]; // should be the same number of samples as on the capturing side
            decoder.Decode(encodedData, 0, encodedData.Length, decodedFrame, 0, false); //Error happens here

            // todo: do something with the decoded data
        }
 
Coordinator
Oct 12, 2011 at 2:47 PM

You are sampling with 8kHz but you use mode wide which requires 16kHz sampling!

Changing that either way should do the trick.

Am 12.10.2011 16:17 schrieb "zLan" <notifications@codeplex.com>:

From: zLan

I'm using NSpeex Encoder/Decoder but I keep getting IndexOutOfRangeException when trying to decode.

Starting up Audio:

        private void StartUpAudio() 
        {
            _sink = new MemoryAudioSink();

            //_source in query
            var query = from format in _capture.AudioCaptureDevice.SupportedFormats
                        where format.SamplesPerSecond == 8000 && format.BitsPerSample == 16 && format.Channels == 1 && format.WaveFormat == WaveFormatType.Pcm
                        select format;
            var videoFormat = query.FirstOrDefault();

            if (videoFormat == null)
            {
                ShowMessageBox("Your sound device may not found or in use also please make sure that it's support (16 bits,8000 samples,1 channel) please tell your system administrator about this problem!");
                return;
            }

            _sink.OnBufferFulfill += new EventHandler(SendVoiceBuffer);
            _capture.AudioCaptureDevice.DesiredFormat = videoFormat;
            _sink.CaptureSource = _capture;
            _sink.StartSending = true;
            _isRecording = true;
        }
 
Encoding/Sending Audio:
        void SendVoiceBuffer(object VoiceBuffer, EventArgs e)
        {
            byte[] PCM_Buffer = (byte[])VoiceBuffer;

            if (PCM_Buffer.Length >= 8000)
            {
                try
                {
                    byte[] buffer = EncodeAudio(PCM_Buffer);
                    Send_Audio_Bytes(buffer); //Send bytes through TCP
                }
                catch (Exception ex)
                {
                    //catch
                }
            }
        }
        int rawDataSize = 0;
        public byte[] EncodeAudio(byte[] rawData)
        {
            var encoder = new SpeexEncoder(BandMode.Wide);
            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;
        }
Decoding:
        SpeexDecoder decoder = new SpeexDecoder(BandMode.Wide);
        private void Decode(byte[] encodedData)
        {
            short[] decodedFrame = new short[8000]; // should be the same number of samples as on the capturing side
            decoder.Decode(encodedData, 0, encodedData.Length, decodedFrame, 0, false);

            // todo: do something with the decoded data
        }

Read the full discussion online.

To add a post to this discussion, reply to this email (nspeex@discussions.codeplex.com)

To start a new discussion for this project, email nspeex@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Oct 12, 2011 at 3:23 PM

I'm new to Audio so if you could help clairfy, it would be greatly appreciated.

When you say I'm sampling 8kHz but using 16kHz sampling do you mean I need to change my bandmode to Narrow?

or do I need to change my references from 8000 SamplesPerSecond to 16000?

 

Also if I plan on streaming the bytes, should I be using 8Khz or 16kHz?

Coordinator
Oct 12, 2011 at 3:29 PM

Depends what you need! If you want better quality by sacrifying bandwidth you should sample at 16 kHz and use wide band mode.

If you require low bandwidth then narrow band with 8 kHz is your choice.

Am 12.10.2011 17:23 schrieb "zLan" <notifications@codeplex.com>:

From: zLan

I'm new to Audio so if you could help clairfy, it would be greatly appreciated.

When you say I'm sampling 8kHz but using 16kHz sampling do you mean I need to change my bandmode to Narrow?

or do I need to change my references from 8000 SamplesPerSecond to 16000?

Also if I plan on streaming the bytes, should I be using 8Khz or 16kHz?

Read the full discussion online.

To add a post to this discussion, reply to this email (nspeex@discussions.codeplex.com)

To start a new discussion for this project, email nspeex@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Oct 12, 2011 at 7:24 PM
Edited Oct 12, 2011 at 7:25 PM

I'm now having problems with decoding the bytes and play it through an MediaElement. After I decode, I'm getting 4000 decoderBytes, but that isn't an a byte[] so I don't understand how I can get the decoded bytes into a playable format.

        SpeexDecoder decoder = new SpeexDecoder(BandMode.Narrow);
        private void Decode(byte[] encodedData)
        {
            try
            {
                short[] decodedFrame = new short[8000]; // should be the same number of samples as on the capturing side
                var decodedData = new byte[encodedData.Length];
                var decoderBytes = decoder.Decode(encodedData, 0, encodedData.Length, decodedFrame, 0, false);
                byte[] DecodedBuffer = new byte[decoderBytes];
                byte[] decodedAudioData = null;
                for (int shortIndex = 0, byteIndex = 0; byteIndex < decoderBytes; shortIndex++)
                {
                    BitConverter.GetBytes(DecodedBuffer[shortIndex + byteIndex]).CopyTo(decodedAudioData, byteIndex * 2);
                    byteIndex++;
                }

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

        }

        void PlayWave(byte[] PCMBytes)
        {
            MemoryStream ms_PCM = new MemoryStream(PCMBytes);
            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();
        }