Techouse Developers Blog

テックハウス開発者ブログ|マルチプロダクト型スタートアップ|エンジニアによる技術情報を発信|SaaS、求人プラットフォーム、DX推進

RubyKaigi 2025 - How to make the Groovebox (Day2)

ogp

こんにちは、株式会社Techouse 新卒バックエンドエンジニアの sakaidubz です。

RubyKaigi 2025 DAY2 の @asonas さんによる "How to make the Groovebox" というセッションについて紹介させていただきます。

前提

私自身は音楽制作をしたことがない初心者です。専門用語や理論について誤った解釈がある可能性があります。ご理解をお願いします。

Grooveboxとは

Groovebox は、asonas さんにより開発された Ruby で電子音楽を作ることができるCLIアプリケーションです。シンセサイザー、ステップシーケンサー、エフェクターなどを組み合わせて音楽制作するためのツールで、すべてが Ruby で実装されています。

セッションの背景

私自身、ダンスミュージックなど電子音楽は毎日聴いていますが、実際どのように DAW(Digital Audio Workstation)で作られているのか、その細かい仕様や仕組みについては詳しくありませんでした。(主に聴く側・流す側であり、作る側に回ったことはない。)

そんな私にとって、「音楽制作を理解するために作った」というテーマのもとで開発された Groovebox のアプローチは興味を惹かれるものでした。

私にとっては「音楽制作の基本的な How を伝えるために作られた」CLIアプリケーションであるとも感じました。実際に何も知らない制作ツールの仕組みを少しだけ知れたような気がしました。

セッション内容

セッションでは、asonas さんが Groovebox の開発背景や技術的な仕組みについて解説されました。特に印象的だったのは、「音楽制作ツールを理解するために作る」という姿勢です。既存の DAW や音楽制作ソフトウェアのブラックボックス化された部分を、Ruby で実装することで理解を深めるというアプローチが非常に興味深かったです。

asonas さんは、実際のハードウェアシンセサイザーやシーケンサーを例に挙げながら、それらの機器がいかに複雑で、使いこなすためには膨大なマニュアルを読む必要があるかを説明されました。例えば、シーケンサーのマニュアルは164ページにも及ぶとのことでした。「電子楽器を使うと、音楽理論以上に学ぶものが多い」という言葉が印象に残りました。

そこで、ソフトウェアエンジニアとして、自分でコードを書いて理解を深めるというアプローチを取られたとのことです。これは私たちエンジニアが日常的に行っている、ドキュメントを読んだりサンプルコードを動かしたりして知識を得るプロセスと同じだと例えていて共感しました。

セッションでのデモの様子

デモでは、実際に Groovebox を使って音楽を作る様子が披露され、Ruby だけで作られたとは思えないほど本格的な音が鳴っていたのが印象的でした。キックやスネア、ハイハットといったドラム音源から、ベースのような音色まで、様々な音を生成し、それらを組み合わせて曲を作り上げていく様子は非常に興味深いものでした。

