Ambiera Forum

Discussions, Help and Support.

Ambiera Forum > irrKlang
Low latency streaming / sidetone. Is it possible?

kindyre
Registered User
Quote
2014-08-22 14:08:07

Hi,

We'd really like to use irrKlang for dealing with sound in one of our projects, since it's perfect for 95% of what we're doing. But we've run into some roadblocks trying to implement sidetone (redirect microphone to headphones).

Obviously irrKlang doesn't have native support for this sort of thing, but our hope was that it would be possible with some work(arounds). Basically, all you need to manually create sidetone is:

- Get PCM data chunk from microphone
- Output PCM data chunk to speakers
- Chunks must be tiny (<= 20ms ideally)
- Output must be seamless (otherwise you get clicks/distortion)

The first point was easy enough: ICapturedAudioDataReceiver::OnReceiveAudioDataStreamChunk gives us the data chunks and from there we can buffer them for easy retrieval when we're ready to play them.

Playing the chunks proved to be far more difficult than it had any right to be, but eventually I got two different approaches (partially) working:

Option 1.: Subclass IFileReader and pretend to be a huge file, but output recorded data in read(), OR...
Option 2.: Create 20ms SoundSource from PCMData, attach ISoundStopEventReceiver, overwrite buffer with new data when it finishes playing, play again, rinse and repeat

The problems really start with the other two requirements:

Problem 1.: OnReceiveAudioDataStreamChunk seems to prefer to deliver 500ms chunks (and therefore with a 500ms delay). This isn't good enough for sidetone. Is there any way to force it to be called more often / with smaller chunks?

Problem 2.: Using Option 1 to stream sound produces seamless output. Good! However, when you start playback, read() is called to request 1 second worth of data and then immediately continues to request 50ms chunks 20 times per second. IE, it tries to create and maintain a 1 second buffer. This is too long for us. We need a 20ms buffer or less. Is there any way to make this buffer smaller?

The API seems to imply that you can use the return value of read() to provide less bytes than irrKlang requested. But if you, for example, return 50ms of sound when it requests the initial 1 second, it seems to completely ignore your return value. So it just plays your 50ms of sound followed by 950ms of silence. After that playback resumes with 1 second delay. Am I missing something or does that return value not have any real purpose?

Problem 3.: Using Option 2 to stream sound eliminates the buffer issue since you're playing each 20ms chunk separately. Good! However, playback isn't seamless since there is a small gap between a chunk finishing and starting playback again after receiving the SoundStopEvent and overwriting the buffer. This creates a click at the beginning and end of every chunk. With 20ms chunks that's 2 * 50 = 100 clicks per second, which sounds quite ghastly.

What's worse is that for some reason, when using an event to trigger the chunk update and playback, the update is ignored and the first chunk keeps getting played over and over. This doesn't happen when doing exactly the same things in the same order but without the event. I assume this is a threading issue. Specifically, it seems like ISound::drop() isn't working right from the event thread.

Is there any way to eliminate the gaps and event issues? Perhaps get rid of the event? But then how would you synchronize the chunks to play one after the other? Or is Option 2 just not viable / worse than Option 1?

Any responses appreciated, even if it's just "No, this isn't possible!"

I'd be happy to post code samples if there's interest!


niko
Moderator
Quote
2014-08-22 18:24:41

I see, so from what I gather, this won't work with your scenario. So basically I'd say "No, this isn't possible", for now at least. Going to add something in the near future for this. But it's difficult to say when this exactly will be, so better use another solution for this in the meantime.


kindyre
Registered User
Quote
2014-08-24 00:15:04

Thanks for the swift response, Niko! :)

Was afraid you might say that... but hoping I was just missing something.


Create reply:


Posted by: (you are not logged in)


Enter the missing letter in: "Internat?onal" (you are not logged in)


Text:

 

  

Possible Codes


Feature Code
Link [url] www.example.com [/url]
Bold [b]bold text[/b]
Image [img]http://www.example.com/image.jpg[/img]
Quote [quote]quoted text[/quote]
Code [code]source code[/code]

Emoticons


   






Copyright© Ambiera e.U. all rights reserved.
Privacy Policy | Terms and Conditions | Imprint | Contact