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

原创 2005年05月25日 12:28:00

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.
大多数的工作在事例应用程序中是被两个类驱动的:wavestream和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.
wavestream类扩展了了system.io.stream命名空间,并且增加了必要的代码,使得他能从一个wav文件中读取音频数据。它的构造函数读取了文件头信息和一些由格式属性提供的其他的相关信息,比如说实际的流长度,和音频数据的格式。
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.
一个很重要的应当注意的事情,就是在wavestream类中获取一些操作是直接同音频数据流相关的。用这种方法你不必关心数据头的长度或者是那些在流的末尾那些不属于音频数据块的多余byte。
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.
waveoutplayer类是最有意义的事情发生的地方,为了简单期间,这个类的接口被缩减到了最小,没有开始,结束,或暂停方法。生成一个waveoutplayer的实例就会使得系统立即开始播放音频数据流。
Let's have a look at the code that creates the WaveOutPlayer instance. As you can see, the constructor takes five parameters:
让我们来看看这些代码创造的waveoutplayer实例,你可以看到,构造函数含有5个参数。
private void Play()
{
    Stop();
    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.
第一个参数是你可以使用的音频设备的id号码,值-1代表系统默认的设备,但是如果你的系统中有多个声卡,那时你可以从0到安装的声卡个数减一的数字中选取一个特别的音频设备。
The second parameter is the format of the audio samples. In this example, the format is taken directly from the wave stream.
第二个参数是音频实例的格式,这个格式直接从wavestream类中提取出来。
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:
第五个也是最后一个参数是一个委托,它将周期性的调用内部的音频缓冲区来结束播放,这样一来你就可以向缓冲区填充新的数据。在应用程序例程中我们可以从wavestream中来读取,像这样
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;
        }
    }
    else
    {
        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:
要结束播放,只需要像这样调用player对象的dispose函数就可以。
private void Stop()
{
    if (m_Player != null)
    try
    {
        m_Player.Dispose();
    }
    finally
    {
        m_Player = null;
    }
}

Conclusion
结论
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 翻译.

C#中的底层音频控制播放

原文出处:A low-level audio player in C#扩展阅读:‍A full-duplex audio player in C# using the waveIn/waveOut A...
  • kenkao
  • kenkao
  • 2010年11月27日 12:36
  • 3948

WordPress插件 WP Audio Player 全HTML5支持音乐视频播放器插件[更新至v6.0]

WP Audio Player 是一款WordPress插件,简单的操作就可以让你的网站瞬间变成一个多媒体的站点,功能齐全的音频/视频播放器。已经制作了5个自定义皮肤和响应布局。在移动设备上能完美工作...
  • wpzhuti
  • wpzhuti
  • 2016年05月17日 22:56
  • 1744

A low-level audio player in C#

http://www.codeproject.com/cs/media/cswavplay.aspA low-level audio player in C#By Ianier Munoz This ...
  • metababy
  • metababy
  • 2006年01月14日 15:20
  • 990

jquery实现audio的播放控制

实现audio的暂停与播放控制。播放
  • EndisenChen
  • EndisenChen
  • 2017年04月17日 16:44
  • 5240

HTML5用audio标签做一个最简单的音频播放器

在做系统的时候,要求做一个音频播放器,就在网上查找了一些资料,发现这样的资料还是很千篇一律的,EasyUI框架并没有给我们一个音频播放器的功能,在bootstrap上有,但是也是结合html5来写的,...
  • u010540106
  • u010540106
  • 2015年10月27日 21:30
  • 4496

h5 自定义简单的音乐播放器

这里实现的播放只有暂停/播放、显示进度条、当前时间、总时长的功能。(暂未封装成插件)        h5 提供了audio标签,供我们播放音乐资源。其兼容性先不考虑,但就样式而言,并不足以满...
  • SheldonJiang
  • SheldonJiang
  • 2015年11月20日 08:37
  • 8010

Android学习之MediaPlayer 音频播放器

简易音频播放
  • qq_33335724
  • qq_33335724
  • 2017年08月10日 17:31
  • 159

AudioPlayer.js,一个响应式且支持触摸操作的jquery音频插件 - DragonDean

AudioPlayer.js是一个响应式、支持触摸操作的 HTML5 的音乐播放器。本文是对其官网的说用说明文档得翻译,博主第一次翻译外文。不到之处还请谅解、之处。 JS文件地址: http://o...
  • bboyjoe
  • bboyjoe
  • 2015年08月25日 11:24
  • 930

JS实现HTML5音频播放自定义UI

此处首先放一个MDN上关于H5音频播放的文档 使用 HTML5 音频和视频 音频audio标签使用之后是默认带进度条的,所以audio标签中的属性是我们可以定制,选择将其全部隐藏就是了,然后自己实...
  • licheng11403080324
  • licheng11403080324
  • 2017年03月03日 21:32
  • 3717

HTML5使用js jq控制<audio>的播放 暂停

正所谓节后三天瘟!第一天上班脑子迷迷糊糊。一上来就写一端代码控制audio,凭借仅存的记忆,还不错!弄出来了!中间遇到了一点点小坑,特地拿出来晒晒,免得以后再吃亏! 任务要求:利用js或者jq控制音频...
  • u011456552
  • u011456552
  • 2017年02月06日 18:36
  • 1548
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:a low-level audio player(by Ianier Munoz)底层音频控制播放器
举报原因:
原因补充:

(最多只允许输入30个字)