mcpField
M
matlab-play-record-audio

matlab-play-record-audio

github.com/matlabクリエイティブ・メディア1.2k52 回インストール1 日前に更新
リポジトリ

matlab-play-record-audio について

audiostreamerによるMATLABのオーディオ機器I/Oを扱うスキルです。再生、録音、全二重キャプチャに加え、コールバックや機器診断を説明します。Audio Toolbox R2025a以降が必要です。

主な機能

  1. 01再生・録音・全二重モード
  2. 02コールバック駆動のストリーミング
  3. 03プリバッファリングとトランスポート制御
  4. 04オーディオ機器の列挙と選択
  5. 05遅延とアンダーランの診断

活用シーン

  1. 01サウンドカード経由で音声を再生
  2. 02マイクから音声を収録
  3. 03ループバックや音響測定の実施
  4. 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正のスカラー44100Hz
DeviceBufferSize正の整数または "auto""auto"ASIO では固定です(asiosettings を使用してください)。
DeviceBitFormat"single" / "int24" / "int16""int24"ASIO で int16 を指定しても、通知なく int24 が使用されます
PlayerChannels行ベクトルまたは "auto""auto"1 始まりのマッピングです。"auto" はモノラルをステレオにアップミックスします。チャンネル数が N≥2 の場合、デバイスで N チャンネルを開きます
RecorderChannels行ベクトル11 始まりのマッピングです。デフォルトでは 1 チャンネルを録音します — ステレオの場合は、例として 1:2 を設定します
ExclusiveModeon/off"on"WASAPI のみ — OS のミキシング/リサンプリングを無効にします
ConstantLatency"off" / "dropPlayer" / "dropRecorder""off"全二重のドロップアウト処理

重要: Mode、SampleRate、Driver、DeviceBufferSize、DeviceBitFormat、ExclusiveMode、ConstantLatency、PlayerChannels、RecorderChannels は、ストリーミング開始後にロックされます。これらのプロパティを変更する前に release(as) を呼び出してください。そうしないと、警告とともに自動的に解放されます。

コールバックプロパティ
プロパティシグネチャトリガー
PlayerFcn@(obj, event)プレーヤーのバッファーが PlayerMinSamples を下回ったとき
PlayerMinSamplespositive int (default 16384)PlayerFcn をトリガーするしきい値
RecorderFcn@(obj, event)レコーダーのバッファーが RecorderMinSamples を超えたとき
RecorderMinSamplespositive int (default 1024)RecorderFcn をトリガーするしきい値
PlayerCompletedFcn@(obj, event)出力キューが空になったとき
RecorderCompletedFcn@(obj, event)固定長の録音が完了したとき
PlayerUnderrunFcn@(obj, event)プレーヤーのアンダーランが発生したとき

すべてのコールバックは、引数を正確に2つ受け取る必要があります。 第1引数は audiostreamer オブジェクトです。第2引数は .Type フィールドを持つイベント構造体です。イベントが不要な場合は @(obj, ~) を使用してください。

種類ごとのイベント構造体のフィールド:

  • PlayerFcn:event.Type = "Player"、event.NumPlayerSamples
  • RecorderFcn:event.Type = "Recorder"、event.NumRecorderSamples
  • PlayerCompletedFcn:event.Type = "PlayerCompleted"、event.StreamTime
  • RecorderCompletedFcn:event.Type = "RecorderCompleted"、event.StreamTime
  • PlayerUnderrunFcn: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:playrecRecorderFcnConflictRecorderFcn が設定されている状態で、出力引数を指定して 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 での代替手段
audiodevinfoASIO をサポートしていません。デバイス一覧が不完全ですaudiostreamer.getAudioDevices()、audiostreamer.getPlayerNames() など
audioplayer / audiorecorderASIO/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 を指定した audioDeviceReaderRecorderChannels=1:2audiostreamer はデフォルトで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.


コメント