Advertisement
Guest User

FFT_python_Raspberry Pi

a guest
Mar 4th, 2013
3,307
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.47 KB | None | 0 0
  1. # Python 2.7 code to analyze sound and interface with Arduino
  2.  
  3. import pyaudio # from http://people.csail.mit.edu/hubert/pyaudio/
  4. import serial  # from http://pyserial.sourceforge.net/
  5. import numpy   # from http://numpy.scipy.org/
  6. import audioop
  7. import sys
  8. import math
  9. import struct
  10.  
  11. '''
  12. Sources
  13.  
  14. http://www.swharden.com/blog/2010-03-05-realtime-fft-graph-of-audio-wav-file-or-microphone-input-with-python-scipy-and-wckgraph/
  15. http://macdevcenter.com/pub/a/python/2001/01/31/numerically.html?page=2
  16.  
  17. '''
  18.  
  19. MAX = 0
  20.  
  21. def list_devices():
  22.     # List all audio input devices
  23.     p = pyaudio.PyAudio()
  24.     i = 0
  25.     n = p.get_device_count()
  26.     while i < n:
  27.         dev = p.get_device_info_by_index(i)
  28.         if dev['maxInputChannels'] > 0:
  29.             print str(i)+'. '+dev['name']
  30.         i += 1
  31.  
  32. def arduino_soundlight():
  33.     chunk      = 2**11 # Change if too fast/slow, never less than 2**11
  34.     scale      = 50    # Change if too dim/bright
  35.     exponent   = 5     # Change if too little/too much difference between loud and quiet sounds
  36.     samplerate = 44100
  37.  
  38.     # CHANGE THIS TO CORRECT INPUT DEVICE
  39.     # Enable stereo mixing in your sound card
  40.     # to make you sound output an input
  41.     # Use list_devices() to list all your input devices
  42.     device   = 2  
  43.    
  44.     p = pyaudio.PyAudio()
  45.     stream = p.open(format = pyaudio.paInt16,
  46.                     channels = 1,
  47.                     rate = 44100,
  48.                     input = True,
  49.                     frames_per_buffer = chunk,
  50.                     input_device_index = device)
  51.    
  52.     print "Starting, use Ctrl+C to stop"
  53.     try:
  54.         ser = serial.Serial(
  55.             port='com3',
  56.             timeout=1
  57.         )
  58.         while True:
  59.             data  = stream.read(chunk)
  60.  
  61.             '''
  62.            # Old RMS code, will only show the volume
  63.            
  64.            rms   = audioop.rms(data, 2)
  65.  
  66.            level = min(rms / (2.0 ** 16) * scale, 1.0)
  67.            level = level**exponent
  68.            level = int(level * 255)
  69.  
  70.            print level
  71.            ser.write(chr(level))
  72.            '''
  73.  
  74.             # Do FFT
  75.             levels = calculate_levels(data, chunk, samplerate)
  76.  
  77.             # Make it look better and send to serial
  78.             for level in levels:
  79.                 level = max(min(level / scale, 1.0), 0.0)
  80.                 level = level**exponent
  81.                 level = int(level * 255)
  82.                 ser.write(chr(level))
  83.  
  84.             s = ser.read(6)
  85.  
  86.     except KeyboardInterrupt:
  87.         pass
  88.     finally:
  89.         print "\nStopping"
  90.         stream.close()
  91.         p.terminate()
  92.         ser.close()
  93.  
  94. def calculate_levels(data, chunk, samplerate):
  95.     # Use FFT to calculate volume for each frequency
  96.     global MAX
  97.  
  98.     # Convert raw sound data to Numpy array
  99.     fmt = "%dH"%(len(data)/2)
  100.     data2 = struct.unpack(fmt, data)
  101.     data2 = numpy.array(data2, dtype='h')
  102.  
  103.     # Apply FFT
  104.     fourier = numpy.fft.fft(data2)
  105.     ffty = numpy.abs(fourier[0:len(fourier)/2])/1000
  106.     ffty1=ffty[:len(ffty)/2]
  107.     ffty2=ffty[len(ffty)/2::]+2
  108.     ffty2=ffty2[::-1]
  109.     ffty=ffty1+ffty2
  110.     ffty=numpy.log(ffty)-2
  111.    
  112.     fourier = list(ffty)[4:-4]
  113.     fourier = fourier[:len(fourier)/2]
  114.    
  115.     size = len(fourier)
  116.  
  117.     # Add up for 6 lights
  118.     levels = [sum(fourier[i:(i+size/6)]) for i in xrange(0, size, size/6)][:6]
  119.    
  120.     return levels
  121.  
  122. if __name__ == '__main__':
  123.     #list_devices()
  124.     arduino_soundlight()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement