94 lines
3.0 KiB
Python
94 lines
3.0 KiB
Python
from imports import *
|
|
|
|
def arg(num, usage, default=None):
|
|
val = ''
|
|
if len(sys.argv) > num:
|
|
val = sys.argv[num]
|
|
else:
|
|
if default != None:
|
|
return default
|
|
raise ValueError(usage)
|
|
return val
|
|
|
|
def args(starting_num, usage, default=None):
|
|
l = []
|
|
if len(sys.argv) > starting_num:
|
|
l = sys.argv[starting_num:]
|
|
else:
|
|
if default != None:
|
|
return default
|
|
raise ValueError(usage)
|
|
return l
|
|
|
|
class AudioCutter:
|
|
def __init__(self, wav_file, json_file):
|
|
# Store a wav file's sound data and json data representing tagged chunks of audio in the wav
|
|
with open(json_file, 'r') as f:
|
|
self.json_info = json.load(f)
|
|
|
|
with open(wav_file, 'rb') as f:
|
|
self.wav = wave.open(f)
|
|
|
|
self.nchannels, self.sampwidth, self.framerate, self.nframes, self.comptype, self.compname = self.wav.getparams()
|
|
_, self.data = wavfile.read(wav_file)
|
|
|
|
# Accumulate new sound data cut from the original, along with new related json data
|
|
self.new_data = self.data[0:1]
|
|
self.new_json_info = {}
|
|
|
|
# State of a search through the json/wav file:
|
|
self.current_sec = 0
|
|
self.searching_for = None
|
|
self.last_search = None
|
|
|
|
def save_and_quit(self, new_wav_file):
|
|
wavfile.write(new_wav_file, self.framerate, self.new_data)
|
|
with open(new_wav_file.replace(".wav", ".json"), 'w') as f:
|
|
json.dump(self.new_json_info, f)
|
|
sys.exit(0)
|
|
|
|
def audio_and_length(self, start, end):
|
|
start_frame = int(start * self.framerate)
|
|
end_frame = int(end * self.framerate)
|
|
return self.data[start_frame:end_frame], end - start
|
|
|
|
def take_audio(self, tag, info, start, end):
|
|
audio, length = self.audio_and_length(start, end)
|
|
self.new_data = vstack((self.new_data, audio))
|
|
self.current_sec += length
|
|
self.new_json_info[tag] = info
|
|
|
|
def play_audio(self, start, end):
|
|
audio, _ = self.audio_and_length(start, end)
|
|
play_buffer(audio, self.nchannels, self.sampwidth, self.framerate)
|
|
|
|
def search(self):
|
|
phrase = input("phrase (lower-case) to search for?")
|
|
self.last_search = phrase
|
|
self.searching_for = phrase
|
|
|
|
def repeat_search(self):
|
|
self.searching_for = self.last_search
|
|
|
|
def process_audio(self, chunk_processor, new_wav_file):
|
|
for (audio_tag, chunk_info) in self.json_info.items():
|
|
# When the AudioCutter is searching for a phrase, skip all audio tags that don't match
|
|
if self.searching_for != None:
|
|
if self.searching_for in audio_tag:
|
|
self.searching_for = None
|
|
else:
|
|
continue
|
|
|
|
chunk_processor(audio_tag, chunk_info)
|
|
|
|
if self.searching_for != None:
|
|
print(f"{self.searching_for} not found")
|
|
|
|
self.save_and_quit(new_wav_file)
|
|
|
|
|
|
|
|
|
|
|
|
|