summaryrefslogtreecommitdiffstats
path: root/nixos/tests/marytts.nix
blob: d6b880099d25cd677fd1a7426b7b912bea3dcb8d (plain)
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
84
85
{ lib, ... }:
let
  port = 59126;
in
{
  name = "marytts";
  meta.maintainers = with lib.maintainers; [ pluiedev ];

  nodes.machine =
    { pkgs, ... }:
    {
      networking.firewall.enable = false;
      networking.useDHCP = false;

      services.marytts = {
        enable = true;
        inherit port;

        voices = [
          (pkgs.fetchzip {
            url = "https://github.com/marytts/voice-bits1-hsmm/releases/download/v5.2/voice-bits1-hsmm-5.2.zip";
            hash = "sha256-1nK+qZxjumMev7z5lgKr660NCKH5FDwvZ9sw/YYYeaA=";
          })
        ];

        userDictionaries = [
          (pkgs.writeTextFile {
            name = "userdict-en_US.txt";
            destination = "/userdict-en_US.txt";
            text = ''
              amogus | @ - ' m @U - g @ s
              Nixpkgs | n I k s - ' p { - k @ - dZ @ s
            '';
          })
        ];
      };
    };

  testScript = ''
    from xml.etree import ElementTree
    from urllib.parse import urlencode

    machine.wait_for_unit("marytts.service")

    with subtest("Checking health of MaryTTS server"):
      machine.wait_for_open_port(${toString port})
      assert 'Mary TTS server' in machine.succeed("curl 'localhost:${toString port}/version'")

    with subtest("Generating example MaryXML"):
      query = urlencode({
        'datatype': 'RAWMARYXML',
        'locale': 'en_US',
      })
      xml = machine.succeed(f"curl 'localhost:${toString port}/exampletext?{query}'")
      root = ElementTree.fromstring(xml)
      text = " ".join(root.itertext()).strip()
      assert text == "Welcome to the world of speech synthesis!"

    with subtest("Detecting custom voice"):
      assert "bits1-hsmm" in machine.succeed("curl 'localhost:${toString port}/voices'")

    with subtest("Finding user dictionary"):
      query = urlencode({
        'INPUT_TEXT': 'amogus',
        'INPUT_TYPE': 'TEXT',
        'OUTPUT_TYPE': 'PHONEMES',
        'LOCALE': 'en_US',
      })
      phonemes = machine.succeed(f"curl 'localhost:${toString port}/process?{query}'")
      phonemes_tree = ElementTree.fromstring(phonemes)
      print([i.get('ph') for i in phonemes_tree.iter('{http://mary.dfki.de/2002/MaryXML}t')])
      assert ["@ - ' m @U - g @ s"] == [i.get('ph') for i in phonemes_tree.iter('{http://mary.dfki.de/2002/MaryXML}t')]

    with subtest("Synthesizing"):
      query = urlencode({
        'INPUT_TEXT': 'Nixpkgs is a collection of over 100,000 software packages that can be installed with the Nix package manager.',
        'INPUT_TYPE': 'TEXT',
        'OUTPUT_TYPE': 'AUDIO',
        'AUDIO': 'WAVE_FILE',
        'LOCALE': 'en_US',
      })
      machine.succeed(f"curl 'localhost:${toString port}/process?{query}' -o ./audio.wav")
      machine.copy_from_machine("./audio.wav")
  '';
}