Skip to content

Commit

Permalink
move onus of audio encoding into utils
Browse files Browse the repository at this point in the history
  • Loading branch information
ajar98 committed Jul 9, 2024
1 parent 0336b7c commit 9e09592
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
7 changes: 4 additions & 3 deletions vocode/streaming/output_device/twilio_output_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,13 @@ def enqueue_mark_message(self, mark_message: MarkMessage):

def send_dtmf_tones(self, keypad_entries: List[KeypadEntry]):
for keypad_entry in keypad_entries:
dtmf_tone_pcm = generate_dtmf_tone(keypad_entry, sampling_rate=self.sampling_rate)
dtmf_tone_mulaw = audioop.lin2ulaw(dtmf_tone_pcm, 2)
dtmf_tone = generate_dtmf_tone(
keypad_entry, sampling_rate=self.sampling_rate, audio_encoding=self.audio_encoding
)
dtmf_message = {
"event": "media",
"streamSid": self.stream_sid,
"media": {"payload": base64.b64encode(dtmf_tone_mulaw).decode("utf-8")},
"media": {"payload": base64.b64encode(dtmf_tone).decode("utf-8")},
}
self._twilio_events_queue.put_nowait(json.dumps(dtmf_message))

Expand Down
16 changes: 14 additions & 2 deletions vocode/streaming/utils/dtmf_utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import audioop
from enum import Enum

import numpy as np

from vocode.streaming.models.audio import AudioEncoding

DEFAULT_DTMF_TONE_LENGTH_SECONDS = 0.3


class KeypadEntry(str, Enum):
ONE = "1"
Expand Down Expand Up @@ -31,10 +36,17 @@ class KeypadEntry(str, Enum):


def generate_dtmf_tone(
keypad_entry: KeypadEntry, sampling_rate: int, duration_seconds: float = 0.3
keypad_entry: KeypadEntry,
sampling_rate: int,
audio_encoding: AudioEncoding,
duration_seconds: float = DEFAULT_DTMF_TONE_LENGTH_SECONDS,
) -> bytes:
f1, f2 = DTMF_FREQUENCIES[keypad_entry]
t = np.linspace(0, duration_seconds, int(sampling_rate * duration_seconds), endpoint=False)
tone = np.sin(2 * np.pi * f1 * t) + np.sin(2 * np.pi * f2 * t)
tone = tone / np.max(np.abs(tone)) # Normalize to [-1, 1]
return (tone * 32767).astype(np.int16).tobytes()
pcm = (tone * 32767).astype(np.int16).tobytes()
if audio_encoding == AudioEncoding.MULAW:
return audioop.lin2ulaw(pcm, 2)
else:
return pcm

0 comments on commit 9e09592

Please sign in to comment.