Hi All
i have downloaded following code from web that inputs sound samples and displays spectrum, i want to print frequencies present in each second in the spectrum.i.e
when ever the spectrum is displayed i want to print those frequencies as well on the console. Below is the code i am using i initially used "print fftx". Is "fftx" present in the code is frequency. Also how can i measure the amplitude of each frequency so as next step i will print three frequencies with the top most amplitude.
Thanks in advance.

import pyaudio
import scipy
import struct
import scipy.fftpack

from Tkinter import *
import threading
import time, datetime
import wckgraph
import math

#ADJUST THIS TO CHANGE SPEED/SIZE OF FFT
bufferSize=2**11
#bufferSize=2**8

# ADJUST THIS TO CHANGE SPEED/SIZE OF FFT
sampleRate=48100
#sampleRate=64000

p = pyaudio.PyAudio()
chunks=[]
ffts=[]
def stream():
global chunks, inStream, bufferSize
while True:
chunks.append(inStream.read(bufferSize))

def record():
global w, inStream, p, bufferSize
inStream = p.open(format=pyaudio.paInt16,channels=1,\
rate=sampleRate,input=True,frames_per_buffer=bufferSize)
threading.Thread(target=stream).start()

def downSample(fftx,ffty,degree=10):
x,y=[],[]
for i in range(len(ffty)/degree-1):
x.append(fftx[i*degree+degree/2])
y.append(sum(ffty[i*degree:(i+1)*degree])/degree)
return [x,y]

def smoothWindow(fftx,ffty,degree=10):
lx,ly=fftx[degree:-degree],[]
for i in range(degree,len(ffty)-degree):
ly.append(sum(ffty[i-degree:i+degree]))
return [lx,ly]

def smoothMemory(ffty,degree=3):
global ffts
ffts = ffts+[ffty]
if len(ffts) <= degree:
return ffty
ffts=ffts[1:]
return scipy.average(scipy.array(ffts),0)

def detrend(fftx,ffty,degree=10):
lx,ly=fftx[degree:-degree],[]
for i in range(degree,len(ffty)-degree):
ly.append(ffty-sum(ffty[i-degree:i+degree])/(degree*2))
#ly.append(fft-(ffty[i-degree]+ffty[i+degree])/2)
return [lx,ly]

def graph():
global chunks, bufferSize, fftx,ffty, w
if len(chunks)>0:
data = chunks.pop(0)
data=scipy.array(struct.unpack("%dB"%(bufferSize*2),data))
#print "RECORDED",len(data)/float(sampleRate),"SEC"
ffty=scipy.fftpack.fft(data)
fftx=scipy.fftpack.rfftfreq(bufferSize*2, 1.0/sampleRate)
fftx=fftx[0:len(fftx)/4]
ffty=abs(ffty[0:len(ffty)/2])/1000
ffty1=ffty[:len(ffty)/2]
ffty2=ffty[len(ffty)/2::]+2
ffty2=ffty2[::-1]
ffty=ffty1+ffty2
ffty=scipy.log(ffty)-2
#fftx,ffty=downSample(fftx,ffty,5)
#fftx,ffty=detrend(fftx,ffty,30)
#fftx,ffty=smoothWindow(fftx,ffty,10)
ffty=smoothMemory(ffty,3)
#fftx,ffty=detrend(fftx,ffty,10)
w.clear()
#w.add(wckgraph.Axes(extent=(0, -1, fftx[-1], 3)))
w.add(wckgraph.Axes(extent=(0, -1, 6000, 3)))
w.add(wckgraph.LineGraph([fftx,ffty]))
w.update()
if len(chunks)>20:
print "falling behind...",len(chunks)

def go(x=None):
global w,fftx,ffty
print "STARTING!"
threading.Thread(target=record).start()
while True:
graph()

root = Tk()
root.title("SPECTRUM ANALYZER")
root.geometry('500x200')
w = wckgraph.GraphWidget(root)
w.pack(fill=BOTH, expand=1)
go()
mainloop()

Dani AI

Generated

Short answer: yes — the array you call fftx is the frequency axis (the center frequency of each FFT bin) and the FFT output (ffty) are complex frequency bins whose amplitudes are the magnitudes (absolute values). To reliably print the three strongest frequencies each second you need three things in the pipeline: correct byte→sample conversion, sensible amplitude scaling, and a robust peak-selection step (windowing and optional interpolation improve accuracy).

A minimal, practical approach (replace the decoding/reading pieces in your app with this step) — convert raw bytes to signed 16‑bit samples, apply a window, do an rFFT, form a single‑sided amplitude spectrum, then pick the top 3 bins:

import numpy as np

N = len(raw_bytes)//2
samples = np.frombuffer(raw_bytes, dtype=np.int16).astype(float)/32768.0
windowed = samples * np.hanning(N)
Y = np.fft.rfft(windowed)
freqs = np.fft.rfftfreq(N, 1.0/sr)
amps = (2.0 / N) * np.abs(Y)    # single-sided amplitude (except DC/Nyquist)
idx = np.argsort(amps)[-3:][::-1]
for i in idx:
    print(freqs[i], amps[i])

