Click here to Skip to main content
15,896,154 members
Articles / Desktop Programming / MFC

CWaveForm

Rate me:
Please Sign up or sign in to vote.
3.46/5 (7 votes)
24 Feb 20062 min read 190.4K   2.4K   57  
A simple wave form API wrapper class
/*
+===========================================================================+
|				Copyright (C) Direct Line Corp. 1999-2000.					|
+---------------------------------------------------------------------------+
| File Name:																|
|																			|
|	WaveForm.h																|
|																			|
+---------------------------------------------------------------------------+
| Descriptions:																|
|																			|
|	Win32 wave form API object oriented definition.							|
|																			|
+---------------------------------------------------------------------------+
| Developer(s):																|
|																			|
|	Xu Wen Bin.																|
|																			|
+===========================================================================+
|                         C H A N G E     L O G                             |
+---------------------------------------------------------------------------+
|																			|
|	07-20-01	1.00	Created.											|
|	08-08-01	1.01	Modified.											|
|	02-22-06	1.02	Modified.											|
|																			|
+---------------------------------------------------------------------------+
| Notes:	 																|
|																			|
|	1. Wave device sequence : open()->start()->stop()->close().				|
|	2. Support seperate operation on wave in and out object.				|
|																			|
+===========================================================================+
*/

#ifndef _WAVEFORM_H_
#define _WAVEFORM_H_

#include <Mmsystem.h>
#include <Mmreg.h>
#include <Msacm.h>
#include "Interface.h"

/****************************************************************************
 * Limitation for number of wave buffer can be queued in list.
 ****************************************************************************
 */
#define MIN_WAVE_NUM		4
#define MAX_WAVE_NUM		16
#define MAX_WAVE_BUFFER_LEN	8192
#define MAX_BUFFER_IN_QUEUE	MAX_WAVE_BUFFER_LEN * (MAX_WAVE_NUM / 2)

#define WAVE_FORM_FLOW_IN	0x00000001
#define WAVE_FORM_FLOW_OUT	0x00000002
#define WAVE_FORM_FLOW_BOTH	0x00000003

#define VALIDATE(x,y) x > y ? (x = y) : (y = x)

/****************************************************************************
 * External messages borrowed from [Thread.h].
 ****************************************************************************
 */
#define WM_STREAM_NOTIFY		WM_USER + 1
#define SUB_EVENT_WAVE_IN		0x00000001
#define SUB_EVENT_SOCKET_IN		0x00000002

#define WM_STREAM_CONTROL		WM_USER + 2
#define SUB_EVENT_WAVE_QUIT		0x00000001
#define SUB_EVENT_SOCKET_QUIT	0x00000002

/****************************************************************************
 * Internal wave frame structure.
 ****************************************************************************
 */
typedef struct stWaveFrame
{
	WAVEHDR waveHdr;
	CHAR    Data[MAX_WAVE_BUFFER_LEN];
} WAVEFRAME, *PWAVEFRAME;

typedef PWAVEFRAME * PPWAVEFRAME;

/****************************************************************************
 * Wave device state.
 ****************************************************************************
 */
#define WAVE_STATE_OPEN     0x0001
#define WAVE_STATE_CLOSE    0x0002
#define WAVE_STATE_START	0x0003
#define WAVE_STATE_STOP		0x0004
#define WAVE_STATE_RESET	0x0005
#define WAVE_STATE_PAUSE	0x0006
#define WAVE_STATE_RESTART	0x0007

/****************************************************************************
 * Wave device callback routines.
 ****************************************************************************
 */
static void CALLBACK WaveInCallBackRoutine
(
	HWAVEIN   hwi,
	UINT      uMsg,
	DWORD     dwInstance,
	DWORD     dwParam1,
	DWORD     dwParam2
);

static void CALLBACK WaveOutCallBackRoutine
(
	HWAVEOUT  hwo,
	UINT      uMsg,
	DWORD     dwInstance,
	DWORD     dwParam1,
	DWORD     dwParam2
);

static DWORD ThreadProcIn
(
    PVOID pData
);

static DWORD ThreadProcOut
(
    PVOID pData
);

/****************************************************************************
 * CWaveForm class definition.
 ****************************************************************************
 *
 */
