Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用matlab识别音高_Matlab_Signal Processing_Spectrogram - Fatal编程技术网

用matlab识别音高

用matlab识别音高,matlab,signal-processing,spectrogram,Matlab,Signal Processing,Spectrogram,我正试图做一个项目,在一个WAV文件,其中有一个序列的音符,它使用MATLAB读取。例如,我的WAV文件可能包含一个C-D-C-E序列。将该文件输入我的程序将打印出C-D-C-E 我尝试使用WAVREAD将文件转换为向量,然后 使用采样对其进行降采样并生成一个单通道文件。 然后我就可以得到一个在特定频率下有峰值的光谱图 从这里,我想得到关于如何使MATLAB识别峰值频率的帮助,从而使我能够打印出注释 还是我走错了路 提前谢谢 你走在正确的轨道上,但这不是一个简单的问题。我建议研究的是一种叫做ch

我正试图做一个项目,在一个WAV文件,其中有一个序列的音符,它使用MATLAB读取。例如,我的WAV文件可能包含一个C-D-C-E序列。将该文件输入我的程序将打印出C-D-C-E

我尝试使用WAVREAD将文件转换为向量,然后 使用采样对其进行降采样并生成一个单通道文件。 然后我就可以得到一个在特定频率下有峰值的光谱图

从这里,我想得到关于如何使MATLAB识别峰值频率的帮助,从而使我能够打印出注释

还是我走错了路


提前谢谢

你走在正确的轨道上,但这不是一个简单的问题。我建议研究的是一种叫做chromagram的东西。这将使用从频谱图中收集的信息,并将其转换为钢琴音符频率。这将给出歌曲和声内容的近似值。由于音符谐波中的剩余能量,这可能并不完全准确,但这只是一个开始

一定要意识到,转录,这是你正在做的,是一项非常困难的任务,尚未得到100%的解决。人们至今仍在研究这个问题。我有生成色度的代码,但我必须挖掘它

编辑

下面是一些色度代码

clc; close all; clear all;
% didn't have wav file, but simply replace this with the following
% [audio,fs] = wavread('audioFile.wav')
audio = rand(1,10000);
fs = 44100; % temp sampling frequency, will depend on audio input
NFFT = 1024; % feel free to change FFT size
hamWin = hamming(NFFT); % window your audio signal to avoid fft edge effects

% get spectral content
S = spectrogram(audio,hamWin,NFFT/2,NFFT,fs);

% Start at center lowest piano note
A0 = 27.5;
% all 88 keys
keys = 0:87;
center = A0*2.^((keys)/12); % set filter center frequencies
left = A0*2.^((keys-1)/12); % define left frequency
left = (left+center)/2.0;
right = A0*2.^((keys+1)/12); % define right frequency
right = (right+center)/2;

% Construct a filter bank
filter = zeros(numel(center),NFFT/2+1); % place holder
freqs = linspace(0,fs/2,NFFT/2+1); % array of frequencies in spectrogram
for i = 1:numel(center)
    xTemp = [0,left(i),center(i),right(i),fs/2]; % create points for filter bounds
    yTemp = [0,0,1,0,0]; % set magnitudes at each filter point
    filter(i,:) = interp1(xTemp,yTemp,freqs); % use interpolation to get values for   frequencies
end

% multiply filter by spectrogram to get chroma values.
chroma = filter*abs(S);

%Put into 12 bin chroma
chroma12 = zeros(12,size(chroma,2));
for i = 1:size(chroma,1)
    bin = mod(i,12)+1; % get modded index
    chroma12(bin,:) = chroma12(bin,:) + chroma(i,:); % add octaves together
end
这应该能奏效。这可能不是最快的解决方案,但它应该能够完成任务


当然,它是可以优化的

你走在正确的轨道上,但这不是一个简单的问题。我建议研究的是一种叫做chromagram的东西。这将使用从频谱图中收集的信息,并将其转换为钢琴音符频率。这将给出歌曲和声内容的近似值。由于音符谐波中的剩余能量,这可能并不完全准确,但这只是一个开始

一定要意识到,转录,这是你正在做的,是一项非常困难的任务,尚未得到100%的解决。人们至今仍在研究这个问题。我有生成色度的代码,但我必须挖掘它

编辑

下面是一些色度代码

clc; close all; clear all;
% didn't have wav file, but simply replace this with the following
% [audio,fs] = wavread('audioFile.wav')
audio = rand(1,10000);
fs = 44100; % temp sampling frequency, will depend on audio input
NFFT = 1024; % feel free to change FFT size
hamWin = hamming(NFFT); % window your audio signal to avoid fft edge effects

% get spectral content
S = spectrogram(audio,hamWin,NFFT/2,NFFT,fs);

