タイムスタンプ付ストリームI/Oによる音の実時間処理 栗田 亮 (東工大) 千葉 滋 (東工大) 光来 健一 (NTT未来ねっと研究所)
タイミングが重要な音の処理 ♪ ♪ 自動伴奏システム IN OUT 解析 伴奏データ 作成 ソリストに対しコンピュータが伴奏を合わせる ソリストのメロディーの入力に対し伴奏データを出力で返す 入出力をリアルタイムに処理する必要がある IN OUT ♪ ♪ 解析 伴奏データ 作成 音程、音量、 テンポ、etc 伴奏 メロディー
音の入出力処理 Linuxカーネルにおける音の録音 再生の場合は逆の流れ kernel application A/D サウンドデバイスにアクセスして行う A/Dコンバータ・・・アナログ・デジタル変換器 割り込み・・・カーネルバッファにデジタルデータが格納される read()・・・カーネルバッファからアプリケーションバッファへサウンドデータをコピー 再生の場合は逆の流れ kernel application アナログデータ buffer buffer A/D
音の処理のミス 原因 その1: ハードウェア~カーネル間でのデータ損失 → アナログ音の録音再生では高負荷時でもめったに起きない その1: ハードウェア~カーネル間でのデータ損失 → アナログ音の録音再生では高負荷時でもめったに起きない 割り込みの衝突は少ない その2: カーネル~アプリケーション間の転送の遅れ ハードウェア~カーネル間の転送レートについていけなくなり、バッファリングでミスが生じる OSに大きな負荷がかかると生じる
2つの処理ミス 音飛び 途切れ 録音時に発生し、一部のデータが抜け落ちる カーネルバッファが一杯になって生じる 再生時に発生し、再生が一時止まる カーネルバッファが空になって生じる 9 8 7 4 3 2 1 9 8 7 4 3 2 1 6 5 アプリケーションへ カーネル 1 2 3 4 5 6 7 8 9 ハードウェアへ 再生STOP カーネル
従来のLinux Linuxが備える実時間処理機能 問題点 優先度割り当て機能 完全な優先実行は不可能 処理ミスに対処できない 指定したプロセスを優先して実行することが可能 問題点 完全な優先実行は不可能 優先度の高い処理が、優先度の低い処理やハードウェア割り込みによって妨げられる場合がある 処理ミスに対処できない 処理ミスを検知する機能がないので対処できない
リアルタイムLinuxによる対処 既存のリアルタイムLinux 問題点 処理ミスに対処できない リアルタイムスケジューラを用いる実時間処理システム ハードリアルタイム:RT-Linux, ART-Linuxなど ソフトリアルタイム:Linux-SRT, QLinuxなど 問題点 マルチメディア処理には不向き(ハードリアルタイム) ハードリアルタイムOSの応答性はあまり必要ではない 処理ミスに対処できない ユーザーの負担が大きい システムの肥大化 プログラミングが複雑
提案するシステム TS-I/O (Time Stamp - I/O) 処理ミスに対処する機能を提供 TS-I/Oでの入力処理 I/Oデータがバッファに格納された時刻を記録する 音飛びの検知が可能 タイムスタンプとデータサイズを比較する kernel buffer application buffer size=8 サウンド データ buf 時刻 4 6 10 tsize 音飛び タイム スタンプ 0..4 6..10 tbuf
TS-I/Oでの出力処理(1) 再生中の処理ミスへの対処 間が発生した場合、それ以降のデータをとばす 時間軸に沿った再生が可能 application buffer kernel buffer data0~5 5 7 0~5 play 5~7 no data! 7~10 play サウンド データ 7秒経過(2秒遅れ) data7~10 data5~10
TS-I/Oでの出力処理(2) タイムスタンプに従った再生処理 アプリケーションが渡したタイムスタンプに従って再生 録音時のミス(音飛び)に対処した再生が可能 application buffer kernel buffer size=8 0~5 play 5~7 wait… 7~10 play 音飛びした サウンド データ 0..5 7..10 タイム スタンプ
TS-I/Oの利点 シンプルな設計 カーネルレベルの処理 全てのストリームに適応できる I/Oのみをリアルタイム化 マシンの性能に依存しない実時間処理を可能に カーネルレベルの処理 アプリケーションレベルではできない処理が可能 OS内のバッファリングでのミスの検知 全てのストリームに適応できる 全てのストリームにTS-I/Oを利用できれば、タイミング重視のプログラムの作成は非常に楽 汎用ルーチンを作ることで実装できそう
追加システムコール read_gettbuf(fd,buf,tbuf,size,tsize) read(fd,buf,size)+タイムスタンプの取り出し デバイスからの録音データとタイムスタンプを返す tbuf・・・タイムスタンプを格納するバッファ tsize・・・タイムスタンプのサイズ write_puttbuf(fd,buf,tbuf,size,tsize) write(fd,buf,size)+タイムスタンプの転送 デバイスに再生データとタイムスタンプを送る
TS-I/Oの実装 デバイスドライバの関数に処理を追加 タイムスタンプの付加 タイムスタンプを処理 割り込み処理関数 read関数 関数が呼ばれた際にタイムスタンプを取得する タイムスタンプを処理 read関数 タイムスタンプをアプリケーションに転送する write関数 タイムスタンプに従って、時間軸にそった同期再生を行う 再生処理中のミスに対して、その後のデータが時間軸にそうように処理をとばす
実験 オーバーヘッドを測定 割り込み関数のオーバーヘッド 割り込み関数、read関数、write関数のオーバーヘッド 計算機:PentiumⅢ 733MHz, メモリ 512MB 処理にかかったクロックを測定 割り込み関数のオーバーヘッド 割り込み関数1回あたりのオーバーヘッドを測定 割り込み関数呼び出しの周期: 5333 μsec 結果: 2.3 μsec → 割り込み関数の呼ばれる周期内に納まる小さい値
read関数のオーバーヘッド 10秒のデータを数回のread関数に分けて録音し、1回あたりのタイムスタンプ転送の時間を測定 呼び出す回数が多いほどオーバーヘッドは大きい この時間だけバッファにデータがたまるが、この程度なら問題ない 回数(1回あたりの時間) オーバーヘッド(μsec) 割合(%) 10000回(1msec) 3.2 0.32 1000回(10msec) 5.4 0.054 100回(100msec) 33.1 0.031
write関数のオーバーヘッド 10秒のデータを数回のwrite関数に分けて再生し、関数が1回呼ばれてから終わるまでの処理時間を測定 今回はミスが起こらない場合のオーバーヘッドを測定 100回呼び出した場合、オーバーヘッドはほとんどなかった この時間だけバッファのデータが減っていくが、この程度なら問題ない 回数(1回あたりの時間) オーバーヘッド(μsec) 割合(%) 10000回(1msec) 8.8 0.88 1000回(10msec) 10.3 0.103 100回(100msec)
ネットワークにおけるTS-I/O(1) TS-I/Oの拡張・・・UDPを利用するマルチメディア処理に関して パケットの損失の検知 メディア内、メディア間の同期 処理時間の制御 受信側のアプリケーションに処理開始時間を指定する → これらの処理をOSが自動的にしてくれる
♪ ネットワークにおけるTS-I/O(2) QoS制御 サーバー クライアント バッファのデータが減ってきた場合、タイムスタンプをみてストリームを優先的に処理 サーバからのストリームをバッファリングしながら再生する場合に有効 アプリケーションではできない処理 サーバー クライアント タイムスタンプ Check! ♪ 出力 リングバッファ
関連研究 アプリケーションレベルの実時間処理 関連研究 アプリケーションレベルの実時間処理 MPEG 映像や音声の圧縮符号化方式 各パケットにタイムスタンプを含むヘッダーを付加する RTP(Real-time Transport Protocol) 映像や音声のストリーミングのためのプロトコル タイムスタンプなどを含むヘッダーを付加して送る 我々のTS-I/O 上の技術が提供する実時間処理をカーネルレベルで提供する パケットの損失の検知、同期処理
実時間処理のレベルの比較 アプリケーション TS-I/O リアルタイムOS リアルタイムスケジューリング SOFT メディア内、メディア間の同期が可能 TS-I/O カーネルレベルの実時間処理 QoS制御 OS内のバッファリングミスの検知 リアルタイムOS リアルタイムスケジューリング SOFT アプリケーション TS-I/O リアルタイムOS HARD
まとめ TS-I/Oを提案 今後の発展 Linuxにおけるカーネルレベルでの実時間処理を可能にする機能 TS-I/Oの拡張 ルーチンの作成 現在、各デバイスドライバを書き換える設計 → 汎用ルーチンを作ることで、デバイスドライバへの変更をせずに処理を提供する予定