如何延迟音频播放以与 FFT 同步
Posted
技术标签:
【中文标题】如何延迟音频播放以与 FFT 同步【英文标题】:How to delay audio playback to sync with FFT 【发布时间】:2017-10-21 05:00:48 【问题描述】:我正在使用 C# WPF 进行实时 FFT。
我正在使用 NAudio 的 WaveIn 和 BufferedWaveProvider 来捕捉 Stereo Mix 录制的任何声音。我每秒多次对缓冲区进行 FFT 并使用位图显示它,以便显示器显示通过扬声器播放的任何音频的实时傅立叶变换。
我的问题是,正如预期的那样,显示的 FFT 稍微落后于来自扬声器的音频(可能是 200 毫秒)。
有什么方法可以记录应该从扬声器播放的当前音频,以便我可以对其执行 FFT,然后在静音时稍后(例如 200 毫秒)播放它原始实时音频。
最终结果将只是有效地从显示的 FFT 中消除感知延迟。例如,当我的程序运行时,来自 youtube 视频的音频会稍微落后于视频。
以下是我目前掌握的相关方法:
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);
我还是音频处理的新手 - 任何帮助都将不胜感激。
【问题讨论】:
你在使用 WriteableBitmap 吗? @Clemens 是的,我已经安装了 WriteableBitmapEx 包 【参考方案1】:延迟的原因是WaveIn
的延迟,默认情况下约为 200 毫秒。您可以减少这种情况,但有辍学的风险。
虽然您可以使用 WasapiCapture
捕获系统正在播放的音频,但无法使用 NAudio 更改它,或延迟其播放。
【讨论】:
感谢马克的回答。我确定您已经多次回答了这个问题,但是我怎样才能减少 WaveIn 的延迟?我没有看到 WaveIn 的任何属性似乎可以做到这一点。 将BufferMilliseconds
设置为较低的值以上是关于如何延迟音频播放以与 FFT 同步的主要内容,如果未能解决你的问题,请参考以下文章