charとwchar_t以外のストリーム

C++標準のストリームの単位はcharまたはwchar_tです。それ以外の型のストリームも作成可能ですが、std::char_traitsの特殊化が必要になります。
一方、オーディオデータは通常、8ないし16ビットの整数の組を単位(サンプル)とします。例えば典型的な16ビットステレオのサンプルは16ビット×2=32ビットです。
初期の設計では、hamigaki::audio::vorbis_fileの文字型は、このサンプルの型と一致していました。しかし、この設計には次のような問題がありました。

  • 対応する基本型がない場合がある(5.1チャンネルの場合など)。構造体だとパディングが心配。
  • そもそもstd::char_traitsを基本型で特殊化できない(結果は未定義)
  • ファイルを読むまでサンプルの種類は分からないので、テンプレートのパラメータを決定できない

よって、文字型はcharに変更されました。
しかし、今度は読み込みとシークを必ずサンプル単位で行わなければならないという制約がついてしまいました。なんとなくiostream的には文字単位で操作できた方がよい気がして、hamigaki::iostreams::splitというブロック単位ストリームを文字単位ストリームに変換するアダプタを作ってお茶を濁していました。

と、これが昨日までの話。入力にばかり気をとられて、出力でも同じ問題があることを失念していました。試しにpcm_sinkのバッファサイズを奇数にしてみたところ、ノイズだらけの音が再生されました。
読み出しはバッファリングすることでなんとかなりましたが、書き出しの場合、中途半端なデータでflush()されたら対応のしようがありません。
で、やっぱりブロック単位のストリームにしようかなと思案中です。

規格を覗いてみると、次のような用語が見つかりました。

任意位置ストリーム(arbitrary-positional stream)
任意の整数値位置にシーク可能なストリーム
位置復元可能ストリーム(repositional stream)
以前に停止した位置に対してだけシーク可能なストリーム

ただ、この用語を参照しているところがどこにもないのです。定義だけ。
まぁ、位置復元可能ストリームもありってことなんでしょうが、、、。要調査です。

#あっダメだ。Boost.IostreamsのSeekableDeviceはBlockingを要求してる、、、。