オートネゴシエーション

Hamigaki.Audioのチュートリアルを考えていたのですが、どうにも分かりにくい。

#include <hamigaki/audio/pcm_device.hpp>
#include <hamigaki/audio/vorbis_file.hpp>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/copy.hpp>

namespace audio = hamigaki::audio;
namespace io = boost::iostreams;

const std::string filename("doremi.ogg");

audio::vorbis_file<io::file_source> vf(
    (io::file_source(filename, BOOST_IOS::binary)));

const audio::vorbis_info& info = vf.info();

audio::pcm_format fmt;
fmt.rate = info.rate;
fmt.bits = 16;
fmt.channels = info.channels;

io::copy(vf, audio::pcm_sink(fmt, 4096));

面倒なのは以下の点。

  • vorbis_fileのテンプレート引数とコンストラクタにSourceの名前を書く必要がある
  • vorbis_fileからフォーマット情報を取得して、pcm_sinkに渡す必要がある

つまり、こう書きたいわけです。

#include <hamigaki/audio/pcm_device.hpp>
#include <hamigaki/audio/vorbis_file.hpp>
#include <boost/iostreams/copy.hpp>

namespace audio = hamigaki::audio;
namespace io = boost::iostreams;

io::copy(audio::vorbis_file("doremi.ogg"), audio::pcm_sink());

vorbis_fileのデフォルト実装として、ファイルから読み込むように修正するのは簡単です。
一方、2つ目の問題を解消するためにはvorbis_fileとpcm_sinkの間で自動的にフォーマットのネゴシエーションを行う枠組みが必要です。より一般化するとSource-Sink間プロトコルのオートネゴシエーションです。
この枠組みに必要な機能を特定するために、いくつかのデコーダやデバイスを作ってみようと思います。手始めにWAVEファイル辺りから。