2017-10-21 29 views
0

J'utilise C# WPF pour effectuer une FFT en temps réel. J'utilise WaveIn et BufferedWaveProvider de NAudio pour capturer tout son enregistré par Stereo Mix. Je prends la FFT du buffer plusieurs fois par seconde et l'affiche en utilisant un bitmap de sorte que l'affichage montre une transformée de Fourier en temps réel de tout son passant par les haut-parleurs. Mon problème est que, comme prévu, la FFT affichée est légèrement inférieure à l'audio provenant des enceintes (peut-être 200 ms).Comment retarder la lecture audio pour la synchronisation avec FFT

Y a-t-il un moyen d'enregistrer l'audio actuel qui est censé être lu par les haut-parleurs pour que je puisse effectuer la FFT et ensuite le lire un peu plus tard (par exemple 200 ms) coupure de l'audio en temps réel original.

Le résultat final serait simplement d'éliminer efficacement le retard perçu de la FFT affichée. L'audio d'une vidéo YouTube, par exemple, serait légèrement en retard sur la vidéo pendant que mon programme est en cours d'exécution.

Voici les méthodes pertinentes de ce que j'ai en ce moment:

public MainWindow() 
    { 
     sampleSize = (int)Math.Pow(2, 13); 
     BUFFERSIZE = sampleSize * 2; 

     InitializeComponent(); 

     // get the WaveIn class started 
     WaveIn wi = new WaveIn(); 
     wi.DeviceNumber = deviceNo; 
     wi.WaveFormat = new NAudio.Wave.WaveFormat(RATE, WaveIn.GetCapabilities(wi.DeviceNumber).Channels); 

     // create a wave buffer and start the recording 
     wi.DataAvailable += new EventHandler<WaveInEventArgs>(wi_DataAvailable); 
     bwp = new BufferedWaveProvider(wi.WaveFormat); 

     bwp.BufferLength = BUFFERSIZE; //each sample is 2 bytes 
     bwp.DiscardOnBufferOverflow = true; 
     wi.StartRecording(); 
    } 

    public void UpdateFFT() 
    { 
     // read the bytes from the stream    
     byte[] buffer = new byte[BUFFERSIZE]; 
     bwp.Read(buffer, 0, BUFFERSIZE); 
     if (buffer[BUFFERSIZE - 2] == 0) return; 

     Int32[] vals = new Int32[sampleSize]; 
     Ys = new double[sampleSize]; 
     for (int i = 0; i < vals.Length; i++) 
     { 
      // bit shift the byte buffer into the right variable format 
      byte hByte = buffer[i * 2 + 1]; 
      byte lByte = buffer[i * 2 + 0]; 
      vals[i] = (short)((hByte << 8) | lByte); 
      Ys[i] = vals[i]; 
     } 

      FFT(Ys); 
    } 

Je suis encore nouveau pour le traitement audio - toute aide serait appréciée.

+0

Utilisez-vous un WriteableBitmap? – Clemens

+0

@Clemens Oui et j'ai le paquet WriteableBitmapEx installé –

Répondre

0

La cause de votre retard est la latence de WaveIn qui est d'environ 200 ms par défaut. Vous pouvez réduire cela mais au risque d'abandons.

Bien que vous puissiez capturer l'audio lu par le système avec WasapiCapture, il est impossible de le modifier avec NAudio ou de retarder sa lecture.

+0

Merci pour la réponse Mark. Je suis sûr que vous avez répondu à cela plusieurs fois, mais comment puis-je réduire la latence de WaveIn? Je ne vois aucune propriété de WaveIn qui semble faire cela. –

+0

Définissez 'BufferMilliseconds' sur une valeur inférieure –