mcpField
A
Audio

Audio

ローカル
github.comメディア・デザイン3291 日前に更新

Audio について

Audioは、開発者や音声処理ワークフロー向けのJavaScript音声編集・分析ライブラリで、CLIも備えています。ffmpegを使わず、ストリーミングやページ分割処理、非破壊編集、再生、分析を行えます。

主な機能

  1. 01140種類以上の音声処理プラグイン
  2. 02取り消し可能な非破壊編集
  3. 03ストリーミング再生とエンコード
  4. 04大容量ファイル向けページ分割処理
  5. 05ラウドネス、スペクトル、ビート、音高の分析
  6. 06バッチ処理とスクリプト用CLI

活用シーン

  1. 01ポッドキャストのラウドネス調整と検査
  2. 02録音のトリミング、ノイズ除去、EQ
  3. 03ビート、音高、キーの分析
  4. 04スクリプトでの音声一括処理

MCP 対応

AudioはMCPサーバーを提供し、測定、表示、編集、選択、再生、検査などの音声ツールをMCPクライアントに公開します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"audiojs-audio": {
"command": "npx",
"args": [
"-y",
"audio"
]
}
}
}
起動コマンドnpx -y audio

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmaudio2.10.0

ツール

1

掲載時のツール一覧 · 2 週間前に更新

パラメーター型必須説明
argsstringはい`audio` の後に続く引数。shell の引用符で囲み、絶対パスを指定します:"/Users/me/voice.m4a trim normalize podcast save /Users/me/voice.mp3"

詳細

audio test npm

高水準のオーディオ操作:読み込み、再生、分析、編集。140以上のプラグイン:ノイズ除去、ダイナミクス、EQ、フィルター、エフェクト、リバーブ、時間とピッチ、空間、合成、音楽分析。

  • あらゆる形式 — 高速なwasm コーデック、ffmpeg 不要。
  • 非破壊 — 仮想編集、無制限の取り消し、即時クローン。
  • ストリーム優先 — デコード中に再生/エンコード、リアルタイム編集。
  • ページ分割 — 2Gb のメモリー制限なし、10Gb 以上のファイルを開けます。
  • 分析 — ラウドネス、スペクトル、ビート、ピッチ、コード、キー。
  • モジュール式 – プラグイン可能な操作、ツリーシェイキング対応。
  • CLI — 再生、バッチ処理、スクリプト、unix パイプ、タブ補完。
  • クロスプラットフォーム — ブラウザー、node、deno、bun。

npm install audio
開始   レシピ   API   CLI   FAQ   プラグイン   アーキテクチャ   比較   RX 12

開始

Node

npm i audio

import audio from 'audio'

let song = audio('song.mp3')
song.play()                                  // the speakers, as a page plays it: no ffmpeg, no player to spawn
song.pause(); song.seek(60); song.resume()

let voice = audio('voice.wav').trim().normalize('podcast')
await voice.save('clean.mp3')
let { pass, rules } = await voice.check('podcast')  // each rule of Apple's spec, measured
ブラウザー
<script type="module">
  import audio from 'https://esm.sh/audio'
  audio('./song.mp3').trim().normalize().fade(0.5, 2).clip({ at: 60, duration: 30 }).play()
</script>
どこでも使えるAudio
import 'audio/polyfill'          // the page's HTMLAudioElement, in Node, Bun and Deno
let song = new Audio('song.mp3')
song.onended = () => console.log('done')
await song.play()
song.currentTime = 30; song.volume = 0.5; song.loop = true

イベント、その順序、プロミス、エラーは、観察ごとに比較した Chromium 本来の要素と同じです(test/polyfill.js)。import { Audio } from 'audio/polyfill' はグローバルを変更しません。

CLI
npm i -g audio # or: npx audio …
audio voice.wav trim normalize podcast save clean.mp3
audio clean.mp3 check podcast
#   Apple Podcasts  https://podcasters.apple.com/support/893-audio-requirements
#   ✓ Loudness     -16.44 LUFS  -17 to -15
#   ✓ True peak     -1.18 dBTP  ≤ -1
#   pass

失敗すると終了コード 1 になるため、同じ行でビルドを保護できます:CI で確認。

スキル
npx skills add audiojs/audio
MCP
npx add-mcp "npx -y audio --mcp"  # asks which of your agents: Claude Code, Codex, Cursor, Gemini CLI, Kimi Code, Pi, OpenCode, Zed…

Prompt: make ~/Desktop/interview.m4a podcast-ready and tell me the loudness before and after

同時に使えるエージェントは1つです:claude mcp add audio -- npx -y audio --mcp、qwen mcp add audio npx -y audio --mcp、droid mcp add audio "npx -y audio --mcp"。

Playground とエージェント
npx audio --bridge
# audio bridge on http://127.0.0.1:7777
#
#   key     3e37b8c61acf5b50f010852168f4843d
#   agents  Claude Code, Codex, Pi, Kimi Code
#
#   In the playground's Agent panel, paste the key, then Connect. It stays the same next time.

playgroundを開くと、編集するたびに1行のaudioコードが生成されます。キーを使ってブリッジに接続すると(キーは一度入力すれば、ブリッジに保存されます)、チャットであなたのエージェントが動作します。エージェントは、そこで開いているサウンドを測定、確認、編集、再生し、どの編集で何が変わったかを特定します。各編集の前後でサウンドを測定し、編集によって取り除かれたものも確認します。各タブにはエージェントとの会話がそれぞれ保存され、モデルはメッセージの下で選択できます。ブリッジはPATH上のClaude Code、Codex、Pi、Gemini CLI、Qwen Code、Kimi Code、OpenCode、Kilo Code、Cline、Goose、Factory Droid、Cursor、Augment、Kiro、Mistral Vibeを検出します。ACPに対応するその他のエージェントは、コマンドラインから起動できます。--agent "my-agent --acp"。

どのMCPエージェントでも、playgroundのツール(state、measure、look、edit、select、play、check、…)を使えます。起動中のブリッジは自動的に検出されます。npx add-mcp "npx -y audio --mcp --playground"。

エージェントは、各自の設定で指定されたモデルを使って思考します。Piでは、ollama launch pi --configを使うとローカルモデルを恒久的に設定できます。Claude Codeでは、ブリッジの環境変数を使って、Anthropic互換のエンドポイントを指定できます。

ANTHROPIC_BASE_URL=http://localhost:11434 ANTHROPIC_AUTH_TOKEN=ollama ANTHROPIC_API_KEY= ANTHROPIC_MODEL=qwen3-coder npx audio --bridge
モデルANTHROPIC_BASE_URL。プロバイダーのキーはANTHROPIC_AUTH_TOKENとして指定
Ollamahttp://localhost:11434、トークンはollama(ドキュメント)
Z.ai GLMhttps://api.z.ai/api/anthropic(ドキュメント)
Kimihttps://api.moonshot.ai/anthropic(ドキュメント)
Qwenhttps://coding-intl.dashscope.aliyuncs.com/apps/anthropic、Coding Plan(ドキュメント)
DeepSeekhttps://api.deepseek.com/anthropic(ドキュメント)
埋め込み

playgroundはどのページにも埋め込めます。スクリプトは要素自体のテキストです。読み手がその位置までスクロールすると実行され、再生や編集ができ、全体をplaygroundで開けます。読み手の情報は保存されません。

<script type="module" src="https://audio.js.org/embed.js"></script>

<audio-repl panel="code" display="wave" height="320">
<pre><code>audio('chime.wav')
  .trim()
  .normalize(-1)</code></pre>
</audio-repl>

panel:code(デフォルト)、edits(設定付きの各ステップ)、またはnone。display:waveまたはspec。heightはpx単位です。フレームが読み込まれるまで、またスクリプトが実行されない場所では、<pre>が表示されます。

レシピ

クリーンアップ
// master a raw take
let a = audio('raw-take.wav')
a.trim(-30).normalize('podcast').fade(0.3, 0.5)
await a.save('clean.wav')

// full restoration chain via ecosystem plugins (see API › Plugins)
a.gate(-45).dehum().deesser().compressor({ threshold: -18 }).limiter({ ceiling: -1 })

// cut 2:00–2:15, smooth the splice
a.remove({ at: 120, duration: 15 }).fade(0.1, { at: 120 })

// find clipped blocks
let clips = await a.stat('clipping')

// does it pass? each rule of the spec, measured
let { pass, rules } = await a.check('podcast')         // acx, podcast, spotify, broadcast, netflix
マスタリングと納品
// master a song to a reference track: its tone (mid and side), width and loudness, under -1 dBTP
audio('mix.wav').master(await audio('reference.wav')).save('master.wav')

// audiobook chapter for ACX: RMS -23..-18 dB, peaks under -3 dB, floor under -60 dB, room tone at each end, 44.1 kHz
let ch = audio('chapter-01.wav')
  .highpass(80).omlsa({ gMin: -12 }).compressor({ threshold: -24, ratio: 2.5 })
  .normalize(-20, 'rms', { ceiling: -3.5 })
  .trim().pad(1.5, 2).roomtone()                      // room tone, not digital silence
  .resample(44100)
console.log(await ch.check('acx'))                    // passed 10 of 10 real narrations (.work/pro.md)
await ch.save('chapter-01.mp3', { bitrate: 192 })

// tighten pauses in a talking-head video, then hand the cuts to the video editor
let talk = audio('talk.mp4').shrink(0.3)
await talk.save('talk.m4a')                            // the sound, cut
await talk.save('talk.edl')                            // the same cuts for the picture (Premiere, Resolve)
作曲
// podcast montage
let ep = audio([intro, interview.trim().normalize('podcast'), outro], { crossfade: 0.5 })
await ep.save('episode.mp3')

// voiceover over music
music.gain(-12).mix(voice, { at: 2 })

// ringtone: the chorus + fades
audio('song.mp3').crop({ at: 45, duration: 30 }).fade(0.5, 2).normalize().save('ringtone.mp3')

// split an audiobook into chapters
let [ch1, ch2, ch3] = audio('audiobook.mp3').split(1800, 3600)

// glitch: stutter + reverse
let v = a.clip({ at: 1, duration: 0.25 })
audio([v, v, v, v]).reverse({ at: 0.25, duration: 0.25 })
分析
// waveform bars — and progressively, as it decodes
let [mins, peaks] = await a.stat(['min', 'max'], { bins: canvas.width })
a.on('data', ({ delta }) => appendBars(delta.max[0], delta.min[0]))

// features for ML
let mfcc = await a.stat('cepstrum', { bins: 13 })
let [loud, rms] = await a.stat(['loudness', 'rms'])

// notes, chords, key
let notes = await a.stat('notes')    // [{time, duration, freq, midi, note, clarity}]
let chords = await a.stat('chords')  // [{time, duration, label, root, quality, confidence}]
let key = await a.stat('key')        // {tonic, mode, label, confidence}
録音と生成
// mic take
let a = audio()
a.record()
// …later
a.stop()
a.trim().normalize()

// tone — any t => sample function
let tone = audio.from(t => Math.sin(440 * Math.PI * 2 * t), { duration: 2 })

// sonify data
let s = audio.from(t => Math.sin((200 + data[t / 0.2 | 0]) * Math.PI * 2 * t) * 0.5, { duration: data.length * 0.2 })
自動化
a.gain(t => -12 * (0.5 + 0.5 * Math.cos(t * Math.PI * 4)))  // 2Hz tremolo in dB
a.lowpass(t => 400 + 4000 * t)                              // filter sweep
a.pan({ t: [0, 2, 4], v: [-1, 1, -1] })                     // curve L→R→L over 4s, serializable
music.ducker({ key: voice })                                // sidechain (plugin)
ストリーミングと永続化
// stream to network — encode/playback during decode
for await (let chunk of audio('2hour-mix.flac').highpass(40)) socket.send(chunk[0].buffer)

// serialize edits, restore later
let json = JSON.stringify(a)     // { source, edits, ... }
let b = audio(JSON.parse(json))  // re-decode + replay edits

API

作成
メソッド                        説明                                                                                                                
audio(source, opts?)ファイル、URL、バイト列、またはバイトストリームからデコードします。すぐに返り、バックグラウンドでデコードします。ストリームは到着した順にデコードされます。
audio.from(source, opts?)既存のPCM、AudioBuffer、無音、または関数をラップします。同期処理で、I/Oは行いません。
let a = audio('voice.mp3')                // file path
let b = audio('https://cdn.ex/track.mp3') // URL
let c = audio(inputEl.files[0])           // Blob, File, Response, ArrayBuffer
let d = audio()                           // empty, ready for .push() or .record()
let e = audio([intro, body, outro])       // concat (virtual, no copy)
let f = audio([a, b, c], { crossfade: 2 })  // concat with 2s crossfade
let g = audio(process.stdin)              // byte stream: pipe, socket, fetch body – decodes as it arrives
// opts: { sampleRate, channels, crossfade, curve, storage: 'memory' | 'persistent' | 'auto' }

await a    // await for decode — if you need .duration, full stats etc

let a = audio.from([left, right])                 // Float32Array[] channels
let b = audio.from(3, { channels: 2 })           // 3s silence
let c = audio.from(t => Math.sin(440*TAU*t), { duration: 2 })  // generator
let d = audio.from(audioBuffer)                   // Web Audio AudioBuffer
let e = audio.from(int16arr, { format: 'int16' }) // typed array + format
let f = audio.from(store, { length, channels, sampleRate }) // pages in a store ({ read(i), has(i), write(i, page) }), read as needed
プロパティ
プロパティ                        説明                                                                                                                        
.duration編集後の合計秒数です。
.channelsチャンネル数です。
.sampleRateサンプルレートです。
.lengthチャンネルあたりのサンプル数です。
.currentTimeスピーカーから現在再生されている位置を秒単位で示します。レイテンシーが補正された滑らかな値で、一時停止中は再生再開位置を保持します。
.playing再生中は true です。
.paused一時停止中は true です。
.volume0~1 のリニア値です。設定可能です。
.muted音量とは独立したミュート状態です。設定可能です。
.loop再生中も設定可能です。範囲が繰り返され、各つなぎ目には 10 ms の等電力クロスフェードが適用されます。
.playbackRate0.0625~16 の範囲で、再生中もクリックノイズなしに設定できます。.preservesPitch が false でない限り、ピッチは維持されます(ブラウザーのメディア要素が速度を変えて再生する場合と同じ WSOLA 方式です)。false の場合は約 50 ms かけて滑らかに変化し、テープのようにピッチも変わります。.speed() はこの速度を音声に反映します。
.preservesPitchtrue の場合、再生速度が 1 以外でもピッチを維持します。false の場合はバリスピードとなり、ピッチも速度に応じて変わります。再生中も設定可能です。
.ended再生が最後まで到達したとき true です。stop() の後は true になりません。
.seekingシーク中は true です。
.played再生音が聞こえると解決する Promise です。
.recordingマイク録音中は true です。
.readyデコードが完全に完了すると解決する Promise です。
.source元のソースです。
.bitDepthソースの保存時のサンプル深度です。16、24、32(浮動小数点)を指定します。非可逆圧縮音声または生成音声の場合は null です。可逆形式の save ではこの値が維持されます。
.pagesFloat32Array のページストアです。
.statsブロックごとの統計情報(ピーク、RMS など)です。
.edits編集リストです。
.version編集ごとにインクリメントされます。
構造
メソッド                        説明                                                                                                                        
.trim(threshold?)先頭と末尾の無音を取り除きます(dB、デフォルトは自動)。ライブストリームでは、しきい値を指定するとストリーミングし、音が再開するまで無音の末尾を保持します。自動設定では入力全体を読み込むため、終端まで待機します。
.shrink(gap?, threshold?)無音の間隔を gap 秒(デフォルトは 0.3)に短縮します。0 では無音を取り除きます。trim と同様に、しきい値を指定するとストリーミングします。
≡ FFmpeg silenceremove、Audacity の truncate-silence
.crop({at, duration})指定範囲を残し、それ以外を破棄します。
.remove(at, duration, crossfade?)指定範囲を削除し、隙間を閉じます。crossfade('10ms')を指定すると、カット位置を中心に等パワーのクロスフェードを行います。長さは変わりません。
.insert(source, at?, crossfade?)音声を挿入します(デフォルトは末尾)。または、指定した秒数の無音を挿入します。crossfade は両方の接合部をフェードします。
.copy({at?, duration?})指定範囲を(デフォルトは全体)このインスタンスのクリップボードにコピーします。
.cut({at?, duration?, crossfade?})コピーしてから削除します。
.paste({at?, crossfade?})クリップボードの内容を挿入します(デフォルトは末尾)。
.move({at, duration, to, crossfade?})指定範囲を to までスライドさせ、移動先の音声に上書きします。元の位置は無音になり、長さは維持されます(末尾を越える場合は延長されます)。crossfade は両端を中心にクロスフェードします。
≡ DAW のクリップをスリップモードで移動
.clip({at, duration})ゼロコピーの抜粋を新しいインスタンスとして作成します。
.split(...offsets)タイムスタンプ間のゼロコピー抜粋を作成します。
.pad(before, after?)音声の前後に無音を追加します(秒)。
.repeat(n)n 回繰り返します。
.reverse({at?, duration?})音声全体または指定範囲を逆再生します。
.speed(rate, {type?})ピッチと長さを同時に変化させます。type: 'sinc' は線形補間の代わりに Lanczos sinc(16 ゼロ交差)でサンプル間を読み取り、レートが 1 に近いときに高域のオクターブを維持します。
.stretch(factor, {voice?, method?})ピッチを維持して長さを変化させます(位相ロック・ボコーダー)。t => f または {t, v} の係数でテンポを変化させます。長さは ∫factor dt になります。範囲 {at, duration} はサンプル単位で round(round(duration · sampleRate) · factor) の長さになり、その周囲の音声は元のままです。{ voice: true } は、ボコーダーでは離れて聞こえる声のパルス形状と子音を維持します。短縮時は波形の一部を順にコピーし(WSOLA、@audio/stretch-wsola)、低速化時は適合する波形の位置からボコーダーのフレームを再開するため(PVSOLA、@audio/stretch-pvsola)、息や残響が繰り返されてフランジャーのようになるのを防ぎます。対象は単一の声で、和音には対応しません。{ method } は別の方法で伸縮し、モジュールはそのときだけ読み込まれます:'vocoder'、'pghi'、'wsola'、'psola'、'sms'、'transient'、'hybrid'、'paulstretch'(@audio/stretch-*)。デフォルトの 'phase-lock' はストリーミングとスライドに対応し、voice も使用できます。それ以外は一定の係数で伸縮対象を一度にレンダリングします。範囲を指定した場合は、両側の音声との間にクロスフェードを入れます。
≡ Logic Flex Time Monophonic、Ableton Tones
.warp(markers)時間上の位置を移動します:秒単位の [[from, to], …]。マーカー間ではピッチを維持したまま音声を伸縮して合わせます。開始位置と終了位置は変わりません。
≡ Logic Flex Time、Ableton warp markers
.pitch(semitones, {voice?, method?})長さを維持してピッチを変化させます。半音数には曲線 {t, v}(秒 → 半音数。点間は直線で、端の外側では一定。ゲインラインと同様)または t => semitones を指定できます。値がゼロの位置では音声は元のままです。{ voice: true } は、pYIN のピッチトラック上で検出された声自身の声門周期の間隔を変更します(TD-PSOLA、オプションの @audio/tune-curve)。フォルマントと子音を維持し、対象は単一の声です。範囲の端は声のピッチの変化速度に合わせて滑らかに移行し、周期は入力音声の位置に戻ります。{ method } は別の方法でピッチを変更し、モジュールはそのときだけ読み込まれます(@audio/shift-*):'vocoder'、'formant'(声の音色を維持)、'psola'、'wsola'、'lpc'、'transient'、'hybrid'、'hpss'、'sms'、'sample'、'delay'、'ola'、'granular'、'paulstretch'、または 'auto'(@audio/shift が音に応じて選択し、すべてを読み込みます)。デフォルトの 'phase-lock' はストリーミングと曲線への追従に対応し、voice も使用できます。それ以外は一定の半音数で変更対象を一度にレンダリングします。範囲を指定した場合は、10 ms かけてフェードインとフェードアウトを行います。
≡ Melodyne のピッチ描画
.intonation(factor)声の抑揚を、平均ピッチを基準に広げたり平坦にしたりします:1 は元のまま、0 は単調な音程、2 は幅を 2 倍にします。声自身の周期の間隔を再調整します(pitch({ voice: true }) と同様)。タイミング、フォルマント、子音を維持し、対象は単一の声です。
≡ Melodyne のピッチ変調、Praat のピッチレンジ係数
.formant(semitones)ピッチを維持したままフォルマント(スペクトル包絡、つまり声の母音や頭の大きさ)を移動させます。数値、曲線 {t, v}、または t => semitones を指定します。あらゆる音に使用できます。pitch() と組み合わせると、声自身のフォルマントを維持することも、別の声のフォルマントを適用することもできます。
≡ Melodyne のフォルマントツール、Praat のフォルマントシフト比
.remix(channels)チャンネル数を指定します(ITU-R BS.775 に従ってダウンミックス:7.1 → 5.1、ステレオ、モノラル)。またはマップを指定します:[1, 0] は左右を入れ替え、null は無音チャンネルを表します。
すべてのオペレーションは末尾に {at, duration, channel} の範囲を取ります。ただし、チャンネルを変更する remix と crossover、およびタイムラインを維持するすべての mix は例外です。範囲では、出力のうちどれだけを聴かせるかを指定し、残りは入力になります。値は 0〜1、または時間に沿った曲線 {t, v} です({ mix: { t: [11.99, 12, 14, 14.01], v: [1, 0, 0, 1] } } は 12 秒から 14 秒まで音をオフにします。これは RX の「選択範囲を修復」と同様です。エフェクト独自の mix は、そのエフェクトに適用されます)。時間は秒または文字列('1:30'、'2m')で指定します。負の値は末尾から数えます。FFmpeg の短縮名は長い名前と同じように使えます。duration の代わりに d、crossfade の代わりに xfade を使えます(a.remove({ at: 1, d: 0.5, xfade: 0.01 }))。
a.trim(-30)                               // strip silence below -30dB
a.remove({ at: '2m', duration: 15 })      // delete 2:00–2:15, close gap
a.remove(12.3, 0.4, '10ms')               // cut a breath, crossfaded: no click
a.insert(intro, { at: 0 })                // prepend; .insert(3) appends 3s silence
a.copy(60, 30).paste(120)                 // duplicate the chorus at 2:00
a.cut(2, 1).paste(5)                      // move 2s–3s to 5s of the shortened timeline
a.move({ at: 2, duration: 1, to: 5 })     // slide 2s–3s over 5s–6s, silence left at 2s–3s
let [pt1, pt2] = a.split('30m')           // zero-copy parts
let hook = a.clip({ at: 60, duration: 30 })  // zero-copy excerpt
a.stretch(1.1)                            // 10% longer, same pitch
a.warp([[1, 1], [2, 2.4], [3, 3]])        // the hit at 2s lands at 2.4s; 1s–3s keeps its length
a.pitch(-2)                               // 2 semitones down, same tempo
a.pitch({ t: [1, 1.2, 2, 2.2], v: [0, 3, 3, 0] }, { voice: true })  // a note drawn 3 semitones up, formants kept
a.intonation(1.5, { at: 2, d: 3 })        // 2s–5s: every rise and fall half as wide again
a.formant(-2)                             // a larger, darker voice on the same notes
a.remix([0, 0])                           // L→both; .remix(1) for mono
処理
メソッド                        説明                                                                                                                
.gain(dB, opts?){ unit: 'linear' } を指定すると、倍率を受け取ります。
.fade(in, out?, curve?)曲線は 'linear'、'exp'、'log'、'cos' から選べます。audio.op('fade').curves に関数として用意されています。{start, end} は 0〜1 のレベルで、任意のレベル間をフェードします(ダッキング)。{mid} は振幅が半分になる点を調整します。
≡ Audacity adjustable-fade
.normalize(target?, mode?)DC 成分を除去し、ノーマライズします。ラウドネスの目標値では真のピーク上限が維持され、デフォルトは -1 dBTP です。先読みリミッターを適用してから、下げた分のラウドネスを補います。Apple Podcasts、Spotify、EBU R 128(ITU-R BS.1770-4)向けのプリセットがあります。
'podcast' -16 LUFS
'spotify' -14 LUFS(YouTube、Tidal、Amazon Music も同様)
'broadcast' -23 LUFS
-18, 'lufs' 任意のラウドネス、-3 ピーク dB、引数なし:ピーク 0 dBFS、'rms' モード
オーディオインスタンス:統合ラウドネス
{ ceiling: -2 } dBTP、false でオフ
{ dc: false } DC 成分を維持
{ adaptive: true } ライブストリームで有効にすると、すぐに開始します。ゲインはこれまでに聞こえた音に応じて変化し、ピークモードでは目標値自体となる上限が、まだ聞こえていない音を保護します。これを指定しない場合、選択範囲全体に同じゲインが適用されるため、ライブストリームでは終了まで待機します。
≡ FFmpeg loudnorm
.roomtone(threshold?)デジタル無音(-90 dBFS 未満が 10 ms 以上続く箇所:編集で取り除かれた無音区間、pad())を、録音に含まれるルームトーンで埋めます。ルームトーンとは、0.3 秒間変化せず、プログラム音声より 20 dB 低い音量の静かな区間です。.trim().pad(1.5, 2).roomtone() を使うと、オーディオブックのチャプターの両端にルームトーンが加わります(ACX はデジタル無音を許可していません)。すべての無音区間がゲート処理またはカットされている場合、取り出せる音はないため、何も変わりません。
≡ iZotope RX Ambience Match
.mix(source, at?, gain?)at 秒の位置に重ねます。ソースのレベルは gain dB です。
≡ FFmpeg amix weights
.crossfade(source, duration?, curve?)オーバーラップさせて末尾に追加します。デフォルトは 0.5 秒です。似た素材には 'cos'(デフォルト)が適しています。異なるトラック間で音量を保つには 'equal'(等電力)を使います。いずれも audio.op('crossfade').curves にあります。ソースを指定せず .crossfade({ at, duration }) とすると、エディターで選択範囲をクロスフェードするように、その範囲の前後をクロスフェードします。範囲の前の音が後の音へとフェードし、範囲自体は削除されます。
≡ FFmpeg acrossfade
.pan(value, opts?)−1 は左、0 は中央、1 は右です。
.write(data, {at?})at から raw PCM または別の音声で上書きします。テープに録音して既存の音を上書きするのと同様に、末尾を超える部分があれば長さが延びます。
.transform(fn)インラインの (input, output, ctx) => void です。シリアライズされません。
a.gain(-3)                                // reduce 3dB
a.gain(6, { at: 10, duration: 5 })        // boost range
a.gain(t => -12 * Math.cos(t * TAU))      // automate over time
a.fade(0.5, -2, 'exp')                    // 0.5s in, 2s exp fade-out
a.normalize('podcast')                    // -16 LUFS, -1 dBTP
a.normalize(-27, 'lufs', { ceiling: -2 }) // Netflix
a.mix(voice, { at: 2 })                   // overlay at 2s
a.mix(bed, 0, -18)                        // music bed, 18 dB under
a.crossfade(next, 2)                      // 2s crossfade into next
a.crossfade(song2, 4, 'equal')            // equal-power, for unrelated tracks
a.pan(-0.3, { at: 10, duration: 5 })      // pan left for range
フィルター
メソッド                        説明                                                                                                                
.highpass(freq, order?)、.lowpass(freq, order?)バターワース・パスフィルター。偶数の整数次数 ≥ 2:2(12 dB/oct、デフォルト)、4(24)、6、8、… その他の次数は拒否されます。
.bandpass(freq, Q?)、.notch(freq, Q?)バンドパス/ノッチ。
.allpass(freq, Q?)位相シフト、振幅は一定です。
.phase(angle?)すべての周波数の位相を angle 度だけ回転させます(ヒルベルト変換。数値、カーブ {t, v}、または t => degrees):振幅、RMS、ラウドネスはそのままで、-angle で元に戻ります。180 はサンプルごとに極性を反転します({ channel: 1 }:1 チャンネル)。未設定の場合は、ピークを最も低くする時間経過に応じた角度をチャンネル全体に適用し、どのチャンネルも上昇させません。音声のゼロを中心としたばらつきがより均等になり、VoiceBank の2つのテスト用スピーカーで、各30文を使用した平均ではピークが0.7 dB、0.8 dB低下し、最大で2.9 dB低下します。2つの声が交互に話す場合は、それぞれに独自の角度を適用します。ストリームの遅延は0.28秒です。
≡ iZotope RX Phase
.lowshelf(freq, dB)、.highshelf(freq, dB)シェルフ EQ。
.eq(freq, gain, Q?)パラメトリック EQ。
.filter(type, ...params)タイプ名またはカスタムフィルター関数で指定します。

