ピストンコラージュ
ピストンコラージュは洞窟物語の作者が作った曲を作るソフトです。
ピストンコラージュの曲をループで聴きたいので、
dllを、ポーティングしてループして再生するようにしました。
implib/system pxtone.lib pxtone.dll
とやって、pxtone.libを作成。
// pxtone.d private import std.c.windows.windows; extern(C): alias bool function(int clock, bool bEnd) PXTONEPLAY_CALLBACK; // pxtone を生成します。 BOOL pxtone_Ready( HWND hWnd, // ウインドウハンドルを渡してください int channel_num, // のチャンネル数を指定してください。( 1:モノラル / 2:ステレオ ) int sps, // 秒間サンプリングレートです。 ( 11025 / 22050 / 44100 ) int bps, // 1サンプルを表現するビット数です。( 8 / 16 ) float buffer_sec, // 曲を再生するのに使用するバッファサイズを秒で指定します。( 推奨 0.1 ) bool bDirectSound, // TRUE: DirectSound を使用します / FALSE: WAVEMAPPER を使用します。 PXTONEPLAY_CALLBACK pProc // サンプリング舞に呼ばれる関数です。NULL でかまいません。 ); // pxtone の準備 BOOL pxtone_ResetSampling( HWND hWnd, int channel_num, int sps, int bps, float buffer_sec, BOOL bDirectSound, PXTONEPLAY_CALLBACK pProc ); // pxtone で生成されたDirectSoundのポインタ(LPDIRECTSOUND)を取得する。 // 取得したDirectSoundはリリースしないように注意してください。 void *pxtone_GetDirectSound(); // ラストエラー文字列取得 char *pxtone_GetLastError(); // pxtone の音質を取得します void pxtone_GetQuality( int *p_channel_num, int *p_sps, int *p_bps, int *p_sample_per_buf ); // pxtone // pxtone を開放します BOOL pxtone_Release(); // 曲を読み込みます BOOL pxtone_Tune_Load( HMODULE hModule, // リソースから読む場合はモジュールハンドルを指定します。NULL でも問題ないかも。 char *type_name, // リソースから読む場合はリソースの種類名。外部ファイルを読む場合は NULL。 char *file_name // ファイルパスもしくはリソース名。 ); // 曲を解放します BOOL pxtone_Tune_Release(); // 曲を再生します BOOL pxtone_Tune_Play( int start_sample, // 開始位置です。主に Stop や Fadeout で取得した値を設定します。0 で最初から。 int fade_msec // フェードインする場合はここに時間(ミリ秒)を指定します。 ); // フェードアウトスイッチを入れて現在再生サンプルを取得します int pxtone_Tune_Fadeout( int msec ); // 曲のボリュームを設定します。1.0 が最大で、0.5 が半分です。 void pxtone_Tune_SetVolume( double v ); // 曲を停止して現在再生サンプルを取得 int pxtone_Tune_Stop(); // 再生中かどうかを調べます BOOL pxtone_Tune_IsPlaying(); // ループ再生の ON/OFF を切り替えます void pxtone_Tune_SetLoop( BOOL bLoop ); // 曲の情報を取得します void pxtone_Tune_GetInformation( int *p_beat_num, float *p_beat_tempo, int *p_beat_clock, int *p_meas_num ); // 曲の名称を取得します char* pxtone_Tune_GetName(); // 曲のコメントを取得します char* pxtone_Tune_GetComment();
import pxtone; import std.c.windows.windows; import std.thread; import std.string; import std.c.windows.windows; import std.file; import std.path; class PxTone : Thread { HWND hwnd; this() { HINSTANCE hInst = GetModuleHandleA(null); WNDCLASS wc; wc.lpszClassName = "DWndClass"; wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = &WindowProc; wc.hInstance = hInst; wc.hIcon = LoadIconA(cast(HINSTANCE) null, IDI_APPLICATION); wc.hCursor = LoadCursorA(cast(HINSTANCE) null, IDC_CROSS); wc.hbrBackground = cast(HBRUSH) (COLOR_WINDOW + 1); wc.lpszMenuName = null; wc.cbClsExtra = wc.cbWndExtra = 0; assert(RegisterClassA(&wc)); hwnd = CreateWindowA("DWndClass", "pxtone", WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, HWND_DESKTOP, cast(HMENU) null, hInst, null); assert(hwnd); start(); } int run() { MSG msg; while (GetMessageA(&msg, cast(HWND) null, 0, 0)) { TranslateMessage(&msg); DispatchMessageA(&msg); } return 1; } static extern(Windows) int WindowProc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_PAINT: { static char text = "pxtone"; PAINTSTRUCT ps; HDC dc = BeginPaint(hWnd, &ps); TextOutA(dc, 0, 0, text, text.length); EndPaint(hWnd, &ps); break; } case WM_DESTROY: PostQuitMessage(0); break; default: break; } return DefWindowProcA(hWnd, uMsg, wParam, lParam); } } static int clock; static bool bEnd; static extern(C) bool callBack(int _clock, bool _bEnd) { clock = _clock; bEnd = _bEnd; return true; } void main() { PxTone m = new PxTone(); if (pxtone_Ready(m.hwnd, 2, 44100, 16, 0.1, true, &callBack)) { pxtone_Tune_SetLoop(false); printf("ready\n"); char list=listdir("."); while (true) { foreach (char file; list) { if (getExt(file) != "ptcop") continue; printf("%.*s\n", file); if(pxtone_Tune_Load(null, null, std.string.toStringz(file))) { printf("%s\n", pxtone_Tune_GetName()); printf("%s\n", pxtone_Tune_GetComment()); printf("load \n"); pxtone_Tune_Play(0, 0); printf("play\n"); do { Sleep(100); } while (!bEnd); printf("stop\n"); pxtone_Tune_Stop(); pxtone_Tune_Release(); } } } pxtone_Release(); } }
なかんじで。
コンパイルは、
dmd pxtoneplay.d pxtone.lib gdi32.lib
かな。