加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 将WAV文件转换为频谱图

发布时间:2020-12-16 01:55:32 所属栏目:百科 来源:网络整理
导读:嗨,我对这件事很新,所以请耐心等待.我正在尝试将WAV文件转换为频谱图但不确定如何开始.我读了一些关于读取PCM数据(我认为是我的WAV文件)并将其存储在WavReader类中的数组中的内容,然后对其应用FFT并将其转换为GUI.我目前正在使用Naudio来实现这一点,但找不到
嗨,我对这件事很新,所以请耐心等待.我正在尝试将WAV文件转换为频谱图但不确定如何开始.我读了一些关于读取PCM数据(我认为是我的WAV文件)并将其存储在WavReader类中的数组中的内容,然后对其应用FFT并将其转换为GUI.我目前正在使用Naudio来实现这一点,但找不到任何显示如何将WAV文件转换为频谱图的内容.谢谢

编辑:
我发现有关使用Naudio将PCM转换为FFT并且我卡住了.

using (var reader = new AudioFileReader("test1.wav"))
        {
          // test1.wav is my file to process
          // test0.wav is my temp file

            IWaveProvider stream16 = new WaveFloatTo16Provider(reader);
            using (WaveFileWriter converted = new WaveFileWriter("test0.wav",stream16.WaveFormat))
            {
                // buffer length needs to be a power of 2 for FFT to work nicely
                // however,make the buffer too long and pitches aren't detected fast enough
                // successful buffer sizes: 8192,4096,2048,1024
                // (some pitch detection algorithms need at least 2048)
                byte[] buffer = new byte[8192];
                int bytesRead;
                do
                {
                    bytesRead = stream16.Read(buffer,buffer.Length);
                    converted.WriteData(buffer,bytesRead);
                } while (bytesRead != 0 && converted.Length < reader.Length);
            }
        }

编辑:我还想知道是否有可能以编程方式比较2个不同文件的2个谱图.

解决方法

您还可以使用 BASS.NET库本机提供所有这些功能,并且是免费的.

Visuals.CreateSpectrum3DVoicePrint Method确实如此.

如果您在使用它时遇到困难,请随时寻求帮助.

编辑:这是一个快速而肮脏的样本

public partial class Form1 : Form
{
    private int _handle;
    private int _pos;
    private BASSTimer _timer;
    private Visuals _visuals;

    public Form1()
    {
        InitializeComponent();
    }

    private void timer_Tick(object sender,EventArgs e)
    {
        bool spectrum3DVoicePrint = _visuals.CreateSpectrum3DVoicePrint(_handle,pictureBox1.CreateGraphics(),pictureBox1.Bounds,Color.Cyan,Color.Green,_pos,false,true);
        _pos++;
        if (_pos >= pictureBox1.Width)
        {
            _pos = 0;
        }
    }

    private void Form1_Load(object sender,EventArgs e)
    {
        string file = "....mysong.mp3";
        if (Bass.BASS_Init(-1,44100,BASSInit.BASS_DEVICE_DEFAULT,Handle))
        {
            _handle = Bass.BASS_StreamCreateFile(file,BASSFlag.BASS_DEFAULT);

            if (Bass.BASS_ChannelPlay(_handle,false))
            {
                _visuals = new Visuals();
                _timer = new BASSTimer((int) (1.0d/10*1000));
                _timer.Tick += timer_Tick;
                _timer.Start();
            }
        }
    }
}

编辑2

您可以提供文件名,但您也可以使用接受IntPtr的其他重载或使用带Bass.BASS_StreamPutData的Bass.BASS_StreamCreatePush提供您自己的音频数据.

关于比较光谱图,您可以执行以下操作:

>将图像调整为更小的尺寸,通过将图像抖动到8位来减少信息(但是使用了一个好的算法)
>比较两个图像

然而,为了比较音频数据我强烈建议你使用指纹,它大致这样做,但比我的建议更健壮.

这是一个可以免费使用的指纹库:

http://www.codeproject.com/Articles/206507/Duplicates-detector-via-audio-fingerprinting

但不完全确定它适用于小样本.

编辑3

我恐怕找不到我读过的链接,但这就是他们所做的:减少数据和比较图像,例如下面的例子(最后一张图片):

(注意:不要与图像1进行比较,它只是为了说明为什么使用较低的分辨率可能会提供更好的产量)

(自http://blog.echonest.com/post/545323349/the-echo-nest-musical-fingerprint-enmfp起)

现在对该过程进行了非常基本的解释:

比较来源A:

比较源B :(我刚刚更改了A的区域)

比较结果:

(通过将以前的图像添加为图层并将第二层混合设置为差异而不是正常而使用Paint.Net完成)

如果指纹相同,则得到的图像将是完全黑色的.

通过将数据减少为8位图像,您可以简化比较过程,但请记住,您需要一个良好的抖动算法.

这是一个很好的:

http://www.codeproject.com/Articles/66341/A-Simple-Yet-Quite-Powerful-Palette-Quantizer-in-C

好吧,它与Photoshop或Hypersnap不同(IMO是例外),但这可能足以完成任务.

并且不惜一切代价避免Floyd–Steinberg dithering或者做错误扩散的事情.

这里有一些尝试创建抖动算法:http://bisqwit.iki.fi/story/howto/dither/jy/

谨慎对待,因为我不是该领域的专家,但这大致是如何完成的.

转到https://dsp.stackexchange.com/,在那里问几个问题,你可能会得到有用的提示.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读