##### Actions

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

# Windows Phone音频降噪

WS - OtomiiLu

Windows Phone音频降噪 本文说明了运用Windows Phone快速傅里叶变换算法来进行音频降噪的一种方法。

## 在 Windows Phone中使用FFT

`using FFT;`

### Compute()

`void Compute(UInt32 NumSamples, Double[] pRealIn, Double[] pImagIn, Double[] pRealOut, Double[] pImagOut, Boolean bInverseTransform);`

NumSamples 样本数量 (必须是2的n次方) pRealIn 真正的原始数据样本输入 pImagIn 虚系数输入(选填，可为空), 当计算傅里叶逆变换时，须填写此参数 pRealOut 实系数输出 pImagOut 虚系数输出 bInverseTransform 当bInverseTransform为true时, 计算快速傅里叶逆变换。

### 切割频段

`private double[] fingerprint;`

`DispatcherTimer dtFingerprint;  // Timer to detect fingerprintdtFingerprint = new DispatcherTimer();dtFingerprint.Interval = TimeSpan.FromMilliseconds(4000);dtFingerprint.Tick += new EventHandler(stopFingerprintDetection); private void stopFingerprintDetection(object sender, EventArgs e){            dtFingerprint.Stop();            microphone.Stop();             MessageBar.Text = "Noise fingerprint computed.";             SetButtonStates(false, false, true);             microphone.Start();             UserHelp.Text = "Record";            StatusImage.Source = microphoneImage;}`

DispacherTimer 被包含在 System.Windows.Threadin命名空间下。 在我的 .xaml 中，我加入了一个复选框，来开启/关闭录音降噪。

`<CheckBox Content="Noise Reduction" Name="cb_noise_reduction" ... />当录音按钮被按下时我们分配“指纹”数组，并开启监测计时器。 <code csharp>private void recordButton_Click(object sender, EventArgs e){            // Get audio data in 1/2 second chunks            microphone.BufferDuration = TimeSpan.FromMilliseconds(100);             // Allocate memory to hold the audio data            buffer = new byte[microphone.GetSampleSizeInBytes(microphone.BufferDuration)];             // Allocate memory to hold the audio data            fingerprint = new double[ FFT.FourierTransform.NextPowerOfTwo((uint) microphone.GetSampleSizeInBytes(microphone.BufferDuration))];             // Set the stream back to zero in case there is already something in it            stream.SetLength(0);             WriteWavHeader(stream, microphone.SampleRate); // To save in .WAV format             if ((bool)cb_noise_reduction.IsChecked)            {                dtFingerprint.Start(); // Start the noise finger print detection            }            else            {                SetButtonStates(false, false, true);                UserHelp.Text = "Record";                StatusImage.Source = microphoneImage;            }             // Start recording            microphone.Start(); }`

`private double cutoff = 0; void microphone_BufferReady(object sender, EventArgs e) {            // Retrieve audio data            microphone.GetData(buffer);             int index = 0;             double[] sampleBuffer = new double[FFT.FourierTransform.NextPowerOfTwo((uint)buffer.Length)];             for (int i = 0; i < buffer.Length; i += 2)            {                sampleBuffer[index] = Convert.ToDouble(BitConverter.ToInt16((byte[])buffer, i)); index++;            }             if (dtFingerprint.IsEnabled)            {                                MessageBar.Text = "Computing noise fingerprint";                 double[] xre = new double[sampleBuffer.Length]; // Real part                double[] xim = new double[sampleBuffer.Length]; // Immaginary part                 FFT.FourierTransform.Compute((uint)sampleBuffer.Length, sampleBuffer, null, xre, xim, false);                 double spectrum = 0;                 for (int i = 0; i < xre.Length; i++)                {                    spectrum = (float)(Math.Sqrt((xre[i] * xre[i]) + (xim[i] * xim[i]))); // Magnitude                    if (spectrum > fingerprint[i])                    {                        fingerprint[i] = spectrum;                                            }                }                            }            else            {                                MessageBar.Text = "Recording....";                 double cMagnitude = 0;                // double cPhase     = 0;                 double[] xre = new double[sampleBuffer.Length]; // Real part                double[] xim = new double[sampleBuffer.Length]; // Immaginary part                 double[] ixre = new double[sampleBuffer.Length]; // Real part                double[] ixim = new double[sampleBuffer.Length]; // Immaginary part                 double[] fftoutput = new double[sampleBuffer.Length];                byte[] output = new byte[buffer.Length];                 FFT.FourierTransform.Compute((uint)sampleBuffer.Length, sampleBuffer, null, xre, xim, false);                 for (int i = 0; i < xre.Length; i++)                {                      cMagnitude = (float)(Math.Sqrt((xre[i] * xre[i]) + (xim[i] * xim[i]))); // Magnitude                     if (cMagnitude < (fingerprint[i] ))                    {                        xre[i] *= cutoff;  xre[(xre.Length - 1) - i] *= cutoff;                                               xim[i] *= cutoff;  xim[(xre.Length - 1) - i] *= cutoff;                    }                                    }                 FFT.FourierTransform.Compute((uint)xre.Length, xre, xim, ixre, ixim, true);                 index = 0;                short tmp = 0;                 for (int i = 0; i < buffer.Length / 2; i++)                {                    tmp = (short)ixre[i];                                        output[index] = (byte)((short)tmp & 255); output[index + 1] = (byte)((((short)tmp) >> 8) & 255);                    index += 2;                }                 // Store the audio data in a stream                //stream.Write(buffer, 0, buffer.Length);                stream.Write(output, 0, output.Length);            } }`