⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 waveout.cs

📁 PPC 上 播放声音的一些测试使用
💻 CS
📖 第 1 页 / 共 3 页
字号:
				catch
				{
				}
			}

			/// <summary>
			/// Called by the MessageWindow when the buffer currently being played has
			/// finished.  This method starts the loading of the next block on a
			/// separate thread.  If the current block is the last one then playback is
			/// stopped.
			/// </summary>
			public void BlockDone()
			{
				m_curBlock++;

				try
				{
					if (m_curBlock < m_numBlocks)
					{
						//Debug.Assert((m_whdr[(m_curBlock + 2) % 2].dwFlags & Wave.WAVEHDR.WHDR_INQUEUE) != 0,						"ERROR: A sound block finished before the subsequent block was written.");

						if(this.m_playing)
						{
							Thread loadThread = new Thread(new ThreadStart(LoadBuffer));
							loadThread.Start();
						}
					}
					else if (m_curBlock == m_numBlocks)
					{
						 Stop();
					}
				}
				catch
				{}
			}

			/// <summary>
			/// Stop playing the current file and clean up all resources.
			/// </summary>
			public void Stop()
			{
				waveOutReset(m_hwo);

				m_playing = false;

				if (m_rdr != null)
				{
					m_rdr.BaseStream.Close();
					m_rdr.Close();
					m_rdr = null;
				}

				for (int i = 0; i < 2; i++)
				{
					if (m_whdr[i] != null)
					{
						lock(m_whdr[i])
						{
							if (m_hwo != IntPtr.Zero)
								waveOutUnprepareHeader(m_hwo, m_whdr[i], (uint)Marshal.SizeOf(m_whdr[i]));

							m_whdr[i].Dispose();
							m_whdr[i] = null;
						}
					}
				}

				if (m_hwo != IntPtr.Zero)
					waveOutClose(m_hwo);

				m_hwo = IntPtr.Zero;
				m_wfmt = null;

			}

			/// <summary>
			/// Resume the playback of a paused sound.
			/// </summary>
			/// <returns>MMSYSERR.NOERROR if successful</returns>
			public Wave.MMSYSERR Resume()
			{
				return waveOutRestart(m_hwo);
			}

			/// <summary>
			/// Pause the playback of a sound.
			/// </summary>
			/// <returns>MMSYSERR.NOERROR if successful</returns>
			public Wave.MMSYSERR Pause()
			{
				return waveOutPause(m_hwo);
			}

			/// <summary>
			/// Get the volume of this sound.
			/// </summary>
			/// <param name="volLeft">Left channel volume level</param>
			/// <param name="volRight">Right channel volume level</param>
			/// <returns>MMSYSERR.NOERROR if successful</returns>
			public Wave.MMSYSERR GetVolume(ref ushort volLeft, ref ushort volRight)
			{
				uint vol = 0;

				Wave.MMSYSERR result = waveOutGetVolume(m_hwo, ref vol);
				if (result != Wave.MMSYSERR.NOERROR)
					return result;

				volLeft = (ushort)(vol & 0x0000ffff);
				volRight = (ushort)(vol >> 16);

				return Wave.MMSYSERR.NOERROR;
			}

			/// <summary>
			/// Sets the volume of this sound.
			/// </summary>
			/// <param name="volLeft">Left channel volume level</param>
			/// <param name="volRight">Right channel volume level</param>
			/// <returns>MMSYSERR.NOERROR if successful</returns>
			public Wave.MMSYSERR SetVolume(ushort volLeft, ushort volRight)
			{
				uint vol = ((uint)volLeft & 0x0000ffff) | ((uint)volRight << 16);
				return waveOutSetVolume(m_hwo, vol);
			}

			/// <summary>
			/// Clean up all resources.
			/// </summary>
			public void Dispose()
			{
				Stop();
			}
		}

		/// <summary>
		/// Defines the MessageWindow used to receive messages from the audio
		/// system.
		/// </summary>
		public class SoundMessageWindow : MessageWindow
		{
			public const int MM_WOM_OPEN  = 0x03BB;
			public const int MM_WOM_CLOSE = 0x03BC;
			public const int MM_WOM_DONE  = 0x03BD;

			// Instance of a playback interface
			protected WaveOut m_wo = null;

			public SoundMessageWindow(WaveOut wo)
			{
				m_wo = wo;
			}

			protected override void WndProc(ref Message msg)
			{
				switch (msg.Msg)
				{
					// When this message is encountered, a block is
					// done playing, so notify the WaveOut instance.
					case MM_WOM_DONE:
						m_wo.BlockDone(msg.WParam);
						break;

				}
				base.WndProc(ref msg);
			}
		}

		/// <summary>
		/// Maintain an instance of a MessageWindow that handles audio messages.
		/// </summary>
		protected SoundMessageWindow m_msgWindow = null;

		/// <summary>
		/// An instance of WaveFile used as the source for playing audio.
		/// </summary>
		protected WaveFile m_file = null;

		/// <summary>
		/// Create an instance of WaveOut.
		/// </summary>
		public WaveOut()
		{
			m_msgWindow = new SoundMessageWindow(this);
			m_file = new WaveFile();
		}

		/// <summary>
		///  Determine the number of available playback devices.
		/// </summary>
		/// <returns>Number of output devices</returns>
		public uint NumDevices()
		{
			return (uint)waveOutGetNumDevs();
		}

		/// <summary>
		/// Get the name of the specified playback device.
		/// </summary>
		/// <param name="deviceId">ID of the device</param>
		/// <param name="prodName">Destination string assigned the name</param>
		/// <returns>MMSYSERR.NOERROR if successful</returns>
		public Wave.MMSYSERR GetDeviceName(uint deviceId, ref string prodName)
		{
			WAVEOUTCAPS caps = new WAVEOUTCAPS();
			Wave.MMSYSERR result = waveOutGetDevCaps(deviceId, caps, caps.Size);
			if (result != Wave.MMSYSERR.NOERROR)
				return result;

			prodName = caps.szPname;

			return Wave.MMSYSERR.NOERROR;
		}

		/// <summary>
		/// Specifies if playback has finished.
		/// </summary>
		/// <returns>true if no playback is in progress.</returns>
		public bool Done()
		{
			if (m_file != null)
				return m_file.Done;

			return true;
		}

		/// <summary>
		/// Pause playback.
		/// </summary>
		/// <returns>MMSYSERR.NOERROR if successful</returns>
		public Wave.MMSYSERR Pause()
		{
			if (m_file != null)
				return m_file.Pause();

			return Wave.MMSYSERR.NOERROR;
		}


		/// <summary>
		/// Resume playback of a paused sound.
		/// </summary>
		/// <returns>MMSYSERR.NOERROR if successful</returns>
		public Wave.MMSYSERR Resume()
		{
			if (m_file != null)
				return m_file.Resume();

			return Wave.MMSYSERR.NOERROR;
		}

		/// <summary>
		/// Determines the length of the audio file, in milliseconds.
		/// </summary>
		/// <returns>Millieconds</returns>
		public uint Milliseconds()
		{
			if (m_file != null)
				return m_file.Milliseconds;

			return 0;
		}

		/// <summary>
		/// Play a file.
		/// </summary>
		/// <param name="fileName">Name of file to play</param>
		/// <param name="bufferSize">Size of playback buffers</param>
		/// <param name="volLeft">Volume of left channel</param>
		/// <param name="volRight">Volume of right channel</param>
		/// <returns>MMSYSERR.NOERROR if successful</returns>
		public Wave.MMSYSERR Play(string fileName, int bufferSize, ushort volLeft, ushort volRight)
		{
			if (m_file != null)
			{
				return m_file.Play(0, fileName,  m_msgWindow.Hwnd,  bufferSize, volLeft, volRight);
			}

			return Wave.MMSYSERR.ERROR;
		}

		/// <summary>
		/// Play a stream.
		/// </summary>
		/// <param name="strm">stream to play</param>
		/// <param name="bufferSize">Size of playback buffers</param>
		/// <param name="volLeft">Volume of left channel</param>
		/// <param name="volRight">Volume of right channel</param>
		/// <returns>MMSYSERR.NOERROR if successful</returns>
		public Wave.MMSYSERR Play(Stream strm, int bufferSize, ushort volLeft, ushort volRight)
		{
			if (m_file != null)
			{
				return m_file.Play(0, strm,  m_msgWindow.Hwnd,  bufferSize, volLeft, volRight);
			}

			return Wave.MMSYSERR.ERROR;
		}

		public void Stop()
		{
			if (m_file != null)
				m_file.Stop();
		}

		/// <summary>
		/// A block has finished so notify the WaveFile.  In a more complicated example,
		/// this class might maintain an array of WaveFile instances.  In such a case, the
		/// wParam of the message could be passed from the MM_WIM_DATA message.  This
		/// value represents the m_hwi member of the file that caused the message.
		/// The code might look something like:
		/// foreach (WaveFile f in m_files)
		/// {
		///		if (f.m_hwi.ToInt32() == wParam.ToInt32())
		///		{
		///			f.BlockDone();
		///			break;
		///		}
		/// }
		/// </summary>
		public void BlockDone(IntPtr hwo)
		{
			if (m_file != null)
				m_file.BlockDone();
		}

		/// <summary>
		/// Clean up an allocated resources.
		/// </summary>
		public void Dispose()
		{
			if (m_msgWindow != null)
				m_msgWindow.Dispose();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -