从流中播放波形文件

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 中的本机波函数和结构来实现你想要的东西。

很抱歉这个模糊的答案,但我没有时间彻底测试它。

【讨论】:

以上是关于从流中播放波形文件的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5 - 无法从流中播放视频

iOS - 如何从流中读取音频并播放音频

NAudio - 从 Stream 播放 MIDI

在波形上显示波形文件播放进度的最佳方式

在linux中播放波形文件[关闭]

如何在 Flash 中创建一个音乐播放器来创建音频文件的波形?