CMMSystem v1.10
Welcome to CMMSystem, a collection of freeware 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.
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 a "CMixerException*" / "CMixerException&"
to be thrown.
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.
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.
Usage
- To use the classes in your code simply add the CMMSystem.cpp and .h files
to your project
- As of v1.07, the classes are now designed for VC 2017 or later. They will
not compile on earlier releases of VC.
- To see the class in action, have a look at the code in various sample projects.
History
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)
Contacting the Author
PJ Naughter
Email: pjna@naughter.com
Web: http://www.naughter.com
11 June 2022