Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
81b877a
feat: add Ruby binding boilerplate
KitaitiMakoto Aug 11, 2026
2f7f0bd
feat(ruby): add licenses
KitaitiMakoto Aug 11, 2026
cee062d
feat(ruby): change name
KitaitiMakoto Aug 11, 2026
b2c6d63
feat(ruby): move development depencies from Gemfile to *.gemspec
KitaitiMakoto Aug 11, 2026
45f7084
feat(ruby): add Gemfile.lock and vendor/bundle to .gitignore
KitaitiMakoto Aug 11, 2026
e5a87a3
feat(ruby): add Cargo.lock
KitaitiMakoto Aug 11, 2026
6fe087e
feat(ruby): add rubygems-tasks to development depencencies
KitaitiMakoto Aug 11, 2026
14f7331
feat(ruby): use rubygems-tasks instead of bundler/gem_tasks
KitaitiMakoto Aug 11, 2026
484a3fd
feat(ruby): remove needless scripts
KitaitiMakoto Aug 11, 2026
3c30c93
feat(ruby): use default settings for test task
KitaitiMakoto Aug 11, 2026
780fff8
feat(ruby): move rb_sys from dependency to development dependency
KitaitiMakoto Aug 11, 2026
4a197fd
feat(ruby): add Kar to development dependencies
KitaitiMakoto Aug 11, 2026
86b959a
feat(ruby): use kar to build Rust instead of rb_sys and rake-compiler
KitaitiMakoto Aug 11, 2026
540fb84
feat(ruby): remove rb_sys and rake-compiler from dependencies
KitaitiMakoto Aug 11, 2026
9c95f06
feat(ruby): add ebur128-stream create to dependencies
KitaitiMakoto Aug 11, 2026
17376b1
feat(ruby): install ebur128-stream
KitaitiMakoto Aug 11, 2026
2c82c4a
feat(ruby): update rb-sys-test-helpers
KitaitiMakoto Aug 11, 2026
945a4cf
feat(ruby): install rb-sys-test-helpers
KitaitiMakoto Aug 11, 2026
ed14ca6
feat(ruby): change crate name
KitaitiMakoto Aug 11, 2026
67441b3
feat(ruby): change Rust edition
KitaitiMakoto Aug 11, 2026
dcd89c0
ruby(feat): change dependency name
KitaitiMakoto Aug 11, 2026
bdeb557
feat(ruby): update crates
KitaitiMakoto Aug 11, 2026
a194f6a
feat(ruby): implement Analyzer.new
KitaitiMakoto Aug 11, 2026
2ff0fed
feat(ruby): add test for Analyzer.new
KitaitiMakoto Aug 11, 2026
c2d4626
feat(ruby): implement Analyzer#push_interleaved
KitaitiMakoto Aug 11, 2026
788c8c8
feat(ruby): add test for Analyzer#push_interleaved
KitaitiMakoto Aug 11, 2026
6473989
feat(ruby): add Report
KitaitiMakoto Aug 12, 2026
9da27ca
feat(ruby): define Analyzer#finalize
KitaitiMakoto Aug 12, 2026
a5d518e
feat(ruby): add test for Analyzer#finalize
KitaitiMakoto Aug 12, 2026
c2329bc
feat(ruby): define Analyzer#push_planar
KitaitiMakoto Aug 12, 2026
7bb795c
feat(ruby): add test for Analyzer#push_planar
KitaitiMakoto Aug 12, 2026
35e0a47
fix(ruby): respect engine's error
KitaitiMakoto Aug 12, 2026
c1c950a
feat(ruby): add test for Analyzer#push_interleaved
KitaitiMakoto Aug 12, 2026
3677f57
chore(ruby): set prefix for original ebur128-stream
KitaitiMakoto Aug 12, 2026
1f85331
chore(ruby): remove unnecessary member builder from Analyzer
KitaitiMakoto Aug 12, 2026
aacabad
feat(ruby): extract report module
KitaitiMakoto Aug 12, 2026
f84f965
feat(ruby): implement Report attributes
KitaitiMakoto Aug 12, 2026
a9becdc
feat(ruby): add test for Report
KitaitiMakoto Aug 12, 2026
e5eba5e
feat(ruby): customize Report#inspect
KitaitiMakoto Aug 12, 2026
86584ce
feat(ruby): define Report#deconstruct_keys
KitaitiMakoto Aug 12, 2026
0282b6c
chore(ruby): add test for Report#deconstruct_keys
KitaitiMakoto Aug 12, 2026
c2bc17a
chore(ruby): run cargo fmt
KitaitiMakoto Aug 12, 2026
7cfea5d
feat(ruby): don't use unreachable!
KitaitiMakoto Aug 12, 2026
5226c85
chore(ruby): refine error messages
KitaitiMakoto Aug 12, 2026
735da05
feat(ruby): enable ebur128-stream's normalize feature
KitaitiMakoto Aug 12, 2026
2c274d2
chore(ruby): extract parse_channels_arg
KitaitiMakoto Aug 12, 2026
a8552e9
feat(ruby): define Normalizer.new
KitaitiMakoto Aug 12, 2026
be67d2f
feat(ruby): add test for Normalizer.new
KitaitiMakoto Aug 12, 2026
15f9985
feat(ruby): add NormalizeReport
KitaitiMakoto Aug 12, 2026
1519d92
feat(ruby): implement Normalizer#normalize_in_place
KitaitiMakoto Aug 12, 2026
3ec129b
feat(ruby): add test for Normalizer#normalize_in_place
KitaitiMakoto Aug 12, 2026
76d6540
chore(ruby): extract Reportable module
KitaitiMakoto Aug 12, 2026
ebe87f8
feat(ruby): add NormalizeReport#deconstruct_keys and #inspect
KitaitiMakoto Aug 12, 2026
0cef907
feat(ruby): add test for NormalizeReport reportable
KitaitiMakoto Aug 12, 2026
5e2da43
chore(ruby): inspect false properly
KitaitiMakoto Aug 12, 2026
67fb4ea
chore(ruby): extract MemoryView
KitaitiMakoto Aug 12, 2026
2cde8e7
feat(ruby): use custom error
KitaitiMakoto Aug 13, 2026
11e269a
chore(ruby): use InterleavedSamples in push_interleaved
KitaitiMakoto Aug 13, 2026
e1444f0
chore(ruby): remove outdated comment
KitaitiMakoto Aug 13, 2026
6465322
chore(ruby): use RArray.to_vec()
KitaitiMakoto Aug 13, 2026
c18f575
chore(ruby): remove needless variable binding
KitaitiMakoto Aug 13, 2026
777c962
feat(ruby): introduce memory_view::Flags
KitaitiMakoto Aug 13, 2026
76efc4f
chore(ruby): introduce Error::Runtime and Argument
KitaitiMakoto Aug 13, 2026
c9cc4bd
feat(ruby): introduce PlanarSamples and support MemoryView for push_p…
KitaitiMakoto Aug 13, 2026
500f425
chore(ruby): change method name
KitaitiMakoto Aug 13, 2026
4aff603
chore(ruby): refactor InterleavedSamples::try_convert()
KitaitiMakoto Aug 13, 2026
c32b468
fix(ruby): try ideal MemoryView first
KitaitiMakoto Aug 13, 2026
3f09488
feat(ruby): refine MemoryView
KitaitiMakoto Aug 14, 2026
019925c
chore(ruby): Remove module qualification
KitaitiMakoto Aug 14, 2026
4b32177
fix(ruby): allow readonly MemoryView for InterleavedSamples
KitaitiMakoto Aug 14, 2026
dc208db
feat(ruby): add Numo::NArray Alternative to dev dependency
KitaitiMakoto Aug 14, 2026
89e97e6
test(ruby): add test for MemoryView
KitaitiMakoto Aug 14, 2026
96cfb4d
feat(ruby): wrap rb_memory_view_release by protect
KitaitiMakoto Aug 15, 2026
28c8924
docs(ruby): add comment on SEGV
KitaitiMakoto Aug 15, 2026
ebb023f
feat(ruby): enable simd feature
KitaitiMakoto Aug 15, 2026
6bbeaa6
refactor(ruby): extractd analyzer module
KitaitiMakoto Aug 15, 2026
87a6ff2
refactor(ruby): remove manual try_convert
KitaitiMakoto Aug 15, 2026
41ceb2e
refactor(ruby): use magnus::rb_sys::protect
KitaitiMakoto Aug 15, 2026
7a02d4c
refactor(ruby): use as_raw() instead of transmute()
KitaitiMakoto Aug 15, 2026
bedaa0b
feat(ruby): add snapshot module
KitaitiMakoto Aug 15, 2026
8d6afee
feat(ruby): add Analyzer::snapshot()
KitaitiMakoto Aug 15, 2026
84ef823
test(ruby): add test for Snapshot
KitaitiMakoto Aug 15, 2026
462d17d
feat(ruby): add Analyzer#reset
KitaitiMakoto Aug 15, 2026
2451785
test(ruby): add test for Analyzer#reset
KitaitiMakoto Aug 15, 2026
b0dd7a3
fix(ruby): call PlanarSamples::try_convert() explicitely to avoid SEGV
KitaitiMakoto Aug 15, 2026
34c963d
chore(ruby): remove unused useless assignment
KitaitiMakoto Aug 15, 2026
c24c453
refactor(ruby): use self instead of rb_self
KitaitiMakoto Aug 15, 2026
cbe9af0
refactor(ruby): add and use analyzer_mut()
KitaitiMakoto Aug 15, 2026
3556790
feat(ruby): add Analyzer#sample_rate and #samples_per_block
KitaitiMakoto Aug 15, 2026
20c19a5
style(ruby): format
KitaitiMakoto Aug 15, 2026
eb1b71a
feat(ruby): add Channels
KitaitiMakoto Aug 15, 2026
b0f74be
refactor(ruby): use Channels instead of parse_channels_arg()
KitaitiMakoto Aug 15, 2026
7b2b76c
chore(ruby): remove unsed function
KitaitiMakoto Aug 15, 2026
655ce92
refactor(ruby): extract Channel
KitaitiMakoto Aug 15, 2026
9bef4a7
feat(ruby): add Analyzer#channels
KitaitiMakoto Aug 15, 2026
d5e501f
feat(ruby): add Analyzer#modes
KitaitiMakoto Aug 15, 2026
7eb6b50
style(ruby): format
KitaitiMakoto Aug 15, 2026
bb913ae
test(ruby): add test for Analyzer#modes
KitaitiMakoto Aug 15, 2026
131136b
feat(ruby): add Reportable#==
KitaitiMakoto Aug 15, 2026
0b29e47
test(ruby): add test to see diff of Array and MemoryView
KitaitiMakoto Aug 15, 2026
05e80e5
chore(ruby): add sync_version task
KitaitiMakoto Aug 15, 2026
5a4c17a
fix(ruby): initialize MemoryView with 0
KitaitiMakoto Aug 16, 2026
a026464
feat(ruby): complete gemspec
KitaitiMakoto Aug 16, 2026
00bb83e
doc(ruby): add license files in gem package
KitaitiMakoto Aug 16, 2026
fa7383a
refactor(ruby): use Interleaved/PlanaerSamples as method argument
KitaitiMakoto Aug 16, 2026
75e8215
test(ruby): restore test for MemoryView
KitaitiMakoto Aug 16, 2026
f2ea5c4
chore(ruby): ignore documentation directroy
KitaitiMakoto Aug 16, 2026
94a573c
doc(ruby): add classes to RBS signature file
KitaitiMakoto Aug 16, 2026
9a402ab
feat(ruby): accept more MemoryView format
KitaitiMakoto Aug 18, 2026
063210a
refactor(ruby): Make consume_memory_view return MemoryView
KitaitiMakoto Aug 18, 2026
ba14128
reafactor(ruby): extract WritableSamples
KitaitiMakoto Aug 18, 2026
fe1203e
fix(ruby): swap expected and actual
KitaitiMakoto Aug 19, 2026
247db60
docs(ruby): complete README
KitaitiMakoto Aug 19, 2026
b7f0731
docs(ruby): add example scripts
KitaitiMakoto Aug 19, 2026
ff28bd5
test(ruby): extract TestAnalyzer
KitaitiMakoto Aug 19, 2026
88b70f2
feat(ruby): add ItemDesc feature to MemoryView
KitaitiMakoto Aug 20, 2026
ce1d336
feat(ruby): check MemoryView more strictly
KitaitiMakoto Aug 20, 2026
2473598
refactor(ruby): remove unnecessary lifetime
KitaitiMakoto Aug 20, 2026
f1cc86e
chore(ruby): update microphone example
KitaitiMakoto Aug 20, 2026
bca9032
refactor(ruby): remove needless method calls
KitaitiMakoto Aug 21, 2026
b9a79c5
doc(ruby): fix a typo
KitaitiMakoto Aug 21, 2026
e432948
refactor(ruby): use grey_knights::memory_view::ValidatedMemoryView in…
KitaitiMakoto Sep 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions bindings/ruby/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/.bundle/
/.yardoc
/_yardoc/
/coverage/
/doc/
/pkg/
/html/
/spec/reports/
/tmp/
*.bundle
*.so
*.o
*.a
mkmf.log
target/
Gemfile.lock
/vendor/bundle/
ext/ebur128_stream/.rustc_info.json
ext/ebur128_stream/release/
5 changes: 5 additions & 0 deletions bindings/ruby/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## [Unreleased]

