WASAPI - trouble with CoCreateInstance method - audio

I am trying to capture audio from the mic using the windows core audio APIs
The relevant lines of code are
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
IMMDeviceEnumerator *pEnumerator = NULL;
hr = CoCreateInstance(CLSID_MMDeviceEnumerator,NULL,CLSCTX_ALL,IID_IMMDeviceEnumerator, (void**)&pEnumerator);
hr returns the following value-
0x800401f0 : CoInitialize has not been called.
I have adapted the sample program from the msdn page - Capturing an audio stream
What could be wrong? Also I don't understand what the error means - from the descriptions I got from Google search and all.
I am using Visual studio 2012 express on Win7 Home Pro x64.

Isn't the error message clear enough? You need to call CoInitialize before calling CoCreateInstance (or using COM in any other way).

Related

where to put a while loop in a system tray application so that loop starts with the app

I have created a System Tray Application using Windows Forms Template (Visual C++) in Visual Studio 2008. I have used ContextMenuStrip and NotifyIcon. It's a managed code as I have used the form and Drag/Drop.
I want as soon as this System Tray Application starts, it starts polling for any new USB devices (from a specific vendor) connected.
The logic is ready except I don't know "Where to put this while(1) loop?"
It works fine in a console app that I made but now we want it to be integrated to the system tray app.
Here is the code snippet:
int numDevices, n = 0;
while(1)
{
Sleep(5000);
numDevices = usb_find_devices();
if(connectedDevices > numDevices)
{
enumDevices();
connectedDevices++;
}
}
It would really be appreciable if anyone could suggest me some pointers on how to proceed.
Thank you Hans! I added a new "Component Class" with WM_DEVICECHANGE and it is working fine.
Just in case anyone needs this info:
If a function needs to be called as soon as the Windows Forms App starts (Systray app in my case), the respective function can be called after the call to "InitializeComponent()" function. Though it is clearly mentioned "TODO: Add the constructor code here", still a beginner (like me) has inhibitions regarding "Where to put this Function Call??" Hope this helps somebody..

Calling COM Methods using Microsoft Detours

I am trying to hook compile method of the jscript.dll located in C:\Windows\System32 which is the core of Internet Explorer Javascript Engine.
The code work fine for API Calls for example RegOpenKeyExW which is reponsible to read registery values.
But when I try to use COleScript::Compile in jscript.dll it get me an error.
this is my Code:
FunctionHook* CompileFunExWHook = new FunctionHook();
CompileFunExWHook->Identifier = "COleScript::Compile";
CompileFunExWHook->Module = "jscript.dll";
CompileFunExWHook->Detour = (PBYTE)MyRegOpenKeyExW;
HookManager::Instance()->CreateHook(CompileFunExWHook);
pOriginalRegOpenKeyExW = (pRegOpenKeyExW)(HookManager::Instance()- >GetHook("COleScript::Compile")->DetourAddress);

MonoTouch: ESSession for external accessories

I am porting coding from Objective C to MonoTouch to use an external accessory. It is super basic coding, however when I create The EASession and try to use the InputStream or OutputStream, they are both NULL. I have used it in Objective-C so I know this should not happen.
I am able to repeatedly connect/disconnect the device and detect it. Now I just can't seem to read the data from the device because of this null issue. Below is my coding:
session = new EASession(acc, "com.idtechproducts.reader");
session.OutputStream.Delegate = streamDel; // Crashed saying OutputStream is null
session.OutputStream.Schedule (NSRunLoop.Current , "NSDefaultRunLoopMode");
session.OutputStream.Open ();
You need to list the external accessories you're going to use in your
Info.plist.
There is some documentation on this on apple's site:
http://developer.apple.com/library/ios/#featuredarticles/ExternalAccessoryPT/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009502
Here is a screenshot of how to set this value in Info.plist:
http://screencast.com/t/AYmOWjf8wkL

Microsoft Media Foundation Webcam Interface

I've been working on a c++ interface to capture images from all types of webcams via the Micrsoft Media Foundation. I've already got a bit of code that can connect with several types of webcams and is able to capture images in different resolutions and formats.
I know that under WinXP it is possible to change different parameters of the webcam (like white balance, exposure time e.g.) by using the Direct Show library. Unfortunately the interface in the Direct Show library that made it possible to easily capture single frames from a webcam is removed from Direct Show under Win7. Does anybody know how I can acces these parameters using Microsoft Media Foundation or any other library that I can combine with the Microsoft Media Foundation?
It is possible to call a DirectShow QueryInterface method from WMF. Example code is given at Windows Media Foundation: Controlling Camera Properties.
This should let you set available camera parameters like focus and white balance etc.
HRESULT CMFVideoCaptureDlg::SetupCamera(IMFMediaSource* pCameraSource) {
CComQIPtr<IAMCameraControl> spCameraControl(pCameraSource);
HRESULT hr = S_OK;
if(spCameraControl) {
long min, max, step, def, control;
hr = spCameraControl->GetRange(CameraControl_Exposure, &min, &max, &step, &def, &control);
if(SUCCEEDED(hr))
hr = spCameraControl->Set(CameraControl_Exposure, 1, CameraControl_Flags_Manual);
}
CComQIPtr<IAMVideoProcAmp> spVideo(pCameraSource);
if(spVideo)
hr = spVideo->Set(VideoProcAmp_WhiteBalance, 0, VideoProcAmp_Flags_Auto);
return hr;
}
It turns out Media Foundation does not define any specific interfaces
for these tasks. Curiously enough, it implements interfaces defined by
its predecessor, DirectShow, on its media source (represented by the
IMFMediaSource interface), when that media source is a video camera
DirectShow is still good in Windows 7 (the easiest to check is using GraphEdit and AMCap from Windows SDK). Media Foundation however lacks essential support in earlier versions of Windows.
This article has the following code and it works like a charm!
HRESULT CMFVideoCaptureDlg::SetupCamera(IMFMediaSource* pCameraSource) {
CComQIPtr spCameraControl(pCameraSource);
HRESULT hr = S_OK;
if(spCameraControl) {
long min, max, step, def, control;
hr = spCameraControl->GetRange(CameraControl_Exposure, &min, &max, &step, &def, &control);
if(SUCCEEDED(hr))
hr = spCameraControl->Set(CameraControl_Exposure, 1, CameraControl_Flags_Manual);
}
CComQIPtr spVideo(pCameraSource);
if(spVideo)
hr = spVideo->Set(VideoProcAmp_WhiteBalance, 0, VideoProcAmp_Flags_Auto);
return hr;
}
IAMCameraControl and IANVideoProcAmp still support White balance,pan,zoom in Windows 8. camera control is so far not part of MFT.We have to use Direct Show to do these things.

How to get webcam video stream bytes in c++

I am targeting windows machines. I need to get access to the pointer to the byte array describing the individual streaming frames from an attached usb webcam. I saw the playcap directshow sample from the windows sdk, but I dont see how to get to raw data, frankly, I don't understand how the video actually gets to the window. Since I don't really need anything other than the video capture I would prefer not to use opencv.
Visual Studio 2008 c++
Insert the sample grabber filter. Connect the camera source to the sample grabber and then to the null renderer. The sample grabber is a transform, so you need to feed the output somewhere, but if you don't need to render it, the null renderer is a good choice.
You can configure the sample grabber using ISampleGrabber. You can arrange a callback to your app for each frame, giving you either a pointer to the bits themselves, or a pointer to the IMediaSample object which will also give you the metadata.
You need to implement ISampleGrabberCB on your object, and then you need something like this (pseudo code)
IFilterInfoPtr m_pFilterInfo;
ISampleGrabberPtr m_pGrabber;
m_pGrabber = pFilter;
m_pGrabber->SetBufferSamples(false);
m_pGrabber->SetOneShot(false);
// force to 24-bit mode
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(mt));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
m_pGrabber->SetMediaType(&mt);
m_pGrabber->SetCallback(this, 0);
// SetCallback increments a refcount on ourselves,
// but we own the grabber so this is recursive
/// -- must addref before SetCallback(NULL)
Release();

Resources