From c4c15eff39d8edd64993a62c2c84472da99f3e96 Mon Sep 17 00:00:00 2001 From: Filipi Fuchter Date: Thu, 16 Jan 2025 18:30:19 -0300 Subject: [PATCH] Sending a silence frame to prevent the audio from clipping. --- .../server/signalling_bot.py | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/examples/bot-ready-signalling/server/signalling_bot.py b/examples/bot-ready-signalling/server/signalling_bot.py index 0a93d0cbc..23d407c05 100644 --- a/examples/bot-ready-signalling/server/signalling_bot.py +++ b/examples/bot-ready-signalling/server/signalling_bot.py @@ -7,13 +7,14 @@ import asyncio import os import sys +from dataclasses import dataclass import aiohttp from dotenv import load_dotenv from loguru import logger from runner import configure -from pipecat.frames.frames import EndFrame, TTSSpeakFrame +from pipecat.frames.frames import AudioRawFrame, EndFrame, OutputAudioRawFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner from pipecat.pipeline.task import PipelineTask @@ -26,6 +27,34 @@ logger.remove(0) logger.add(sys.stderr, level="DEBUG") +@dataclass +class SilenceFrame(OutputAudioRawFrame): + def __init__( + self, + audio: bytes = None, + sample_rate: int = 16000, + num_channels: int = 1, + duration: float = 0.1, + ): + # Initialize the parent class with the silent frame's data + super().__init__( + audio=self.create_silent_audio_frame(sample_rate, num_channels, duration).audio, + sample_rate=sample_rate, + num_channels=num_channels, + ) + + @staticmethod + def create_silent_audio_frame( + sample_rate: int, num_channels: int, duration: float + ) -> AudioRawFrame: + """Create an AudioRawFrame containing silence.""" + frame_size = num_channels * 2 # 2 bytes per sample for 16-bit audio + total_frames = int(sample_rate * duration) + total_bytes = total_frames * frame_size + silent_audio = bytes(total_bytes) # Create a byte array filled with zeros + return AudioRawFrame(audio=silent_audio, sample_rate=sample_rate, num_channels=num_channels) + + async def main(): async with aiohttp.ClientSession() as session: (room_url, _) = await configure(session) @@ -50,7 +79,11 @@ async def main(): if "playable" not in message: return await task.queue_frames( - [TTSSpeakFrame(f"Hello there, how are you doing today ?"), EndFrame()] + [ + SilenceFrame(duration=0.5), + TTSSpeakFrame(f"Hello there, how are you doing today ?"), + EndFrame(), + ] ) await runner.run(task)