aider/aider/voice.py
Paul Gauthier 1f42b0839f aider: Fixed issue with passing the callback argument to the sd.rec function in record_and_transcribe function.
# Aider chat conversation:

USER: I ran this command:

 python -m aider.voice

And got this output:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/Users/gauthier/Projects/aider/aider/voice.py", line 42, in <module>
    print(record_and_transcribe(api_key))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/gauthier/Projects/aider/aider/voice.py", line 22, in record_and_transcribe
    recording = sd.rec(int(sample_rate * duration), samplerate=sample_rate, channels=1, callback=on_key_press)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/gauthier/Projects/aider/.venv/lib/python3.11/site-packages/sounddevice.py", line 276, in rec
    ctx.start_stream(InputStream, samplerate, ctx.input_channels,
TypeError: _CallbackContext.start_stream() got multiple values for argument 'callback'
Recording started, press any key to stop...

ASSISTANT: It seems like there's an issue with the way the `callback` argument is being passed to the `sd.rec` function in the `record_and_transcribe` function in the `aider/voice.py` file.

The `sd.rec` function is a convenience function that internally creates an instance of `sd.InputStream` and starts recording. The `callback` argument should be passed to the `sd.InputStream` constructor, not the `sd.rec` function.

Here's how we can fix this:

1. Modify the `aider/voice.py` file.

```python
aider/voice.py
<<<<<<< HEAD
    recording = sd.rec(int(sample_rate * duration), samplerate=sample_rate, channels=1, callback=on_key_press)
=======
    # Create an instance of InputStream with the callback
    stream = sd.InputStream(samplerate=sample_rate, channels=1, callback=on_key_press)
    stream.start()
    recording = sd.rec(int(sample_rate * duration), samplerate=sample_rate, channels=1)
>>>>>>> updated
```

This change creates an instance of `sd.InputStream` with the `on_key_press` callback and starts the stream before calling `sd.rec`. This should ensure that the callback is correctly passed to the `InputStream` and not the `rec` function.
2023-08-10 15:49:26 -03:00

45 lines
1.4 KiB
Python

import sounddevice as sd
import numpy as np
import keyboard
import openai
import io
import os
def record_and_transcribe(api_key):
# Set the sample rate and duration for the recording
sample_rate = 16000 # 16kHz
duration = 10 # in seconds
# Create a callback function to stop recording when a key is pressed
def on_key_press(e):
print("Key pressed, stopping recording...")
sd.stop()
# Start the recording
print("Recording started, press any key to stop...")
# Create an instance of InputStream with the callback
stream = sd.InputStream(samplerate=sample_rate, channels=1, callback=on_key_press)
stream.start()
recording = sd.rec(int(sample_rate * duration), samplerate=sample_rate, channels=1)
# Wait for a key press
keyboard.wait()
# Convert the recording to bytes
recording_bytes = io.BytesIO()
np.save(recording_bytes, recording, allow_pickle=False)
recording_bytes = recording_bytes.getvalue()
# Transcribe the audio using the Whisper API
response = openai.Whisper.asr.create(audio_data=recording_bytes)
# Return the transcription
return response['choices'][0]['text']
if __name__ == "__main__":
api_key = os.getenv('OPENAI_API_KEY')
if not api_key:
raise ValueError("Please set the OPENAI_API_KEY environment variable.")
print(record_and_transcribe(api_key))