Spaces:
Runtime error
Runtime error
import numpy as np | |
NOTE_FREQUENCIES = { | |
'C4': 261.63, # Middle C | |
'D4': 293.66, | |
'E4': 329.63, | |
'F4': 349.23, | |
'G4': 392.00, | |
'A4': 440.00, | |
'B4': 493.88, | |
'C5': 523.25 | |
} | |
# from pydub import AudioSegment | |
# import simpleaudio as sa | |
def generate_sine_wave(frequency, duration, sample_rate=44100, amplitude=0.5): | |
""" | |
Generate a sine wave for a given frequency, duration, and sample rate. | |
""" | |
t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False) | |
wave = amplitude * np.sin(2 * np.pi * frequency * t) | |
return wave | |
def apply_decay(wave, decay_factor=0.0001): | |
""" | |
Apply an exponential decay to the waveform to simulate the damping effect. | |
""" | |
decay = np.exp(-decay_factor * np.arange(len(wave))) | |
return wave * decay | |
def create_xylophone_note(frequency, duration=0.5, sample_rate=44100): | |
""" | |
Create a synthesized xylophone note using sine waves and damping. | |
""" | |
# Generate the fundamental frequency | |
wave = generate_sine_wave(frequency, duration, sample_rate) | |
# Add overtones (harmonics) to mimic the xylophone's metallic timbre | |
overtone1 = generate_sine_wave( | |
frequency * 2.5, duration, sample_rate, amplitude=0.3) | |
overtone2 = generate_sine_wave( | |
frequency * 4.0, duration, sample_rate, amplitude=0.2) | |
# Combine the fundamental frequency and overtones | |
combined_wave = wave + overtone1 + overtone2 | |
# Apply decay to simulate the note fading out | |
combined_wave = apply_decay(combined_wave) | |
# Normalize to 16-bit range and convert to audio segment | |
# audio_data = (combined_wave * 32767).astype(np.int16) | |
audio_data = combined_wave | |
return audio_data | |
# audio_segment = AudioSegment(audio_data.tobytes( | |
# ), frame_rate=sample_rate, sample_width=2, channels=1) | |
# return audio_segment | |
# def play_note(note): | |
# """ | |
# Play a given AudioSegment note using simpleaudio. | |
# """ | |
# play_obj = sa.play_buffer( | |
# note.raw_data, num_channels=1, bytes_per_sample=2, sample_rate=note.frame_rate) | |
# play_obj.wait_done() | |
def get_note(note: str) -> np.ndarray: | |
# Example usage to create and play a sequence of xylophone notes | |
return create_xylophone_note(NOTE_FREQUENCIES.get(note, 'C4')) | |
# Generate and play each note | |
# for note_name, frequency in note_frequencies.items(): | |
# print(f"Playing {note_name}") | |
# note = create_xylophone_note(frequency) | |
# play_note(note) | |