Spaces:
Sleeping
Sleeping
| """Configuration module for audio settings and chord progressions.""" | |
| from dataclasses import dataclass, field | |
| from pathlib import Path | |
| import yaml | |
| class PitchDetectorConfig: | |
| """Configuration settings for pitch detection.""" | |
| sample_rate: int = 16000 | |
| hop_length: int = 512 | |
| decoder_mode: str = "local_argmax" | |
| threshold: float = 0.006 | |
| f0_min: int = 80 | |
| f0_max: int = 880 | |
| interp_uv: bool = False | |
| device: str = "cpu" | |
| class AudioConfig: | |
| """Configuration class for audio-related settings.""" | |
| sample_rate: int = 16000 | |
| buffer_duration: float = 0.3 | |
| note_duration: float = 1.0 | |
| pitch_detector: PitchDetectorConfig = field(default_factory=PitchDetectorConfig) | |
| def from_yaml(cls, yaml_data: dict) -> "AudioConfig": | |
| """Create AudioConfig instance from YAML data.""" | |
| config = cls( | |
| sample_rate=yaml_data.get("sample_rate", cls.sample_rate), | |
| buffer_duration=yaml_data.get("buffer_duration", cls.buffer_duration), | |
| note_duration=yaml_data.get("note_duration", cls.note_duration), | |
| ) | |
| if "pitch_detector" in yaml_data: | |
| pitch_detector_data = yaml_data["pitch_detector"] | |
| # The sample rate must be set explicitly | |
| # Use the sample rate specified in the audio config | |
| pitch_detector_data["sample_rate"] = config.sample_rate | |
| config.pitch_detector = PitchDetectorConfig(**pitch_detector_data) | |
| return config | |
| class IntervalPracticeConfig: | |
| """Configuration settings for interval practice.""" | |
| num_problems: int = 10 | |
| interval: int = 0 | |
| def from_yaml(cls, yaml_data: dict) -> "IntervalPracticeConfig": | |
| """Create IntervalPracticeConfig instance from YAML data.""" | |
| return cls( | |
| num_problems=yaml_data.get("num_problems", cls.num_problems), | |
| interval=yaml_data.get("interval", cls.interval), | |
| ) | |
| class PiecePracticeConfig: | |
| """Configuration settings for piece practice.""" | |
| selected_song: str = "fly_me_to_the_moon" | |
| chord_progressions: dict = field(default_factory=dict) | |
| def from_yaml(cls, yaml_data: dict) -> "PiecePracticeConfig": | |
| """Create PiecePracticeConfig instance from YAML data.""" | |
| return cls( | |
| selected_song=yaml_data.get("selected_song", cls.selected_song), | |
| chord_progressions=yaml_data.get( | |
| "chord_progressions", {cls.selected_song: []} | |
| ), | |
| ) | |
| class Config: | |
| """Application configuration handler.""" | |
| audio: AudioConfig | |
| interval_practice: IntervalPracticeConfig | |
| piece_practice: PiecePracticeConfig | |
| def __init__(self, config_path: str | Path = "config.yml"): | |
| """Initialize Config instance. | |
| Args: | |
| config_path: Path to YAML configuration file (default: 'config.yml'). | |
| """ | |
| self.config_path = Path(config_path) | |
| self._load_config() | |
| def _load_config(self): | |
| if self.config_path.exists(): | |
| with open(self.config_path, "r") as f: | |
| yaml_data = yaml.safe_load(f) | |
| self.audio = AudioConfig.from_yaml(yaml_data.get("audio", {})) | |
| self.interval_practice = IntervalPracticeConfig.from_yaml( | |
| yaml_data.get("interval_practice", {}) | |
| ) | |
| self.piece_practice = PiecePracticeConfig.from_yaml( | |
| yaml_data.get("piece_practice", {}) | |
| ) | |
| else: | |
| self.audio = AudioConfig() | |
| self.interval_practice = IntervalPracticeConfig() | |
| self.piece_practice = PiecePracticeConfig() | |
| self.piece_practice.chord_progressions = { | |
| # opening 4 bars of Fly Me to the Moon | |
| "fly_me_to_the_moon": [ | |
| ("A", "natural_minor", "A", "min7", 8), | |
| ("A", "natural_minor", "D", "min7", 8), | |
| ("C", "major", "G", "dom7", 8), | |
| ("C", "major", "C", "maj7", 4), | |
| ("F", "major", "C", "dom7", 4), | |
| ] | |
| } | |