|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES
// OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// � 2007 Gary W. Schwede and Stream Computers, Inc. All rights reserved.
// Contact: gary at streamcomputers dot com. Permission to incorporate
// all or part of this code in your application is given on the condition
// that this notice accompanies it in your code and documentation.
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using Microsoft.DirectX.DirectSound;
using StreamComputers.Riff;
namespace StreamComputers.MdxDirectSound
{
/// <summary>
/// Simple Windows Forms Dialog to play CD-standard .WAV files using Managed
/// DirectX DirectSound functions. This player locates SecondaryBuffers in software
/// only, avoiding spurious notifications seen when located in hardware.
/// </summary>
public class SimpleMdxPlayer : Form
{
#region private fields
private Label lblSoundFile;
private Button btnOpenFile;
private Label lblBufSize;
private Button btnPlay;
private Button btnPause;
private Button btnStop;
private RadioButton rdoBtnStatic;
private RadioButton rdoBtnStreaming;
private Button btnCreateBuf;
/// <summary>
/// Required designer variable.
/// </summary>
private Container components = null;
private string m_PathToSoundFile = string.Empty;
private string m_SelectedFilePathAndName = string.Empty;
private MdxSoundBuffer m_Buffer = null;
private Device m_MDXDevice = null;
#endregion
public SimpleMdxPlayer()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
EnableFileSelectUI(true);
EnableBufferUI(false);
EnablePlayUI(false);
}
#region IDisposable implementation
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
if (disposing)
{
if(m_Buffer != null)
{
m_Buffer.Dispose();
}
if(m_MDXDevice != null)
{
m_MDXDevice.Dispose();
m_MDXDevice = null;
}
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
#endregion
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.lblSoundFile = new System.Windows.Forms.Label();
this.btnOpenFile = new System.Windows.Forms.Button();
this.rdoBtnStatic = new System.Windows.Forms.RadioButton();
this.rdoBtnStreaming = new System.Windows.Forms.RadioButton();
this.lblBufSize = new System.Windows.Forms.Label();
this.btnPlay = new System.Windows.Forms.Button();
this.btnPause = new System.Windows.Forms.Button();
this.btnStop = new System.Windows.Forms.Button();
this.btnCreateBuf = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// lblSoundFile
//
this.lblSoundFile.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.lblSoundFile.Location = new System.Drawing.Point(112, 32);
this.lblSoundFile.Name = "lblSoundFile";
this.lblSoundFile.Size = new System.Drawing.Size(200, 24);
this.lblSoundFile.TabIndex = 0;
this.lblSoundFile.Text = "no file selected.";
this.lblSoundFile.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// btnOpenFile
//
this.btnOpenFile.Location = new System.Drawing.Point(16, 32);
this.btnOpenFile.Name = "btnOpenFile";
this.btnOpenFile.Size = new System.Drawing.Size(80, 24);
this.btnOpenFile.TabIndex = 1;
this.btnOpenFile.Text = "&Open File";
this.btnOpenFile.Click += new System.EventHandler(this.btnOpenFile_Click);
//
// rdoBtnStatic
//
this.rdoBtnStatic.Checked = true;
this.rdoBtnStatic.Location = new System.Drawing.Point(112, 80);
this.rdoBtnStatic.Name = "rdoBtnStatic";
this.rdoBtnStatic.Size = new System.Drawing.Size(80, 24);
this.rdoBtnStatic.TabIndex = 6;
this.rdoBtnStatic.TabStop = true;
this.rdoBtnStatic.Text = "Static";
//
// rdoBtnStreaming
//
this.rdoBtnStreaming.Location = new System.Drawing.Point(112, 104);
this.rdoBtnStreaming.Name = "rdoBtnStreaming";
this.rdoBtnStreaming.Size = new System.Drawing.Size(80, 24);
this.rdoBtnStreaming.TabIndex = 7;
this.rdoBtnStreaming.Text = "Streaming";
//
// lblBufSize
//
this.lblBufSize.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.lblBufSize.Location = new System.Drawing.Point(208, 88);
this.lblBufSize.Name = "lblBufSize";
this.lblBufSize.Size = new System.Drawing.Size(104, 24);
this.lblBufSize.TabIndex = 8;
this.lblBufSize.Text = "Buffer Size (KB)";
this.lblBufSize.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// btnPlay
//
this.btnPlay.Location = new System.Drawing.Point(40, 160);
this.btnPlay.Name = "btnPlay";
this.btnPlay.Size = new System.Drawing.Size(64, 24);
this.btnPlay.TabIndex = 10;
this.btnPlay.Text = "&Play";
this.btnPlay.Click += new System.EventHandler(this.btnPlay_Click);
//
// btnPause
//
this.btnPause.Location = new System.Drawing.Point(140, 160);
this.btnPause.Name = "btnPause";
this.btnPause.Size = new System.Drawing.Size(64, 24);
this.btnPause.TabIndex = 11;
this.btnPause.Text = "Pa&use";
this.btnPause.Click += new System.EventHandler(this.btnPause_Click);
//
// btnStop
//
this.btnStop.Location = new System.Drawing.Point(240, 160);
this.btnStop.Name = "btnStop";
this.btnStop.Size = new System.Drawing.Size(64, 24);
this.btnStop.TabIndex = 12;
this.btnStop.Text = "&Stop";
this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
//
// btnCreateBuf
//
this.btnCreateBuf.Location = new System.Drawing.Point(16, 88);
this.btnCreateBuf.Name = "btnCreateBuf";
this.btnCreateBuf.Size = new System.Drawing.Size(80, 24);
this.btnCreateBuf.TabIndex = 9;
this.btnCreateBuf.Text = "Create Buffer";
this.btnCreateBuf.Click += new System.EventHandler(this.btnCreateBuf_Click);
//
// SimpleMdxPlayer
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(336, 213);
this.Controls.Add(this.btnCreateBuf);
this.Controls.Add(this.btnStop);
this.Controls.Add(this.btnPause);
this.Controls.Add(this.btnPlay);
this.Controls.Add(this.lblBufSize);
this.Controls.Add(this.rdoBtnStreaming);
this.Controls.Add(this.rdoBtnStatic);
this.Controls.Add(this.btnOpenFile);
this.Controls.Add(this.lblSoundFile);
this.Name = "SimpleMdxPlayer";
this.Text = "SimpleMdxPlayer";
this.Load += new System.EventHandler(this.SimpleMdxPlayer_Load);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static void Main()
{
Application.Run(new SimpleMdxPlayer());
}
private void SimpleMdxPlayer_Load(object sender, EventArgs e)
{
try
{
m_MDXDevice = new Device(); // default device
Debug.Assert(m_MDXDevice.Caps.Secondary16Bit);
m_MDXDevice.SetCooperativeLevel(this, CooperativeLevel.Priority);
}
catch
{
MessageBox.Show("Cannot find sound device. Application will exit.");
this.Close();
throw;
}
}
#region OpenFileDialog code
/// <summary>
/// Stops play if in progress. Invokes OpenFileDialog to set input sound file member.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpenFile_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.InitialDirectory = m_PathToSoundFile;
openFileDialog.Filter = "Wave files(*.wav)|*.wav";
if (DialogResult.Cancel == openFileDialog.ShowDialog())
return;
m_PathToSoundFile = Path.GetDirectoryName(openFileDialog.FileName);
lblSoundFile.Text = Path.GetFileName(openFileDialog.FileName);
m_SelectedFilePathAndName = openFileDialog.FileName;
EnableBufferUI(true);
EnablePlayUI(false);
}
#endregion
#region btnCreateBuf_Click code
/// <summary>
/// Creates a new MDX DS SecondaryBuffer of the type specified by the radio buttons.
/// </summary>
private void btnCreateBuf_Click(object sender, EventArgs e)
{
EnablePlayUI(false);
if(rdoBtnStatic.Checked)
{
// Create a new static secondary buffer, and load the whole sound file.
// Set GlobalFocus for new buffer, but let other properties be defaults.
// DirectSound may "locate" the buffer in hardware if resources are available.
BufferDescription bdesc = new BufferDescription();
bdesc.GlobalFocus = true;
if(m_Buffer != null)
{
m_Buffer.Dispose();
}
try
{
m_Buffer = new StaticSoundBuffer(m_SelectedFilePathAndName, bdesc, m_MDXDevice);
}
catch(OutOfMemoryException)
{
if (m_Buffer != null)
{
m_Buffer.Dispose();
}
return;
}
catch (ArgumentException)
{
if (m_Buffer != null)
{
m_Buffer.Dispose();
}
return;
}
}
else
{
Debug.Assert(rdoBtnStreaming.Checked, "None of two radio buttons checked.") ;
if(m_Buffer != null)
{
m_Buffer.Dispose();
}
try
{
// create a streaming secondary buffer, "located" in software.
m_Buffer = new SimpleStreamingSoundBuffer(m_SelectedFilePathAndName, m_MDXDevice);
}
catch(RiffParserException)
{
if(m_Buffer != null)
{
m_Buffer.Dispose();
}
return;
}
}
// set the buffer length label
lblBufSize.Text = String.Format("{0} KB", m_Buffer.BufferLength / 1024) ;
EnablePlayUI(true);
}
#endregion
#region IPlayable event code
private void btnPlay_Click(object sender, EventArgs e)
{
EnableFileSelectUI(false);
EnableBufferUI(false);
try
{
m_Buffer.Play();
}
catch (OutOfMemoryException)
{
m_Buffer.Dispose();
EnablePlayUI(false);
EnableBufferUI(true);
EnableFileSelectUI(true);
}
}
private void btnPause_Click(object sender, EventArgs e)
{
m_Buffer.Pause();
}
private void btnStop_Click(object sender, EventArgs e)
{
m_Buffer.Stop();
EnableBufferUI(true);
EnableFileSelectUI(true);
}
#endregion
#region EnableUI code
private void EnableFileSelectUI(bool enable)
{
btnOpenFile.Enabled = enable;
}
private void EnableBufferUI(bool enable)
{
btnCreateBuf.Enabled = enable;
}
private void EnablePlayUI(bool enable)
{
btnPlay.Enabled = enable;
btnPause.Enabled = enable;
btnStop.Enabled = enable;
}
#endregion
}
}
|
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.
My life and career have been a bit unusual (mostly in good ways). So, I'm grateful every day for the opportunities God's given me to do different things and see different aspects of life.
Education: B.S. Physics '73 (atmospheric physics, sounding rockets), M.S. Computer Science '76 (radio astronomy, fuzzy controllers, music pattern recognition and visualization) New Mexico Tech; Ph.D. Engineering '83 (parallel computer architecture, digital signal processing, economics) U.C. Berkeley.
I'm married to Susan, a wonderful woman whom I met in a Computer Architecture class at U.C. Berkeley.
Professional activities: Digital systems engineer, digital audio pioneer, founder or key in several tech startups, consulting engineer, expert witness. I'm currently developing a multithreading framework in C# .NET, that makes it almost easy to write correct programs for multicore processors. I'm also implementing a new transform for recognizing, editing, and processing signals, especially sound.
I'm an occasional essayist, public speaker, and podcaster, and free-market space advocate. I enjoy good wine, good music, good friends, and cats.
If you think your project could use a different point of view, I'm available for consulting work in the San Francisco Bay area, or (preferrably) via the net.