ebur128_stream 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +6 -0
- data/LICENSE-APACHE +201 -0
- data/LICENSE-MIT +21 -0
- data/README.md +256 -0
- data/Rakefile +31 -0
- data/ebur128_stream.gemspec +50 -0
- data/ext/ebur128_stream/Cargo.lock +359 -0
- data/ext/ebur128_stream/Cargo.toml +21 -0
- data/ext/ebur128_stream/build.rs +5 -0
- data/ext/ebur128_stream/src/analyzer.rs +159 -0
- data/ext/ebur128_stream/src/error.rs +57 -0
- data/ext/ebur128_stream/src/lib.rs +123 -0
- data/ext/ebur128_stream/src/normalize.rs +121 -0
- data/ext/ebur128_stream/src/report.rs +52 -0
- data/ext/ebur128_stream/src/samples.rs +209 -0
- data/ext/ebur128_stream/src/snapshot.rs +49 -0
- data/lib/ebur128_stream/version.rb +5 -0
- data/lib/ebur128_stream.rb +68 -0
- data/sample/analyze-microphone.rb +110 -0
- data/sample/analyze-planar-data.rb +38 -0
- data/sample/analyze-wavefile.rb +77 -0
- data/sample/normalize.rb +35 -0
- data/sig/ebur128_stream.rbs +69 -0
- data/test/helper.rb +18 -0
- data/test/test_analizer.rb +114 -0
- data/test/test_ebur128_stream.rb +13 -0
- data/test/test_normalize_report.rb +35 -0
- data/test/test_normalizer.rb +49 -0
- data/test/test_report.rb +34 -0
- data/test/test_snapshot.rb +36 -0
- metadata +177 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
|
2
|
+
# It is not intended for manual editing.
|
|
3
|
+
version = 4
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "aho-corasick"
|
|
7
|
+
version = "1.1.5"
|
|
8
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
+
checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"memchr",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[[package]]
|
|
15
|
+
name = "bindgen"
|
|
16
|
+
version = "0.72.1"
|
|
17
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
18
|
+
checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
|
|
19
|
+
dependencies = [
|
|
20
|
+
"bitflags",
|
|
21
|
+
"cexpr",
|
|
22
|
+
"clang-sys",
|
|
23
|
+
"itertools",
|
|
24
|
+
"proc-macro2",
|
|
25
|
+
"quote",
|
|
26
|
+
"regex",
|
|
27
|
+
"rustc-hash",
|
|
28
|
+
"shlex",
|
|
29
|
+
"syn",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[[package]]
|
|
33
|
+
name = "bitflags"
|
|
34
|
+
version = "2.13.1"
|
|
35
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
36
|
+
checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
|
|
37
|
+
|
|
38
|
+
[[package]]
|
|
39
|
+
name = "bytemuck"
|
|
40
|
+
version = "1.25.2"
|
|
41
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
42
|
+
checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797"
|
|
43
|
+
|
|
44
|
+
[[package]]
|
|
45
|
+
name = "cexpr"
|
|
46
|
+
version = "0.6.0"
|
|
47
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
48
|
+
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
|
49
|
+
dependencies = [
|
|
50
|
+
"nom",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
[[package]]
|
|
54
|
+
name = "cfg-if"
|
|
55
|
+
version = "1.0.4"
|
|
56
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
57
|
+
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
|
58
|
+
|
|
59
|
+
[[package]]
|
|
60
|
+
name = "clang-sys"
|
|
61
|
+
version = "1.9.1"
|
|
62
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
63
|
+
checksum = "157a8ba7b480713b56f4c09fd13fc3e0a22a5dfab8097ba61cbc5feef950788a"
|
|
64
|
+
dependencies = [
|
|
65
|
+
"glob",
|
|
66
|
+
"libc",
|
|
67
|
+
"libloading",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[[package]]
|
|
71
|
+
name = "ebur128-stream"
|
|
72
|
+
version = "0.1.0"
|
|
73
|
+
dependencies = [
|
|
74
|
+
"ebur128-stream 0.2.0",
|
|
75
|
+
"grey-knights",
|
|
76
|
+
"magnus",
|
|
77
|
+
"rb-sys",
|
|
78
|
+
"rb-sys-env",
|
|
79
|
+
"rb-sys-test-helpers",
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
[[package]]
|
|
83
|
+
name = "ebur128-stream"
|
|
84
|
+
version = "0.2.0"
|
|
85
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
86
|
+
checksum = "66e026ac32fee8397cdbaafee0030443af608d6c4832e590905b16c9450b7536"
|
|
87
|
+
dependencies = [
|
|
88
|
+
"bitflags",
|
|
89
|
+
"libm",
|
|
90
|
+
"wide",
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
[[package]]
|
|
94
|
+
name = "either"
|
|
95
|
+
version = "1.18.0"
|
|
96
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
97
|
+
checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34"
|
|
98
|
+
|
|
99
|
+
[[package]]
|
|
100
|
+
name = "glob"
|
|
101
|
+
version = "0.3.4"
|
|
102
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
103
|
+
checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b"
|
|
104
|
+
|
|
105
|
+
[[package]]
|
|
106
|
+
name = "grey-knights"
|
|
107
|
+
version = "0.1.0"
|
|
108
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
109
|
+
checksum = "4ddc9622bcf1fe8243d34e708e00e4b41ca627a385e1d0684df7ddbe79f1c663"
|
|
110
|
+
dependencies = [
|
|
111
|
+
"magnus",
|
|
112
|
+
"rb-sys",
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
[[package]]
|
|
116
|
+
name = "itertools"
|
|
117
|
+
version = "0.13.0"
|
|
118
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
119
|
+
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
|
120
|
+
dependencies = [
|
|
121
|
+
"either",
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
[[package]]
|
|
125
|
+
name = "lazy_static"
|
|
126
|
+
version = "1.5.0"
|
|
127
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
128
|
+
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
|
129
|
+
|
|
130
|
+
[[package]]
|
|
131
|
+
name = "libc"
|
|
132
|
+
version = "0.2.189"
|
|
133
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
134
|
+
checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
|
|
135
|
+
|
|
136
|
+
[[package]]
|
|
137
|
+
name = "libloading"
|
|
138
|
+
version = "0.8.9"
|
|
139
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
140
|
+
checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
|
|
141
|
+
dependencies = [
|
|
142
|
+
"cfg-if",
|
|
143
|
+
"windows-link",
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
[[package]]
|
|
147
|
+
name = "libm"
|
|
148
|
+
version = "0.2.16"
|
|
149
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
150
|
+
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
|
151
|
+
|
|
152
|
+
[[package]]
|
|
153
|
+
name = "magnus"
|
|
154
|
+
version = "0.8.2"
|
|
155
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
156
|
+
checksum = "3b36a5b126bbe97eb0d02d07acfeb327036c6319fd816139a49824a83b7f9012"
|
|
157
|
+
dependencies = [
|
|
158
|
+
"magnus-macros",
|
|
159
|
+
"rb-sys",
|
|
160
|
+
"rb-sys-env",
|
|
161
|
+
"seq-macro",
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
[[package]]
|
|
165
|
+
name = "magnus-macros"
|
|
166
|
+
version = "0.8.0"
|
|
167
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
168
|
+
checksum = "47607461fd8e1513cb4f2076c197d8092d921a1ea75bd08af97398f593751892"
|
|
169
|
+
dependencies = [
|
|
170
|
+
"proc-macro2",
|
|
171
|
+
"quote",
|
|
172
|
+
"syn",
|
|
173
|
+
]
|
|
174
|
+
|
|
175
|
+
[[package]]
|
|
176
|
+
name = "memchr"
|
|
177
|
+
version = "2.8.3"
|
|
178
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
179
|
+
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
|
180
|
+
|
|
181
|
+
[[package]]
|
|
182
|
+
name = "minimal-lexical"
|
|
183
|
+
version = "0.2.1"
|
|
184
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
185
|
+
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|
186
|
+
|
|
187
|
+
[[package]]
|
|
188
|
+
name = "nom"
|
|
189
|
+
version = "7.1.3"
|
|
190
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
191
|
+
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
|
192
|
+
dependencies = [
|
|
193
|
+
"memchr",
|
|
194
|
+
"minimal-lexical",
|
|
195
|
+
]
|
|
196
|
+
|
|
197
|
+
[[package]]
|
|
198
|
+
name = "proc-macro2"
|
|
199
|
+
version = "1.0.107"
|
|
200
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
201
|
+
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
|
|
202
|
+
dependencies = [
|
|
203
|
+
"unicode-ident",
|
|
204
|
+
]
|
|
205
|
+
|
|
206
|
+
[[package]]
|
|
207
|
+
name = "quote"
|
|
208
|
+
version = "1.0.47"
|
|
209
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
210
|
+
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
|
211
|
+
dependencies = [
|
|
212
|
+
"proc-macro2",
|
|
213
|
+
]
|
|
214
|
+
|
|
215
|
+
[[package]]
|
|
216
|
+
name = "rb-sys"
|
|
217
|
+
version = "0.9.130"
|
|
218
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
219
|
+
checksum = "02faf625bb10ba893e3ae620f19c9fb1b5f8fcae0fe4eb86bb3f2230fad75edb"
|
|
220
|
+
dependencies = [
|
|
221
|
+
"rb-sys-build",
|
|
222
|
+
]
|
|
223
|
+
|
|
224
|
+
[[package]]
|
|
225
|
+
name = "rb-sys-build"
|
|
226
|
+
version = "0.9.130"
|
|
227
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
228
|
+
checksum = "05be6f9c86fe5482808162826f6c047d093b3670582296c770de1d94f8066694"
|
|
229
|
+
dependencies = [
|
|
230
|
+
"bindgen",
|
|
231
|
+
"lazy_static",
|
|
232
|
+
"proc-macro2",
|
|
233
|
+
"quote",
|
|
234
|
+
"regex",
|
|
235
|
+
"shell-words",
|
|
236
|
+
"syn",
|
|
237
|
+
]
|
|
238
|
+
|
|
239
|
+
[[package]]
|
|
240
|
+
name = "rb-sys-env"
|
|
241
|
+
version = "0.2.3"
|
|
242
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
243
|
+
checksum = "cca7ad6a7e21e72151d56fe2495a259b5670e204c3adac41ee7ef676ea08117a"
|
|
244
|
+
|
|
245
|
+
[[package]]
|
|
246
|
+
name = "rb-sys-test-helpers"
|
|
247
|
+
version = "0.3.0"
|
|
248
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
249
|
+
checksum = "ccc637c53cad6a6b49ad51c5857c64e36bd70c955ffafe9dc9cc5bc9dd0b3b18"
|
|
250
|
+
dependencies = [
|
|
251
|
+
"rb-sys",
|
|
252
|
+
"rb-sys-env",
|
|
253
|
+
"rb-sys-test-helpers-macros",
|
|
254
|
+
]
|
|
255
|
+
|
|
256
|
+
[[package]]
|
|
257
|
+
name = "rb-sys-test-helpers-macros"
|
|
258
|
+
version = "0.3.0"
|
|
259
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
260
|
+
checksum = "b1c1fce35d9ac77a2745e539232fb82a75856675a5daf4ef8b1ca994d89f8b3f"
|
|
261
|
+
dependencies = [
|
|
262
|
+
"quote",
|
|
263
|
+
"syn",
|
|
264
|
+
]
|
|
265
|
+
|
|
266
|
+
[[package]]
|
|
267
|
+
name = "regex"
|
|
268
|
+
version = "1.13.1"
|
|
269
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
270
|
+
checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
|
|
271
|
+
dependencies = [
|
|
272
|
+
"aho-corasick",
|
|
273
|
+
"memchr",
|
|
274
|
+
"regex-automata",
|
|
275
|
+
"regex-syntax",
|
|
276
|
+
]
|
|
277
|
+
|
|
278
|
+
[[package]]
|
|
279
|
+
name = "regex-automata"
|
|
280
|
+
version = "0.4.18"
|
|
281
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
282
|
+
checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2"
|
|
283
|
+
dependencies = [
|
|
284
|
+
"aho-corasick",
|
|
285
|
+
"memchr",
|
|
286
|
+
"regex-syntax",
|
|
287
|
+
]
|
|
288
|
+
|
|
289
|
+
[[package]]
|
|
290
|
+
name = "regex-syntax"
|
|
291
|
+
version = "0.8.11"
|
|
292
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
293
|
+
checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
|
|
294
|
+
|
|
295
|
+
[[package]]
|
|
296
|
+
name = "rustc-hash"
|
|
297
|
+
version = "2.1.3"
|
|
298
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
299
|
+
checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
|
|
300
|
+
|
|
301
|
+
[[package]]
|
|
302
|
+
name = "safe_arch"
|
|
303
|
+
version = "0.7.4"
|
|
304
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
305
|
+
checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323"
|
|
306
|
+
dependencies = [
|
|
307
|
+
"bytemuck",
|
|
308
|
+
]
|
|
309
|
+
|
|
310
|
+
[[package]]
|
|
311
|
+
name = "seq-macro"
|
|
312
|
+
version = "0.3.6"
|
|
313
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
314
|
+
checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
|
|
315
|
+
|
|
316
|
+
[[package]]
|
|
317
|
+
name = "shell-words"
|
|
318
|
+
version = "1.1.1"
|
|
319
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
320
|
+
checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77"
|
|
321
|
+
|
|
322
|
+
[[package]]
|
|
323
|
+
name = "shlex"
|
|
324
|
+
version = "1.3.0"
|
|
325
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
326
|
+
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
|
327
|
+
|
|
328
|
+
[[package]]
|
|
329
|
+
name = "syn"
|
|
330
|
+
version = "2.0.119"
|
|
331
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
332
|
+
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
|
|
333
|
+
dependencies = [
|
|
334
|
+
"proc-macro2",
|
|
335
|
+
"quote",
|
|
336
|
+
"unicode-ident",
|
|
337
|
+
]
|
|
338
|
+
|
|
339
|
+
[[package]]
|
|
340
|
+
name = "unicode-ident"
|
|
341
|
+
version = "1.0.24"
|
|
342
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
343
|
+
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
|
344
|
+
|
|
345
|
+
[[package]]
|
|
346
|
+
name = "wide"
|
|
347
|
+
version = "0.7.33"
|
|
348
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
349
|
+
checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03"
|
|
350
|
+
dependencies = [
|
|
351
|
+
"bytemuck",
|
|
352
|
+
"safe_arch",
|
|
353
|
+
]
|
|
354
|
+
|
|
355
|
+
[[package]]
|
|
356
|
+
name = "windows-link"
|
|
357
|
+
version = "0.2.1"
|
|
358
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
359
|
+
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "ebur128-stream"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2024"
|
|
5
|
+
authors = ["Kitaiti Makoto <KitaitiMakoto@gmail.com>"]
|
|
6
|
+
publish = false
|
|
7
|
+
|
|
8
|
+
[lib]
|
|
9
|
+
crate-type = ["cdylib"]
|
|
10
|
+
|
|
11
|
+
[dependencies]
|
|
12
|
+
magnus = { version = "0.8.2", features = ["rb-sys"] }
|
|
13
|
+
rb-sys = { version = "0.9", features = ["stable-api-compiled-fallback"] }
|
|
14
|
+
ebur128-stream-rs = { package = "ebur128-stream", version = "0.2.0", features= ["normalize", "simd"] }
|
|
15
|
+
grey-knights = { version = "0.1.0" }
|
|
16
|
+
|
|
17
|
+
[build-dependencies]
|
|
18
|
+
rb-sys-env = "0.2.2"
|
|
19
|
+
|
|
20
|
+
[dev-dependencies]
|
|
21
|
+
rb-sys-test-helpers = { version = "0.3.0" }
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
use crate::{Channels, Error, InterleavedSamples, PlanarSamples, Report, Snapshot};
|
|
2
|
+
use ebur128_stream_rs as engine;
|
|
3
|
+
use magnus::{
|
|
4
|
+
Integer, Module, RArray, RModule, Ruby, Symbol, TryConvert, Value, function, method,
|
|
5
|
+
prelude::*,
|
|
6
|
+
scan_args::{get_kwargs, scan_args},
|
|
7
|
+
};
|
|
8
|
+
use std::{
|
|
9
|
+
cell::{Ref, RefCell, RefMut},
|
|
10
|
+
time::Duration,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
#[magnus::wrap(class = "EBUR128Stream::Analyzer")]
|
|
14
|
+
struct Analyzer {
|
|
15
|
+
analyzer: RefCell<Option<engine::Analyzer>>,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
impl Analyzer {
|
|
19
|
+
fn new(args: &[Value]) -> Result<Self, Error> {
|
|
20
|
+
let args = scan_args::<(), (), (), (), _, ()>(args)?;
|
|
21
|
+
let kws =
|
|
22
|
+
get_kwargs::<_, (Channels,), (Option<Integer>, Option<RArray>, Option<Integer>), ()>(
|
|
23
|
+
args.keywords,
|
|
24
|
+
&["channels"],
|
|
25
|
+
&["sample_rate", "modes", "expected_duration"],
|
|
26
|
+
)?;
|
|
27
|
+
let (channels,) = kws.required;
|
|
28
|
+
let (sample_rate, modes, expected_duration) = kws.optional;
|
|
29
|
+
|
|
30
|
+
let mut builder = engine::AnalyzerBuilder::new().channels(&channels);
|
|
31
|
+
|
|
32
|
+
if let Some(sample_rate) = sample_rate {
|
|
33
|
+
builder = builder.sample_rate(sample_rate.to_u32()?);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if let Some(values) = modes {
|
|
37
|
+
use engine::Mode;
|
|
38
|
+
|
|
39
|
+
let mut modes = Mode::empty();
|
|
40
|
+
for value in values.into_iter() {
|
|
41
|
+
let mode = Symbol::try_convert(value)?;
|
|
42
|
+
modes |= match mode.name()?.as_ref() {
|
|
43
|
+
"integrated" => Mode::Integrated,
|
|
44
|
+
"momentary" => Mode::Momentary,
|
|
45
|
+
"short_term" => Mode::ShortTerm,
|
|
46
|
+
"true_peak" => Mode::TruePeak,
|
|
47
|
+
"lra" => Mode::Lra,
|
|
48
|
+
"all" => Mode::All,
|
|
49
|
+
_ => {
|
|
50
|
+
return Err(Error::argument(format!("unknown mode: {mode}")))?;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
builder = builder.modes(modes);
|
|
55
|
+
}
|
|
56
|
+
if let Some(expected_duration) = expected_duration {
|
|
57
|
+
builder = builder.expected_duration(Duration::from_secs(expected_duration.to_u64()?));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let analyzer = builder.build().map_err(Error::runtime)?;
|
|
61
|
+
|
|
62
|
+
Ok(Self {
|
|
63
|
+
analyzer: RefCell::new(Some(analyzer)),
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
fn sample_rate(&self) -> Result<u32, Error> {
|
|
68
|
+
Ok(self.analyzer()?.sample_rate())
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fn channels(ruby: &Ruby, rb_self: &Self) -> Result<RArray, Error> {
|
|
72
|
+
Ok(Channels::from(rb_self.analyzer()?.channels()).try_into_rarray(ruby)?)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
fn modes(ruby: &Ruby, rb_self: &Self) -> Result<RArray, Error> {
|
|
76
|
+
let syms = rb_self
|
|
77
|
+
.analyzer()?
|
|
78
|
+
.modes()
|
|
79
|
+
.iter_names()
|
|
80
|
+
.map(|mode| ruby.to_symbol(mode.0.to_lowercase()))
|
|
81
|
+
.collect::<Vec<Symbol>>();
|
|
82
|
+
Ok(ruby.ary_new_from_values(&syms))
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
fn samples_per_block(&self) -> Result<u32, Error> {
|
|
86
|
+
Ok(self.analyzer()?.samples_per_block())
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
fn push_interleaved(&self, samples: InterleavedSamples) -> Result<(), Error> {
|
|
90
|
+
Ok(self.analyzer_mut()?.push_interleaved(samples.as_slice())?)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
fn push_planar(&self, samples: PlanarSamples) -> Result<(), Error> {
|
|
94
|
+
Ok(self
|
|
95
|
+
.analyzer_mut()?
|
|
96
|
+
.push_planar(&samples.channel_slices())?)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
fn snapshot(&self) -> Result<Snapshot, Error> {
|
|
100
|
+
let snapshot = self.analyzer_mut()?.snapshot();
|
|
101
|
+
|
|
102
|
+
Ok(Snapshot { snapshot })
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
fn reset(&self) -> Result<(), Error> {
|
|
106
|
+
self.analyzer_mut()?.reset();
|
|
107
|
+
|
|
108
|
+
Ok(())
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
fn finalize(&self) -> Result<Report, Error> {
|
|
112
|
+
let mut analyzer = self
|
|
113
|
+
.analyzer
|
|
114
|
+
.try_borrow_mut()
|
|
115
|
+
.map_err(|_| Error::runtime("analyzer already in use"))?;
|
|
116
|
+
let analyzer = analyzer
|
|
117
|
+
.take()
|
|
118
|
+
.ok_or_else(|| Error::runtime("analyzer already finalized"))?;
|
|
119
|
+
let report = analyzer.finalize();
|
|
120
|
+
|
|
121
|
+
Ok(Report { report })
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
fn analyzer<'a>(&'a self) -> Result<Ref<'a, engine::Analyzer>, Error> {
|
|
125
|
+
let analyzer = self
|
|
126
|
+
.analyzer
|
|
127
|
+
.try_borrow()
|
|
128
|
+
.map_err(|_| Error::runtime("analyzer already in use"))?;
|
|
129
|
+
|
|
130
|
+
Ref::filter_map(analyzer, Option::as_ref)
|
|
131
|
+
.map_err(|_| Error::runtime("analyzer not initialized"))
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
fn analyzer_mut<'a>(&'a self) -> Result<RefMut<'a, engine::Analyzer>, Error> {
|
|
135
|
+
let analyzer = self
|
|
136
|
+
.analyzer
|
|
137
|
+
.try_borrow_mut()
|
|
138
|
+
.map_err(|_| Error::runtime("analyzer already in use"))?;
|
|
139
|
+
|
|
140
|
+
RefMut::filter_map(analyzer, Option::as_mut)
|
|
141
|
+
.map_err(|_| Error::runtime("analyzer not initialized"))
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
pub(crate) fn init(ruby: &Ruby, module: &RModule) -> Result<(), Error> {
|
|
146
|
+
let analyzer = module.define_class("Analyzer", ruby.class_object())?;
|
|
147
|
+
analyzer.define_singleton_method("new", function!(Analyzer::new, -1))?;
|
|
148
|
+
analyzer.define_method("sample_rate", method!(Analyzer::sample_rate, 0))?;
|
|
149
|
+
analyzer.define_method("channels", method!(Analyzer::channels, 0))?;
|
|
150
|
+
analyzer.define_method("modes", method!(Analyzer::modes, 0))?;
|
|
151
|
+
analyzer.define_method("samples_per_block", method!(Analyzer::samples_per_block, 0))?;
|
|
152
|
+
analyzer.define_method("push_interleaved", method!(Analyzer::push_interleaved, 1))?;
|
|
153
|
+
analyzer.define_method("push_planar", method!(Analyzer::push_planar, 1))?;
|
|
154
|
+
analyzer.define_method("snapshot", method!(Analyzer::snapshot, 0))?;
|
|
155
|
+
analyzer.define_method("finalize", method!(Analyzer::finalize, 0))?;
|
|
156
|
+
analyzer.define_method("reset", method!(Analyzer::reset, 0))?;
|
|
157
|
+
|
|
158
|
+
Ok(())
|
|
159
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
use ebur128_stream_rs as engine;
|
|
2
|
+
use magnus::{Ruby, error::IntoError};
|
|
3
|
+
|
|
4
|
+
pub(crate) enum Error {
|
|
5
|
+
Magnus(magnus::Error),
|
|
6
|
+
Engine(engine::Error),
|
|
7
|
+
Runtime(String),
|
|
8
|
+
Argument(String),
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
impl From<magnus::Error> for Error {
|
|
12
|
+
fn from(err: magnus::Error) -> Self {
|
|
13
|
+
Self::Magnus(err)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
impl From<engine::Error> for Error {
|
|
18
|
+
fn from(err: engine::Error) -> Self {
|
|
19
|
+
Self::Engine(err)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
impl IntoError for Error {
|
|
24
|
+
fn into_error(self, ruby: &Ruby) -> magnus::Error {
|
|
25
|
+
match self {
|
|
26
|
+
Self::Magnus(err) => err,
|
|
27
|
+
Self::Engine(err) => {
|
|
28
|
+
let err_class = match err {
|
|
29
|
+
engine::Error::InterleavedLengthNotMultiple {
|
|
30
|
+
samples: _,
|
|
31
|
+
channels: _,
|
|
32
|
+
}
|
|
33
|
+
| engine::Error::ChannelMismatch {
|
|
34
|
+
expected: _,
|
|
35
|
+
got: _,
|
|
36
|
+
}
|
|
37
|
+
| engine::Error::PlanarLengthMismatch { first: _, got: _ }
|
|
38
|
+
| engine::Error::NonFiniteSample => ruby.exception_arg_error(),
|
|
39
|
+
_ => ruby.exception_runtime_error(),
|
|
40
|
+
};
|
|
41
|
+
magnus::Error::new(err_class, err.to_string())
|
|
42
|
+
}
|
|
43
|
+
Self::Runtime(msg) => magnus::Error::new(ruby.exception_runtime_error(), msg),
|
|
44
|
+
Self::Argument(msg) => magnus::Error::new(ruby.exception_arg_error(), msg),
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
impl Error {
|
|
50
|
+
pub(crate) fn runtime<T: ToString>(err: T) -> Self {
|
|
51
|
+
Self::Runtime(err.to_string())
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
pub(crate) fn argument<T: ToString>(err: T) -> Self {
|
|
55
|
+
Self::Argument(err.to_string())
|
|
56
|
+
}
|
|
57
|
+
}
|