a low-level audio player(by Ianier Munoz)底层音频控制播放器

类别:.NET开发 点击:0 评论:0 推荐:

When developing applications that deal with such low-level issues, the most commonly used technologies are DirectSound and the waveout API. This article describes a sample application that uses the waveout API in C# through Interop to play a WAV file in a continuous loop.

当开发的应用程序需要处理一些这样的低水平的音频事务的时候,最常采用的方法就是用DirectSound和waveou API(包含在winmm.dll中)。 本片文章讲描述一个范例应用程序,在C#中使用windows API 来循环播放音频(wav)数据。
Using the code
Most of the work in the sample application is carried out by two classes: WaveStream and WaveOutPlayer.
The WaveStream class extends System.IO.Stream and implements the necessary code to read audio samples from a WAV file. The constructor reads the file header and extracts all the relevant information including the actual length of the stream and the format of the audio samples, which is exposed through the Format property.
One important thing to note is that seeking operations in the WaveStream class are relative to the sound data stream. This way you don't have to care about the length of the header or about those extra bytes at the end of the stream that don't belong to the audio data chunk. Seeking to 0 will cause the next read operation to start at the beginning of the audio data.
The WaveOutPlayer class is where the most interesting things happen. For the sake of simplicity, the interface of this class has been reduced to the strict minimum. There are no Start, Stop or Pause methods. Creating an instance of WaveOutPlayer will cause the system to start streaming immediately.
Let's have a look at the code that creates the WaveOutPlayer instance. As you can see, the constructor takes five parameters:
private void Play()
    if (m_AudioStream != null)
        m_AudioStream.Position = 0;
        m_Player = new WaveLib.WaveOutPlayer(-1, m_Format, 16384, 3,
            new WaveLib.BufferFillEventHandler(Filler));

The first parameter is the ID of the wave device that you want to use. The value -1 represents the default system device, but if your system has more than one sound card, then you can pass any number from 0 to the number of installed sound cards minus one to select a particular device.
The second parameter is the format of the audio samples. In this example, the format is taken directly from the wave stream.
The third and forth parameters are the size of the internal wave buffers and the number of buffers to allocate. You should set these to reasonable values. Smaller buffers will give you less latency, but the audio may stutter if your computer is not fast enough.
The fifth and last parameter is a delegate that will be called periodically as internal audio buffers finish playing, so that you can feed them with new sound data. In the sample application we just read audio data from the wave stream, like this:
private void Filler(IntPtr data, int size)
    byte[] b = new byte[size]; //开辟新的缓冲区大小为size
    if (m_AudioStream != null)
        int pos = 0;
        while (pos < size)
            int toget = size - pos;
            int got = m_AudioStream.Read(b, pos, toget);
            if (got < toget)
                m_AudioStream.Position = 0; // loop if the file ends
            pos += got;
        for (int i = 0; i < b.Length; i++) //将缓冲区清零
            b[i] = 0;
    System.Runtime.InteropServices.Marshal.Copy(b, 0, data, size);

Please note that this delegate may be called from any internal thread created by the WaveOutPlayer object, so if you want to call into your Windows Forms objects you should use the Invoke mechanism.
请牢记这个委托将被内部的由waveoutplayer对象创建的线程来调用。所以如果你想把它用于你的windows forms对象中,你需要用Invoke机制
To stop playing, just call Dispose on the player object, like this:
private void Stop()
    if (m_Player != null)
        m_Player = null;

This sample demonstrates how to use the waveout API from C#. This is useful for applications that require more control on the audio stream compared to what other higher level libraries offer. Typical examples are applications that generate or modify audio samples on the fly, such as digital effect processors.
这个例程展示了怎样在c#中使用waveout api。这是十分有用的应用程序,相对于其他的高水平的类库,他需要更多的对音频数据的控制。典型的例子是一些能够自由的产生或者修改音频数据的应用程序,像一些数字音效处理器。
A modified version of this sample that implements support for DirectX plug-ins is included in the Adapt-X SDK, which is a commercial product that can be found at www.chronotron.com.
一个修改后的音频样例增加了包含在adapt-x sdk中的嵌入式direct x的支持,这将是一个商用的软件,可以在www.chronotron.com上找到。

translated by tq010or 2005.5.25

Copyright (C) 1999-2003 Ianier Munoz. All Rights Reserved.

英文版权属于Ianier  Munoz

tq010or 翻译.