Skip to content

Implement software resampling for microphone input - #431

Open
imatrisciano wants to merge 3 commits into
collabora:mainfrom
imatrisciano:main
Open

Implement software resampling for microphone input#431
imatrisciano wants to merge 3 commits into
collabora:mainfrom
imatrisciano:main

Conversation

@imatrisciano

Copy link
Copy Markdown

On some systems, audio recording can fail due to error -9997 (invalid sample rate) while trying to acquire the input audio device. This has been observed to happen on a desktop computer running Kubuntu 25.10 and a laptop running Ubuntu 24.04

To solve this issue, this PR introduces a fallback mechanism for client-side software resampling through librosa, whenever the audio input device does not natively support the needed 16kHz sample rate.

This PR also ensures that the microphone is only accessed if the record() method is invoked, and it is closed as soon as that method returns .

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses microphone acquisition failures on systems that can’t open an input device at 16kHz (e.g., PyAudio -9997) by adding a software-resampling fallback, and by deferring microphone access until record() is called (closing the stream when recording ends).

Changes:

  • Add an on-demand microphone open/close path with a fallback to the device’s default sample rate when 16kHz is unsupported.
  • Resample captured audio to 16kHz client-side (via librosa) before sending it over the websocket.
  • Update output WAV metadata and client requirements to reflect the new sampling-rate handling.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.

File Description
whisper_live/client.py Adds microphone open/close helpers, invalid-sample-rate fallback, and per-chunk software resampling before sending audio.
requirements/client.txt Adds librosa to client requirements.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread whisper_live/client.py
Comment thread whisper_live/client.py
Comment thread whisper_live/client.py
Comment thread whisper_live/client.py
Comment thread whisper_live/client.py
Comment thread whisper_live/client.py
Comment thread whisper_live/client.py
boxerab and others added 2 commits April 17, 2026 12:53
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@boxerab

boxerab commented Apr 17, 2026

Copy link
Copy Markdown
Collaborator

@copilot apply changes based on the comments in this thread

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.

Comment thread whisper_live/client.py
def _open_microphone(self):
self.microphoneSampleRate = self.targetSampleRate

def open_stream(self):
Comment thread whisper_live/client.py
)

try:
open_stream(self)
Comment thread whisper_live/client.py

try:
self.microphoneSampleRate = int(self.p.get_default_input_device_info()["defaultSampleRate"])
open_stream(self)
Comment thread whisper_live/client.py
Comment on lines +472 to +473
def _close_audio_stream(self):
"""Closes the audio stream and terminates the PyAudio instance."""
Comment thread whisper_live/client.py
Comment on lines 625 to +626
output_container = av.open(save_file, mode="w")
output_audio_stream = output_container.add_stream(codec_name="pcm_s16le", rate=self.rate)
output_audio_stream = output_container.add_stream(codec_name="pcm_s16le", rate=self.microphoneSampleRate)
Comment thread whisper_live/client.py
Comment on lines 724 to +725
# save frames if more than a minute
if len(self.frames) > 60 * self.rate:
if len(self.frames) > 60 * self.microphoneSampleRate:
Comment thread whisper_live/client.py
Comment on lines 732 to +735
except KeyboardInterrupt:
self.finalize_recording(n_audio_file)
finally:
self._close_microphone()
Comment thread whisper_live/client.py
Comment on lines +696 to +700
self._open_microphone()
if self.stream is None:
logging.error("Failed to open microphone stream; aborting recording.")
self.close_all_clients()
self.write_all_clients_srt()

@makaveli10 makaveli10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@makaveli10

makaveli10 commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

@imatrisciano can you please look into the copilot's review comments?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants