14

我正在制作一个采样器程序,其中从 1 到 9 的每个键都会发出不同的声音。一切正常,但是当我同时按下两个(或更多)声音时,第二个“杀死”第一个。

我正在播放 .WAV 文件中的声音,使用SoundPlayer. 我该如何解决这个问题?

4

6 回答 6

7

您需要使用 DirectX (DirectSound) 或一些旨在允许同时播放多个声音的类似 API。

于 2009-08-16T20:43:32.047 回答
7

有一种简单的方法可以在 C# 或 VB.Net 中一次播放多个声音。您必须调用mciSendString()API 函数来播放每个 .wav 文件。你甚至不必做多线程,除非你在循环播放。MusicPlayer是使用创建的类的完整工作示例mciSendString()

// Sound api functions
[DllImport("winmm.dll")]
static extern Int32 mciSendString(string command, StringBuilder buffer, int bufferSize, IntPtr hwndCallback);

在上述函数中,关键是第一个参数命令。只要您使用单独的命令名称调用两个函数,它们就会分别/同时播放。这是我在我的一个 C# 程序中所做的:

private void PlayWorker()
{
    StringBuilder sb = new StringBuilder();
    mciSendString("open \"" + FileName + "\" alias " + this.TrackName, sb, 0, IntPtr.Zero);
    mciSendString("play " + this.TrackName, sb, 0, IntPtr.Zero);
    IsBeingPlayed = true;
}

编辑:添加了一个工作示例的链接。

于 2011-07-18T04:58:05.023 回答
3

你可以这样做:

SoundPlayer支持 WAV 流。你可以

  • 混合您“手动”演奏的样本,并且,
  • 假的(从某个地方获取 WAV 标头,并不复杂)。

并将这样的流作为参数提供给构造SoundPlayer函数

这样您就不必使用某种复杂的 DirectSound 库,并且仍然可以进行混音(一次多个声音)。

于 2012-02-02T21:53:17.693 回答
3
using System.Windows.Media

Function void Play(string audioPath)
{
MediaPlayer myPlayer = new MediaPlayer();
myPlayer.Open(new System.Uri(audioPath));
myPlayer.Play();
}

Play(Application.StartupPath + "\\Track1.wav");
Play(Application.StartupPath + "\\Track2.wav");

此代码可以同时播放两个音频文件,第二个音频的调用track2.wav不会干扰track1.wav.

于 2016-06-27T08:35:15.440 回答
1

我猜在您的 KeyPress 事件(或您正在使用的任何东西)中,您正在使用构造函数创建一个新的 SoundPlayer 实例,该构造函数采用 WAV 文件的路径,然后调用其 Play 方法。从理论上讲,这不应该导致您遇到的“单声道”效果,因为自 Windows 98 以来,Windows 已经能够同时播放多个 WAV 文件。我认为您所听到的(基于我自己对此类的使用)不是第二个声音开始时第一个声音的截止,而是实际上是由于从磁盘加载 WAV 文件时整体播放暂停而导致的故障。

不要在每次按键时加载一个新的 SoundPlayer 实例,而是尝试创建一个类范围的 SoundPlayer 对象数组,并在表单的 Load 事件中从磁盘预加载它们。然后在按下键时调用每个 SoundPlayer 的 Play 方法。这可能会解决您的问题,尽管我认为您仍然会以这种方式偶尔出现故障。

于 2009-08-16T21:03:45.010 回答
0

您需要通过 SharpDX 使用 xAudio2,它是专门用于游戏开发的 directX 组件,您可以在此处找到完整的工作示例: https ://github.com/sharpdx/SharpDX-Samples/tree/master/Desktop/XAudio2/PlaySound

于 2020-06-05T22:26:08.650 回答