会場のスピーカーの鳴りが良く、キックのサウンドが非常に良いなと感じました(笑)。私の好みのBPM 140だったら踊り出していたかもしれません...。(Xでも少し取り上げられていました。

Groovebox の特徴

私が感じ取れた Groovebox の特徴は、以下3点です。

  1. Math モジュールによる波形生成
    Ruby の標準ライブラリである Math モジュールを使って、サイン波(正弦波)や三角波などの波形を直接生成しています。Math.sinMath::PI といった基本的な数学関数だけで、シンセサイザーの基本となる波形を作り出している点が非常にエレガントです。セッションでは、サイン波、ノコギリ波、三角波、パルス波、矩形波といった基本波形の生成方法が紹介されました。

  2. dRuby による分散アーキテクチャ Ruby の標準ライブラリである dRuby (Distributed Ruby) を使って、メインプロセスとシーケンサープロセスを分離しています。main.rb では DRb.start_service によって Groovebox インスタンスをサーバーとして公開し、別プロセスの sequencer.rb からアクセスする構成になっています。これにより、音声生成処理とシーケンス処理を分離し、パフォーマンスを向上させています。

  3. 和音対応と音割れ防止の工夫
    複数の音を同時に鳴らす際に、単純に波形を足し合わせると音が割れてしまう問題に対して、1.0 / Math.sqrt(active_instruments) という計算で適切なゲイン調整しています。これにより、和音を美しく鳴らすことができます。セッションでは、アクティブノートの数に応じて音量を調整する実装が紹介されました。

Groovebox の使い方

使い方は非常にシンプルで、リポジトリを git clone した後、以下の4つのコマンドを実行するだけです。

$ brew install portaudio
$ bundle install
$ ruby main.rb  # 一つ目のターミナルで実行
$ ruby bin/sequencer  # 別のターミナルで実行し、操作画面が表示される

また、MIDIファイルを読み込むこともできます。これがプロデューサー目線だと非常に便利だそうです。

シーケンサーモードとシンセモードの2つのモードがあり、それぞれYouTubeでデモ動画が公開されています。

引用: README

Groovebox のコード

詳細はasonas/groovebox-rubyをご覧いただくのが良いですが、個人的に着目した点をいくつか挙げてみます。

1. オシレーターの実装

オシレーターは音の基本となる波形を生成する部分です。Grooveboxでは、oscillator.rbで様々な波形(サイン波、ノコギリ波、三角波、パルス波、矩形波)を生成しています。

def generate_wave(note, buffer_size)
  delta = 2.0 * Math::PI * note.frequency / @sample_rate

  Array.new(buffer_size) do
    # 各倍音ごとに合成
    sample_sum = 0.0
    @harmonics.each do |(harmonic_ratio, amplitude_ratio)|
      # 各倍音の周波数を n倍して波形を生成
      harmonic_phase = note.phase * harmonic_ratio

      # 波形選択
      partial_sample =
        case @waveform
        when :sine
          Math.sin(harmonic_phase)
        when :sawtooth
          2.0 * (harmonic_phase / (2.0 * Math::PI) - (harmonic_phase / (2.0 * Math::PI)).floor) - 1.0
        when :triangle
          2.0 * (2.0 * ((harmonic_phase / (2.0 * Math::PI)) - 0.5).abs) - 1.0
        when :pulse
          (harmonic_phase % (2.0 * Math::PI)) < Math::PI ? 1.0 : -1.0
        when :square
          (harmonic_phase % (2.0 * Math::PI)) < Math::PI ? 0.5 : -0.5
        else
          0.0
        end

      sample_sum += partial_sample * amplitude_ratio
    end

    note.phase += delta
    note.phase -= 2.0 * Math::PI if note.phase > 2.0 * Math::PI

    sample_sum
  end
end

この部分は、数学的な関数を使って波形を生成しています。特に興味深いのは、倍音(harmonics)の概念を取り入れている点です。基本波に加えて倍音を合成することで、より豊かな音色を作り出しています。セッションでは、これらの波形を実際に鳴らしながら、それぞれの特徴を説明されていました。

2. エンベロープジェネレーターの実装

エンベロープジェネレーターは、音の時間的変化を制御する部分です。ADSR(Attack, Decay, Sustain, Release)と呼ばれる4つのパラメータで音の変化を表現します。

def calculate_envelope(playing_time)
  # アタック段階
  if playing_time < @attack
    return (playing_time / @attack) if @attack > 0
    return 1.0
  end

  # ディケイ段階
  if playing_time < @attack + @decay
    decay_progress = (playing_time - @attack) / @decay
    return 1.0 - ((1.0 - @sustain) * decay_progress)
  end

  # サステイン段階
  return @sustain
end

この実装により、鍵盤を押した瞬間から離すまでの音の変化を細かく制御できます。セッションでは、アタックを長くすると音がゆっくり立ち上がり、短くすると瞬時に最大音量になることなどが実演されていました。

3. dRuby による分散処理

Grooveboxでは、dRuby(Distributed Ruby)を使って、音声生成処理とシーケンス処理を分離しています。

# main.rb
DRb.start_service('druby://localhost:8786', groovebox)
puts "Groovebox DRb server started at druby://localhost:8786"

# bin/sequencer
DRb.start_service
groovebox = DRbObject.new_with_uri('druby://localhost:8786')

この構成により、音声処理を担当するメインプロセスと、シーケンス処理を担当するプロセスを分離し、それぞれが最適なパフォーマンスで動作できるようになっています。

4. シーケンサーの実装

シーケンサーは、音楽のリズムやメロディを時間軸に沿って制御する部分です。Grooveboxでは、ステップシーケンサーを実装しています。

def run
  @playing = true
  loop do
    break unless @playing
    
    if @current_position >= @steps_per_track
      @current_position = 0
    end
    
    @tracks.each do |track|
      step = track[:steps][@current_position]
      if step.active
        @groovebox.change_sequencer_channel(track[:instrument_index])
        @groovebox.sequencer_note_on(track[:midi_note] || step.note, step.velocity || 100)
      end
    end
    
    sleep(60.0 / (@bpm * 4))
    
    @tracks.each do |track|
      step = track[:steps][@current_position]
      if step.active
        @groovebox.change_sequencer_channel(track[:instrument_index])
        @groovebox.sequencer_note_off(track[:midi_note] || step.note)
      end
    end
    
    @current_position += 1
  end
end

この実装により、複数のトラックを同時に再生し、それぞれのステップでノートのオン・オフを制御できます。セッションでは、実際にシーケンサーを操作して、ドラムパターンやメロディを作成するデモが行われました。

Groovebox を使ってみた感想

使ってみた様子

まず驚いたのは、Ruby だけでこれほど本格的な音楽制作ツールが作れるということです。一般的に、音楽制作ソフトウェアは C++ や Rust などの低レベル言語で書かれることが多い(らしい)ですが、Ruby でも十分実用的なレベルの音が出せることに感心しました。

私自身、電子音楽は日常的に聴いていますが、その制作過程や仕組みについては詳しくありませんでした。DAWの複雑なインターフェースや専門用語の多さに圧倒されることもあります。しかし、Grooveboxのコードを読むことで、シンセサイザーやシーケンサーの基本原理が以前よりも理解しやすくなったと感じます。

特に、dRuby を使った分散アーキテクチャは非常に興味深いアプローチだと感じました。音声処理とシーケンス処理を分離することで、それぞれのプロセスが最適なパフォーマンスで動作できるようになっています。

セッションでも触れられていましたが、市販の楽器やDAWは機能が豊富である反面、学習コストが非常に高いです。一方、Grooveboxはその学習の過程を身近な Ruby で置き換えており、内部ロジックを理解することの傾斜を下げてくれていると感じました。

まとめ

asonas さんの "How to make the Groovebox" セッションは、Ruby で音楽制作ツールを作るという挑戦的な取り組みを紹介するものでした。特に印象的だったのは、「理解するために作る」という姿勢です。既存のツールをブラックボックスとして使うのではなく、自分で実装することで深い理解を得るというアプローチは、エンジニアとして非常に共感できるものでした。

音楽制作に興味のあるRubyistの方は、ぜひ asonas/groovebox-ruby をチェックしてみてください。

最後に、素晴らしいセッションを提供してくださった asonas さんに感謝します。Ruby の可能性を広げる取り組みに、今後も注目していきたいと思います。


Techouseでは、社会課題の解決に一緒に取り組むエンジニアを募集しております。 ご応募お待ちしております。

jp.techouse.com