Project

beeps

0.0
A long-lived project that still receives updates
Synthesize and play beep sounds.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

~> 0.3.13
~> 0.3.13
 Project Readme

Beeps - Audio synthesis and playback library

Ask DeepWiki License Build Status Gem Version

⚠️ Notice

This repository is a read-only mirror of our monorepo. We do not accept pull requests or direct contributions here.

🔄 Where to Contribute?

All development happens in our xord/all monorepo, which contains all our main libraries. If you'd like to contribute, please submit your changes there.

For more details, check out our Contribution Guidelines.

Thanks for your support! 🙌

🚀 About

Beeps is an audio library for Ruby. You build a processor graph — oscillators, file / mic input, filters, envelopes, effects — by wiring nodes together with the >> operator, then render the result to a Sound and play it back.

It is part of the xord/* family and underlies the audio support in Reflex, Processing, RubySketch, and Reight. Like the rest of the family, it is primarily developed for our own use, but it works as a standalone audio synthesis gem.

📋 Requirements

  • Ruby 3.0.0 or later
  • A C++ compiler with C++20 support
  • Xot and Rucy (declared as runtime dependencies)
  • Platform audio backend:
    • macOS — OpenAL and AVFoundation (bundled with the OS)
    • Windows — OpenAL (MINGW_PACKAGE_PREFIX-openal) and Media Foundation
    • Linuxlibopenal-dev

The following third-party DSP libraries are cloned from GitHub and statically linked while the native extension is being built, so you do not need to install them separately:

Library Role
STK Core synthesis primitives
AudioFile WAV / AIFF file I/O
r8brain-free-src High-quality sample-rate conversion
signalsmith-stretch Time stretching and pitch shifting

📦 Installation

Add this line to your Gemfile:

gem 'beeps'

Then install:

$ bundle install

Or install it directly:

$ gem install beeps

require 'beeps' automatically calls Beeps.init! and registers Beeps.fin! at exit. Set $BEEPS_NOAUTOINIT = true before requiring if you want to manage the lifetime yourself.

📚 What's Included

Generators (signal sources)

Class Purpose
Beeps::Oscillator Sine / triangle / square / sawtooth / noise / sample-playback oscillator
Beeps::Value Constant or linearly-interpolated control value over time
Beeps::Sequencer Schedule processors at given offsets and durations
Beeps::FileIn Stream audio from a WAV / AIFF / other supported file
Beeps::MicIn Capture audio from a microphone
Beeps::TextIn Synthesize speech from text

Filters (processors that take an input)

Class Purpose
Beeps::Gain Multiply the signal by a gain coefficient
Beeps::Mixer Sum multiple inputs
Beeps::Envelope Attack / Decay / Sustain / Release envelope with note_on / note_off
Beeps::LowPass Low-pass filter with cutoff frequency
Beeps::HighPass High-pass filter with cutoff frequency
Beeps::Reverb Reverb with mix, room_size, damping controls
Beeps::TimeStretch Change duration without affecting pitch
Beeps::PitchShift Change pitch without affecting duration
Beeps::Analyser FFT analyser — exposes time-domain and spectrum readings

Playback

Class Purpose
Beeps::Sound A finite, renderable audio asset (created from a processor or load_sound)
Beeps::SoundPlayer Returned by Sound#play; supports pause, stop, position, loop, ...

💡 Usage

Play a 440 Hz sine tone for one second

require 'beeps'

osc    = Beeps::Oscillator.new(:sine, frequency: 440)
sound  = Beeps::Sound.new(osc, 1)
player = sound.play

sleep 1   # keep the script alive while the sound plays

Build a processor chain with >>

require 'beeps'

# oscillator -> half-volume -> low-pass at 800 Hz -> reverb
chain =
  Beeps::Oscillator.new(:sawtooth, frequency: 220) >>
  Beeps::Gain.new(0.5) >>
  Beeps::LowPass.new(cutoff: 800) >>
  Beeps::Reverb.new(mix: 0.3, room_size: 0.7)

Beeps::Sound.new(chain, 2).play
sleep 2

a >> b calls b.add_input(a) and returns b, so the right-most node is the head of the chain you pass to Sound.new.

ADSR envelope

require 'beeps'

osc = Beeps::Oscillator.new(:sine, frequency: 440)
env = Beeps::Envelope.new(0.05, 0.1, 0.7, 0.3, input: osc)
env.note_on
env.note_off 0.5    # release after 0.5 s

Beeps::Sound.new(env, 1).play
sleep 1

Play and save a wave file

require 'beeps'

# play an existing file
player = Beeps.load_sound('drum.wav').play

# render a chain and save it to disk
sound = Beeps::Sound.new(Beeps::Oscillator.new(:square, frequency: 880), 0.5)
sound.save 'square.wav'

Capture from the microphone and analyse

require 'beeps'

mic      = Beeps::MicIn.new(1)            # 1 channel
analyser = Beeps::Analyser.new(1024, mic) # 1024-point FFT
mic.start

loop do
  sleep 0.1
  puts analyser.spectrum.first(8).map {|v| v.round 3 }.inspect
end

🛠️ Development

$ rake lib    # build the native C++ library (libbeeps)
$ rake ext    # build the Ruby C extension
$ rake test   # run the test suite
$ rake doc    # generate RDoc from C++ sources
$ rake       # default: builds the extension

In the xord/all monorepo you can scope by module, e.g. rake beeps test.

📜 License

Beeps is licensed under the MIT License. See the LICENSE file for details.

The third-party DSP libraries listed above retain their own licenses.