流音频中的降噪和压缩

2024-03-18

希望你能帮忙。我正在从麦克风录制音频并通过网络实时传输。样本的质量为 11025hz、8 位、单声道。虽然有一点延迟(1秒),但效果很好。我需要帮助的是我现在正在尝试实现降噪和压缩,以使音频更安静并使用更少的带宽。音频样本存储在 C# 的 bytes[] 数组中,我使用 Socket 发送/接收该数组。

谁能建议如何在 C# 中实现压缩和降噪?我不介意使用第三方库,只要它是免费的(LGPL 许可证等)并且可以从 C# 使用。但是,我更喜欢实际工作的源代码示例。预先感谢您的任何建议。

UPDATE:

我将位大小从 8 位音频更改为 16 位音频,噪音问题得到解决。显然,麦克风的 8 位音频信噪比太低。 11khz、16 位单声道的声音听起来很棒。

然而,自从我发布这篇文章以来,这个项目的要求已经发生了变化。我们现在也正在尝试添加视频。我有一个回调设置,每 100 毫秒从网络摄像头接收实时图像。我需要对音频和视频进行编码,混合它们,将它们在我的套接字上传输到服务器,服务器将流重新传输到另一个客户端,该客户端接收流,解复用流并解码音频和视频,显示图片框中的视频并将音频输出到扬声器。

我正在寻找 ffmpeg 来帮助进行(de|en)编码/[de]复用,并且我还在寻找 SharpFFmpeg 作为 ffmpeg 的 C# 互操作库。

我找不到任何这样做的好例子。我整个星期都在互联网上搜索,但没有真正的运气。非常感谢您提供的任何帮助!

这是一些代码,包括我的麦克风录音回调函数:



        private const int AUDIO_FREQ = 11025;
        private const int CHANNELS = 1;
        private const int BITS = 16;
        private const int BYTES_PER_SEC = AUDIO_FREQ * CHANNELS * (BITS / 8);
        private const int BLOCKS_PER_SEC = 40;
        private const int BUFFER_SECS = 1;
        private const int BUF_SIZE = ((int)(BYTES_PER_SEC / BLOCKS_PER_SEC * BUFFER_SECS / 2)) * 2; // rounded to nearest EVEN number

        private WaveLib.WaveOutPlayer m_Player;
        private WaveLib.WaveInRecorder m_Recorder;
        private WaveLib.FifoStream m_Fifo;

        WebCam MyWebCam;

        public void OnPickupHeadset()
        {
            stopRingTone();
            m_Fifo = new WaveLib.FifoStream();

            WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(AUDIO_FREQ, BITS, CHANNELS);
            m_Player = new WaveLib.WaveOutPlayer(-1, fmt, BUF_SIZE, BLOCKS_PER_SEC,
                            new WaveLib.BufferFillEventHandler(PlayerCB));
            m_Recorder = new WaveLib.WaveInRecorder(-1, fmt, BUF_SIZE, BLOCKS_PER_SEC,
                            new WaveLib.BufferDoneEventHandler(RecorderCB));

            MyWebCam = null;
            try
            {
                MyWebCam = new WebCam();                
                MyWebCam.InitializeWebCam(ref pbMyPhoto, pbPhoto.Width, pbPhoto.Height);
                MyWebCam.Start();
            }
            catch { }

        }

        private byte[] m_PlayBuffer;
        private void PlayerCB(IntPtr data, int size)
        {
            try
            {
                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
                {
                    // Read what we can 
                    int fifoLength = (int)m_Fifo.Length;
                    m_Fifo.Read(m_PlayBuffer, 0, fifoLength);

                    // Zero out rest of buffer
                    for (int i = fifoLength; i < m_PlayBuffer.Length; i++)
                        m_PlayBuffer[i] = 0;                        
                }

                // Return the play buffer
                Marshal.Copy(m_PlayBuffer, 0, data, size);
            }
            catch { }
        }


        private byte[] m_RecBuffer;
        private void RecorderCB(IntPtr data, int size)
        {
            try
            {
                if (m_RecBuffer == null || m_RecBuffer.Length != size)
                    m_RecBuffer = new byte[size];
                Marshal.Copy(data, m_RecBuffer, 0, size);

                // HERE'S WHERE I WOULD ENCODE THE AUDIO IF I KNEW HOW

                // Send data to server
                if (theForm.CallClient != null)
                {
                    SocketAsyncEventArgs args = new SocketAsyncEventArgs();
                    args.SetBuffer(m_RecBuffer, 0, m_RecBuffer.Length);
                    theForm.CallClient.SendAsync(args);
                }
            }
            catch { }
        }

        //Called from network stack when data received from server (other client)
        public void PlayBuffer(byte[] buffer, int length)
        {
            try
            {
                //HERE'S WHERE I WOULD DECODE THE AUDIO IF I KNEW HOW

                m_Fifo.Write(buffer, 0, length); 
            }
            catch { }
        }

  

