--- PlayCore.dll version 3.6.0 --- ※ このファイルは固定長フォントのエディタ(メモ帳など)で閲覧してください。 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= PlayCore.dll について  PlayCore.dll は、EasyPlayML desktop が利用する DLL です。 EasyPlayML desktop を利用することで SMF ファイル (MIDI ファイル) を 作成することが可能ですが、このプログラムが使うファイル形式 .tmd (Text Melody Data) の内部データを解釈するのが PlayCore.dll となります。  PlayCore.dll は API を提供しているため、EasyPlayML desktop を 利用せずに API 経由でメロディデータの解析や再生などを行うことができます。 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 使い方  C/C++ などで PlayCore.dll をロードし、GetProcAddress() 関数で PlayCore.dll に 定義されている関数アドレスを取得し、呼び出します。PlayCore.h には関数と 構造体の定義が記述されており、PlayCore.lib ライブラリ ファイルを利用することで 静的リンクを行うことも可能です。  PlayCore.dll に定義されている関数は以下の通りです (すべて extern "C")。 BOOL WINAPI PlayMIDIAvailable(); 説明: MIDI デバイスが存在するかどうかチェックします。 BOOL WINAPI PlayInitialize(LPDWORD lpdwError /* = NULL*/); 説明: 再生するために MIDI デバイスを初期化します。  lpdwError はエラー時にエラーコードが設定されます。NULL の場合  エラーコードは設定されません。また、0xFFFFFFFF の時は  デバイスが働いていない(または存在しない)ことを示します。 void WINAPI PlayTerminate(); 説明: MIDI デバイスを閉じます。 BOOL WINAPI PlayText(int nCount, const LPCSTR* lplpszParts, PROCESSSMSGPROC pfnProcessMsg); 説明: データを演奏します。nCount は lplpszParts にある メロディのパート数、lplpszParts はメロディデータの配列です。 lplpszParts のメロディデータは、Play Board での「メロディ データ」に 相当します。なお、解析は別スレッド(タイマー関数)で行われるため、  この関数は 解析が終了する前に戻ります。(テキストは解放しても構いません。)  pfnProcessMsg は、ユーザー定義の関数で、PROCESSMSGPROC 型は typedef BOOL (CALLBACK* PROCESSMSGPROC)(); と定義します。この関数はテキスト解析中に呼び出され、関数の中では ウィンドウがロックされないようにするためにメッセージ処理などを行います。 FALSE を返した場合、解析処理は終了されます。 例は後述しています。  関数の戻り値が FALSE のときは PlayGetLastError でエラーの詳細を取得することができます。 BOOL WINAPI PlayText2(LPCSTR lpszSeparatedParts, int nCount, PROCESSSMSGPROC pfnProcessMsg); 説明: データを演奏します。こちらは、lpszSeparatedParts の内容を パートごとに NULL 文字で区切ってください。nCount に負の値を指定すると、 NULL 文字からパート数を計算します。その際、最後は NULL 文字を 2 つ入れます。なお、nCount を指定した場合、計算中のパートの番号が nCount を下回っていたら、2 つ続く NULL 文字でも読み取りを終了しません。 形式: lpszSeparatedParts = part1part2part3, nCount = -1    lpszSeparatedParts = part1part2part4, nCount = 4  pfnProcessMsg は上の説明をご覧ください。  関数の戻り値が FALSE のときは PlayGetLastError でエラーの詳細を取得することができます。 --- Version 1.05 まで --- BOOL WINAPI PlayWait(DWORD dwMilliseconds); --- Version 2.00 以降 --- int WINAPI PlayWait(DWORD dwMilliseconds); 説明: 演奏中に呼び出します。テキストの解析処理部分に dwMilliseconds で  指定したミリ秒の時間だけ処理を預けます (WaitForSingleObject とほぼ同じ)。  演奏が終了していた場合は 0 を返し、dwMilliseconds だけ待った場合は  1 を返します。dwMilliseconds に INFINITE (= 0xFFFFFFFF) を指定すると  演奏が終了するまで処理が戻りません。Version 2.00 以降は、  待機中にウィンドウのメッセージが入った場合、待機を中断して  PlayWait は 2 を返して終わります (MsgWaitForMultipleObjects を使用)。  ※ Version 3.0 以降では、呼び出し元プロセスが User32.dll をロード    していないときは、MsgWaitForMultipleObjects を使用しません。 void WINAPI PlayStop(); 説明: 演奏を止めます。PlaySetRepeat でリピート可能にしたときは  演奏が自動で止まらないため、この関数で止める必要があります。 void WINAPI PlaySetRepeat(BOOL bRepeat); 説明: リピート再生を可能にします。bRepeat を TRUE にするとリピートします。  呼び出しは演奏停止中でも演奏中でも可能です。 BOOL WINAPI PlayCreateMIDI(HANDLE hFile, int nTempo, LPCSTR lpszComment, LPCSTR lpszCopyright, LPCSTR lpszTitle, int nCount, const LPCSTR* lplpszNames, const LPCSTR* lplpszParts, LPCSTR lpszDefTitleFormat); 説明: メロディデータから SMF ファイル(MIDI ファイル)を作成します。  hFile は出力先ファイルのハンドル、nTempo は初期テンポ、lpszComment は MIDI  ファイルに含めるコメント、lpszCopyright は MIDI ファイルの著作権、  lpszTitle はタイトル、nCount はパート数、lplpszNames は各パートの  パート名、lplpszParts は各パートのメロディデータ、  lpszDefTitleFormat はパート名が存在しなかった時の既定のパート名と  なる文字列です。lpszDefTitleFormat は、%d という文字列を含むと、  それがパートの番号に置き換わります (ただし %d は各文字列内 1 回のみ利用可能)。  なお、lplpszParts の途中のパートは NULL でも構いません。  ドラムパートを含める場合は、メロディデータで i 命令を使用するか、  パート数を 10 以上にして 10 番目(インデックス値 9)にドラムパートを  指定する必要があります。  関数の戻り値が FALSE のときは PlayGetLastError でエラーの詳細を取得することができます。 --- Version 2.0 以降に追加された関数 --- BOOL WINAPI PlayTextEx(int nCount, const LPCSTR* lplpszParts, PROCESSMSGPROC pfnProcessMsg, int nIndex, int nPositionStart, int nPositionEnd); BOOL WINAPI PlayTextEx2(LPCSTR lpszSeparatedParts, int nCount /* = -1*/, PROCESSMSGPROC pfnProcessMsg, int nIndex, int nPositionStart, int nPositionEnd); 説明: この 2 つの関数では、データの一部分だけを再生することが可能です。  nIndex で再生する範囲の基準となるメロディのインデックスを指定し、  nPositionStart と nPositionEnd で再生開始・終了位置を、メロディ  文字列の位置・範囲 (ABCDEFG という文字列の場合、位置 2 は C の位置)  を指定します。残りの引数は PlayText、PlayTextEx 関数と同じです。  なお、文字列はすべて ANSI 文字列(UTF-8 形式)です。  関数の戻り値が FALSE のときは PlayGetLastError でエラーの詳細を取得することができます。 --- Version 3.0 以降に追加された関数 --- DWORD PLAYCOREAPI PlayCompileData(LPCSTR lpszParts, LPPLAYMELODYDATA lpMelodyData, DWORD dwSize); 説明: lpszParts で指定したメロディデータを PLAYMELODYDATA の配列に変換します。  dwSize には lpMelodyData の最大配列サイズ(バイト単位)を指定します。  lpMelodyData が NULL の場合、あるいは dwSize で指定した数が  変換に必要な配列のサイズよりも小さい場合、戻り値は必要なサイズが返ります。 ※ dwSize は配列の要素数ではないことに注意してください。 BOOL PLAYCOREAPI PlayFromCompiled(int nCount, const LPCPLAYMELODYDATA* lplpMelodyData, PROCESSMSGPROC pfnProcessMsg); BOOL PLAYCOREAPI PlayFromCompiledEx(int nCount, const LPCPLAYMELODYDATA* lplpMelodyData, PROCESSMSGPROC pfnProcessMsg, int nIndex, int nPositionStart, int nPositionEnd); [※ 非推奨 : それぞれ PlayFromCompiled2 および PlayFromCompiledEx2 を使用してください。] 説明: PLAYMELODYDATA の配列からデータを読み込み演奏します。lplpMelodyData は  各パートごとの「PLAYMELODYDATA の配列」をまとめた配列です。  その他は PlayText、PlayTextEx と同じですが、nPositionStart と nPositionEnd は  PLAYMELODYDATA の配列における位置です。  関数の戻り値が FALSE のときは PlayGetLastError でエラーの詳細を取得することができます。  ※ lplpMelodyData に含めるメロディデータの配列は、厳密な PLAYMELODYDATA の    配列ではなく、各要素のサイズが (MELODYDATA_HEADER_SIZE + wDataSize メンバの値)    となっています。 BOOL PLAYCOREAPI PlayCheckText(LPCSTR lpszPlayText, LPDWORD lpdwErrorPos, LPWORD lpwErrorReason); 説明: lpszPlayText のメロディデータをチェックします。正常なデータであれば  TRUE を返します。エラーが見つかった場合は lpdwErrorPos にテキストの位置、  lpwErrorReason にエラーの原因を設定して FALSE を返します。lpwErrorReason は  PLAYERRORREASON 列挙子の中のいずれかの値です。  また、関数の戻り値が FALSE のときは PlayGetLastError でもエラーの詳細を取得することができます。 BOOL PLAYCOREAPI PlaySetMute(int nIndex, BOOL bMute); 説明: ミュートする(演奏しない)、あるいはそれを解除するパートを指定します。  nIndex はパート番号であり、MIDI チャンネル番号ではありません。  ミュートは音を鳴らさないだけであり、テンポ命令などは処理されます。  PlayCreateMIDI 関数には影響しません。 BOOL PLAYCOREAPI PlayGetVersion(LPWORD lpwMajor, LPWORD lpwMinor); 説明: PlayCore.dll のバージョンを返します。 --- Version 3.1 以降に追加された関数 --- BOOL PLAYCOREAPI PlayFromCompiled2(int nCount, const LPCPLAYMELODYDATA* lplpMelodyData, const size_t* pnMelodyDataSizes, PROCESSMSGPROC pfnProcessMsg); BOOL PLAYCOREAPI PlayFromCompiledEx2(int nCount, const LPCPLAYMELODYDATA* lplpMelodyData, const size_t* pnMelodyDataSizes, PROCESSMSGPROC pfnProcessMsg, int nIndex, int nPositionStart, int nPositionEnd); 説明: PLAYMELODYDATA の配列からデータを読み込み演奏します。lplpMelodyData は  各パートごとの「PLAYMELODYDATA の配列」をまとめた配列、pnMelodyDataSizes は  その配列の各要素に対応する「データサイズ」の配列です。  その他は PlayText、PlayTextEx と同じですが、nPositionStart と nPositionEnd は  PLAYMELODYDATA の配列における位置です。  関数の戻り値が FALSE のときは PlayGetLastError でエラーの詳細を取得することができます。 BOOL PLAYCOREAPI PlayCalcMelodyDataPos(LPCSTR lpszPart, int nEndPos, DWORD* pdwPosResult); 説明: 文字列形式のメロディデータから PLAYMELODYDATA 形式のデータに変換した際に、  文字列における nEndPos の位置に対応するデータ位置を pdwPosResult に返します。  nEndPos は文字列としての位置を指定します。  関数の戻り値が FALSE のときは PlayGetLastError でエラーの詳細を取得することができます。 BOOL PLAYCOREAPI PlayGetLastError(LPDWORD lpdwErrorPos, LPWORD lpwErrorReason); 説明: 最後にメロディデータを解析した際に発生したエラーを返します。 BOOL PLAYCOREAPI PlayInitializeEx(UINT uDeviceID, LPDWORD lpdwError /* = NULL*/); 説明: Windows によって定められる MIDI デバイスの ID を指定してデバイスの初期化を行います。  デバイスの ID を指定することができる以外は PlayInitialize と同じです。 ----------------------------------------  Visual Basic から呼び出す場合、Declare ステートメントを使用してください。 DWORD、int、BOOL は Long 型、LPCSTR は String 型、PROCESSSMSGPROC は Long 型で定義し、PROCESSSMSGPROC に指定する値は、標準モジュールに関数を 作成し、その関数を AddressOf を使って指定してください。 なお、Visual Basic からは PlayText ではなく PlayText2 が利用しやすい形式となっています。 ※ PlayFromCompiled などの関数については未対応です。 --- PROCESSMSGPROC 型の関数の例 (C/C++) --- BOOL CALLBACK ProcessMsgProc() { MSG msg; if (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (msg.message == WM_QUIT) { // メインメッセージループに WM_QUIT を取得させるため // GetMessage を呼び出さない。 return FALSE; } else if (msg.message == WM_PAINT) { // このメッセージは削除 (GetMessage) の必要が無い ::DispatchMessage(&msg); } else { // 普通のメッセージ処理 ::GetMessage(&msg, NULL, 0, 0); ::TranslateMessage(&msg); ::DispatchMessage(&msg); } } return TRUE; } --- PROCESSMSGPROC 型の関数の例 (VB) --- Public Function ProcessMsgProc() As Long DoEvents ' アプリケーションが終了しているフラグがあれば ' それをチェックし、終了しているならば 0 を返します。 ProcessMsgProc = 1 End Function =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 再配布とインストール & アンインストール  この DLL は自由に使用・再配布が可能です。ただし、これを使って再生する曲が 自作曲で無い場合や、個人で利用するとき以外は著作権にご注意ください。 なお、DLL に関係のない問題に関しての責任は負いかねます。  DLL のインストール・アンインストールはコピーと削除のみで可能です。 レジストリなどは使用していません。 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= メロディデータの命令について  使用可能な命令の一覧については以下のWebサイト上に掲載しています。 → https://www.pg-fl.jp/music/play/syntax.htm =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 更新履歴 Version 3.6 ・pb において負の値が利用できない問題を修正しました。 Version 3.1 (未公開) ・以下の命令を追加しました。(説明省略、順不同)  atc、cele、phas、rpn、nrpn、macro、mmacro、& (マクロ呼び出し)、  「1, 2, 3, ...」(マクロ内音符)、zz ・n 命令を r 命令に変更しました。 Version 3.00.3 ・データの内部処理を大きく変更しました(PLAYMELODYDATA の導入)。  それに伴って、演奏のズレがほとんど無くなりました。 ・MIDI ファイル出力におけるベース時間を変更しました。 ・「臨時記号」の概念を導入し、小節内では臨時記号が続くようにしました。  小節区切りは「|」と改行文字です。 ・以下の命令を追加しました。(説明省略、順不同)  nf、sigp、key、ped、hold、legato、port、soft、sust、bal、foot、  modl、ports、cho、revb、trem、pb、pbs ・tn 命令を廃止しました。 ・テンポ命令と調号命令は、どのパートに記述しても全パートに影響が  出るようにしました。 ・その他多くのバグを修正しました。 Version 2.01.2 ・w 命令や、そのほかの時間処理の不具合を修正しました。 ・以下の命令を追加しました。  sig -- 調号を設定します。この後の音符は、+ や - を付けなくても 調号に合わせて変化します。 形式は 2 通りあります。 sigb-m : 「b-m」は「Bフラットマイナー」を表し、フラットが 5 つ付いた ~~~ 調号が設定されます。同様に「sigf+」は「f+」なのでシャープが 6 つ、「siga+m」は「a+m」なのでシャープが 7 つ付きます。 (※ b-m と a+m は同じ調ですが、シャープやフラットの付く音が 変わります。) sig+4 : 「+」は音符の直後につけるとシャープですが、調号命令では ~~ 「+4」などと表記して「シャープ 4 つの調号」と表すことができます。 同様に「-2」は「フラット 2 つ」です。+ や - を省略すると + が付いているものとみなされます。「+0」と「-0」は同じ意味で シャープやフラットのない調号になります。 ※ MIDI ファイルを意識する場合は前者の形式を使ってください。 Version 2.01 ※ Play Board 2.00 はしばらく時間がかかりそうです。 ・以下の命令を追加しました。  rep{ } -- { } で囲まれている部分を 1 度だけ繰り返します。  cresc{ } -- { } 内を演奏中に、強さを m から n (数値) に徐々に変えます。   m、n は 10 進数、16 進数 (先頭に x)、8 進数 (先頭に 0) が   指定でき、m > n でも m < n でも構いません。  rit{ } -- { } 内を演奏中に、テンポを m から n (数値) に徐々に変えます。   m、n の指定は上記と同じです。  ta、tI、tII -- テンポ命令の特殊版で、ta は「a tempo」、tI は「Tempo I」、   tII は「Tempo II」を表します。 Version 2.00 ※ Play Board 2.00 の開発 (現在開発中、グラフィック編集が可能)   に先駆け、PlayCore 修正版を公開。 ・PlayTextEx、PlayTextEx2 関数を追加し、部分再生を可能にしました。 ・内部の処理でスレッドを廃止し、timeSetEvent 関数によるコールバック  内での処理に変更、CPU 使用率を占拠しなくなりました。 ・PlayWait 関数の内容 (戻り値) を変更。今までのアプリケーションは  そのまま使用できます。 Version 1.05 ・以下の命令を追加しました。  arp -- ピアノの終わりなどによくあるアルペジオです。 和音の直前に指定してください。 tn -- テンポ + 休符です。txxx 命令の直後に n 命令を置いたのと同義です。 tn のあとには三桁の数値がきます (テンポを表す)。  stac -- スタッカートです。音の直前に指定してください。 内容としては h030 とほぼ同義ですが、1 つの音のみ有効です。  stacs -- スタッカーティシモです。音の直前に指定してください。 内容としては h015 とほぼ同義ですが、1 つの音のみ有効です。  stact -- スタッカートとテヌートの組み合わせです。音の直前に指定してください。 内容としては h040 とほぼ同義ですが、1 つの音のみ有効です。  ten -- テヌートです。音の直前に指定してください。 内容としては h090 とほぼ同義ですが、1 つの音のみ有効です。 Version 1.04 (初期バージョン) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ホームページ: https://www.pg-fl.jp/ 作者: ジェット