问题标签 [waveout]

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.

0 投票
3 回答
808 浏览

c++ - 播放波形文件立即结束 (C++, Windows)

我有以下情况。在一台机器上有一个Fritz ISDN卡。有一个进程负责在此设备的波形输出上播放某个波形文件(ISDN连接在启动时建立并保持不变)。这个场景很简单,只要需要,进程就会调用waveOutWrite()先前打开的 wave 设备(一切都初始化了,当然没有任何问题),并且回调函数等待MM_WOM_DONEmsg 知道播放已经完成。

然而,几天后(过程和机器都没有改变)MM_WOM_DONE消息在调用后立即出现,waveOutWrite()即使波持续了几秒钟。再次没有报告错误,看起来文件已播放但长度为零(事实并非如此)。我也确信waveOutReset()我的进程没有调用它(它也会触发发送提到的消息)。过去我曾经遇到过一些奇怪的问题,只需重新安装TAPI驱动程序即可解决。这次由于某种原因,我再次执行该操作是有问题的,我正在尝试更多的分析方法:)。有什么建议可能导致这种行为吗?也许在ISDN线路的另一端有什么东西?

0 投票
1 回答
992 浏览

c# - 尝试在 C# 中使 waveout 工作时 vhost.exe 崩溃

我尝试在 C# 中使用 waveout 来同时播放更多的 wav 文件(至少是不同的文件)。(SoundPlayer 对象一次只播放一个,我不想为这个简单的目标使用 DirectSound 和 MediaPlayer 对象或任何其他高级技术。)

我将一个工作的 C++ 代码移植到 C# 并且它可以工作(在研究了如何编组和如何调用本机 win32 dll-s 以及如何分配和锁定非托管内存之后)但它以某种方式使 vhost.exe 崩溃,我不知道为什么这样做。(它不会抛出任何异常,只会出现标准的 windows 错误对话框并且程序崩溃并退出。)

有没有人有任何想法?

这是该类的来源:

0 投票
3 回答
2770 浏览

windows - 来自 waveOutWrite API 方法的回调的延迟(或延迟)时间是多少?

我正在另一个论坛上与一些开发人员就准确生成 MIDI 事件(注意消息等)进行辩论。人耳对轻微的计时误差非常敏感,我认为他们的主要问题来自于他们使用分辨率相对较低的计时器,这些计时器以大约 15 毫秒的间隔量化他们的事件(这足以导致可察觉的不准确性)。

大约 10 年前,我编写了一个示例应用程序(Windows 95 上的 Visual Basic 5),它是一个组合的软件合成器和 MIDI 播放器。基本前提是一个跳跃缓冲播放系统,每个缓冲区是十六分音符的持续时间(例如:每分钟有 120 个四分音符,每个四分音符是 500 毫秒,因此每个十六分音符是 125 毫秒,所以每个缓冲区为 5513 个样本)。每个缓冲区都通过 waveOutWrite 方法播放,该方法的回调函数用于排队下一个缓冲区并发送 MIDI 消息。这使基于 WAV 的音频和 MIDI 音频保持同步。

在我看来,这种方法效果很好——MIDI 音符听起来甚至没有一点不同步(而如果你使用精确到 15 毫秒的普通计时器来播放 MIDI 音符,它们听起来会明显不同步)。

理论上,这种方法会产生精确到样本的 MIDI 时序,即 0.0227 毫秒(因为每毫秒有 44.1 个样本)。我怀疑这是这种方法的真正延迟,因为在缓冲区完成和通知 waveOutWrite 回调之间可能存在一些轻微延迟。有谁知道这个延迟实际上会有多大?

0 投票
2 回答
1328 浏览

winapi - 查询 HWAVEOUT 句柄的波形格式

上下文:我有一段代码知道 waveOut 句柄 (HWAVEOUT) 的值。但是代码没有创建句柄,因此在创建句柄时传递给 waveOutOpen 的 WAVEFORMATEX 是未知的。

我想找出传递给 waveOutOpen 调用的那个 WAVEFORMATEX 结构的内容。

使用它的更多细节:代码在调用而不是 waveOutWrite 的挂钩函数中运行。因此代码知道句柄值,但不知道句柄创建的细节。

只是为了让人们不需要查找:
waveOutOpen 的签名是

waveOutWrite 的签名是:

注意:我也在挂钩 waveOutOpen,但它可能在我有挂钩之前就已经被调用了。

0 投票
4 回答
5915 浏览

multithreading - waveOut (Win32API) 和多线程

我找不到任何有关 waveOut API 的线程安全的信息。

在我创建新的 waveOut 句柄后,我有这些线程:

线程 1:缓冲区处理。使用这些 API 函数:

  • waveOutPrepareHeader
  • waveOutWrite
  • waveOutUnprepareHeader

线程 2: Gui,控制器线程。使用这些 API 函数:

  • waveOutPause
  • waveOutRestart
  • waveOutReset
  • waveOutBreakLoop

这两个线程在同时使用相同的 waveOut 句柄时运行。在我的测试中,我没有发现该功能有任何问题,但这并不意味着它是安全的。

这种架构是线程安全的吗?是否有任何关于 waveOut API 的线程安全的文档?关于 waveOut API 线程安全的任何其他建议?

谢谢。

0 投票
1 回答
373 浏览

volume - DirectSound 影响 WinXP 上的系统音量

我目前正在开发用于语音网络聊天软件的音频引擎。一切正常 - 捕获/播放/混合通道。

问题在于在 Windows XP 下使用它。我一直在收到用户报告,其中包含启动应用程序后他们的全局系统容量设置为零的信息。

我假设这是由于 WaveOut/DSound 冲突而发生的。