すべてバイクアッドです。

a.highpass(80).lowshelf(200, -3)          // rumble + mud
a.eq(3000, 2, 1.5).highshelf(8000, 3)     // presence + air
a.notch(50)                               // remove hum
a.allpass(1000)                           // phase shift at 1kHz
a.phase()                                 // the peaks lowered, nothing heard
a.phase(180, { channel: 1 })              // the right channel's polarity
a.filter(customFn, { cutoff: 2000 })      // custom filter function
エフェクト
方法                        説明                                                                                                                
.vocals(mode?, {model?})ミッド/サイド:'isolate'(デフォルト)はセンターを残し、'remove'はサイドを残します。modelを指定すると、代わりに学習済みモデルで分離します。'mel-roformer'(KimのMel-Band RoFormer、MITライセンスの重み、ボーカルのみ、WebGPUがある環境では実行。MUSDB18プレビューのボーカルで12.08 dB SDRとここでは最高、M4 Maxでリアルタイムの0.44倍)、'scnet-large'(SCNet、MITライセンスの重み)、'umxhq'(Open-Unmix、MITライセンスの重み)、または'htdemucs'(Hybrid Transformer Demucs、研究目的のみの重み)を、オプションの@audio/neural-separate経由で使用します。その後'remove'を指定すると、モデルのボーカルを差し引くため、2つを足すとサンプル単位で入力に戻ります。つまり、声とそれ以外を別々に修復してミックスします(Nodeではaudio.memo = new Map()によりモデルは両方に対して一度だけ実行されます。プレイグラウンドでは「Split the voice to a new track」です)。'scnet-large'と'scnet'はホスト型です。それ以外の重みはローカルにエクスポートするか(方法)、weightsから配信できます。
≡ SoX oops;SCNet、Demucs、Open-Unmix
.rebalance(vocals?, bass?, drums?, other?, {model?, residual?, step?})曲のボーカル、ベース、ドラム、それ以外をそれぞれ独立したレベル(dB、−Infinityでミュート)にします。分離モデルが入力を4つのステムに分け、それぞれの変更分を元に加えるため、各ステムを0 dBにすればサンプル単位で入力がそのまま残ります。モデルがどのステムにも割り当てなかった成分はそのままか、residual dB(−Infinityならステムのみ。つまり、単独のステムと、入力からそのステムを差し引いたものを足すと、サンプル単位で入力に戻ります)になります。モデルは'scnet-large'(デフォルト:SCNet-large、MITライセンスの重み、169 MB)、'scnet'(43 MB、所要時間は3分の1)、'htdemucs'(研究目的のみの重み)、または'umxhq'を、オプションの@audio/neural-separate経由で使用します。重みはローカルにエクスポートするか(方法)、weightsから配信できます。入力は11秒のセグメントに分けて一度だけ分離し、各セグメントをstep(0.5)の間隔で処理します(0.25なら各サンプルを4回聴き、所要時間は2倍になりますが、0.07~0.17 dB改善します)。ゲインを動かすと、ステムが再び読み込まれます。MUSDB18テストプレビューで、各ステムを単独で再生した場合のBSSEval v4 SDRは、ボーカル・ベース・ドラム・その他の順に10.75・8.17・10.30・6.94。iZotope RX 12 Music RebalanceのBest設定は10.89・9.66・9.85・6.45で、50曲中33曲、32曲、38曲、32曲で上回ります。ボーカルを6 dB上げた場合は20.2 dB対19.5、ドラムを6 dB下げた場合は21.9対20.9です(bench/rx/separate.mjs)。
≡ iZotope RX Music Rebalance
.scene(dialogue?, music?, effects?, {model?})サウンドトラックのセリフ、音楽、効果音をそれぞれ独立したレベル(dB、−Infinityでミュート)にします。分離モデルが入力を3つのステムに分け、それぞれの変更分を元に加えるため、各ステムを0 dBにすればサンプル単位で入力がそのまま残ります。モデルは'mrx'(デフォルト:MRX、Petermannら、ICASSP 2022、MERLのMITライセンスの重み、122 MB、リアルタイムの5分の1)または'tiger'(TIGER、ICLR 2025、Apache-2.0ライセンスの重み、29 MB、所要時間は約50倍。テストクリップ30件ではMRXの10.9・5.2・5.7 dBに対し12.7・10.2・8.1 dB、セリフを6 dB上げた場合は18.7に対し21.0)を、オプションの@audio/neural-separate経由で使用します。重みはローカルにエクスポートするか(方法)、weightsから配信できます。入力は一度だけ分離し、ゲインを動かすとステムが再び読み込まれます。Divide and Remaster v3の英語テストセット(60秒のクリップ150件)でのSNR中央値は、セリフ・音楽・効果音の順に11.8・5.3・6.0 dBです(セリフをdeepfilter(0)に通した場合は10.5、著者らのBandit v2は15.6・10.4・9.9、重みはCC BY-SA)。セリフを6 dB上げた場合、真のリミックスとの差は18.9 dBで、そのままの場合の7.2 dBを上回ります(bench/rx/scene.mjs)。RX 12 Scene RebalanceはPro Tools(AAX)内でのみ実行されます。未測定です。
≡ iZotope RX Scene Rebalance
.dither(bits?, {shape?})TPDF。デフォルトは16ビットです。shape: trueを指定すると、2次ノイズシェーピングを追加します。量子化ノイズが約Nyquist/2より上に移動し、聴感上静かになります。
.crossfeed(freq?, level?)ヘッドホンのクロスフィード。デフォルトは700 Hz、0.3です。
≡ SoX earwax、bs2b
.convolve(ir, mix?, {normalize?, tail?})インパルス応答を通した音、つまり部屋、プレート、キャビネット、マイクで収録した音です。irにはファイルまたはURL、オーディオインスタンス、サンプルのチャンネルを指定でき、サウンドのサンプルレートにリサンプリングされます。チャンネルcは、折り返しながらIRのチャンネルcを通ります。レイテンシーはありません(Gardnerの分割畳み込み:先頭は直接処理し、その後ろをFFTパーティションで処理)。減衰音は末尾の後までレンダリングされます(tail: falseならレンダリングしません)。mixは0~1(1)、normalize: trueはIRを単位エネルギーに正規化します。
≡ Pedalboard Convolution、FFmpeg afir
.resample(rate, {type?})アップサンプリングではデフォルトで線形補間、ダウンサンプリングではデフォルトでアンチエイリアス処理された窓付きsincを使い、比率に応じてタップ幅を広げます。type: 'sinc'または'linear'で方式を指定できます。
.crossover(...freqs)N個の分割周波数から、チャンネルごとにN+1個の帯域を生成します。順序は帯域優先です。Linkwitz-Rileyの4次フィルターを使います。帯域を合計するとフラットに戻ります。
≡ FFmpeg acrossover
.match(ref, amount?)マッチEQ:最大8つのパラメトリックバンドを、参照音/ソース音のスペクトル比に合わせて調整します。音色のみを合わせ、ラウドネスはnormalizeで調整します。ストリームでは{lookahead}秒(10秒)遅れて処理し、音を聴きながらフィットし直します。{ midside: true }を指定すると、ステレオペアのミッドとサイドを別々に合わせ、サイドレベルも参照音の幅に合わせます。
≡ iZotope Ozone Match EQ
.align(ref, {within?, span?, drift?})参照音と一緒に再生できるよう、時間をずらして位置を合わせます。別の場所で作り直したり別録りしたパートを元の位置に戻し、遅れている場合は先頭を切り、早い場合は前に無音を入れます。波形が一致するサンプル位置までの遅延をGCC-PHATで求め、一致しない場合はスペクトルフラックスでオンセットから求めます。±within秒(10秒)以内を対象とし、最初のspan秒(60秒)から読み取ります。両方の音声が最後の20秒まで続き、その間に遅延が増えている場合(drift: falseならスキップ)、まずサンプルレートを合わせます。別々のクロックで動くコピーを参照音のクロックに合わせて読み戻すため、ピッチも一緒に変わります。別のテンポで演奏されたパート(±10%)は、ピッチを保ったまま参照音に伸縮され、bench/align.mjsの大半では両端のずれが2 ms以内になります。
.master(ref, opts?)参照トラックに合わせてマスタリングします。まずミッドとサイドをmatchし、次に参照音の統合ラウドネスに合わせてnormalizeします。上限は-1 dBTP({ ceiling })です。
≡ Matchering
.auto(type?, {intensity?, targetLufs?, ceiling?})音声の内容に応じて録音を修復・仕上げます(@audio/chain)。まず測定し、各修復を個別の根拠に基づいて適用します(declip、declick、deplosive、dehum、denoise、dereverb、deesser)。測定上必要な場合にのみEQ(クリーンな音声のばらつきの範囲を保ち、スピーチの目標に近づけます)、グルー(ラウドネスレンジが12 LUを超える場合)、ラウドネス処理を行います。typeの目標('speech'がデフォルトで−16 LUFS、'music'は−14、'voice-music')に合わせ、真のピークがceiling dB(−1)未満になるよう、必要なピークに最大6 dB × intensityのトゥルーピークリミッティングを行います。何も必要ない録音は、レベル以外はそのまま返します。音声の下にあるベッド音は、@audio/neural-denoiseがインストールされていればDeepFilterNet3(deepfilter()のモデル。ノイズを60 dB × intensity低減し、適用内容をレシピに記録)で処理し、そうでなければOM-LSAで処理します。'speech'では音声を残します。intensityは0~2(1)で、処理の強さを調整します。0にすると、ゲインを上限で止めます。クリーンな録音に複数の不具合を加えた音声(bench/rx/assistant.mjs)での修復結果を、設定を調整したiZotope RX 12 Repair Assistantと比較すると、スピーチPESQは2.56に対して2.99、SI-SDRは13.0に対して18.4 dB、DNSMOS OVRLは3.12に対して3.12、音楽ODGは−2.23に対して−1.69です。クリーンなスピーチは3.81に対して4.46、定常ベッド音はPESQ 2.94に対して2.97です(DEM​​ANDではRXが優位で、2.53に対し2.90。9件中4件はベッド音なしと判定されます)。ニューラルパッケージがない場合、スピーチは2.79、ベッド音は2.39と2.07です。auto()全体では、スピーチの89%、音楽の98%が目標から1 LU以内になり、真のピークは最大でも−1.00 dBTPです。リミッティングによるクリーンなミックスのODGへの影響は0.30で、修復のみの−0.22、入力の0.21に対して悪化しますが、クリーンな声には影響しません(PESQ 4.45)。
≡ iZotope RX Repair Assistant、Dolby.io Media Enhance
.spectral(band?, gain?, {at, duration})時間×周波数の範囲にゲインを適用します。bandは[lo, hi] Hzです。デフォルトではその帯域を除去します。
≡ Audacityのスペクトル編集、FFmpeg afftfilt
.repair(band?, {at, duration, method?, window?})周囲の音から損傷した範囲(ドロップアウト、ビープ音、クリックの連続)を再構築します。methodの'auto'(デフォルト)は、window秒(10秒)前までを検索し、シームレスにつながる区間を移植します。それが見つからない場合、最大70 msまではAR補間、それより長い場合は正弦波でつなぎます。'ar'、'sinusoidal'、'similarity'、'spectral'を指定すると方式を固定できます。
≡ iZotope RX Spectral Repair
.declick(threshold?, longest?, {at?, duration?})クリックを除去します。レコードのパチッという音、接合不良、デジタルのノイズ、声の口のクリック音などが対象です。各音が周囲のAR予測誤差のthreshold倍(8倍)を超えた場合に検出します。音の広がりや鳴り方から最も適切な音を推定し、両側46 msの範囲から、その下にあるはずの音を再構築します。2.5~15 ms離れた似たパルス(声や弦をはじく音)、音そのものの励起(破裂音やアタック)、またはlongest ms(6 ms)を超えるバーストは正常な音とみなし、変更しません。{ at, duration }を指定すると、その範囲内だけでクリックを探します。類似音や長さを理由に除外されるものはありません。クリックが届かない部分は何も変わりません。約0.9秒遅れてストリーミング処理します。周囲の音の5倍の大きさのクリックでは、パチッという音を34 dB、グリッチを46 dB、口のクリック音を28 dB低減します。測定したすべての種類と大きさで、iZotope RX 12 De-clickとMouth De-clickより多く除去します(@audio/denoise-declickのREADME)。
≡ iZotope RX De-click、Audacity Click Removal
.denoise(reduction?, threshold?, {noise})一定のノイズ(ヒス、ハムやブザー、ファン、部屋の環境音、テープノイズ)を除去します。ノイズだけが再生されている部分からノイズを学習します。noiseには、演算の入力の{ at, duration }、その複数指定、またはstat('print')で保存したノイズプリントを指定します。全体をreduction dB(12 dB)低減するか、演算独自の{ at, duration }内だけ、またはbandの[low, high] Hz内だけを低減し、それ以外はそのままにします。残るのは同じノイズを静かにした音で、音楽的な音色は残りません。threshold(dB)を上げるとノイズプリントのレベルが上がり、より小さい音もノイズとして扱われます。一定のノイズにはOM-LSA(@audio/denoise-omlsa)を使い、チャンネルごとに個別のノイズプリントを使用します。ライブソースでは、範囲が届いてから一度レンダリングします。VoiceBank+DEMANDのPESQでは、各話者が話し始める前の0.5秒からノイズを学習した場合、ノイズ入りは1.97、omlsa()は2.40、denoise()は2.48です。変動するノイズにはomlsa()またはdeepfilter()を使います。
≡ iZotope RX Spectral De-noise(Learn)、Adobe Audition Noise Reduction(ノイズプリント)、Audacity Noise Reduction
.recover(cutoff?)電話回線、狭帯域コーデック、16 kHzファイルなどでcutoff Hzより上が失われた声の帯域を、その声自身の倍音から再構築します。pYINでピッチを求め、帯域の境界より上の各倍音を、下の倍音が設定するレベル(1オクターブあたり12 dB低下)で合成し、その間の息の音はノイズとして合成して2 dB低下させます。入力にその帯域がない部分だけに加えるため、入力のロールオフにつながり、境界より下はそのままです。指定がなければ、長期スペクトルが3分の1オクターブ以内に25 dB落ち、そのまま下がり続ける位置をカットオフとします(声がこれほど急にロールオフすることはありません)。位置がなければ何も変わりません。VoiceBankのテストセットを8 kHzと16 kHzにカットした場合、再構築帯域の対数スペクトル距離は13.9 dBと12.3 dB、sbr()は20.0 dBと16.7 dB、入力は41.3 dBと40.6 dBでした(bench/recover.mjs)。帯域を追加するとPESQは低下するため(bench/recover.py)、順位をつけるにはまだ聴感テストが必要です。
≡ iZotope RX Spectral Recovery
.deepfilter(limit?, {floor?, music?, weights?, device?}), .rnnoise(limit?)オプションの@audio/neural-denoise経由で、ニューラル音声ノイズ除去を行います。キー入力、交通音、にぎやかな部屋など、変動するノイズも除去します。deepfilterはDeepFilterNet3を実行します。8 MBのモデルは一度ダウンロードされ、レンダリング前に入力全体を処理します。rnnoiseはパッケージに含まれる重みを使ってRNNoiseをストリーミング処理し、30 ms遅れます。limitはノイズをどれだけ下げるかをdBで指定します。deepfilterでは18が、声自体がフィルター処理されたように聞こえる前の最大値です(DNSMOS SIGは18までは維持され、それを超えると低下します)。そのため、部屋の環境音は残ります。また、声よりfloor dB(40 dB)以内のノイズはその下限まで下げられるため、声と同じくらい大きいノイズも、声より18 dB低い位置に残すのではなく除去します。rnnoiseでは16が、声に影響し始める前の最大値です。RNNoiseはノイズがなくても単語の語尾を下げます(16では10 dB、上限なしでは31 dB)。0を指定するとその動作を緩和します。deepfilterは、モデルがノイズとみなす長く伸びた歌声の音符を保ちます(VocalSetでは1.9 dBの低下で、39 dBではありません)。また、16 kHzファイルやコーデックの空の高域を、モデルの学習時のノイズフロアとして扱います(16 kHz VoiceBank+DEMANDのPESQは2.83で、2.72ではありません)。VoiceBank+DEMANDのPESQは、ノイズ入り1.97、wiener() 2.19、rnnoise() 2.49、deepfilter() 3.05、deepfilter(0) 3.15、iZotope RX 12 Dialogue Isolate 2.72です。声より5~−5 dB低いノイズ、雑音、音楽のベッド音や室内音では、deepfilter()は1.99でRXの1.86を上回ります(bench/rx/isolate.mjs)。音楽のみの場合は変更せずに通過します(music: 'enhance'を指定すると音楽も強調されます)。
≡ DeepFilterNet、RNNoise、iZotope RX Dialogue Isolate
.dereverb(reduction?, {music?, method?, weights?, device?})ニューラルモデルを使って、声から初期反射音と残響の余韻を含む部屋の響きを除去します。オプションの@audio/neural-separate経由で、anvuewのルーム・ディリバーブを使用します。pyroomacousticsでシミュレーションした室内の音声を使って学習したモノラルのBand-Split RoFormerです(GPL-3.0ライセンスの重み、60 MB。一度ダウンロード)。レンダリング前に入力全体を処理し、チャンネルは別々に処理します。部屋の響きをreduction dB(60なら完全に消え、12なら少し残ります)低減し、モデルが除去した成分をミックスし直すため、値を動かしてもモデルは再実行されません。モデルにとって声以外はすべて部屋の響きなので、音楽はそのまま通過します(music: 'pass'は、@audio/neural-denoiseの音声/音楽ガードです。deepfilterと同様、録音とモデルの音声の両方で判定します。長い残響は声を伸びた音符のように響かせるためです)。音楽のベッド音に重なる声は音声とみなされ、ベッド音も部屋の響きと一緒に処理されます。モデルが学習していないMIT IR Surveyの19室の音声(bench/rx/dereverb.mjsのテスト、T60は0.38~1.85秒)では、PESQは1.39から2.65、STOIは0.77から0.94になり、余韻は15.6 dB低下します(長い録音では1.37から2.58、17.5 dB低下)。設定を調整したiZotope RX 12 De-reverbの1.45、残響をオフにしたDialogue Isolateの1.79を上回ります。声より10 dB低いノイズがある場合は1.26から1.70になり、RX Dialogue Isolateは1.33です。ドライ音声は4.64から4.55に低下し、その125 Hzのオクターブ帯は2.1 dB下がります。ガードを通した音楽は、すべてのオクターブで0.9 dB以内に戻ります(MUSDB18プレビュー、GuitarSet、4曲:そのままの状態、フレーズに分割した状態、室内音を加えた状態)。一方、室内音があると、歌声などの声はモデルとガードの両方で、オクターブ帯域が最大6 dB低下します。method: 'wpe'ならモデルは不要です。重み付き予測誤差と残響後期のゲイン(@audio/denoise-dereverbのstrength)を使い、残響後期を約6 dB低減します(PESQ 1.53)。ドライ録音、間がない録音、音楽は変更しません。
≡ iZotope RX De-reverb、Dialogue Isolateの残響処理
.vocos({crossover?, weights?, device?})Vocos(ニューラルボコーダー。Siuzdak、ICLR 2024、charactrのMITライセンスの重み)で声を作り直します。オプションの@audio/neural-vocode経由で処理します。メルスペクトログラムの各STFTフレームについて、振幅と位相を新たに予測するため、別のボコーダーが残した音(TTSのフレームの鳴り残りや、10、20、30 ms後のかすかな複製音)がVocosの音に置き換わります。Vocosは12 kHzより上を生成しないため、Linkwitz-Rileyで分割し、crossover Hz(11000)より上は入力を保持します。0ならVocosの出力のみを使います。27 MBのモデルは一度ダウンロードされます。音声用のボコーダーのため、音楽は変化して戻ります。
.derustle(reduction?, {ambience?})ピンマイクの衣擦れを声から除去し、部屋の一定の環境音を残します。deepfilterのモデルを使い(同じ入力に対する実行を共有)、モデルが除去した音をdeepfilterと同じようにミックスし直します。衣擦れを声よりreduction dB(45 dB)低くし、部屋の環境音は12 dB低くします(ambience: falseならすべて除去します)。設定は、10~37秒の話者の声の下に衣擦れを加えて選びました(FreesoundのCC0およびCC BYの衣擦れとマイク取り扱い音。オープンライセンスのラベリアマイクの衣擦れ音はありません)。テストでは、話者55人、衣擦れが声と同じ大きさの場合、PESQは1.21から2.13、SI-SDRは−0.3から13.5 dBになりました。部屋の音のみでは4.37、クリーンな録音では4.61です(deepfilter()では2.12、4.31、4.59。iZotope RX 12 Dialogue Isolateと、RXでホスト可能なダイアログ分離モデルでは2.06、2.96、3.96)(bench/rx/derustle.mjs)。RX 12 De-rustleはPro Tools(AAX)内でのみ実行されます。未測定です。
≡ iZotope RX De-rustle
.deconstruct(tonal?, noise?, transient?, {separation?})音のトーナル成分、ノイズ成分、トランジェント成分を、それぞれ独立したレベル(dB)にします。時間方向と周波数方向のメディアンフィルター(Fitzgerald 2010)を使い、separation(2。Driedger、Müller、Disch 2014)に応じて、どちらでもないものをノイズとします。チャンネル間でソフトマスクを共有します。各成分を足すと入力に戻ります。すべてを0 dBにすれば、サンプル単位で入力がそのまま残ります。和音は100%トーナル成分に、クリック音はトランジェント成分に、ヒスは68%がノイズ成分に入り(残りの各成分には1%ずつ入ります)。
≡ iZotope RX Deconstruct
.azimuth(delay?)ステレオペアの時間と極性をそろえ、2つ目のチャンネルを1つ目に合わせます。指定がない場合、KnappとCarterの1976年の重み付けを使った一般化相互相関で毎秒遅延を測定し、サンプル間を精密化します(正確な小数サンプル単位のシフトを0.0001サンプルの精度で復元します)。ずれを追従し、逆配線されたチャンネルは正しい向きに戻します。ミックスのステレオイメージのように、すでにそろっているペアはサンプル単位でそのままにします。delayをmsで指定すると手動設定できます。
≡ iZotope RX Azimuth
.dewow(mode?)ワウとフラッターを補正します。ディスクやテープの速度を時間ごとに測定し、その逆数に従って音を読み戻します。音楽自体の音符(ディスクの1回転ごとのワウ、'partial')、パイロット音または基準音('reference'、refFreq)、あるいは1つの声のピッチ('pitch')を使います。ワウが確認されなければ何も変えません。ワウのない録音はサンプル単位で元のまま戻ります(@audio/denoise-dewow)。
≡ iZotope RX Wow & Flutter
.desqueak(squeak?, {pick?, amp?})ギターの巻弦上を指が滑るときの弦のきしみ音を低減します。音符の特徴ではないもの(93 msフレームで読み取る、ビンにとどまる倍音。ピック音の低い倍音やクリック音ではないもの)を基準に音符と区別します。45 ms以上続く各ビンを、きしみ音の周囲で保たれているレベルまで下げます。squeak dBが上限(30 dB)です。その下で鳴り続ける音符の倍音は維持され、きしみ音以外の録音はサンプル単位でそのままです。pick dBを指定すると、各ピック音のクリックを、15 ms後に鳴っている音符のレベルまで弱めます(-9なら、アタックを6~12 dB強くした録音を元に戻します)。amp dBを指定すると、一定のヒスやブザーを下げます(静かなフレームのノイズプリントを使ったOM-LSAで、音符のピークは保持します)。GuitarSetのテスト録音に対するiZotope RX 12 Guitar De-noiseとの比較では、きしみ音を追加した場合、誤差の低減は2.7 dBに対して3.3 dB、SNRは20.5 dBに対して23.2 dB、クリーンな録音で変更されたサンプルは12.9%に対して2.4%です。強すぎるピック音は、調整後で3.3 dBに対して8.9 dB。録音時のきしみ音では、中央値が13.5 dBに対して12.8 dBで、RXが処理するピック音とクリック音の半分を処理します(@audio/denoise-desqueak、bench/rx/guitar.mjs)。
≡ iZotope RX Guitar De-noise
.codec(format?, bitrate?, {quality?})非可逆コーデックで処理した音を返します。'mp3'(デフォルト)、'aac'、'opus'、'vorbis'をbitrate kbps(128)で処理します。'mp3'はquality(LAMEの-V:0が最高、10未満)でVBR処理できます。'gsm'はGSM 06.10フルレートで、8 kHzの13 kbps(1990年代の電話回線)です。エンコードしてから、その場でデコードします。各コーデックの遅延は、コーデック自身のギャップレス情報を使って補正し、その後相関で確認するため、入力と0.03サンプル以内でそろいます。A/B比較するか、コーデックが除去する音を聴いてみてください。コーデックはピークを変化させます。8つのMUSDB18ミックスの7秒の抜粋を-14 LUFS、-1 dBTP以下に正規化したマスターは、Opus 160 kbpsを通すと最大0.5 dB、Vorbisでは0.3 dB上回りました。MP3 320とAAC 256では0.1 dB未満でした。.codec('opus', 160).stat('truepeak')で測定できます。
≡ iZotope RX Streaming Preview、Pedalboard MP3Compressor、GSMFullRateCompressor
a.vocals()                                // isolate center-panned vocals
a.vocals('remove')                        // remove vocals (karaoke)
a.vocals({ model: 'umxhq' })              // vocals by a separation model
a.rebalance({ vocals: 6, drums: -3 })     // the vocals up, the drums down
a.rebalance(-Infinity)                    // a karaoke track
a.scene(6)                                // a film's dialogue 6 dB up over its music and effects
a.scene(-Infinity)                        // a music and effects track
a.dither(16)                              // TPDF dither to 16-bit
a.dither(16, { shape: true })             // noise-shaped
a.crossfeed()                             // headphone crossfeed
a.convolve('hall.wav', 0.3)               // 30 % of a captured hall
a.resample(48000)                         // resample to 48kHz (linear)
a.resample(96000, { type: 'sinc' })       // high-quality windowed-sinc
a.match(reference, 0.7)                   // 70% of the way to its tone
a.align(original)                         // a part remade elsewhere, put back where the original stood
a.spectral([1000, 4000], -30, { at: 2.1, duration: 0.3 })  // a cough
a.repair({ at: 1.2, duration: 0.05 })     // a dropout
a.repair({ at: 42, duration: 1 })         // a lost second of music: the passage that fits
a.declick()                               // every click
a.declick({ at: 12.31, duration: 0.02 })  // the clicks seen there
a.denoise({ noise: { at: 1.2, duration: 0.5 } })  // hiss learned from a pause, 12 dB down everywhere
a.deepfilter()                            // speech out of noise: room tone 18 dB down and kept, loud noise to 40 under the voice
a.rnnoise()                               // the same, streaming
a.dereverb()                              // the room off a voice
a.dereverb(12)                            // the room 12 dB down
a.derustle()                              // a clip-on mic's clothing rustle, the room kept
a.vocos()                                 // a TTS voice made again by a neural vocoder, its frame echo gone
a.deconstruct(0, -12)                     // the hiss 12 dB down, tones and attacks as they were
a.azimuth()                               // a tape's two tracks back in line
a.dewow({ mode: 'reference', refFreq: 1000 })  // a transfer's wow, read from its calibration tone
a.desqueak()                              // a guitar's string squeaks
a.desqueak({ pick: -9, amp: -20 })        // and its harsh picks, and the amp's hiss and buzz
a.codec('aac', 256)                       // what a 256 kbps AAC stream does to it
a.codec('gsm')                            // a phone call
入出力
メソッド                        説明                                                                                                                        
await .read(opts?)レンダリング済みPCMです。変換するには{ format, channel }を指定します。データがまだ届いているソースの場合、指定範囲のデータが届くまで待機し、全データを読む場合はソースの終端まで待機します(終わりのないストリームでは範囲を読み取るか、stream()を使用してください)。
await .save(path, opts?)エンコードして書き込みます。形式は拡張子から判定します。可逆形式ではソースのビット深度が維持されます。{ bitDepth, bitrate, quality, codec }でエンコーダーを設定します。m4aとmp3ではマーカーをチャプターとして書き込みます。出力はエンコードしながらストリーム出力され、終端で合計値をヘッダーに反映します(パイプでは「不明」のままです)。ライブソースからのm4aはフラグメント化されます。.mp4/.movに保存した動画ソースでは映像が維持され、音声トラックのみが変更されます。.edl、.otio、.fcpxmlではカットを書き込みます。
await .encode(format?, opts?)Uint8Arrayにエンコードします。'edl'、'otio'、'fcpxml'の場合は、カットをUTF-8で返します。
await .cuts(format?, opts?)編集内容を動画編集ソフト用のカットリストとして返します。'edl'(CMX 3600:Premiere、Resolve、Avid)、'fcpxml'(Final Cut Pro、Resolve)、'otio'(OpenTimelineIO)を指定できます。指定しない場合は{ fps, clips: [{ at, duration, from, rate, source }] }を返します。カット、移動、ギャップ、挿入ファイルがクリップの配置を決め、速度、伸縮、ワープが再生レートを設定します。マーカーも引き継がれます。処理内容はリストに含まれないため、処理済み音声を映像の下に配置してください。カット位置は動画トラックのフレーム(MP4/MOV)に合わせます。それ以外の場合は{ fps }(30)が使用され、音声との差は各位置で半フレーム以内です。タイムコードトラックはソースの時刻から始まり、カウント時にドロップフレームを処理します({ dropFrame })。CLIのsave cuts.edlでファイルを書き出せます。
.clone()編集内容は独立し、ページは共有されます。
.push(data, format?)プッシュ可能なインスタンスにPCMを入力します。.stop()で確定します。
let pcm = await a.read()                              // Float32Array[]
let raw = await a.read({ format: 'int16', channel: 0 })
for await (let block of a) send(block)                 // async-iterable over blocks
await a.save('out.mp3')                                // format from extension
await a.save('book.mp3', { bitrate: 192 })             // ACX: 192 kbps CBR
await a.save('master.wav', { bitDepth: 24 })           // 24-bit
await a.save('talk.mp4')                               // video in, video out
let bytes = await a.encode('flac')                     // Uint8Array
let b = a.clone()                                      // independent copy, shared pages

