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