% Start at center lowest piano note
A0 = 27.5;
% all 88 keys
keys = 0:87;
center = A0*2.^((keys)/12); % set filter center frequencies
left = A0*2.^((keys-1)/12); % define left frequency
left = (left+center)/2.0;
right = A0*2.^((keys+1)/12); % define right frequency
right = (right+center)/2;

% Construct a filter bank
filter = zeros(numel(center),NFFT/2+1); % place holder
freqs = linspace(0,fs/2,NFFT/2+1); % array of frequencies in spectrogram
for i = 1:numel(center)
    xTemp = [0,left(i),center(i),right(i),fs/2]; % create points for filter bounds
    yTemp = [0,0,1,0,0]; % set magnitudes at each filter point
    filter(i,:) = interp1(xTemp,yTemp,freqs); % use interpolation to get values for   frequencies
end

% multiply filter by spectrogram to get chroma values.
chroma = filter*abs(S);

%Put into 12 bin chroma
chroma12 = zeros(12,size(chroma,2));
for i = 1:size(chroma,1)
    bin = mod(i,12)+1; % get modded index
    chroma12(bin,:) = chroma12(bin,:) + chroma(i,:); % add octaves together
end
这应该能奏效。这可能不是最快的解决方案,但它应该能够完成任务


当然,它是可以优化的

这是一个非常复杂的问题。峰间测量可能会成功,但如果音乐变得更加复杂,肯定不会成功。我以前解决过这个问题,也见过其他人尝试过,我见过的同行中最成功的项目包括:

1.限制时间。对于一个程序来说,可能很难确定一个音符什么时候在变化!如果您试图将人声与乐器分开,或者例如当两个和弦连续演奏时,但它们之间有一个音符保持不变,则这一点尤其正确。因此,通过限制时间,它意味着找出每段音乐的发生时间,因此在您的例子中,将曲目分为四个曲目,每个音符一个。您可能能够利用每个音符的攻击优势,将攻击自动检测为要测试的新片段的开始

2.限制频率。你必须使用你所知道的,否则你将需要进行本征模比较。奇异值分解在这个领域是有效的。但是如果你让钢琴分别演奏不同的音符,并且你有钢琴演奏歌曲的录音,你可以做的是对每个片段进行快速傅立叶变换,看看上面的时间限制,去掉噪音,然后比较它们。然后使用减法或其他度量来确定每个音符的最佳匹配


这是对担忧的粗略解释,但相信我,对这种分析施加的约束越多越好

这是一个非常复杂的问题。峰间测量可能会成功,但如果音乐变得更加复杂,肯定不会成功。我以前解决过这个问题,也见过其他人尝试过,我见过的同行中最成功的项目包括:

1.限制时间。对于一个程序来说,可能很难确定一个音符什么时候在变化!如果您试图将人声与乐器分开,或者例如当两个和弦连续演奏时,但它们之间有一个音符保持不变,则这一点尤其正确。因此,通过限制时间,它意味着找出每段音乐的发生时间,因此在您的例子中,将曲目分为四个曲目,每个音符一个。您可能能够利用每个音符的攻击优势,将攻击自动检测为要测试的新片段的开始

2.限制频率。你必须使用你所知道的,否则你将需要进行本征模比较。奇异值de 在这个舞台上,构图是有效的。但是如果你让钢琴分别演奏不同的音符,并且你有钢琴演奏歌曲的录音,你可以做的是对每个片段进行快速傅立叶变换,看看上面的时间限制,去掉噪音,然后比较它们。然后使用减法或其他度量来确定每个音符的最佳匹配


这是对担忧的粗略解释,但相信我,对这种分析施加的约束越多越好

谢谢大家!!我会查一下chromagram是什么。但是,有没有办法正确访问生成的光谱图中的数据呢?是的,S=spectrogramx,window,noverlap,nfft,FSF这似乎是一个值得赏金的答案!请注意,这是我在大学时研究的一个主题:@MZimmerman6嗨,我一直在读你的答案,但我在代码中迷失了方向。你如何选择NFFT?是否有一些规则?。他告诉你什么?在你开始构建过滤器之后,我就迷路了。你能不能再详细一点?谢谢!我会查一下chromagram是什么。但是,有没有办法正确访问生成的光谱图中的数据呢?是的,S=spectrogramx,window,noverlap,nfft,FSF这似乎是一个值得赏金的答案!请注意,这是我在大学时研究的一个主题:@MZimmerman6嗨,我一直在读你的答案,但我在代码中迷失了方向。你如何选择NFFT?是否有一些规则?。他告诉你什么?在你开始构建过滤器之后,我就迷路了。你能不能再详细一点?是的,我肯定需要这些限制,因为这是我的第一个项目。非常感谢。是的,我肯定需要这些约束,因为这是我的第一个项目。非常感谢。