class CWaveForm : public IIUnknown,
                  public IIStreamDevice,
				  public IIDataSource<PWAVEFRAME>,
				  public IIDataSink<PWAVEFRAME>,
                  public CAdvise
{
public:
    static BOOL SoundCardExists()
    {
        WAVEINCAPS waveInCaps;

        if (::waveInGetNumDevs() == 0)
        {
            ::MessageBox(0, _T("No sound card installed"), _T("WaveForm"), MB_OK);
            return FALSE;
        }

        if (waveInGetDevCaps(0, &waveInCaps, sizeof(WAVEINCAPS)) != MMSYSERR_NOERROR)
        {
            ::MessageBox(0, _T("Cannot determine sound card capabilities"), _T("WaveForm"), MB_OK);
            return FALSE;
        }

        return TRUE;
    }

public:
	CWaveForm
	(
		UINT           uDirection,
		UINT           uWaveInDeviceID,
		UINT           uWaveOutDeviceID,
		WAVEFORMATEX * lpWaveInFormatEx,
		WAVEFORMATEX * lpWaveOutFormatEx,
		DWORD          dwWaveInVolume,
		DWORD          dwWaveOutVolume
	);

	~CWaveForm();

	/////////////////////////////////////////////////////////////////////////
	// Standard interface implementation.
	/////////////////////////////////////////////////////////////////////////
	IMP_IIUNKNOWN();
	IMP_IISTREAMDEVICE();
	IMP_IIDATASOURCE(PWAVEFRAME);
	IMP_IIDATASINK(PWAVEFRAME);

	/////////////////////////////////////////////////////////////////////////
	// WaveForm spefific APIs.
	/////////////////////////////////////////////////////////////////////////
    BOOL GetFormat(UINT uDirection, LPWAVEFORMATEX lpWaveFormatEx);
	BOOL SetFormat(UINT uDirection, LPWAVEFORMATEX lpWaveFormatEx);
	BOOL UpdateFormat(UINT uDirection, LPWAVEFORMATEX lpWaveFormatEx);

	BOOL GetVolume(UINT uDirection, PDWORD pVolume);
	BOOL SetVolume(UINT uDirection, DWORD dwVolume);

	BOOL Compress(PVOID inData, ULONG inDataLength, PVOID outData, PULONG outDataLength);
	BOOL Uncompress(PVOID inData, ULONG inDataLength, PVOID outData, PULONG outDataLength);

private:
	LONG m_RefCount;

	UINT m_uDirection;
	UINT m_waveInState;
	UINT m_waveOutState;
	UINT m_waveInDeviceID;
	UINT m_waveOutDeviceID;

	WAVEFORMATEX m_waveInFormatEx;
	WAVEFORMATEX m_waveOutFormatEx;

	HWAVEIN  m_hWaveIn;
	HWAVEOUT m_hWaveOut;

	DWORD m_waveInVolume;
	DWORD m_waveOutVolume;

	DWORD m_dwWaveInByteInDevice;
	DWORD m_dwWaveOutByteInDevice;

	CRITICAL_SECTION m_waveInFrameFreeListLock;
	CRITICAL_SECTION m_waveInFrameWaitingListLock;
    CRITICAL_SECTION m_waveInFrameProcessListLock;
	CList<PWAVEFRAME,PWAVEFRAME&> m_waveInFrameFreeList;
	CList<PWAVEFRAME,PWAVEFRAME&> m_waveInFrameWaitingList;
    CList<PWAVEFRAME,PWAVEFRAME&> m_waveInFrameProcessList;

	CRITICAL_SECTION m_waveOutFrameFreeListLock;
	CRITICAL_SECTION m_waveOutFrameWaitingListLock;
    CRITICAL_SECTION m_waveOutFrameProcessListLock;
	CList<PWAVEFRAME,PWAVEFRAME&> m_waveOutFrameFreeList;
	CList<PWAVEFRAME,PWAVEFRAME&> m_waveOutFrameWaitingList;
    CList<PWAVEFRAME,PWAVEFRAME&> m_waveOutFrameProcessList;

    BOOL m_bWaveInProcessFlag;
    HANDLE m_hWaveInProcessEvent;
    HANDLE m_hWaveInProcessThread;

    BOOL m_bWaveOutProcessFlag;
    HANDLE m_hWaveOutProcessEvent;
    HANDLE m_hWaveOutProcessThread;

    void WaveInProcess();
    void WaveOutProcess();

    void OnWaveInData(PWAVEFRAME waveFrame);
	void OnWaveOutDone(PWAVEFRAME waveFrame);

    friend static void CALLBACK WaveInCallBackRoutine
	(
		HWAVEIN  hwi,
		UINT     uMsg,
		DWORD    dwInstance,
		DWORD    dwParam1,
		DWORD    dwParam2
	);
	friend static void CALLBACK WaveOutCallBackRoutine
	(
		HWAVEOUT  hwo,
		UINT      uMsg,
		DWORD     dwInstance,
		DWORD     dwParam1,
		DWORD     dwParam2
	);
    friend static DWORD ThreadProcIn
    (
        LPVOID lpData
    );
	friend static DWORD ThreadProcOut
    (
        LPVOID lpData
    );
};

#endif // _WAVEFORM_H_

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Program Manager Microsoft
China China
Graduated from Shanghai Tongji university in 1997 with bachelor degree in computer science, Wenbin got his first job as a system engineer at Bell Alcatel Mobile Shanghai office responsible for telcom-class mobile system development and deployment. Since then, Wenbin has in turn worked for Intel and Microsoft both inside and outside China, first as senior engineer, later project manager and then senior product manager.

With 15-year experience working with the world top IT companies, Wenbin has developed solid skill in C/C++, C#, Java, software engineering, agile development, etc, and multiple talents in product management, public presentation and speech, etc. He has always been an active member at PMI (Project Management Institution) and a regular lecture at Intel Developer Forum, Microsoft TechED conference as well as many other world-class industrial conferences. His wide-ranged industrial practice and high-level personal maturity have made him one of the best in public speech and professional training.

Over the years, Wenbin has cultivated his very own style in public speech, which is considered informative, engaging and refined. Since last year, Wenbin has also taken new adventure in project and product management consulting business and has proven high capacity through his work with many local emergent IT firms. Wenbin’s specialty in management consulting is on project management methodologies and processes, project management tools (e.g. MS Project), and team recruitment, build, and motivation.

In addition, Wenbin has received many professional qualifications including MCSE (Microsoft Certified System Engineer), MCSD (Microsoft Certified System Developer), MCDBA (Microsoft Certified Database Administrator), SCJP 2 (Sun Certified Java Programmer 2), and PMP (PMI Certified Project Management Professional). On top of that, Wenbin has got several on-duty inventions and one of them was successfully patented by United States Patent and Trademark Office.

Comments and Discussions