Record directshow audio device to file - c++

I've stumbled through some code to enumerate my microphone devices (with some help), and am able to grab the "friendly name" and "clsid" information from each device.
I've done some tinkering with GraphEd.exe to try and figure out how I can take audio from directshow and write it to a file (I'm not currently concerned about the format, wav should be fine), and can't seem to find the right combination.
One of the articles I've read linked to this Windows SDK sample, but when I examined the code, I ended up getting pretty confused at how to use that code, ie. setting the output file, or specifying which audio capture device to use.
I also came across a codeguru article that has a nicely featured audio recorder, but it does not have an interface for selecting the audio device, and I can't seem to find where it statically picks which recording device to use.
I think I'd be most interested in figuring out how to use the Windows SDK sample, but any explanation on either of the two approaches would be fantastic.
Edit: I should mention my knowledge and ability as a win32 COM programmer is very low on the scale, so if this is easy, just explain it to me like I'm five, please.

Recording audio into file with DirectShow needs you to build the right filter graph, as you should have figured out already. The parts include:
The device itself, which you instantiate via moniker (not CLSID!), it is typically PCM format
Multiplexer component that converts streams into container format
File Writer Filter that takes file-compatible stream and writes into a file
The tricky moment is #2 since there is not standard component available. Windows SDK samples however contains the missing part - WavDest Filter Sample. Building it and making it ready for use, you can build a graph that records from device into .WAV file.
Your graph will look like this, and it's built easily programmatically as well:
I noticed that I have a variation of WavDest installed with Google Earth - for the case you have troubles building it yourself and you will be looking for prebuilt binary.

You can instruct ffmpeg to record from a directshow device, and output to a file.

Related

Easiest way to control USB TMC device on Windows/C++

I am developing C++/Qt application which interacts with Tektronix TDS2002 oscilloscope via USB. The oscilloscope appears as "USB Test and Measurement device (IVI)".
Currently I use TekVISA library supplied by the oscilloscope's vendor. It works, but it is huge, old, buggy and poorly maintained. Therefore I would like to bypass the library and interface the device directly.
So far I have found this simple library: https://github.com/xyphro/WinUsbTmc It is exactly what I am looking for, but it uses libusb which requires to install some device filter and in addition it is advised to be more development tool than customer solution. Do you have any experience on this?
What is the easiest way to interact with USB Test and Measurement device in Windows/C++/Qt?
Thank you for your suggestions :)
You need a USB driver. My oscilloscope works with the driver included in this VISA package (the driver can be extracted very easily): http://www.keysight.com/main/software.jspx?cc=CZ&lc=eng&nid=-11143.0.00&id=2504667&pageMode=CV I assume all USB TMC devices can use the same driver, but I have no possibility to check this.
USB driver can be accessed via standard Windows functions. Guys on this forum were really close:
https://forum.tek.com/viewtopic.php?f=568&t=137573 and also this document was very useful: http://www.ivifoundation.org/downloads/Class%20Specifications/Ivi-6%202_USBTMC_2010-03-23.doc
You cannot write commands to OSC directly - data you send and receive have certain header which has to be in the correct format, otherwise the oscilloscope ignores the message. See reading and writting implementation in this simple library: https://github.com/xyphro/WinUsbTmc I didn't use this library because it uses libusb library which uses some kind of device filter and I personally do not like this concept (and in addition I have genuine working driver).
Data you read have also a simple header. To ensure you fit the header structure on input data well, you should first flush the input buffer. Then you issue reading request (using write command - see WinUsbTmc library above) and finally you receive the data and fit the header on its beginning.
I hope this will help to somebody :)
With regards
klasyc

Retrieve the peak of an audio stream from OpenNI

I'm attempting to grab the peak level (decibal level or whatnot) from an audio stream from a Kinect using OpenNI.
I've found these:
http://openni.org/docs2/Reference/classxn_1_1_audio_meta_data.html
http://openni.org/docs2/tutorial/smpl_audio.html
But I'm having a hard time piecing it together. I just need an integer of some sort to figure out how loud the surrounding area for the kinect is.
Thanks!
I've tried using the Audio API provided by OpenNI with no luck, not even the provided sample. I had the same question a while back.
If you're on osx/linux you can use both openni/libfreenect side by side(as admin only on linux) and libfreenect has some experimental audio support.
In the mean time I've found two other projects that look interesting:
HARK
MS Kinect-OpenNI Bridge
I haven't used both, although the second looks promising, so it should be possible to access audio via MS SDK and process data using OpenNI as well.

Recording application output to video using FFmpeg (or similar)

