从流中播放波形文件
Posted
技术标签:
【中文标题】从流中播放波形文件【英文标题】:Playing wave files from stream 【发布时间】:2012-01-13 11:58:50 【问题描述】:我必须设计一个播放声音的程序(来自 WAV 文件)。我必须创建一个 wav 并播放它。完成后,我必须更改该波形文件的内容并再次播放。这就像播放一个不断变化的波形文件。我想创建一个流,但问题是当我编辑该流时(使用 ms.Postion 和 ms.WriteByte),出现错误,提示“wave 头文件已损坏”。以下是我的代码:
MemoryStream ms = new MemoryStream(Sample1);
SoundPlayer myPlayer = new SoundPlayer(ms);
myPlayer.Play(); //Wav file plays
for (int x = 0; x < 50; x++)
ms.Position = 44 + x;
ms.WriteByte(10);
myPlayer.Stop();
myPlayer.Play(); //Header file corrupt
是否有另一种方法可以循环播放流,并在播放时更改其内容。例如,流正在循环 Sound1,每当按下按钮时,流的内容都会更改为播放 Sound2。
谢谢!
【问题讨论】:
尝试将整个内存流写入一个文件,看看SoundPlayer
是否在做一些意想不到的事情,比如不使用规范的 .wav 文件格式。不编辑内存流时Sample1
会播放吗?
是的,当我不编辑内存流时它会播放
现在我已经设法通过更改数组“Sample1”的内容来更改流的内容。问题是当我运行声音播放器(即 myPlayer.PlayLooping)时,我只能听到原始流的内容。我找不到将声音播放器设置为播放新流的方法。谢谢
头文件损坏是因为开始播放时,内存流中的位置不为0。要解决这个问题,首先需要写入整个内存流,设置文件长度在标题中,将位置设置为 0 并开始播放。
【参考方案1】:
我试过做你想做的同样的事情,也失败了。似乎SoundPlayer
类将内容复制到内部缓冲区或直接保留声卡内存。当你第一次调用 play 时,它也会调用 Load
来做前面提到的事情。将相同的流重新分配给该类并没有帮助我,调用 Load 强制它重新加载内容也失败了。我不知道他们是如何实现这个类的,但我认为你需要有两个 SoundPlayer
类和 (very likely
) 你可以在同一个流中使用它们(尽管我认为你不能同时播放它们同时,不是因为共享流,而是因为其他问题)。如果生成的波不是很大,您还可以尝试使用具有两个内存流的单个 SoundPlayer
类(我认为如果您为该类分配不同的内存流,它应该强制重新加载)。我还没有测试任何建议的解决方案。只要记住在将流传递给SoundPlayer
类之前倒带它(我怀疑这是标题损坏问题的原始问题)。我没有对此进行测试,但我认为它应该可以工作。至少据我所知,更改 Sample1
的内容不应该对内存流产生任何影响
如果上述方法失败,或者只是因为您像我一样是性能狂,我建议您使用 DirectSound(托管 DirectX 的一部分)(如果可用)或导入并使用位于 winmm.dll 中的本机波函数和结构来实现你想要的东西。
很抱歉这个模糊的答案,但我没有时间彻底测试它。
【讨论】:
以上是关于从流中播放波形文件的主要内容,如果未能解决你的问题,请参考以下文章