Solved

How to play a wav/wave file in C# .NET?

Posted on 2004-08-17
8
689 Views
Last Modified: 2010-08-05
I need sample C# code that shows how to open up a wav file and send the loaded amplitude values to be played by the sound card.
0
Comment
Question by:kayhustle
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
8 Comments
 
LVL 12

Expert Comment

by:vascov
ID: 11826659
Hi,

Do you mean something like:
using System;
using System.Runtime.InteropServices;

class SoundLib
{
      [ DllImport("winmm.dll") ]
      public static extern long PlaySound(String Name, long Module, long Flags);
}

class App
{
      public static void Main( string[] snds )
      {
            foreach( string snd in snds )
            {
                  try
                  {
                        SoundLib.PlaySound( snd, 0, 0 );
                  }
                  catch( Exception e )
                  {
                        Console.WriteLine( e.ToString() );
                  }
            }
      }
}

ps "C:\windows\media\chimes.wav"


Or do you need something more elaborate ?

Vasco
0
 
LVL 1

Author Comment

by:kayhustle
ID: 11826728
No, I need to know how to open up the wav file and read the individual amplitude values, then pass these as chunks to be played by the sound card.  Wav files store the sound as the numeric amplitude values in a range from 0 to 2 ^(#bits), I need to read these individual values for each channel and play them back.
0
 
LVL 3

Expert Comment

by:chintan_vaishya
ID: 11827565
0
Cloud Training Guides

FREE GUIDES: In-depth and hand-crafted Linux, AWS, OpenStack, DevOps, Azure, and Cloud training guides created by Linux Academy instructors and the community.

 
LVL 1

Author Comment

by:kayhustle
ID: 11836111
While those links are very helpful, they don't actually answer my question.  They show how to play a wav file.  I need to know how to open it and read the individual amp values for processing.
0
 
LVL 12

Accepted Solution

by:
vascov earned 500 total points
ID: 11836388
0
 
LVL 4

Expert Comment

by:Eran_R
ID: 11843283
If I understand your needs correctly, here's what you need:

You need to make use of DirectX DirectSound technology.
DirectSound uses something called SoundBuffers that contain actual wave data. This data can be static but can also be streaming as you require.

Luckily enough microsoft already provide managed wrappers for all that COM junk.
It's called "Managed DirectX" and you can download it from microsoft.

Here's a snippet from the Managed DirectX SDK documentation which I think answers your needs:

Using Streaming Buffers
================
A streaming buffer plays a long sound that cannot all fit into the buffer at once. As the buffer plays, old data is periodically replaced with new data. Play a streaming sound with the following procedure:

1. Call SecondaryBuffer(Stream,BufferDescription,Device) to create a buffer with the correct waveform format, and of a convenient size. A buffer large enough to hold one or two seconds of data is typical; smaller buffers can be used, but they have to be refreshed more frequently, which can be inefficient.
2. Set notification positions so that your application knows when to refresh a portion of the buffer. For example, you can set notifications halfway through the buffer and at the end. When the play cursor reaches the halfway point, the first part of the buffer is refreshed; when it reaches the end, the second part is refreshed. Alternatively, you can poll the play cursor as the buffer plays, but this is less efficient than notification. For more information, see Play and Write Cursors.
3. Load the entire buffer with data by using Buffer.Write.
4. Call Buffer.Play (inherited by SecondaryBuffer), specifying the BufferStatus.Looping property.
5. When the play cursor reaches the first point at which you want to refresh data, call Write again, writing new data from the start of the buffer up to the play cursor. Save the position of the last byte written.
6. Call Write each time the cursor reaches a refresh point, writing data to the part of the buffer that lies between the saved position and the play cursor. Note that wraparound is handled automatically: if the buffer is 10,000 bytes long, and you write 2000 bytes to offset 9000, the last 1000 bytes are written to the front of the buffer.
7. When all data has been written to the buffer, set a notification position at the last valid byte, or poll for this position. When the cursor reaches the end of the data, call Buffer.Stop.

The full documentation is available on the following link:
http://msdn.microsoft.com/archive/en-us/directx9_m/directx/sound/playingsounds/directsound_buffers.asp

A more general link on DirectSound using managed DirectX:
http://msdn.microsoft.com/archive/en-us/directx9_m/directx/sound/playingsounds/playing_sounds_entry.asp

Hope this helps,
Eran
0
 
LVL 1

Author Comment

by:kayhustle
ID: 11899709
Ok, so I can get the wave bytes, but do you know how those bytes correspond to the left and right channel amplitude values.  The code project documentation shows how to get the sample rate and a lot of other header info, but do you know how the actual wave data is arranged, so that I could lets say plot the waveform in an image?
Thank you
0
 
LVL 1

Author Comment

by:kayhustle
ID: 11945793
Found the answer, vascov's link points to an article written by Ianier Munoz, I emailed the guy and asked him.  He pointed me to an article he wrote about programming audio effects in C#, http://www.codeproject.com/cs/media/cswavplayfx.asp,and in those source files, he processes the individual amplitude values in the wave.  Thank you everybody.
0

Featured Post

Get HTML5 Certified

Want to be a web developer? You'll need to know HTML. Prepare for HTML5 certification by enrolling in July's Course of the Month! It's free for Premium Members, Team Accounts, and Qualified Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A basic question.. “What is the Garbage Collector?” The usual answer given back: “Garbage collector is a background thread run by the CLR for freeing up the memory space used by the objects which are no longer used by the program.” I wondered …
More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

632 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question