matlab-play-record-audio について
audiostreamerによるMATLABのオーディオ機器I/Oを扱うスキルです。再生、録音、全二重キャプチャに加え、コールバックや機器診断を説明します。Audio Toolbox R2025a以降が必要です。
主な機能
- 01再生・録音・全二重モード
- 02コールバック駆動のストリーミング
- 03プリバッファリングとトランスポート制御
- 04オーディオ機器の列挙と選択
- 05遅延とアンダーランの診断
活用シーン
- 01サウンドカード経由で音声を再生
- 02マイクから音声を収録
- 03ループバックや音響測定の実施
- 04利用可能なオーディオ機器の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-play-record-audioインストール後、Claude Code で/matlab-play-record-audioを入力して読み込まれたか確認します。
同梱ファイルmanifest.yaml
詳細
audiostreamer — MATLAB オーディオデバイス I/O(R2025a+)
audiostreamer は、audioDeviceWriter、audioDeviceReader、audioPlayerRecorder を統合した置き換え機能です。コールバック、事前バッファリング、トランスポート制御、測定ヘルパーを備え、プレーヤー専用、レコーダー専用、または全二重モードを利用できます。
バージョン要件: audiostreamer には Audio Toolbox R2025a 以降が必要です。start メソッドと write メソッドは R2026a で追加されました。
使用する場面
- サウンドカードまたは USB オーディオデバイスでオーディオを再生する
- マイクまたはオーディオインターフェイスからオーディオを録音する
- 全二重の再生と録音を行う(例:音響測定、ループバックテスト)
- オーディオデバイスとドライバーを一覧表示または選択する
- MATLAB でオーディオハードウェア I/O を扱うあらゆるワークフロー
使用しない場面
- 単発の音を再生する場合 — 短いクリップを順序制御なしで一度だけ再生するなら、
soundまたはsoundscで十分です。順次再生(例:再生前後の比較)にはaudiostreamerを使用します。play()の呼び出しは自動的にキューに追加されますが、重なったsoundの呼び出しは同時に再生されます。 - コード生成(codegen) —
audiostreamerはまだ codegen をサポートしていません。codegen を対象とする場合は従来の API を使用してください - Simulink モデル — Simulink では引き続き既存のオーディオ I/O ブロックを使用し、
audiostreamerは使用しません - Audio Toolbox を利用できない場合 — ユーザーが Audio Toolbox を持っていない場合は、
sound/soundsc、audioplayer/audiorecorder、または DSP System Toolbox のaudioDeviceWriterを代わりに使用してください - ファイル I/O のみの場合 — デバイスでの再生や録音を伴わずにオーディオファイルを読み書きするには、このスキルではなく
audioread/audiowriteを使用します - DAQ ハードウェア — National Instruments などのデータ収集デバイスには、DAQ Toolbox と
daqオブジェクトを使用します - MIDI 専用デバイス — MIDI 制御には
audiostreamerではなく、mididevice/midicontrolsを使用します
構築
Mode と SampleRate には名前と値のペアを使用します(位置引数による省略記法もありますが、入力補完には対応していません)。
デフォルトの Mode は "player" です。録音する場合は、Mode を明示的に設定する必要があります — Mode="recorder" または Mode="full-duplex" を指定してください。Recorder や RecorderChannels など、ほかのプロパティから Mode が推測されることはありません。
as = audiostreamer % default: player mode, 44100 Hz
as = audiostreamer(Mode="player", SampleRate=fs) % player at fs Hz
as = audiostreamer(Mode="recorder", SampleRate=fs) % recorder at fs Hz
as = audiostreamer(Mode="full-duplex", SampleRate=fs) % simultaneous play + record
as = audiostreamer(Mode="full-duplex", SampleRate=48000, Driver="ASIO", ...
Player="Focusrite USB ASIO", Recorder="Focusrite USB ASIO", ...
PlayerChannels=[1 2], RecorderChannels=[1 2])
プロパティ
デバイス設定(ストリーミング開始前に設定)
| プロパティ | 型 | デフォルト | 備考 |
|---|---|---|---|
Mode | "player" / "recorder" / "full-duplex" | "player" | 構築時またはプロパティ経由で設定 |
Driver | "DirectSound" / "ASIO" / "WASAPI"(Win);"CoreAudio"(Mac);"ALSA"(Linux) | OS のデフォルト | Windows でのみ設定します(Mac/Linux ではドライバーは各 1 つです)。構築時に設定すると、そのドライバーのデフォルトデバイスが選択されます。 |
Player | 文字列 | ドライバーのシステムデフォルト | 出力デバイス名です。選択したドライバーのデフォルトデバイスを使用する場合は省略します。 |
Recorder | 文字列 | ドライバーのシステムデフォルト | 入力デバイス名です。選択したドライバーのデフォルトデバイスを使用する場合は省略します。 |
SampleRate | 正のスカラー | 44100 | Hz |
DeviceBufferSize | 正の整数または "auto" | "auto" | ASIO では固定です(asiosettings を使用してください)。 |
DeviceBitFormat | "single" / "int24" / "int16" | "int24" | ASIO で int16 を指定しても、通知なく int24 が使用されます |
PlayerChannels | 行ベクトルまたは "auto" | "auto" | 1 始まりのマッピングです。"auto" はモノラルをステレオにアップミックスします。チャンネル数が N≥2 の場合、デバイスで N チャンネルを開きます |
RecorderChannels | 行ベクトル | 1 | 1 始まりのマッピングです。デフォルトでは 1 チャンネルを録音します — ステレオの場合は、例として 1:2 を設定します |
ExclusiveMode | on/off | "on" | WASAPI のみ — OS のミキシング/リサンプリングを無効にします |
ConstantLatency | "off" / "dropPlayer" / "dropRecorder" | "off" | 全二重のドロップアウト処理 |
重要: Mode、SampleRate、Driver、DeviceBufferSize、DeviceBitFormat、ExclusiveMode、ConstantLatency、PlayerChannels、RecorderChannels は、ストリーミング開始後にロックされます。これらのプロパティを変更する前に release(as) を呼び出してください。そうしないと、警告とともに自動的に解放されます。
コールバックプロパティ
| プロパティ | シグネチャ | トリガー |
|---|---|---|
PlayerFcn | @(obj, event) | プレーヤーのバッファーが PlayerMinSamples を下回ったとき |
PlayerMinSamples | positive int (default 16384) | PlayerFcn をトリガーするしきい値 |
RecorderFcn | @(obj, event) | レコーダーのバッファーが RecorderMinSamples を超えたとき |
RecorderMinSamples | positive int (default 1024) | RecorderFcn をトリガーするしきい値 |
PlayerCompletedFcn | @(obj, event) | 出力キューが空になったとき |
RecorderCompletedFcn | @(obj, event) | 固定長の録音が完了したとき |
PlayerUnderrunFcn | @(obj, event) | プレーヤーのアンダーランが発生したとき |
すべてのコールバックは、引数を正確に2つ受け取る必要があります。 第1引数は audiostreamer オブジェクトです。第2引数は .Type フィールドを持つイベント構造体です。イベントが不要な場合は @(obj, ~) を使用してください。
種類ごとのイベント構造体のフィールド:
PlayerFcn:event.Type = "Player"、event.NumPlayerSamplesRecorderFcn:event.Type = "Recorder"、event.NumRecorderSamplesPlayerCompletedFcn:event.Type = "PlayerCompleted"、event.StreamTimeRecorderCompletedFcn:event.Type = "RecorderCompleted"、event.StreamTimePlayerUnderrunFcn:event.Type = "PlayerUnderrun"、event.SamplesUnderrun
読み取り専用ステータス
| プロパティ | 説明 |
|---|---|
NumPlayerSamples | 出力バッファーに現在キューイングされているサンプル数 |
NumRecorderSamples | ブロックせずに read() で読み取れるサンプル数 |
MaxPlayerChannels | 選択したデバイスの最大出力チャンネル数 |
MaxRecorderChannels | 選択したデバイスの最大入力チャンネル数 |
メソッド
再生
| メソッド | 説明 |
|---|---|
play(obj, x) | x をキューに追加して再生します。ブロックします。出力バッファーが PlayerMinSamples 以下になるまで待機します(戻る時点で最大 PlayerMinSamples 個のサンプルが未再生のまま残ります)。release の前に再生を完了させるには、最後の play の後に waitfor(as) を呼び出してください。 |
play(obj, x, "non-blocking") | バッファーのレベルに関係なく、x をキューに追加してすぐに戻ります。 |
play(obj) | PlayerFcn コールバックのループを開始します(データ引数なし)。 |
write(obj, x) | [R2026a+] 再生を開始せずに、x を出力バッファーにキューイングします。start() と組み合わせて使用します。 |
write(obj, x, "non-blocking") | [R2026a+] x をキューに追加し、バッファーのレベルに関係なくすぐに戻ります。 |
録音
| メソッド | 説明 |
|---|---|
record(obj) | 無期限の録音を開始します。バッファーに未読のサンプルが残っている場合は警告します。回避するには、stop(as)(全二重の場合は stop(as, "recorder"))を実行してから、read(as) でバッファーを空にしてください。サンプルがコールバックまたは read によってすでに消費されている場合は不要です。 |
record(obj, numSamples) | numSamples 個のサンプルを録音して停止します。未読サンプルに関する同じ警告が適用されます。 |
read(obj) | 利用可能な録音済みサンプルをすべて、すぐに返します(ノンブロッキング)。利用可能なサンプルがない場合は空を返します。 |
read(obj, numSamples) | numSamples 個のサンプルが利用可能になるまでブロックし、その後それらを返します。 |
全二重
| メソッド | 説明 |
|---|---|
playrec(obj, x) | x を再生しながら同時に録音します。ノンブロッキングです。録音はバックグラウンドで続行され、データは read で取得します。 |
playrec(obj, x, numSamples) | x を再生しながら numSamples 個のサンプルを録音します。ブロッキング方式で、録音した行列を返します。 |
playrec(obj) | コールバック駆動の全二重を開始します(RecorderFcn および/または PlayerFcn が必要です)。 |
playrec はプレーヤーとレコーダーの両方を一時停止し、音声をキューに追加してから、両方を同時に再開することで、再現可能なレイテンシーを実現します。これは、impzest を使った測定に不可欠です。
トランスポート制御
| メソッド | 説明 |
|---|---|
start(obj) | [R2026a+] 現在のモードでストリーミングを開始します。 |
start(obj, Mode="player") | [R2026a+] プレーヤーのみを開始します(全二重)。 |
start(obj, Mode="recorder", SamplesToRecord=N) | [R2026a+] 固定数のサンプルを指定してレコーダーを開始します。 |
stop(obj) | すべてのストリーミングを停止します。未読み取りの入力サンプルは保持されます。アンダーラン数をリセットします(getUnderrunCount と同様です)。 |
stop(obj, "player"/"recorder"/"both") | 指定した側を停止します。 |
pause(obj) / pause(obj, "player"/"recorder"/"both") | 状態を保持したまま一時停止します。 |
resume(obj) / resume(obj, "player"/"recorder"/"both") | 一時停止から再開します。 |
waitfor(obj) / waitfor(obj, "player"/"recorder"/"both") | 完了するまでブロックします。 |
release(obj) | 停止、フラッシュ、デバイスのクローズ、解放を行います。未読み取りのサンプルは削除されます。 |
クエリ/診断
| メソッド | 説明 |
|---|---|
isPlaying(obj) | OnOffSwitchState を返します |
isRecording(obj) | OnOffSwitchState を返します |
isPlayerPaused(obj) | OnOffSwitchState を返します |
isRecorderPaused(obj) | OnOffSwitchState を返します |
getUnderrunCount(obj) | 前回の呼び出し以降のアンダーランサンプル数を返します。カウンターをリセットします(stop と同様です)。 |
getStreamTime(obj) | 経過ストリーム時間を秒単位で返します。 |
getStreamTime(obj, "reset") | ストリームタイマーをリセットします。 |
measureLoopbackLatency(obj) | 全二重のみ、単一チャンネル。遅延をサンプル数で返します。 |
静的デバイス列挙
audiostreamer.getDrivers() % Available drivers for this OS
audiostreamer.getPlayerNames() % All output devices
audiostreamer.getPlayerNames("ASIO") % Output devices for specific driver
audiostreamer.getRecorderNames() % All input devices
audiostreamer.getRecorderNames("ASIO") % Input devices for specific driver
audiostreamer.getAudioDevices() % Struct array: Name, Driver, MaxRecorderChannels, MaxPlayerChannels, SampleRate (channel counts are int32)
注: getAudioDevices() は MaxRecorderChannels と MaxPlayerChannels に対して int32 を返します。UI コンポーネント(例:uispinner の Limits)や、double を想定する演算でこれらの値を使用する前に、double() にキャストしてください。
重要:setup() メソッドはありません
audiostreamer にパブリックな setup() メソッドはありません。デバイスの初期化は、最初の play()、record()、playrec()、または start() の呼び出し時に暗黙的に行われます。setup() は呼び出さないでください。エラーになります。
PlayerFcn が設定されている場合、最初のストリーミング呼び出しでは、デバイスを開く前に、少なくとも8192サンプル(または PlayerMinSamples のいずれか大きい方)を事前バッファーするため、関数が繰り返し呼び出されます。
よくあるパターン
パターン1:シンプルなブロッキング測定(スイープ+IR)
as = audiostreamer(Mode="full-duplex", SampleRate=48000, ...
PlayerChannels=1, RecorderChannels=1);
x = sweeptone(2, 1, 48000);
y = playrec(as, x, size(x, 1)); % blocking: returns recorded audio
underruns = getUnderrunCount(as);
ir = impzest(x, y);
release(as);
パターン2:waitfor を使用したノンブロッキング再生+録音
as = audiostreamer(Mode="full-duplex", SampleRate=48000);
x = sweeptone(3, 2, 48000);
playrec(as, x); % non-blocking (no output arg)
waitfor(as); % block until done
y = read(as); % retrieve recorded data
release(as);
パターン3:事前バッファー再生(write+start)— R2026a+
再生の開始タイミングを正確に制御する必要がある場合(例:同期した全二重開始)は、write+start を使用します。シンプルな再生では、play(as, signal) でも同じ結果が得られます。キューに追加され、自動的に開始されます。
as = audiostreamer(Mode="player", SampleRate=48000);
write(as, signal); % queue without starting
start(as); % begin playback
waitfor(as); % wait for completion
release(as);
パターン4:コールバック駆動のストリーミングプレーヤー
as = audiostreamer(Mode="player", SampleRate=48000, DeviceBufferSize=1024);
gen = dsp.ColoredNoise("pink", NumChannels=2, SamplesPerFrame=1024);
as.PlayerFcn = @(obj, ~) play(obj, gen());
as.PlayerMinSamples = 4096;
play(as); % or start(as) [R2026a+] — begins callback loop
% ... later ...
stop(as);
release(as);
パターン5:コールバック駆動のレベル測定(レコーダー)
as = audiostreamer(Mode="recorder", SampleRate=48000);
as.RecorderFcn = @(obj, ~) updateMeter(read(obj));
as.RecorderMinSamples = 1024;
start(as); % or record(as) before R2026a
% ... meter updates in background ...
stop(as);
release(as);
パターン6:フレーム単位の処理ループ(全二重)
従来の audioDeviceReader/audioDeviceWriter ループを置き換える最も直接的な方法です。read でサンプルを取得できるように、ループの前に start(as) を呼び出してください。
as = audiostreamer(Mode="full-duplex", SampleRate=48000, RecorderChannels=1:2);
start(as);
for iter = 1:numIterations
in = read(as, frameLength); % blocks until frameLength samples available
out = process(myPlugin, in);
write(as, out); % blocks until buffer has room
end
nUnderruns = getUnderrunCount(as); % total underruns since last call (resets counter)
release(as);
R2026a より前は、start/write の代わりに record(as)+play(as, out) を使用してください。
プレーヤーのみの場合(例:ファイル入力→デバイス出力)は、start を呼び出す必要はありません。play(as, out) を使用すると、キューに追加され、自動的に開始されます。
パターン7:コールバックを使用した繰り返し測定(全二重)
as = audiostreamer(Mode="full-duplex", SampleRate=48000, PlayerChannels=1, RecorderChannels=1);
x = sweeptone(2, 1, 48000);
as.RecorderMinSamples = size(x, 1);
as.RecorderFcn = @(obj, ~) processMeasurement(obj, x);
as.PlayerFcn = @(obj, ~) write(obj, x); % or play(obj, x) before R2026a
as.PlayerMinSamples = size(x, 1);
as.ConstantLatency = "dropPlayer"; % keep in sync for impzest
playrec(as); % starts callback-driven measurement loop
% ... runs continuously ...
stop(as);
release(as);
パターン8:タイマーベースのGUI更新を行うアプリ
as = audiostreamer(Mode="player", SampleRate=fs, DeviceBufferSize=1024);
as.PlayerFcn = @(obj, ~) play(obj, getNextFrame());
as.PlayerMinSamples = 20 * 1024;
as.PlayerUnderrunFcn = @(~, ev) fprintf("Dropped %d samples\n", ev.SamplesUnderrun);
figTimer = timer(ExecutionMode="fixedRate", Period=0.05, ...
TimerFcn=@(~,~) updatePlot(as));
play(as); % starts callback loop
start(figTimer); % starts GUI updates
% ...
stop(as);
release(as);
stop(figTimer);
delete(figTimer);
タイマーコールバックでは、負荷の高いGUI操作を行う前にバッファーの状態を確認してください:
function updatePlot(as)
if as.NumPlayerSamples < 0.5 * as.PlayerMinSamples
return % skip GUI update to prevent dropout
end
% ... update plots ...
if as.NumPlayerSamples > 0.9 * as.PlayerMinSamples
drawnow("limitrate");
end
end
パターン9:制御のための write/start を使用した全二重— R2026a+
as = audiostreamer(Mode="full-duplex", SampleRate=48000);
write(as, excitation); % queue output
start(as, SamplesToRecord=size(excitation,1)); % start both
waitfor(as, "both");
y = read(as);
release(as);
ティアダウンのベストプラクティス
release(as) で十分です。ストリーミングの停止、バッファーのフラッシュ、デバイスのクローズが自動的に行われるため、先に stop を呼び出す必要はありません。ただし、release は未再生のサンプルを破棄します。再生を完了させる必要がある場合は、先に waitfor(as) を呼び出してください。
waitfor(as); % ensure all queued audio finishes playing
release(as);
アプリでは、try-catch で囲み、参照を nil にしてください。
try
release(as);
catch
end
as = [];
デストラクターは自動的に release() を呼び出しますが、デバイスがロックされたままになるのを避けるため、アプリでは明示的にクリーンアップすることを推奨します。PlayerCompletedFcn 内から release を呼び出しても安全で、デッドロックは発生しません。
注: isvalid(as) は、解放後も true を返します。そのため、解放済みの audiostreamer を検出する用途には使えません。解放状態を追跡するには、オブジェクトの参照を nil にして、isempty で確認してください。
ConstantLatency モード(全二重)
| 値 | 動作 | 用途 |
|---|---|---|
"off" | ドロップアウト後に無音フレームを挿入します(レイテンシーが増加します) | 一般用途 |
"dropPlayer" | 出力フレームが遅れた場合に破棄します。レイテンシーは一定に保たれます | impzest を使用したスイープベースの測定 |
"dropRecorder" | 入力フレームを破棄します。レイテンシーは一定です | 適応フィルター(impzest とは互換性がありません) |
エラー条件
| エラー ID | 原因 |
|---|---|
audio:device:methodRequiresModes | 現在の Mode では無効なメソッドを呼び出しています(例:プレイヤーモードでの record())。再生と録音の両方のメソッドが必要な場合は、Mode を "full-duplex" に設定してください。 |
audio:device:invalidChannelMap | チャンネルインデックスがデバイスの最大値を超えています。MaxPlayerChannels または MaxRecorderChannels を確認し、マッピングを調整してください。 |
audio:device:callbackNargin | コールバックが引数をちょうど 2 つ受け取りません。@(obj, ~) または @(obj, event) のシグネチャーを使用してください。 |
audio:device:playrecRecorderFcnConflict | RecorderFcn が設定されている状態で、出力引数を指定して playrec が呼び出されています。コールバックが read() でサンプルを消費するため、戻り値に渡すサンプルが残りません。ブロッキング形式の playrec を呼び出す前に、RecorderFcn をクリアしてください。 |
audio:device:startModePlayerNotValid | レコーダー専用モードでの start(Mode="player") |
audio:device:startModeRecorderNotValid | プレイヤー専用モードでの start(Mode="recorder") |
MATLAB:validators:mustBeFinite | オーディオデータに NaN または Inf が含まれています |
MATLAB:validators:mustBeReal | オーディオデータが複素数です |
audiostreamer と従来のオーディオ API の比較
Audio Toolbox が利用可能な場合、すべてのオーディオデバイス I/O には audiostreamer を強く推奨します。従来の代替手段は、Audio Toolbox がインストールされていない場合や特殊なケースで、フォールバックとして役立つことがあります。
| 従来の API | 制限事項 | audiostreamer での代替手段 |
|---|---|---|
audiodevinfo | ASIO をサポートしていません。デバイス一覧が不完全です | audiostreamer.getAudioDevices()、audiostreamer.getPlayerNames() など |
audioplayer / audiorecorder | ASIO/WASAPI の排他モードに対応していません。ドライバーモデルに制限があり、コールバックもありません | プレイヤー/レコーダー/全二重モードの audiostreamer |
sound / soundsc | 内部で audioplayer を作成します。同時に呼び出すと再生が重なります(キューに追加されません) | 順次再生には play() を使用する audiostreamer |
audioDeviceWriter / audioDeviceReader | オブジェクトが別々で、コールバックや事前バッファリングに対応していません。フレームごとのループしか使用できません | ブロッキング/ノンブロッキングモードを備えた単一の audiostreamer オブジェクト |
audioPlayerRecorder | 全二重機能に制限があり、トランスポート制御やレイテンシー測定に対応していません | playrec、measureLoopbackLatency、start/stop/pause/resume |
audiodevreset は呼び出して問題ありません。オーディオサブシステムをリセットするため、使用する API にかかわらず、デバイスエラーからの復旧に役立つことがあります。
sound/soundsc を使用してもよい場合: シーケンスを伴わない、単独の再生に限られます。2 つのクリップを連続して再生する必要がある場合(例:変更前と変更後の比較)は、audiostreamer を使用してください。play() の呼び出しは自動的にキューに追加されます。
移行時の注意点(audioDeviceReader/Writer → audiostreamer)
| 旧方式 | audiostreamer | 注意点 |
|---|---|---|
NumChannels=2 を指定した audioDeviceReader | RecorderChannels=1:2 | audiostreamer はデフォルトで1チャンネルを録音します。ステレオ/マルチチャンネルを使用するには、RecorderChannels を明示的に設定する必要があります。 |
audioDeviceWriter はフレームごとにアンダーラン数を返す | ループ後に getUnderrunCount(as) | play() に戻り値はありません。合計数が必要な場合は getUnderrunCount を呼び出してください。呼び出すたびにカウンターがリセットされます。 |
audioDeviceReader はフレームごとにオーバーラン数を返す | 同等の機能は不要です | audiostreamer は録音したサンプルをすべて内部にバッファリングするため、レコーダーでオーバーランは発生しません。 |
Device='Default' | Player/Recorder を省略 | 「Default」という文字列はありません。このプロパティを省略すると、現在のドライバーのシステム既定値が選択されます。 |
[data, nOverrun] = deviceReader() | record(as) の後に data = read(as, N) | ループの前に record(as)(または start(as) [R2026a+])を呼び出す必要があります。そうしないと、read はサンプルを待ち続け、永久にブロックされます。 |
| リーダーとライターに別々のオブジェクトを使用 | 単一の audiostreamer(Mode="full-duplex") | 1つのオブジェクトで両方向を処理します。デバイスで異なるドライバーが必要な場合や、同時に開くと競合する場合は、別々のオブジェクトを使用してください。 |
診断
ストリーミングの問題をデバッグするには、診断トレースを有効にします。
as = audiostreamer(Mode="full-duplex", SampleRate=44100);
as.TraceEnabled = true; % logs internal timing and buffer state
Copyright 2026 The MathWorks, Inc.