那么我应该去哪里呢?


你们的目标是相互排斥的。 11025Hz/8bit/Mono WAV 文件听起来很吵(带有大量“嘶嘶声”)的原因是它们的采样率和位分辨率较低(44100Hz/16bit/Stereo 是 CD 品质音频的标准)。

如果您继续以该速率进行录制和流式传输,您将会听到嘈杂的音频 - 就这样。消除(或实际上只是减弱)这种噪音的唯一方法是将音频上采样到 44100Hz/16 位,然后对其执行某种降噪算法。这种上采样必须由客户端应用程序执行,因为在流式传输之前在服务器上执行此操作意味着您将流式传输比原始音频大 8 倍的音频(在服务器上执行此操作也是完全没有意义的,因为您会最好一开始就以更密集的格式进行录制)。

您想要做的是以 CD 质量格式录制原始音频,然后将其压缩为 MP3 或 Ogg Vorbis 等标准格式。请参阅之前的问题:

.NET 最好的音频压缩库是什么? https://stackoverflow.com/questions/203254/whats-the-best-audio-compression-library-for-net

Update:我没用过这个,但是:

http://www.ohloh.net/p/OggVorbisDecoder http://www.ohloh.net/p/OggVorbisDecoder

我认为您需要一个编码器,但我找不到适用于 Ogg Vorbis 的编码器。我认为您也可以尝试编码为 WMV 格式:

http://www.discussweb.com/c-programming/1728-encoding-wmv-file-c-net.html http://www.discussweb.com/c-programming/1728-encoding-wmv-file-c-net.html

更新2:抱歉,我的直播知识水平很低。如果我正在做像你正在做的事情,我会从音频和静态图像创建一个(未压缩的)AVI 文件(使用avifil32.dll首先,通过 PInvoke 方法),然后将其压缩为 MPEG(或任何标准格式 - YouTube 有一个页面,他们在其中讨论他们的首选格式,并且使用其中一种可能会很好)。

我不确定这是否能满足您的需要,但此链接:

http://csharpmagics.blogspot.com/ http://csharpmagics.blogspot.com/

使用这个免费播放器:

http://www.videolan.org/ http://www.videolan.org/

可能会起作用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

流音频中的降噪和压缩 的相关文章