We have a requirement to lets users record a video of our 3D application. I can already grab the individual rendered frames so this question is specifically about how to write frames into a video file.
I don't think writing each frame as a separate file and post-processing is a workable option.
I can look at options to record to a simple video file for later optimising/encoding, or writing directly to a sensibly encoded format.
FFmpeg was suggested in another post but it looks a bit daunting to me. Is it the best option, if not what can be suggested? We can work with LGPL but not full GPL.
We're working on Windows (Win32 not MFC) in C++. Sample/pseudo code with your recommended library is very much appreciated... basically after how to do 3 functions:
startRecording() does whatever initialization is needed
recordFrame() takes pointer to frame data and encodes it, ideally with timing data
endRecording() finalizes the video file, shuts down video system, etc
Check out the sources to Taksi on sourceforge. http://taksi.sourceforge.net/
You need 2 things.
1. A code to compress the frames.
2. A container file format. Like AVI or MPG.
Taksi useses the old VideoForWindows API and AVI not the newer COM API's but it still might work for you.

Portable library to play samples on individual 5.1 channels with C/C++?

I'm looking for a free, portable C or C++ library which allows me to play mono sound samples on specific channels in a 5.1 setup. For example the sound should be played with the left front speaker whereby all other speakers remain silent. Is there any library capable of doing this?
I had a look at OpenAL. However, I can only specify the position from which the sound should come, but it seems to me that I cannot say something like "use only the front left channel to play this sound".
Any hints are welcome!
I had a look at OpenAL. However, I can only specify the position from which the sound should come, but it seems to me that I cannot say something like "use only the front left channel to play this sound".
I don't think this is quite true. I think you can do it with OpenAL, although it's not trivial. OpenAL only does the positional stuff if you feed it mono format data. If you give it stereo or higher, it plays the data the way it was provided. However, you're only guaranteed stereo support. You'll need to check to see if the 5.1 channel format extension is available on your system (AL_FORMAT_51CHN16). If so, then, I think that you feed your sound to the channel you want and feed zeroes to all the others channels when you buffer the samples. Note that you need hardware support for this on the sound card. A "generic software" device won't cut it.
See this discussion from the OpenAL mailing list.
Alternatively, I think that PortAudio is Open, cross-platform, and supports multiple channel output. You do still have to interleave the data so that if you're sending a sound to a single channel, you have to send zeroes to all the others. You'll also still need to do some checking when opening a stream on a device to make sure the device supports 6 channels of output.
A long time ago I used RTAudio. But I cannot say if this lib can do what you want to archive, but maybe it helps.
http://fmod.org could do the trick too
I use the BASS Audio Library http://www.un4seen.com for all my audio, sound and music projects. I am very happy with it.
BASS is an audio library to provide developers with powerful and efficient sample, stream (MP3, MP2, MP1, OGG, WAV, AIFF, custom generated, and more via add-ons), MOD music (XM, IT, S3M, MOD, MTM, UMX), MO3 music (MP3/OGG compressed MODs), and recording functions. All in a tiny DLL, under 100KB* in size. C/C++, Delphi, Visual Basic, MASM, .Net and other APIs are available. BASS is available for the Windows, Mac, Win64, WinCE, Linux, and iOS platforms.
I have never used it to play different samples in a 5.1 configuration. But, according their own documentation, it should be possible.
Main features
Samples Support for WAV/AIFF/MP3/MP2/MP1/OGG and custom generated samples
Sample streams Stream any sample data in 8/16/32 bit, with both "push" and "pull" systems. File streams MP3/MP2/MP1/OGG/WAV/AIFF file streaming. Internet file streaming. Stream data from HTTP and FTP servers (inc. Shoutcast, Icecast & Icecast2), with IDN and proxy server support and adjustable buffering. ** Custom file streaming ** Stream data from anywhere using any delivery method, with both "push" and "pull" systems
Multi-channel Support for more than plain stereo, including multi-channel OGG/WAV/AIFF files
...
Multiple outputs Simultaneously use multiple soundcards, and move channels between them
Speaker assignment Assign streams and MOD musics to specific speakers to take advantage of hardware capable of more than plain stereo (up to 4 separate stereo outputs with a 7.1 soundcard)
3D sound Play samples/streams/musics in any 3D position
Licensing
BASS is free for non-commercial use. If you are a non-commercial entity (eg. an individual) and you are not making any money from your product (through sales, advertising, etc), then you can use BASS in it for free. Otherwise, one of the following licences will be required.

Get native video resolution of a video file

I'm currently writing some custom EVR for a Media Foundation player.
So far everything work, but i'm in need of finding the native resolution of the video file i'm rendering.
I try to use the IBasicFilter2 Interface to use the getVideoSize, get_VideoHeight or other get_SourceWidth etc... but it always return me a E_NOINTERFACE...
So do someone have an esay way of getting resolution of a video file? Even if it's with a nice light library...just the size nothing else...Windows manage to find it inside the file browser, but i'm totally unable to get it from code...
Thanks!
You can use IMediaDet in DirectShow to get information on the streams in a media file including the resolution of video streams.
There are come caveats though so you might want a backup method.
You need suitable DirectShow filters registered which understand the media file being examined. It's possible that you may have a filter installed that gives wrong results - e.g. an audio only filter is registered for a media type that ignores any video streams in the file.
It's currently deprecated with no indication on the MSDN reference page of what is replacing this functionality. It can also be a pain to build as the headers have been removed from the Windows SDK.
Here's one case in point where that method doesn't work...
Get MP4 stream lengths