import matplotlib.pyplot as plt
import numpy as np
import openai
import os
import pyaudio
import pyttsx3
import threading
import tkinter as tk
import queue
import wave
import whisper
from langchain import OpenAI, SQLDatabase
from langchain.agents.agent_toolkits import SQLDatabaseToolkit
from langchain.agents import create_sql_agent
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from tkinter import scrolledtext

AUDIO_FORMAT = pyaudio.paInt16
CHANNELS = 1
FRAME_RATE = 16000
CHUNK = 1024

# Get OpenAI API key
openai.api_key = os.environ["OPENAI_API_KEY"]

s2_password = "<password>"
s2_host = "<host>"
s2_db = "timeseries_db"
db = SQLDatabase.from_uri(f"mysql+pymysql://admin:{s2_password}@{s2_host}:3306/{s2_db}")

llm = OpenAI(
    model_name = "gpt-3.5-turbo-instruct",
    temperature = 0,
    verbose = False
)

toolkit = SQLDatabaseToolkit(db = db, llm = llm)

agent_executor = create_sql_agent(
    llm = OpenAI(
        model_name = "gpt-3.5-turbo-instruct",
        temperature = 0
    ),
    toolkit = toolkit,
    verbose = False
)

model = whisper.load_model("base.en")

# GUI class
class AudioRecorderGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("Audio Recorder")

        self.start_button = tk.Button(root, text = "Start Recording", command = self.start_recording)
        self.start_button.pack(pady = 10)

        self.stop_button = tk.Button(root, text = "Stop Recording", command = self.stop_recording, state = tk.DISABLED)
        self.stop_button.pack(pady = 5)

        self.exit_button = tk.Button(root, text = "Exit", command = self.exit_program)
        self.exit_button.pack(pady = 5)

        self.transcription_box = scrolledtext.ScrolledText(root, height = 5, width = 60)
        self.transcription_box.pack(padx = 10, pady = 10)

        self.recording_timer = None
        self.audio_filename = "audio_recording.wav"

        self.fig, self.ax = plt.subplots()
        self.canvas = FigureCanvasTkAgg(self.fig, master = self.root)
        self.canvas_widget = self.canvas.get_tk_widget()
        self.canvas_widget.pack(side = tk.TOP, fill = tk.BOTH, expand = 1)
        self.audio_array = np.array([])

        self.update_waveform = False

    def update_waveform_plot(self):
        while self.update_waveform and not self.stop_event.is_set():
            data = self.audio_queue.queue[-1] if not self.audio_queue.empty() else np.zeros(1024)
            self.audio_array = np.frombuffer(data, dtype = np.int16)
            self.ax.clear()
            self.ax.plot(self.audio_array, color = "r")
            self.ax.set_title("Real-Time Audio Waveform")
            self.ax.set_xlabel("Time (samples)")
            self.ax.set_ylabel("Amplitude")
            self.ax.set_ylim(-128, 128)
            self.ax.set_xlim(0, len(self.audio_array))
            self.canvas.draw()
            self.root.update()

    def speak_audio(self, text):
        engine = pyttsx3.init()
        engine.setProperty("voice", "english_us")
        engine.setProperty("rate", 150)
        engine.say(text)
        engine.runAndWait()
        engine.stop()

    def start_recording(self):
        self.transcription_box.delete(1.0, tk.END)
        self.stop_event = threading.Event()
        self.audio_queue = queue.Queue()

        self.record_thread = threading.Thread(target = self.record_audio)
        self.record_thread.start()

        self.recording_timer = self.root.after(20000, self.stop_recording)

        self.update_waveform = True
        self.update_waveform_plot_thread = threading.Thread(target = self.update_waveform_plot)
        self.update_waveform_plot_thread.start()
        
        self.start_button.config(state = tk.DISABLED)
        self.stop_button.config(state = tk.NORMAL)

    def stop_recording(self):
        if self.recording_timer:
            self.root.after_cancel(self.recording_timer)
            self.recording_timer = None

        self.stop_event.set()
        self.record_thread.join()

        transcription = self.transcribe_audio(self.audio_filename)
        self.transcription_box.insert(
            tk.END,
            "Transcription:\n" + transcription + "\n"
        )
        
        speak_thread = threading.Thread(target = self.speak_audio, args = (agent_executor.run(transcription),))
        speak_thread.start()

        self.start_button.config(state = tk.NORMAL)
        self.stop_button.config(state = tk.DISABLED)

    def record_audio(self):
        audio = pyaudio.PyAudio()
        stream = audio.open(
            format = AUDIO_FORMAT,
            channels = CHANNELS,
            rate = FRAME_RATE,
            input = True,
            frames_per_buffer = CHUNK
        )

        while not self.stop_event.is_set():
            data = stream.read(CHUNK)
            self.audio_queue.put(data)

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

        with wave.open(self.audio_filename, "wb") as wf:
            wf.setnchannels(CHANNELS)
            wf.setsampwidth(audio.get_sample_size(AUDIO_FORMAT))
            wf.setframerate(FRAME_RATE)
            wf.writeframes(b''.join(list(self.audio_queue.queue)))

    def transcribe_audio(self, filename):
        with open(filename, "rb") as audio_file:
            # transcript = openai.Audio.transcribe(
            #     model = "whisper-1",
            #     file = audio_file,
            #     language = "en"
            # )
            transcript = model.transcribe(filename)
            return transcript["text"].strip()

    def exit_program(self):
        self.root.destroy()

