diff --git a/funasr/utils/load_utils.py b/funasr/utils/load_utils.py index b689d65ec6..f9e702d0c9 100644 --- a/funasr/utils/load_utils.py +++ b/funasr/utils/load_utils.py @@ -133,10 +133,14 @@ def load_audio_text_image_video( if hasattr(data_or_path_or_list, "seek"): data_or_path_or_list.seek(0) import soundfile as sf - data_np, audio_fs = sf.read(data_or_path_or_list, dtype="float32") - data_or_path_or_list = torch.from_numpy(data_np).squeeze() - if data_or_path_or_list.ndim > 1 and kwargs.get("reduce_channels", True): - data_or_path_or_list = data_or_path_or_list.mean(-1) + data_np, audio_fs = sf.read( + data_or_path_or_list, dtype="float32", always_2d=True + ) + # Match torchaudio's [channels, samples] layout so resampling + # always operates on the sample axis, including retained channels. + data_or_path_or_list = torch.from_numpy(data_np.T) + if kwargs.get("reduce_channels", True): + data_or_path_or_list = data_or_path_or_list.mean(0) except: if hasattr(data_or_path_or_list, "seek"): data_or_path_or_list.seek(0) diff --git a/tests/test_load_audio_bytes.py b/tests/test_load_audio_bytes.py index d23ae04a71..107195394f 100644 --- a/tests/test_load_audio_bytes.py +++ b/tests/test_load_audio_bytes.py @@ -10,6 +10,7 @@ from unittest import mock import wave +import pytest import numpy as np @@ -89,6 +90,69 @@ def _free_format_mp3_bytes(): return bytes(data) +@pytest.mark.parametrize("without_torchaudio", [False, True]) +@pytest.mark.parametrize("as_file", [False, True], ids=["bytesio", "path"]) +@pytest.mark.parametrize("source_rate", [8000, 16000, 48000]) +@pytest.mark.parametrize("channels", [1, 2, 3]) +@pytest.mark.parametrize("reduce_channels", [False, True]) +def test_soundfile_channel_layout( + without_torchaudio, + as_file, + source_rate, + channels, + reduce_channels, + monkeypatch, + tmp_path, +): + import torch + + times = np.arange(source_rate // 10) / source_rate + samples = np.stack( + [np.sin(2 * np.pi * (440 + 220 * channel) * times) for channel in range(channels)], + axis=1, + ) + pcm = np.round(samples * 12000).astype("