ASIOデバイスの列挙

ASIO(Audio Stream Input Output:アジオ)は、オーディオデバイスのドライバインタフェースの一つである。

http://ja.wikipedia.org/wiki/ASIO

ASIOデバイスはシステムに登録されてるので、システムに問い合せて列挙するそうです。Windowsだったらレジストリです。Macの方はCodeFragmentってなってますがよく知りません。


いちいちレジストリいじったりとかめんどくさいですが、$(SDKDir)/host/asiodrivers.hが引き受けてくれるらしいですよ、奥さん!
asiodrivers.hは環境に合わせて環境依存なヘッダ(Windowsなら$(SDKDir)/host/pc/asiolist.h)を読み込んでその中のクラスを継承してます。プリプロセス時多態です。そんな言葉聞いたことないですが。


なぜasiodrivers.hさんがディレクトリ階層を無視して#include "asiolist.h"ってやっちゃってるのかはこの際気にしないとして、


AsioDriversはこんなインターフェースを持ってます。
$(SDKDir)/host/asiodrivers.h

class AsioDrivers : (環境依存の基底クラス)
{
public:
	AsioDrivers();
	~AsioDrivers();
	
	bool getCurrentDriverName(char *name);
	long getDriverNames(char **names, long maxDrivers);
	bool loadDriver(char *name);
	void removeCurrentDriver();
	long getCurrentDriverIndex() {return curIndex;}
protected:
	unsigned long connID;
	long curIndex;
};

( ゚д゚ )列挙したいのにドライバの総数がわからないよ!
これは困りました。getDriverNamesにはmaxDrivers以下で見つかったドライバの数を返してくれるそうなので、適当に多めに見積もってfullに格納されて帰ってきたらもうちょっと容量増やして、とかやりましょうか。
そんなことやってられませんので、基底クラスが持ってる、ドライバの総数を返すメンバ関数を呼んでやればいいのです。

包含で以てドライバの総数が取れるAsioDriversとしてクラス化

AsioDrivers.hpp

#ifndef HWM_ASIO_DRIVERS_HPP
#define HWM_ASIO_DRIVERS_HPP

#include <asiodrivers.h>

namespace hwm
{

class AsioDrivers
{
public:
    long getNumDrivers          () const
    {
        //platform
#if     MAC
        return ad_.getNumFragments();
#elif   WINDOWS
        return ad_.asioGetNumDev();
#endif  //platform
    }

    bool getCurrentDriverName   (char *name) const                      { return ad_.getCurrentDriverName(name); }
    long getDriverNames         (char **names, long maxDrivers) const   { return ad_.getDriverNames(names, maxDrivers); }
    bool loadDriver             (char *name)                    { return ad_.loadDriver(name); }
    void removeCurrentDriver    ()                              { ad_.removeCurrentDriver(); }
    long getCurrentDriverIndex  () const                        { return ad_.getCurrentDriverIndex(); }

private:
    mutable ::AsioDrivers   ad_;
};

}   //namespace hwm

#endif  //HWM_ASIO_DRIVERS_HPP
#include <iostream>
#include <vector>

#include <boost/array.hpp>
#include <boost/assert.hpp>

#include <pstade/oven/identities.hpp>
#include <pstade/oven/io.hpp>

#include "./AsioDrivers.hpp"

int main()
{
    using namespace pstade::oven;
    std::vector<boost::array<char, 32> >    buffer_arr;
    std::vector<char *>                     buffers;

    hwm::AsioDrivers    ad;
    size_t const        max_dev = ad.getNumDrivers();

    buffer_arr.resize(max_dev);
    buffers.resize(max_dev);

    for(size_t i = 0; i < max_dev; ++i) {
        buffers[i] = buffer_arr[i].data();
    }

    if(max_dev != 0) {
        size_t const entries = ad.getDriverNames(&buffers[0], buffers.size());
        BOOST_ASSERT(entries == max_dev);

        std::cout << (buffers|identities) << std::endl;
    }
}

{ASIO Sample,ASIO4ALL v2}

(これ書いてて何に一番楽しみを感じているかって言ったらpstade/oven/io.hppですよね。)