Source code for fmusvid.core.audio

"""
Audio class for FMUS-VID.

This module provides the Audio class for handling audio operations.
"""

from typing import Union, Optional, Dict, Any, Callable
from pathlib import Path
import logging

logger = logging.getLogger(__name__)

[docs] class Audio: """ Class for handling audio operations. This class provides methods for manipulating audio. """
[docs] def __init__(self, audio_data: Any, backend: Any): """ Initialize an Audio object. Args: audio_data: Backend-specific audio data backend: Backend instance """ self._audio_data = audio_data self._backend = backend
[docs] def save(self, path: Union[str, Path], **kwargs) -> None: """ Save audio to file. Args: path: Output file path **kwargs: Save options - codec: Audio codec (e.g., "mp3", "aac") - bitrate: Audio bitrate (e.g., "192k") Example: >>> audio.save("output.mp3", codec="mp3", bitrate="192k") """ self._backend.save_audio(self._audio_data, path, **kwargs)
[docs] def trim(self, start: float, end: Optional[float] = None) -> 'Audio': """ Trim audio to specified time range. Args: start: Start time in seconds end: End time in seconds (None means until the end) Returns: New Audio object Example: >>> intro = audio.trim(0, 10) # First 10 seconds """ new_audio_data = self._backend.trim_audio(self._audio_data, start, end) return Audio(new_audio_data, self._backend)
[docs] def volume(self, level: float) -> 'Audio': """ Set audio volume. Args: level: Volume level (1.0 = original, 0.5 = 50%, 2.0 = 200%) Returns: New Audio object Example: >>> quieter = audio.volume(0.8) # Reduce volume to 80% """ new_audio_data = self._backend.volume_audio(self._audio_data, level) return Audio(new_audio_data, self._backend)
[docs] def fade_in(self, duration: float) -> 'Audio': """ Add fade-in effect. Args: duration: Fade duration in seconds Returns: New Audio object Example: >>> with_fade = audio.fade_in(2) # 2-second fade in """ new_audio_data = self._backend.fade_in_audio(self._audio_data, duration) return Audio(new_audio_data, self._backend)
[docs] def fade_out(self, duration: float) -> 'Audio': """ Add fade-out effect. Args: duration: Fade duration in seconds Returns: New Audio object Example: >>> with_fade = audio.fade_out(2) # 2-second fade out """ new_audio_data = self._backend.fade_out_audio(self._audio_data, duration) return Audio(new_audio_data, self._backend)
[docs] def normalize(self, target_db: float = -3) -> 'Audio': """ Normalize audio levels. Args: target_db: Target peak level in dB Returns: New Audio object Example: >>> normalized = audio.normalize(-3) # Normalize to -3 dB """ new_audio_data = self._backend.normalize_audio(self._audio_data, target_db) return Audio(new_audio_data, self._backend)
[docs] def mix(self, other: 'Audio', weight: float = 0.5) -> 'Audio': """ Mix with another audio track. Args: other: Audio to mix with weight: Weight of the other audio (0.5 = equal mix) Returns: New Audio object Example: >>> mixed = voice.mix(music, weight=0.3) # Mix voice with background music """ new_audio_data = self._backend.mix_audio( self._audio_data, other._audio_data, weight ) return Audio(new_audio_data, self._backend)
[docs] def info(self) -> Dict[str, Any]: """ Get audio information. Returns: Dictionary with audio information - duration: Duration in seconds - channels: Number of channels - sample_rate: Sample rate in Hz - codec: Audio codec - bitrate: Audio bitrate Example: >>> info = audio.info() >>> print(f"Duration: {info['duration']} seconds") """ return self._backend.get_audio_info(self._audio_data)
[docs] def __repr__(self) -> str: """String representation of the Audio object.""" try: info = self.info() return (f"Audio(duration={info['duration']:.2f}s, " f"channels={info['channels']}, " f"sample_rate={info['sample_rate']}Hz)") except Exception: return "Audio(unknown info)"