Click here to Skip to main content
15,886,069 members
Articles / Mobile Apps

Nerdkill game for PocketPC

Rate me:
Please Sign up or sign in to vote.
4.46/5 (29 votes)
28 Jun 2004CPOL13 min read 101.7K   1.2K   35  
A shoot'em up platform in C# for the .NET Compact Framework.
//*******************************************************************
/*

	Solution:	NerdkillPocket
	Project:	NerdkillPocket
	File:		RWaveOut.cs

	Copyright 2003, 2004, Raphael MOLL.

	This file is part of NerdkillPocket.

	NerdkillPocket is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	NerdkillPocket is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with NerdkillPocket; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

*/
//*******************************************************************



using System;
using System.Reflection;
using System.Runtime.InteropServices;

//*********************************************
namespace Alfray.Nerdkill.Platform.RPocketSound
{
	//***************************************************
	/// <summary>
	/// RWaveOut abstracts the usage of the WaveOut interface
	/// from Windows/Windows CE under C# for the Nerdkill Project.
	/// 
	/// Details can be found here:
	/// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetcomp/html/WaveInOut.asp
	/// 
	/// Disclaimer:
	/// Note that the MSDN article can be used as a reference (especially for the syntax
	/// of DllImport) and the general idea, yet this class is NOT an exact copy of
	/// the classes provided by the MSDN P/Invoke Library. There are significant differences
	/// due to the fact that this class only implements the bare minimum needed by the
	/// Nerdkill project. It should NOT be considered a generic implementation of WaveOut in C#.
	/// 
	/// The following APIs are mapped here:
	/// - WAVEFORMATEX
	/// - WAVEHDR
	/// - WAVE_MAPPER
	/// - CALLBACK_FUNCTION
	/// - waveOutOpen
	/// - waveOutGetErrorText
	/// - waveOutPrepareHeader
	/// - waveOutWrite
	/// - waveOutUnprepareHeader
	/// - waveOutReset
	/// - waveOutClose
	/// </summary>
	//***************************************************
	public abstract class RWaveOut
	{
		//-------------------------------------------
		//----------- Public Constants --------------
		//-------------------------------------------

		// WAVE_MAPPER can be used in place of a device identifier when opening an audio device in order to automatically find a best fit.
		public const uint WAVE_MAPPER = unchecked((uint)(-1));

		// CALLBACK_WINDOW is used when opening an audio device to specify that windows messages will be the method for receiving feedback from the audio system.
		public const uint CALLBACK_WINDOW  = 0x10000;

		// Messages sent to the window callback by WaveOut -- RM 20040523
		public const int MM_WOM_OPEN = 0x3BB;
		public const int MM_WOM_CLOSE = 0x3BC;
		public const int MM_WOM_DONE = 0x3BD;

		// flags for wFormatTag field of WAVEFORMAT -- extracted from mmsystem.h
		public const uint WAVE_FORMAT_PCM = 1;

		// The WF_OFFSET constants are defined to provide locations associated with WAVEFORMATEX members in a file.
		// WF_OFFSET_DATA specifies the file location at which actual audio data starts.
		public const int WF_OFFSET_FORMATTAG = 20;
		public const int WF_OFFSET_CHANNELS = 22;
		public const int WF_OFFSET_SAMPLESPERSEC = 24;
		public const int WF_OFFSET_AVGBYTESPERSEC = 28;
		public const int WF_OFFSET_BLOCKALIGN = 32;
		public const int WF_OFFSET_BITSPERSAMPLE = 34;
		public const int WF_OFFSET_DATA = 44;

		// Size of a WAVEHDR structure -- RM 20040524
		public static uint SizeofWAVEHDR = (uint)Marshal.SizeOf(typeof(WAVEHDR));

		// Possible values for WAVEHDR.dwFlags -- RM 20040525
		public const int WHDR_DONE       = 0x00000001;  /* done bit */
		public const int WHDR_PREPARED   = 0x00000002;  /* set if this header has been prepared */
		public const int WHDR_BEGINLOOP  = 0x00000004;  /* loop start block */
		public const int WHDR_ENDLOOP    = 0x00000008;  /* loop end block */
		public const int WHDR_INQUEUE    = 0x00000010;  /* reserved for driver */

		//-------------------------------------------
		//----------- Public Classes ----------------
		//-------------------------------------------

		[StructLayout(LayoutKind.Sequential)]
		public class WAVEFORMATEX
		{
			public ushort wFormatTag;
			public ushort nChannels;
			public uint nSamplesPerSec;
			public uint nAvgBytesPerSec;
			public ushort nBlockAlign;
			public ushort wBitsPerSample;
			// public ushort cbSize; -- not used for PCM data
		}