随机推荐

  • CouchDB 文档更新处理程序(就地更新)

    http wiki apache org couchdb Document Update Handlers http wiki apache org couchdb Document Update Handlers CouchDB 0 10
  • 如何切换不同版本的gem安装?

    我在本地计算机上安装了三个版本的机架 rack 1 4 1 1 3 6 1 3 5 对于某些宝石 例如Cucumber 它需要较低版本rack被激活 我尝试过bundle但也没有什么好处 执行时 cucumber仍将使用激活的机架版本1 4
  • 反汇编Java字节码的Java程序[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我最近正在阅读有关字节码分析的内容 我需要以下查询的帮助 如果我想编写一个反汇编 Java 字节码 通过读取类文件 并打印操作码的 J
  • 如何在 MVC 4 中实现自定义 OpenID 依赖方

    我喜欢新的 MVC OpenID OAuth 登录功能 但我想知道如何添加新的登录按钮 例如我希望我的用户使用他们的 StackExchange 帐户或使用他们的 OpenID url 登录 就像在 stackoverflow 中一样htt
  • Fiddler 重新发行以及作曲家编辑和重新发行

    我在日常生活中使用 Fiddler 然而 对我来说最常用的功能 例如Reissue and Edit and Reissue from composer没有任何捷径 我不知道如何为此使用 fiddler 脚本 有人能指出这个问题的解决方案吗
  • 如何使用 Material ui Reactjs 禁用今天日期中的过去日期?

    我正在使用 React Material ui 创建日期范围选择器 我此功能背后的逻辑是选择所需日期 如果已选择所需日期 则禁用所选日期中的所有过去日期 如何实现这个react材质ui 这是我的代码 import React from re
  • struts 2将属性标签的值分配给隐藏字段

    我想将字段描述中的值分配给隐藏字段测试 但问题是 描述 包含单词序列 并且以下代码仅将第一个单词分配给 测试
  • 何时考虑 Solr

    我正在开发一个应用程序 需要通过搜索来做有趣的事情 包括全文搜索 命中突出显示 分面搜索等 该数据集可能有 3000 10000 条记录 每条记录有 20 30 个字段 并且全部存储在 MySQL 中 该网站的流量概况可能是中小型 所有这些
  • 如何将可绘制图像附加到 Gmail?

    我正在尝试将 gridview 中的图像附加到 gmail 或 facebook 但是每当我尝试附加应用程序时就会崩溃 并且我收到以下带有空指针异常的错误 以下是我使用 gridview 图像选择的代码 有人可以帮忙吗 public cla
  • VSCodium - Python 模块没有绿色语法

    最近 我正在尝试从 VSCode 迁移到 VSCodium 我发现一个问题是VSCodium中没有模块的绿色着色 如下图所示 左 VSCode 具有绿色语法 右 VSCodium 没有绿色语法 我在网上看到一些其他的截图 他们的 VSCod
  • java.time.ZonedDateTime.parse 和 iso8601?

    为什么 JDK8 DateTime 库似乎无法解析有效的 iso8601 日期时间字符串 它因表示为 01 而不是 01 00 的时区偏移而阻塞 这有效 java time ZonedDateTime parse 2015 08 18T00
  • 在 Thymeleaf 方言处理器中访问 HttpServletRequest 和 HttpServletResponse

    我正在尝试创建一个执行 ServletDispatcher include 的 Thymeleaf 方言处理器 我扩展了 AbstractElementTagProcessor 并重写了 doProcess 方法 相关代码片段是 Overr
  • 从中间件调用控制器的操作方法

    我的中间件类位于不同的类库项目中 控制器位于不同的项目中 我正在尝试做的事情是 如果不满足特定条件 则从中间件重定向到自定义控制器 操作方法 但是 我无法使用 Response Redirect 方法来做到这一点 我怎样才能在中间件类中做到
  • 无法在 Go 代码中获取 AWS EKS 集群的 kubeconfig

    我已经创建了一个 AWS EKS 集群 为了获取它的 kubeconfig 我通常运行aws eks update kubeconfig name cluster name region us west 2使用外壳 但是 我现在希望在 Go
  • Docker-compose 命名挂载卷

    为了跟踪 docker compose 使用的卷 我想使用命名卷 这对于 正常 卷非常有效 例如 version 2 services example app volume named vol dir in container volume
  • 如果用户未使用 FastAPI-Login 包登录,则重定向到登录页面

    我想在用户未登录时将他们重定向到登录页面 这是我的代码 from fastapi import Depends FastAPI HTTPException status Body Request from fastapi encoders
  • AS3 的 Tween 库 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有人可以推荐我一个好的 AS3 Tween 库吗 用于 Flash 而不是 Flex 吐温精简版 ht
  • 从服务中删除持续通知

    我有一项在启动时创建通知的服务 然后 ondestroy 我希望将其删除 我只是使用 cancel NOTIFICATION ID 当它是正常通知时它效果很好 但当我使用正在进行的事件时它不会取消它 我确实读到过一些关于如果 android
  • UILabel字体:粗体和斜体[重复]

    这个问题在这里已经有答案了 可能的重复 iPhone iPad的UILabel如何设置粗体和斜体 https stackoverflow com questions 4713236 how do i set bold and italic
  • 流音频中的降噪和压缩

    希望你能帮忙 我正在从麦克风录制音频并通过网络实时传输 样本的质量为 11025hz 8 位 单声道 虽然有一点延迟 1秒 但效果很好 我需要帮助的是我现在正在尝试实现降噪和压缩 以使音频更安静并使用更少的带宽 音频样本存储在 C 的 by