feat: rotary digit tracking, audio post processing
This commit is contained in:
parent
9231963870
commit
ad784673f7
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
*.wav
|
*.wav
|
||||||
|
*.mp3
|
||||||
|
76
rotaryGuestBook.py
Normal file → Executable file
76
rotaryGuestBook.py
Normal file → Executable file
@ -6,9 +6,18 @@ import time
|
|||||||
import wave
|
import wave
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from gpiozero import Button
|
from gpiozero import Button
|
||||||
|
from multiprocessing import Process
|
||||||
from signal import pause
|
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)
|
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
|
# TODO: rotary encoder: special key codes trigger certain voicemails
|
||||||
|
|
||||||
@ -52,25 +61,44 @@ class AudioInterface:
|
|||||||
)
|
)
|
||||||
""" Play entire file """
|
""" Play entire file """
|
||||||
data = self.wf.readframes(self.chunk)
|
data = self.wf.readframes(self.chunk)
|
||||||
while data != b"":
|
while len(data):
|
||||||
self.stream.write(data)
|
self.stream.write(data)
|
||||||
data = self.wf.readframes(self.chunk)
|
data = self.wf.readframes(self.chunk)
|
||||||
|
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
# stop the stream, close it, and terminate the pyaudio instantiation
|
# stop the stream, close it, and terminate the pyaudio instantiation
|
||||||
self.stream.stop_stream()
|
self.stream.stop_stream()
|
||||||
self.stream.close()
|
self.stream.close()
|
||||||
self.audio.terminate()
|
self.audio.terminate()
|
||||||
|
|
||||||
def close(self):
|
def close(self, outputFile):
|
||||||
# save the audio frames as .wav file
|
# save the audio frames as .wav file
|
||||||
with wave.open(os.getcwd() + "/recordings/"
|
with wave.open(outputFile, "wb") as wavefile:
|
||||||
+ f"{datetime.now().isoformat()}.wav", "wb") as wavefile:
|
|
||||||
wavefile.setnchannels(self.chans)
|
wavefile.setnchannels(self.chans)
|
||||||
wavefile.setsampwidth(self.audio.get_sample_size(self.format))
|
wavefile.setsampwidth(self.audio.get_sample_size(self.format))
|
||||||
wavefile.setframerate(self.samp_rate)
|
wavefile.setframerate(self.samp_rate)
|
||||||
wavefile.writeframes(b"".join(self.frames))
|
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():
|
def offHook():
|
||||||
audioInterface = AudioInterface()
|
audioInterface = AudioInterface()
|
||||||
print("Phone off hook, ready to begin!")
|
print("Phone off hook, ready to begin!")
|
||||||
@ -78,23 +106,57 @@ def offHook():
|
|||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
# playback voice message through speaker
|
# playback voice message through speaker
|
||||||
print("Playing voicemail message...")
|
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
|
# start recording beep
|
||||||
print("Playing 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
|
# now, while phone is not off the hook, record audio from the microphone
|
||||||
print("recording")
|
print("recording")
|
||||||
audioInterface.record()
|
audioInterface.record()
|
||||||
audioInterface.stop()
|
audioInterface.stop()
|
||||||
audioInterface.close()
|
outputFile = os.getcwd() + "/recordings/" + f"{datetime.now().isoformat()}"
|
||||||
|
audioInterface.close(outputFile + ".wav")
|
||||||
print("finished recording")
|
print("finished recording")
|
||||||
|
print("spawn postProcessing thread")
|
||||||
|
Process(target=audioInterface.postProcess, args=(outputFile,)).start()
|
||||||
|
|
||||||
|
|
||||||
def onHook():
|
def onHook():
|
||||||
print("Phone on hook. Sleeping...")
|
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():
|
def main():
|
||||||
|
rotaryDial.when_pressed = dialing
|
||||||
|
rotaryDial.when_held = held
|
||||||
hook.when_pressed = offHook
|
hook.when_pressed = offHook
|
||||||
hook.when_released = onHook
|
hook.when_released = onHook
|
||||||
pause()
|
pause()
|
||||||
|
Loading…
Reference in New Issue
Block a user