# How to see the amplitude of each frequency?

do you know software that exports spectrograms to images of 500x22000 pixels? all the spectrograms that I know show diffused frequencies and it does not look very good I just want to see the amplitude of each frequency

each vertical line is one second of the sound each horizontal line is a frequency

the entire audible spectrum enters the height of the image

the amplitude of each frequency is the brightness of the pixel

• It is unclear if you already obtained the spectograms using some software and you just want to export it. If so, which program are you using? Or do you want to generate them yourself and you are asking for the software to process the data and generate the desired output? If so it depends on your programming skills and the language you prefer (matlab, phyton, c ...) – Irreducible Mar 28 '18 at 8:21

As I have not had enough reputation to comment, I will provide some of my interpretation of your question (Don't need to accept my answer).

It looks like that you want a spectrogram represented by a 500$\times$22000 matrix. This relates to the number of time and frequency slots. The number of time slots (columns) is determined by the sample number of the given signal. The number of frequency slots (rows) is determined by number of FFT output, which you can adjust by methods such as zero padding.

If you want to get better-looking spectrogram, you might need to adjust the window that is used in performing STFT (or maybe more overlapping in STFT). However, sometimes you just cannot get satisfying resolutions as the time-frequency resolutions are bound to the uncertainty principle. This is decided by your time-domain samples.

A spectrogram is a way to display a 2D set of windowed FFT magnitudes or wavelet analysis decompositions.

If you use FFTs, the choice of FFT window shape and length changes the noise level and contrast. The choice of window overlap somewhat modifies the time resolution. If you use a short window, contrast in the horizontal or time axis is improved, If you use a long (sometime very long) window, contrast and resolution in the vertical or frequency axis is improved. If you want contrast in both axis, then there are non-standard non-linear methods in the literature of combining multiple types, lengths, and overlaps of FFT windows or wavelet decompositions into some sort of composite spectrogram image.

There are also lots of choices in how to color-map the FFT magnitudes into an image. Usually non-linear (log() domain), and possibly locally adaptive.

Here is some code that will get you started.

Having a one second long window is not going to get you satisfactory results in most audio files. Your example pic, if the horizontal pixel represent seconds, has simple tones of very long duration.

Anyway, this code will give you the syntax you need. It may be handy for others as well.

Hope this helps.

Ced


from PIL    import Image
from pydub  import AudioSegment

import numpy as np

#=======================================================================
def main():

#---- Read in the Sound File

theSound = AudioSegment.from_file( "test.mp3" )

#---- Get the Channel Count

theTrackCount = theSound.channels

#---- Get the Raw Audio Data as an Array

if theTrackCount == 2:
theCombined = theSound.split_to_mono()
theSound = theCombined[0]
print "Using left channel only"
elif theTrackCount > 2:
print "Invalid Track Count"

theSamples      = theSound.get_array_of_samples()
theSamplesCount = len( theSamples )

#---- Get the Frame Rate

theSamplesPerSecond = float( theSound.frame_rate )

#---- Print the File Characteristics

print theSamplesPerSecond, theTrackCount, len( theSamples )

#---- Get the File Size in Seconds

theSecondsCount = int( len( theSamples ) / theSamplesPerSecond )

print "Seconds:", theSecondsCount

#---- Create the Image

theImage  = Image.new( "RGB", (500,22000), "black" )

#---- Loop Through the File

theSegmentSpot = 0
theSegmentSize = int( theSamplesPerSecond )

theVonHannWindow = np.hanning( theSegmentSize )

for s in range( 0, theSecondsCount ):
theNextSpot = theSegmentSpot + theSegmentSize
theSegment = theSamples[theSegmentSpot:theNextSpot]

ProcessSegment( s, theSegment, theVonHannWindow, thePixels )
theSegmentSpot = theNextSpot
print s, s / theSecondsCount

#---- Write the Image to a File

theImage.save( "test.jpg" )

#=======================================================================
def ProcessSegment( argSecond, argSegment, argVonHannWindow, argPixels ):

#---- Apply a Von Hann Window and take the DFT

theWindowedSegment = argSegment * argVonHannWindow

theDft = np.fft.rfft( theWindowedSegment )

theAbsDft = np.abs( theDft )

#---- Plot the Peaks

theThreshold = 1000

theFactor = 128.0 / 5000.0

for b in range( 2, 22000 ):
v = theAbsDft[b]
if v > theThreshold:
if v > theAbsDft[b-1]:
if v > theAbsDft[b-2]:
if v > theAbsDft[b+1]:
if v > theAbsDft[b+2]:
theI = int( 128.0 + v * theFactor )
if theI > 255: theI = 255
theShade = ( theI << 16 ) \
+ ( theI << 8 ) + theI

#=======================================================================
main()


To wet your appetite launch sonic visualizer ... once you have opened your audio file

hit -> Layer -> Add Spectrogram

to see the effect you describe

... as you play the file a vertical bar travels left to right to indicate time across horizontal X axis with frequency on the Y axis and magnitude of each frequency determining color across each vertical sampling window

to code this up yourself you simply perform a FFT for a window of frames then slide the window forward in time and repeat ... for each result set of a given FFT calculate the magnitude of each frequency bin ... typically this FFT result set is an array of complex numbers where each array element is a given frequency ... calculate the magnitude using

magnitude = 2.0 * math.Sqrt(curr_real^2 + curr_imag^2) / number_of_samples

then create a mapping between your range of magnitude values (possibly normalize) and your range of RGB colors ... once defined display this bar of colors as a vertical bar then advance to the right as you repeat for next window of audio samples you feed into your FFT call

... as other answers have mentioned there exists a balancing act on how to decide number of audio samples you include in your window ... due to the nature of the FFT algorithm you must put a power of 2 number of audio samples into the window, if you choose to use fewer then pad with zero value samples to top it off ... too many samples and your FFT result set loses temporal specificity ... by definition all samples put into a window and fed into the FFT call result in a single output which is orthogonal to time since at this point its in the frequency domain yet you must visually position it on your screen to represent a spread of time and when your source audio media varies as in a song this single output will temporary blur to the degree to which you include more samples (keep in mind the Fourier Transform is only accurate for a periodic signal, not an aperiodic signal like a song) ... however more samples in a given window affords you resultant frequency bins closer together which is also desirable ... so you can see its a judgement call to pick a balance here

to brush up on how to feed data into a FFT call and how to handle the output from a FFT watch this

https://www.youtube.com/watch?v=mkGsMWi_j4Q # Discrete Fourier Transform - Simple Step by Step