Guest User

Pyaudio

a guest
Mar 9th, 2013
768
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 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()
Add Comment
Please, Sign In to add comment