## [0.1.0] - 2026-08-11

- Initial release
6 changes: 6 additions & 0 deletions bindings/ruby/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

source "https://rubygems.org"

# Specify your gem's dependencies in ebur128_stream.gemspec
gemspec
256 changes: 256 additions & 0 deletions bindings/ruby/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
# EBUR128Stream

A Ruby binding for [ebur128-stream][rust-impl], a streaming, zero-allocation EBU R128 loudness measurement in pure Rust.

## Installation

Install the gem and add to the application's Gemfile by executing:

```bash
bundle add ebur128_stream
```

If bundler is not being used to manage dependencies, install the gem by executing:

```bash
gem install ebur128_stream
```

## Usage

```ruby
require "ebur128_stream"

include EBUR128Stream

analyzer = Analyzer.new(
channels: [:left, :right],
sample_rate: 48_000,
modes: [:integrated, :true_peak]
)
analyzer.push_interleaved samples

report = analyzer.finalize
report.integrated_lufs # => -8.030723453035735
report.true_peak_dbtp # => 20.01377283514713
```

EBUR128Stream provides two main classes:

* [Analyzer](#analyzer) analyzes audio data and reports loudness.
* [Normalizer](#normalizer) analyzes audio data and applies the calibrated gain.

<a name="analyzer"></a>
### Analyzer

EBUR128Stream::Analyzer is a streaming EBU R128 loudness analyzer. It reads audio data and reports statistics such as integrated LUFS, dBTP.

It provides a streaming API, which means you can push chunks of audio data incrementally and get the current status (EBUR128Stream::Snapshot) and the final report (EBUR128Stream::Report).

### Initialization

First, initialize EBUR128Stream::Analyzer:

```ruby
analyzer = EBUR128Stream::Analyzer.new(
# Required. Supports :left, :right, :center, :left_surround, :right_surround, :lfe, :other.
channels: [:left, :right],

# Optional. Must be one of 22_050, 32_000, 44_100, 48_000, 88_200, 96_000, 192_000. Defaults to 48_000.
sample_rate: 48_000,

# Optional. Supports :integrated, :momentary, :short_term, :true_peak, :lra, :all. Defaults to [:all].
modes: [:all],

# Optional. Hint at audio length in seconds so that buffer is allocated first.
expected_duration: 60
)
```

See [Rust documentation](https://docs.rs/ebur128-stream/latest/ebur128_stream/struct.AnalyzerBuilder.html) for details on arguments.

### Pushing samples

Then, push audio samples to EBUR128Stream::Analyzer#push_interleaved or EBUR128Stream::Analyzer#push_planar as you get them:

```ruby
while samples = get_samples
analyzer.push_interleaved(samples)
# Or, analyzer.push_planar samples
end
```

Interleaved samples looks like this:

```ruby
[L1, R1, L2, R2, L3, R3, ...]
```

(*Note* that it's not a 2-D array (`[[L1, R1], [L2, R2], ...]`) but a flat array.)

Planar samples looks like this:

```ruby
[[L1, L2, L3, ...], [R1, R2, R3, ...]]
```

In addition to 1-D or 2-D `Array`s, EBUR128Stream::Analyzer#push_interleaved and EBUR128Stream::Analyzer#push_planar accept MemoryView producers such as:

* `Gst::Sample` from [GStreamer][] gem
* `Torch::Tensor` from [TorchAudio][] or [TorchCodec][] gem (w/ [NDAV::TorchTensor][])
* `Numo::NArray` from [Numo::NArray][] or [Numo::NArray Alternative][] gem when generating and processing audio data with it (w/ [NDAV::Numo::NArray][])

TorchAudio example here:

```ruby
samples, sample_rate = TorchAudio.load("path/to/audio")
analyzer.push_planar(samples)
```

### Snapshots

At any point during streaming, you can get the current statistics (EBUR128Stream::Snapshot) by calling EBUR128Stream::Analyzer#snapshot:

```ruby
snapshot = analyzer.snapshot

snapshot.programme_duration_seconds #=> Current duration
snapshot.momentary_lufs #=> Loudness sliding 400ms window in LUFS
snapshot.short_term_lufs #=> Loudness sliding 3s window in LUFS
snapshot.integrated_lufs #=> Loudness so far in LUFS
snapshot.true_peak_dbtp #=> True peak so far in dBTP
snapshot.loudness_range_lu #=> Loudness range in LU
```

The attributes may be `nil` when there are not enough samples or when the corresponding mode was not specified at initialization.

EBUR128Stream::Snapshot implements `#to_h`:

```ruby
snapshot.to_h #=> {momentary_lufs: ..., short_term_lufs: ..., ...}
```

Also, `#deconstruct_keys` is implemented:

```ruby
snapshot.deconstruct_keys(nil) #=> {momentary_lufs: ..., short_term_lufs: ..., ...}

case analyzer.snapshot
in EBUR128Stream::Snapshot[true_peak_dbtp: 1.0..] => snapshot
$stderr.puts "High true peak found at #{snapshot.programme_duration_seconds}s: #{snapshot.true_peak_dbtp} dBTP"
else
# noop
end
```

### Finalization

Finally, call EBUR128Stream::Analyzer#finalize to complete the analysis and get the report:

```ruby
report = analyzer.finalize

report.programme_duration_seconds #=> Total duration in seconds
report.integrated_lufs
report.loudness_range_lu
report.true_peak_dbtp
report.momentary_max_lufs #=> Maximum momentary loudness in LUFS
report.short_term_max_lufs #=> Maximum short term loudness in LUFS
```

EBUR128Stream::Report also implements `#to_h` and `#deconstruct_keys` like EBUR128Stream::Snapshot.

<a name="normalizer"></a>
### Normalizer

EBUR128Stream::Normalizer analyzes audio data and normalizes it to the target loudness in place.

#### Initialization

Initialize EBUR128Stream::Normalizer with target loudness.

```ruby
normalizer = EBUR128Stream::Normalizer.new(
# Required.
sample_rate: 48_000,

# Required.
channels: [:left, :right],

# Optional. Target loudness in LUFS. Defaults to -23.0.
target_lufs: -14.0,

# Optional. Cap the post-normalisation true peak at this dBTP value.
true_peak_ceiling_dbtp: -1.0,
)
```

#### Normalization

Pass interleaved samples to EBUR128Stream::Normalizer#normalize_in_place:

```ruby
report = normalizer.normalize_in_place(interleaved_samples)
```

*Note* that it modifies the passed `Array` in place as the method name implies.

This returns EBUR128Stream::NormalizeReport:

```ruby
report.measured_integrated_lufs #=> Measured integrated loudness before normalization.
report.measured_true_peak_dbtp # Measured true peak before normalization, in dBTP.
report.target_lufs #=> Target loudness, in LUFS.
report.true_peak_ceiling_dbtp #=> True peak ceiling in dBTP.
report.applied_gain_db #=> Gain that was actually applied in dB.
report.limited_by_true_peak #=> true if the gain was attenuated to honour the true peak ceiling.
```

EBUR128Stream::NormalizeReport also implements `#to_h` and `deconstruct_keys`.

Additionally, it accepts MemoryView as a `samples` argument. The MemoryView must be writable.

## Examples

Complete examples are available in the sample directory.

* sample/analyze-wavefile.rb - A basic example of analyzing audio from wave file using pure-Ruby [WaveFile][] gem.
* sample/analyze-microphone.rb - An example that displays microphone loudness in real time.
* sample/analyze-planar-data.rb - An example of analyzing planar audio data instead of interleaved data.
* sample/normalize.rb - An example of normalizing audio data to desired loudness and saving it to a file.

## Development

After checking out the repo, run `bundle install` to install dependencies. Then, run `bundle exec rake test` to run the tests. You can also run `bundle exec rake console` for an interactive prompt that will allow you to experiment.

To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/vanjamodrinjak21/ebur128_stream. Mention @KitaitiMakoto for issues and pull requests related to the Ruby binding.

## License

Licensed under either of

- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)

at your option.

## See also

* [Rust crate][rust-impl]
* [BS.1770][]

[rust-impl]: https://github.com/vanjamodrinjak21/ebur128-stream
[Analyzer]: rdoc-ref:EBUR128Stream::Analyzer
[BS.1770]: https://www.itu.int/rec/R-REC-BS.1770
[GStreamer]: https://github.com/ruby-gnome/ruby-gnome/tree/main/gstreamer
[TorchAudio]: https://github.com/ankane/torchaudio-ruby
[TorchCodec]: https://github.com/ankane/torchcodec-ruby
[Numo::NArray]: https://ruby-numo.github.io/numo-narray/
[Numo::NArray Alternative]: https://github.com/yoshoku/numo-narray-alt
[WaveFile]: https://wavefilegem.com/
[NDAV::TorchTensor]: https://gitlab.com/KitaitiMakoto/ndav-torch-tensor
[NDAV::Numo::NArray]: https://gitlab.com/KitaitiMakoto/ndav-numo-narray
31 changes: 31 additions & 0 deletions bindings/ruby/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

require "rubygems/tasks"
require "rake/testtask"
require "kar/dsl"
require "rdoc/task"

GEMSPEC = Gem::Specification.load("ebur128_stream.gemspec")

LICENSE_FILES = FileList["LICENSE-APACHE", "LICENSE-MIT"]
LICENSE_FILES.each do |license|
file license => "../../#{license}" do |t|
copy t.source, t.name
end
end

Gem::Tasks.new

cargo "ebur128_stream"

Rake::TestTask.new(test: :cargo)
RDoc::Task.new

task default: :test

task sync_version: ["lib/ebur128_stream/version.rb", "ext/ebur128_stream/Cargo.toml"] do |t|
require_relative t.sources[0]
sh "cargo", "set-version", "--manifest-path", t.sources[1], "--offline", EBUR128Stream::VERSION
end

task build: [:sync_version, :cargo] + LICENSE_FILES
50 changes: 50 additions & 0 deletions bindings/ruby/ebur128_stream.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

require_relative "lib/ebur128_stream/version"

Gem::Specification.new do |spec|
spec.name = "ebur128_stream"
spec.version = EBUR128Stream::VERSION
spec.authors = ["Kitaiti Makoto"]
spec.email = ["KitaitiMakoto@gmail.com"]
spec.licenses = ["Apache-2.0", "MIT"]

spec.summary = "Streaming, zero-allocation EBU R128 loudness measurement."
spec.description = "Ruby binding for Streaming, zero-allocation EBU R128 loudness measurement in pure Rust."
spec.homepage = "https://github.com/vanjamodrinjak21/ebur128-stream"
spec.required_ruby_version = ">= 3.2.0"
spec.metadata["allowed_push_host"] = "https://rubygems.org"
spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = "https://github.com/KitaitiMakoto/ebur128-stream/tree/main/bindings/ruby"
spec.metadata["changelog_uri"] = "https://github.com/KitaitiMakoto/ebur128-stream/tree/main/bindings/ruby/CHANGELOG.md"

# Uncomment the line below to require MFA for gem pushes.
# This helps protect your gem from supply chain attacks by ensuring
# no one can publish a new version without multi-factor authentication.
# See: https://guides.rubygems.org/mfa-requirement-opt-in/
# spec.metadata["rubygems_mfa_required"] = "true"

# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
gemspec = File.basename(__FILE__)
spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls|
ls.readlines("\x0", chomp: true)
end + ["LICENSE-APACHE", "LICENSE-MIT"]
spec.executables = spec.files.grep(%r{\Abin/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.extensions = ["ext/ebur128_stream/Cargo.toml"]

# Uncomment to register a new dependency of your gem
# spec.add_dependency "example-gem", "~> 1.0"

spec.add_development_dependency "irb"
spec.add_development_dependency "rake"
spec.add_development_dependency "test-unit"
spec.add_development_dependency "rubygems-tasks"
spec.add_development_dependency "kar"
spec.add_development_dependency "numo-narray-alt"
spec.add_development_dependency "ndav-numo-narray"

# For more information and examples about making a new gem, check out our
# guide at: https://guides.rubygems.org/make-your-own-gem/
end
Loading