カクタスソフトウェア
カクタスソフトウェア
サウンド MIDI マルチメディア アプリケーション

ASIOシステムの作業領域「DriverInfo」について

DriverInfo構造体

ASIO SDKでは、ASIOシステムや運用に関する様々な情報を一括してDriverInfo構造体に保存しています。この構造体は、運用の便宜を図る目的で導入されたサンプルコードです。構造体のメンバーには、ASIO APIから得られた数値や、コールバック関数から得られた時刻情報などが含まれます。

DriverInfo構造体は、ASIO APIの利用法を説明するための実装例です。この構造体を用いなければ動かない、というものではありません。ユーザーが独自の方法でシステムを構築する場合、この構造体にこだわる必要はありません。実際、C#で実装されているNAudioのコードには、DriverInfo構造体は含まれません。

以下にDriverInfo構造体を示します。

// internal data storage
typedef struct DriverInfo
{
    // ASIOInit()
    ASIODriverInfo driverInfo;

    // ASIOGetChannels()
    long           inputChannels;
    long           outputChannels;

    // ASIOGetBufferSize()
    long           minSize;
    long           maxSize;
    long           preferredSize;
    long           granularity;

    // ASIOGetSampleRate()
    ASIOSampleRate sampleRate;

    // ASIOOutputReady()
    bool           postOutput;

    // ASIOGetLatencies ()
    long           inputLatency;
    long           outputLatency;

    // ASIOCreateBuffers ()
    long inputBuffers;  // becomes number of actual created input buffers
    long outputBuffers; // becomes number of actual created output buffers
    ASIOBufferInfo bufferInfos[kMaxInputChannels + kMaxOutputChannels]; // buffer info's

    // ASIOGetChannelInfo()
    ASIOChannelInfo channelInfos[kMaxInputChannels + kMaxOutputChannels]; // channel info's
    // The above two arrays share the same indexing, as the data in them are linked together

    // Information from ASIOGetSamplePosition()
    // data is converted to double floats for easier use, however 64 bit integer can be used, too
    double         nanoSeconds;
    double         samples;
    double         tcSamples;   // time code samples

    // bufferSwitchTimeInfo()
    ASIOTime       tInfo;           // time info state
    unsigned long  sysRefTime;      // system reference time, when bufferSwitch() was called

    // Signal the end of processing in this example
    bool           stopped;
} DriverInfo;

DriverInfo構造体は、以下の情報を含んでいます。

ドライバー情報

ASIOInit()関数の引数となるASIODriverInfo構造体です。デバイス名などを保持します。

typedef struct ASIODriverInfo
{
    long asioVersion;       // currently, 2
    long driverVersion;     // driver specific
    char name[32];
    char errorMessage[124];
    void *sysRef;           // on input: system reference
                            // (Windows: application main window handle, Mac & SGI: 0)
} ASIODriverInfo;
ASIOのローレベルAPIを用いてデバイスを管理するときは、必要ありません。

チャンネル数

ASIOGetChannels()関数が戻した数値を保持します。デバイスが支援する入力・出力のチャンネル数です。

バッファサイズ

ASIOGetBufferSize()関数が戻した数値を保持します。

属性  名前 意味
long minSize 最小のバッファサイズ
long maxSize 最大のバッファサイズ
long preferredSize 推奨されるバッファサイズ
long granularity この値でバッファを増減させる

バッファサイズの単位は、サンプル数です。

サンプリング周波数

ASIOGetSampleRate()関数が戻した数値を保持します。この数値は、現在運用中のサンプリング周波数です。

ASIOSampleRateの属性は、doubleです。

出力データ完了フラグ

ASIOOutputReady()関数は、再生デバイスにデータ設定が完了したことを知らせます。デバイスはこの通知を利用してレイテンシを低く抑えるための最適化を行います。

プログラムの先頭で、ASIOOutputReady()関数が戻した値を保持しておきます。最適化の機能を支援しないデバイスは、falseを戻します。

レイテンシ

ASIOGetLatencies()関数が戻した数値を保持します。

入力レイテンシは、録音されたデータがコールバック関数で処理できるまでのサンプル数です。一般的に、バッファサイズとデバイス内部での遅れの合計になります。

出力レイテンシは、一般的にバッファサイズに等しくなります。これは、一つ前のバッファが演奏し終わるまで、現在設定中のバッファが待たされるためです。ただしデバイス内部でコピーなどの遅延が発生している場合は、これより遅れる可能性もあります。

バッファ情報

システムが支援する実際の入力・出力デバイス数を保持します。bufferInfos配列の内、この数値が示す領域が有効となります。

