Spaces:
Running
on
Zero
Running
on
Zero
| """ | |
| Utility functions for ACE-Step application | |
| """ | |
| import logging | |
| import yaml | |
| from pathlib import Path | |
| from typing import Dict, Any | |
| import sys | |
| def setup_logging(log_level: str = "INFO") -> logging.Logger: | |
| """ | |
| Setup logging configuration. | |
| Args: | |
| log_level: Logging level | |
| Returns: | |
| Logger instance | |
| """ | |
| # Create logs directory | |
| log_dir = Path("logs") | |
| log_dir.mkdir(exist_ok=True) | |
| # Setup logging | |
| logging.basicConfig( | |
| level=getattr(logging, log_level), | |
| format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', | |
| handlers=[ | |
| logging.FileHandler(log_dir / "ace_step.log"), | |
| logging.StreamHandler(sys.stdout) | |
| ] | |
| ) | |
| logger = logging.getLogger("ace_step") | |
| logger.info("Logging initialized") | |
| return logger | |
| def load_config(config_path: str = "config.yaml") -> Dict[str, Any]: | |
| """ | |
| Load configuration from YAML file. | |
| Args: | |
| config_path: Path to config file | |
| Returns: | |
| Configuration dictionary | |
| """ | |
| config_file = Path(config_path) | |
| if config_file.exists(): | |
| with open(config_file, 'r') as f: | |
| config = yaml.safe_load(f) | |
| else: | |
| # Default configuration | |
| config = { | |
| "checkpoint_dir": "./checkpoints", | |
| "dit_model_path": "acestep-v15-turbo", | |
| "lm_model_path": "acestep-5Hz-lm-1.7B", | |
| "model_path": "ACE-Step/ACE-Step-v1-3.5B", | |
| "sample_rate": 44100, | |
| "output_dir": "outputs", | |
| "timeline_dir": "timelines", | |
| "training_dir": "lora_training", | |
| "chunk_duration": 30, | |
| "force_mono": False, | |
| "device": "auto", | |
| "use_flash_attention": False, | |
| "offload_to_cpu": False | |
| } | |
| # Save default config | |
| with open(config_file, 'w') as f: | |
| yaml.dump(config, f, default_flow_style=False) | |
| return config | |
| def format_duration(seconds: float) -> str: | |
| """ | |
| Format duration in seconds to human-readable string. | |
| Args: | |
| seconds: Duration in seconds | |
| Returns: | |
| Formatted string (e.g., "2:30") | |
| """ | |
| minutes = int(seconds // 60) | |
| secs = int(seconds % 60) | |
| return f"{minutes}:{secs:02d}" | |
| def validate_audio_file(file_path: str) -> bool: | |
| """ | |
| Validate audio file. | |
| Args: | |
| file_path: Path to audio file | |
| Returns: | |
| True if valid, False otherwise | |
| """ | |
| import torchaudio | |
| try: | |
| audio, sr = torchaudio.load(file_path) | |
| return True | |
| except: | |
| return False | |
| def get_audio_info(file_path: str) -> Dict[str, Any]: | |
| """ | |
| Get audio file information. | |
| Args: | |
| file_path: Path to audio file | |
| Returns: | |
| Dictionary with audio info | |
| """ | |
| import torchaudio | |
| try: | |
| audio, sr = torchaudio.load(file_path) | |
| return { | |
| "duration": audio.shape[1] / sr, | |
| "sample_rate": sr, | |
| "channels": audio.shape[0], | |
| "samples": audio.shape[1], | |
| "format": Path(file_path).suffix | |
| } | |
| except Exception as e: | |
| return {"error": str(e)} | |
| def ensure_directories(): | |
| """Create necessary directories if they don't exist.""" | |
| dirs = ["outputs", "timelines", "lora_training", "logs", "models"] | |
| for dir_name in dirs: | |
| Path(dir_name).mkdir(exist_ok=True) | |