Signal processing 乐谱的音频分析

Signal processing 乐谱的音频分析,signal-processing,fft,audio-analysis,Signal Processing,Fft,Audio Analysis,我目前正在开发一个程序,分析一个演奏乐器的独奏音乐家的wav文件,并检测其中的音符。为此,它执行FFT,然后查看生成的数据。目标是(在某些时候)通过编写midi文件来生成乐谱 我只是想得到一些关于它有什么困难的意见,是否有人曾经尝试过,也许有一些事情值得研究。目前我最大的困难是不是所有的音符都是一个频率,我还不能检测到和弦;只有一个音符。同时,在我检测到的音符之间必须有一个停顿,这样我才能确定一个音符已经结束,另一个音符已经开始。欢迎对此发表任何评论 这是我从信号中输入新帧时使用的代码。它查找样

我目前正在开发一个程序,分析一个演奏乐器的独奏音乐家的wav文件,并检测其中的音符。为此,它执行FFT,然后查看生成的数据。目标是(在某些时候)通过编写midi文件来生成乐谱


我只是想得到一些关于它有什么困难的意见,是否有人曾经尝试过,也许有一些事情值得研究。目前我最大的困难是不是所有的音符都是一个频率,我还不能检测到和弦;只有一个音符。同时,在我检测到的音符之间必须有一个停顿,这样我才能确定一个音符已经结束,另一个音符已经开始。欢迎对此发表任何评论

这是我从信号中输入新帧时使用的代码。它查找样本中最主要的频率:

    //Get frequency vector for power match
        double[] frequencyVectorDoubleArray = Accord.Audio.Tools.GetFrequencyVector(waveSignal.Length, waveSignal.SampleRate);

        powerSpectrumDoubleArray[0] = 0; // zero DC

        double[,] frequencyPowerDoubleArray = new double[powerSpectrumDoubleArray.Length, 2];

        for (int i = 0; i < powerSpectrumDoubleArray.Length; i++)
        {
            if (frequencyVectorDoubleArray[i] > 15.00)
            {
                frequencyPowerDoubleArray[i, 0] = frequencyVectorDoubleArray[i];
                frequencyPowerDoubleArray[i, 1] = powerSpectrumDoubleArray[i];
            }
        }

    //Method for finding the highest frequency in a sample of frequency domain data
        //But I want to filter out stuff
        pulsePowerDouble = lowestPowerAcceptedDouble;//0;//lowestPowerAccepted;
        int frequencyIndexAtPulseInt = 0;
        int oldFrequencyIndexAtPulse = 0;
        for (int j = 0; j < frequencyPowerDoubleArray.Length / 2; j++)
        {
            if (frequencyPowerDoubleArray[j, 1] > pulsePowerDouble)
            {
                oldPulsePowerDouble = pulsePowerDouble;
                pulsePowerDouble = frequencyPowerDoubleArray[j, 1];

                oldFrequencyIndexAtPulse = frequencyIndexAtPulseInt;
                frequencyIndexAtPulseInt = j;
            }
        }
        foundFreq = frequencyPowerDoubleArray[frequencyIndexAtPulseInt, 0];
//获取功率匹配的频率向量
double[]FrequencyVector DoubleArray=Accord.Audio.Tools.GetFrequencyVector(waveSignal.Length,waveSignal.SampleRate);
powerSpectrumDoubleArray[0]=0;//零直流
double[,]frequencyPowerDoubleArray=新的双精度[powerSpectrumDoubleArray.Length,2];
对于(int i=0;i15.00)
{
frequencyPowerDoubleArray[i,0]=频率矢量双阵列[i];
频率功率双阵列[i,1]=功率谱双阵列[i];
}
}
//在频域数据样本中查找最高频率的方法
//但我想过滤掉一些东西
pulsePowerDouble=最低功率接受倍频//0;//低功率接受;
int frequencyIndexaxitpulseint=0;
int oldFrequencyIndexAtPulse=0;
对于(int j=0;j脉冲功率双列)
{
oldPulsePowerDouble=pulsePowerDouble;
脉冲功率双倍=频率功率双倍阵列[j,1];
oldFrequencyIndexAtPulse=频率指数脉冲;
频率指数Pulseint=j;
}
}
foundFreq=频率功率双阵列[频率指数脉冲,0];

您不希望关注最高频率,而是关注最低频率。任何乐器的每个音符都充满了和声。期待听到基本音,以及上面的每一个八度音。加上所有的二次和三次谐波


当小号和长号演奏同一个音符时,和声使小号的声音不同于长号。

你不想把重点放在最高频率上,而是放在最低频率上。任何乐器的每个音符都充满了和声。期待听到基本音,以及上面的每一个八度音。加上所有的二次和三次谐波

当喇叭和长号演奏同一个音符时,谐波使喇叭的声音不同于长号。

1)关于频率估计和音高估计(这是两个不同的主题)有很多(几十年的研究文献

2) 峰值FFT频率与音高不同。一些独奏乐器只需一个音符就可以产生十几个频率峰值,更不用说和弦了,而且在音高附近没有任何最大的峰值。对于一些普通仪器,峰值甚至可能不是数学上精确的谐波

3) 使用一个短的无限制FFT的峰值仓不是一个很好的频率估计器

4) 注意:根据仪器的不同,开始检测可能需要一些复杂的模式匹配。

1)关于频率估计和基音估计(这是两个不同的主题)有很多研究文献(几十年的价值)

2) 峰值FFT频率与音高不同。一些独奏乐器只需一个音符就可以产生十几个频率峰值,更不用说和弦了,而且在音高附近没有任何最大的峰值。对于一些普通仪器,峰值甚至可能不是数学上精确的谐波

3) 使用一个短的无限制FFT的峰值仓不是一个很好的频率估计器


4) 注:开始检测可能需要一些复杂的模式匹配,具体取决于仪器。

不幸的是,这是一个极其困难的问题,已经给出了一些原因。我会从“音符识别”的文献搜索(比如谷歌学者)开始


如果这不是一个业余项目,请注意——我曾看到大师论文的创始人在这个特殊的浅滩上,但没有得到任何有用的结果。

不幸的是,这是一个极其困难的问题,一些原因已经给出。我会从“音符识别”的文献搜索(比如谷歌学者)开始


如果这不是一个业余项目,请注意——我在这个特殊的浅滩上见过大师论文的创始人,但没有得到任何有用的结果。

你有什么代码可以给我们看吗?请看“并非所有音符都是纯一个频率”:可能几乎没有一个普通乐器的音符是纯一个频率。顺便说一句,纯正弦波对人耳听起来很烦人,因此在音乐中相当罕见。@Curd-好的一点,我没有想到它是正弦波和音符波。你有什么代码可以给我们看吗?请看“并非所有音符都是纯一个频率”:可能几乎没有一个普通乐器的音符是纯一个频率。顺便说一句,纯正弦波听起来很烦人,因此在音乐中很少见。@Curd-很好的一点,我没有想到它是正弦波还是音符波。请记住,基本音经常会丢失()。是的,上面的代码只取样本中声音最大的。后来我