Click here to Skip to main content
15,885,546 members
Articles / Programming Languages / C#

A simple C# Wave editor, part 1: Background and analysis

Rate me:
Please Sign up or sign in to vote.
4.77/5 (80 votes)
5 Aug 200411 min read 355.4K   8.2K   132  
The first phase of a RIFF/Wave editing "swiss army knife", in which we'll learn how to extract all the data present in common Wave files and store it in an XML document.
// CEditWaveFile.h: interface for the CEditWaveFile class.
//
//
// Created for editing a wav file
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CEDITWAVEFILE_H__4D07CE61_46F7_11D3_9A58_0080C605ADA4__INCLUDED_)
#define AFX_CEDITWAVEFILE_H__4D07CE61_46F7_11D3_9A58_0080C605ADA4__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//############################################################################
// Wav file structures
typedef DWORD FOURCC;	// a four character code 

typedef struct CHUNKHDR {
  FOURCC ckid;		// chunk ID 
  DWORD dwSize; 	// chunk size 
} CHUNKHDR;

#if	0
/* general waveform format structure (information common to all formats) */
typedef struct waveformat_tag {
  WORD wFormatTag;	/* format type */
  WORD nChannels;	/* number of channels (i.e. mono, stereo, etc.) */
  DWORD nSamplesPerSec; /* sample rate */
  DWORD nAvgBytesPerSec;/* for buffer size estimation */
  WORD nBlockAlign;	/* block size of data */
} WAVEFORMAT;
typedef WAVEFORMAT	 *PWAVEFORMAT;
#endif

/* flags for 'wFormatTag' field of WAVEFORMAT */
#define WAVE_FORMAT_PCM 1

/* specific waveform format structure for PCM data */
typedef struct pcmwaveformat_tag {
  WORD wFormatTag;	/* format type */
  WORD nChannels;	/* number of channels (i.e. mono, stereo, etc.) */
  DWORD nSamplesPerSec; /* sample rate */
  DWORD nAvgBytesPerSec;/* for buffer size estimation */
  WORD nBlockAlign;	/* block size of data */
  WORD wBitsPerSample;
} PCMWAVEFORMAT;
typedef PCMWAVEFORMAT *PPCMWAVEFORMAT;


/* MMIO macros */
#define mmioFOURCC(ch0, ch1, ch2, ch3) \
  ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
  ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))

#define FOURCC_RIFF	mmioFOURCC ('R', 'I', 'F', 'F')
#define FOURCC_SFPK	mmioFOURCC ('S', 'F', 'P', 'K')
#define FOURCC_LIST	mmioFOURCC ('L', 'I', 'S', 'T')
#define FOURCC_WAVE	mmioFOURCC ('W', 'A', 'V', 'E')
#define FOURCC_FMT	mmioFOURCC ('f', 'm', 't', ' ')
#define FOURCC_DATA	mmioFOURCC ('d', 'a', 't', 'a')


/* simplified header for standard WAV files */
typedef struct WAVEHDR {
  CHUNKHDR chkRiff; // 8 bytes
  FOURCC fccWave; // 4 bytes
  CHUNKHDR chkFmt;//8 bytes
  WORD wFormatTag;	/* format type  2 bytes*/
  WORD nChannels;	/* 2 bytes number of channels (i.e. mono, stereo, etc.) */
  DWORD nSamplesPerSec; /* 4 bytes sample rate */
  DWORD nAvgBytesPerSec;/* 4 bytes for buffer size estimation */
  WORD nBlockAlign;	/* 2 bytes block size of data */
  WORD wBitsPerSample;//4 bytes
  CHUNKHDR chkData;//8 bytes
} WAVEHDR;/*
 * ---------------------------------------------------------------------
 *  definitions for RIFF output (from Windows MMSYSTEM)
 * ---------------------------------------------------------------------
 */

typedef DWORD FOURCC;	/* a four character code */



/* general waveform format structure (information common to all formats) */
typedef struct waveformat_tag {
  WORD wFormatTag;	/* format type */
  WORD nChannels;	/* number of channels (i.e. mono, stereo, etc.) */
  DWORD nSamplesPerSec; /* sample rate */
  DWORD nAvgBytesPerSec;/* for buffer size estimation */
  WORD nBlockAlign;	/* block size of data */
} WAVEFORMAT;
typedef WAVEFORMAT	 *PWAVEFORMAT;

