2012-08-23 274 views
1
的无缝继承

我试图做的是发挥循环WAV,但与特定的循环开始喜欢在音乐模块文件(。它,S3M。的.mod等所使用的样本位置)。 SoundPlayer没有这个功能,所以我创建了两个独立的文件:原始的wav和wav,开头切到循环开始的地方。我想连续播放这两个文件,无缝地,首先是带有PlaySync()的原始wav文件,然后是带有PlayLooping()的循环部分。声音播放和播放声音

不幸的是我PlaySync()第一个wav后,有一个分裂秒它和PlayLooping()开始播放循环wav之间的中断。打两个独立不同的声音时

private static void PlayThread(SoundPlayer soundPlayer, byte[] wav, byte[] loop) 
    { 
     MemoryStream stream1 = new MemoryStream(wav); 
     MemoryStream stream2 = new MemoryStream(loop); 
     soundPlayer.Stream = stream1; 
     soundPlayer.PlaySync(); 
     // here is where the split second interruption occurs 
     soundPlayer.Stream = stream2; 
     soundPlayer.PlayLooping(); 
    } 

这可能不明显,但是,试图拉断的循环机制我想的时候是非常明显的。声音波形是乐器样本,非常小(通常不超过0x1000字节)。

回答

0

我不知道什么声音播放,但也许消除线3 + 4,而是写你的第二次浪潮第一流而不是创建新流。这种方式实质上是将更多数据添加到流中以供播放。假设你可以写得比它能播放它快,你应该可以。如果一个MemoryStream允许同时读/写,我不确定是否在我的头顶。我做了类似的事情,但没有手头的代码,而且可能略有不同。

另外,是Play()阻止?即直到完成播放,下一行才会运行。如果是这样,则在第3行读取wav文件时暂停。所以你需要移动。播放到另一个线程,以便您可以在第一次播放时开始加载下一个wave。即使你发现你不能写入第一个内存流,并且不得不创建一个新的内存流,至少你会将Wav文件加载到内存流中,并在第一次完成后立即开始播放。这将显着减少暂停。

考虑具有MP3播放列表的媒体播放器。当一个MP3接近完成时,媒体播放器通常将继续并从磁盘加载下一个mp3并在第一个播放完成之前将其加载到内存中。

0

这里是我的测试看起来像:

 string sMediaPath = @"C:\Windows\Media"; 
     SoundPlayer soundPlayer = new SoundPlayer(); 

     soundPlayer.Stream = File.OpenRead(Path.Combine(sMediaPath, "chimes.wav")); 
     soundPlayer.PlaySync(); 

     soundPlayer.Stream = File.OpenRead(Path.Combine(sMediaPath, "chord.wav")); 
     soundPlayer.PlaySync(); 

我发现,这个测试工作完全一样,你想要的 - 与文件之间没有突然停止。这可能是由于其他原因,但最有可能与文件本身有关

  • 比特率:什么是文件的采样率?
  • 声音文件是否交错(立体声)?
  • 声音文件有多大?

也许你的预加载声音播放他们可能会有所作为之前?

 string sMediaPath = @"C:\Windows\Media"; 
     SoundPlayer soundPlayer = new SoundPlayer(); 

     List<Stream> oSoundStreams = new List<Stream>(); 
     oSoundStreams.Add(File.OpenRead(Path.Combine(sMediaPath, "chimes.wav"))); 
     oSoundStreams.Add(File.OpenRead(Path.Combine(sMediaPath, "chord.wav"))); 

     soundPlayer.Stream = oSoundStreams[0]; 
     soundPlayer.PlaySync(); 

     soundPlayer.Stream = oSoundStreams[1]; 
     soundPlayer.PlaySync(); 

编辑:

通过为每个声一片声音播放对象中播放,似乎有可能搞垮您遇到的短间隔:

 string sMediaPath = @"C:\Users\Foogle\Desktop\"; 
     SoundPlayer soundPlayer1 = new SoundPlayer(); 
     SoundPlayer soundPlayer2 = new SoundPlayer(); 

     soundPlayer1.Stream = File.OpenRead(Path.Combine(sMediaPath, "W.wav")); 
     soundPlayer1.Load(); 

     soundPlayer2.Stream = File.OpenRead(Path.Combine(sMediaPath, "P.wav")); 
     soundPlayer2.Load(); 

     for (int i = 0; i < 10; i++) 
     { 
      soundPlayer1.PlaySync(); 
      soundPlayer2.PlaySync(); 
     } 

也许你可以创建一个SoundPlayer对象集合并根据需要播放它们?

希望这会有所帮助。

干杯!

+0

我改变了我原来的职位描述完全是我想去完成。中断很快,一秒钟,但尝试执行我想要的循环机制时非常明显。我做了两个独立的流,但它仍然不起作用。 – giangurgolo

+0

@giangurgolo没有问题,我编辑了我的答案,并包含另一个场景供您测试。 – Rastus7

0

而不是试图连续播放多个SoundPlayer对象,尝试连接.wav文件,并将合并的.wav文件加载到一个SoundPlayer对象。

下载此WaveIO class,将其添加到您的项目,并尝试下面的代码要连续打无缝多的声音:

string[] files = new string[3] { @"filepath1.wav", @"filepath2.wav", @"filepath3.wav" }; 

WaveIO wa = new WaveIO(); 
wa.Merge(files, @"tempfile.wav"); 

System.Media.SoundPlayer sp = new System.Media.SoundPlayer(@"tempfile.wav"); 
sp.Play();