问题标签 [directsound]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - DirectSound:如何改变麦克风的输入音量?
我对 Directsound 和 windows 混音器有一些疑问。我的目标是枚举所有麦克风并能够更改每个麦克风的输入音量。我认为我离解决方案不远,但我没有发现我的代码有什么问题。这是我所做的: - 我枚举所有输入设备并为每个设备获取一个 GUID - 我使用在主题上找到的方法来获取与使用此方法的直接声音 guid 相对应的混音器 ID(但我不确定是否它有效) - 然后我得到与混音器中的控件相对应的 id - 然后我可以修改音量
这是代码:一个vs2008项目
为了测试,我连接了两个麦克风 USB + 线路输入麦克风,我目视检查哪些滑块在移动。但不幸的是,这不是一个好的...这里是我在 windows xp 中打开的所有混音器的屏幕截图 (img177.imageshack.us/img177/5189/mixers.jpg)。
你知道我做错了什么吗?有没有最简单的解决方案?
附加问题:您知道是否有办法使用 Directsound 来了解 Line-in 中是否连接了麦克风?因为即使没有连接麦克风,线路输入也始终被检测为已连接。
.net - Directsound 播放捕获的音频
我正在尝试开发一个简单的 DirectSound 应用程序,但缺乏 .net 文档让我很沮丧。
我想从一台设备捕获音频并将其播放回另一台设备。(如音频中继器)我有捕获部分,但我不知道如何将捕获缓冲区发送到辅助缓冲区。
有谁知道那里的 .net 示例?
c# - 有什么方法可以仅使用 waveIn API 获取音频设备的 GUID?
我问这个的原因是因为我想关联一个给定的 winmm 音频设备,比如你使用 waveInOpen 打开的那些设备和一个 directSound 设备。
buffer - 我应该何时分配 DirectSound 缓冲区?
请帮我拿定主意。
- 在应用程序开始时分配,在出口处免费。
- 流媒体开始时分配,流媒体停止后立即免费。
哪一个?为什么?
以防万一:它是像 Ekiga 这样的语音通信应用程序。我正在使用 DSSCL_NORMAL 分配缓冲区(据我测试,8 位 22KHz 限制是错误的)。
delphi - 带有流缓冲区的 Directsound - 锁定不换行!为 Delphi 使用移植的 DirectX 标头
对,我正在我们的 Delphi voip 应用程序中实现 DirectSound(该应用程序允许多个用户通过网络连接使用无线电)数据通过 UDP 广播进入。就像现在一样,我们深入到原始数据级别,并自己进行来自多个来源的音频混合,并拥有一个用于回放所有这些的集中式组件。
该应用程序本身是一个 Delphi 5 应用程序,我的任务是将其移植到 Delphi 2010。一旦我进入这个音频播放部分,我们得出的结论是,如果我们可以摆脱这个旧代码并用 directsound 替换它是最好的。
因此,我们的想法是每个无线电有一个 SecondaryBuffer(我们每个无线电连接都有一个“面板”,基于我们为每个特定无线电创建的一组组件),并让它们在获得时将数据添加到各自的 SecondaryBuffer数据,只有在数据用完时才会暂停以填充缓冲区中半秒的音频数据。
现在,我被困在向测试应用程序中的缓冲区添加数据的部分,在我开始编写组件以按照我们想要的方式使用它之前,我只是想让它正常工作。
我正在为 Delphi 使用移植的 DirectX 标头(http://www.clootie.ru/delphi/download_dx92.html)
这些头文件的重点是将常规 DirectSound 接口移植到 Delphi,因此希望使用 DirectSound 的非 Delphi 程序员也可以知道我的问题的原因是什么。
我的 SecondaryBuffer (IDirectSoundBuffer) 创建如下:
我省略了我定义我的 PrimaryBuffer 的部分(它被设置为使用循环标志,并且完全按照 MSDN 所说的那样创建)和 DSInterface,但它就像你想象的 IDirectSoundInterface 一样。
现在,每次我收到一条音频消息(由我们制作的其他组件检测、解码并转换为适当的音频格式,这些组件已确认可以工作超过七年),我都会执行以下操作:
AudioData contains the data in my message. Messages always contain 512 bytes of audio data. I added the Memo1.Lines.Add lines to be able to get some debug output (since using breakpoints doesn't quite work, as directsound keeps playing the contents of the primary buffer regardless)
Now, when I'm playing my DSCurrentBuffer using the looping flag (which according to hte MSDN docs is enough to make it a Streaming Buffer) and having this code work out as it wants, my output text in the Memo show that I am being allowed to write up until the end of the buffer... But it doesn't wrap.
SecondPart is always nil. It never ever wraps around to the beginning of the buffer, which means I get the same few seconds of audio data playing over and over.
And yes, I have scoured the net for components that can do this stuff for us and have concluded that the only reliable way is to do it ourselves like this.
And yes, the audio data that this app plays is choppy. I'm holding off on writing the half-a-second buffering code until I can get the write-to-buffer code to wrap as it should :/
I have been reading that people suggest keeping track of your own write cursor, but from what I read Lock and Unlock should help me bypass that need. I'd also rather avoid having to have two buffers that I alternate between back and forth (or a split-buffer, which would essentially be the same thing, only a bit more complex in writing)
Any help greatly appreciated!
c# - 为什么 DirectSound Buffer 在调试条件下无法播放?
我的波不会在调试下播放。如果我按 CTRL+F5,我会得到一个不错的 WAV,控制台会写出文件光标位置 ( buf.PlayPosition
),然后当声音结束时该方法退出。在调试下(当我只是按 F5 时)没有音频输出,但是文件光标位置在控制台窗口中仍然增加,并且方法无异常退出。
有任何想法吗?
delphi - Directsound - 播放充满来自网络的数据的流缓冲区时出现问题!为 Delphi 使用移植的 DirectX 标头
再次回到另一个 DirectSound 问题,这个关于 DirectSound 缓冲区可以使用的方式:
我有大约 30 毫秒间隔通过网络传入的数据包,其中包含由应用程序的其他部分解码为原始 wav 数据的音频数据。
当 Indata 事件由这些其他代码段触发时,我基本上被放入一个以音频数据作为参数的过程中。
DSCurrentBuffer 初始化如下:
我将此数据写入我的辅助缓冲区,如下所示:
输入数据在这里转换为音频数据,与问题本身无关。
以上是我在 OnAudioData 事件中运行的代码(由我们的专有组件定义,该组件解码使用我们的协议发送的消息。)基本上,只要我收到带有音频数据的 UDP 消息,就会运行该代码。
写入缓冲区后,一旦缓冲区中有足够的数据,我将执行以下操作以开始播放: 顺便说一下,BufferSize 目前设置为相当于 1 秒。
到目前为止一切都很好,虽然音频播放有点断断续续。不幸的是,这段代码还不够。
我还需要停止播放并等待缓冲区在数据用完时再次填满。这是我遇到问题的地方。
基本上,我需要能够找出音频播放何时到达我上次写入缓冲区的位置,并在它到达时停止它。否则,我收到的音频数据的任何延迟都会弄乱音频,当然。不幸的是,我不能停止写入缓冲区,因为如果我让缓冲区继续播放,它只会播放一秒钟前留下的旧数据(什么是循环的等等。)所以我需要知道 PlayCursorPosition 是否已达到我在缓冲区写入代码中跟踪的 LastWrittenByte 值。
DirectSound Notifications 似乎可以为我做到这一点,但是每次我向它写入数据时停止然后重新启动缓冲区(SetNotificationPositions() 需要停止缓冲区)对播放本身有显着影响,所以音频播放的声音比以前更加破碎。
我将此添加到编写代码的末尾以获取通知。每次我将数据写入缓冲区时,我都希望设置一个新的通知可能不会很好......但是,嘿,我认为尝试一下不会有什么坏处:
NotificationThread 是一个执行 WaitForSingleObject 的线程。CreateEvent 创建一个新的事件句柄并使其成为 WaitForSingleObject 将开始等待它而不是前一个。ReachedLastWrittenByte 是我的应用程序中定义的一个过程。线程启动一个临界区,并在触发通知时调用它。(WaitForSingleObject 的调用超时时间为 20 毫秒,因此我可以在调用 CreateEvent 时更新句柄,当然。)
ReachedLastWrittenByte() 执行以下操作:
当我的通知被触发并且我在我正在使用的辅助缓冲区上调用 Stop 时,音频仍然继续循环主缓冲区中似乎是剩余数据的内容......
即便如此,通知也没有正确触发。如果我停止从发送这些音频消息的其他应用程序广播音频数据,它只会不断循环缓冲区中的剩余部分。所以基本上,不管怎样,它都会超过我设置的最新通知(lastwrittenbyte)。在播放时,它只是偶尔停止,填充缓冲区然后开始播放......并跳过它刚刚缓冲的半秒数据,继续播放缓冲区填充后传入的数据(所以它填满缓冲区,但显然不关心在开始填充新数据之前播放其内容。是的。我也不知道。)
我在这里似乎缺少什么?使用 DirectSound Notificatiosn 找出最近写入的字节何时播放的想法是徒劳的吗?你会认为有一些方法可以使用流缓冲区进行这种缓冲。
c# - 是否可以使用 DirectSound 在 C# 中转码音频?
我想将大量音频从源格式转码为 PCM,而不需要重新采样或弄乱样本大小。我想如果 Windows Media Player 可以播放该文件并且它不使用旧版 ACM 编解码器,那么它必须使用 DirectSound 来播放(这是在 Windows XP 和 Windows Server 2k3 上)。那么是否可以从 C# 访问 DirectSound 并这样做?我试过在网上搜索,但所有的例子都是关于播放的,我没有兴趣做。
c# - 语音会议 - 如何让更多人参与对话?
首先,我只是一个业余爱好者,所以如果这是一个愚蠢的问题或者我太天真了,我很抱歉。(这也意味着我买不起昂贵的图书馆)
情况是这样的:我正在 C#.NET 中构建一个简单的语音聊天应用程序(类似于 Ventrilo 或 TeamSpeak,但仅适用于大约 15 或 20 人,并在 100Mbps LAN 上运行)。我有工作服务器(每个客户端的生成线程)和客户端应用程序,使用 UDP 进行连接,使用 DirectSound 来捕获和播放声音。我可以进行“一对一”通话,但我无法弄清楚最重要的事情之一:
我如何在对话中有两个以上的人?
c# - 使用哪个音频库?
我想构建一个 .Net 应用程序来处理音频,并使用 ClickOnce 部署分发它。我需要访问原始音频管道。我应该使用哪个音频库?我听说 DirectSound 的托管库是一条死胡同。我需要尽可能少地安装在客户端的机器上。ClickOnce 过程之外的任何操作都不起作用。
NAudio 可能是一种可能性,但是否有可能单独安装驱动程序?还有 SlimDX。
很遗憾——托管的 DirectX 库似乎运行良好,根据我的阅读,DirectX 可以包含在 ClickOnce 安装中。