1 /**
2 * KFR (http://kfrlib.com)
3 * Copyright (C) 2016 D Levin
4 * See LICENSE.txt for details
5 */
6
7 #include <kfr/base.hpp>
8 #include <kfr/dsp.hpp>
9 #include <kfr/io.hpp>
10
11 using namespace kfr;
12
main(int argc,char ** argv)13 int main(int argc, char** argv)
14 {
15 if (argc < 3)
16 {
17 println("Usage: ebu_test INPUT_IN_F32_RAW_FORMAT CHANNEL_NUMBER");
18 return 1;
19 }
20
21 // Prepare
22 FILE* f = fopen(argv[1], "rb");
23 const int channel_number = atoi(argv[2]);
24 if (channel_number < 1 || channel_number > 6)
25 {
26 println("Incorrect number of channels");
27 return 1;
28 }
29 fseek(f, 0, SEEK_END);
30 uintmax_t size = ftell(f);
31 fseek(f, 0, SEEK_SET);
32 if (size % (sizeof(float) * channel_number))
33 {
34 println("Incorrect file size");
35 return 1;
36 }
37
38 // Read file
39 const size_t length = size / (sizeof(float) * channel_number);
40 univector<float> interleaved(size / sizeof(float));
41 size_t read_len = fread(interleaved.data(), 1, size, f);
42 if (read_len != size)
43 {
44 println("Can't read file");
45 return 1;
46 }
47
48 // Deinterleave
49 univector<univector<float>> data(channel_number, univector<float>(length));
50 for (size_t ch = 0; ch < channel_number; ++ch)
51 {
52 for (size_t i = 0; i < length; ++i)
53 {
54 data[ch][i] = interleaved[i * channel_number + ch];
55 }
56 }
57
58 std::vector<Speaker> speakers;
59 switch (channel_number)
60 {
61 case 1:
62 speakers = { Speaker::Mono };
63 break;
64 case 2:
65 speakers = { Speaker::Left, Speaker::Right };
66 break;
67 case 3:
68 speakers = { Speaker::Left, Speaker::Right, Speaker::Center };
69 break;
70 case 4:
71 speakers = { Speaker::Left, Speaker::Right, Speaker::LeftSurround, Speaker::RightSurround };
72 break;
73 case 5:
74 speakers = { Speaker::Left, Speaker::Right, Speaker::Center, Speaker::LeftSurround,
75 Speaker::RightSurround };
76 break;
77 case 6:
78 speakers = { Speaker::Left, Speaker::Right, Speaker::Center,
79 Speaker::LeftSurround, Speaker::RightSurround, Speaker::Lfe };
80 break;
81 }
82
83 ebu_r128<float> loudness(48000, speakers);
84
85 float M, S, I, RL, RH;
86 float maxM = -HUGE_VALF, maxS = -HUGE_VALF;
87 for (size_t i = 0; i < length / loudness.packet_size(); i++)
88 {
89 std::vector<univector_ref<float>> channels;
90 for (size_t ch = 0; ch < channel_number; ++ch)
91 {
92 channels.push_back(data[ch].slice(i * loudness.packet_size(), loudness.packet_size()));
93 }
94 loudness.process_packet(channels);
95 loudness.get_values(M, S, I, RL, RH);
96 maxM = std::max(maxM, M);
97 maxS = std::max(maxS, S);
98 }
99
100 {
101 // For file-based measurements, the signal should be followed by at least 1.5 s of silence
102 std::vector<univector_dyn<float>> channels(channel_number,
103 univector_dyn<float>(loudness.packet_size()));
104 for (size_t i = 0; i < 15; ++i)
105 loudness.process_packet(channels);
106 float dummyM, dummyS, dummyI;
107 loudness.get_values(dummyM, dummyS, dummyI, RL, RH);
108 }
109
110 println(argv[1]);
111 println("M = ", M);
112 println("S = ", S);
113 println("I = ", I);
114 println("LRA = ", RH - RL);
115 println("maxM = ", maxM);
116 println("maxS = ", maxS);
117 println();
118
119 return 0;
120 }
121