流音频中的降噪和压缩

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(使用前将#替换为@)

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

  • 通过 CMIS (dotCMIS) 连接到 SP2010:异常未经授权

    我正在使用 dotCMIS 并且想要简单连接到我的 SP2010 服务器 我尝试用 C 来做到这一点 如下所示http chemistry apache org dotnet getting started with dotcmis htm
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 重载<<的返回值

    include
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 覆盖子类中的字段或属性

    我有一个抽象基类 我想声明一个字段或属性 该字段或属性在从该父类继承的每个类中具有不同的值 我想在基类中定义它 以便我可以在基类方法中引用它 例如覆盖 ToString 来表示 此对象的类型为 property field 我有三种方法可以
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定

随机推荐

  • 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