let src = audio()                                      // pushable source
src.push(buf, 'int16')                                 // feed PCM
src.stop()                                             // finalize
再生/録音
メソッド                        説明                                                                                                                
.play(opts?){ at, duration, loop, volume, rate, paused, device }を指定します。atのデフォルト値はcurrentTimeです(再生終了後は開始位置)。すでに再生中の場合は、途切れることなく指定位置に移動します。deviceには、IDまたは名前で出力デバイスを指定します(ページでは専用のコンテキスト上で再生され、そのデバイスに出力されます)。
.play({ from: b })bの現在の再生位置(範囲、ループ、音量、再生レート、一時停止状態)をクロスフェードで引き継ぎ、途切れることなく再生します。bは停止します。
.pause()、.resume()、.seek(t)、.stop()いずれも5 msかけて変化するため、クリックノイズが発生しません。seekはクロスフェードし、ループ中はその範囲内にとどまります。.stop()は録音も終了します。
.record(opts?)マイクを使用します。{ device, sampleRate, channels, monitor }を指定します。deviceには、IDまたは名前で入力デバイスを指定します。monitorでは、録音した音を編集内容に通して、入力されるそばからデフォルト出力(true)またはIDか名前で指定した出力に返します。約50 msの遅延があります(入力の読み取り、1ブロック分、出力のリングバッファに加え、編集処理自体の先読み分)。DAWでトラックのインサートを通してモニタリングするのと同様です。
≡ Pedalboard AudioStream
audio.devices()入力と出力を返します:{ input: [{ id, name, default }], output: [...] }。Nodeではプラットフォーム固有のID(CoreAudioのUID、WASAPIのエンドポイントID、ALSAの名前)が使われます。ページではenumerateDevices()が使われ、マイクの使用が許可されると名前が取得できます。
audio.contextページで共有される1つのAudioContextで、再生に使用されます。初回使用時に作成され、最初の操作で再開されます。再生前に独自のコンテキストを設定してください。

