IDirectMusicSynth
COM公式ドキュメント
IDirectMusicSynth インターフェイスは、DirectMusic がユーザーモードのシンセサイザーと通信するために使用します。
メソッド 17
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
Open メソッドは、DirectMusic シンセサイザーの "ポート" を開きます。
| pPortParams | DMUS_PORTPARAMS8* | inout | DirectMusic "ポート" を開く際のオプションのセットを指定する DMUS_PORTPARAMS 構造体(Microsoft Windows SDK ドキュメントで説明)へのポインター。この構造体には、サンプルレート、ステレオモード、ボイス数など、ポートのセットアップパラメーターが含まれます。このパラメーターに NULL を設定した場合は、既定の設定が使用されます。 |
戻り値
呼び出しが成功した場合、Open は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
| pPortParams に無効なポインターが渡されたことを示します。 | |
|
ポートが既に開かれていることを示します。 |
|
出力に使用できるシンクが存在しないことを示します。 |
解説(Remarks)
DirectMusic シンセサイザーの "ポート" は一度しか開けません。2 回目に開こうとすると失敗します。
ただし、DirectMusic はシンセサイザーポートの複数のインスタンスをサポートします。これは CoCreateInstance(Windows SDK ドキュメントで説明)を呼び出して複数の IDirectMusicSynth オブジェクトを作成することで実現されます。
ポートは IDirectMusicSynth::Close メソッドで閉じられるまで有効です。
ポートを開くとき、DMUS_PORTPARAMS で要求されたパラメーターの一部がサポートされていない場合や、ポートが要求を "格上げ" する場合(つまり、要求された値ではなくサポートされる最大ボイス数を返す場合)があります。いずれの場合も、Microsoft ソフトウェアシンセサイザーは S_FALSE を返し、実際にサポートされる内容を示すように DMUS_PORTPARAMS を変更します。カスタムシンセも、既存のコードとの互換性を確保するためにこの動作をエミュレートしてください。
ポートを開いただけではシンセサイザーは有効になりません。シンセサイザーは、ポートを開き、さらに IDirectMusicSynth::Activate によってオーディオ出力を有効にすることで有効になります。
DirectMusic の "ポート" という用語を DMus ポートドライバーと混同しないでください。DirectMusic ポートは、DirectMusic フィルターのレンダーピンまたはキャプチャーピンに対応します。DirectMusic ポートの詳細については、Windows SDK ドキュメントの IDirectMusicPort インターフェイスの説明を参照してください。
Close メソッドは、DirectMusic の "ポート"(音楽データを送受信するデバイスを指す DirectMusic の用語)を閉じます。
戻り値
呼び出しが成功した場合、Close は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
|
ポートが開かれていなかったことを示します。 |
解説(Remarks)
このメソッドは、IDirectMusicSynth::Open の呼び出しによって以前に開かれた DirectMusic "ポート" を閉じます。
DirectMusic "ポート" が閉じられると、そのポートに以前ダウンロードされたすべてのインストゥルメントとウェーブが自動的に解放されます。ただし、アプリケーションはポートを閉じる前にこれらのオブジェクトを明示的に解放することが望ましい方法です。
DirectMusic の "ポート" という用語を DMus ポートドライバーと混同しないでください。DirectMusic ポートは、DirectMusic フィルターのレンダーピンまたはキャプチャーピンに対応します。DirectMusic ポートの詳細については、Microsoft Windows SDK ドキュメントの IDirectMusicPort インターフェイスの説明を参照してください。
SetNumChannelGroups メソッドは、シンセサイザーにチャネルグループ数を新しい値に設定するよう指示します。
| dwGroups | DWORD | in | 要求するチャネルグループ数を指定します。 |
戻り値
呼び出しが成功した場合、SetNumChannelGroups は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
|
シンセが開かれていないか、正しく構成されていないことを示します。 |
| チャネルグループを割り当てられないことを示します。 |
解説(Remarks)
IDirectMusicSynth::Open によって DirectMusic "ポート" に作成するチャネルグループ数を伝えていても、アプリケーションが後から SetNumChannelGroups の呼び出しでその数を動的に増減する必要が生じる場合があります。
各チャネルグループは 16 個の MIDI チャネルのセットをサポートします。たとえば、dwChannelGroups に 3 を設定すると、シンセサイザーは 48 個のチャネルを作成します。
詳細については、Microsoft Windows SDK ドキュメントの IDirectMusic インターフェイスの説明を参照してください。
Download メソッドは、ウェーブまたはインストゥルメントの定義をシンセサイザーにダウンロードします。
| phDownload | HANDLE* | inout | ダウンロードハンドルの出力ポインター。このパラメーターは呼び出し元が確保した変数を指し、メソッドはそこにダウンロードデータを識別するハンドルを書き込みます。呼び出し元は、後でこのハンドルを使用してデータをアンロードします。 |
| pvData | void* | inout | ダウンロードデータを格納した連続したメモリセグメントへのポインター。データ形式の概要については、Microsoft Windows SDK ドキュメントの DirectMusic セクションにある低レベル DLS の説明を参照してください。 |
| pbFree | BOOL* | inout | ダウンロードデータのメモリを解放できるかどうかを示すステータス値の出力ポインター。このパラメーターは呼び出し元が確保した変数を指し、メソッドは pvData が指すストレージを呼び出し元が解放できるかどうかを示すブール値を書き込みます。TRUE の場合、アプリケーションは戻り後にメモリを安全に解放できます。FALSE の場合、呼び出し元はアンロードされるまで pvData が指すメモリを確保したままにしなければなりません。 |
戻り値
呼び出しが成功した場合、Download は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
| いずれかのポインターが無効であることを示します。 | |
| データをダウンロードできないことを示します。 | |
|
シンセが開かれていないか、正しく構成されていないことを示します。 |
|
ウェーブチャンクに複数のインターリーブされたチャネルが含まれていることを示します。 |
|
アーティキュレーションチャンクまたはリンクが不正であることを示します。 |
|
インストゥルメントチャンクまたはリンクが不正であることを示します。 |
|
ウェーブダウンロードデータへのリンクが不正であることを示します。 |
|
インストゥルメント内のリージョンに、グローバルなアーティキュレーションもローカルなアーティキュレーションも存在しないことを示します。 |
|
ウェーブデータが PCM ではないことを示します。 |
|
ウェーブヘッダーが破損していることを示します。 |
|
オフセットテーブルにエラーが含まれていることを示します。 |
|
ダウンロードデータがインストゥルメントでもウェーブでもないことを示します。 |
解説(Remarks)
データは pvData が指す連続したメモリチャンクに格納されます。ただし、チャンクの先頭には、後続するデータの性質を定義する 2 つのデータ構造体があります。これらは DMUS_DOWNLOADINFO 構造体と DMUS_OFFSETTABLE 構造体(Microsoft Windows SDK ドキュメントで説明)です。DMUS_DOWNLOADINFO は、データのサイズや用途(ウェーブかインストゥルメントか)を含め、データの解析方法を記述するヘッダーです。DMUS_OFFSETTABLE は、後続のデータセグメントへのバイトオフセットのセットを提供します。データの解析はすべてこのテーブルを介して管理されます。
データ内のある構造体が別の構造体を参照する場合は、常にオフセットテーブルへのインデックスによって記述されます。オフセットテーブルはそれをデータ内のバイトオフセットに変換します。これにより、シンセサイザーはすべての参照に対して境界チェックを行うことができ、実装がより堅牢になります。カーネルモード実装では、ドライバーがオフセットテーブルのプライベートコピーを作成できるため、ユーザーモードのアプリケーションが参照を改変してクラッシュを引き起こすことを防げます。
DMUS_DOWNLOADINFO の dwDLType メンバーは、ダウンロードするデータの種類を指定します。インストゥルメントの場合は DMUS_DOWNLOADINFO_INSTRUMENT、ウェーブの場合は DMUS_DOWNLOADINFO_WAVE に設定します。新しいデータ型が登場すれば、それらに識別子が割り当てられます。dwDLId は、オブジェクトの一意な 32 ビット識別子を保持します。この識別子はオブジェクト同士を結び付けるために使用されます。レベル 1 DLS の場合、識別子はウェーブとインストゥルメントを結び付けるために使用されます。DMUS_DOWNLOADINFO の dwNumOffsetTableEntries メンバーは、後続の DMUS_OFFSETTABLE 構造体のエントリ数を示します。最後に、cbSize メンバーは、DMUS_DOWNLOADINFO + DMUS_OFFSETTABLE + データチャンクから成るメモリチャンク全体のサイズを指定します。
なお、ダウンロード用メモリには常に 32 バイトの追加パディングが付加されます。これにより、マルチポイント補間のためにループ末尾に追加のパディングを必要とするシンセサイザー実装が、ウェーブチャンクの末尾以降の領域を最大 32 バイトまで追加データで埋められるようになります。この追加パディングは cbSize に反映されます。
シンセサイザーの実装によっては、ダウンロードチャンク内のメモリをそのまま利用することを選ぶ場合があります。結局のところ、ウェーブを格納するのに十分なメモリが既に確保されているのであれば、シンセサイザーは同じメモリを再生用の保存領域として使用できます。そのため、シンセサイザーにはそのメモリを保持するという選択肢があり、その判断を pbFree パラメーターで返します。シンセサイザーがメモリを保持する場合、呼び出し元はそれを解放してはなりません。後で IDirectMusicSynth::Unload メソッドが、アンロード要求後にメモリを非同期に解放するためのコールバック機構を提供します。
Unload メソッドは、IDirectMusicSynth::Download の呼び出しによって以前にダウンロードされた DLS リソース(MIDI インストゥルメントの波形データまたはアーティキュレーションデータ)をアンロードします。
| hDownload | HANDLE | in | DLS リソースのハンドル。IDirectMusicSynth::Download メソッドの以前の呼び出しで取得したものです。下記の lpFreeHandle パラメーターが NULL 以外の場合、シンセサイザーはこのハンドルを lpFreeHandle コールバックルーチンの第 1 引数として渡します。 |
| lpFreeHandle | INT_PTR | in | DLS リソースを格納するメモリが使用されなくなったときに呼び出されるコールバックルーチンへのポインター。IDirectMusicSynth::Download の元の呼び出しが pbFree に FALSE を返した場合、シンセサイザーは Download から戻った後もダウンロードチャンク内の呼び出し元が確保したメモリへのアクセスを継続していることを意味します。その場合、シンセサイザーはメモリを解放できるようになり次第、呼び出し元に通知しますが、DLS リソースが現在使用中である可能性があるため、この通知は Unload からの戻りより後になることがあります。コールバック関数は 2 つのハンドルを引数として受け取ります。1 つ目は hDownload パラメーター(上記参照)、2 つ目は hUserData パラメーター(下記参照)です。 |
| hUserData | HANDLE | in | ユーザーデータへのポインター。上記の lpFreeHandle コールバック関数の第 2 引数として渡されます。この値の意味は呼び出し元だけが知っていますが、通常は解放対象のメモリの状態を記述するコンテキスト情報へのポインターです。 |
戻り値
呼び出しが成功した場合、Unload は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
| データをアンロードできないことを示します(hDownload が無効である可能性が高い)。 | |
|
シンセが開かれていないか、正しく構成されていないことを示します。 |
解説(Remarks)
呼び出し元が IDirectMusicSynth::Download を呼び出して DLS リソースをシンセサイザーにダウンロードすると、シンセサイザーは DLS リソースの独自のコピーを作成するか、呼び出し元のコピーを使い続けるかを選択できます。Download メソッドは、pbFree パラメーターで出力する値によって、どちらの方法をとったかを示します。
-
*pbFree=TRUE は、シンセサイザーが独自のコピーを作成した場合です。この場合、呼び出し元は Download からの戻り時に DLS 用メモリを解放できます。また、
Unloadメソッドの lpFreeHandle および hUserData パラメーターには NULL を指定できます。 - *pbFree=FALSE は、シンセサイザーが呼び出し元のコピーへのポインターを保持している場合です。この場合、呼び出し元はシンセサイザーがそのメモリの使用を終えるまで、DLS リソースを格納するメモリの確保を維持しなければなりません。
Unload の呼び出しから戻った直後に DLS リソースのメモリを解放してはなりません。その代わり、呼び出し元はシンセサイザーが lpFreeHandle コールバックルーチンを呼び出すのを待つ必要があります。シンセサイザーは、ノートの再生が終了しメモリが不要になり次第、このコールバックを呼び出します。
詳細については、Microsoft Windows SDK ドキュメントの IDirectMusic および IDirectMusicPort インターフェイスの説明と、IDirectMusicPort::UnloadInstrument メソッドの説明を参照してください。
PlayBuffer メソッドは、MIDI メッセージのストリームをシンセサイザーにダウンロードします。
| rt | LONGLONG | in | バッファーの開始時刻を指定します。この値は REFERENCE_TIME 単位で、以前に IDirectMusicSynth::SetMasterClock の呼び出しで設定したマスタークロックを基準とします。また、この値は IDirectMusicSynth::GetLatencyClock のクロックが返す時刻より後である必要があります。 |
| pbBuffer | BYTE* | inout | IDirectMusicBuffer オブジェクトが生成した、タイムスタンプ付きの MIDI メッセージを格納するメモリバッファーへのポインター |
| cbBuffer | DWORD | in | バッファーのサイズをバイト単位で指定します。 |
戻り値
呼び出しが成功した場合、PlayBuffer は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
| バッファーポインターが不正であることを示します。 | |
|
シンセが開かれていないか、正しく構成されていないことを示します。 |
|
IDirectMusicSynthSink オブジェクトが接続されていなかったことを示します。 |
|
シンセが非アクティブなときにメソッドが呼び出されたことを示します。これは有効ではありません。 |
| メッセージをキューに入れられないことを示します。 |
解説(Remarks)
これは、IDirectMusicPort::PlayBuffer メソッドのソフトウェアシンセサイザーによる実装です。バッファー形式の詳細については、Microsoft Windows SDK ドキュメントの IDirectMusicPort::PlayBuffer の説明を参照してください。
バッファー内の各 MIDI メッセージのタイムスタンプを正しく対応付けるために、シンセは REFERENCE_TIME 形式から内部のサンプルベースの時間へ変換する必要があります。ウェーブ出力ストリームは実際には IDirectMusicSynthSink によって管理されるため、シンセは各 MIDI メッセージについて IDirectMusicSynthSink::RefTimeToSample を呼び出して、タイムスタンプをサンプル時間に変換します。
通常、シンセサイザーはバッファーから各 MIDI メッセージを取り出し、サンプル時間でタイムスタンプを付け、自身の内部キューに格納します。このキューは、後にレンダリング処理によって消費されます。レンダリング処理は IDirectMusicPort::Render によって管理され、IDirectMusicSynthSink オブジェクトから呼び出されます。
詳細については、Windows SDK ドキュメントの IDirectMusic、IDirectMusicPort、IDirectMusicBuffer の各インターフェイスの説明を参照してください。
GetRunningStats メソッドは、シンセサイザーの状態に関する現在の情報を取得し、アプリケーションがシンセの動作状況を把握できるようにします。
| pStats | DMUS_SYNTHSTATS* | inout | DMUS_SYNTHSTATS 構造体(Microsoft Windows SDK ドキュメントで説明)へのポインター。メソッドはこの構造体にシンセの統計情報を書き込みます。 |
戻り値
呼び出しが成功した場合、GetRunningStats は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
| 統計情報を取得できないことを示します。 | |
| pStats ポインターが不正であることを示します。 | |
| シンセサイザーがこのメソッドを実装していないことを示します(最悪の事態を想定してください)。 | |
|
シンセが開かれていないか、正しく構成されていないことを示します。 |
解説(Remarks)
GetRunningStats メソッドは、CPU 負荷、ピーク音量、スチールされたノート数(優先度レベルの変更による。IDirectMusicSynth::SetChannelPriority を参照)など、シンセサイザーの状態に関する現在の情報を返します。このメソッドは、これらの統計情報を DMUS_SYNTHSTATS 構造体に出力します。
アプリケーションは GetRunningStats を定期的に呼び出して、実行中のシンセサイザーの状態を取得できます。実行状態のパラメーターは、dwFreeMemory を除いてすべて 1 秒ごとに更新されます。
アプリケーションは通常、Windows SDK ドキュメントで説明されている IDirectMusicPort::GetRunningStats を呼び出すことで、間接的に GetRunningStats にアクセスします。
GetPortCaps メソッドは、DirectMusic の "ポート"(音楽データを送受信するデバイスを指す DirectMusic の用語)の機能を取得します。
| pCaps | DMUS_PORTCAPS* | inout | DMUS_PORTCAPS 構造体(Microsoft Windows SDK ドキュメントで説明)へのポインター。メソッドはこの構造体に DirectMusic "ポート" の機能を書き込みます。 |
戻り値
呼び出しが成功した場合、GetPortCaps は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
| pCaps ポインターが不正であることを示します。 |
解説(Remarks)
アプリケーションが IDirectMusic::EnumPort(Windows SDK ドキュメントで説明)を呼び出して利用可能な DirectMusic "ポート" を列挙すると、DirectMusic は登録された各デバイスの GetPortCaps メソッドを呼び出します。
つまり、この呼び出しの際にシンセサイザーの作成と初期化という追加のオーバーヘッドが発生します。単にシンセサイザーを作成するだけのオーバーヘッドは最小限に抑えるのが望ましいでしょう。機能を取得するためだけに作成され、その後すぐに解放される可能性があるためです。
DirectMusic の "ポート" という用語を DMus ポートドライバーと混同しないでください。DirectMusic ポートは、DirectMusic フィルターのレンダーピンまたはキャプチャーピンに対応します。DirectMusic ポートの詳細については、Windows SDK ドキュメントの IDirectMusicPort インターフェイスの説明を参照してください。
SetMasterClock メソッドは、シンセサイザーにマスターのタイムソースを提供します。シンセサイザーは、DirectMusic の他の部分と同期するためにこれを必要とします。
| pClock | IReferenceClock* | in | マスターの IReferenceClock(Microsoft Windows SDK ドキュメントで定義)オブジェクトへのポインター。このオブジェクトは、現在の DirectMusic インスタンス内のすべてのデバイスで使用されます。 |
戻り値
呼び出しが成功した場合、SetMasterClock は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
| インターフェイスポインターが不正であることを示します。 | |
|
シンセが開かれていないか、正しく構成されていないことを示します。 |
解説(Remarks)
IDirectMusicSynthSink によって管理されるシンセサイザーのウェーブ出力デバイスは、同期先となるマスタークロックを受け取るまで機能できません。ウェーブ出力デバイスは自身の内部クロックをマスタークロックに位相同期させ、それによってシンセサイザーにタイミング情報を提供できるようになり、IDirectMusicSynth::PlayBuffer の呼び出しで受け取るタイムスタンプを解釈できるようになります。
ほとんどの実装では、SetMasterClock は IDirectMusicSynthSink::SetMasterClock の呼び出しによってマスタークロックを IDirectMusicSynthSink に渡す程度のことしか行いません。
マスタークロックは、IDirectMusicSynth::GetLatencyClock の呼び出しでシンセから取得されるレイテンシクロックとは大きく異なります。マスタークロックが時間の基準を提供するのに対し、レイテンシクロックは単にシンセサイザーのレンダリングエンジンの進行状況を追跡するだけです。これにより、アプリケーションは PlayBuffer メソッドを呼び出してイベントを再生用に送出できる最も早い時刻を知ることができます。レイテンシクロックはマスタークロックに厳密に同期しているため、その単位は相対的なものです。
シンセサイザーのレイテンシは、レイテンシクロックの時刻とマスタークロックの時刻を比較することで測定できます。なお、レイテンシクロックはシンセサイザーのミキシングがバースト的に行われることを反映してジッターを持ちますが、マスタークロックは滑らかに進行するはずです。レイテンシは 450 ミリ秒を超えてはなりません。
詳細については、Windows SDK ドキュメントの IDirectMusic インターフェイスの説明を参照してください。
pClock パラメーターは、COM オブジェクトの参照カウント規約に従います。
GetLatencyClock メソッドは、現在のミックス時間を追跡する参照クロックオブジェクトの IReferenceClock インターフェイス(Microsoft Windows SDK ドキュメントで説明)への参照を取得します。
| ppClock | IReferenceClock** | out | レイテンシクロックの出力ポインター。このパラメーターは呼び出し元が確保したポインター変数を指し、メソッドはそこにレイテンシクロックオブジェクトの IReferenceClock インターフェイスへのポインターを書き込みます。このインターフェイスを通じて、シンセサイザーは現在のミックス時間を取得できます。このパラメーターには有効な NULL 以外のポインター値を指定してください。 |
戻り値
呼び出しが成功した場合、GetLatencyClock は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
| レイテンシクロックにアクセスできなかったことを示します。 | |
| ppClock ポインターが有効でないことを示します。 | |
|
IDirectMusicSynthSink オブジェクトが接続されていなかったことを示します。 |
|
シンセが開かれていないか、正しく構成されていないことを示します。 |
解説(Remarks)
このメソッドは、出力オーディオストリームを扱うウェーブシンク(IDirectMusicSynthSink)オブジェクトによって作成されたレイテンシクロックを返します。レイテンシクロックは、IReferenceClock::GetTime メソッドが呼び出されるたびに現在のレンダー時刻を返します。この時刻は常に、マスタークロック(IDirectMusicSynth::SetMasterClock および IDirectMusicSynthSink::SetMasterClock の呼び出しによってシンセサイザーとウェーブシンクに設定されます)が確立した時刻を基準とする相対値です。レイテンシ時刻は、パフォーマンスがノートの再生を開始できる次の時刻を判断するために使用されます。レイテンシは 450 ミリ秒を超えてはなりません。
レイテンシクロックの詳細については、Synthesizer Latency を参照してください。また、Windows SDK ドキュメントの IDirectMusic および IReferenceClock インターフェイスの説明も参照してください。
ppClock パラメーターは、COM オブジェクトの参照カウント規約に従います。
Activate メソッドは、プログラム制御によってオーディオデバイスを有効または無効にします。
| fEnable | BOOL | in | オーディオデバイスを有効にするか無効にするかを指定します。TRUE の場合、メソッドはデバイスを有効にします。FALSE の場合は無効にします。 |
戻り値
呼び出しが成功した場合、Activate は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
| オーディオデバイスが既に非アクティブであることを示します。 | |
| 要求が失敗したことを示します。 | |
| デバイスをロードするのに十分なメモリがないことを示します。 | |
|
シンセが開かれていないか、正しく構成されていないことを示します。 |
|
IDirectMusicSynthSink オブジェクトが接続されていなかったことを示します。 |
|
シンセが既にアクティブであることを示します。 |
解説(Remarks)
プログラム制御でオーディオデバイスを有効・無効にできるようにすることで、Activate はアプリケーションにリソース使用を管理する手段を提供します。音楽を再生していないとき、アプリケーションはウェーブ出力リソースを非アクティブにして、他のアプリケーションが使用できるように解放できます。
ウェーブ出力リソースは、実際には IDirectMusicSynthSink インターフェイスを持つ別の COM オブジェクトによって管理されます。このオブジェクトは、まず SetSynthSink の呼び出しによって接続されている必要があります。そうでない場合、シンセサイザーは Activate の呼び出しを DMUS_E_NOSYNTHSINK で失敗させます。
アクティブ化の処理は、主にウェーブシンクオブジェクトが行います。IDirectMusicSynth::Activate が呼び出されると、シンセは内部のアクティブ化状態を設定し、IDirectMusicSynthSink::Activate を呼び出してウェーブ出力を有効または無効にします。
SetSynthSink メソッドは、シンセとウェーブシンクとの接続を確立します。
| pSynthSink | IDirectMusicSynthSink* | in | シンセシンクへのポインター。このパラメーターは、シンセに接続する IDirectMusicSynthSink シンクオブジェクトを指すか、シンセを現在のシンセシンクから切断する場合は NULL を指定します。 |
戻り値
呼び出しが成功した場合、SetSynthSink は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
| pSynthSink に無効なポインターが渡されたことを示します。 | |
| IDirectMusicSynthSink オブジェクトに接続できなかったためにメソッドが失敗したことを示します。 | |
| 接続を確立するのに十分なメモリがないことを示します。 |
解説(Remarks)
シンセサイザーがその機能の多くを公開できるようになる前に、IDirectMusicSynthSink インターフェイスで表されるウェーブシンクオブジェクトに接続されている必要があります。IDirectMusicSynth::SetSynthSink メソッドはこの接続を確立します。
IDirectMusicSynthSink オブジェクトは、最終的なオーディオ出力先(DirectSound、Microsoft Win32 ウェーブオーディオ、またはその他のオーディオストリームなど)への実際の接続処理を担当します。既定の実装ではデータを DirectSound に送ります。
このアプローチにより、シンセサイザー自身に特別なコードを持たせることなく、さまざまな方式のオーディオ出力に接続できます。これにより、1 つのシンセサイザー実装を任意の利用可能なウェーブ出力デバイスに非常に簡単に接続できます。
詳細については、Microsoft Windows SDK ドキュメントの IDirectMusic インターフェイスの説明を参照してください。
pSynthSink パラメーターは、COM オブジェクトの参照カウント規約に従います。
Render メソッドは、オーディオストリーム内のバッファーへレンダリングするために、シンセシンクから呼び出されます。
| pBuffer | SHORT* | inout | 書き込み先のバッファーへのポインター |
| dwLength | DWORD | in | バッファーの長さを指定します。バッファー長はバイト単位ではなくサンプル単位で表されます。バッファーのバイト単位のサイズは、そのバッファーの形式によって変化します。形式は IDirectMusicSynth::Activate コマンドに応じてシンセが設定します。 |
| llPosition | LONGLONG | in | オーディオストリーム内の位置を指定します。位置はバイト単位ではなくサンプル単位で表されます。呼び出し元は、呼び出しのたびにこの値を dwLength ずつ増加させてください。 |
戻り値
呼び出しが成功した場合、Render は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
| メソッドが失敗したことを示します。 | |
| バッファーが不正であることを示します。 | |
|
シンセが開かれていないか、正しく構成されていないことを示します。 |
|
シンセが非アクティブなときには、このメソッドが有効でないことを示します。 |
解説(Remarks)
通常、シンセサイザーはメッセージをレンダリング済みのウェーブデータへ変換する処理を 2 つのプロセスで管理します。1 つ目のプロセスでは、IDirectMusicSynth::PlayBuffer の呼び出しでアプリケーションから受け取った MIDI メッセージにタイムスタンプを付け、内部キューに格納します。次に、Render に応じて、2 つ目のプロセスがキューから MIDI メッセージを取り出し、要求されたレンダーバッファーの時間範囲内で適切な音を合成してオーディオを生成します。
シンセサイザーは MIDI メッセージをバッファーにレンダリングする際、IDirectMusicSynthSink::RefTimeToSample を呼び出して MIDI のタイムスタンプをサンプル位置に変換します。これにより、(IDirectMusicSynthSink の実装が適切に書かれている限り)きわめて正確なタイミングが保証されます。
詳細については、Microsoft Windows SDK ドキュメントの IDirectMusic インターフェイスの説明を参照してください。
SetChannelPriority メソッドは、MIDI チャネルの優先度を設定します。
| dwChannelGroup | DWORD | in | チャネルが属するグループを指定します。この値は 1 以上でなければなりません。 |
| dwChannel | DWORD | in | チャネルグループ内のチャネルを指定します。このパラメーターは 0 から 15 の範囲のインデックスです。 |
| dwPriority | DWORD | in | チャネルの優先度ランクを指定します。このパラメーターに定義されているランク値の一覧については、Microsoft Windows SDK ドキュメントの IDirectMusicPort::GetChannelPriority のリファレンスページを参照してください。 |
戻り値
呼び出しが成功した場合、SetChannelPriority は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。
解説(Remarks)
SetChannelPriority メソッドは、MIDI 合成エンジンをサポートするために実装されています。このメソッドにより、割り当てられたボイスを、どのチャネル上にあるかに応じて異なる優先度で動作させることができます。同時に処理しきれないほど多くのボイスがある場合、ボイスが解放されることがあり、そのボイスが属するチャネルの優先度に基づいて破棄されます。より高い優先度のチャネルに新しいボイスが入り、空きボイスがない場合、MIDI 合成エンジンは最も優先度の低いボイスからチャネルをスチールし、チャネルを再割り当てします。
詳細については、Windows SDK ドキュメントの IDirectMusicPort::GetChannelPriority および IDirectMusicPort::SetChannelPriority メソッドの説明を参照してください。
GetChannelPriority メソッドは、MIDI チャネルの優先度を出力します。
| dwChannelGroup | DWORD | in | チャネルが属するチャネルグループを指定します。このパラメーターは 1 以上でなければなりません。 |
| dwChannel | DWORD | in | チャネルグループ内のチャネルのインデックスを指定します。これは 0 から 15 の範囲の値です。 |
| pdwPriority | DWORD* | inout | 優先度ランクの出力ポインター。このパラメーターは呼び出し元が確保した変数を指し、メソッドはそこに優先度ランクの値を書き込みます。このパラメーターに定義されている優先度の値の一覧については、Microsoft Windows SDK ドキュメントの IDirectMusicPort::GetChannelPriority のリファレンスページを参照してください。 |
戻り値
呼び出しが成功した場合、GetChannelPriority は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。
解説(Remarks)
このメソッドは IDirectMusicSynth::SetChannelPriority メソッドと組み合わせて使用し、チャネルの優先度を制御して正しいボイススチールを実現します。
詳細については、Windows SDK ドキュメントの IDirectMusicPort::GetChannelPriority および IDirectMusicPort::SetChannelPriority メソッドの説明を参照してください。
GetFormat メソッドは、ウェーブ形式に関する情報を取得します。
| pWaveFormatEx | WAVEFORMATEX* | inout | 呼び出し元が確保した WAVEFORMATEX 構造体へのポインター。メソッドはこの構造体に形式に関する情報を書き込みます。この値は NULL でもかまいません。詳細については、以下の「解説」セクションを参照してください。 |
| pdwWaveFormatExSize | DWORD* | inout | 呼び出し元が確保した DWORD 変数へのポインター。この変数には、pWaveFormatEx が指す構造体のサイズをバイト単位で指定します。詳細については、以下の「解説」セクションを参照してください。 |
戻り値
呼び出しが成功した場合、GetFormat は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
| いずれかのポインターが有効でないことを示します。 | |
|
シンセが開かれていないか、正しく構成されていないことを示します。 |
解説(Remarks)
WAVEFORMATEX 構造体は、形式の詳細に応じて可変長になることがあります。そのため、アプリケーションは形式の記述を取得する前に、まずこのメソッドを pWaveFormatEx パラメーターに NULL を指定して呼び出し、IDirectMusicSynth オブジェクトに形式のサイズを問い合わせます。この場合、シンセは pdwWaveFormatExSize パラメーターに構造体のサイズを返します。アプリケーションはその後、十分なメモリを確保し、IDirectMusicSynth::GetFormat を再度呼び出して形式の記述を取得できます。
pWaveFormatEx パラメーターが NULL でない場合、DirectMusic は pWaveFormatEx に最大で pdwWaveFormatExSize バイトを書き込みます。
詳細については、Microsoft Windows SDK ドキュメントの IDirectMusicPort インターフェイスおよび IDirectMusicPort::GetFormat メソッドの説明を参照してください。
GetAppend メソッドは、DirectMusic の "ポート" がダウンロードバッファーの末尾に追加する必要があるウェーブサンプルの数を出力します。
| pdwAppend | DWORD* | inout | 追加するサンプル数の出力ポインター。このパラメーターは呼び出し元が確保した変数を指し、メソッドはそこにメモリを必要とする追加サンプルの数を書き込みます。必要なメモリのバイト数は、ウェーブ形式から計算できます。 |
戻り値
呼び出しが成功した場合、GetAppend は S_OK を返します。それ以外の場合は、適切なエラーコードを返します。次の表に、返される可能性のあるステータスコードの一部を示します。
| 戻り値 | 説明 |
|---|---|
| ポインターバッファーが無効であることを示します。 | |
| メソッドが実装されていないことを示します。 |
解説(Remarks)
このメソッドは、ダウンロードバッファーの末尾にどれだけの追加ストレージを用意すべきかを判断するために呼び出されます。メソッドは、バッファーを拡張すべき追加のウェーブサンプル数を示すカウントを出力します。
波形をダウンロードする際、シンセの実装によっては、波形の末尾にわずかなデータを付加する必要がある場合があります。ポートの合成エンジンは、この追加メモリをループ境界をまたぐ補間のために使用できます。
たとえば、ウェーブが末尾の 20 サンプルでループする場合、ループバック時の処理を計算する補間の演算に、正しく補間するための追加データが末尾に必要となることがあります。
ダウンロードバッファーを pdwAppend の分だけ拡張しておくと、シンセは単にバッファーの末尾に追加サンプルを付け足すだけで済みます。そうでない場合、シンセは追加データを付加する領域を確保するために、ダウンロードバッファーの内容をより大きなバッファーへコピーしなければなりません。
DirectMusic の "ポート" という用語を DMus ポートドライバーと混同しないでください。DirectMusic ポートは、DirectMusic フィルターのレンダーピンまたはキャプチャーピンに対応します。DirectMusic ポートの詳細については、Microsoft Windows SDK ドキュメントの IDirectMusicPort インターフェイスの説明を参照してください。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IDirectMusicSynth "{09823661-5C85-11D2-AFA6-00AA0024D8B6}" #usecom global IDirectMusicSynth IID_IDirectMusicSynth "{58C2B4D0-46E7-11D1-89AC-00A0C9054129}" #comfunc global IDirectMusicSynth_Open 3 var #comfunc global IDirectMusicSynth_Close 4 #comfunc global IDirectMusicSynth_SetNumChannelGroups 5 int #comfunc global IDirectMusicSynth_Download 6 sptr,sptr,var #comfunc global IDirectMusicSynth_Unload 7 sptr,sptr,sptr #comfunc global IDirectMusicSynth_PlayBuffer 8 int64,var,int #comfunc global IDirectMusicSynth_GetRunningStats 9 var #comfunc global IDirectMusicSynth_GetPortCaps 10 var #comfunc global IDirectMusicSynth_SetMasterClock 11 sptr #comfunc global IDirectMusicSynth_GetLatencyClock 12 sptr #comfunc global IDirectMusicSynth_Activate 13 int #comfunc global IDirectMusicSynth_SetSynthSink 14 sptr #comfunc global IDirectMusicSynth_Render 15 var,int,int64 #comfunc global IDirectMusicSynth_SetChannelPriority 16 int,int,int #comfunc global IDirectMusicSynth_GetChannelPriority 17 int,int,var #comfunc global IDirectMusicSynth_GetFormat 18 var,var #comfunc global IDirectMusicSynth_GetAppend 19 var ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※#usecom 末尾は CoCreateInstance 用のクラスID(コクラスCLSID, SDKから自動取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IDirectMusicSynth "{09823661-5C85-11D2-AFA6-00AA0024D8B6}" #usecom global IDirectMusicSynth IID_IDirectMusicSynth "{58C2B4D0-46E7-11D1-89AC-00A0C9054129}" #comfunc global IDirectMusicSynth_Open 3 sptr #comfunc global IDirectMusicSynth_Close 4 #comfunc global IDirectMusicSynth_SetNumChannelGroups 5 int #comfunc global IDirectMusicSynth_Download 6 sptr,sptr,sptr #comfunc global IDirectMusicSynth_Unload 7 sptr,sptr,sptr #comfunc global IDirectMusicSynth_PlayBuffer 8 int64,sptr,int #comfunc global IDirectMusicSynth_GetRunningStats 9 sptr #comfunc global IDirectMusicSynth_GetPortCaps 10 sptr #comfunc global IDirectMusicSynth_SetMasterClock 11 sptr #comfunc global IDirectMusicSynth_GetLatencyClock 12 sptr #comfunc global IDirectMusicSynth_Activate 13 int #comfunc global IDirectMusicSynth_SetSynthSink 14 sptr #comfunc global IDirectMusicSynth_Render 15 sptr,int,int64 #comfunc global IDirectMusicSynth_SetChannelPriority 16 int,int,int #comfunc global IDirectMusicSynth_GetChannelPriority 17 int,int,sptr #comfunc global IDirectMusicSynth_GetFormat 18 sptr,sptr #comfunc global IDirectMusicSynth_GetAppend 19 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※#usecom 末尾は CoCreateInstance 用のクラスID(コクラスCLSID, SDKから自動取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。