2009-08-16 16 views
10

Sto creando un programma di campionamento in cui ogni tasto da 1 a 9 emetterà un suono diverso. Tutto funziona bene, ma quando premo due (o più) suoni allo stesso tempo, il secondo "uccide" il primo.Riproduzione di più suoni mediante SoundPlayer

Sto riproducendo i suoni dai file .WAV utilizzando SoundPlayer. Come posso risolvere questo?

risposta

6

È necessario utilizzare DirectX (DirectSound) o API simili progettate per consentire la riproduzione di più suoni allo stesso tempo.

1

Immagino che durante l'evento KeyPress (o qualsiasi altra cosa tu stia utilizzando) stai creando una nuova istanza di SoundPlayer usando il costruttore che prende un percorso per il file WAV e poi chiama il suo metodo Play. In teoria questo non dovrebbe causare l'effetto "mono" che stai incontrando, dal momento che Windows è stato in grado di riprodurre più file WAV contemporaneamente da Windows 98. Ciò che penso tu stia ascoltando (basato sul mio uso personale di questa classe) non è un taglio del primo suono quando inizia il secondo, ma in realtà un problema tecnico che risulta dalla riproduzione generale in pausa mentre il file WAV viene caricato dal disco.

Invece di caricare una nuova istanza di SoundPlayer su ciascun tasto premere, provare a creare una serie di oggetti SoundPlayer con ambito classe e precaricarli dal disco nell'evento Load del modulo. Quindi basta chiamare il metodo Play di ciascun SoundPlayer quando si preme il tasto. Questo potrebbe risolvere il tuo problema, anche se penso che continuerai ad avere problemi occasionali in questo modo.

6

C'è un modo semplice per riprodurre più suoni contemporaneamente in C# o VB.Net. Dovrai chiamare la funzione API mciSendString() per riprodurre ogni file .wav. Non dovrai nemmeno fare il multi-threading, a meno che non stiate eseguendo il loop. Here è un esempio operativo completo di una classe MusicPlayer creata utilizzando mciSendString().

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

Nella funzione sopra riportata, il tasto è il primo comando di parametro. Finché si chiamano due funzioni con un nome di comando separato, queste suoneranno separatamente/simultaneamente. Questo è quello che ho fatto in uno dei miei programmi 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; 
} 

MODIFICA: aggiunto collegamento a un esempio di lavoro.

+0

Questo funziona, ma solo se si invia ogni volta un nuovo nome traccia univoco, è questo in base alla progettazione?Se provi a riprodurre un altro suono su un trackname utilizzato in precedenza (anche molto tempo dopo che il primo si è fermato), è silenzioso. – Sire

+0

@Sire Questo non dovrebbe accadere. Sei sicuro di inviare il comando "stop" seguito dal comando "close" una volta completata la riproduzione? Puoi fare riferimento alla mia intera implementazione di MusicPlayer [qui] (http://pastebin.com/TtrCdeER). Prestare particolare attenzione a PlayWorker() che viene chiamato all'interno di un thread per la riproduzione di un audio. –

+0

Grazie per il codice completo! Vorrei aggiungere questo link alla risposta. – Sire

3

Si potrebbe fare questo:

SoundPlayer supporta WAV Stream. Si potrebbe

  • campioni MIX si gioca 'per mano' e,
  • Falso (ottenere l'intestazione WAV da qualche parte, non è complicato).

E fornire tale flusso come parametro a the SoundPlayer constructor.

In questo modo non sarà necessario utilizzare librerie DirectSound in qualche modo complicate e continuare a mixare (più suoni contemporaneamente).

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

Questo codice potrebbe svolgere due file audio contemporaneamente, la chiamata in seconda audio track2.wav non disturberà il gioco di track1.wav.

+0

questa è una bella soluzione. 2 domande: 1. apparentemente, 'Load' non esiste in' MediaPlayer'. Funziona ancora senza di essa, però. 2. Aggiungendo un altro 'mPlayer.Play()' subito dopo che il primo non riprodurrà il file audio due volte, ma una volta - perché? – HeyJude

+0

Il metodo di caricamento è presente in SoundPlayer, deve essere corretto. In secondo luogo, non riprodurrà il file audio due volte perché stiamo passando diversi file audio. Track1.wav, Track2.wav. – Vijayaraghavan

+0

@Pransesh, permettetemi di chiarire la mia intenzione: quello che intendevo è che se lo facciamo: 'function void Play (string audioPath) {... myPlayer.Play(); myPlayer.Play(); } 'allora Play verrà eseguito una volta, invece di due. Perché? – HeyJude

Problemi correlati