#include "CPeak.h"
#include <deque>
using namespace std;
//#include "MMWaveEditXCtl.h"
class CMMWaveEditXCtrl;
class CEditWaveFile  
{
	public:
		CEditWaveFile();
		virtual ~CEditWaveFile();

		// Variables
		CString				m_sWaveFileName;

		long				m_lMaxZoom;
		long				m_lTotalFileLength;
		long				m_lCurrentZoomFactor;
		long				m_lLastZoomFactorUsed;
		WAVEHDR				m_WaveHeader;
		BOOL				m_bPeakFileBeingUsed;
		BOOL				m_bInitialized;
		long				m_lCurFilePosition;
		deque<CPoint>		m_lPoints;
		deque<CPoint>		m_rPoints;
		long				m_lTotalLPoints;
		long				m_lCursorPosition;
		long				m_lStartOfSelection;
		CRect				m_rcLastSelectRect;
		BOOL				m_bDraggingCursorInSel;

		//Temp
		CMMWaveEditXCtrl*	m_lpOwnerCtrl;
		// Fucntions

	public:

		long				GetSamplesPerSecond				();
		long				GetNumberOfChannels				();
		long				GetTotalFileLength				();
		void				GetScrollRanges					(long& lLow,long&lHigh,CRect& rcBounds);

		BOOL				InitializeFile					(CString sFilename);
		void				BuildPeakFile16BS				();
		void				BuildPeakFile16B				();
		void				BuildPeakFile8BS				();
		void				BuildPeakFile8B					();
		// Manipulations
		void				ZoomInToNextLevel				();
		void				ZoomOutToNextLevel				();
		// Bitmap Creation
		void				Draw							(CDC* lpDC,CRect rcBounds);
		float				GetFileLengthInSeconds			();

		void				SetCursorPosition				(long lPosition);
		void				SetSelectionPosition			(long lPosition);
		void				GetSelectionRanges				(long& lLow,long& lHigh);	

		CRect				SizingSelection					(long lPosition,CRect rcBounds);
		void				BeginingDragOfSelection			(long lPosition,CRect rcBounds,BOOL bLeft);


		void				SetCursorAsStartSelec			();
		BOOL				IsCursorVisible					(CRect& rcBounds);

		CRect				GetSelectionRect				(CRect& rcBounds);
		// Playing curosr
		BOOL				IsPointVisible					(CRect& rcBounds,long lFilePosition);

	private:
		BOOL				IsThereACurrentPeakFile			();
		long				GetMaxZoomFactor16BS			(CFile* lpFile);
		long				GetMaxZoomFactor16B				(CFile* lpFile);
		long				GetMaxZoomFactor8BS				(CFile* lpFile);
		long				GetMaxZoomFactor8B				(CFile* lpFile);

		// Bitmap
		void				Create16BSWaveFormBmp			(CDC* lpDC,CRect rcBounds);
		void				Create16BWaveFormBmp			(CDC* lpDC,CRect rcBounds);
		void				Create8BSWaveFormBmp			(CDC* lpDC,CRect rcBounds);
		void				Create8BWaveFormBmp				(CDC* lpDC,CRect rcBounds);

		void				Draw16BSdbLine					(CDC* lpDC,CRect rcBounds,float& scale);
		void				Draw16BScale					(CDC* lpDC,CRect rcBounds,float& scale);
		void				Draw16BSWaveformDirectlyFromFile(CDC* lpDC,CRect rcBounds);
		void				DrawUnInitialized				(CDC* lpDC,CRect rcBounds);

};

#endif // !defined(AFX_CEDITWAVEFILE_H__4D07CE61_46F7_11D3_9A58_0080C605ADA4__INCLUDED_)

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
Web Developer
Canada Canada
Jonathan Kade is a native of Detroit, MI. He's interested in multimedia, hardware/software interfacing, working with low-level data, and low-level programming in general.

Comments and Discussions