c# - 抑制 FFT 中的频率

标签 c# .net audio 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();
    }

这是我的 Wave 类(class)。

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 后向都可以正常工作。你能告诉我我的错误是什么吗?

最佳答案

不幸的是,人声,即使在唱歌时,也不在“频率范围”内。它通常有一个主频率和随后的多个谐波,具体取决于音素。

使用这个https://play.google.com/store/apps/details?id=radonsoft.net.spectralview&hl=en或一些类似的应用程序来看看我的意思 - 然后重新定义你的策略。还有谷歌“卡拉 OK”效果。

下一步:

从您的示例中并不明显,但您应该在 Windows 中扫描整个文件(google 'fft windowing')来处理整个文件。

关于c# - 抑制 FFT 中的频率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17912397/

相关文章:

audio - 在 Ogg/Opus 上寻找

audio - 单声道音频阅读库

c# - 界面内的事件是什么意思?

.net - 如何从 MemoryStream 中获取字符串?

c# - Select 不适用于 IQueryable 但适用于 IList

c# - 如何在隐藏时调用对象方法

c# - 如何在一个 IEnumerable 上同时运行两种方法

c# - 将依赖注入(inject)应用于抽象类 c# 的不同实现

c# - 如何将 .Net Core Web Api 从 VS Code 发布到 Azure?

html - 声音源到听众的距离是否会影响它们在WebAudio API中的播放时间?