import os
import pyaudio
import openai
import soundfile as sf
import numpy as np
import base64
from pydub import AudioSegment
from pydub.utils import which, mediainfo, make_chunks, silence
from pydub.silence import detect_nonsilent

# set up OpenAI API key
openai.api_key = "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"

# set up audio stream
CHUNK = 2000
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 3000

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

# set up prompt
prompt = "Hello, how can I help you today?"

# check if ffmpeg exists in the system path or the pydub package can find it
if which("ffmpeg") is None:
    os.environ["PATH"] += os.pathsep + "/usr/local/bin/ffmpeg"

while True:
    # record audio from microphone
    frames = []
    for i in range(int(RATE / CHUNK * 5)):
        data = stream.read(CHUNK)
        frames.append(data)

    # convert audio to text using OpenAI API
    audio_data = b''.join(frames)
    audio_array = np.frombuffer(audio_data, dtype=np.int16)
    sf.write("input.wav", audio_array, RATE)

    audio = AudioSegment.from_wav("input.wav")

    try:
        audio.export("input.mp3", format="mp3", codec="libmp3lame")

        with open("input.mp3", "rb") as f:
            audio_bytes = f.read()

        # encode audio bytes as base64 string
        audio_base64 = base64.b64encode(audio_bytes).decode()

        response = openai.Completion.create(
            engine="davinci",
            prompt=prompt,
            audio=audio_base64,
            temperature=0.5,
            max_tokens=60,
            n=1,
            stop=None,
            timeout=10,
        )

        if "choices" in response and len(response["choices"]) > 0:
            response_audio_base64 = response["choices"][0]["audio"]
            response_audio = base64.b64decode(response_audio_base64)

            # detect silence in response audio and remove it
            response_audio = AudioSegment.from_file(
                response_audio, format="mp3")
            non_silent_audio = detect_nonsilent(response_audio, min_silence_len=50)[0]
            response_audio = response_audio[non_silent_audio[0]:non_silent_audio[1]]

            stream.write(response_audio.raw_data)
        else:
            print("Unexpected response format:", response)

    except Exception as e:
        print("Error:", e)

# stop audio stream
stream.stop_stream()
stream.close()
p.terminate()
