‹ projects

vmc

a voice model creator for CMU Sphinx
Log | Files | Refs | README | LICENSE

getaudio.py (3564B)


      1 #!/usr/bin/python3
      2 # 
      3 # DESCRIPTION
      4 # 
      5 #       getaudio is used to sequentially prompt the user for dictations of 
      6 #       displayed sentences.
      7 #
      8 # DEPENDENCIES: python3-pyaudio, python3
      9 #
     10 # USAGE
     11 # 
     12 #       python3 getaudio.py /path/to/simple-list-of-sentences.txt \
     13 #                           /audio/recording/folder \
     14 #                           recording-repetitions \
     15 #                           model-name \
     16 #                           num_of_preexisting_audio_recordings
     17 #
     18 # LIBRARY IMPORTS -------------------------------------------------------------
     19 
     20 import sys, os, _thread, pyaudio, wave, contextlib
     21 
     22 # VARIABLE DEFINITIONS --------------------------------------------------------
     23 
     24 chunk = 1024
     25 FORMAT = pyaudio.paInt16
     26 CHANNELS = 1
     27 RATE = 16000
     28 
     29 sentence_file = sys.argv[1]                # e.g. ~/sentencelist.txt
     30 audio_recording_folder = sys.argv[2].rstrip(os.sep) # e.g. ~/.psyche/audio
     31 reps = int(sys.argv[3])                    # e.g. 5
     32 model_name = sys.argv[4]                   # e.g. 'en-us'
     33 
     34 try:
     35     recording_count = int(sys.argv[5]) # how many audio files already exist
     36 except IndexError:
     37     recording_count = 0
     38 
     39 # FUNCTION DEFINITIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     40 
     41 # ignore sdterr messages: as from pyaudio
     42 @contextlib.contextmanager
     43 def ignore_stderr():
     44     devnull = os.open(os.devnull, os.O_WRONLY)
     45     old_stderr = os.dup(2)
     46     sys.stderr.flush()
     47     os.dup2(devnull, 2)
     48     os.close(devnull)
     49     try:
     50         yield
     51     finally:
     52         os.dup2(old_stderr, 2)
     53         os.close(old_stderr)
     54 
     55 def record_until_keypress(audio_filepath):
     56 
     57     # detect keypress [enter]
     58     def input_thread(L):
     59         input()
     60         L.append(None)
     61 
     62     # initialize audio stream - and keep it quiet
     63     with ignore_stderr():
     64         p = pyaudio.PyAudio()
     65         stream = p.open(format = FORMAT,
     66                 channels = CHANNELS,
     67                 rate = RATE,
     68                 input = True,
     69                 frames_per_buffer = chunk)
     70 
     71     # create interrupt thread
     72     L = []
     73     _thread.start_new_thread(input_thread, (L,))
     74     
     75     # record data during loop
     76     frames = []
     77     while True:
     78         data = stream.read(chunk)
     79         frames.append(data)
     80         if L: 
     81             stream.stop_stream()
     82             break
     83     
     84     # exit cleanly after break
     85     stream.close()
     86     p.terminate()
     87     
     88     # write data to WAVE file
     89     data = b''.join(frames)
     90     wf = wave.open(audio_filepath, 'wb')
     91     wf.setnchannels(CHANNELS)
     92     wf.setsampwidth(p.get_sample_size(FORMAT))
     93     wf.setframerate(RATE)
     94     wf.writeframes(data)
     95     wf.close()
     96 
     97 
     98 # LOGIC ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     99 
    100 if not os.path.exists(audio_recording_folder):
    101     raise NotADirectoryError("Audio recording save folder does not exist.")
    102 
    103 # create list of sentences for prompt
    104 sentence_list = []
    105 with open(sentence_file) as f:
    106     for line in f:
    107         sentence_list.append(line)
    108 
    109 num_recs = len(sentence_list)*reps+recording_count
    110 
    111 # collect audio files
    112 try:
    113 
    114     input("Press [enter], read text, & press [enter].")
    115 
    116     for sentence in sentence_list*reps: 
    117         #recording number
    118         recording_count+=1
    119 
    120         # record audio with visual
    121         print("Recording no. %04d of %04d: \n\n\t%s" % (recording_count, num_recs, sentence), end='\r')
    122 
    123         # recording file should look like this (e.g.): ./bespoke_training_data/audio/arctic_0001.wav        
    124         record_until_keypress(str(audio_recording_folder + os.sep + model_name + "_%04d.wav" % recording_count))
    125 
    126 except KeyboardInterrupt:
    127     pass
    128 
    129