2009-08-16 87 views
10

Estoy haciendo un programa de muestra en el que cada tecla del 1 al 9 emitirá un sonido diferente. Todo funciona bien, pero cuando presiono dos (o más) sonidos al mismo tiempo, el segundo "mata" al primero.Reproducir múltiples sonidos usando SoundPlayer

Estoy reproduciendo los sonidos de archivos .WAV, usando SoundPlayer. ¿Como puedo resolver esto?

Respuesta

6

Deberá usar DirectX (DirectSound) o alguna API similar que esté diseñada para permitir la reproducción de múltiples sonidos al mismo tiempo.

1

Supongo que en su evento KeyPress (o lo que sea que esté usando) está creando una nueva instancia de SoundPlayer utilizando el constructor que toma una ruta al archivo WAV, y luego llama a su método Play. En teoría, esto no debería causar el efecto "mono" que estás encontrando, ya que Windows ha sido capaz de reproducir múltiples archivos WAV simultáneamente desde Windows 98. Lo que creo que estás escuchando (basado en mi propio uso de esta clase) no es un corte del primer sonido cuando comienza el segundo, sino una falla que resulta de la pausa general de reproducción cuando el archivo WAV se carga desde el disco.

En lugar de cargar una nueva instancia de SoundPlayer en cada pulsación de tecla, intente crear una matriz de objetos SoundPlayer de clase y precargarlos desde el disco en el evento Load de su formulario. Luego simplemente llame al método Play de SoundPlayer cuando se presione la tecla. Esto puede solucionar su problema, aunque creo que de todos modos obtendrá fallas ocasionales de esta manera.

6

Hay una manera simple de reproducir varios sonidos a la vez en C# o VB.Net. Tendrá que llamar a la función de API mciSendString() para reproducir cada archivo .wav. Ni siquiera tendrá que hacer varios subprocesos, a menos que esté jugando en bucle. Here es un ejemplo de trabajo completo de una clase MusicPlayer creada usando mciSendString().

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

En la función anterior, la tecla es el primer comando de parámetro. Siempre que llame a dos funciones con un nombre de comando separado, se reproducirán por separado/simultáneamente. Esto es lo que hice en uno de mis programas 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; 
} 

EDITAR: Agregó un enlace a un ejemplo de trabajo.

+0

Esto funciona pero solo si envía un nuevo nombre de pista único cada vez, ¿es esto por diseño?Si intenta reproducir otro sonido en un nombre de pista utilizado anteriormente (incluso mucho después de que se detuvo el primero), es silencioso. – Sire

+0

@Sire Eso no debería suceder. ¿Estás seguro de que estás enviando el comando "detener" seguido del comando "cerrar" después de completar la reproducción? Puede consultar toda la implementación de MusicPlayer [aquí] (http://pastebin.com/TtrCdeER). Preste especial atención a PlayWorker() que se llama dentro de un hilo para reproducir un audio. –

+0

¡Gracias por el código completo! Agregaría ese enlace a la respuesta. – Sire

3

Usted puede hacer esto:

SoundPlayer soporta WAV corriente. Se podría

  • muestras MIX que jugar 'de mano' y,
  • falso (obtener la cabecera WAV desde algún lugar, no es complicado).

Y proporcione la secuencia como parámetro a the SoundPlayer constructor.

De esta manera no tendrá que usar de alguna manera complicadas bibliotecas DirectSound, y aún tendrá mezcla (múltiples sonidos a la vez).

1
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"); 

Este código podría desempeñar dos archivos de audio al mismo tiempo, la llamada en el segundo audio track2.wav no perturbará el juego de track1.wav.

+0

esa es una buena solución. 2 preguntas: 1. Aparentemente, 'Load' no existe en' MediaPlayer'. Sin embargo, todavía funciona sin eso. 2. Agregar otro 'mPlayer.Play()' justo después del primero no reproducirá el archivo de audio dos veces, sino una vez, ¿por qué? – HeyJude

+0

El método de carga está presente en SoundPlayer, se debe corregir. En segundo lugar, no reproducirá el archivo de audio dos veces porque estamos pasando diferentes archivos de audio. Track1.wav, Track2.wav. – Vijayaraghavan

+0

@Pransesh, permítanme aclarar mi intención: lo que quise decir es que si lo hacemos: 'Function void Play (string audioPath) {... myPlayer.Play(); myPlayer.Play(); } 'entonces Play se ejecutará una vez, en lugar de dos veces. ¿Por qué? – HeyJude

Cuestiones relacionadas