昨日に続きC++でwavファイルを読み込む処理を書く時のメモになります。
読み込んだバイト列をサンプル単位の値に変換するときに、8・16・32ビットのデータであれば値をそのままキャストするだけで済むのですが、
24ビットだった場合の処理で毎回手間取ってしまうためここに書いておくことにしました。
バイト列を読み込んで32ビットintで返す構造体を定義します。
struct int24
{
private:
unsigned char bits[3];
public:
static const std::int32_t MaxValue = 0x007fffff; // 8388607
static const std::int32_t MinValue = 0xff800000; // -8388608
explicit operator std::int32_t() const
{
if (bits[2] & 0x80)
return bits[0] | (bits[1] << 8) | (bits[2] << 16) | (0xff << 24);
else
return bits[0] | (bits[1] << 8) | (bits[2] << 16);
}
};
読み込む際はここからintにキャストして
std::shared_ptr<char[]> buffer; // 読み込むバイト列
/* 読み込み処理 */
int24 val24 = std::reinterpret_pointer_cast<int24[]>(buffer)[0];
std::int32_t val32 = std::static_cast<std::int32_t>(val24);
とかすればよし。……おそらく。
逆に32ビットintからint24に変換したい場合は符号を見て0x7fffffでマスクしたりすればよいと思います(省略)。