Created
October 10, 2015 10:25
-
-
Save derblub/f2d308ffa777ed5ed6a7 to your computer and use it in GitHub Desktop.
8 bar Audio equaliser using MCP2307 (via https://www.raspberrypi.org/forums/viewtopic.php?p=314087)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# 8 bar Audio equaliser using MCP2307 | |
import alsaaudio as aa | |
import smbus | |
from time import sleep | |
from struct import unpack | |
import numpy as np | |
bus=smbus.SMBus(0) #Use '1' for newer Pi boards; | |
ADDR = 0x20 #The I2C address of MCP23017 | |
DIRA = 0x00 #PortA I/O direction, by pin. 0=output, 1=input | |
DIRB = 0x01 #PortB I/O direction, by pin. 0=output, 1=input | |
BANKA = 0x12 #Register address for Bank A | |
BANKB = 0x13 #Register address for Bank B | |
#Set up the 23017 for 16 output pins | |
bus.write_byte_data(ADDR, DIRA, 0); #all zeros = all outputs on Bank A | |
bus.write_byte_data(ADDR, DIRB, 0); #all zeros = all outputs on Bank B | |
def TurnOffLEDS (): | |
bus.write_byte_data(ADDR, BANKA, 0xFF) #set all columns high | |
bus.write_byte_data(ADDR, BANKB, 0x00) #set all rows low | |
def Set_Column(row, col): | |
TurnOffLEDS() | |
bus.write_byte_data(ADDR, BANKA, col) | |
bus.write_byte_data(ADDR, BANKB, row) | |
# Initialise matrix | |
TurnOffLEDS() | |
# Set up audio | |
sample_rate = 44100 | |
no_channels = 2 | |
chunk = 512 # Use a multiple of 8 | |
data_in = aa.PCM(aa.PCM_CAPTURE, aa.PCM_NORMAL) | |
data_in.setchannels(no_channels) | |
data_in.setrate(sample_rate) | |
data_in.setformat(aa.PCM_FORMAT_S16_LE) | |
data_in.setperiodsize(chunk) | |
def calculate_levels(data, chunk,sample_rate): | |
# Convert raw data to numpy array | |
data = unpack("%dh"%(len(data)/2),data) | |
data = np.array(data, dtype='h') | |
# Apply FFT - real data so rfft used | |
fourier=np.fft.rfft(data) | |
# Remove last element in array to make it the same size as chunk | |
fourier=np.delete(fourier,len(fourier)-1) | |
# Find amplitude | |
power = np.log10(np.abs(fourier))**2 | |
# Araange array into 8 rows for the 8 bars on LED matrix | |
power = np.reshape(power,(8,chunk/8)) | |
matrix= np.int_(np.average(power,axis=1)/4) | |
return matrix | |
print "Processing....." | |
while True: | |
TurnOffLEDS() | |
# Read data from device | |
l,data = data_in.read() | |
data_in.pause(1) # Pause capture whilst RPi processes data | |
if l: | |
# catch frame error | |
try: | |
matrix=calculate_levels(data, chunk,sample_rate) | |
for i in range (0,8): | |
Set_Column((1<<matrix[i])-1,0xFF^(1<<i)) | |
except audioop.error, e: | |
if e.message !="not a whole number of frames": | |
raise e | |
sleep(0.001) | |
data_in.pause(0) # Resume capture |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment