diff --git a/src/sounddiff/formats.py b/src/sounddiff/formats.py index 15564a5..2e03462 100644 --- a/src/sounddiff/formats.py +++ b/src/sounddiff/formats.py @@ -21,6 +21,15 @@ # Formats that require ffmpeg FFMPEG_FORMATS = {".mp3", ".aac", ".m4a", ".wma", ".opus"} +# Mapping for original format display names in metadata +FORMAT_DISPLAY_NAMES: dict[str, str] = { + ".mp3": "MP3", + ".aac": "AAC", + ".m4a": "AAC", + ".wma": "WMA", + ".opus": "Opus", +} + def _remove_if_exists(path: str) -> None: """Remove a file if it exists, silently ignoring missing files.""" @@ -100,6 +109,12 @@ def load_audio(path: str | Path) -> tuple[np.ndarray, AudioMetadata]: except RuntimeError as e: raise RuntimeError(f"Cannot read audio file: {original_filepath} ({e})") from e + if original_filepath != read_filepath: + ext = original_filepath.suffix.lower() + display_format = FORMAT_DISPLAY_NAMES.get(ext, ext.lstrip(".").upper()) + else: + display_format = info.format + try: file_size: int | None = original_filepath.stat().st_size except OSError: @@ -111,7 +126,7 @@ def load_audio(path: str | Path) -> tuple[np.ndarray, AudioMetadata]: sample_rate=sample_rate, channels=data.shape[1], bit_depth=_subtype_to_bits(info.subtype), - format_name=info.format, + format_name=display_format, frames=len(data), file_size=file_size, ) diff --git a/tests/test_formats.py b/tests/test_formats.py index 89bc58c..f87fb84 100644 --- a/tests/test_formats.py +++ b/tests/test_formats.py @@ -56,6 +56,35 @@ def test_frames_matches_data_length(self) -> None: data, meta = load_audio(FIXTURES_DIR / "sine_a.wav") assert meta.frames == len(data) + def test_transcoded_format_name_is_correct(self, tmp_path: Path) -> None: + """Verifies that transcoded files show their original format name, not WAV.""" + from unittest.mock import patch + + # 1. Creamos un archivo MP3 falso para pasar la validación de path.exists() + fake_mp3 = tmp_path / "test.mp3" + fake_mp3.write_text("fake audio content") + + # 2. Simulamos que ffmpeg existe y que la lectura del WAV temporal funciona + with ( + patch("sounddiff.formats.shutil.which", return_value="ffmpeg"), + patch("sounddiff.formats.subprocess.run"), + patch("sounddiff.formats.sf.info") as mock_info, + patch("sounddiff.formats.sf.read") as mock_read, + ): + # Configuramos el mock para simular lo que devolvería el WAV temporal + class MockInfo: + format = "WAV" + subtype = "PCM_16" + + mock_info.return_value = MockInfo() + mock_read.return_value = (np.zeros((100, 2), dtype=np.float64), 44100) + + # 3. Llamamos a tu función + _, meta = load_audio(fake_mp3) + + # 4. LA COMPROBACIÓN FINAL: Debe decir MP3 y no WAV + assert meta.format_name == "MP3" + def test_file_size_is_populated(self) -> None: _, meta = load_audio(FIXTURES_DIR / "sine_a.wav") assert meta.file_size is not None