2013-07-28 151 views
2

我想要做的是從某首歌曲中檢索頻率,並抑制所有未出現在人類聲音範圍或一般任何範圍內的頻率。這是我的抑制功能。從FFT抑制頻率

public void SupressAndWrite(Func<FrequencyUnit, bool> func) 
    { 
     this.WaveManipulated = true; 
     while (this.mainWave.WAVFile.NumSamplesRemaining > 0) 
     { 
      FrequencyUnit[] freqUnits = this.mainWave.NextFrequencyUnits(); 

      Complex[] compUnits = (from item 
            in freqUnits 
            select (func(item) 
            ? new Complex(item.Frequency, 0) :Complex.Zero))  
            .ToArray(); 

      FourierTransform.FFT(compUnits, FourierTransform.Direction.Backward); 

      short[] shorts = (from item 
           in compUnits 
           select (short)item.Real).ToArray(); 

      foreach (short item in shorts) 
      { 
       this.ManipulatedFile.AddSample16bit(item); 
      } 
     } 
     this.ManipulatedFile.Close(); 
    } 

這是我的課。

public sealed class ComplexWave 
{ 
    public readonly WAVFile WAVFile; 
    public readonly Int32 SampleSize; 

    private FourierTransform.Direction fourierDirection { get; set; } 

    private long position; 
    /// <param name="file"></param> 
    /// <param name="sampleSize in BLOCKS"></param> 
    public ComplexWave(WAVFile file, int sampleSize) 
    { 
     file.NullReferenceExceptionCheck(); 

     this.WAVFile = file; 
     this.SampleSize = sampleSize; 

     if (this.SampleSize % 8 != 0) 
     { 
      if (this.SampleSize % 16 != 0) 
      { 
       throw new ArgumentException("Sample Size"); 
      } 
     } 
     if (!MathTools.IsPowerOf2(sampleSize)) 
     { 
      throw new ArgumentException("Sample Size"); 
     } 
     this.fourierDirection = FourierTransform.Direction.Forward; 
    } 
    public Complex[] NextSampleFourierTransform() 
    { 
     short[] newInput = this.GetNextSample(); 
     Complex[] data = newInput.CopyToComplex(); 

     if (newInput.Any((x) => x != 0)) 
     { 
      Debug.Write("done"); 
     } 
     FourierTransform.FFT(data, this.fourierDirection); 

     return data; 
    } 
    public FrequencyUnit[] NextFrequencyUnits() 
    { 
     Complex[] cm = this.NextSampleFourierTransform(); 
     FrequencyUnit[] freqUn = new FrequencyUnit[(cm.Length/2)]; 
     int max = (cm.Length/2); 
     for (int i = 0; i < max; i++) 
     { 
      freqUn[i] = new FrequencyUnit(cm[i], this.WAVFile.SampleRateHz, i, cm.Length); 
     } 
     Array.Sort(freqUn); 
     return freqUn; 
    } 
    private short[] GetNextSample() 
    { 
     short[] retval = new short[this.SampleSize]; 

     for (int i = 0; i < this.SampleSize; i++) 
     { 
      if (this.WAVFile.NumSamplesRemaining > 0) 
      { 
       retval[i] = this.WAVFile.GetNextSampleAs16Bit(); 
       this.position++; 
      } 
     } 
     return retval; 
    } 
} 

FFT正向和FFT反向正常工作。你能告訴我我的錯誤是什麼。

+2

丹妮拉的答案是正確的。但是,如果您的目標是消除某些頻率而不是其他頻率,則不應使用FFT。您應該使用時域方法:http://blog.bjornroche.com/2012/08/why-eq-is-完成時間domain.html –

+0

@BjornRoche很高興我找到了你的博客,最後有人可以從中學習:) –

回答

2

不幸的是,人的聲音,即使在唱歌時,也不在「頻率範圍」。它通常具有一個主頻率和多個諧波,取決於音素。

使用此https://play.google.com/store/apps/details?id=radonsoft.net.spectralview&hl=en或一些類似的應用程序來查看我的意思 - 然後重新定義您的策略。另外谷歌'卡拉OK'的影響。

NEXT:

這不是從你的例子很明顯,但你應該掃描窗口整個文件(谷歌「FFT窗口」)來處理它的整體。

+0

對於低音和低音歌手在其音域的底部,基本音高頻率幾乎可以完全從FFT。由麥克風拾取的所有能量包括更高的泛音頻率,一些遠高於女高音範圍,取決於正在唱的元音。 – hotpaw2