현재 FMOD 오디오 라이브러리의 getSpectrum
기능을 재현하려고합니다. 이 함수는 현재 재생중인 버퍼의 PCM 데이터를 읽고,이 데이터에 창을 적용하고 스펙트럼을 얻기 위해 FFT를 적용합니다.FFT - PCM 데이터에 창 적용
각 플로트가 0과 1 dB (10.0f * (float)log10(val) * 2.0f
) 사이에있는 float 배열을 반환합니다. 나는이 문서에 따르면, 4096 바이트 버퍼에 PCM 데이터를 얻을
첫째, PCM 데이터입니다 : 내가하는 일의 확실하지 않다
내가 그렇게해야 내가 그것을 설명 할 것입니다 왼쪽과 오른쪽 쌍의 데이터 인 샘플로 구성됩니다. 내 경우
나는 위의 이미지처럼 16 비트 샘플 함께 일하고 있어요. 나는 왼쪽 채널에서만 작동 싶다면, 내가하고 짧은 배열의 왼쪽 PCM 데이터를 저장 : 샘플은 = 4 바이트 경우
가short *data = malloc(4096);
FMOD_Sound_ReadData(sound, (void *)data, 4096, &read);
그래서, 내가 가진 1024 개 샘플은 왼쪽을 나타내는 1024 반바지 즉, 오른쪽 채널을 나타내는 1024 개의 반바지.
가 FFT를 수행하기 위해, I는 float 배열을 가지고 내 데이터의 창 (해닝)를 적용해야 i
배열에서의 위치이며, 상기 입력은
float hanningWindow(short in, size_t i, size_t s)
{
return in*0.5f*(1.0f-cos(2.0f*M_PI*(float)(i)/(float)(s-1.0f)));
}
휴 in
및 배열의 크기 (1024)는 s
입니다.
는 왼쪽 채널을 효율적으로 활용하려면 다음
float *input = malloc(1024*sizeof(float));
for (i = 0; i < 1024; i++)
input[i] = hanningWindow(data[i*2], i, 1024);
가 그럼 난 (실제의 복잡한) kiss_fft하기 위해 FFT의 감사를 수행합니다. dB에서
kiss_fft_cpx c = output[i];
float amp = sqrt(c.r*c.r + c.i*c.i);
계산 :
amp = 10.0f * (float)log10(amp) * 2.0f;
I 1024/2 + 1 = 513
I는 각 주파수의 진폭을 계산 크기의 kiss_fft_cpx *ouput
(복소 배열)를 얻을 amp
은 0과 1 사이에 있지 않습니다. PCM 데이터 또는 끝 부분에서 데이터를 정규화해야하는 곳을 알지 못합니다. 또한 나는 PCM 데이터에 내 윈도우를 적용하는 방법을 잘 모르겠습니다.
여기 getSpectrum 함수의 결과에 비해 0에서 20kHz까지의 노래에서 얻은 결과가 있습니다. (A 직사각형 창에 대한)
My Result getSpectrum Result
어떻게 동일한 결과를 얻을 수 있습니까?
, 당신이 정말로 각각의 삼각에서 그들을 계산보다는에서 Hann의 윈도우 계수를 저장한다 시각. –
sqrt를 사용할 필요가 없습니다. 참고로, 20 * log10 (sqrt (x)) == 10 * log10 (x) –