再生では、audio.context上のAudioWorkletに最大2秒先までレンダリングします(Nodeでは@audio/speaker)。そのため、メインスレッドがビジー状態でも再生は止まらず、play()の実行から数ミリ秒以内に音が出ます(デバイス自体のレイテンシーを除く)。再生中のインスタンスを編集すると、変更箇所は約50 ms後に聞こえます。先読みしてレンダリング済みの音声からクロスフェードして切り替わります。デコード中やプッシュ中など、データがまだ届いているソースでは、届いた分を再生し、追加データが届くと再生を続けます。チャンネル数は問わずそのまま再生され、ダウンミックスはデバイスが行います。

a.play({ at: 30, duration: 10 })          // play 30s–40s
await a.played                            // wait for sound
a.volume = 0.5; a.loop = true             // live adjustments
a.muted = true                            // mute without changing volume
a.playbackRate = 1.5                      // faster, the pitch kept
a.preservesPitch = false                  // the pitch follows the speed, as a tape's
a.pause(); a.seek(60); a.resume()         // jump to 1:00
a.highpass(80)                            // an edit while playing: heard where it happens
b.play({ from: a })                       // b takes over at the same place, crossfaded
b.stop()                                  // end playback or recording

await audio.context.audioWorklet.addModule('./scrub.js')  // your own nodes, on the same context
let scrub = new AudioWorkletNode(audio.context, 'scrub')

