colin-guyon / rpi-audio-levels Goto Github PK
View Code? Open in Web Editor NEWPython binding allowing to retrieve audio levels by frequency bands given audio samples (power spectrum in fact), on a raspberry pi, using GPU FFT
License: Other
Python binding allowing to retrieve audio levels by frequency bands given audio samples (power spectrum in fact), on a raspberry pi, using GPU FFT
License: Other
Hello!
I have in use:
Raspberry Pi B+ V1.2
USB Soundcard
Raspbian GNU/Linux 7 (wheezy)
Linux version 4.1.13+ (dc4@dc4-XPS13-9333) (gcc version 4.8.3 20140303 (prerelease) (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03) ) #826 PREEMPT Fri Nov 13 20:13:22 GMT 2015
pi@raspberrypi ~/rpi-audio-levels $ python setup.py build_ext --inplace
/usr/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: 'install_requires'
warnings.warn(msg)
running build_ext
cythoning src/rpi_audio_levels.pyx to src/rpi_audio_levels.c
Error compiling Cython file:
------------------------------------------------------------
...
list bands_indexes not None):
cdef:
unsigned int i
int **c_bands_indexes
unsigned int bands_count = len(bands_indexes)
float[:] data_memview = data
^
------------------------------------------------------------
src/rpi_audio_levels.pyx:46:18: Expected an identifier or literal
building 'rpi_audio_levels' extension
creating build
creating build/temp.linux-armv6l-2.7
creating build/temp.linux-armv6l-2.7/src
creating build/temp.linux-armv6l-2.7/opt
creating build/temp.linux-armv6l-2.7/opt/vc
creating build/temp.linux-armv6l-2.7/opt/vc/src
creating build/temp.linux-armv6l-2.7/opt/vc/src/hello_pi
creating build/temp.linux-armv6l-2.7/opt/vc/src/hello_pi/hello_fft
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c src/rpi_audio_levels.c -o build/temp.linux-armv6l-2.7/src/rpi_audio_levels.o -I/opt/vc/src/hello_pi/hello_fft/
src/rpi_audio_levels.c:1:2: error: #error Do not use this file, it is the result of a failed Cython compilation.
Best regards!
Thanks for pointing me to this fork Colin.
As i wrote earlier, i´m currently using the PI and numpy.fft() to compute audio for a school project.
This is what i'm using to get the FFT out of a 44100Hz mic sample.
The current data length is 8192 np.int16 samples (some 0.2 seconds of audio)
def getFFT(data,rate):
data=data*np.hamming(len(data))
fft=np.fft.fft(data)
fft=np.abs(fft)
fft=10*np.log10(fft) #get decibels
freq=np.fft.fftfreq(len(fft),1.0/rate)
return freq[:int(len(freq)/2)],fft[:int(len(fft)/2)] # return X axis and power bands
This code (taken from SWHear.py lib, by Scott Harden) renders some 22k FFT bands.
I kind of understand how to do the same in your GPU_FFT implementation by sending the right data type, however i fail to understand what the "bands_indexes" parameter is telling the function.
How would you implement audio_levels.compute() in order to yield 22k bands ?
Hello, I love the idea of being able to program data analysis etc. in python while using GPUI_FFT in c. Great work of implementing the cython bridge! It makes showcases with the raspberry much easier!
I am currently trying to fft some single channel .wav data (48000Hz Sample Rate, 0.2s lenght) with rpi-audio-levels, only analyzing frequencies between 500Hz and 3kHz. When I do a spectrum analysis with audacity of the file I get the follwing spectrum:
However, when I try to analyse it with audio_levles.compute the same file with 250 bands á 10Hz will return:
This for Samplesize of 1024:
This for Samplesize of 2048:
This for Samplesize of 4096
It should be easy to distinguish that these spectrums do not look like one another.
Also there should not be any empty fields. However, the levels vector does contain random values or sometimes the Value -inf or for its spectrum. Am I misunderstanding something?
Main function:
from rpi_audio_levels import AudioLevels #GPU FFT - Cython bridge by colin guyon
import CustomFunctions as sf
import numpy as np
#2**DATA_SIZE equals Sample size
DATA_SIZE = 10
# Number of Frequency Bands
BANDS_COUNT = 250
# Init
audio_levels = AudioLevels(DATA_SIZE, BANDS_COUNT)
#Frequencies.
FREQ_START = 500 #How many Hz is minimum of frequency Range?
FREQ_STOP = 3000 #How many Hz is maximum of frequency Range?
#Generate band indexes:
indexes = sf.calculate_bands(FREQ_START,FREQ_STOP, BANDS_COUNT)
#load wav file into numpy array
data = sf.get_c0_data(TESTFILE)
data = np.float32(data)
#FFT through data
levels, means, stds = audio_levels.compute(data, indexes)
sf.calculate_bands:
def calculate_bands(minFrequency, maxFrequency, bandCount):
#Calculate Band width
band_width = (maxFrequency-minFrequency)/bandCount
#Generate band indexes:
band_current = minFrequency
band_next = band_current + band_width
indexes=[]
for ctr in range(bandCount):
#print(ctr)
buffer = (band_current, band_next)
indexes.append(buffer)
band_current = band_next
band_next = band_next + band_width
return indexes
sf.get_c0_data
import numpy as np
import wave
def get_c0_data(filename):
'''
Read date of first Channel from the provided wavefile
'''
#Read Data
wav = wave.open(filename)
nch = wav.getnchannels()
depth = wav.getsampwidth()
wav.setpos(0)
sdata = wav.readframes(wav.getnframes())
# Extract channel data (24-bit data not supported)
typ = { 1: np.uint8, 2: np.uint16, 4: np.uint32 }.get(depth)
if not typ:
raise ValueError("sample width {} not supported".format(depth))
data = np.fromstring(sdata, dtype=typ)
ch_data = data[0::nch]
return ch_data
So I varied every parameter which audio_levels.compute allows for: different frequencies, different audio files and always I get levels and means-arrays with rubbish as content. Has anyone got any Idea what may cause this? Spent now over 15 Hours iterating and retrying with no luck at all. Did I critically misunderstand what kind of Data have to be fed into the FFT?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.