如何强制 DSound 不影响系统音量?播放设备初始化:DirectSoundCreate8(&GUID, &pAudio, NULL);

和:

pAudio->SetCooperativeLevel(parentWnd, DSSCL_PRIORITY);

我目前无法调试应用程序,因为我使用的是 Vista 并且一切正常。

希望你能帮我解决这个问题!多谢!

问候,安东。

0 投票
1 回答
325 浏览

c# - 包装原生库时维护封装

我正在编写一个 C# 库来包装 Win32 API(waveOut...函数系列),并且已经到了我不确定如何在不破坏封装的情况下管理代码不同部分之间的交互的地步。到目前为止,我有这样的设置:

这段代码中最重要的一点是,被 Device 包裹的句柄对于 Device 之外的任何东西都是不可见的。

现在我想添加一个AudioBlock类,它将包装原生WAVEHDR结构和音频样本数据。我遇到的问题是,从现在开始,我感兴趣的几乎所有其他本机函数 ( waveOut[Un]PrepareHeader, waveOutWrite) 都需要句柄和WAVEHDR. 似乎要么设备必须触摸WAVEHDR,要么块必须有权访问句柄。任何一种方法都意味着某些类与它在概念上不知道业务的事物交互。

当然,有几种方法可以解决这个问题:

  1. 使句柄和/或WAVEHDR内部而不是私有。

  2. 创建AudioBlock一个嵌套类.Device

  3. 有一个第三类(我什至不敢想名字(foo)Manager),它维护(例如)从块到标题的映射,给定一个块,设备可以使用它来帮助它播放样本,而无需触及块的内部。

可能还有其他人;我希望如此:)

我对这些方法的反对意见(对或错):

  1. 他们可能不是严格意义上的公开,但使用内部成员对我来说似乎是一种逃避。库中不需要它们的部分仍然可以看到有效的实现细节。我一直在想“我想向使用或修改此代码的任何人呈现什么界面?”

  2. 这几乎在我脑海中起作用。通过将块视为设备的“实现细节”,允许它依赖设备的内部结构似乎更容易接受。除了一个块真的是一个独立的实体;它不依赖于单个设备,也不用于帮助实现设备的逻辑。

  3. 这最接近我想要保持的分离水平,但开始误入过度工程领域,就像我经常做的那样:P 它还引入了一个人为的想法,即必须从某个地方集中分配块以保持映射完整.

那么,是否有人对(重新)构建此代码有任何建议?有效答案包括“你的反对意见#X 是一个热气腾腾的锅”,只要你能说服我 :) ETA:例如,如果你认为通过社交手段(文档、惯例)来强制执行这种事情比技术性的(访问修饰符、程序集边界),请告诉我并指出一些参考资料。

0 投票
1 回答
937 浏览

winapi - waveOutSetVolume 忽略句柄

我的代码中有几个并行播放的波形句柄。

现在我想为每个波形手柄设置不同的音量。

有一个waveOutSetVolumewin32api函数:http: //msdn.microsoft.com/en-us/library/ms713762%28v=vs.85%29.aspx

问题是,它完全忽略了我发送的句柄,它为我的程序中的所有波形句柄设置了音量。

如何使其将音量设置为特定的waveout句柄?

0 投票
1 回答
787 浏览

c++ - Flash 和音频挂钩

我正在尝试捕获 activeX flash 组件正在播放的音频。

我通过找到flash.ocx 模块并挂钩 waveOutWrite 函数来做到这一点。

这似乎运作良好,但是我无法区分在内部调用 waveOutWrite 的不同 activex 实例,因为音频似乎来自同一个线程并针对同一个输出设备。

我的问题是如何区分谁在调用 waveOutWrite?

我认为答案在于为每个 activex 实例加载一个 flash.ocx 实例,虽然模块加载由 COM 自动处理,但不确定如何实现这一点。我的一个想法是在不同的进程中创建 activex 组件,希望这会导致从不同的线程调用 waveOutWrite 函数。然而,这似乎是实现这一目标的一种相当复杂的方法。

有任何想法吗?

0 投票
1 回答
135 浏览

c# - 线程困境,至少我认为是

我正在尝试输出音频样本,并使用来自http://www.codeproject.com/KB/audio-video/cswavplay.aspx的 cswavplay 来执行此操作,而后者似乎又DllImports来自 winmm.dll。

我确实让它使用 8 位样本播放,但是当我尝试向它提供 16 位样本时它失败了。我尽我所能挖掘代码,我将其理解为:

每次 cswavplay 播放完最后一个缓冲区时,我都会得到一个指向缓冲区的指针。它适用于一次迭代,它播放一个缓冲区,有时......我得到了各种有趣的异常,例如当我尝试使用 44100 的缓冲区大小来更清楚地听到播放了多少时,AccessViolationException。但是当我在 WaveOut 类(cswavplay 的一部分)内的不同位置放置断点时,似乎它使用的所有对象(如缓冲区和 AutoResetEvent 的实例)在第二次迭代中仍然存在。我最好的猜测是这些问题与线程或 GC 有关。例外情况似乎很随机,而且我经验不足,无法完全理解发生了什么。

我要求以下任何一项:

1)关于可能是什么问题的疯狂猜测

2)有根据的猜测可能是什么问题

3) 指向使用 C# 实时输出声音的另一种方法

我不是要求对我没有编写的软件进行彻底的错误跟踪,所以不要介意 cswavplay ......

归根结底,我可能在这里做错了什么,但很难知道我什么时候没有得到相关的异常(沿着BufferAllocationException或其他的线)......

编辑:

感谢所有关于其他声音 API 的建议。他们似乎都假设一个 .wav 文件。很抱歉不清楚,我不是在播放 .wav 文件,我是实时合成样本。