Ответ 1
Вам нужно будет использовать DirectX (DirectSound) или какой-либо аналогичный API, который предназначен для одновременного воспроизведения нескольких звуков.
Я делаю программу сэмплера, где каждый ключ от 1 до 9 будет создавать другой звук. Все работает нормально, но когда я нажимаю два (или более) звука одновременно, второй "убивает" первый.
Я воспроизвожу звуки из .WAV файлов, используя SoundPlayer
. Как я могу это решить?
Вам нужно будет использовать DirectX (DirectSound) или какой-либо аналогичный API, который предназначен для одновременного воспроизведения нескольких звуков.
Существует один простой способ одновременного воспроизведения нескольких звуков на С# или VB.Net. Вам нужно будет вызвать функцию API mciSendString()
для воспроизведения каждого .wav файла. Вам даже не придется делать многопоточность, если вы не играете в петле. Здесь - полный рабочий пример класса MusicPlayer
, созданного с помощью mciSendString()
.
// Sound api functions
[DllImport("winmm.dll")]
static extern Int32 mciSendString(string command, StringBuilder buffer, int bufferSize, IntPtr hwndCallback);
В приведенной выше функции ключ является первой командой параметра. Пока вы вызываете две функции с отдельным именем команды, они будут играть отдельно/одновременно. Это то, что я сделал в одной из моих программ на С#:
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;
}
EDIT: добавлена ссылка на рабочий пример.
Вы можете сделать это:
SoundPlayer
поддерживает WAV-поток. Вы могли
И укажите такой поток как параметр конструктор SoundPlayer
.
Таким образом вам не придется использовать какие-то сложные библиотеки DirectSound и все еще иметь микширование (сразу несколько звуков).
Я предполагаю, что в вашем событии KeyPress (или независимо от того, что вы используете) вы создаете новый экземпляр SoundPlayer, используя конструктор, который берет путь к WAV файлу, а затем вызывает его метод воспроизведения. Теоретически это не должно вызывать эффект "моно", с которым вы сталкиваетесь, поскольку Windows способна одновременно воспроизводить несколько файлов WAV с Windows 98. То, что, как я думаю, вы слышите (основано на моем собственном использовании этого класса) не является срезом первого звука при втором запуске, но на самом деле является сбоем, который является результатом общего приостановления воспроизведения, когда WAV файл загружается с диска.
Вместо того, чтобы загружать новый экземпляр SoundPlayer при каждом нажатии клавиши, попробуйте создать массив объектов SoundPlayer класса и предварительно загрузить их с диска в форме Load event. Затем просто вызовите каждый метод воспроизведения SoundPlayer, когда нажата клавиша. Это может решить вашу проблему, хотя я думаю, что вы все равно будете сталкиваться с такими сбоями.
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
.