Click here to Skip to main content
15,867,453 members
Articles / Desktop Programming / MFC
Article

Converting Wav file to MP3 or other format using DirectShow

Rate me:
Please Sign up or sign in to vote.
4.84/5 (49 votes)
30 Jul 2002CPOL3 min read 698.5K   22.2K   188   128
Simple class to convert stereo 44 kHz, 16 bit wav file to another format, including MP3. The class shows how to use DirectShow API for audio conversion.

Sample Image - DShowEncoder.gif

Introduction

This article explains how to use the DirectShow API for simple audio conversion, particularly Wav to MP3 conversion. Audio codecs in the DirectShow API are of three type : native codecs, ACM codecs, and DMO (DirectX Media Object) codecs.

There are only few audio native codecs for audio compression. For MP3 encoding, the only one that I've found is the LAME DirectShow wrapper from Elecard. Most MP3 encoders are in the ACM (Audio Compression Manager) format, wich was introduced with the Windows Multimedia API. CDSEncoder class and it's relative classes CDSCodec and CDSCodecFormat enumerate ACM codecs and their respective compression parameters, construct a graph and do the encoding.

The GraphBuilder and other filters

Image 2

The graph consist of five filters:

  • File source (async) for reading the input wav file,
  • WAV Parser for wav parsing,
  • ACM codec for audio compression (in this case : MP3 ACM, wrapped by the ACM Wrapper Filter),
  • WAV Dest, for wav output multiplexing,
  • File Writer for writing the output file.

Important note

The WAV Dest filter is not included in standard filters, but need to be compiled from the DirectX SDK (SDK_root\Samples\Multimedia\DirectShow\Filters\WavDest). For convenience, the compiled WAV Dest filter is included in the demo zip, but you have to register it by RegSrv32 wavdest.ax.

ACM codecs and the ACM Wrapper filter

All of the ACM codecs are listed in DirectShow in the Audio Compressors Filter Category (CLSID_AudioCompressorCategory) and cannot be instantiated directly. We have to use the Device Enumerator to use them.

Note : Depending of your configuration, several ACM codecs for a same format can be installed on your computer. This can be the case for MP3 codecs. You set priority or deactivate some of them by the use of control panel, as show in the following figure.

Codec configuration

The DeviceEnumerator or how to browse ACM codecs

The Device Enumerator must be used to retrieve an instance of an ACM codec. It returns the codecs list by the IEnumMoniker interface, so we can get the filter interface (IBaseFilter) by a call to IMoniker::BindToObject() and the filter name by a call to IMoniker::BindToStorage().

Configuring the ACM codec with IAMStreamConfig interface

Once the desired codec is instantiated, we can obtain an IBaseFilter interface for filter configuration. Since each IBaseFilter have one or more Pin, we have to search the output Pin by the use of the IEnumPins interface and IPin::QueryDirection() calls.
With the output Pin, we can query the IAMStreamConfig interface to configure the following property :

  • Numbers of channels,
  • Samples per second,
  • Average byte per second,
  • Bits per sample.

Note : For some codecs (including MP3), the call to IAMStreamConfig::SetFormat() must be after the graph rendering.

The classes

CDSEncoder

CDSEncoder assumes the following task :

  • Enumerate the Audio codecs (CLSID_AudioCompressorCategory),
  • Build, render, and run the graph.

class CDSEncoder : public CArray<CDSCodec*, CDSCodec*>
{
public:
  void BuildGraph(CString szSrcFileName, CString szDestFileName, 
    int nCodec, int nFormat);
  CDSEncoder();
  virtual ~CDSEncoder();

protected:
  void BuildCodecArray();
  HRESULT AddFilterByClsid(IGraphBuilder *pGraph, LPCWSTR wszName, 
    const GUID& clsid, IBaseFilter **ppF);
  BOOL SetFilterFormat(AM_MEDIA_TYPE* pStreamFormat, 
    IBaseFilter* pBaseFilter);

  IGraphBuilder *m_pGraphBuilder;
};

As CDSEncoder inherits from CArray, the collection of codecs is exposed by CArray methods with each codecs returned as CDSCodec object.

CDSCodec

CDSCodec assumes the following task :

  • Enumerate the codec supported parameters,
  • expose the codec name.

class CDSCodec : public CArray<CDSCodecFormat*, CDSCodecFormat*>
{
public:
  CDSCodec();
  virtual ~CDSCodec();

  CString m_szCodecName;
  IMoniker  *m_pMoniker;
  void BuildCodecFormatArray();
};

As CDSCodec inherits from CArray, the collection of codecs supported parameters is exposed by CArray methods with each parameters returned as CDSCodecFormat object.

CDSCodecFormat

CDSCodecFormat exposes the properties of one-codec parameters :

  • Number of channels,
  • Samples per second,
  • Bytes per second,
  • Bits per samples.

