about summary refs log tree commit homepage
path: root/test/test_rg_integration.rb
blob: b9ef2b93d98768acb87088a2c2b8b7a23a3a4aed (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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# -*- encoding: binary -*-
# Copyright (C) 2013, Eric Wong <normalperson@yhbt.net>
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
require './test/player_integration'
class TestRgIntegration < Minitest::Unit::TestCase
  include PlayerIntegration

  def tmp_pluck(len = 5)
    pluck = Tempfile.open(%w(pluck .flac))
    cmd = %W(sox -R -n -r44100 -c2 -C0 #{pluck.path} synth #{len} pluck)
    assert system(*cmd), cmd
    cmd = %W(metaflac
             --set-tag=REPLAYGAIN_TRACK_GAIN=-2
             --set-tag=REPLAYGAIN_ALBUM_GAIN=-3.0
             --set-tag=REPLAYGAIN_TRACK_PEAK=0.666
             --set-tag=REPLAYGAIN_ALBUM_PEAK=0.999
             #{pluck.path})
    assert system(*cmd), cmd
    [ pluck, len ]
  end

  def test_rg_changes_added
    s = client_socket
    pluck, len = tmp_pluck

    # create the default sink, as well as a dumper
    dumper = Tempfile.open(%w(dump .sox))
    dump_pid = Tempfile.new(%w(dump .pid))
    default_pid = default_sink_pid(s)
    dump_cmd = "echo $$ > #{dump_pid.path}; sox $SOXFMT - #{dumper.path}"
    s.send("sink ed dump active=true command='#{dump_cmd}'", Socket::MSG_EOR)
    assert_equal("OK", s.readpartial(666))

    # start playback!
    s.send("enq \"#{pluck.path}\"", Socket::MSG_EOR)
    assert_equal "OK", s.readpartial(666)

    # wait for playback to start
    yaml = cur = nil
    Timeout.timeout(5) do
      begin
        s.send("current", Socket::MSG_EOR)
        cur = YAML.load(yaml = s.readpartial(1666))
      end while cur["current_offset"] == 0 && sleep(0.01)
    end

    assert_nil cur["current"]["env"]["RGFX"]

    assert_equal DTAS::Format.new.rate * len, cur["current_expect"]

    wait_files_not_empty(dump_pid)
    pid = read_pid_file(dump_pid)

    check_gain = proc do |expect, mode|
      s.send("rg mode=#{mode}", Socket::MSG_EOR)
      assert_equal "OK", s.readpartial(666)
      Timeout.timeout(5) do
        begin
          s.send("current", Socket::MSG_EOR)
          cur = YAML.load(yaml = s.readpartial(3666))
        end while cur["current"]["env"]["RGFX"] !~ expect && sleep(0.01)
      end
      assert_match expect, cur["current"]["env"]["RGFX"]
    end

    check_gain.call(%r{vol -3dB}, "album_gain")
    check_gain.call(%r{vol -2dB}, "track_gain")
    check_gain.call(%r{vol 1\.3}, "track_peak")
    check_gain.call(%r{vol 1\.0}, "album_peak")

    s.send("rg preamp+=1", Socket::MSG_EOR)
    assert_equal "OK", s.readpartial(666)
    s.send("rg", Socket::MSG_EOR)
    rg = YAML.load(yaml = s.readpartial(3666))
    assert_equal 1, rg["preamp"]

    s.send("rg preamp-=1", Socket::MSG_EOR)
    assert_equal "OK", s.readpartial(666)
    s.send("rg", Socket::MSG_EOR)
    rg = YAML.load(yaml = s.readpartial(3666))
    assert_nil rg["preamp"]

    s.send("rg preamp=2", Socket::MSG_EOR)
    assert_equal "OK", s.readpartial(666)
    s.send("rg", Socket::MSG_EOR)
    rg = YAML.load(yaml = s.readpartial(3666))
    assert_equal 2, rg["preamp"]

    s.send("rg preamp-=0.3", Socket::MSG_EOR)
    assert_equal "OK", s.readpartial(666)
    s.send("rg", Socket::MSG_EOR)
    rg = YAML.load(yaml = s.readpartial(3666))
    assert_equal 1.7, rg["preamp"]

    s.send("rg preamp-=-0.3", Socket::MSG_EOR)
    assert_equal "OK", s.readpartial(666)
    s.send("rg", Socket::MSG_EOR)
    rg = YAML.load(yaml = s.readpartial(3666))
    assert_equal 2.0, rg["preamp"]

    s.send("rg preamp-=+0.3", Socket::MSG_EOR)
    assert_equal "OK", s.readpartial(666)
    s.send("rg", Socket::MSG_EOR)
    rg = YAML.load(yaml = s.readpartial(3666))
    assert_equal 1.7, rg["preamp"]

    dethrottle_decoder(s)

    # ensure we did not change audio length
    wait_pid_dead(pid, len)
    samples = `soxi -s #{dumper.path}`.to_i
    assert_equal cur["current_expect"], samples
    assert_equal `soxi -d #{dumper.path}`, `soxi -d #{pluck.path}`

    stop_playback(default_pid, s)
  end

  def test_rg_env_in_source
    s = client_socket
    s.preq("rg mode=album_gain")
    assert_equal "OK", s.readpartial(666)
    pluck, len = tmp_pluck
    cmd = DTAS::Source::SOURCE_DEFAULTS["command"]
    fifo = tmpfifo
    s.preq("source ed command='env > #{fifo}; #{cmd}'")
    assert_equal "OK", s.readpartial(666)
    s.preq("sink ed default command='cat >/dev/null' active=true")
    assert_equal "OK", s.readpartial(666)
    s.preq(%W(enq #{pluck.path}))
    assert_equal "OK", s.readpartial(666)

    rg = {}
    File.readlines(fifo).each do |line|
      line =~ /\AREPLAYGAIN_/ or next
      k, v = line.chomp!.split(/=/)
      rg[k] = v
    end
    expect = {
      "REPLAYGAIN_TRACK_GAIN" => "-2",
      "REPLAYGAIN_ALBUM_GAIN" => "-3.0",
      "REPLAYGAIN_TRACK_PEAK" => "0.666",
      "REPLAYGAIN_ALBUM_PEAK" => "0.999",
      "REPLAYGAIN_REFERENCE_LOUDNESS" => nil
    }
    assert_equal expect, rg
  end
end