##### Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries. Thanks for all your past and future contributions.

# 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);            } }`