マルチストリームとサンプルサイズ
昨日はマルチストリームの長さを考えましたが、今日は要素のサイズについて考えます。
複数のストリームがあるとき、各ストリームの要素サイズもまた異なる場合があります。実際、ASIOの場合は一つのデバイスが複数のインタフェース(アナログ、S/PDEIFなど)を持つことがあり、インタフェース毎に要素のサイズが違うことも考えられます。
サンプルサイズの違うストリームを扱うとなると、multiplexer/demultiplexerも、要素のサイズをコンストラクタではなく、push()のタイミングで設定する必要があります。
// 入力、出力ともに2つずつ asio.create_buffers(2, 2); // コンストラクタではサイズを指定しない io_ex::multiplexer muxer; // 第2引数は要素のサイズ muxer.push(asio.get_source(0), asio.get_source(0).block_size()); muxer.push(asio.get_source(1), asio.get_source(1).block_size()); io_ex::demultiplexer demuxer; // 入力チャンネルのサイズから出力チャンネルのサイズへ変換 demuxer.push( io::compose( audio::sample_cvt( asio.get_source(0).block_size(), asio.get_sink(0).block_size() ), asio.get_sink(0) ) asio.get_source(0).block_size() ); demuxer.push( io::compose( audio::sample_cvt( asio.get_source(1).block_size(), asio.get_sink(1).block_size() ), asio.get_sink(1) ) asio.get_source(1).block_size() ); // バッファサイズは、まだ決め打ち io_ex::background_copy bg_copy(muxer, demuxer, 2*64*4); std::cin.ignore(256, '\n');
block_size()はBoost.Iostreamsのコンセプトでないため、アダプタをかぶせるとアダプタのメンバ関数には現れません。このため、要素のサイズを推定するのが難しくなっています。
もし、Boost.Iostreamsにblock_size()のコンセプトがあれば、メンバ関数block_size()の存在を期待して(あるいはヘルパ関数を介して)値を推定できるため、次のように短く書くことができます。
// sample_cvtとSinkを合成する架空の関数 template<class Source, class Sink> cvt_sink<Sink> make_cvt_sink(const Source& src, const Sink& snk); asio.create_buffers(2, 2); io_ex::multiplexer muxer; muxer.push(asio.get_source(0)); muxer.push(asio.get_source(1)); io_ex::demultiplexer demuxer; demuxer.push(make_cvt_sink(asio.get_source(0), asio.get_sink(0))); demuxer.push(make_cvt_sink(asio.get_source(1), asio.get_sink(1))); io_ex::background_copy bg_copy(muxer, demuxer, 2*64*4); std::cin.ignore(256, '\n');
無いものねだりしても仕方がないので、こんな関数でお茶を濁しておきます。
template<class Sink> void push_with_cvt( io_ex::demultiplexer& demuxer, const Sink& snk, std::streamsize in_size, std::streamsize out_size) { demuxer.push( io::compose( audio::sample_cvt(in_size, out_size), snk ) in_size ); } io_ex::demultiplexer demuxer; push_with_cvt(demuxer, asio.get_sink(0), asio.get_source(0).block_size(), asio.get_sink(0).block_size()); push_with_cvt(demuxer, asio.get_sink(1), asio.get_source(1).block_size(), asio.get_sink(1).block_size());