float_t
wide_adaptor<boost::int_least32_t>を実装完了。
昨日の例がこう書けるようになりました。
audio::aiff_file_source file("doremi.aiff"); audio::pcm_format fmt = file.format(); if (fmt.type == audio::int8) fmt.type = audio::uint8; else fmt.type = audio::int_le16; // float -> boost::int_least32_t に変更 io::copy( audio::widen<boost::int_least32_t>(file), audio::widen<boost::int_least32_t>(audio::pcm_sink(fmt)) );
boost::int_least32_tで特殊化するのはマズいかもしれません。
boost::int_least32_tとboost::int_least16_tが同じ環境もあるので、この作りでは16ビット整数用の特殊化を行うことができません。
また、wide_adaptor<boost::int_least32_t>が浮動小数点フォーマットをサポートすべきかどうかも検討の余地があります。(今のところサポートしています。)
整数フォーマットの最大精度は24ビットなので、演算の途中で仮数24ビット以上の浮動小数点型が必要になります。
そこで、boost::int_tの実装を真似して、そのfloat版を作成してみました。
// とりあえず1番小さい型が1番速いものとする template<typename LeastFloat> struct float_fast_t { typedef LeastFloat fast; }; template<int Category> struct float_least_helper {}; // サイズの大きい順 template<> struct float_least_helper<1> { typedef long double least; }; template<> struct float_least_helper<2> { typedef double least; }; template<> struct float_least_helper<3> { typedef float least; }; // Bitsは仮数のビット数 template<int Bits> struct float_t { typedef typename float_least_helper < (Bits <= std::numeric_limits<long double>::digits) + (Bits <= std::numeric_limits<double>::digits) + (Bits <= std::numeric_limits<float>::digits) >::least least; typedef typename float_fast_t<least>::fast fast; }; // 最低24ビットの仮数を持つ浮動小数点型 typedef float_t<24>::least float_least24_t;
浮動小数点型の場合、std::numeric_limits<T>::digitsは仮数のビット数で、IEEE754 Single/Doubleに見られるような暗黙の最上位ビットも含めた値です。
正確には指数の精度も確認すべきでしょうが、ほとんど精度がいらない(今回の場合5ビットで十分)ので見てません。