This project has moved and is read-only. For the latest updates, please go here.

Dsp Truespeech Play Stream

Oct 18, 2012 at 3:31 AM

How to play a dsp group truespeech data from a stream of 32 bytes. 

Oct 19, 2012 at 3:10 PM

use the RawSourceWaveStream, passing in your stream and creating a TrueSpeechWaveFormat object

Oct 20, 2012 at 3:51 AM


TrueSpeechWaveFormat tspf = new TrueSpeechWaveFormat(); using (MemoryStream ms = new MemoryStream(Encoding.Default.GetBytes(dataToPlay))) { RawSourceWaveStream rws = new RawSourceWaveStream(ms, tspf); WaveFormatConversionStream pcmStream = (WaveFormatConversionStream)WaveFormatConversionStream.CreatePcmStream(rws); wo.Init(pcmStream); wo.Play(); }
this is inside a function which gets called at a delay of 85ms. So its consuming too much memory. Whats' the neat way of doing this?
can you provide a simple source?

Oct 20, 2012 at 9:34 AM

Use a single BufferedWaveProvider, and whenever you receive data, decompress it and put it into the BufferedWaveProvider. Then you can just play from the bufferedwaveprovider. For a full code example, look at the source code for the network chat application in NAudioDemo (see the Source Code tab above)

Oct 21, 2012 at 4:52 AM

no luck with the source code. the buffer is getting full in 1 second. i tried to boolean option to discard data whn buffer is full. The stream is sending data in an interval of 100ms. its playing i think but no sound coming out. cpu usage is 50. 

Oct 21, 2012 at 9:14 AM

are you sure you're reading from the BufferedWaveProvider?

Oct 21, 2012 at 1:15 PM
Edited Oct 21, 2012 at 1:17 PM

yes. i just duplicated your network chat demo. But in one second the buffer is getting full. and i hear a click sound in the beginning. 

Can you tell me how the bufferwaveprovider works? Is it like, the default length of the buffer is 5 seconds and as we play data from it, it gets emptied? or does the new data overwrites the buffer and whenever we call play on it, it plays whatever data is in it?

What im doing is, i call the following when the server gets connected. this is exactly the same code from network chat demo. other than discardonbufferoverflow and the remote endpoint.

this.codec = new TrueSpeechChatCodec();

 

waveOut = new WaveOut();
                                            waveProvider = new BufferedWaveProvider(codec.RecordFormat);
                                            waveProvider.DiscardOnBufferOverflow = true;
                                            waveOut.Init(waveProvider);
                                            waveOut.Play();
                                            connected = true;
					    ListenerThreadState state = new ListenerThreadState() { Codec = this.codec };
	 				    ThreadPool.QueueUserWorkItem(this.ListenerThread, state);

 

The above code gets called only once, i.e when the server gets connected. Then, whenever the server sends the truespeech data, i pass the data as string to a public variable. The variable is "PlayString" Then i assume the following code does add the data to the buffer from the public variable

 

class ListenerThreadState
        {
            public INetworkChatCodec Codec { get; set; }
        }

        private void ListenerThread(object state)
        {
            ListenerThreadState listenerThreadState = (ListenerThreadState)state;

            try
            {
                while (connected)
                {
                    byte[] b = Encoding.Default.GetBytes(this.PlayString);
                    byte[] decoded = listenerThreadState.Codec.Decode(b, 0, b.Length);

                    waveProvider.AddSamples(decoded, 0, decoded.Length);
                    
                }
            }
            catch (SocketException)
            {
                // usually not a problem - just means we have disconnected
            }
        }

This is the code i'm using. do you have any suggestion? this.codec = new TrueSpeechChatCodec();<-- is this particular line of code correct? I added the classes TrueSpeechChatCodec, INetworkChatCodec and AcmChatCodec to my project.

Forgot to mention, the data is 96 bytes. On debugging, the byte[] decoded, is of length 1440 bytes.

Oct 21, 2012 at 4:10 PM

BufferedWaveProvider uses a circular buffer, with a read position and a write position, so everything written to it gets read out unless the buffer overflows. Where is your incoming stream coming from? If it is a file, then it is quite possible it is downloading so fast that the buffer fills up and overflows. If it is a realtime stream, then you ought not to get too many problems with overflow. BufferedWaveProvider can be set up to have a longer buffer time if needed (e.g. 30 seconds or more).

What WaveFormat are you passing into the BufferedWaveProvider? The WaveFormat should be the decoded (i.e. PCM) WaveFormat. I have no idea whether those numbers are correct for the formats you are working with. You could compare them with the byte[] sizes in the NAudioDemo

Oct 21, 2012 at 4:45 PM

as i mentioned earlier, im passing in dsp truespeech waveformat. I tried setting a longer buffer time too. no use still. im getting the truespeech data with a length of 96 bytes from a server in realtime with a delay of 100 ms. In the following code 

while (connected)
                {
                    byte[] b = Encoding.Default.GetBytes(this.PlayString);
                    byte[] decoded = listenerThreadState.Codec.Decode(b, 0, b.Length);

                    waveProvider.AddSamples(decoded, 0, decoded.Length);
                    
                }

PlayString.Length = 96 bytes

Length of "b" is 96 bytes

Length of "decoded" is 1440 bytes.

Oct 21, 2012 at 4:47 PM

the WaveFormat of the BufferedWaveProvider must not be Truespeech. It must be PCM. It has to be the exact decoded WaveFormat from the Codec.

Oct 21, 2012 at 5:08 PM
Edited Oct 21, 2012 at 5:11 PM

ok so how do i decode truespeech to pcm and pass it on to the bufferedwaveprovider? im a total newbie in codes and stuffs like that. sry.

i know you already mentioned to use rawwavesource stream. but i really dunno how to.

Oct 21, 2012 at 5:18 PM

To debug audio codecs I recommend doing things offline first. So save some incoming audio to a raw .dat file. Then use the RawStreamSource and WaveFileConversionStream to try to convert it to PCM, writing it out with a WaveFileWriter. Listen to the resulting WAV file and see if it sounds right. Only once you are sure you are decoding audio properly are you ready to try and play it back on the fly

Oct 21, 2012 at 5:25 PM

using the following code the sound is playing.

 

using (MemoryStream ms = new MemoryStream(Encoding.Default.GetBytes(dataToPlay)))
            {
                RawSourceWaveStream rws = new RawSourceWaveStream(ms, tspf);

                WaveFormatConversionStream pcmStream = (WaveFormatConversionStream)WaveFormatConversionStream.CreatePcmStream(rws);

                waveOut.Init(pcmStream);
            }

can you tell me how to decode dsp truespeech to pcm in realtime?

 

Oct 21, 2012 at 6:42 PM

The way to do it is the way that the NAudio chat demo does it. If you are feeding audio into the buffered wave provider in the correct format then it will play