Skip to content

Commit

Permalink
Add audio visualizer client and server, spi driver speed improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
longjos committed Aug 1, 2014
1 parent 828a6ff commit e970b24
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 6 deletions.
Binary file added 8k8bitpcm.wav
Binary file not shown.
7 changes: 2 additions & 5 deletions raspledstrip/LPD8806.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,8 @@ def __init__(self, led_count):
raise Exception("SPI module not available")
self.spi = spidev.SpiDev()
self.spi.open(0, 0)
self.spi.max_speed_hz = 12000000
self.spi.max_speed_hz = 18000000
print 'py-spidev MHz: %d' % (self.spi.max_speed_hz / 1000000.0)

def update(self, pixel_buffer):
for led in xrange(self.led_count):
self.spi.xfer2([i for i in pixel_buffer[led]])
self.spi.xfer2([0x00, 0x00, 0x00]) #zero fill the last to prevent stray colors at the end
self.spi.xfer2([0x00]) #once more with feeling - this helps :)
self.spi.xfer2([item for sublist in pixel_buffer for item in sublist]+[0x00, 0x00, 0x00])
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
mock==1.0.1
nose==1.3.3
nose==1.3.3
PyAudio==0.2.8
numpy==1.8.1
80 changes: 80 additions & 0 deletions visualize_audio_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import wave
import pyaudio
import numpy
import socket
import struct

LED_DRIVER_HOST = '0.0.0.0' #Set this to the address of the raspberry pi with the LEDs attached
#LED_DRIVER_HOST = 'localhost'
LED_DRIVER_PORT = 50007
BUFFER_SIZE = 512


def main():
display_buffer = [bytearray([0x00, 0x00, 0x00]) for i in xrange(36)]

#input_stream = FileReader('8k8bitpcm.wav') # local file for testing
input_stream = LiveReader()
output_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

def lpush(buffer, byte):
def lpush_iter(buffer, pos, byte):
if pos < len(buffer):
current_byte = buffer[pos]
buffer[pos] = byte
return lpush_iter(buffer, pos+1, current_byte)
else:
return buffer

return lpush_iter(buffer, 0, byte)

audio_bytes = input_stream.read_bytes(BUFFER_SIZE)

while audio_bytes:
buf = numpy.frombuffer(audio_bytes, dtype=numpy.int8)
window = numpy.hanning(len(buf))
buf = buf * window
fourier = numpy.fft.rfft(buf, 8)

power = numpy.abs(fourier)
spectrum = (power * 255/power.max()).astype(numpy.int8).clip(0)
element = bytearray([spectrum[1], spectrum[2], spectrum[3]])

display_buffer = lpush(display_buffer, element)
buf = ""
for pixel in display_buffer:
buf += struct.pack('BBB', *pixel)
output_socket.sendto(
buf,
(LED_DRIVER_HOST, LED_DRIVER_PORT)
)
audio_bytes = input_stream.read_bytes(BUFFER_SIZE)


class AudioReader(object):
def read_bytes(self, buffer_size):
pass


class FileReader(AudioReader):
def __init__(self, file_name):
self._fp = wave.open(file_name, 'r')

def read_bytes(self, buffer_size):
return self._fp.readframes(buffer_size)


class LiveReader(AudioReader):
def __init__(self):
self._paudio = pyaudio.PyAudio()
self._stream = self._paudio.open(
format=pyaudio.paInt8,
channels=1,
rate=16000,
input=True
)

def read_bytes(self, buffer_size):
return self._stream.read(buffer_size)

main()
33 changes: 33 additions & 0 deletions visualize_audio_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import socket
import struct
from raspledstrip.LPD8806 import LPD8806SPI
led_strip = LPD8806SPI(36)

HOST = ''
PORT = 50007

input_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
input_socket.bind((HOST, PORT))
display_buffer = [bytearray([0x00, 0x00, 0x00]) for i in xrange(36)]
gamma = [0x80 | int(pow(float(i) / 255.0, 2.5) * 127.0 + 0.5) for i in range(256)]


def lpush(buffer, byte):
def lpush_iter(buffer, pos, byte):
if pos < len(buffer):
current_byte = buffer[pos]
buffer[pos] = byte
return lpush_iter(buffer, pos+1, current_byte)
else:
return buffer

return lpush_iter(buffer, 0, byte)


while 1:
byte_buffer, from_addr = input_socket.recvfrom(36*3)
for i in xrange(36):
pixel = struct.unpack('BBB', byte_buffer[i*3:(i*3 + 3)])
display_buffer = lpush(display_buffer, bytearray([gamma[pixel[0]], gamma[pixel[1]], gamma[pixel[2]]]))
led_strip.update(display_buffer)
#print display_buffer

0 comments on commit e970b24

Please sign in to comment.