The so-called multimedia computers usually have sound cards (soft or hard sound cards), which can capture audio. You must be familiar with the attachment "recorder" program that comes with windows. You can use a microphone for recording and generate a wave file. After reading this article, you will find that using DirectShow to write an audio capture application is also so easy!
As you know, DirectShow supports hardware through specific packaging filters. The sound card uses the audio capture filter, and the filter uses a set of Apis starting with wavein (such as waveinopen ). Run graphedit and insert the filter. In the "audio capture sources" directory, we can see all the filters that represent the sound cards on the local machine (some machines have several sound cards installed, here there will be several filters ). By adding this filter to the filter graph, we find that this filter has many input pins, such as line in, CD audio, microphone, and stereo mix. There is a capture output pin. It should be noted that in the filter graph, these input pins do not have real data inflows, but they are symbolic representations of each input terminal of the sound card. Therefore, these input pins are never connected.
Let's take a look at how to create an audio capturing program. First, add an audio capture filter. As you know, DirectShow adds a hardware filter, which relies on "enumeration". Sound Card filter is no exception. The filter representing the sound card is registered in the clsid_audioinputdevicecategory directory. You can use the system device enumerator to enumerate this directory to find the sound card object you want to create. (Here we will not go into details about how to enumerate .) After the sound card filter is successfully added, the next problem is to connect the filter to other filters. For example, if we want to capture and generate a wave file, we need to add a wave DEST filter and a file writer filter, and then connect them in sequence. It should be noted that the wave DEST filter is an example of the Microsoft DirectX SDK. In the samples/multimedia/DirectShow/filters/wavdest directory, we must first compile this example and register this filter. The filter function is to write a file header information to the wave file when capture ends. Is the filter connection graph in graphedit:
Click to view the chart
The following is a frame code for creating an audio capture program for your reference:
Void buildaudiocapturegraph (void) // warning! No error checking here. <br/>{ <br/> ibasefilter * psrc = NULL, * pwavedest = NULL, * pwriter = NULL; <br/> ifilesinkfilter * psink = NULL; <br/> igraphbuilder * pgraph; <br/> // create the filter graph manager. <br/> cocreateinstance (clsid_filtergraph, null, clsctx_inproc_server, iid_igraphbuilder, (void **) & pgraph); <br/> // Add the audio capture filter. <br/> findaudiocapture (& psrc); // assume that this function enumerates <br/> // audio capture devices and picks one. <br/> pgraph-> addfilter (psrc, l "capture"); <br/> // Add the wavdest and the file writer. <br/> addfilterbyclsid (pgraph, l "wavdest", clsid_wavdest, & pwavdest); <br/> addfilterbyclsid (pgraph, l "file writer", clsid_filewriter, & pwriter ); <br/> // set the file name. <br/> pwriter-> QueryInterface (iid_ifilesinkfilter, (void **) & psink); <br/> psink-> setfilename (L "C: // mywackywav.wav ", null); <br/> // hook everything up. <br/> connecttwofilters (pgraph, psrc, pwavdest); <br/> connecttwofilters (pgraph, pwavdest, pwriter); <br/>}
Of course, while capturing audio, we can also monitor the input of the audio source in real time. As follows:
We have an infinite pin tee next to the audio capture filter. This filter can copy the data of an input pin into multiple copies and send them out through each output pin. (This filter is also an example of Microsoft DirectX SDK, in the samples/multimedia/DirectShow/filters/inftee directory .) We can see that one of the tee filters is connected to the directsound Renderer, and the sound can be output on the sound card.
It's easy to create an audio capture application! Next, we will discuss some parameter settings that may be used before audio capturing. On each input pin of the Sound Card filter, we can obtain the iamaudioinputmixer interface. Through this interface, we can set the audio attributes of each input terminal, such as whether to allow audio from an input terminal to participate in mixing, audio input volume, and treble and bass. In addition, the iamaudioinputmixer interface can also be obtained in the filter. In this case, the interface method can be called to control the attributes of each input terminal. You can also set the audio sampling frequency and the specific audio format (8 bits or 16 bits, single or dual channels ). We can use the iamstreamconfig of the capture output pin to complete the process. The following code is for reference:Hresult hR = pcapturepin-> QueryInterface (iid_iamstreamconfig, (void **) & pcfg ); <br/> // read current media type/format <br/> am_media_type * PMT = {0}; <br/> hR = pcfg-> getformat (& PMT ); <br/> If (succeeded (HR )) <br/>{< br/> // fill in values for the new format <br/> waveformatex * PWF = (waveformatex *) PMT-> pbformat; <br/> PWF-> nchannels = (Word) nchannels; <br/> PWF-> nsamplespersec = nfrequency; <br/> PWF-> navgbytespersec = lbytespersecond; <br/> PWF-> wbitspersample = (Word) (nbytespersample * 8); <br/> PWF-> nblockalign = (Word) (nbytespersample * nchannels ); <br/> // set the new formattype for the output pin <br/> hR = pcfg-> setformat (PMT); <br/> deletemediatype (PMT ); <br/>}< br/> // release interfaces <br/> pcfg-> release ();The last thing to mention is the special aspect of audio capturing: We can use the iambuffernegotiation interface on the capture output pin to change the buffer size of audio capturing to reduce the playback latency. By default, the audio capture filter uses a buffer of 0.5 seconds. For some special applications, such a large buffer is unnecessary, resulting in a large latency. Generally, it is very reliable to set the buffer to accommodate 80 ms of data, or even 30-40 ms is enough. However, it cannot be too small. Otherwise, the audio capturing efficiency will be affected and the sound quality will be damaged. The following code sets the buffer size for audio capturing for your reference:
Pcapturepin-> QueryInterface (iid_iambuffernegotiation, (void **) & PNEG ); <br/> // set the buffer size based on selected Settings <br/> allocator_properties prop = {0}; <br/> prop. cbbuffer = lbuffersize; <br/> prop. cbuffers = 6; <br/> prop. cbalign = nbytespersample * nchannels; <br/> hR = PNEG-> suggestallocatorproperties (& prop); <br/> PNEG-> release ();The above describes how to create an audio capturing program and how to set capture parameters. I believe you have some knowledge about how to write an audio capture program. Audio capturing directly produces PCM data. We can also compress it as needed, such as using MP3 format (Microsoft provides a free MP3 encoder) and AC3 format; after compression, the data volume is smaller, which can be used in many applications.