How to get native sample rate of audio driver (Windows) - windows

I have a simple sample mixer, when profiling I noticed that ~40-50% of the time is being spent resampling (44.1 => 48kHz, they must do something more sophisticated than lerp).
This step is gone when I open the playback device (DSound in my case) in 48kHz mode.
Question is: is there a way to query audio driver's default (native) sample rate to avoid resampling?
I tried searching the web/docs but found nothing, I thought this might be a simple API call.
Thanks.

In case you are still curious, I had the same question and had trouble finding answers. Someone pointed me in the right direction, and I was able to get a working code example for getting playback properties (Win >= Vista). You can only do this in Windows higher than XP, but that is where resampling from 44.1 to 48 can sound bad (XP had better default resampling). How do you get the current sample rate of Windows audio playback?

Related

WASAPI: IAudioClient->Initialize succeeds even when IAudioClient->IsFormatSupported fails with same format

I am trying to find out which output formats are supported by a specific audio device in exclusive mode.
To do this, I am using IAudioClient->IsFormatSupported(), which according to the documentation should be usable for this.
Unfortunately, it returns AUDCLNT_E_UNSUPPORTED_FORMAT for almost every format I try to pass, except for default 2-channel, 44.1khz audio.
If I actually try to initialize the audioclient, there are however formats that succeed, but which failed in IsFormatSupported().
Just trying to Initialize every format is not an option because this could result in stopping the audio from other applications.
Has anyone else seen this behavior or know if there is another way to find which formats are supported by a specific audio device?
I have seen this behavior as well. It seems like IsFormatSupported will only accept what is marked as 'supported' in the playback device settings in Windows, but Initialize seems to actually end up asking the drivers if it's indeed possible.
In my specific situation, I have a Xoxar HDAV1.3 setup to use HDMI as output. Two playback devices are always available: Speakers and S/PDIF Pass-through Device. If I try, for example, to request 6 channels for the S/PDIF playback device, IsFormatSupported will reject it (in theory, S/PDIF only supports 2, and that's all I can see in the settings), but calling Initialize will succeed and work (it goes out HDMI after all, for which 6 channels is supported). Talk about misleading device names!
I'm afraid there's no real practical way to work around this issue.

Flex 4 > spark.components.VideoPlayer > How to switch bit rate?

The VideoPlayer (possibly VideoDisplay also) component is capable of somehow automatically picking the best quality video on the list it's given. An example is here:
http://help.adobe.com/en_US/FlashPlatform/beta/reference/actionscript/3/spark/components/mediaClasses/DynamicStreamingVideoItem.html#includeExamplesSummary
I cannot find the answers to below questions.
Assuming that the server that streams recorded videos is capable of switching across same videos with different bit rates and streaming them from any point within their timelines:
Is the bandwidth test/calculation within this component only done before the video starts playing, at which point it picks the best video source and never uses the other ones? Or, does it continuously or periodically execute its bandwidth tests and does it accordingly switch between video sources during the playback?
Does it support setting the video source through code and can its automatic switching between video sources be turned off (in case I want to provide this functionality to the user in the form of some button/dropdown or similar)? I know that the preferred video source can be set, but this only means that that video source will be tested/attempted first.
What other media servers can be used with this component, besides the one provided by Adobe, to achieve automated and manual switching between different quality of same video?
Obviously, I'd like to create a player that is smart enough to automatically switch between different quality of videos, and that will support manual instructions related to which source to play - both without interrupting the playback, or at least without restarting it (minor interruptions acceptable). Also, the playback needs to be able to start at any given point within the video, after enough data has been buffered (of course), but most importantly, I want to be able to start the playback beyond what's buffered. A note or two about fast-forwarding is not going to hurt, if anyone knows anything.
Thank you for your time.

How to detect if any sound plays on a windows xp machine

Is it possible to detect if any sound plays on a windows xp machine? Help in any language would be useful. I basically need to write a program that runs all the time and outputs some text to a file whenever a sound plays. I don't need any specific information about the sound, just whether a sound is playing. I don't care whether the speakers are actually powered on or anything like that.
The question was easy, but the answer is difficult. You'll need to utilize DirectSound to achieve your purpose. I haven't tested my solution yet, but you can try to call IDirectSoundBuffer8::GetStatus(), then check the return value of pdwStatus parameter. According to MSDN, DSBSTATUS_PLAYING is set if the buffer is being heard.
Since you didn't tell about programming language you are using, I implement the following example using my favorite language, Delphi.
var
dwStatus: DWORD;
hResult: HRESULT;
hResult := GetStatus(#dwStatus);
if hResult = DS_OK then begin
if dwStatus and DSBSTATUS_PLAYING <> 0 then
ShowMessage('Sound card is playing sound now.');
end;
UPDATE
I just found a VB forum discussed about how to detect silence (no output of sound card). Download DetSilence.zip. In the DXRecord_GotWavData Sub, modify the constants SilencePercent and NonSilencePercent to the values you need.
I ended up approaching this in an unconventional manner. First I installed Virtual Audio Cable (http://www.ntonyx.com/vac.htm) and configured it as my primary sound device. I then configured the recording device to record the sound from the primary output device. This basically means I can hit "record" and it will record anything going to the sound card. Then I used a perl module, Win32::SoundRec to record sound to a file. I periodically check the wav file for activity and if there is some, I know sound was playing. I used another perl module, Audio::Wav, to parse the WAV file and look for activity (silence vs. non-silence).

NSSound-like framework that works, but doesn't require dealing with a steep learning curve

I've pretty much finished work on a white noise feature for one of my applications using NSSound to play a loop of 10 second AAC-encoded pre-recorded white noise.
[sound setLoops: YES]
should be all that's required, right?
It works like a charm but I've noticed that there is an audible pause between the sound file finishing and restarting.. a sort of "plop" sound. This isn't present when looping the original sound files and after an hour or so of trying to figure this out, I've come to the conclusion that NSSound sucks and that the audible pause is an artefact of the synchronisation of the private background thread playing the sound. It seems to be dependent on the main run loop somehow and this causes the audible gap between the end and restarting of the sound.
I know very little about sound stuff and this is a very minor feature, so I don't want to get into the depths of CoreAudio just to play a looping 10s sound fragment.. so I went chasing after a nice alternative, but nothing seems to quite fit:
Core Audio: total overkill, but at least a standard framework
AudioQueue: complicated, with C++ sample code!?
MusicKit/ SndKit: also huge learning curve, based on lots of open source stuff, etc.
I saw that AVFoundation on iOS 4 would be a nice way to play sounds, but that's only scheduled for Mac OS X 10.7..
Is there any easy-to-use way of reliably looping sound on Mac OS X 10.5+?
Is there any sample code for AudioQueue or Core Audio that takes the pain out of using them from an Objective-C application?
Any help would be very much appreciated..
Best regards,
Frank
Use QTKit. Create a QTMovie for the sound, set it to loop, and leave it playing.
Just for the sake of the archives.
QTKit also suffers from a gap between the end of one play through and start of the next one. It seems to be linked with re-initializing the data (perhaps re-reading it from disk?) in some way. It's a lot more noticeable when using the much smaller but highly compressed m4a format than when playing uncompressed aiff files but it's still there even so.
The solution I've found is to use Audio Queue Services:
http://developer.apple.com/mac/library/documentation/MusicAudio/Conceptual/AudioQueueProgrammingGuide/AQPlayback/PlayingAudio.html#//apple_ref/doc/uid/TP40005343-CH3-SW1
and
http://developer.apple.com/mac/library/samplecode/AudioQueueTools/Listings/aqplay_cpp.html#//apple_ref/doc/uid/DTS10004380-aqplay_cpp-DontLinkElementID_4
The Audio Queue calls a callback function which prepares and enqueues the next buffer, so when you reach the end of the current file you need to start again from the beginning. This gives completely gapless playback.
There's two gotchas in the sample code in the documentation.
The first is an actual bug (I'll contact DTS about this so they can correct it). Before allocating and priming the audio buffers, the custom structure must switch on playback otherwise the audio buffer never get primed and nothing is played:
aqData.mIsRunning = 1;
The second gotcha is that the code doesn't run in Cocoa but as a standalone tool, so the code connects the audio queue to a new run loop and actually implements the run loop itself as the last step of the program.
Instead of passing CFRunLoopGetCurrent(), just pass NULL which causes the AudioQueue to run in its own run loop.
result = AudioQueueNewOutput ( // 1
&aqData.mDataFormat, // 2
HandleOutputBuffer, // 3
&aqData, // 4
NULL, //CFRunLoopGetCurrent (), // 5
kCFRunLoopCommonModes, // 6
0, // 7
&aqData.mQueue // 8
);
I hope this can save the poor wretches trying to do this same thing in the future a bit of time :-)
Sadly, there is a lot of pain when developing audio applications on OS X. The learning curve is very steep because the documentation is fairly sparse.
If you don't mind Objective-C++ I've written a framework for this kind of thing: SFBAudioEngine. If you wanted to play a sound with my code here is how you could do it:
DSPAudioPlayer *player = new DSPAudioPlayer();
player->Enqueue((CFURLRef)audioURL);
player->Play();
Looping is also possible.

How can the audio data being sent to the speakers be captured from an application?

Is there an API that is suitable for doing this? A possible application of this is for writing a visualiser, and to play with real time signal processing.
EDIT: The operating system in question is Windows. On Linux, a roundabout way to accomplish this is with Jack, but I'm hoping for a way to read the data in the audio buffer without having to couple apps to Jack.
EDIT: A good answer is found here.
If sound board used for playback has recording device/line like "Stereo Mix", "What U Hear", etc., then it is enought to write simple recording application, that is capable to record from a specified recording device/line and record from the "Stereo Mix",...
General case (for "all sound boards") will require to write special driver. Examples of applications with such spesial drivers: Virtual Audio Cable (http://software.muzychenko.net/eng/vac.html); Total Recorder (http://www.totalrecorder/com).

Resources