diff --git a/.gitignore b/.gitignore index d8dd753..0b1c5d4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.wav +*.mp3 diff --git a/rotaryGuestBook.py b/rotaryGuestBook.py old mode 100644 new mode 100755 index 09d068a..9b1de8e --- a/rotaryGuestBook.py +++ b/rotaryGuestBook.py @@ -6,9 +6,18 @@ import time import wave from datetime import datetime from gpiozero import Button +from multiprocessing import Process from signal import pause +from pydub.scipy_effects import band_pass_filter +from pydub.effects import normalize, compress_dynamic_range, low_pass_filter, high_pass_filter +from pydub import AudioSegment +from pydub.playback import play hook = Button(17) +rotaryDial = Button(18, hold_time=0.25, hold_repeat=True) +count = 0 +dialed = [] +reset_flag = False # TODO: rotary encoder: special key codes trigger certain voicemails @@ -52,25 +61,44 @@ class AudioInterface: ) """ Play entire file """ data = self.wf.readframes(self.chunk) - while data != b"": + while len(data): self.stream.write(data) data = self.wf.readframes(self.chunk) + def stop(self): # stop the stream, close it, and terminate the pyaudio instantiation self.stream.stop_stream() self.stream.close() self.audio.terminate() - def close(self): + def close(self, outputFile): # save the audio frames as .wav file - with wave.open(os.getcwd() + "/recordings/" - + f"{datetime.now().isoformat()}.wav", "wb") as wavefile: + with wave.open(outputFile, "wb") as wavefile: wavefile.setnchannels(self.chans) wavefile.setsampwidth(self.audio.get_sample_size(self.format)) wavefile.setframerate(self.samp_rate) wavefile.writeframes(b"".join(self.frames)) + + def postProcess(self, outputFile): + source = AudioSegment.from_file(outputFile + ".wav", format="wav") + + print("Filtering...") + filtered = band_pass_filter(source, 200, 15000) + print("Normalizing...") + normalized = normalize(filtered) + # print("Compress Dynamic Range") + # compressed = compress_dynamic_range(normalized) + + print("Exporting normalized") + normalized.export(outputFile + "normalized.mp3", format="mp3") + # print("Exporting compressed") + # compressed.export(outputFile + "compressed.mp3", format="mp3") + print("Finished...") + # Effects.apply_gain_stereo(audio_segment, 3, 3) + + def offHook(): audioInterface = AudioInterface() print("Phone off hook, ready to begin!") @@ -78,23 +106,57 @@ def offHook(): time.sleep(1) # playback voice message through speaker print("Playing voicemail message...") - audioInterface.play(os.getcwd() + "/sounds/voicemail.wav") + # audioInterface.play(os.getcwd() + "/sounds/voicemail.wav") + play(AudioSegment.from_wav(os.getcwd() + "/sounds/voicemail.wav")) # start recording beep print("Playing beep...") - audioInterface.play(os.getcwd() + "/sounds/beep.wav") + # audioInterface.play(os.getcwd() + "/sounds/beep.wav") + play(AudioSegment.from_file(os.getcwd() + "/sounds/beep.wav", format="wav") - 16) # now, while phone is not off the hook, record audio from the microphone print("recording") audioInterface.record() audioInterface.stop() - audioInterface.close() + outputFile = os.getcwd() + "/recordings/" + f"{datetime.now().isoformat()}" + audioInterface.close(outputFile + ".wav") print("finished recording") + print("spawn postProcessing thread") + Process(target=audioInterface.postProcess, args=(outputFile,)).start() def onHook(): print("Phone on hook. Sleeping...") +def dialing(): + global count, reset_flag + count+=1 + print(f"dialing, increment count: {count}") + reset_flag = False + +def reset(): + global count, reset_flag + count = 0 + toggle = False + print(f"reset count: {count}") + reset_flag = True + + +def held(): + if(not reset_flag): + print("holding") + print(count) + global dialed + if (count == 10): + dialed.append(0) + else: + dialed.append(count) + print(f"number dialed: {dialed}") + reset() + + def main(): + rotaryDial.when_pressed = dialing + rotaryDial.when_held = held hook.when_pressed = offHook hook.when_released = onHook pause()