简体   繁体   中英

Plot spectrum of a wave as in Audacity

I would like to plot frequency graphs similar to the ones that Audacity can draw:

大胆频率PNG

I did not find a software to do that (in command line) so I started to play with python to do it, using the specgram function. As I am not able to redo such a graph (the purple one from audacity), I was wondering if someone know exactly what Audacity is plotting, waht it means, and is there any pseudo-code somewhere? I have less than basic knowledge in audio processing, but if someone guides me on that part, I think I can code any suggestion/pseudo code/procedure. Right now, I'm here, plotting something like this which is roughly what I have seen everywhere so far.

我的振幅和频率图PNG

> pxx, freqs, bins, _ = plt.specgram(y, NFFT=s, Fs=rate, noverlap=0,
                                        cmap=plt.cm.binary, sides='onesided',
                                        window=signal.blackmanharris(s),
                                        scale_by_freq=True,
                                        mode='magnitude')
plot(freqs, numpy.log10(pxx.max(axis=1)))

I don't understand how can I get these "decrease" of dB vs. frequency which I can see on any audio WAV with Audacity

Cheers

As far as I see Audacity plots the magnitude spectrum, ie the absolute value of the fourier transform of the first 2048 samples. You plot the maximum amplitude in all time chunks relating to each frequency bin of the short time fourier transform .

Maybe this fits your needs:

import numpy as np
from scipy import signal
from matplotlib import pyplot as plt

y = y[0:2048] * signal.blackmanharris(2048)
X_amp = np.abs(np.fft.rfft(y))
X_db = 20 * np.log10(X_amp)
freqs = np.fft.rfftfreq(2048, 1/rate)
plt.plot(freqs, X_db)

EDIT:

Oh I found this page in the Audacity manual . So plt.specgram should be fine to imitate Audacity, just take np.average(pxx, axis=1) . The manual does not say what hop size is used... maybe try to set the noverlap -parameter to s/2 . (A common choice.)

Thanks, I was close but you found it. Finally the code is quite simple:

pxx, freqs, bins, _ = plt.specgram(y, NFFT=s, Fs=rate, noverlap=0,
                                   cmap=plt.cm.binary, sides='onesided',
                                   window=signal.blackmanharris(s),
                                   scale_by_freq=True,
                                   mode='magnitude')
plot(freqs, 20 * log10(mean(pxx, axis=1)), 'g')

And, except the y-axis unit, I'm almost one pixel accurate against audacity:

Final plot

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM