improvisation-lab / scripts /pitch_detection_demo.py
atsushieee's picture
Upload folder using huggingface_hub
c1e08a0 verified
raw
history blame
4.01 kB
"""Script for demonstrating pitch detection functionality."""
import argparse
import time
import gradio as gr
from improvisation_lab.config import Config
from improvisation_lab.domain.analysis import PitchDetector
from improvisation_lab.domain.music_theory import Notes
from improvisation_lab.infrastructure.audio import (DirectAudioProcessor,
WebAudioProcessor)
def create_process_audio(pitch_detector: PitchDetector):
"""Create audio processing callback function.
Args:
pitch_detector: PitchDetector instance
Returns:
Callback function for processing audio data
"""
def process_audio(audio_data):
frequency = pitch_detector.detect_pitch(audio_data)
if frequency > 0: # voice detected
note_name = Notes.convert_frequency_to_note(frequency)
print(
f"\rFrequency: {frequency:6.1f} Hz | Note: {note_name:<5}",
end="",
flush=True,
)
else: # no voice detected
print("\rNo voice detected ", end="", flush=True)
return process_audio
def run_direct_audio_demo(config: Config):
"""Run pitch detection demo using microphone input.
Args:
config: Configuration object
"""
pitch_detector = PitchDetector(config.audio.pitch_detector)
mic_input = DirectAudioProcessor(
sample_rate=config.audio.sample_rate,
buffer_duration=config.audio.buffer_duration,
)
print("Starting pitch detection demo (Microphone)...")
print("Sing or hum a note!")
print("-" * 50)
try:
mic_input._callback = create_process_audio(pitch_detector)
mic_input.start_recording()
while True:
time.sleep(0.1)
except KeyboardInterrupt:
print("\nStopping...")
finally:
mic_input.stop_recording()
def run_web_audio_demo(config: Config):
"""Run pitch detection demo using Gradio interface.
Args:
config: Configuration object
"""
pitch_detector = PitchDetector(config.audio.pitch_detector)
audio_input = WebAudioProcessor(
sample_rate=config.audio.sample_rate,
buffer_duration=config.audio.buffer_duration,
)
print("Starting pitch detection demo (Gradio)...")
result = {"text": "No voice detected"}
def process_audio(audio_data):
frequency = pitch_detector.detect_pitch(audio_data)
if frequency > 0:
note_name = Notes.convert_frequency_to_note(frequency)
result["text"] = f"Frequency: {frequency:6.1f} Hz | Note: {note_name}"
else:
result["text"] = "No voice detected"
audio_input._callback = process_audio
def handle_audio(audio):
"""Handle audio input from Gradio."""
if audio is None:
return result["text"]
if not audio_input.is_recording:
audio_input.start_recording()
audio_input.process_audio(audio)
return result["text"]
interface = gr.Interface(
fn=handle_audio,
inputs=gr.Audio(
sources=["microphone"],
streaming=True,
type="numpy",
),
outputs=gr.Text(label="Detection Result"),
live=True,
title="Pitch Detection Demo",
allow_flagging="never",
stream_every=0.05,
)
interface.queue()
interface.launch(
share=False,
debug=True,
)
def main():
"""Run the pitch detection demo."""
parser = argparse.ArgumentParser(description="Run pitch detection demo")
parser.add_argument(
"--input",
choices=["direct", "web"],
default="web",
help="Input method (direct: microphone or web: browser)",
)
args = parser.parse_args()
config = Config()
if args.input == "web":
run_web_audio_demo(config)
else:
run_direct_audio_demo(config)
if __name__ == "__main__":
main()