Practical cautions and tips: do not unpack audio as unsigned bytes — use int16 (or the correct dtype for your PyAudio format). Remember frequency resolution = sampleRate / N (e.g. N=2048 at 48 kHz ≈ 23.4 Hz/bin); increase N or use parabolic interpolation on peak bins for finer frequency estimates. Apply a window (Hann/Blackman) to reduce leakage and compute amplitudes on the linear spectrum (convert to dB only for display). Heavy smoothing (your smoothMemory) can blunt short transients — detect peaks on the raw/smoothed-linear magnitudes, then average or debounce results across frames if you want one report per second. Finally, was right: keep code blocks formatted so helpers can read and test fixes quickly.

Recommended Answers

All 2 Replies

Please use code tags with your code to preserve the indentations. Otherwise the code is very difficult to read and not too many folks will help.

[code]
your Python code here

[/code]

Hi All
i have downloaded following code from web that inputs sound samples and displays spectrum, i want to print frequencies present in each second in the spectrum.i.e
when ever the spectrum is displayed i want to print those frequencies as well on the console. Below is the code i am using i initially used "print fftx". Is "fftx" present in the code is frequency. Also how can i measure the amplitude of each frequency so as next step i will print three frequencies with the top most amplitude.
Thanks in advance.

import pyaudio
import scipy
import struct
import scipy.fftpack

from Tkinter import *
import threading
import time, datetime
import wckgraph
import math

#ADJUST THIS TO CHANGE SPEED/SIZE OF FFT
bufferSize=2**11
#bufferSize=2**8

# ADJUST THIS TO CHANGE SPEED/SIZE OF FFT
sampleRate=48100
#sampleRate=64000

p = pyaudio.PyAudio()
chunks=[]
ffts=[]
def stream():
global chunks, inStream, bufferSize
while True:
chunks.append(inStream.read(bufferSize))

def record():
global w, inStream, p, bufferSize
inStream = p.open(format=pyaudio.paInt16,channels=1,\
rate=sampleRate,input=True,frames_per_buffer=bufferSize)
threading.Thread(target=stream).start()

def downSample(fftx,ffty,degree=10):
x,y=[],[]
for i in range(len(ffty)/degree-1):
x.append(fftx[i*degree+degree/2])
y.append(sum(ffty[i*degreei+1)*degree])/degree)
return [x,y]

def smoothWindow(fftx,ffty,degree=10):
lx,ly=fftx[degree:-degree],[]
for i in range(degree,len(ffty)-degree):
ly.append(sum(ffty[i-degree:i+degree]))
return [lx,ly]

def smoothMemory(ffty,degree=3):
global ffts
ffts = ffts+[ffty]
if len(ffts) <= degree:
return ffty
ffts=ffts[1:]
return scipy.average(scipy.array(ffts),0)

def detrend(fftx,ffty,degree=10):
lx,ly=fftx[degree:-degree],[]
for i in range(degree,len(ffty)-degree):
ly.append(ffty[i]-sum(ffty[i-degree:i+degree])/(degree*2))
#ly.append(fft[i]-(ffty[i-degree]+ffty[i+degree])/2)
return [lx,ly]

def graph():
global chunks, bufferSize, fftx,ffty, w
if len(chunks)>0:
data = chunks.pop(0)
data=scipy.array(struct.unpack("%dB"%(bufferSize*2),data))
#print "RECORDED",len(data)/float(sampleRate),"SEC"
ffty=scipy.fftpack.fft(data)
fftx=scipy.fftpack.rfftfreq(bufferSize*2, 1.0/sampleRate)
fftx=fftx[0:len(fftx)/4]
ffty=abs(ffty[0:len(ffty)/2])/1000
ffty1=ffty[:len(ffty)/2]
ffty2=ffty[len(ffty)/2::]+2
ffty2=ffty2[::-1]
ffty=ffty1+ffty2
ffty=scipy.log(ffty)-2
#fftx,ffty=downSample(fftx,ffty,5)
#fftx,ffty=detrend(fftx,ffty,30)
#fftx,ffty=smoothWindow(fftx,ffty,10)
ffty=smoothMemory(ffty,3)
#fftx,ffty=detrend(fftx,ffty,10)
w.clear()
#w.add(wckgraph.Axes(extent=(0, -1, fftx[-1], 3)))
w.add(wckgraph.Axes(extent=(0, -1, 6000, 3)))
w.add(wckgraph.LineGraph([fftx,ffty]))
w.update()
if len(chunks)>20:
print "falling behind...",len(chunks)

def go(x=None):
global w,fftx,ffty
print "STARTING!"
threading.Thread(target=record).start()
while True:
graph()

root = Tk()
root.title("SPECTRUM ANALYZER")
root.geometry('500x200')
w = wckgraph.GraphWidget(root)
w.pack(fill=BOTH, expand=1)
go()
mainloop()
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.