Advertisement
Guest User

Untitled

a guest
Oct 2nd, 2016
292
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.06 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. from sys import byteorder
  4. from array import array
  5. from struct import pack
  6.  
  7. import pyaudio
  8. import wave
  9.  
  10. THRESHOLD = 500
  11. CHUNK_SIZE = 1024
  12. FORMAT = pyaudio.paInt16
  13. RATE = 44100
  14.  
  15. def is_silent(snd_data):
  16.     "Returns 'True' if below the 'silent' threshold"
  17.     return max(snd_data) < THRESHOLD
  18.  
  19. def normalize(snd_data):
  20.     "Average the volume out"
  21.     MAXIMUM = 16384
  22.     times = float(MAXIMUM)/max(abs(i) for i in snd_data)
  23.  
  24.     r = array('h')
  25.     for i in snd_data:
  26.         r.append(int(i*times))
  27.     return r
  28.  
  29. def trim(snd_data):
  30.     "Trim the blank spots at the start and end"
  31.     def _trim(snd_data):
  32.         snd_started = False
  33.         r = array('h')
  34.  
  35.         for i in snd_data:
  36.             if not snd_started and abs(i)>THRESHOLD:
  37.                 snd_started = True
  38.                 r.append(i)
  39.  
  40.             elif snd_started:
  41.                 r.append(i)
  42.         return r
  43.  
  44.     # Trim to the left
  45.     snd_data = _trim(snd_data)
  46.  
  47.     # Trim to the right
  48.     snd_data.reverse()
  49.     snd_data = _trim(snd_data)
  50.     snd_data.reverse()
  51.     return snd_data
  52.  
  53. def add_silence(snd_data, seconds):
  54.     "Add silence to the start and end of 'snd_data' of length 'seconds' (float)"
  55.     r = array('h', [0 for i in xrange(int(seconds*RATE))])
  56.     r.extend(snd_data)
  57.     r.extend([0 for i in xrange(int(seconds*RATE))])
  58.     return r
  59.  
  60. def record():
  61.     """
  62.    Record a word or words from the microphone and
  63.    return the data as an array of signed shorts.
  64.  
  65.    Normalizes the audio, trims silence from the
  66.    start and end, and pads with 0.5 seconds of
  67.    blank sound to make sure VLC et al can play
  68.    it without getting chopped off.
  69.    """
  70.     p = pyaudio.PyAudio()
  71.     stream = p.open(format=FORMAT, channels=1, rate=RATE,
  72.         input=True, output=True,
  73.         frames_per_buffer=CHUNK_SIZE)
  74.  
  75.     num_silent = 0
  76.     snd_started = False
  77.  
  78.     r = array('h')
  79.  
  80.     while 1:
  81.         # little endian, signed short
  82.         snd_data = array('h', stream.read(CHUNK_SIZE))
  83.         if byteorder == 'big':
  84.             snd_data.byteswap()
  85.         r.extend(snd_data)
  86.  
  87.         silent = is_silent(snd_data)
  88.  
  89.         if silent and snd_started:
  90.             num_silent += 1
  91.         elif not silent and not snd_started:
  92.             snd_started = True
  93.  
  94.         if snd_started and num_silent > 30:
  95.             break
  96.  
  97.     sample_width = p.get_sample_size(FORMAT)
  98.     stream.stop_stream()
  99.     stream.close()
  100.     p.terminate()
  101.  
  102.     r = normalize(r)
  103.     r = trim(r)
  104.     r = add_silence(r, 0.5)
  105.     return sample_width, r
  106.  
  107. def record_to_file(path):
  108.     "Records from the microphone and outputs the resulting data to 'path'"
  109.     sample_width, data = record()
  110.     data = pack('<' + ('h'*len(data)), *data)
  111.  
  112.     wf = wave.open(path, 'wb')
  113.     wf.setnchannels(1)
  114.     wf.setsampwidth(sample_width)
  115.     wf.setframerate(RATE)
  116.     wf.writeframes(data)
  117.     wf.close()
  118.  
  119. if __name__ == '__main__':
  120.     print("please speak a word into the microphone")
  121.     record_to_file('demo.wav')
  122.     print("done - result written to demo.wav")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement