Date:2025-06-09
RMS(Root Mean Square) | openFrameworks
音の可視化や音響解析において、RMS(Root Mean Square:二乗平均平方根・実効値)は非常に重要な指標です。RMSは、音の瞬間的なピーク値ではなく、ある時間範囲(bufferSize)の振幅の平均をとることで、音響信号のダイナミクスや音量感の把握、さらには視覚化のベースとしても自然な表現が可能になります。

本記事では、RMSの理論的背景を簡潔に整理し、その理解のため、openFrameworksを使って音のRMSをリアルタイム音声入力から計算・可視化する方法をまとめます。フィールドレコーディングや音の視覚化・オーディオリアクティブのプロジェクトにも応用可能です。
1. RMS(Root Mean Square)とは?
RMS(Root Mean Square、二乗平均平方根)とは、変動する値の「平均的な大きさ(エネルギー量)」を表す指標です。主に物理や音響、電気工学、信号処理などの分野で使われます。
デジタル音声などで使用される離散データの場合は、以下の式で定義されます。

ここで、xi は各サンプル値、Nはサンプル数です。絶対値の平均よりも滑らかで、ピーク値よりも実際の音量感に近い値を得られるため、音響解析では広く使用されています。
単純な平均(平均値)は「正負がある波」ではゼロに近づいてしまうため、振幅の「実効的な大きさ」を表すためにRMSが使われます。
RMSは、以下のステップで求めます。
- 値を全て二乗する。
- 二乗値の平均を取る。
- 最後に平方根を取る
2. RMSをプログラム(openFrameworks)にて計算し理解する。
openFrameworksにて、次の通りの方法でRMSを計算します。
- リアルタイム音声入力(マイク)を使う: ofSoundStream, ofSoundBuffer, audioIn を利用
リアルタイム音声入力からRMSを計算
マイクや外部入力音声からRMSを計算する場合、ofSoundStream, ofSoundBuffer, audioInを利用しRMS を計算します。以下、それぞれの役割。
- ofSoundStream
音声の入出力を管理するクラス。サンプリングレートやバッファサイズ、入力チャンネルなどを設定します。 - ofSoundBuffer
バッファに溜まった音データを保持・操作するクラス。今回はRMSを計算するため、バッファに溜まったデータを使用します。 - audioIn(ofSoundBuffer & input)
マイクから入ってきた音データをリアルタイムで受け取る関数。audioInはofBaseAppに定義されいる仮想関数。引数にて得られたofSoundBufferを受け分析処理を行います。
▸ 処理の流れ
- ofSoundStream で入力の設定。(bufferSize や Channles数など)
- ofSoundBufferにてサンプルを貯める。
- audioIn() にて ofSoundBuffer を使ってRMSのを行う。
コード例1:audioIn()でのRMS計算
void ofApp::audioIn(ofSoundBuffer & input){
float sum = 0.0;
int numCounted = 0;
for (size_t i = 0; i < input.getNumFrames(); i++){
float sample = input[i];
sum += sample * sample;
numCounted++;
}
sum = sqrt(sum / (float)numCounted);
smoothedRms *= 0.93;
smoothedRms += 0.07 * sum;
}
▸ コード例1 説明
1. 初期化
- float sum = 0.0;
各サンプルの二乗値を合計するための変数をゼロで初期化します。 - int numCounted = 0;
処理したサンプル数を数えるための変数をゼロで初期化します。
2. 全サンプルの処理
- for (size_t i = 0; i < input.getNumFrames(); i++){ ... }
入力された音声データ (input) のすべてのサンプルに対して、以下の処理を繰り返します。input.getNumFrames() は、現在入力されている音声データのサンプル数を取得します。
補足: ここで言う "Frames" は、実際には個々の音声サンプルの数を意味します。リアルタイム処理では、ofSoundStream で設定したバッファサイズと完全に一致するとは限りません。そのため、ofSoundBuffer から実際に得られたサンプル数 (getNumFrames()) を使うことが重要です。 - float sample = input[i];
現在のサンプルの値を変数sample
に格納します。 - sum += sample * sample;
現在のサンプルの値を二乗し、それを sum 変数に加算します。これは、RMS (Root Mean Square: 二乗平均平方根) を計算する準備段階です。
3. RMS (Root Mean Square) の計算
- sum = sqrt(sum / (float)numCounted);
すべてのサンプルの二乗値の合計 (sum) を、処理したサンプル数 (numCounted) で割り、その結果の平方根を計算します。これが、現在の音声データの RMS 値となります。
4. RMS 値の平滑化
- smoothedRms *= 0.93;:過去の平滑化された RMS 値 (smoothedRms) に 0.93 を掛け、過去の値を少し減衰させます。
- smoothedRms += 0.07 * sum;:現在の RMS 値 (sum) に 0.07 を掛け、その結果を現在の smoothedRms に加算します。
この平滑化処理により、急激な音量の変化が緩和され、より滑らかな音量の変化として smoothedRms に反映されます。0.93 と 0.07 という係数は、平滑化の度合いを調整するための値です。
これは「指数移動平均(Exponential Moving Average, EMA)」によるスムージング処理になります。
- smoothedRms は前回までの滑らかなRMS値
- sum は今回のRMS計算結果
この2行は、最新値sumと、過去の値smoothedRmsを重み付けして「滑らかに追従する値」を作っています。
- smoothedRms *= 0.93;
→ 過去の値を93%残す - smoothedRms += 0.07 * sum;
→ 今回の新しい値(sum)を7%だけ足す
合計で100%になる(0.93 + 0.07 = 1.0)。
このようなスムージング処理は大きく変動する音量の見た目のガタ付きをスムーズにします。0.93/0.07のバランスを変えると「追従の速さ」が変わります。(0.07を大きくすると追従が速くなり、0.07を小さくするとより滑らか(反応が遅い)になります。)
コード例2 応用:audioIn()でのRMS計算(マルチチャンネル)
void ofApp::audioIn(ofSoundBuffer & input){
float sum = 0.0;
int numCounted = 0;
int numChannels = input.getNumChannels();
for (size_t i = 0; i < input.getNumFrames(); i++){
for (int ch = 0; ch < numChannels; ch++) {
float sample = input[i * numChannels + ch];
sum += sample * sample;
numCounted++;
}
}
sum = sqrt(sum / (float)numCounted);
smoothedRms *= 0.93;
smoothedRms += 0.07 * sum;
}
▸ コード例2 説明
ステレオなど複数のチャンネルがある場合getNumChannels()にてチャンネル数をあてforで回します。
float sample = input[i * numChannels + ch];の配列は、ofSoundBufferの配列は[Left] [Right] [Left] [Right] ...といったインターリーブ形式(Interleaved)にて値が格納されているため配列にchとして0,1とそれぞれ加算します。これにより、0フレーム目がindex 0, 1、1フレーム目がindex 2, 3、2フレーム目がindex 4, 5...となります。
3. RMSの値の視覚化
この smoothedRms を draw() 関数内で視覚化することで、リアルタイムな音の強さを直感的に表示できます。下記は円の大きさを音のRMSにて変化を加えます。

void ofApp::draw() {
ofBackground(0);
ofNoFill();
ofSetColor(255);
ofSetLineWidth(2);
float radius = ofMap(smoothedRms, 0.0, 0.1, 0.0, 500.0, true) + 100;
ofSetCircleResolution(100);
ofDrawCircle(ofGetWidth()/2, ofGetHeight()/2, radius);
}
4. RMSの可視化方法
RMSはそのまま数値として出力するだけでなく、次のような視覚表現に応用できます
- 音量バー
- 時系列の折れ線グラフ
- ヒートマップや波形へのオーバーレイ表示
- インタラクティブな音の粒子表現など
RMS計算を応用し、以下のような拡張を進めます
- 複数チャンネル(ステレオ/サラウンド)での比較
- RMSの時間変化からエンベロープを描く
- ピーク値やスペクトル解析との組み合わせ
- 録音環境の自動評価やトリガー検出への応用
また、openFrameworksとMax/MSPやPure Dataなどのツールと連携することで、より複雑な音響インタラクションも構築できます。
5. RMS(Root Mean Square)
RMS(実効値)は、音の「強さ」を表現するための基本かつ重要な指標です。本記事では、RMSの理論的な背景から、openFrameworksによる実装、さらにその可視化までをまとめました。
その他の音響指標(ピーク値、ラウドネス、FFTなど)と組み合わせることで、より豊かな音の理解と視覚表現が可能になるます。
BGD_SOUNDS on bandcamp
BGD_SOUNDSでは、アートワークで使用するために録音された様々な音を公開しています。ぜひフォローしてください。
安価で利用できる膨大な著作権フリーのサウンドライブラリーを目指し、定期的に音源ライブラリーを増やしています。音源のほとんどは、192kHzの32bitにて録音。音楽制作や映像制作など、それぞれの用途に合わせて利用できます。(メタデータも含まれています。)
BGD_CLUB(月額サブスクリプション)も始めました。低価格からすべてのライブラリーにアクセスし自由にダウンロードすることが可能です。
