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

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.

Related

WatchKit: Video Duration

Is there a way to determine the duration of a video currently set to WKInterfaceInlineMovie? I need to implement a circular progress bar displaying a current progress.
I have a URL of the file initially downloaded from network. It plays well, but I haven't found any way to determine its length (actually, nor questions asking that which is strange).
Of course, I can ask the backend server to send this info, but I'd like to avoid such complications if possible.
OK, it seems I overcame the WKInterfaceInlineMovie API limitation by the help of AVFoundation and CoreMedia.
I create AVAsset object using a movie URL from a shared folder (AVAsset(url:)). Then I get CMTime duration from the AVAsset's duration property (which is a CMTime object).
Actually, I was very surprised to find out that it works. I'm still testing it, because it's too good to be true and I'm expecting to run across some pitfalls. I'll update the answer if anything else's found.

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

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

OS X Programmatically Set Default Output Device

I have been attempting to change which audio device my computer sends sound to. My end goal is to create a program that can make my laptop output to its built-in speakers even when headphones are plugged into the headphone jack.
I stumbled across this project, but the methods it uses (specifically AudioHardwareSetProperty) are deprecated. It also just doesn't work (it will say it changed the output device, but sound will still go to my headphones).
CoreAudio seems very poorly documented and I could not find ANY code online that did not use that function. I would go with the deprecated function if it did what I wanted, but it doesn't. I'm unsure weather it's broken or just doesn't do what I think it does, but that really doesn't matter in the end.
I attempted to look at the comments on AudioHardwareSetProperty but all I found was this in the discussion section:
Note that the value of the property should not be considered changed until the
HAL has called the listeners as many properties values are changed
asynchronously. Also note that the same functionality is provided by the
function AudioObjectGetPropertyData().
This is obviously not true, since I know for a fact that AudioObjectGetPropertyData is used for getting information about one specific audio device.
Is what I am trying to do possible with CoreAudio?

Detect USB - Insert/Remove - VB.NET on Windows CE 6.0

I'm becoming mad trying to figure out how to resolve this task. My goal is pretty easy, copy a file on the USB stick every time that it is inserted and then release the USB stick turning off the LED. What is the best way to solve it?
1) I found this article
http://geekswithblogs.net/BruceEitman/archive/2008/06/13/windows-ce-monitoring-for-disk-insertion-to-add-support-for.aspx
or
http://geekswithblogs.net/BruceEitman/archive/2008/06/13/windows-ce-monitoring-for-disk-insertion-to-add-support-for.aspx
but I can't translate it on VB.NET project.
2) Then I read that is enough to use RequestDeviceNotifications for block devices. But How can I do that in VB.NET?
I would like to avoid OpenNetCF if possible.
Thank you
Since you don't want to "use OpenNETCF" I assume that you don't want to use any libraries or capabilities not built in to the CF. We'll skip the argument of that silliness and the "value of your time" discussion and take that as a requirement.
What you need to do is:
Use P/Invoke to call CreateMsgQueue. That's going to give you back a Handle. You'll probably want to do CloseMsgQueue as well for completeness
P/Invoke RequestDeviceNotifications and pass it the handle returned from #1 above along with the DEVCLASS GUID value for the device notifications you want - probably STORE_MOUNT_GUID. Again, adding StopDeviceNotifications for completeness is a good idea.
At that point you'll get a message on the queue whenever a insert or remove happens. You then call ReadMsgQueue to get the DEVDETAIL data in the message.
Parse the DEVDETAIL and look at the fAttached member.
It'd take me a while to write that for you, so you'll need to do this on your own.
Start writing the project, find P/Invoke routines for the calls you need (like FindFirstFile and CreateProcess). On SO, have a look at Storage Card Problem In windows mobile and How to register form for WM_DEVICECHANGE message in windows mobile.
You are only going to be dead in the water if you can not find a particular call that you can't make.
As you work through your project, post (or search for) the actual problems you run into.
Otherwise, it sounds like you are asking someone to write the project and hand it to you.

Play video from a byte array

I am using visual basic .NET and I want to play a video from a byte array that I have, but without saving it first at the disk. Directly from that array. I tried the directshow lib for a while but didn't managed to find a way to play it. WMP didn't worked either.
Any ideas?
There is no stock component to stream from memory, however the task has more or less good generic solution. A number of files/formats are playable starting from so called File Source (Async) Filter, which is a generic file/data accessor. If you could provide a similar/compatible source filter which streams from memory, it would wokd great and cover a number of formats at a time.
Provided that you are going to have hard time doing it in VB.NET, and in managed code in general, you will perhaps need a third party solution for this. So you might eventually end up with a much easier workaround to save data into temporary file and play it from there.