Naudio: how to properly remove 1 out of several sounds played by an AsioOut without stopping all other sounds? - naudio

I am using AsioOut because need to minimize latency as much as possible. Since I can only run 1 AsioOut at a time, I am using a MixingWaveProvider32 to play back multiple sounds at the same time. The problem I am running into is that I don't know how to properly remove 1 sound without pausing all the others.
I can easily add a new IWaveProvider (AudioFileReader in my case) to the MixingWaveProvider32 by simply adding it as an input stream, but if I try to remove it the same way the audio starts glitching (I think it's looping the last available buffer). I can prevent this by stopping the AsioOut before swapping the sound, but this brings 2 problems:
all other sounds also get stopped
if the sound I am trying to remove already finished on it's own then I get softlocked on AsioOut.Stop() (the method never finishes).
How do I properly remove 1 sound without running into these problems?

I found a solution myself: By running all sounds through a WaveChannel32 before putting them in the MixingWaveProvider32 I can add and remove the sounds at any time without stopping the AsioOut without getting any audio glitches.

I suspect this is a bug in MixingWaveProvider32 due to the combination of WaveBuffer and Array.Clear which can fail to clear enough of the buffer resulting in the glitching sound you describe.
I suggest you try with MixingSampleProvider instead, which is the successor to MixingWaveProvider32

Related

How to stop stream from ending

How to stop the take method from ending nested streams, to be used with flatten?
Is there some other solution to nested streams? I tried merging fromDiagram without end symbol, but apparently that doesn't work.
I got told that xs.never() is method specifically for this use case, and while I still don't know why fromDiagram would fail, I suppose that is an answer enough.
xs.merge(stream.take(1), xs.never()).map(nestedStream)

What can I use instead of sprintf?

I am working on TI-TM4C129X ARM board and trying to write a LOG mechanism.It works good when I call it from the Tasks although I faced a problem when I called it with a timer.As I understand that, printf like functions works with Hwi and this causes the error. My aim is to format strings together with the operations like sprintf(),vsprintf(),memcpy() and memset(). How can I solve this problem ? Is there any equivalent methods that success sprintf() operation ?
Thanks for your answers,
Best Regards.
It sounds like the printf is the problem, not sprintf. Assuming your Log message uses an interrupt (UARTs do), and your timer is called from an interrupt, then your options are limited.
I would set a flag in the timer that your task code can check, once outside the context of the timer. This flag could indicate one of several messages to print, even include a time stamp if that helps to resort things afterwards, since your printed messages will not be in order.
Or, with SWO output (like the Segger j-link), you should be able to just send the data. But to avoid scrambled sentences, you need to halt interrupts while sending out a debug message, which obviously can affect the real-time behavior.

NAudio: Playing ringing tone for a softphone - use looping or Timer?

I started to check the way how I can use NAudio to play sounds using different Output devices.
Now I would like to use NAudio for the following use case:
I would like to play a ringback when a call arrives on a soft phone. The ringback audio (wav file of 3-5 sec) should be played repeatedly until the call is accepted or the caller hangs-up the call.
I found now two ways of doing it:
Following entry explains how this could be solved by playing a file in a loop:
NAudio looping an audio file
Another entry explains how to work this out by using a timer to play the file repeatedly:
NAudio - Play an audiofile, wait for 2 seconds, play the audio file again
The question is which way is the better one to go for? So does it make sense to start the playback often for a quite short-time?
Another question which arise is if there is way to make sure that in the looping case the playback is rellay stopped as it does not make sense to have the ringback played from the loudspeaker although the person is talking already to the caller.
Thank you very much for your support!
Uzay
I'd recommend using the looping solution in this scenario. It avoids the need to keep closing and opening the soundcard. Stopping works exactly the same whether you are looping or not.

When does Core Data flush to disk?

I use Core Data in my application, and discovered some odd behavior of the simulator: When I add some data to Core Data in my app and quits the simulator using the "stop" button in XCode (or just press Cmd-Q) immediately, the data is not stored in the database the next time I start the simulator. After some testing, I found out, that the data is stored to disk:
immediately if I press the home button. (Almost - it is possible to quit the application before data is stored if quitting very fast.)
If I let the application run for some time (at least about 20 seconds) after adding data.
It does not help to call [NSManagedObjectContext save:]. The behavior is the same.
So my question is: What is the reason for this kind of behavior? Are there any way to force flushing to disk before quitting? And are there any risk that I can loose data this way when running on a device (personally, I do not see any, except a force close, but the odd behavior bothers me a bit)
Stopping the simulator with the stop button in Xcode is probably the same as smashing your iPhone with a hammer (but preserving the SSD). Basically, your app and everything else just stops. There's no reasonable way to ensure that data is saved when that happens.
You're probably using nested context's. If your context has a parent context, calling -save: will just save to that context, not to the file system.
Nested context are (usually) used to safely use a context on a background queue, and allowing a foreground context to save without having to incur the overhead of saving to the file system. The save to the file system will happen on a background queue and not block the main thread.
I too have been wrestling with this for a very long time and Daniel Eggert's answer under (2) above is the first - and only - useful answer I have found on the internet. I presume JRV is using the NSManagedDocumentContext from a UIManagedDocument. If this is the case then Apple's 'default' saving method is incomplete! Having adopted Daniel Eggert's solution my data is now preserving perfectly and is also immune to a simulator 'STOP' gesture. I recommend Daniel Eggert's answer under (2) above to anyone else wishing to write resilient code in this case.

Random Crashing and weird console output

I wrote an entire app, and I was just about to submit it to the app store, and in my final testing, I went back and added a few releases to ensure proper memory management was observed. And since then, I keep getting these random crashes. I've tried removing some or all of the release calls, I've tried retaining objects. I cleaned the project. I used NSZombieEnabled and that also is not helping. All this to not avail.
Most of the time, the console says provides no help. Usually the app loads, I put NSLogs in viewDidLoad, viewDidAppear, and viewWillAppear, and they all show up in the console, then it crashes.
Sometimes I also get EXC_BAD_ACCESS (and I know what that means). But its occurring randomly. So this doesn't make sense to me. Thanks for any help possible. I've written this whole app, and spent months on it. So I'm really stuck. Thank you.
Have you tried Build --> Analyze? It will search your code for leaks and other useful things you might have missed. Try that and see if it finds anything for you.
I agree with Rudy. It sounds like you're releasing something that is still in use. I would go back to the version that was working and start adding the releases one at a time til it causes the crash. Slow but effective debugging.
When you say that you "sometimes" get EXC_BAD_ACCESS, what do you get the rest of the time? Where does the crash stack indicate you're crashing? What messages do you get?
Random crashes usually indicate a timing problem. A common cause is accessing things on multiple threads. Are you? It can also mean timing differences based on network traffic.
Make sure the console doesn't indicate an exception rather than a memory violation. Usually there's something in the console that will be useful.