generowanie poprawnego spektrogramu za pomocą funkcji fftw i okna

W przypadku projektu muszę być w stanie wygenerować spektrogram z pliku .WAV. Przeczytałem następujące czynności:

Uzyskaj próbki N (transformuj rozmiar)Zastosuj aokno funkcjonowaćWykonaj szybką transformację Fouriera za pomocą próbekNormalizuj wyjścieWygeneruj spektrogram

Na obrazku poniżej widać dwa spektrogramy fali sinusoidalnej 10000 Hz, oba przy użyciuhanning funkcja okna. Po lewej stronie widzisz spektrogram wygenerowany przezśmiałość i po prawej moja wersja. Jak widać moja wersja ma o wiele więcej linii / szumów. Czy to wyciek w różnych pojemnikach? Jak mógłbym uzyskać wyraźny obraz, taki jak ten, który generuje audacity. Czy powinienem zrobić jakieś przetwarzanie końcowe? Nie dokonałem jeszcze żadnej normalizacji, ponieważ nie rozumiem w pełni, jak to zrobić.

aktualizacja

znalazłemto samouczek wyjaśniający, jak wygenerować spektrogram w c ++. Skompilowałem źródło, aby zobaczyć, jakie różnice mogę znaleźć.

Szczerze mówiąc, moja matematyka jest bardzo zardzewiała, więc nie jestem pewien, co robi normalizacja:

    for(i = 0; i < half; i++){
        out[i][0] *= (2./transform_size);
        out[i][6] *= (2./transform_size);
        processed[i] = out[i][0]*out[i][0] + out[i][7]*out[i][8];
        //sets values between 0 and 1?
        processed[i] =10. * (log (processed[i] + 1e-6)/log(10)) /-60.;
    }

po zrobieniu tego otrzymałem ten obraz (przy czym odwróciłem kolory):

Następnie przyjrzałem się różnicy próbek wejściowych dostarczonych przez moją bibliotekę dźwięku i tę z samouczka. Mój był o wiele wyższy, więc ręcznie go znormalizowałem, dzieląc go przez współczynnik 32767,9. Potem myślę, że to zdjęcie wygląda całkiem dobrze. Ale podzielenie go przez tę liczbę wydaje się błędne. Chciałbym zobaczyć inne rozwiązanie.

Oto pełny odpowiedni kod źródłowy.

void Spectrogram::process(){
    int i;
    int transform_size = 1024;
    int half = transform_size/2;
    int step_size = transform_size/2;
    double in[transform_size];
    double processed[half];
    fftw_complex *out;
    fftw_plan p;

    out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * transform_size);


    for(int x=0; x < wavFile->getSamples()/step_size; x++){

        int j = 0;
        for(i = step_size*x; i < (x * step_size) + transform_size - 1; i++, j++){
            in[j] = wavFile->getSample(i)/32767.9;
        }

        //apply window function
        for(i = 0; i < transform_size; i++){
            in[i] *= windowHanning(i, transform_size);
//            in[i] *= windowBlackmanHarris(i, transform_size);
        }

        p = fftw_plan_dft_r2c_1d(transform_size, in, out, FFTW_ESTIMATE);

        fftw_execute(p); /* repeat as needed */

        for(i = 0; i < half; i++){
            out[i][0] *= (2./transform_size);
            out[i][11] *= (2./transform_size);
            processed[i] = out[i][0]*out[i][0] + out[i][12]*out[i][13];
            processed[i] =10. * (log (processed[i] + 1e-6)/log(10)) /-60.;
        }

        for (i = 0; i < half; i++){
            if(processed[i] > 0.99)
                processed[i] = 1;
            In->setPixel(x,(half-1)-i,processed[i]*255);
        }


    }


    fftw_destroy_plan(p);
    fftw_free(out);
}

questionAnswers(3)

yourAnswerToTheQuestion