属性 名前 意味
long inputBuffers 実際の入力デバイス数
long outputBuffers 実際の出力デバイス数
ASIOBufferInfo bufferInfos ASIOBufferInfo構造体
SDKのサンプルプログラムでは、bufferInfos配列のサイズを固定値で割り当てています。これは、Cで書かれた古いスタイルのプログラムに良く見られる手法です。これから書き直すのであれば、デバイスの数に応じて領域を確保した方が良いでしょう。

ASIOBufferInfo構造体は、ASIOCreateBuffers()関数の引数として用います。入出力の区別、チャンネルのインデックス、及びバッファのアドレスを保持します。

typedef struct ASIOBufferInfo
{
    ASIOBool isInput;           // on input:  ASIOTrue: input, else output
    long channelNum;            // on input:  channel index
    void *buffers[2];           // on output: double buffer addresses
} ASIOBufferInfo;

チャンネル情報

属性 名前 意味
ASIOChannelInfo channelInfos ASIOChannelInfo構造体

ASIOChannelInfo構造体は、ASIOGetChannelInfo()関数の引数として用います。

typedef struct ASIOChannelInfo
{
    long channel;           // on input, channel index
    ASIOBool isInput;       // on input
    ASIOBool isActive;      // on exit
    long channelGroup;      // dto
    ASIOSampleType type;    // dto
    char name[32];          // dto
} ASIOChannelInfo;

サンプル位置情報

これらの位置情報は、演奏時間の表示などに利用するため、時刻情報(ASIOTime)から得た数値を、利用しやすい形に変換したものです。

属性  名前 意味
double nanoSeconds 再生時間
double samples 再生済みサンプル数
double tcSamples タイムコード

上記の3つの変数は、コールバック関数(bufferSwitchTimeInfo)が呼び出されたとき、引数のASIOTime構造体の情報を元に設定されます。

時刻情報

時刻情報は、ASIOTime構造体に設定されます。

ASIOTime構造体は、時刻を保持する2つのメンバーから成ります。基本的にAsioTimeInfoを用い、timeCode.flagsが有効なとき、拡張情報としてASIOTimeCodeを利用することができます。

以下に、ASIOTime構造体を示します。

typedef struct ASIOTime                     // both input/output
{
    long reserved[4];                       // must be 0
    struct AsioTimeInfo     timeInfo;       // required
    struct ASIOTimeCode     timeCode;       // optional, evaluated if (timeCode.flags & kTcValid)
} ASIOTime;

AsioTimeInfo

AsioTimeInfo構造体には、現在のシステム時刻、サンプル位置、サンプリング周波数などが記録されます。

typedef struct AsioTimeInfo
{
    double          speed;                  // absolute speed (1. = nominal)
    ASIOTimeStamp   systemTime;             // system time related to samplePosition, in nanoseconds
                                            // on mac, must be derived from Microseconds() (not UpTime()!)
                                            // on windows, must be derived from timeGetTime()
    ASIOSamples     samplePosition;
    ASIOSampleRate  sampleRate;             // current rate
    unsigned long   flags;                  // (see below)
    char reserved[12];
} AsioTimeInfo;

ASIOTimeCode

ASIOTimeCode構造体は、SMPTEのタイムコードでの運用を支援するためと思われます。

typedef struct ASIOTimeCode
{
    double          speed;                  // speed relation (fraction of nominal speed)
                                            // optional; set to 0. or 1. if not supported
    ASIOSamples     timeCodeSamples;        // time in samples
    unsigned long   flags;                  // some information flags (see below)
    char future[64];
} ASIOTimeCode;

残念ながら執筆現在、ASIOTimeCodeの利用について、詳しい情報が得られていません。SKDにも関連するコードはほとんど無く、実装や運用について十分な解析ができない状況です。

TimeCodeは、一般的にSMPTEのタイムコードを意味します。SDKドキュメントのサンプルプログラムにもフレームレートを設定する記述が見られ、SMPTEでの運用を示唆しています。

 
ASIOTimeCode* tc = &asioTime.timeCode;
tc->speed = 1.; tc->frameRate = AsioFPS_30; // frame rate

しかし実際のASIOTimeCode構造体には、frameRateというメンバーは無く、またヘッダーにもAsioFPS_30という定義は含まれていません。このことからTimeCodeについては十分に実装されていない可能性もあり、現段階では利用しない方が良いかも知れません。

sysRefTime

bufferSwitch()関数がコールされた時の時刻を保持します。Windowsの場合、timeGetTime()で得られた値を用います。

停止フラグ

stoppedフラグは、サンプルプログラムの終了を知らせるためのもので、これ以上の意味はありません。

ユーザーが独自のアプリケーションを作成するときは、アプリケーションの内容に応じて、スタート・ストップなどのステータスフラグを用意する必要があります。

ドキュメントの先頭へ

カクタスソフトウェア 技術協力 資料室 資料室の広場 SourceForge.jp お問い合わせ