How we built a realtime system for responsive voice AI in six months
Back to Tutorials
aiTutorialintermediate

How we built a realtime system for responsive voice AI in six months

August 3, 202681 views4 min read

Build a real-time voice AI system with continuous conversation flow, using Python and WebRTC for low-latency communication.

Introduction

In this tutorial, you'll build a real-time voice interaction system similar to what OpenAI developed for GPT-Live. You'll create a responsive voice AI that can handle continuous conversation with minimal latency, using Python and WebRTC for real-time communication. This system will process speech-to-text, send it to an AI model, and convert the response back to speech in real-time.

Prerequisites

  • Python 3.8+
  • Basic understanding of Python and web development
  • Installed packages: pyaudio, websockets, openai, speechrecognition, pydub
  • Access to OpenAI API key
  • Basic knowledge of WebRTC concepts

Step 1: Set Up Your Development Environment

Install Required Dependencies

First, create a virtual environment and install the necessary packages:

python -m venv voice_ai_env
source voice_ai_env/bin/activate  # On Windows: voice_ai_env\Scripts\activate
pip install pyaudio websockets openai speechrecognition pydub

This setup gives us the core libraries needed for audio capture, web communication, AI integration, and audio processing.

Step 2: Create the Core Voice Processing Class

Implement Audio Capture and Streaming

Let's start by creating the foundation for real-time audio processing:

import pyaudio
import wave
import threading
import asyncio
import websockets
import json


class VoiceAIProcessor:
    def __init__(self, api_key):
        self.api_key = api_key
        self.audio = pyaudio.PyAudio()
        self.chunk = 1024
        self.format = pyaudio.paInt16
        self.channels = 1
        self.rate = 16000
        self.recording = False
        self.websocket = None

    def start_recording(self):
        self.recording = True
        stream = self.audio.open(
            format=self.format,
            channels=self.channels,
            rate=self.rate,
            input=True,
            frames_per_buffer=self.chunk
        )

        print("Recording... Press Ctrl+C to stop")
        try:
            while self.recording:
                data = stream.read(self.chunk)
                # Send audio data to WebSocket
                if self.websocket:
                    asyncio.run(self.websocket.send(data))
        except KeyboardInterrupt:
            print("Recording stopped")

        stream.stop_stream()
        stream.close()
        self.audio.terminate()

This class sets up audio recording with PyAudio, capturing audio in chunks that can be streamed to a WebSocket for real-time processing.

Step 3: Implement WebSocket Communication

Connect to Real-time AI Service

Next, we'll add WebSocket functionality to communicate with the AI service:

async def connect_websocket(self, uri):
    try:
        self.websocket = await websockets.connect(uri)
        print(f"Connected to {uri}")
        
        # Handle incoming audio responses
        async for message in self.websocket:
            # Process the AI-generated audio
            self.play_audio_response(message)
    except Exception as e:
        print(f"WebSocket error: {e}")

async def send_audio_to_ai(self, audio_data):
    if self.websocket:
        await self.websocket.send(audio_data)
        
    # Receive AI response
    response = await self.websocket.recv()
    return response

The WebSocket connection allows for low-latency communication with the AI service, enabling real-time interaction without waiting for full audio chunks.

Step 4: Integrate Speech Recognition and Synthesis

Handle Text-to-Speech Conversion

Now we'll add speech recognition and text-to-speech capabilities:

import speech_recognition as sr
from gtts import gTTS
import io
import pygame


def transcribe_audio(self, audio_file):
    recognizer = sr.Recognizer()
    with sr.AudioFile(audio_file) as source:
        audio = recognizer.record(source)
    try:
        text = recognizer.recognize_google(audio)
        return text
    except sr.UnknownValueError:
        return "Could not understand audio"

def text_to_speech(self, text):
    tts = gTTS(text=text, lang='en', slow=False)
    audio_buffer = io.BytesIO()
    tts.write_to_fp(audio_buffer)
    audio_buffer.seek(0)
    return audio_buffer

This integration allows us to convert spoken audio to text for processing and generate natural-sounding responses using text-to-speech.

Step 5: Create the Main Interaction Loop

Build Continuous Conversation Flow

async def main_conversation_loop(self):
    # Connect to AI service
    await self.connect_websocket("wss://your-ai-service.com/voice")
    
    # Start recording
    recording_thread = threading.Thread(target=self.start_recording)
    recording_thread.start()
    
    # Simulate AI interaction
    while True:
        # Get user input
        user_input = input("You: ")
        
        # Send to AI
        ai_response = await self.send_to_ai(user_input)
        
        # Convert to speech
        audio_response = self.text_to_speech(ai_response)
        
        # Play response
        self.play_audio_response(audio_response)
        
        # Continue conversation
        if user_input.lower() in ['quit', 'exit']:
            break

This loop creates the turn-based conversation flow, where user input is processed by the AI and responses are played back in real-time.

Step 6: Add Latency Optimization

Implement Buffer Management

class OptimizedVoiceProcessor(VoiceAIProcessor):
    def __init__(self, api_key):
        super().__init__(api_key)
        self.audio_buffer = []
        self.buffer_size = 5  # Process every 5 chunks
        
    def process_audio_chunks(self, audio_data):
        self.audio_buffer.append(audio_data)
        
        if len(self.audio_buffer) >= self.buffer_size:
            # Send batch for processing
            batch = b''.join(self.audio_buffer)
            self.send_audio_to_ai(batch)
            self.audio_buffer.clear()
            
    def start_optimized_recording(self):
        stream = self.audio.open(
            format=self.format,
            channels=self.channels,
            rate=self.rate,
            input=True,
            frames_per_buffer=self.chunk
        )

        try:
            while self.recording:
                data = stream.read(self.chunk)
                self.process_audio_chunks(data)
        except KeyboardInterrupt:
            print("Recording stopped")

This optimization reduces processing overhead by batching audio chunks, which significantly improves the system's responsiveness.

Summary

You've now built a foundation for a real-time voice AI system that mimics the capabilities described in OpenAI's GPT-Live. This system features continuous audio capture, WebSocket communication, speech recognition, and text-to-speech conversion. The key improvements include low-latency architecture through batched processing and continuous conversation flow. While this tutorial provides the core components, production systems would require additional features like noise filtering, better error handling, and more sophisticated AI integration.

Remember to replace the WebSocket URI with your actual AI service endpoint and ensure your OpenAI API key is properly configured for full functionality.

Source: OpenAI Blog

Related Articles