def main():
    root = tk.Tk()
    app = AudioRecorderGUI(root)
    root.mainloop()

if __name__ == "__main__":
    main()

langchain.agents.agent_toolkits.SQLDatabaseToolkit langchain.SQLDatabase.from_uri langchain.OpenAI
[((652, 740), 'langchain.SQLDatabase.from_uri', 'SQLDatabase.from_uri', (['f"""mysql+pymysql://admin:{s2_password}@{s2_host}:3306/{s2_db}"""'], {}), "(\n    f'mysql+pymysql://admin:{s2_password}@{s2_host}:3306/{s2_db}')\n", (672, 740), False, 'from langchain import OpenAI, SQLDatabase\n'), ((743, 816), 'langchain.OpenAI', 'OpenAI', ([], {'model_name': '"""gpt-3.5-turbo-instruct"""', 'temperature': '(0)', 'verbose': '(False)'}), "(model_name='gpt-3.5-turbo-instruct', temperature=0, verbose=False)\n", (749, 816), False, 'from langchain import OpenAI, SQLDatabase\n'), ((848, 882), 'langchain.agents.agent_toolkits.SQLDatabaseToolkit', 'SQLDatabaseToolkit', ([], {'db': 'db', 'llm': 'llm'}), '(db=db, llm=llm)\n', (866, 882), False, 'from langchain.agents.agent_toolkits import SQLDatabaseToolkit\n'), ((1073, 1102), 'whisper.load_model', 'whisper.load_model', (['"""base.en"""'], {}), "('base.en')\n", (1091, 1102), False, 'import whisper\n'), ((5634, 5641), 'tkinter.Tk', 'tk.Tk', ([], {}), '()\n', (5639, 5641), True, 'import tkinter as tk\n'), ((933, 991), 'langchain.OpenAI', 'OpenAI', ([], {'model_name': '"""gpt-3.5-turbo-instruct"""', 'temperature': '(0)'}), "(model_name='gpt-3.5-turbo-instruct', temperature=0)\n", (939, 991), False, 'from langchain import OpenAI, SQLDatabase\n'), ((1266, 1335), 'tkinter.Button', 'tk.Button', (['root'], {'text': '"""Start Recording"""', 'command': 'self.start_recording'}), "(root, text='Start Recording', command=self.start_recording)\n", (1275, 1335), True, 'import tkinter as tk\n'), ((1410, 1501), 'tkinter.Button', 'tk.Button', (['root'], {'text': '"""Stop Recording"""', 'command': 'self.stop_recording', 'state': 'tk.DISABLED'}), "(root, text='Stop Recording', command=self.stop_recording, state=\n    tk.DISABLED)\n", (1419, 1501), True, 'import tkinter as tk\n'), ((1571, 1626), 'tkinter.Button', 'tk.Button', (['root'], {'text': '"""Exit"""', 'command': 'self.exit_program'}), "(root, text='Exit', command=self.exit_program)\n", (1580, 1626), True, 'import tkinter as tk\n'), ((1705, 1756), 'tkinter.scrolledtext.ScrolledText', 'scrolledtext.ScrolledText', (['root'], {'height': '(5)', 'width': '(60)'}), '(root, height=5, width=60)\n', (1730, 1756), False, 'from tkinter import scrolledtext\n'), ((1937, 1951), 'matplotlib.pyplot.subplots', 'plt.subplots', ([], {}), '()\n', (1949, 1951), True, 'import matplotlib.pyplot as plt\n'), ((1974, 2019), 'matplotlib.backends.backend_tkagg.FigureCanvasTkAgg', 'FigureCanvasTkAgg', (['self.fig'], {'master': 'self.root'}), '(self.fig, master=self.root)\n', (1991, 2019), False, 'from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg\n'), ((2181, 2193), 'numpy.array', 'np.array', (['[]'], {}), '([])\n', (2189, 2193), True, 'import numpy as np\n'), ((2948, 2962), 'pyttsx3.init', 'pyttsx3.init', ([], {}), '()\n', (2960, 2962), False, 'import pyttsx3\n'), ((3237, 3254), 'threading.Event', 'threading.Event', ([], {}), '()\n', (3252, 3254), False, 'import threading\n'), ((3282, 3295), 'queue.Queue', 'queue.Queue', ([], {}), '()\n', (3293, 3295), False, 'import queue\n'), ((3326, 3368), 'threading.Thread', 'threading.Thread', ([], {'target': 'self.record_audio'}), '(target=self.record_audio)\n', (3342, 3368), False, 'import threading\n'), ((3562, 3612), 'threading.Thread', 'threading.Thread', ([], {'target': 'self.update_waveform_plot'}), '(target=self.update_waveform_plot)\n', (3578, 3612), False, 'import threading\n'), ((4496, 4513), 'pyaudio.PyAudio', 'pyaudio.PyAudio', ([], {}), '()\n', (4511, 4513), False, 'import pyaudio\n'), ((2467, 2502), 'numpy.frombuffer', 'np.frombuffer', (['data'], {'dtype': 'np.int16'}), '(data, dtype=np.int16)\n', (2480, 2502), True, 'import numpy as np\n'), ((4931, 4967), 'wave.open', 'wave.open', (['self.audio_filename', '"""wb"""'], {}), "(self.audio_filename, 'wb')\n", (4940, 4967), False, 'import wave\n'), ((2421, 2435), 'numpy.zeros', 'np.zeros', (['(1024)'], {}), '(1024)\n', (2429, 2435), True, 'import numpy as np\n')]