zoukankan      html  css  js  c++  java
  • 全双工音频播放器在c#中使用waveIn / waveOut api

    http://www.codeproject.com/Articles/4889/A-full-duplex-audio-player-in-C-using-the-waveIn-w

    一篇关于低级音频捕获和回放使用waveIn / waveOut api通过P / Invoke c#。
    下载源文件- 15.1 Kb
    Sample Image - cswavrec.gif
    
    介绍
    当我在我的文章里已经提到 c#的低级音频播放器 ,没有内置类的。 净框架来处理声音。 音频播放这不仅适用,而且对音频捕捉。
    
    但值得注意的是,举9 SDK包括管理类高级和低级音频操作。 然而,有时你不想让您的应用程序依赖于完整的DX 9运行时,只做基本的声音回放和捕获,也有一些地区管理声音处理软件根本不能帮助(例如,多渠道声音回放和捕获)。
    
    不过,我强烈建议你使用管理声音回放和捕捉声音处理软件,除非你有充分的理由不这样做。
    
    本文描述了一个示例应用程序使用 waveIn 和 waveOut 通过P / Invoke api在c#中捕捉到声卡的音频信号的输入,然后重播(几乎)在同一时间。
    
    使用的代码
    示例代码重用 WaveOutPlayer 类从我的文章 c#的低级音频播放器 。 这个示例中的新类 WaveInRecorder 和 FifoStream 。
    
    的 FifoStream 类继承了 System.IO.Stream 实现一个FIFO(先进先出)的字节数。 的覆盖 写 方法将数据添加到FIFO的尾巴, 读 法正从FIFO的头和删除数据。 的 长度 属性返回缓冲数据的数量。 调用 冲洗 将清除所有未决数据。
    
    的 WaveInRecorder 类是类似于 WaveOutPlayer 类。 事实上,如果你看源文件,您会注意到,这些类的实现非常相似。 与 WaveOutPlayer ,这个类的接口已经减少到严格的最小值。
    
    创建一个实例 WaveInRecorder 将导致系统立即开始记录。 这是创建的代码 WaveOutPlayer 和 WaveInRecorder 实例。
    
    private void Start()
    {
        Stop();
        try
        {
            WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(44100, 16, 2);
            m_Player = new WaveLib.WaveOutPlayer(-1, fmt, 16384, 3, 
                            new WaveLib.BufferFillEventHandler(Filler));
            m_Recorder = new WaveLib.WaveInRecorder(-1, fmt, 16384, 3, 
                            new WaveLib.BufferDoneEventHandler(DataArrived));
        }
        catch
        {
            Stop();
            throw;
        }
    }
    的 WaveInRecorder 五个参数的构造函数。 除了最后一个参数,它们的意思是一样的 WaveOutPlayer 。
    
    第一个参数是波的ID输入您想要使用的装置。 的值 - - - - - - 1 代表默认的系统设备,但是如果你的系统有一个以上的声卡,然后你可以通过任何数量 0 安装声卡的数量- 1,选择一个特定的设备。
    
    第二个参数是音频的格式样本。
    
    第三个参数的大小,内部缓冲区和缓冲区分配的数量。 你应该设置这些合理的值。 较小的缓冲区会给你更少的延迟,但捕获音频可能有差距,如果你的电脑还不够快。
    
    第五和最后一个参数是一个委托,将被称为定期内部音频缓冲区获取的数据。 在样例应用程序中我们把捕获的数据FIFO,像这样:
    
    private void DataArrived(IntPtr data, int size)
    {
        if (m_RecBuffer == null || m_RecBuffer.Length < size)
            m_RecBuffer = new byte[size];
        System.Runtime.InteropServices.Marshal.Copy(data, m_RecBuffer, 0, size);
        m_Fifo.Write(m_RecBuffer, 0, m_RecBuffer.Length);
    }
    类似地, 填料 方法被调用时每次玩家需要更多数据。 我们的实现只是读取FIFO的数据,如下所示:
    
    private void Filler(IntPtr data, int size)
    {
        if (m_PlayBuffer == null || m_PlayBuffer.Length < size)
            m_PlayBuffer = new byte[size];
        if (m_Fifo.Length >= size)
            m_Fifo.Read(m_PlayBuffer, 0, size);
        else
            for (int i = 0; i < m_PlayBuffer.Length; i++)
                m_PlayBuffer[i] = 0;
        System.Runtime.InteropServices.Marshal.Copy(m_PlayBuffer, 
                                                     0, data, size);
    }
    注意,我们宣布临时缓冲区 m_RecBuffer 和 m_PlayBuffer 成员字段,以提高性能,节省一些垃圾收集。
    
    停止播放,就叫 处理 在玩家和捕获对象。 我们还需要冲洗FIFO,以便下次 开始 被称为没有剩余数据。
    
    private void Stop()
    {
        if (m_Player != null)
            try
            {
                m_Player.Dispose();
            }
            finally
            {
                m_Player = null;
            }
        if (m_Recorder != null)
            try
            {
                m_Recorder.Dispose();
            }
            finally
            {
                m_Recorder = null;
            }
        m_Fifo.Flush(); // clear all pending data
    }
    结论
    这个示例演示了如何结合 waveIn 和 waveOut api在c#中。 作为练习,您可能想要将这段代码与音频效果本文框架 在c#编程音频效果 现场应用效果,在实时音频输入,虽然延迟可能是一个问题对于某些应用程序。
    
    许可证
    本文没有明确许可连接但可能包含在本文使用条款文本或下载文件本身。 如果有疑问请联系作者通过下面的讨论板。
    
    作者许可列表可以找到可能使用 在这里
    
    分享
  • 相关阅读:
    1. 首次运行 Git 的配置
    本地git连接github
    Cygwin(linux)中vim配置
    ibatis入门
    XML(可扩展性标记语言)学习汇总一
    第一只小啊小爬虫(纪念下)
    Android SQLite DB的封装
    关于做项目的一些感想
    Git 初学三(git对象与git重置)
    Git 初学二(暂存区)
  • 原文地址:https://www.cnblogs.com/endv/p/5439966.html
Copyright © 2011-2022 走看看