using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using Microsoft.DirectX;
using Microsoft.DirectX.DirectSound;
using System.Threading;
namespace DirectSound3DDemo {
public class FrmMain : System.Windows.Forms.Form {
private System.ComponentModel.Container components = null;
public FrmMain() {
InitializeComponent();
pnlMain.MouseDown += new MouseEventHandler(pnlMain_MouseDown);
pnlMain.MouseMove += new MouseEventHandler(pnlMain_MouseMove);
pnlMain.MouseUp += new MouseEventHandler(pnlMain_MouseUp);
prepareSound(currFile);
}
protected override void Dispose(bool disposing) {
if(disposing) {
if(components != null) {
components.Dispose();
}
}
base.Dispose(disposing);
}
#region Windows Forms Design Tools generated code
private void InitializeComponent()
{
this.pnlMain = new DirectSound3DDemo.FlickerFreePanel();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.lblSoundPos = new System.Windows.Forms.Label();
this.btnRotate = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
this.trkHeight = new System.Windows.Forms.TrackBar();
this.label4 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.trkHeight)).BeginInit();
this.SuspendLayout();
//
// pnlMain
//
this.pnlMain.BackColor = System.Drawing.Color.Black;
this.pnlMain.Location = new System.Drawing.Point(8, 8);
this.pnlMain.Name = "pnlMain";
this.pnlMain.Size = new System.Drawing.Size(312, 312);
this.pnlMain.TabIndex = 0;
this.pnlMain.Paint += new System.Windows.Forms.PaintEventHandler(this.pnlMain_Paint);
//
// label1
//
this.label1.Location = new System.Drawing.Point(328, 8);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(232, 32);
this.label1.TabIndex = 1;
this.label1.Text = "Red dot is the sound source, Green dot is the listener.";
//
// label2
//
this.label2.Location = new System.Drawing.Point(328, 48);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(96, 16);
this.label2.TabIndex = 2;
this.label2.Text = "Sound Position";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// lblSoundPos
//
this.lblSoundPos.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.lblSoundPos.Location = new System.Drawing.Point(432, 48);
this.lblSoundPos.Name = "lblSoundPos";
this.lblSoundPos.Size = new System.Drawing.Size(104, 16);
this.lblSoundPos.TabIndex = 3;
this.lblSoundPos.Text = "10, 10, 0";
this.lblSoundPos.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// btnRotate
//
this.btnRotate.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.btnRotate.Location = new System.Drawing.Point(336, 72);
this.btnRotate.Name = "btnRotate";
this.btnRotate.Size = new System.Drawing.Size(216, 24);
this.btnRotate.TabIndex = 4;
this.btnRotate.Text = "Rotate Source";
this.btnRotate.Click += new System.EventHandler(this.btnRotate_Click);
//
// label3
//
this.label3.Location = new System.Drawing.Point(336, 112);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(72, 32);
this.label3.TabIndex = 5;
this.label3.Text = "Height of the sound source";
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// trkHeight
//
this.trkHeight.Location = new System.Drawing.Point(352, 152);
this.trkHeight.Maximum = 50;
this.trkHeight.Minimum = -50;
this.trkHeight.Name = "trkHeight";
this.trkHeight.Orientation = System.Windows.Forms.Orientation.Vertical;
this.trkHeight.Size = new System.Drawing.Size(45, 168);
this.trkHeight.TabIndex = 6;
this.trkHeight.TickFrequency = 10;
this.trkHeight.TickStyle = System.Windows.Forms.TickStyle.Both;
this.trkHeight.Scroll += new System.EventHandler(this.trkHeight_Scroll);
//
// label4
//
this.label4.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.label4.Location = new System.Drawing.Point(416, 112);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(136, 200);
this.label4.TabIndex = 7;
this.label4.Text = @"Instructions: click and drag on the black panel to move the sound source. Hit on 'Rotate Source' to make the source rotating around the center. Scroll the trackbar to move up and down the source in the 3D space (effects may be noticeable only on surround systems).";
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// FrmMain
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(570, 328);
this.Controls.Add(this.label4);
this.Controls.Add(this.trkHeight);
this.Controls.Add(this.label3);
this.Controls.Add(this.btnRotate);
this.Controls.Add(this.lblSoundPos);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.pnlMain);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.Name = "FrmMain";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "DirectSound3D";
((System.ComponentModel.ISupportInitialize)(this.trkHeight)).EndInit();
this.ResumeLayout(false);
}
#endregion
[STAThread] static void Main() {
Application.Run(new FrmMain());
}
private string currFile = Application.StartupPath + "\\AudioMono.wav";
private Device dSound;
private SecondaryBuffer sound;
private Buffer3D sound3D;
private DirectSound3DDemo.FlickerFreePanel pnlMain;
private System.Windows.Forms.Label label1;
private Listener3D listener;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label lblSoundPos;
private bool mouseDown = false;
private System.Windows.Forms.Button btnRotate;
private bool rotating = false;
private int ray = 0;
private int angle = 0;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TrackBar trkHeight;
private System.Windows.Forms.Label label4;
private int h = 0;
private void prepareSound(string file) {
dSound = new Device();
dSound.SetCooperativeLevel(this.Handle, CooperativeLevel.Priority);
BufferDescription d = new BufferDescription();
d.Control3D = true;
d.ControlVolume = true;
d.ControlFrequency = true;
d.Guid3DAlgorithm = DSoundHelper.Guid3DAlgorithmHrtfFull; // High quality algorithms
sound = new SecondaryBuffer(currFile, d, dSound);
sound3D = new Buffer3D(sound);
sound3D.Mode = Mode3D.HeadRelative; // Enable possibility to move sound's source and listener positons
Microsoft.DirectX.DirectSound.Buffer b; // A primary buffer is needed
BufferDescription dp = new BufferDescription();
dp.PrimaryBuffer = true;
dp.Control3D = true;
b = new Microsoft.DirectX.DirectSound.Buffer(dp, dSound);
listener = new Listener3D(b);
// Setup initial positions
listener.Position = new Vector3(0, 0, 0);
sound3D.Position = new Vector3(10, 10, 0);
Listener3DOrientation o = new Listener3DOrientation();
// Set the orientation's data: the listener looks forward
o.Front = new Vector3(1, 0, 0);
o.Top = new Vector3(0, 1, 0);
listener.Orientation = o;
// Set attenuation
sound3D.MinDistance = 50;
listener.DopplerFactor = 10;
sound.Play(0, BufferPlayFlags.Looping);
}
private void pnlMain_Paint(object sender, System.Windows.Forms.PaintEventArgs e) {
try {
Vector3 listPos = listener.Position;
Vector3 sndPos = sound3D.Position;
Graphics gr = e.Graphics;
//gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
gr.DrawLine(Pens.Blue, pnlMain.Width / 2, 0, pnlMain.Width / 2, pnlMain.Height);
gr.DrawLine(Pens.Blue, 0, pnlMain.Height / 2, pnlMain.Width, pnlMain.Height / 2);
gr.DrawEllipse(Pens.Green, pnlMain.Width / 2 + (listPos.X - 4), pnlMain.Height / 2 - (listPos.Y + 4), 8, 8);
gr.FillEllipse(Brushes.Green, pnlMain.Width / 2 + (listPos.X - 4), pnlMain.Height / 2 - (listPos.Y + 4), 8, 8);
gr.DrawEllipse(Pens.Red, pnlMain.Width / 2 + (sndPos.X - 4), pnlMain.Height / 2 - (sndPos.Y + 4), 8, 8);
gr.FillEllipse(Brushes.Red, pnlMain.Width / 2 + (sndPos.X - 4), pnlMain.Height / 2 - (sndPos.Y + 4), 8, 8);
}
catch {}
}
private void pnlMain_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) {
mouseDown = true;
if(!rotating) {
Vector3 p = new Vector3(-pnlMain.Width / 2 + e.X, pnlMain.Height / 2 - e.Y, h);
sound3D.Position = p;
lblSoundPos.Text = p.X.ToString() + ", " + p.Y.ToString() + ", " + h.ToString();
pnlMain.Refresh();
}
}
private void pnlMain_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) {
if(mouseDown && !rotating) {
Vector3 p = new Vector3(-pnlMain.Width / 2 + e.X, pnlMain.Height / 2 - e.Y, h);
sound3D.Position = p;
lblSoundPos.Text = p.X.ToString() + ", " + p.Y.ToString() + ", " + h.ToString();
pnlMain.Refresh();
}
}
private void pnlMain_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) {
mouseDown = false;
}
private void btnRotate_Click(object sender, System.EventArgs e) {
if(rotating) {
rotating = false;
btnRotate.Text = "Rotate Source";
}
else {
btnRotate.Text = "Stop Rotation";
ray = (int)Math.Round(Math.Sqrt(Math.Pow(sound3D.Position.X, 2) + Math.Pow(sound3D.Position.Y, 2)));
angle = (int)Math.Round(Math.Atan(sound3D.Position.Y / sound3D.Position.Y) * 180 / Math.PI);
Thread t = new Thread(new ThreadStart(rotator));
rotating = true;
t.Start();
}
}
private void rotator() {
int r = ray;
int a = angle;
if(a % 2 != 0)
a++;
Vector3 pos;
while(rotating) {
pos = new Vector3((float)Math.Cos(a * Math.PI / 180) * r, (float)Math.Sin(a * Math.PI / 180) * r, h);
sound3D.Position = pos;
lblSoundPos.Text = string.Format("{0:N0}", pos.X) + ", " + string.Format("{0:N0}", pos.Y) + ", " + h.ToString();
pnlMain.Refresh();
a += 2;
if(a == 360)
a = 0;
Thread.Sleep(50);
}
}
private void trkHeight_Scroll(object sender, System.EventArgs e) {
h = trkHeight.Value;
Vector3 pos = sound3D.Position;
lblSoundPos.Text = string.Format("{0:N0}", pos.X) + ", " + string.Format("{0:N0}", pos.Y) + ", " + h.ToString();
}
protected override void OnClosed(EventArgs e) {
// Terminate thread!!!
rotating = false;
base.OnClosed (e);
}
}
// A flicker free panel
public class FlickerFreePanel : System.Windows.Forms.Panel {
public FlickerFreePanel() {
SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
}
}
}