2006-05-01から1ヶ月間の記事一覧

floatストリームの設計

floatストリームの方針を決めるため、デバイス毎の要素型を表にしてみました。 デバイス 型 asio char wave_file char pcm_device char direct_sound char vorbis_file float sine_wave float vorbis_fileは通常charストリームで扱いますが、ネイティブな型…

IEEE754浮動小数点数のデコード/エンコード

C++

また、妙な方向に脱線中です。 MSDNを眺めていたら、便利な関数を発見しました。 float ldexp( float x, // 浮動小数点値。 int exp // 整数の指数。 ); ldexp 関数は x * 2 の exp 乗の値を返します。 C89から存在する関数のようですが、全然知りませんでし…

floatストリーム開発再開

id:y-hamigaki:20060328 のコンパイルエラーは#ifdefのチェックが余計なだけだと、今頃になって気が付きました。 Cygwin/MinGWでも問題なさそうなのでfloatストリーム再開です。 floatストリームと言いつつも構想は広がり、 charの多バイトストリーム(1〜4バ…

asio::driver_list

ASIOドライバの列挙を実装できました。 namespace hamigaki { namespace audio { namespace asio { struct driver_info { std::string clsid; // クラスID std::string name; // ドライバ名 }; HAMIGAKI_AUDIO_DECL std::vector<driver_info> driver_list(); } } } // End</driver_info>…

続 レジストリキーの列挙

昨日のregistry_key_iteratorですが、 class registry_key : boost::noncopyable { public: registry_key( ::HKEY parent, const std::string& sub_key, ::REGSAM sam) boost::optional<std::string> sub_key_name(::DWORD index) const; };のようなレジストリキーのクラ</std::string>…

レジストリキーの列挙

そろそろASIOの初期化を修正しようと思います。 CLSIDを直指定だと、いつまでたってもテストコードをパッケージに追加できないのです。ASIOのドライバを検索するためには、レジストリのHKEY_LOCAL_MACHINE\SOFTWARE\ASIO配下のキーを列挙する必要があります…

Newマリオ

ヨドバシのポイントが残っていたので買ってきました。 2Dマリオは久しぶりです。 ジャンプの感覚がつかめず、最初のクリボーにやられてしまいました。 その後もクリボーを踏みそこなうこと多々。下手すぎです。 ファイアが出ないと思ったら、ジャンプボタン…

mmapとmprotect

またcdecl_thunkをg++に移植した時の話です。 サンクような自己書き換えコードを実行可能にするためには、OSのメモリ保護のモードを変更する必要があります。POSIX環境でこれを実行する関数はmprotect()です。 規格によると、mprotect()はmmap()で確保したメ…

関数ポインタのキャスト

今日はcdecl_thunkをg++に移植したときに詰まった関数ポインタのキャストについて。 cdecl_thunkでは、関数ポインタとオブジェクトポインタ(void*)の相互変換が必要になります。 VC++だと、この変換はreinterpret_castで出来るのですが、規格上は許可されて…

続 Hamigaki.Detail

C++

思いついた案を書き並べておきます。 Hamigaki.Detailのヘッダを自己完結的にしない。インクルードする側で必要なヘッダを事前にインクルードさせる→使いにくいのが難点 コンパイル必須にするHamigaki.Detailのヘッダでも処理系依存ヘッダを見せない。→無関…

Hamigaki.Detail

MinGWの件は置いといて、ライブラリの構造のお話です。HamigakiライブラリではBoostの構造を真似て、ライブラリ毎に名前空間とディレクトリを分割しています。(Hamigaki.Iteratorなど一部例外あり) いろいろなライブラリを作っていると、処理系依存のコード…

続cygwinでASIO

IASIOのメンバ呼び出しをインラインアセンブラで書き直しました。もう全然C++じゃないです。 inline ::ASIOBool asio_init(::IASIO* this_ptr, void *sys_handle) { ::ASIOBool result; __asm__ ( "mov %2, %%eax\n\t" "push %%eax\n\t" "mov %1, %%ecx\n\t"…

cygwinでASIO?

ASIOサポートをソースツリーにマージして、Cygwin/MinGWでも動くように調整中です。 Cygwin/MinGWでコンパイルまではできましたが、実行するとコアダンプします。 サンクや仮想メモリ周りが怪しい気がして、サンクをはずして動かしてみましたが、効果なしで…

バグ取りとかメンバの追加とか

ここ数日の検討結果をコードに反映させました。今日の成果物日記に書いてない変更で大きなところは、multiplexer/demultiplexerのcomponent()メソッドでしょうか。 class multiplexer_impl { public: template<typename Source> void push(const Source& src, std::streamsize</typename>…

続 ASIOのバッファサイズ

よく考えると、2のn乗だけを扱うのであれば、最小値と最大値だけ返せば済む気がしてきました。 class asio_device { public: // 最小バッファサイズと最大バッファサイズを返す。 std::pair<long,long> minmax_buffer_size() const; };あるいは全部まとめて、 struct as</long,long>…

ASIOのバッファサイズ

ASIOには指定可能なバッファサイズを取得するASIOGetBufferSize関数があります。 ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);ここで、 minSize 設定可能な最小バッファサイズ maxSize 設定可能な…

マルチストリームとサンプルサイズ

昨日はマルチストリームの長さを考えましたが、今日は要素のサイズについて考えます。 複数のストリームがあるとき、各ストリームの要素サイズもまた異なる場合があります。実際、ASIOの場合は一つのデバイスが複数のインタフェース(アナログ、S/PDEIFなど)…

multiplexer

demultiplexerの反対の動きをするmultiplexerを作りました。 multiplexerは複数のストリームを1つにまとめます。 これを使って昨日の例をステレオにすると、次のようになります。 // 入力、出力ともに2つずつ asio.create_buffers(2, 2); // 32bit決め打ち…

asio_source

今日はasio_sourceの実装に取り掛かりました。 asio_sourceを追加すると、昨日の再生/停止問題がさらに複雑になります。 次のような場合を考えます。 // SourceとSinkを1個ずつ作成 asio.create_buffers(1, 1); // キャプチャしたデータをすぐに再生 io_ex::…

複数ストリームの再生と停止

asio_sinkのstart()とstop()周りを修正しました。今日の成果物asio_sinkはチャンネル毎に別のストリームになるように設計しています。そして、個々のストリームはシングルスレッドで順に書き込んでも、マルチスレッドで並行して書き込んでも動くようになって…

sample_cvt

PCMフォーマット変換フィルタの入出力サイズを可変になるように修正してみました。 (2の補数表現以外も考慮しているため、意外に時間がかかりました←かなり無駄) asio.create_buffers(0, 2); io_ex::demultiplexer demuxer(2); // 16ビット -> 32ビット demu…

続demultiplexer

ノンブロッキングにするまでもなく、demultiplexer内部のバッファリングをやめたらうまくいきました。 というわけで、ステレオ再生は以下のようになります。 asio.create_buffers(0, 2); io_ex::demultiplexer demuxer(4); // バッファサイズの指定がなくな…

続asio_sink

ステレオ再生が出来ない原因が分かりました。問題はasio_sinkではなく、demultiplexerにありました。 demultiplexerを使わず、次のようにスレッドを使って再生するとうまくいきました。 asio.create_buffers(0, 2); // ド io_ex::background_copy copy0( io:…

asio_sink

まだ作りかけですが、何とかモノラル再生ができたのでアップしました。今日の成果物ステレオだとうまく鳴らないので、どこかバグっています。 #include <hamigaki/detail/windows/com_library.hpp> #include <hamigaki/audio/asio.hpp> #include <hamigaki/audio/sine_wave.hpp> #include <boost/iostreams/copy.hpp> #include <boost/iostreams/restrict.hpp> namespace audio = hamigaki::aud…</boost/iostreams/restrict.hpp></boost/iostreams/copy.hpp></hamigaki/audio/sine_wave.hpp></hamigaki/audio/asio.hpp></hamigaki/detail/windows/com_library.hpp>

demultiplexer

asio_sinkの再構成中です。 これまで扱ってきたオーディオデバイスと違い、ASIOの入出力はチャンネル毎に別バッファとなっています。これはデータの加工を考慮すると便利なインタフェースですが、単に再生するだけでよい場合は不便です。 そこで、ASIOのマル…

作り直し

やっぱり、どう考えてもダブルバッファリングなしでは無理です。ノイズが入ります。 Winampプラグインもライブラリ内でさらにバッファリングしているようです。このバッファを小さくすると、実際に音が鳴らなくなりました。おそらく、ちゃんとしたASIO対応デ…

やっと音が鳴りました

まだ、asio_sinkの実装中。ようやく音は鳴ったのですが、ノイズしかでません。 自分の環境だとPCMフォーマットはASIOSTInt32LSB固定なので、とりあえずハードコーディングで進めています。根本的にフォーマットの扱いを間違えている気がします。ヘッダを見る…

続cdecl_thunk

昨日のcdecl_thunkを使うと、ASIOのコールバック関数は次のようになります。 struct asio_callbacks { cdecl_thunk<2> buffer_switch; cdecl_thunk<2> sample_rate_changed; cdecl_thunk<4> asio_message; cdecl_thunk<3> buffer_switch_time_info; };sample…

cdecl_thunk

asio_sinkを作成中。 ASIOのコールバック関数にコンテキストを渡せないので、仕方なくサンクを書く羽目になりました。 Windowsで一般的な__stdcall呼び出し規約でなく、__cdecl呼び出し規約なので実装が少々面倒です。 アセンブリ言語は得意でないので、コン…

ASIO SDKとグローバル変数

ASIOと言っても、今回はAudio Streaming I/Oの方です。 S.F. Programmingさんの話だと、ASIOのサポートはaudioライブラリとしては必要なもののようです。 これまで名前ぐらいしか知りませんでしたが、調べてみました。自分のサウンドカードは(多分)ASIOに対…