Resample audio in ExotelFrameSerializer
This commit is contained in:
@@ -11,6 +11,7 @@ from typing import Optional
|
|||||||
from loguru import logger
|
from loguru import logger
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from pipecat.audio.utils import create_default_resampler
|
||||||
from pipecat.frames.frames import (
|
from pipecat.frames.frames import (
|
||||||
AudioRawFrame,
|
AudioRawFrame,
|
||||||
Frame,
|
Frame,
|
||||||
@@ -63,6 +64,8 @@ class ExotelFrameSerializer(FrameSerializer):
|
|||||||
self._exotel_sample_rate = self._params.exotel_sample_rate
|
self._exotel_sample_rate = self._params.exotel_sample_rate
|
||||||
self._sample_rate = 0 # Pipeline input rate
|
self._sample_rate = 0 # Pipeline input rate
|
||||||
|
|
||||||
|
self._resampler = create_default_resampler()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def type(self) -> FrameSerializerType:
|
def type(self) -> FrameSerializerType:
|
||||||
"""Gets the serializer type.
|
"""Gets the serializer type.
|
||||||
@@ -95,8 +98,13 @@ class ExotelFrameSerializer(FrameSerializer):
|
|||||||
answer = {"event": "clear", "streamSid": self._stream_sid}
|
answer = {"event": "clear", "streamSid": self._stream_sid}
|
||||||
return json.dumps(answer)
|
return json.dumps(answer)
|
||||||
elif isinstance(frame, AudioRawFrame):
|
elif isinstance(frame, AudioRawFrame):
|
||||||
# Audio data is now directly used without resampling
|
data = frame.audio
|
||||||
payload = base64.b64encode(frame.audio).decode("ascii")
|
|
||||||
|
# Output: Exotel outputs PCM audio, but we need to resample to match requested sample_rate
|
||||||
|
serialized_data = await self._resampler.resample(
|
||||||
|
data, frame.sample_rate, self._exotel_sample_rate
|
||||||
|
)
|
||||||
|
payload = base64.b64encode(serialized_data).decode("ascii")
|
||||||
|
|
||||||
answer = {
|
answer = {
|
||||||
"event": "media",
|
"event": "media",
|
||||||
@@ -125,11 +133,17 @@ class ExotelFrameSerializer(FrameSerializer):
|
|||||||
|
|
||||||
if message["event"] == "media":
|
if message["event"] == "media":
|
||||||
payload_base64 = message["media"]["payload"]
|
payload_base64 = message["media"]["payload"]
|
||||||
audio_data = base64.b64decode(payload_base64)
|
payload = base64.b64decode(payload_base64)
|
||||||
|
|
||||||
# Audio data is now directly used without resampling
|
deserialized_data = await self._resampler.resample(
|
||||||
|
payload,
|
||||||
|
self._exotel_sample_rate,
|
||||||
|
self._sample_rate,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Input: Exotel takes PCM data, so just resample to match sample_rate
|
||||||
audio_frame = InputAudioRawFrame(
|
audio_frame = InputAudioRawFrame(
|
||||||
audio=audio_data,
|
audio=deserialized_data,
|
||||||
num_channels=1, # Assuming mono audio from Exotel
|
num_channels=1, # Assuming mono audio from Exotel
|
||||||
sample_rate=self._sample_rate, # Use the configured pipeline input rate
|
sample_rate=self._sample_rate, # Use the configured pipeline input rate
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user