class CDSCodecFormat  
{
public:
  WORD BitsPerSample();
  DWORD BytesPerSec();
  DWORD SamplesPerSecond();
  WORD NumberOfChannels();
  CDSCodecFormat();
  virtual ~CDSCodecFormat();

public:
  AM_MEDIA_TYPE* m_pMediaType;
};

Known issues

Errors Checking

The article goal is to demonstrate the use of DirectShow for simple audio conversion. These classes are not as safe as they have to be. Please keep this in mind if you plan to use it in a production environment.

Source Wav format

There are no sampling conversion, so you can only generate 44 kHz output files if you use 44 kHz Wav.

Windows Media

Windows Media format can be used only with a certificate that can be obtained by the Windows Media SDK from Microsoft.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) G. LABOURE
France France
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralRe: MPEG to VOB,IFO,BUP Files Pin
Anonymous3-Jun-04 0:38
Anonymous3-Jun-04 0:38 
GeneralRe: MPEG to VOB,IFO,BUP Files Pin
Member 1388937-Jun-04 14:25
Member 1388937-Jun-04 14:25 
GeneralRe: MPEG to VOB,IFO,BUP Files Pin
Member 1388937-Jun-04 14:28
Member 1388937-Jun-04 14:28 
GeneralRe: MPEG to VOB,IFO,BUP Files Pin
Anonymous15-Jul-04 23:59
Anonymous15-Jul-04 23:59 
GeneralMPEG To DVD Convertor Pin
Osman Ishaque3-Dec-03 2:03
Osman Ishaque3-Dec-03 2:03 
GeneralDoesn't work Pin
LioLick26-Nov-03 20:38
LioLick26-Nov-03 20:38 
GeneralCan't Compile - dshow.h ERROR 2 !!!!!!!!! Pin
alan938-Oct-03 14:22
alan938-Oct-03 14:22 
GeneralRe: Can't Compile - dshow.h ERROR 2 !!!!!!!!! Pin
Jigar Mehta20-Jul-04 19:29
Jigar Mehta20-Jul-04 19:29 
Yes

I am also getting the same problem but don't want to fill in the blank... It is there goodness that they are putting their good work on the site... Thanks!!! But please try to solve this problem.. Which thing I should install???

and another thing, I have downloaded EXE version of this and still I am not getting any format on the right side when I select MPEG Layer 3 from the list on the left side... So, what should I download??? The author of the article should see this matter...

Jigar Mehta
(jigarmehta@gatescorp.com)

Software Developer
Gates Information Systems
QuestionHow to save a System.Drawing.Drawing2D.region object to file? Pin
melee29-Sep-03 23:30
melee29-Sep-03 23:30 
AnswerRe: How to save a System.Drawing.Drawing2D.region object to file? Pin
Anonymous12-Oct-03 23:09
Anonymous12-Oct-03 23:09 
Generalthe same dshow .h error !!! Pin
dharani28-Sep-03 18:03
dharani28-Sep-03 18:03 
GeneralConverting .cvh to .wav files Pin
Anonymous28-Aug-03 7:01
Anonymous28-Aug-03 7:01 
GeneralRe: Converting .cvh to .wav files Pin
Anonymous20-Jun-04 7:45
Anonymous20-Jun-04 7:45 
GeneralRe: Converting .cvh to .wav files Pin
Anonymous20-Jun-04 7:46
Anonymous20-Jun-04 7:46 
GeneralCan't get Encoders Pin
alan9326-Jun-03 5:34
alan9326-Jun-03 5:34 
GeneralRe: Can't get Encoders Pin
alan9326-Jun-03 5:35
alan9326-Jun-03 5:35 
GeneralG723 problem Pin
leg22-Apr-03 1:22
leg22-Apr-03 1:22 
GeneralACM wrapper for mp3 to make directshow filter Pin
ashish srivastava9-Mar-03 19:32
ashish srivastava9-Mar-03 19:32 
Generalhelp me Pin
dharani28-Sep-03 18:01
dharani28-Sep-03 18:01 
GeneralACM wrapper for mp3 Pin
ashish srivastava9-Mar-03 19:32
ashish srivastava9-Mar-03 19:32 
GeneralACM wrapper for mp3 Pin
ashish srivastava9-Mar-03 19:31
ashish srivastava9-Mar-03 19:31 
GeneralConvert to .Net Pin
Member 2029375-Mar-03 19:37
Member 2029375-Mar-03 19:37 
GeneralRe: Convert to .Net Pin
Chris P.7-May-04 9:19
Chris P.7-May-04 9:19 
GeneralCould not compress the file. Pin
sudeepmallik17-Feb-03 1:58
sudeepmallik17-Feb-03 1:58 
GeneralRe: Could not compress the file. Pin
viren_123_india17-Nov-03 20:29
viren_123_india17-Nov-03 20:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.