📄 gxsound.cs
字号:
using System;
using System.Data;
using System.IO;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Collections;
namespace GXSoundLibrary
{
/// <summary>
/// Sound interface. This is the entry point to the sound library for the
/// game. This library maintains a list of audio files.
/// </summary>
public class GXSound : IDisposable
{
/// <summary>
/// MessageWindow used to capture sound events.
/// </summary>
protected class SoundMessageWindow : Control
{
/// <summary>
/// Message passed to the audio system when a block has
/// finished playback.
/// </summary>
public const int WM_WOM_DONE = 0x03BD;
/// <summary>
/// Instance of GXSound that parents this message window.
/// </summary>
protected GXSound m_gs = null;
/// <summary>
/// Create an instance of the audio callback MessageWindow.
/// </summary>
/// <param name="gs">GXSound instance that owns this MessageWindow</param>
public SoundMessageWindow(GXSound gs)
{
m_gs = gs;
}
/// <summary>
/// Method that intercepts windows messages. This method passes
/// the WM_WOM_DONE message to the GXSound instance that created
/// this instance.
/// </summary>
/// <param name="msg">Windows message</param>
/*
protected override void WndProc(ref Message msg)
{
switch(msg.Msg)
{
case WM_WOM_DONE:
m_gs.SoundDone(msg.WParam);
break;
}
base.WndProc(ref msg);
}
*/
}
/// <summary>
/// SoundMessageWindow associated with the sound library.
/// </summary>
protected SoundMessageWindow m_msgWindow = null;
/// <summary>
/// Defines the capabilities of the Waveform Output Device
/// used by the sound library.
/// </summary>
WaveOut.WAVEOUTCAPS m_caps = null;
/// <summary>
/// Gets the number of devices available to the sound library.
/// </summary>
public uint NumDevices { get { return m_numDevices; } }
protected uint m_numDevices;
/// <summary>
/// Defines an invalid sound identifier.
/// </summary>
public const int kInvalidId = -1;
/// <summary>
/// List of sound instances maintained by the library.
/// </summary>
protected ArrayList m_soundList = new ArrayList();
/// <summary>
/// Gets/Sets the current Wavefore Audio Output Device in use by
/// the sound library.
/// </summary>
public uint CurDevice
{
get { return m_curDevice; }
set
{
m_curDevice = (value >= 0 && value < m_numDevices) ? value : m_curDevice;
WaveOut.waveOutGetDevCaps(m_curDevice, m_caps, m_caps.Size);
}
}
protected uint m_curDevice;
/// <summary>
/// Defines a sound that can be loaded and played by the sound library. A list
/// of instances of sounds is maintained by the library.
/// </summary>
protected class Sound
{
public WaveFile m_wf = null;
public int m_bufferSize = 0;
public string m_fileName = null;
}
/// <summary>
/// Create an instance of the sound libary.
/// </summary>
public GXSound()
{
m_numDevices = (uint)WaveOut.waveOutGetNumDevs();
m_curDevice = 0;
m_caps = new WaveOut.WAVEOUTCAPS();
WaveOut.waveOutGetDevCaps(m_curDevice, m_caps, m_caps.Size);
m_msgWindow = new SoundMessageWindow(this);
}
/// <summary>
/// Get the name of the specified Waveform Audio Output Device.
/// </summary>
/// <param name="deviceId">Id of the device. The first device is 0, and
/// the last is NumDevices-1.</param>
/// <returns>String representing the name of the device driver</returns>
public string GetDeviceName(uint deviceId)
{
string temp = m_caps.szPname;
if (deviceId == m_curDevice)
return m_caps.szPname;
WaveOut.WAVEOUTCAPS caps = new WaveOut.WAVEOUTCAPS();
WaveOut.waveOutGetDevCaps(deviceId, caps, m_caps.Size);
temp = caps.szPname;
return caps.szPname;
}
/// <summary>
/// Called when a sound has finished playing a block. Called by
/// the SoundMessageWindow.
/// </summary>
/// <param name="hwo">Handle to the Waveform Output Device that
/// was playing the block</param>
internal void SoundDone(IntPtr hwo)
{
// Find the instance of the sound that needs to be updated
foreach (Sound s in m_soundList)
{
if (s.m_wf.hwo == hwo.ToInt32())
{
s.m_wf.BlockDone();
break;
}
}
}
/// <summary>
/// Unload the specified sound. This sound is no longer needed
/// by the game.
/// </summary>
/// <param name="id">Id of sound, as returned by Load.</param>
public void Unload(int id)
{
if (id < 0 || id >= m_soundList.Count)
return;
Sound s = (Sound)m_soundList[id];
s.m_wf.Dispose();
m_soundList.RemoveAt(id);
}
/// <summary>
/// Place a sound in the list of sounds maintained by the library.
/// </summary>
/// <param name="fileName">Name of the sound's .wav file</param>
/// <param name="bufferSize">Total buffer size to use in playback</param>
/// <param name="preload">If true, the sound will be readied for playback.</param>
/// <returns>Id of the sound</returns>
public int Load(string fileName, int bufferSize, bool preload)
{
Sound s = new Sound();
s.m_bufferSize = bufferSize;
s.m_fileName = fileName;
s.m_wf = new WaveFile();
if (preload)
{
string fullName = Assembly.GetExecutingAssembly().GetName().CodeBase;
fullName = Path.GetDirectoryName(fullName);
fullName = Path.Combine(fullName, fileName);
if (Wave.MMSYSERR.NOERROR != s.m_wf.Load(CurDevice, fullName, m_msgWindow.Handle, bufferSize))
return kInvalidId;
}
return m_soundList.Add(s);
}
/// <summary>
/// Play the specified sound. If the sound was not preloaded then it will be
/// loaded at this time.
/// </summary>
/// <param name="id">Id of the sound, as returned by Load</param>
/// <param name="volLeft">Playback volume of left speaker</param>
/// <param name="volRight">Playback volume of right speaker</param>
public void Play(int id, ushort volLeft, ushort volRight)
{
if (id < 0 || id >= m_soundList.Count)
return;
Sound s = (Sound)m_soundList[id];
string fullName = Assembly.GetExecutingAssembly().GetName().CodeBase;
fullName = Path.GetDirectoryName(fullName);
fullName = Path.Combine(fullName, s.m_fileName);
s.m_wf.Play(CurDevice, fullName, m_msgWindow.Handle, s.m_bufferSize, volLeft, volRight);
}
/// <summary>
/// Stop playback of the specified sound.
/// </summary>
/// <param name="id">Id of sound, as returned by Load</param>
public void Stop(int id)
{
if (id < 0 || id >= m_soundList.Count)
return;
((Sound)m_soundList[id]).m_wf.Stop();
}
/// <summary>
/// Get the volume of the specified sound.
/// </summary>
/// <param name="id">Id of the sound, as returned by Load</param>
/// <param name="volLeft">Volume of left speaker</param>
/// <param name="volRight">Volum of right speaker</param>
public void GetVolume(int id, ref ushort volLeft, ref ushort volRight)
{
if (id < 0 || id >= m_soundList.Count)
return;
if ((m_caps.dwSupport & Wave.WAVECAPS_VOLUME) == 0)
{
volLeft = 0xffff;
volRight = 0xffff;
return;
}
((Sound)m_soundList[id]).m_wf.GetVolume(ref volLeft, ref volRight);
if ((m_caps.dwSupport & Wave.WAVECAPS_LRVOLUME) == 0)
volRight = volLeft;
}
/// <summary>
/// Set the volume of the specified sound.
/// </summary>
/// <param name="id">Id of sound, as returned by Load</param>
/// <param name="volLeft">Playback volume of left speaker</param>
/// <param name="volRight">Playback volume of right speaker</param>
public void SetVolume(int id, ushort volLeft, ushort volRight)
{
if (id < 0 || id >= m_soundList.Count)
return;
if ((m_caps.dwSupport & Wave.WAVECAPS_VOLUME) == 0)
return;
if ((m_caps.dwSupport & Wave.WAVECAPS_LRVOLUME) == 0)
volRight = volLeft;
((Sound)m_soundList[id]).m_wf.SetVolume(volLeft, volRight);
}
/// <summary>
/// Pause playback of the specified sound.
/// </summary>
/// <param name="id">Id of sound, as returned by Load</param>
public void Pause(int id)
{
if (id < 0 || id >= m_soundList.Count)
return;
((Sound)m_soundList[id]).m_wf.Pause();
}
/// <summary>
/// Resume paused playback of specified sound.
/// </summary>
/// <param name="id">Id of sound, as returned by Load</param>
public void Resume(int id)
{
if (id < 0 || id >= m_soundList.Count)
return;
((Sound)m_soundList[id]).m_wf.Resume();
}
/// <summary>
/// Free any resources allocated for the sound library.
/// </summary>
public void Dispose()
{
m_msgWindow.Dispose();
foreach (Sound s in m_soundList)
{
s.m_wf.Dispose();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -