CMMSystem
v1.10 A set of C++ classes encapsulating the Win32 Multimedia APIs
Welcome to CMMSystem, a collection of C++ classes to encapsulate some
of the Win32 Multimedia APIs. Areas covered include the waveOut, waveIn, mmio and
mixer APIs
Ever since studying Audio Signal Processing in college, I've always been interested
in computer based audio. These classes are the results of my investigations into
base Win32 support for this area.
Features
- Provide auto clean up through the use of C++ destructors.
- Works equally well in Unicode as well as ASCII builds.
- Automatically links to the Windows Multimedia library namely "WinMM.lib"
- The classes make use of exceptions to report errors to help client code
which is developed to be as robust as possible.
- Hides the complicated buffer management issues which are involved in using
the waveIn / waveOut APIs.
- Included in the download is a number of sample projects to exercise the
various classes. They are:
PlayWav is a simple console application
which reads from any wav file using CMMIOFile and plays it back using the CWaveOut
class.
RecordWave is a simple console application which records to a wav
file using CMMIOFile and CWaveIn
ShowInput which displays a simple frequency
spectrum of the audio data received via waveIn in real-time in an AppWizard
generated MFC SDI application. This program opens the wave input using hard
coded values of 16 bit mono at a sampling frequency of 11025 hertz.
ModifyInput
which is a console application which reads from a 16 bit mono wav file and increases
the pitch of the signal by performing some simple frequency shifting and filtering
of the signal using a Fast Fourier Transform (FFT) and inverse FFT. Hopefully
what you should hear if you use a sample of your own voice as input is your
voice as if you have just inhaled a balloon full of helium!!. To compile both
ShowInput and ModifyInput, you should obtain the FFT class from
https://www.codeproject.com/Articles/6855/FFT-of-waveIn-audio-signals
which both of my sample projects use to implement an FFT.
The classes which constitute CMMSystem are:
CMMIOFile: This class implements a very simple wrapper for the "mmio..."
functions. These functions provide for reading and writing of RIFF files, which
the common .wav file is one instance of. Like all the classes in CMMSystem it is
exception based and will throw a "CMMIOException*" or ""CMMIOException&"
exception when any errors occur. For an example on how easy it is to use this class,
check out the code for the PlayWav and RecordWav sample projects included in the
download.
CWaveOut: This implements a wrapper for the "waveOut.." functions.
This was the first class developed in CMMSystem and was based on the great tutorial
on audio input processing from David Overton at
planet-source-code.com.
The class internally looks after all the details of
buffer management and provides a very simple Write method to send audio data to
it. Again any errors which occur in the class are reported as "CWaveOutException*"
/ "CWaveOutException&" exceptions.
CWaveIn: This is the corollary class to CWaveOut and provides support
for recording audio data. Again the details of buffer management is handled by the
class and a simple Read method is provided to obtain the recorded audio data. Any
errors will cause a "CWaveInException*" / "CWaveInException&"
exception to be thrown.
CMixer: The final class in CMMSystem, CMixer provides a thin veneer
over the very complicated area of the mixer APIs. I do not claim to be any expert
on this particular area and the wrapping provided is very thin. Again any errors
which occur internally will cause aa "CMixerException*" / "CMixerException&"
to be thrown.
Copyright
- You are allowed to include the source code in any product (commercial, shareware,
freeware or otherwise) when your product is released in binary form.
- You are allowed to modify the source code in any way you want except you
cannot modify the copyright details at the top of each module.
- If you want to distribute source code with your application, then you are
only allowed to distribute versions released by the author. This is to maintain
a single distribution point for the source code.
Updates
v1.10 (11 June 2022)
- Updated copyright details.
- Updated the code to use C++ uniform initialization for all variable
declarations.
v1.09 (30 December 2019)
- Fixed various Clang-Tidy static code analysis warnings in the code.
v1.08 (5 June 2019)
- Updated copyright details.
- Updated the code to clean compile on VC 2019
v1.07 (31 December 2018)
- Updated copyright details.
- Fixed a number of C++ core guidelines compiler warnings. These changes
mean that the code will now only compile on VC 2017 or later.
- Removed code which supported now defunct CMMSYSTEM_MFC_EXTENSIONS define
v1.06 (23 December 2017)
- Replaced CString::operator LPC*STR() calls throughout the codebase with
CString::GetString calls
- Replaced NULL throughout the codebase with nullptr. This means that the
minimum requirement for the framework is now VC 2010.
v1.05 (1 January 2017)
- Updated copyright details.
- Updated the ShowInput example application to include a Direct2D codepath
in addition to the existing GDI codepath. Please note that this optimization
requires at least VC 2010 to compile as it makes use of the D2D integration
added to MFC. This optimization helps improve the performance of this application
as well as demonstrating migration of code from GDI to D2D. By default D2D in
now used in this application but if you want to revert back to GDI you can define
the CSHOWINPUT_NOD2D preprocessor value.
- Updated the ShowInput example application to include a codepath which uses
NVIDIA CUDA to optimize the FFT logic using the cuFFT library. To enable support
for this you will need to have the NVIDIA CUDA Toolkit (https://developer.nvidia.com/cuda-toolkit)
installed. You will also need to define the CSHOWINPUT_USECUDA preprocessor
value in the ShowInput application. A prebuilt x64 CUDA enabled D2D implementation
is now provided in the download. Please note that cuFFT is only available in
CUDA when compiled for x64 as noted here:
http://stackoverflow.com/questions/29889897/cufft-lib-for-win32-is-missing
- Updated the ShowInput application to use a 44.1Khz input bit rate for the
audio. At this sampling rate and performing an FFT every 1024 samples, each
FFT bar shown in the spectrum corresponds to 42.06 Hertz. Also due to changing
to this higher sampling rate and the 1024 samples used for the FFT, it means
that the FFT in this app now updates at a rate of 43 frames per second instead
of the previous 10 frames per second when it was using a sampling rate of 11025Khz.
- Updated the ShowInput application to use wider rectangles to show the frequency
spectrum.
- The ShowInput sample application now shows the frequency spectrum normalized.
This means that the frequency with the largest amplitude is now shown with a
height equal to the client area of the application.
v1.04 (12 March 2016)
- Updated copyright details.
- Update the project settings to more modern defaults.
- Reworked the classes to optionally compile without MFC. By default the class
now use STL classes and idioms but if you define CMMSYSTEM_MFC_EXTENSIONS the
class will revert back to the MFC behaviour.
- Added SAL annotations to all the code.
- Updated the code to clean compile on VC 2010 - 2015
- Updated CWaveOut::GetPosition to allow the "cbmmt" parameter to waveOutGetPosition
to be specified.
- Updated CWaveOut::GetDevCaps to allow the "cbwoc" parameter to waveOutGetDevCaps
to be specified.
- Updated CWaveIn::GetPosition to allow the "cbmmt" parameter to waveInGetPosition
to be specified.
- Updated CWaveIn::GetDevCaps to allow the "cbwic" parameter to waveOutGetDevCaps
to be specified.
- Updated CMixer::GetDevCaps to allow the "cbmxcaps" parameter to waveOutGetDevCaps
to be specified.
v1.03 (24 January 2009)
- Updated copyright details
- The code has now been updated to support VC 2005 or later only.
- Updated code to compile correctly using _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
define
- Updated code to clean compile on VC 2008
- Code now compiles cleanly using Code Analysis (/analyze)
v1.02 (19 March 2008)
- Updated copyright details
- Updated the sample apps to clean compile on VC 2008
- Remove VC 6 style classwizard style comments from sample apps
- All Sleep calls now use 0 as their parameter to specify that the rest of
the time slice should be waited for
v1.01 (26 June 2006)
- Updated the documentation to use the same style as the web site.
- Made AfxThrow*Exception classes part of the their respective classes.
- Code now uses new C++ style casts rather than old style C casts where necessary.
- Updated copyright details
- Inclusion of a CMMSYSTEM_EXT_CLASS preprocessor define to allow the class
to be easily used in an extension dll.
- Optimized most of the constructor methods
- Made CWaveIn::GetBuffersFilled thread safe
- Made CWaveOut::GetBuffersFree thread safe
- Made the first parameter to CWaveOut::Write a "const void*".
- Made the first parameter to CWaveIn::Read a "void*".
- Updated code to ensure it clean(ish) compiles on VC 2005.
v1.0 (2 August 2005)