let mic = audio()
mic.record({ sampleRate: 16000, channels: 1 })
mic.stop()

await audio.devices()                     // { input: [{ id, name, default }, …], output: […] }
let take = audio()
take.compressor().plate(0.2)              // edits, heard as they come in
take.record({ device: 'USB', monitor: 'Headphones' })   // by id, name, or part of a name
メータリング
メソッド                        説明                                                                                                                
.meter(what, cb?)再生される内容のブロックごとの統計値を、再生中にリアルタイムで配信します。rms、peak、ms、min、max、dc、clipping、spectrum、または独自の値を指定できます。cb を指定しない場合は .value を読み取ります。{ value, stop() } を返します。ワーカーファサードでも同様に使用できます。ワーカーで測定し、ページに配信します。
オプション                        説明                                                                                                                
type統計値の名前、名前の配列、またはすべてのブロック統計値を対象とする場合は省略します。
channel1つのチャンネルには n、チャンネルごとには [n, m] を指定します。スカラー平均の場合は省略します(a.stat() と同様)。
smoothing1次EMAの時定数τ(秒)。
holdピークホールドの減衰時定数τ(秒)。
bins, fMin, fMaxスペクトラムの解像度と範囲(type: 'spectrum' の場合)。
a.meter('rms', v => draw(v))                                       // scalar avg across channels
a.meter(['rms', 'peak'], v => draw(v))                             // { rms, peak }
a.meter({ type: 'rms', channel: [0, 1] }, v => draw(v))            // [L, R]
a.meter({ type: 'spectrum', bins: 64, smoothing: 0.15 }, drawFFT)  // Float32Array of mel bins
a.meter({}, ({ delta, offset }) => draw(delta))                    // no type → all block stats

