2017-12-30 9 views
0

노래의 특정 시간에 어떤 주파수 (음표)가 연주되는지 파악하는 코드를 작성하고 있습니다 (현재 I 노래의 첫 번째 초만 붙잡는 것을 시험하고있다). 이를 위해 오디오 파일의 첫 번째 부분을 8 개의 다른 청크로 나눕니다. 그럼 각 청크에 FFT를 수행하고 다음과 같은 코드로 플롯 : 나는 너무 음모를 꾸미고 있어요처럼 enter image description here enter image description hereFFT : fs/2 샘플 미만인 경우 단일면 스펙트럼을 찾는 방법

것 같습니다 : 나는 다음과 같이 그래프를 얻을 수행 할 때

% Taking a second of an audio file and breaking it into n many chunks and 
% figuring out what frequencies make up each of those chunks 
clear all; 

% Read Audio 
fs = 44100;   % sample frequency (Hz) 
full = audioread('song.wav'); 

% Perform fft and get frequencies 
chunks = 8;   % How many chunks to break wave into 
for i = 1:chunks 
    beginningChunk = (i-1)*fs/chunks+1 
    endChunk = i*fs/chunks 
    x = full(beginningChunk:endChunk); 
    y = fft(x); 
    n = length(x);  % number of samples in chunk 
    amp = abs(y)/n; % amplitude of the DFT 
    %%%amp = amp(1:fs/2/chunks); % note this is my attempt that I think is wrong 
    f = (0:n-1)*(fs/n);  % frequency range 
    %%%f = f(1:fs/2/chunks); % note this is my attempt that I think is wrong 

    figure(i); 
    plot(f,amp) 
    xlabel('Frequency') 
    ylabel('amplitude') 
end 

많은 점은 그래프의 오른쪽 끝에 주파수가 올라가서 양면 스펙트럼을 사용하고 있다고 생각하기 때문입니다. 나는 1 : fs/2의 샘플만을 사용해야한다고 생각하는데, 문제는 많은 포인트를 얻기에 충분히 큰 행렬이 없다는 것입니다. 나는 1 : fs/2/chunks에서 시도해 보았지만, 나는 그 값이 맞는지 확신 할 수 없으므로 그 값을 주석으로 처리했다. fs/2 샘플 미만일 때 어떻게하면 단일 단면 스펙트럼을 찾을 수 있습니까?

모든 그래프를 그릴 때 주어진 주파수는 거의 똑같습니다. 이것은 놀라운 것이 었습니다. 왜냐하면 정확한 시간에 발생하는 빈도 만 가져와야하기 때문에 청크를 작게 만들어야한다고 생각했기 때문입니다. 따라서 현재 연주중인 음을 연주하게 될 것입니다. 어떤 사람이 각 시간에 어떤 음표가 연주되는지 더 잘 알면 그 정보가 크게 감사 할 것입니다.

+0

[중복 가능합니까?] [이 질문에 답변] (https://stackoverflow.com/q/4364823/253056)을 참조하십시오. –

답변

1

단면 FT의 경우 FFT 알고리즘의 출력의 처음 절반 만 가져 가면됩니다. 나머지 절반 (nagative 주파수)은 입력 값이 실수로 주어지면 중복됩니다.

1/8 초는 상당히 길다. 내가 정확히 기억한다면 음악은 내 전문이 아니므로 관련 주파수는 약 160-1600 Hz입니다. 그것들은 FT의 가장 왼쪽 영역에있을 것입니다. 계산 한 최고 주파수 (FFT의 오른쪽 절반을 떨어 뜨린 후)는 샘플링 주파수의 절반 인 44.1/2kHz입니다. 가장 낮은 주파수와 샘플 간의 거리는 변환의 길이 (44.1 kHz/샘플 수)로 표시됩니다.

+0

문제가 해결되었습니다. 나는 그것이 최고 주파수의 두 배이기 때문에 청크를 3200으로 바꿨습니다. 모든 그래프는 그래프의 왼쪽이 높고 그래프의 오른쪽이 낮아서 (1/x의 그래프와 같이) 추세를 따르는 것으로 나타났습니다. [https://imgur.com/a/ u2K9M] (이와 같이). 나는 항상 이런 식으로 보이는 그래프가있는 이유가 있다면 궁금했다. 그것은 어떤 주파수가 연주되고 있는지 꺼내기가 어렵습니다. –

+0

첫 번째 빈은 f = 0에서 일반적으로 가장 높고 신호의 평균을 인코딩합니다. 그림에서 당신은> 3000 Hz의 주파수 스텝을 가지고 있습니다. 즉, 관련 빈도에서 값을 읽을 수 없습니다. 다음 반 음표와 중간 음표를 구분하려면 주파수 단계 크기가 최대 16 Hz가되도록 청크의 크기를 조정해야합니다 (https://en.m.wikipedia.org/wiki/). Piano_key_frequencies). 주파수 스펙트럼에서 보간 할 수는 없으므로 관심있는 각 주파수를 충분히 밀도있게 샘플링해야합니다. –

+0

16hZ는 한 번에 개별 메모를 선택하기에는 너무 빠릅니다. 청크 크기/Hz와 같은 변수를 조정하는 것만으로 개별 노트를 격리 할 수 ​​있습니까, 아니면 다른 알고리즘을 사용해야합니까? 나는 처음 발견을 들여다 보았다. 유용 할 수 있다고 생각했지만, 그것을 사용해야 할 지, 아니면 더 나은 알고리즘이 필요한지 나는 모른다. –

관련 문제