		[StructLayout(LayoutKind.Sequential)]
		public class WAVEHDR
		{
			public IntPtr lpData;
			public uint dwBufferLength;
			public uint dwBytesRecorded;
			public uint dwUser;
			public uint dwFlags;
			public uint dwLoops;
			public IntPtr lpNext;
			public uint reserved;
		}


		public enum MMSYSERR : int
		{
			NOERROR = 0,
			ERROR = (MMSYSERR_BASE + 1),
			BADDEVICEID = (MMSYSERR_BASE + 2),
			NOTENABLED = (MMSYSERR_BASE + 3),
			ALLOCATED = (MMSYSERR_BASE + 4),
			INVALHANDLE = (MMSYSERR_BASE + 5),
			NODRIVER = (MMSYSERR_BASE + 6),
			NOMEM = (MMSYSERR_BASE + 7),
			NOTSUPPORTED = (MMSYSERR_BASE + 8),
			BADERRNUM = (MMSYSERR_BASE + 9),
			INVALFLAG = (MMSYSERR_BASE + 10),
			INVALPARAM = (MMSYSERR_BASE + 11),
			HANDLEBUSY = (MMSYSERR_BASE + 12),
			INVALIDALIAS = (MMSYSERR_BASE + 13),
			BADDB = (MMSYSERR_BASE + 14),
			KEYNOTFOUND = (MMSYSERR_BASE + 15),
			READERROR = (MMSYSERR_BASE + 16),
			WRITEERROR = (MMSYSERR_BASE + 17),
			DELETEERROR = (MMSYSERR_BASE + 18),
			VALNOTFOUND = (MMSYSERR_BASE + 19),
			NODRIVERCB = (MMSYSERR_BASE + 20),
			LASTERROR = (MMSYSERR_BASE + 20),

			WAVERR_BADFORMAT = (WAVERR_BASE + 0),   /* unsupported wave format */
			WAVERR_STILLPLAYING = (WAVERR_BASE + 1),    /* still something playing */
			WAVERR_UNPREPARED = (WAVERR_BASE + 2),    /* header not prepared */
			WAVERR_SYNC = (WAVERR_BASE + 3),    /* device is synchronous */
			WAVERR_LASTERROR = (WAVERR_BASE + 3),    /* last error in range */
		}


		//-------------------------------------------
		//----------- Public Methods ----------------
		//-------------------------------------------

		[DllImport ("coredll.dll")]
		public static extern MMSYSERR waveOutOpen(ref IntPtr phwi,
			uint uDeviceID, WAVEFORMATEX pwfx, IntPtr dwCallback,
			uint dwInstance, uint fdwOpen);

		[DllImport ("coredll.dll")]
		public static extern MMSYSERR waveOutPrepareHeader(IntPtr hwo,
			IntPtr /*WAVEHDR*/ pwh, uint cbwh);

		[DllImport ("coredll.dll")]
		public static extern MMSYSERR waveOutWrite(IntPtr hwo,
			IntPtr /*WAVEHDR*/ pwh, uint cbwh);

		[DllImport ("coredll.dll")]
		public static extern MMSYSERR waveOutUnprepareHeader(IntPtr
			hwo, IntPtr /*WAVEHDR*/ pwh, uint cbwh);

		[DllImport ("coredll.dll")]
		public static extern MMSYSERR waveOutClose(IntPtr hwo);

		[DllImport ("coredll.dll")]
		public static extern MMSYSERR waveOutReset(IntPtr hwo); 

		//[DllImport ("coredll.dll")]
		//public static extern MMSYSERR waveOutGetErrorText(uint mmrError,
		//	out string pszText, uint cchText); 


		//-------------------------------------------
		//----------- Private Methods ---------------
		//-------------------------------------------


		//-------------------------------------------
		//----------- Private Attributes ------------
		//-------------------------------------------

		private const int WAVERR_BASE = 32;
		private const int MMSYSERR_BASE = 0;

	} // class class RWaveOut
} // namespace Alfray.Nerdkill.Platform.RPocketSound


//---------------------------------------------------------------
//	[C# Template RM 20040516]
//	$Log: RWaveOut.cs,v $
//	Revision 1.2  2004/05/26 08:48:13  ralf
//	Fixes in WaveOut mixer.
//	
//	Revision 1.1  2004/05/24 14:24:44  ralf
//	WinCE's WaveOut sound threaded mixer.
//	
//---------------------------------------------------------------

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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
Raphael is a senior software engineer with a background in electronics engineering.
He enjoys programming in C++ since 1994.
He developed professional software for the BeOS and now focuses on Windows, MacOS and Linux software development.
He uses C++, C#, Java,VB.Net, PHP, Bash and Perl on a regular basis. He is familiar with C, Objective-C, VB6, Python, ML, Haskell, Lisp, Scheme, some obsolete languages (Basic and Pascal) and x86/Motorola assembly languages.
Raphael is a big fan of the .Net platform.
A number of open source personal projects can be found on his web site.

Comments and Discussions