let m = a.meter({ type: 'rms' })                                   // pull form
requestAnimationFrame(function tick() { draw(m.value); requestAnimationFrame(tick) })
m.stop()                                                           // release
分析
メソッド                        説明                                                                                                                
await .stat(name, opts?)1つの値を返します。{ bins: n } を指定すると Float32Array を返し、範囲をn個の区間に分けた各区間の値を示します。つまり、量だけでなく位置もわかります(リスト、キー、スペクトラムは全体を返します。bins はスペクトラムとケプストラムのサイズを指定します)。名前の配列を指定すると、配列を返します。{ channel: n } で1つのチャンネル、[n, m] でチャンネルごとに指定できます。{at, duration} で部分範囲を指定します。
await .detect(opts?)1回の処理で { bpm, confidence, beats, onsets } を返します。{ channel } は stat と同様です。
await .check(spec)配信仕様に適合するかどうかを判定します。{ pass, rules: [{ name, value, unit, min, max, pass }] } を返します。'acx'(RMS、ピーク、ノイズフロア、ルームトーン、44.1 kHz)、'podcast'(Apple:-16 LUFS ±1、≤ -1 dBTP)、'spotify'(-14 LUFSで再生、≤ -1 dBTP)、'broadcast'(EBU R 128:-23 ±0.2 LUFS、≤ -1 dBTP)、'netflix'(ダイアログ -27 ±2 LUFS、≤ -2 dBTP)を指定できます。各上限値の出典は fn/check.js に記載されています。
統計                        説明                                                                                                                
:--:--
'db'ピーク振幅(dBFS)。
'rms'RMS 振幅(リニア値。CLI では dBFS を出力します)。
'noisefloor'最も静かな 0.4 秒間の RMS(dB):単語間の部屋鳴り(ACX Check の測定値。サンプル単位で正確です)。
'print'範囲のノイズプリント。denoise({ noise }) に渡す形式で、0~24 kHz の範囲を 23.4375 Hz 間隔で分割した 1025 バンドの dB 値です(RMS 0.01 のホワイトノイズは −40 と表示されます)。
'peak'max(|min|, |max|)(リニア値)。
'loudness'統合ラウドネス(LUFS、ITU-R BS.1770-4。サラウンドチャンネルは重み付けされ、LFE は除外されます)。
'momentary'、'shortterm'最大 400 ms/3 秒のラウドネス(LUFS、EBU Tech 3341)。
'dialog'音声のみのラウドネス(LUFS)。音声は自動的に検出されます(AES TD1008 dialog loudness)。
'dc'DC オフセット。
'clipping'クリップしたサンプル。16 ビットのフルスケール(±32767/32768)以上が対象です(スカラー値:タイムスタンプ、ビン分割時:件数)。
'silence'無音範囲を {at, duration} として返します。
'crest'ピーク/RMS(dB)。正弦波は約 3 dB、矩形波は約 0 dB です。
'centroid'スペクトル重心(Hz、明るさ)。
'flatness'スペクトルフラットネス:0 は調性音、1 はノイズです。
'correlation'L/R の位相相関(−1~+1)。モノラルの場合は 1 を返します。
'max'、'min'波形のビンごとのピーク包絡線。
'spectrum'メルスペクトル(dB、A 特性)。複数チャンネルの場合は電力の平均値です。
'cepstrum'MFCC。
'bpm'テンポ。
'beats'、'onsets'タイムスタンプを Float64Array(秒)で返します。
'hits'レベルが上昇(打撃音)または下降(停止)する位置を Float64Array(秒)で返します。各位置はアタックのゼロクロス、つまりカットするサンプル位置です。'onsets' が 23 ms ごとのブロックを読み取るのとは異なります。
'notes'[{time, duration, freq, midi, note, clarity}](pYIN + Tony note HMM)。robust: true を指定すると、ノイズや室内音響の影響下でも同じ情報を取得できます(ニューラル pYIN のステージ 1)。poly: true を指定すると、ポリフォニックな [{time, duration, freq, midi, note, velocity, bends}] を取得できます(Basic Pitch)。
'chords'[{time, duration, label, root, quality, bass, confidence}]:NNLS クロマ上の Chordino(Mauch & Dixon 2010)を参照プラグインと照合したものです。ラベルの例は 'Am'、'G7'、'C/E'、'N' です。
'key'{tonic, mode, label, confidence}(Krumhansl-Schmuckler)。
'voicing'範囲内で有声音が占める割合(0~1)。pYIN のピッチカーブ上で、10 ms ごとにピッチが検出されたフレームの割合です。
'hnr'有声音フレームにおける調波対雑音比(dB)。フレームごとに Praat の To Harmonicity (ac) と一致します(Boersma 1993)。有声音がない場合は null です。
'harmonic'周期成分のレベル(dB):各フレームの電力に周期成分の割合(Boersma の r)を掛けた値です。RMS とは異なり、ノイズを除去しても変化しません。編集後に音声として残った部分を示します。
'similar'{ at, duration }(咳、クリック音、ビープ音など)に似た音がほかにある位置を、[{ at, duration, score }] として返します。範囲の対数メルパッチについて、各バンドの中央値との差を取り、全体にわたってスライドさせながらピアソン相関を計算します。threshold(0.7)以上が対象です。band [low, high](Hz)を指定すると、その周波数帯だけを比較します。また、a.similar(range, opts) も使用できます。
≡ iZotope RX Find Similar
オプション:bpm、beats、onsets は { minBpm, maxBpm, delta, frameSize, hopSize } を受け取ります。notes は { minFreq, maxFreq, frameSize, hopSize, minDuration } を受け取ります。chords、key は { frameSize, hopSize, tuning } を受け取ります(44.1 kHz では 16384 サンプルのフレーム、その他のサンプルレートでは 0.34~0.51 秒のフレームを、それぞれ 8 分の 1 ずつずらします。tuning を Hz で指定しない場合、音声からコンサート A を読み取ります)。chords は boostN(コードなしのバイアス、0.1)も受け取ります。key は `method: 'nnls''pcp' も受け取ります。chordsには@audio/mir-nnls-chromaと@audio/mir-chordino が必要です。keyには@audio/mir-nnls-chroma が必要です。これらは参照プラグインの GPL-2.0-or-later に基づく翻訳版で、選択してインストールします(npm i @audio/mir-nnls-chroma @audio/mir-chordino)。method: 'pcp'を指定したkeyに必要なのは、MIT ライセンスの@audio/mir-chromaと@audio/mir-keyだけです。オプションの依存関係をスキップしない限り、これらはaudio とともにインストールされます。robust: trueを指定したnotesには@audio/neural-pitch が必要です(重みを内包)。YIN の代わりにネットワークのピッチ候補を使うことで、YIN では検出できない音符を保持します(Vocadito のオンセット F は、SNR 0 dB で 0.53 に対して 0.76)。一方、クリーンな音声ではわずかに劣るため、デフォルトは引き続き YIN です。poly: trueを指定したnotesは{ minFreq, maxFreq, minDuration, onsetThreshold, frameThreshold }を受け取り、初回使用時にモデルがダウンロードされる@audio/neural-transcribe が必要です。bends` は、11.6 ms ごとのフレーム単位での音符のピッチからのセント差を表し、33.3 セント刻みです(調律された音符は 0 と読み取られます)。
let loud = await a.stat('loudness')                       // LUFS
let [db, clips] = await a.stat(['db', 'clipping'])        // multiple at once
let spec = await a.stat('spectrum', { bins: 128 })        // frequency bins
let [min, max] = await a.stat(['min', 'max'], { bins: 800 }) // peak envelope for canvas rendering
await a.stat('rms', { channel: 0 })                       // left only → number
await a.stat('rms', { channel: [0, 1] })                  // per-channel → [n, n]
let gaps = await a.stat('silence', { threshold: -40 })    // [{at, duration}, ...]
let bpm = await a.stat('bpm')                             // 120.5
let beats = await a.stat('beats')                         // Float64Array [0, 0.5, 1, ...]
let { bpm, confidence, beats, onsets } = await a.detect() // full pipeline, one pass
let notes = await a.stat('notes')                         // [{time, duration, freq, midi, note: 'A4', clarity}]
let chords = await a.stat('chords')                       // [{time, duration, label: 'Am', confidence}]
let k = await a.stat('key')                               // {label: 'C', mode: 'major', confidence}
let coughs = await a.similar({ at: 12.3, duration: 0.4 })  // [{ at, duration, score }]: the other coughs
メタデータ
プロパティ                        説明                                                                                                                
.metaタグ:{title, artist, album, year, bpm, key, comment, pictures, raw, ...}。書き込み可能です。meta.raw には、形式固有のブロックが変更されずに保持されます(WAV bext/iXML、ID3v2 フレーム、FLAC ブロック)。
.meta.picturesカバーアート [{mime, type, description, data, url}]。.url は遅延生成される Blob URL(ブラウザー)またはデータ URL(Node)です。
.markers出力秒数での [{time, label}]。編集に応じて位置がずれるか、削除されます。
.mark(time, label?)time にマーカーを設定します。time は、それまでに編集された音声の秒数です。{at, duration} は領域を表します。後続の編集ではマーカーも引き継がれます。無音部分では、最も近い音からの距離を維持します。末尾より後では、その後の編集で音声がその位置まで伸びるまで末尾にとどまります。チェーンできます。
.regions[{at, duration, label}]。編集に応じて位置がずれるか、削除されます。

デコード時に解析され、保存時に書き込まれます。WAV、MP3、FLAC のラウンドトリップに対応しています。

let a = await audio('song.mp3')
a.meta.title                     // 'Track Name'
a.meta.artist = 'Me'             // mutate
img.src = a.meta.pictures[0].url // lazy Blob URL

a.crop({ at: 10, duration: 30 })
a.markers                         // re-projected — outside markers dropped, inside shifted

await a.save('edited.mp3')        // tags + pictures preserved
await a.save('stripped.wav', { meta: false })   // opt out
ユーティリティ
メソッド                        説明                                                                                                                
.on(event, fn)、.off(event?, fn?)購読/購読解除します。
.undo(n?)取り消した編集を返します。.run() でやり直せます。
.run(...edits)['type', opts] 形式の編集を適用します。操作パラメーター(value、freq など)と範囲キーを指定します。
.dispose()リソースを解放します。using に対応しています。
イベント                        説明                                                                                                                
'data'ページがデコード/プッシュされました。ペイロード:{ delta, offset, sampleRate, channels }。
'change'編集または取り消しが行われました。
'metadata'ストリームヘッダーがデコードされました。ペイロード:{ sampleRate, channels, estDuration }。再生時間を秒で示します。WAV、AIFF、FLAC、MP3 の Xing または VBRI フレーム、固定ビットレートなど、ヘッダーに記載があればその値を使い、なければファイルサイズから求めます。どちらも不明な場合は null です。
'timeupdate'再生位置(実際の再生音に基づき、約 1 秒間に 50 回)。ペイロード:currentTime。
'play'再生が開始または再開されました。
'pause'再生が一時停止されました。
'volumechange'音量またはミュート状態が変更されました。
'ended'再生が終了しました。末尾への到達、stop() の呼び出し、または play({ from }) による再生の引き継ぎで発生します。ループ再生では発生しません。
'progress'保存/エンコード中です。ペイロード:秒単位の { offset, total }。
a.on('data', ({ delta }) => draw(delta))  // decode progress
a.on('timeupdate', t => ui.update(t))     // playback position

a.run(
  ['gain', { value: -3, at: 10, duration: 5 }],
  ['crop', { at: 1, duration: 2 }],
  ['fade', { in: 1, curve: 'exp' }],
  ['insert', { source: ref, at: 2 }],
)
a.undo()                                  // undo last edit
b.run(...a.edits)                         // replay onto another file
JSON.stringify(a); audio(json)            // serialize / restore
プラグイン
メソッド                        説明                                                                                                                
audio.use(...plugins)@audio コントラクトファクトリー、{ stat, compute }形式の統計、{ codec, test?, decode?, encode? }形式のコーデック、audioを受け取る関数、またはレジストリ名を登録します。レジストリプラグインではuseは不要です。a.compressor()やa.stat('truepeak')を呼び出すと、初回使用時に読み込まれます。
audio.op(name, descriptor)opを登録します。process関数、または{ params, process, plan, resolve }形式を指定します。
audio.op(name?)1つのdescriptor、またはすべてのopを返します。
audio.stat(name, descriptor)統計を登録します。(chs, ctx) => [...]、または{ block, reduce, query }形式を指定します。
.plugin(ref, opts?)編集としてネイティブプラグインを追加します。VST3、CLAP、Audio Unit、LV2に対応し、オプションの@audio/host(Node)を介して、ファイル、名前、IDで指定します。パラメーターはキーで指定し、プラグイン独自の単位を使用します。関数または{ t, v }でオートメーションを設定します。レイテンシーは差し引かれ、テイルはレンダリングされます(秒数をtailで指定し、falseならなし)。プラグインが受け取る情報はnotes、midi、bpm、timeSignatureで指定します。keyはサイドチェーン、presetとstateはプリセットと状態、複数のプラグインを含むファイルの場合はpluginで1つを指定します。オプションと同名のパラメーター(mix、at)にはparamsを使用します。isolateを指定すると、独立したプロセスで実行されます。audio --pluginsでプラグイン一覧を、audio --plugins NAMEで各プラグインのパラメーターを表示します。Web Audio Module(WAM 2.0)は、モジュールのURLまたはクラスで指定でき、ページ内でも使用できます。WAM SDKがOfflineAudioContext(Nodeではweb-audio-api)内でホストし、再生前に入力をレンダリングして通します。補正遅延は差し引かれ、無音になるまで減衰をレンダリングします。パラメーターはIDまたはラベルで指定し、オートメーション、WAMイベントとしてのnotes、midi、bpmにも対応します。
≡ Pedalboardのload_plugin、DAWのインサート、WAMホスト

プラグインはエンジンなしでも実行できます。audio/batchは信号全体を、audio/streamはライブチャンクを処理します。プラグインチュートリアル。

import { compressor } from '@audio/dynamics-compressor/audio'
audio.use(compressor)                       // bring-your-own factory

a.freeverb({ room: 0.8 })                   // registry plugin: loads on first render; tail composes
music.ducker({ key: voice })                // sidechain via the key option
await a.stat('truepeak')                    // stat plugins land on a.stat()

audio.op('crush', { params: ['bits'], process: (input, output, ctx) => {
  let steps = 2 ** (ctx.bits ?? 8)
  for (let c = 0; c < input.length; c++)
    for (let i = 0; i < input[c].length; i++)
      output[c][i] = Math.round(input[c][i] * steps) / steps
}})
a.crush(4)                                  // custom op, chainable like built-ins

a.plugin('RX 12 De-click', { sensitivity: 6 })                  // native plugins: npm i @audio/host
a.plugin('AUDelay', { delayTime: 0.25, feedback: t => 20 * t })  // automated, on the timeline
audio(4).plugin('Surge XT', { notes: [{ time: 0, duration: 1, note: 'C4' }], bpm: 96 })
ワーカー
呼び出し                        説明                                                                                                                
audioWorker(source, opts?)同じAPIで、エンジンをWorkerで実行します。メインスレッドに残るのは数KBのファサードです。
audio(source, { worker: true })audio/workerをインポートすると、同様に動作します。
{ worker: new Worker(url) }独自のWorkerエントリーポイントを指定します。コーデック、プラグイン、独自のコードとメッセージを読み込んだ後、audio/workerが専用ポートで通信します。
expose(a) → id、audioWorker.adopt(id, { worker })Workerで作成したインスタンスを、ファサードとしてページに渡します。
audioWorker.contextページのAudioContextです。audio.contextと同じです。

境界を越えると、clip()、split()、clone()はプロミスを返し、opのエラーは'error'を発行します。関数は境界を越えないため、{t, v}形式のカーブを使用してください。play()はWorkerでレンダリングし、ページのAudioWorkletに直接送ります。メインスレッドが数秒間停止しても、音切れは発生しません。アーキテクチャ。

