Wavify is a Ruby audio processing toolkit with immutable transforms, codec I/O, streaming pipelines, DSP effects, and a sequencing DSL.
- Ruby
>= 3.1 - Bundler
- Native build environment for gems with C extensions (
ogg-ruby,vorbis)
Add to your Gemfile:
gem "wavify"Then install:
bundle installOr install directly:
gem install wavifyrequire "wavify"
format = Wavify::Core::Format::CD_QUALITY
audio = Wavify::Audio.tone(
frequency: 440.0,
duration: 1.0,
waveform: :sine,
format: format
)
audio.fade_in(0.02).fade_out(0.05).write("tone.wav")Main constructors:
Audio.read(path, format: nil, codec_options: {})Audio.stream(path_or_io, chunk_size: 4096, format: nil, codec_options: {})Audio.tone(frequency:, duration:, waveform:, format:)Audio.silence(duration_seconds, format:)Audio.mix(*audios)
Immutable transforms (each also has ! in-place variants):
gain,normalize,trim,fade_in,fade_out,pan,reverse,loop,apply
Utility methods:
convert,split(at:),peak_amplitude,rms_amplitude,duration,sample_frame_count
Wavify::Audio.stream("input.wav", chunk_size: 4096)
.pipe(Wavify::Effects::Compressor.new(threshold: -18, ratio: 3.0))
.pipe(Wavify::Effects::Chorus.new(rate: 0.5, depth: 0.2, mix: 0.15))
.write_to("output.aiff", format: Wavify::Core::Format::CD_QUALITY)pipe accepts processors that respond to call, process, or apply.
| Format | Read | Write | Stream Read | Stream Write | Notes |
|---|---|---|---|---|---|
| WAV | ✅ | ✅ | ✅ | ✅ | PCM + float WAV, including extensible WAV |
| AIFF | ✅ | ✅ | ✅ | ✅ | PCM only (AIFC unsupported) |
| FLAC | ✅ | ✅ | ✅ | ✅ | Pure Ruby implementation |
| OGG Vorbis | ✅ | ✅ | ✅ | ✅ | Backed by ogg-ruby + vorbis |
| Raw PCM/Float | ✅* | ✅ | ✅* | ✅ | format: is required for read/stream-read/metadata |
Raw example:
raw_format = Wavify::Core::Format.new(channels: 2, sample_rate: 44_100, bit_depth: 16, sample_format: :pcm)
audio = Wavify::Audio.read("input.pcm", format: raw_format)
audio.write("output.wav")read/stream_readsupport sequential chained streams and interleaved multi-stream OGG.- Interleaved multi-stream decode is mixed into one output stream.
- If interleaved streams have different sample rates, they are resampled to the first logical stream's sample rate before mix.
decode_mode: :strictanddecode_mode: :placeholderare accepted for API compatibility.
Use Wavify.build for one-shot rendering/writing, or Wavify::DSL.build_definition when you want timeline access.
song = Wavify::DSL.build_definition(format: Wavify::Core::Format::CD_QUALITY, tempo: 116, default_bars: 2) do
track :kick do
synth :sine
notes "C2 . . . C2 . . .", resolution: 16
envelope attack: 0.001, decay: 0.05, sustain: 0.0, release: 0.06
gain(-4)
end
arrange do
section :intro, bars: 1, tracks: %i[kick]
end
end
timeline = song.timeline
mix = song.render
mix.write("song.wav")Built-in modules:
- Oscillator waveforms:
:sine,:square,:sawtooth,:triangle,:white_noise,:pink_noise - Envelope (ADSR)
- Biquad filters (lowpass/highpass/bandpass/notch/peaking/shelves)
- Effects:
Delay,Reverb,Chorus,Distortion,Compressor
Scripts in examples/:
examples/format_convert.rbexamples/audio_processing.rbexamples/synth_pad.rbexamples/drum_machine.rbexamples/chill_vibes.rbexamples/hybrid_arrangement.rbexamples/streaming_master_chain.rbexamples/cinematic_transition.rb
Run:
ruby examples/synth_pad.rbInstall dependencies:
bundle installRun tests:
bundle exec rspec
bundle exec rake spec:coverage COVERAGE_MINIMUM=90Generate/check docs:
bundle exec rake docs:examples
bundle exec rake docs:yard
YARD_MINIMUM=85 bundle exec rake docs:check
bundle exec rake docs:allBenchmarks:
bundle exec rake bench:wav_io
bundle exec rake bench:dsp
bundle exec rake bench:flac
bundle exec rake bench:stream
bundle exec rake bench:allRelease checks:
bundle exec rake release:checkWavify is released under the MIT License.