File size: 2,414 Bytes
df66be8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import ast
import shutil
import subprocess
import tempfile
import unittest
from pathlib import Path

import numpy as np
import soundfile as sf
import torch

from fireredtts3 import reference_asr

APP_PATH = Path(__file__).parents[1] / "app.py"


class _FakeGradio:
    class Error(Exception):
        pass

    @staticmethod
    def Info(_message):
        return None


def _load_app_audio_function():
    tree = ast.parse(APP_PATH.read_text(encoding="utf-8"))
    function = next(
        node
        for node in tree.body
        if isinstance(node, ast.FunctionDef) and node.name == "_load_audio"
    )
    namespace = {
        "gr": _FakeGradio,
        "np": np,
        "sf": sf,
        "torch": torch,
        "decode_audio_with_ffmpeg": reference_asr.decode_audio_with_ffmpeg,
    }
    compiled = compile(ast.Module(body=[function], type_ignores=[]), APP_PATH, "exec")
    exec(compiled, namespace)  # noqa: S102 - executes trusted local application code
    return namespace["_load_audio"]


class AppAudioLoadingIntegrationTests(unittest.TestCase):
    @unittest.skipUnless(shutil.which("ffmpeg"), "FFmpeg is required for M4A coverage")
    def test_generate_speech_loads_an_m4a_reference_audio(self):
        load_audio = _load_app_audio_function()

        with tempfile.TemporaryDirectory() as tmpdir:
            wav_path = Path(tmpdir) / "reference.wav"
            m4a_path = Path(tmpdir) / "reference clip.m4a"
            time = np.arange(8000, dtype=np.float32) / 8000
            sf.write(wav_path, 0.25 * np.sin(2 * np.pi * 440 * time), 8000)
            subprocess.run(
                [
                    "ffmpeg",
                    "-nostdin",
                    "-loglevel",
                    "error",
                    "-y",
                    "-i",
                    str(wav_path),
                    "-c:a",
                    "aac",
                    str(m4a_path),
                ],
                check=True,
            )

            waveform, sampling_rate = load_audio(m4a_path, max_seconds=20.0)

        self.assertEqual(sampling_rate, 16000)
        self.assertEqual(waveform.ndim, 2)
        self.assertEqual(waveform.shape[0], 1)
        self.assertGreaterEqual(waveform.shape[1], 16000)
        self.assertLess(waveform.shape[1], 17000)
        self.assertLessEqual(float(waveform.abs().max()), 0.95)


if __name__ == "__main__":
    unittest.main()