import audioWorker from 'audio/worker'
let a = audioWorker('track.mp3')            // decode/edits/stats/encode in a Worker
a.gain(-3).fade(0.5)
let [mins, maxs] = await a.stat(['min','max'], { bins: 640 })  // transferred, zero-copy
a.play()                                    // rendered in the worker, played by an AudioWorklet (Node: @audio/speaker)

// your own worker: its messages stay its own, and what it makes plays on the page
import audio from 'audio'                   // worker.js
import { expose } from 'audio/worker'
self.onmessage = ({ data }) => self.postMessage({ out: expose(audio(data.file).gain(-3)) })

let worker = new Worker('./worker.js', { type: 'module' })   // page
worker.onmessage = ({ data }) => audioWorker.adopt(data.out, { worker }).play()

CLI

npm i -g audio、またはインストールせずにnpx audio …

audio [source] [transforms...] [sink] [options]

パイプラインは、ソースがオーディオを生成し、変換処理がそれを加工し、シンクが受け取ります。シンクを指定せず、ターミナルでファイルを開くとプレーヤーが一時停止状態で起動し、スペースキーで再生します。パイプ、リダイレクト、または--jsonを使用した場合、デフォルトのシンクはstatとなり、概要を出力します。シンクを指定せずにaudio recordを実行すると、recording.wavに保存されます。

# sources
FILE         path, URL, or glob  ('*.wav' for batch)
-            stdin (or omit when piping)
record       capture from microphone

# transforms (chained left-to-right)
gain         fade        trim        normalize   crop
clip         remove      reverse     repeat      pad
speed        stretch     pitch       insert      mix
crossfade    remix       pan         split       resample
highpass     lowpass     eq          lowshelf    highshelf
notch        bandpass    allpass     vocals      dither
crossfeed    shrink      crossover   match       spectral
repair       copy        cut         paste       plugin

# sinks (terminate the chain — at most one)
stat [NAMES...]    print analysis (default)
play [loop]        open player UI
save PATH          encode and write (or `-` for stdout); `192k` bitrate, `24bit` depth

# options
-f --force         overwrite existing output
--format FMT       override output format
--macro FILE       apply edits from JSON
--cue FILE         split at cue-sheet tracks (with split)
--verbose          show progress
--help, -h         help (or per-op: `audio gain --help`)
--mcp              serve the CLI to AI agents as an MCP tool (stdio)
--plugins [NAME]   the native plugins @audio/host finds, or one's parameters

# a native plugin (npm i @audio/host): by name, its parameters as name:value
audio voice.wav plugin "RX 12 De-click" sensitivity:6 save clean.wav

# named options, after an op or sink: name:value
normalize -27 lufs ceiling:-2     ducker key:voice.wav     save out.m4a codec:alac

# compatibility shortcuts
-p ⇔ play     -l ⇔ play loop     -o PATH ⇔ save PATH
再生
Audiojsのデモ

␣ 一時停止 · ←/→ ±10秒シーク · ⇧←/⇧→ ±60秒シーク · ↑/↓ 音量 · l ループ · s 名前を付けて保存 · q 終了

# play full song
audio song.mp3 play

# play fragment
audio song.mp3 10s..15s play

# play and loop a hook
audio song.mp3 30s..45s play loop

# play with effects applied live (streamable ops)
audio song.mp3 normalize broadcast highpass 80hz play
編集
# clean up
audio raw-take.wav trim -30db normalize podcast fade 0.3s -0.5s save clean.wav

# scope a range (applies to whole chain)
audio in.wav 1s..10s gain -3db save out.wav

# range on a single op
audio in.wav gain -3db 1s..10s save out.wav

# filter chain
audio in.mp3 highpass 80hz lowshelf 200hz -3db save out.wav

# concat
audio intro.mp3 + content.wav + outro.mp3 trim normalize fade 0.5s -2s save ep.mp3

# crossfade into next
audio track1.mp3 crossfade track2.mp3 2s save mixed.wav

# voiceover
audio bg.mp3 gain -12db mix narration.wav 2s save mixed.wav

# music bed ducked under the voice (sidechain)
audio bed.mp3 ducker key:voice.wav mix voice.wav save episode.wav

# loudness to any target, true peak held; delivery settings
audio book.wav normalize -20 lufs save book.mp3 192k

# fix a video's sound, keep the picture
audio talk.mp4 highpass 80hz 4 normalize podcast save talk.clean.mp4

# master to a reference track (tone, width, loudness)
audio mix.wav master reference.wav save master.wav

# shorten pauses; the same cuts as an EDL for the video editor (.fcpxml, .otio too)
audio talk.mp4 shrink 0.3 save talk.edl

# split
audio audiobook.mp3 split 30m 60m save 'chapter-{i}.mp3'
audio album.wav split --cue album.cue save '{i} - {title}.mp3'   # cue-sheet tracks, tagged

# record
audio record 30s save voice.wav
解析
# overview (the default sink when piped or redirected)
audio speech.wav stat

# range overview
audio speech.wav 0..10s stat

# specific stats
audio speech.wav stat loudness rms

# tempo / beat grid / onsets
audio track.mp3 stat bpm
audio track.mp3 stat beats onsets

# loudness to spec: integrated, max momentary / short-term, speech only, true peak
audio mix.wav stat loudness momentary shortterm dialog truepeak

# pass or fail against a delivery spec (exit 1 on a fail); --json for scripts
audio episode.wav normalize podcast check podcast
audio chapter.wav check acx --json

# pitch / chords / key
audio song.mp3 stat notes
audio song.mp3 stat chords
audio song.mp3 stat key

# spectrum / cepstrum with bin count
audio speech.wav stat spectrum 128
audio speech.wav stat cepstrum 13

# stat after transforms (transforms apply, then stat)
audio speech.wav gain -3db stat db
バッチ処理
audio '*.wav' trim normalize podcast save '{name}.clean.{ext}'
audio '*.wav' gain -3db save '{name}.out.{ext}'
audio 'chapters/*.mp3' check acx                      # a whole audiobook: one line per chapter
CIでのチェック

仕様を満たさないファイルがあるとビルドは失敗します。ファイルごとに1行で、✓または違反したルールを表示し、失敗が1つでもあれば終了コード1を返します。

# .github/workflows/audio.yml
on: [push, pull_request]
jobs:
  audio:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: audiojs/audio@master   # or any CI: npx -y audio 'episodes/*.mp3' check podcast
        with:
          files: episodes/*.mp3
          spec: podcast              # spotify, broadcast, netflix, acx
Stdin/stdout
cat in.wav | audio gain -3db save -      > out.wav
curl -s https://ex.com/speech.mp3 | audio normalize save clean.wav
Tab completion
eval "$(audio --completions zsh)"       # add to ~/.zshrc
eval "$(audio --completions bash)"      # add to ~/.bashrc
audio --completions fish | source       # fish

よくある質問

どの形式に対応していますか?
decodeを使用して、WAV、MP3、FLAC、OGG Vorbis、Opus、AAC、AIFF、CAF、WebM、AMR、WMA、QOAをデコードできます。encodeを使用して、WAV、MP3、FLAC、Opus、OGG、AIFFにエンコードできます。コーデックはWASMベースで、初回使用時に遅延ロードされます。
ffmpegやネイティブアドオンは必要ですか?
ffmpegは不要です。コーデックと処理はJavaScriptおよびWASMで実行されます。Nodeでの再生と録音には小規模なネイティブアドオンを使用します。macOS、Linux(x64、arm64)、Windows(x64)向けのビルド済みアドオンがあるため、インストール時にコンパイルは不要です。それ以外の環境では、再生時にffplay、SoX、またはaplayにフォールバックします。CLIを使用する場合は、グローバルにインストールしてください:npm i -g audio。
サイズはどれくらいですか?
ページ内では、ライブラリ全体を最小化したファイル(dist/audio.min.js)がgzip圧縮後128 KBです。コーデックとプラグインは初回使用時にimport()経由でロードされるため、使用しない形式は取得されません。Nodeでは、npm i audioで16 MB、327個のパッケージ(すべてのコーデックとプラグイン)がインストールされます。コンパイルは不要です。npm i audio --omit=optionalでは、11.5 MB、115個(コーデックとコア:フィルター、EQ、ラウドネス、ピッチ、ストレッチ)がインストールされます。使用するプラグインファミリーは、使用時に名前を指定して個別にインストールします(npm i @audio/dynamics)。
大きなファイルはどのように処理しますか?
オーディオは固定サイズのページに保存されます。ブラウザーでは、{ storage: 'persistent' }(またはOPFSがある場合の'auto')を指定すると、メモリー使用量が予算を超えた際に、アクセス頻度の低いページがOPFSに退避されます。予算はnavigator.storage.estimate()から自動的に算出されます(クォータの1/4、64MB..512MB)。{budget}で上書きできます。各インスタンスは独自のストアを持ち、そのコピー間ではストアが共有されます。デコード済みファイル、audio.from(pcm)、プッシュストリームで動作します。統計情報はメモリー上に保持されます(2時間のステレオで約7 MB)。
編集は破壊的ですか?
いいえ。a.gain(-3).trim()は編集リストに項目を追加します。ソースページは変更されません。編集はread()/save()/for awaitの際に再実行されます。
ブラウザーで使用できますか?
はい。同じAPIを使用できます。バンドルのオプションとインポートマップについては、ブラウザーを参照してください。
作業を始める前に、ファイル全体を読み込む必要がありますか?
いいえ。再生、編集、構造操作(クロップ、リピート、パディング、挿入など)はすべてデコード中に逐次ストリーミングされるため、ファイルの読み込み完了前に出力が始まります。データの到着に合わせて編集プランが再コンパイルされ、各操作について安全に出力できる境界が追跡されます。全体の長さに依存する操作(終端を指定しないリバース、負のat)のみ、デコード完了まで待機します。
TypeScriptに対応していますか?
はい。audio.d.tsが同梱されています。
FFmpeg/SoX/librosaと同等の機能がありますか?
はい。audiojsエコシステムは、FFmpegフィルター、SoXエフェクト、librosa分析、Pedalboard、MIREXの実用的な基本機能を網羅しており、すべて@audio/*プラグインとして提供されています。audioはこれらを単一のAPI経由で接続します(未対応の項目は一部の専門的なもの、または意図的に対象外としたものです)。すべてのエフェクト、フィルター、ジェネレーター、アナライザーはレジストリーにあります。名前を指定して呼び出すと、初回使用時にロードされます。対応状況の一覧はdocs/comparison.mdをご覧ください。
SoX/FFmpeg/Audacity/librosa/Web Audio/Tone.jsとどう違いますか?
一言で言えば、audioはNodeとブラウザーで同じAPIを使え、デコード中にストリーミングされる非破壊の遅延編集を備えた唯一のツールです。ネイティブツール(SoX、FFmpeg)は生の処理速度では優れていますが、JavaScript API、ブラウザー対応、取り消し機能がありません。ブラウザー向けライブラリー(Web Audio、Tone.js、Howler)はリアルタイムグラフであり、ファイル編集用ではありません。pydub、librosa、aubio、essentia、Pedalboard、SoX、FFmpeg、Audacity、MATLABとの機能およびパフォーマンスの詳細な比較表は、docs/comparison.mdにあります。
## 使用技術
  • decode – コーデックのデコード(13 種類以上の形式)
  • encode – コーデックのエンコード
  • filter – フィルター(重み付け、EQ、聴覚)
  • speaker – オーディオ出力
  • mic – オーディオ入力
  • pitch – ピッチ、コード、キーの分析
  • audio-type – 形式の検出
  • pcm-convert – PCM 形式の変換

MIT · ॐ

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。