2013-07-24 2 views
1

MATLAB을 사용하여 음악 노트가 들어있는 WAV 파일을 읽는 프로젝트를 수행하려고합니다. 예를 들어, 내 WAV 파일에 C-D-C-E 시퀀스가 ​​포함될 수 있습니다. 그리고이 파일을 내 프로그램에 넣으면 "C D C E."가 출력됩니다.matlab을 사용하여 사운드의 음높이를 인식합니다.

WAVREAD를 사용하여 파일을 벡터로 바꾼 다음 을 샘플링하여이를 다운 샘플링하여 하나의 채널 파일로 만들려고했습니다. 그런 다음 특정 주파수에서 "봉우리"가있는 스펙트로 그램을 만들 수있었습니다.

여기에서 MATLAB이 봉우리의 주파수를 인식하도록 만드는 방법에 대한 도움을 받으므로 메모를 인쇄 할 수 있습니다.

아니면 잘못된 추적을하고 있습니까?

미리 감사드립니다.

답변

3

올바른 트랙에 있지만 간단한 문제는 아닙니다. 내가 조사 할 것을 제안하는 것은 크로마그램이라고하는 것입니다. 이것은 스펙트로 그램에서 수집 한 정보를 사용하여 피아노 음표 주파수로 "bin"합니다. 이것은 노래 고조파 콘텐츠의 근사치를 제공합니다. 이는 노트의 고조파에 잔여 에너지가 있기 때문에 완전히 정확하지 않을 수도 있지만 시작일뿐입니다.

당신이하고있는 전사가 매우 어려운 작업이며 아직 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 

을 크로마 몇 가지 코드입니다. 가장 빠른 해결책은 아니지만 업무를 완료해야합니다.

확실하게 최적화 할 수 있습니다.

+0

감사합니다. 나는 chromagram이 무엇인지 찾아 볼 것입니다. 그러나 생성 된 스펙트로 그램의 데이터에 올바르게 액세스 할 수 있습니까? – Diletante

+0

예'S = 스펙트로 그램 (x, 창, noverlap, nfft, fs)' – MZimmerman6

+0

굉장! 나는 당신의 코드를 확실히 시도 할 것이다. 감사합니다. – Diletante

3

MZimmerman6과 마찬가지로 이것은 매우 복잡한 문제입니다. 피크 대 피크 측정은 성공할 수 있지만, 음악이 더 이상 복잡 해지 지 않는지는 확실합니다. 나는이 문제를 전에 풀어 봤고 다른 사람들도 시도해 보았다. 내가 본 동료 중 가장 성공적인 프로젝트는 다음과 같다.

1) 시간 제한. 메모가 바뀌는시기를 프로그램이 결정하는 것은 실제로 어려울 수 있습니다! 보컬을 악기에서 분리하려는 경우 또는 두 개의 코드가 순차적으로 재생되는 경우와 같이 두 코드가 동일하게 유지되는 경우에는 특히 그렇습니다. 따라서 각 음악 청크가 발생할 때마다 알아 내야 할 시간을 제한하십시오. 따라서 귀하의 경우에는 트랙을 네 개의 트랙으로 나눕니다 (각 음표마다 하나씩). 각 노트의 공격을 사용하여 테스트 할 새 세그먼트의 시작으로 공격을 자동으로 탐지 할 수 있습니다.

2) 주파수를 제한하십시오. 알고있는 것을 사용해야합니다. 그렇지 않으면 고유 모드 비교를해야합니다. 특이한 가치 분해가이 분야에서 효과적이었다. 그러나 피아노가 개별적으로 음표를 연주하고 피아노를 녹음하여 연주하면 각 세그먼트의 고속 푸리에 변환 (위의 시간 제한 참조), 노이즈 제거 및 그들을 비교하십시오. 그런 다음 빼기 방법이나 다른 메트릭을 사용하여 각 노트에 가장 적합한 "적합"을 결정합니다.

위의 내용은 대략적인 설명이지만이 종류의 분석에 더 많은 제약 조건을두면 좋을 것 같습니다.

+0

그래,이게 내 첫번째 프로젝트이기 때문에 분명히이 제약 조건이 필요해. 고맙습니다! – Diletante

관련 문제