hamigaki.png

前のページ 上に戻る ホーム 次のページ

チュートリアル

基本的な使い方
浮動小数点数ストリーム

基本的な使い方

Hamigaki.Audioを使用した簡単な例として、WAVEファイルを再生するプログラムを紹介する。

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

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

int main()
{
    audio::wave_file_source wf("doremi.wav");
    io::copy(wf, audio::pcm_sink(wf.format()));
}

Hamigaki.AudioにおけるオーディオデバイスはBoost.IostreamsのSource/Sinkのモデルとして実装されている。ここではSourceとしてwave_file_sourceを、Sinkとしてpcm_sinkを使用している。

wave_file_sourceはWAVEファイルを読み出すSourceである。コンストラクタの引数としてファイル名を指定する。

pcm_sinkはPCMデータを再生するためのSinkである。Source/Sink間のデータのやり取りは同じフォーマットで行う必要がある。そのため、pcm_sinkのコンストラクタにはwave_file_source::format()から取得したpcm_formatを渡す。

Sourceからデータを読み取り、Sinkへ書き出すにはboost::iostreams::copy()を用いる。もちろん、boost::iostreams::read()boost::iostreams::write()も使用できる。

浮動小数点数ストリーム

PCMデータのバイトストリームは、1つのサンプルが複数バイトで表現されたり、一般に実行時までフォーマットが確定しないことから、データの加工を行いにくい性質がある。1つのサンプルをワイド文字1文字で表現できれば、データの加工が容易になる。これはマルチバイトエンコーディングの文字列の扱いに良く似ている。PCMデータの場合、通常ワイド文字にはfloatやdoubleのような浮動小数点数を用いる。これは多くの波形処理にとって都合が良いからである。

例として、440Hzの正弦波を再生するプログラムを示す。

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

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

int main()
{
    audio::pcm_format fmt;
    fmt.type = audio::int_le16;
    fmt.channels = 1;
    fmt.rate = 44100;

    audio::basic_sine_wave_source<float> src(fmt.rate, 440.0f);
    io::copy(src, audio::widen<float>(audio::pcm_sink(fmt)));
}

basic_sine_wave_sourceは正弦波を生成するSourceである。コンストラクタの引数としてサンプリング周波数と正弦波の周波数を指定する。

basic_sine_wave_sourceの文字型はfloatであり、pcm_sinkの文字型charとは一致しないため、そのままではコピーを行うことができない。コピーを行うためには、Source/Sink間でやり取りする文字型をより「大きな」型に統一しなければならない。widen()はこのための関数であり、受け取ったデバイスの文字型をテンプレート引数で指定した型に変換したデバイスを返す。(実際には、write()メンバ関数の中で、float文字列をバイト列へと変換する)

basic_sine_wave_sourceの出力は-1.0~1.0の範囲になる。これが、widen()によって-32768~32767にマッピングされる(フォーマットが16ビットの場合)。変換は単純に32768倍することで行われるため、変換元の値が1.0の場合に値が溢れてしまう。溢れた値は最大値に丸められるが、これが再生の際にノイズとなって現れる。これを防ぐためには、amplify()を使用して振幅を調整すると良い。

#include <hamigaki/audio/amplify.hpp>
#include <hamigaki/audio/pcm_device.hpp>
#include <hamigaki/audio/sine_wave.hpp>
#include <hamigaki/audio/wide_adaptor.hpp>
#include <boost/iostreams/copy.hpp>

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

int main()
{
    audio::pcm_format fmt;
    fmt.type = audio::int_le16;
    fmt.channels = 1;
    fmt.rate = 44100;

    audio::basic_sine_wave_source<float> src(fmt.rate, 440.0f);
    io::copy(
        audio::amplify(src, 0.5f),
        audio::widen<float>(audio::pcm_sink(fmt)));
}
製作著作 © 2006-2008 Takeshi Mouri

前のページ 上に戻る ホーム 次のページ