Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // =========================================================================================================================
- // 很简单的midi钢琴键盘程序, 使用DirectSDK和VC++写的, 需要 DirectX 9 SDK 9.0c June 2010
- // 写的太乱了, 以后有新想法可能会用 ATL重写一遍.
- // 原理就是根据用户按下的键, 索引出对应的调性和音阶内的音符
- // 按照 时值/力度/调性/阶内音符 的组合写入对应的midi消息 (这里力度没模拟, 或者说,模拟的很烂(?))...
- // 然后电脑就会反馈出具体的声音了.
- // 说白了就是按键->发消息..
- //
- // 可使用 至少三种midi合成端口
- // - midi映射, (128合成乐器)
- // - GS波表合成 (128合成乐器)
- // - DirectMusic强化合成器 (234种合成乐器)
- //
- // 键盘映射如下:
- // -----------------------------------------------------------------------------------------------------------------------
- // ZXCVBNM S D F G H - < LOW>
- // 1234567#1#2#4#5#6
- // QWERTYU 2 3 4 5 6 - < MID>
- // 1234567#1#2#4#5#6
- // IOP[]\E 9 0 - + B - < HIGH> E <- enter B <- backspace
- // 1234567#1#2#4#5#6
- // ----------------------------------------------------------------------------
- // 力反馈设置<试试看效果>.此设置用来模拟按键力度, 因为一般而言键盘是没办法返回按键力度的..
- // 上升沿, 也就是按键按下的时候到松开之前的这段过程.
- // 会给与一个初始力度的力值K. 此时按键如果一直处于按下状态会一直增加 K直到经过n个ticks 到达峰值MAX.
- // 下降沿, 也就是按键松开的时候, 这个时候要计算在上升沿时候实际经过的ticks跟n ticks的比值
- // 来跟预先设置的C ticks换算出降低到谷底需要的ticks, 到达0之后, 此时力程图链表项会被销毁, 一个力反馈键完成.
- // K, N, MAX, C 需要用户自行设置
- //
- // 调性键位 F1 - 中音基调性为1 (调性范围 -1 ~2) [note 0 ~ 35]
- // 调性键位 F2 - 中音基调性为2 (调性范围 0 ~3) [note 12 ~ 47]
- // 调性键位 F3 - 中音基调性为3 (调性范围 1 ~4) [note 24 ~ 59]
- // 调性键位 F4 - 中音基调性为4 (调性范围 2 ~5) [note 36 ~ 71]
- // 调性键位 F5 - 中音基调性为5 (调性范围 3 ~6) [note 48 ~ 83]
- // 调性键位 F6 - 中音基调性为6 (调性范围 4 ~7) [note 60 ~ 95]
- // 调性键位 F7 - 中音基调性为7 (调性范围 5 ~8) [note 72 ~ 95]
- // 调性键位 F8 - 中音基调性为8 (调性范围 6 ~8) [note 84 ~ 107]
- // 调性键位 F9 - 中音基调性为9 (调性范围 7 ~9) [note 96 ~ 119]
- // 调性键位 F10- 中音基调性为10(调性范围 8 ~10) [note 108 ~ 127] 为了兼容标准midi最大 note为127
- //
- // 支持七八种简单的, 如混响 3D的effect - 男的
- // =================================================================================================================
- // 嵌入风格清单.
- # if defined (_M_IX86)
- # pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
- # elif defined (_M_IA64)
- # pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
- # elif defined (_M_X64)
- # pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
- # else
- # pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
- # endif
- # include <windows.h>
- # include <windowsx.h>
- # include <d3d9.h>
- # include <d3dx9.h>
- # include <dinput.h>
- # include <assert.h>
- # include <tchar.h>
- # include <CommCtrl.h>
- # include <dmusicc.h>
- # include <dmusics.h>
- # include <dmusici.h>
- # include <dmusbuff.h>
- # include <ks.h>
- # include <vector>
- # include "resource.h"
- // 杂项例子
- namespace CUtil {
- // windows 标准GS乐器指令集
- const TCHAR* std_instruments_set[]=
- {
- _T("1 Acoustic Grand Piano"),
- _T("2 Bright Acoustic Piano"),
- _T("3 Electric Grand Piano"),
- _T("4 Honky-tonk Piano"),
- _T("5 Electric Piano 1"),
- _T("6 Electric Piano 2"),
- _T("7 Harpsichord"),
- _T("8 Clavi"),
- _T("9 Celesta"),
- _T("10 Glockenspiel"),
- _T("11 Music Box"),
- _T("12 Vibraphone"),
- _T("13 Marimba"),
- _T("14 Xylophone"),
- _T("15 Tubular Bells"),
- _T("16 Dulcimer"),
- _T("17 Drawbar Organ"),
- _T("18 Percussive Organ"),
- _T("19 Rock Organ"),
- _T("20 Church Organ"),
- _T("21 Reed Organ"),
- _T("22 Accordion"),
- _T("23 Harmonica"),
- _T("24 Tango Accordion"),
- _T("2T5 Guitar (nylon)"),
- _T("26 Acoustic Guitar (steel)"),
- _T("27 Electric Guitar (jazz)"),
- _T("28 Electric Guitar (clean)"),
- _T("29 Electric Guitar (muted)"),
- _T("30 Overdriven Guitar"),
- _T("31 Distortion Guitar"),
- _T("32 Guitar Harmonics"),
- _T("33 Acoustic Bass"),
- _T("34 Electric Bass (finger)"),
- _T("35 Electric Bass (pick)"),
- _T("36 Fretless Bass"),
- _T("37 Slap Bass 1"),
- _T("38 Slap Bass 2"),
- _T("39 Synth Bass 1"),
- _T("40 Synth Bass 2"),
- _T("41 Violin"),
- _T("42 Viola"),
- _T("43 Cello"),
- _T("44 Contrabass"),
- _T("45 Tremolo Strings"),
- _T("46 Pizzicato Strings"),
- _T("47 Orchestral Harp"),
- _T("48 Timpani"),
- _T("49 String Ensemble 1"),
- _T("50 String Ensemble 2"),
- _T("51 SynthStrings 1"),
- _T("52 SynthStrings 2"),
- _T("53 Choir Aahs"),
- _T("54 Voice Oohs"),
- _T("55 Synth Voice"),
- _T("56 Orchestra Hit"),
- _T("57 Trumpet"),
- _T("58 Trombone"),
- _T("59 Tuba"),
- _T("60 Muted Trumpet"),
- _T("61 French Horn"),
- _T("62 Brass Section"),
- _T("63 SynthBrass 1"),
- _T("64 SynthBrass 2"),
- _T("65 Soprano Sax"),
- _T("66 Alto Sax"),
- _T("67 Tenor Sax"),
- _T("68 Baritone Sax"),
- _T("69 Oboe"),
- _T("70 English Horn"),
- _T("71 Bassoon"),
- _T("72 Clarinet"),
- _T("73 Piccolo"),
- _T("74 Flute"),
- _T("75 Recorder"),
- _T("76 Pan Flute"),
- _T("77 Blown Bottle"),
- _T("78 Shakuhachi"),
- _T("79 Whistle"),
- _T("80 Ocarina"),
- _T("81 Lead 1(square)"),
- _T("82 Lead 2 (sawtooth)"),
- _T("83 Lead 3 (calliope)"),
- _T("84 Lead 4 (chiff)"),
- _T("85 Lead 5 (charang)"),
- _T("86 Lead 6 (voice)"),
- _T("87 Lead 7 (fifths)"),
- _T("88 Lead 8 (bass+lead)"),
- _T("89 Pad 1 (new age)"),
- _T("90 Pad 2 (warm)"),
- _T("91 Pad 3 (polysynth)"),
- _T("92 Pad 4 (choir)"),
- _T("93 Pad 5 (bowed)"),
- _T("94 Pad 6 (metallic)"),
- _T("95 Pad 7 (halo)"),
- _T("96 Pad 8 (sweep)"),
- _T("97 FX 1 (rain)"),
- _T("98 FX 2 (soundtrack)"),
- _T("99 FX 3 (crystal)"),
- _T("100 FX 4 (atmosphere)"),
- _T("101 FX 5 (brightness)"),
- _T("102 FX 6 (goblins)"),
- _T("103 FX 7 (echoes)"),
- _T("104 FX 8 (sci-fi)"),
- _T("105 Sitar"),
- _T("106 Banjo"),
- _T("107 Shamisen"),
- _T("108 Koto"),
- _T("109 Kalimba"),
- _T("110 Bag Pipe"),
- _T("111 Fiddle"),
- _T("112 Shanai"),
- _T("113 Tinkle Bell"),
- _T("114 Agogo"),
- _T("115 Steel Drums"),
- _T("116 Woodblock"),
- _T("117 Taiko Drum"),
- _T("118 Melodic Tom"),
- _T("119 Synth Drum"),
- _T("120 Reverse Cymbal"),
- _T("121 Guitar Fret Noise"),
- _T("122 Breath Noise"),
- _T("123 Seashore"),
- _T("124 Bird Tweet"),
- _T("125 Telephone Ring"),
- _T("126 Helicopter"),
- _T("127 Applause"),
- _T("128 Gunshot")
- };
- // 调整窗口客户区尺寸
- BOOL ReSizeClient (HWND hWindow,
- INT Width,
- INT Height,
- DWORD Style,
- DWORD StyleEx, BOOL bMenu )
- {
- RECT rcClient;
- if (!GetClientRect(hWindow, &rcClient ))
- return FALSE;
- if (Width != -1)
- rcClient.right = Width;
- if (Height != -1)
- rcClient.bottom = Height;
- if ( !AdjustWindowRectEx( &rcClient, Style, (!( Style & WS_CHILD ) && ( bMenu != NULL ) ), StyleEx ) )
- return FALSE;
- return SetWindowPos( hWindow, NULL, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE );
- }
- // 快速拷贝使用的汇编程式
- # if !defined (_WIN64)
- extern "C" {
- int CAlphaSingle32Unalign16_SSE (void * _vptr, int dword_byte,
- int dst_x, int dst_y,
- int dst_w, int dst_h,
- COLORREF col,
- BYTE alpha_dst, BYTE alpha_src);
- int CSurfaceCopy32 (void * _dvptr, int d_pos_x, int d_pos_y, int d_pitch,
- void * _svptr, int s_pos_x, int s_pos_y, int s_pitch,
- int w, int h);
- }
- # define CAlphaSingle CAlphaSingle32Unalign16_SSE
- # define CSurfaceCopy CSurfaceCopy32
- # else
- # endif
- };
- // Direct3D surface 类
- // 用来快速绘图, 离屏surface使用系统内存而非显存 (因为需要频繁读写).
- class CDirectDraw
- {
- private:
- IDirect3DDevice9 *m_Direct3D9_device;
- IDirect3DSurface9 *m_Direct3D9_surface;
- D3DPRESENT_PARAMETERS m_d3dpp;
- HWND m_AttachWindow;
- void initSettings (void) {
- m_Direct3D9_device = NULL;
- m_Direct3D9_surface = NULL;
- }
- void CreateD3dppSurface (int width, int height) {
- // 重置 d3d描述
- ResetD3dpp (m_d3dpp, m_AttachWindow, width, height);
- // 创建 d3d 设备
- HRESULT si = sm_Direct3D9_root->CreateDevice (0,
- D3DDEVTYPE_HAL,
- m_AttachWindow,
- D3DCREATE_SOFTWARE_VERTEXPROCESSING, &m_d3dpp, & m_Direct3D9_device);
- assert (SUCCEEDED (si));
- }
- public:
- // 显存/ 后备缓冲描述
- struct graph_desc {
- DWORD *__vptr;
- DWORD pitch;
- DWORD max_width;
- DWORD max_height;
- };
- // 锁显存/surface
- int lockBuffer (IDirect3DSurface9 *surface, RECT *rcLock, graph_desc &gd) {
- D3DLOCKED_RECT lock_rect;
- D3DSURFACE_DESC lock_desc;
- HRESULT rets = surface->LockRect (& lock_rect, rcLock, D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE);
- if (FAILED (rets))
- return -1;
- else ;
- rets = surface->GetDesc (& lock_desc);
- assert (SUCCEEDED (rets));
- gd.__vptr = (DWORD *) lock_rect.pBits;
- gd.pitch = lock_rect.Pitch;
- if (rcLock != NULL) {
- gd.max_width = abs (rcLock->right - rcLock->left);
- gd.max_height = abs (rcLock->bottom - rcLock->top);
- } else {
- gd.max_width = lock_desc.Width;
- gd.max_height = lock_desc.Height;
- }
- return 0;
- }
- // 重置后备缓冲
- void resetBackSurface (int width, int height) {
- if (m_Direct3D9_surface != NULL) {
- m_Direct3D9_surface->Release ();
- m_Direct3D9_surface = NULL;
- }
- HRESULT rets = m_Direct3D9_device->CreateOffscreenPlainSurface (width, height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM,
- & m_Direct3D9_surface, NULL);
- assert (SUCCEEDED (rets));
- }
- int lockBuffer (RECT *rcLock, graph_desc &gd) {
- return lockBuffer (m_Direct3D9_surface, rcLock, gd);
- }
- int unlockBuffer (void) {
- HRESULT rets =m_Direct3D9_surface->UnlockRect ();
- if (FAILED (rets))
- return -1;
- else return 0;
- }
- void ResetD3dppSurface (int width, int height) {
- ResetD3dpp (m_d3dpp, m_AttachWindow, width, height);
- HRESULT rets = m_Direct3D9_device->Reset (& m_d3dpp);
- assert (SUCCEEDED (rets));
- }
- // 全局direct3d COM根
- static IDirect3D9 *sm_Direct3D9_root;
- public:
- static void InitDirect3D (void) {
- if (sm_Direct3D9_root == NULL) {
- sm_Direct3D9_root = Direct3DCreate9 (D3D_SDK_VERSION);
- assert (sm_Direct3D9_root != NULL);
- }
- }
- static void UninitDirect3D (void) {
- if (sm_Direct3D9_root != NULL) {
- sm_Direct3D9_root->Release ();
- sm_Direct3D9_root = NULL;
- }
- }
- void ResetD3dpp (D3DPRESENT_PARAMETERS &d3dpp, HWND window, int width, int height) {
- ZeroMemory (& d3dpp, sizeof (d3dpp));
- d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
- d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
- d3dpp.Flags = 0;
- d3dpp.hDeviceWindow = window;
- d3dpp.Windowed = TRUE;
- d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // 禁用 Direct3D垂直同步, 这点很重要. 否则会强制等待VBlank导致时间片浪费掉.
- d3dpp.BackBufferHeight = height;
- d3dpp.BackBufferWidth = width;
- }
- // 离屏表面传输到显存交换链
- int BlitBtoV (POINT *ptDst, POINT *ptSrc, SIZE *szSize) {
- IDirect3DSurface9 *t;
- D3DSURFACE_DESC lock_desc;
- int rc = -1;
- HRESULT rets = m_Direct3D9_device->GetBackBuffer (0, 0, D3DBACKBUFFER_TYPE_MONO, & t);
- assert (SUCCEEDED (rets));
- POINT ptSrcT = { 0, 0};
- POINT *ptPpc = ptSrc ? ptSrc : & ptSrcT;
- // 自动适配尺寸.
- rets = m_Direct3D9_surface->GetDesc (& lock_desc);
- assert (SUCCEEDED (rets));
- SIZE *szPpc = szSize;
- SIZE szSrcT;
- if (szPpc == NULL) {
- szPpc = & szSrcT;
- szSrcT.cx = lock_desc.Width - ptPpc->x;
- szSrcT.cy = lock_desc.Height - ptPpc->y;
- if (szSrcT.cx <= 0 || (szSrcT.cy <= 0))
- goto __cleanup;
- }
- RECT ac = { ptPpc->x, ptPpc->y, ptPpc->x + szPpc->cx, ptPpc->y + szPpc->cy};
- rets = m_Direct3D9_device->UpdateSurface (m_Direct3D9_surface, & ac, t, ptDst);
- rc = (SUCCEEDED (rets)) ? 0 : -1;
- __cleanup:
- rets = t->Release ();
- assert (SUCCEEDED (rets));
- return rc;
- }
- // 提交渲染至实际显示
- int postRender (RECT *ptDst, RECT *ptSrc) {
- HRESULT rets = m_Direct3D9_device->Present (ptSrc, ptDst, NULL, NULL);
- if (SUCCEEDED (rets))
- return 0;
- else return -1;
- }
- int postRender (POINT &ptDst, POINT &ptSrc, SIZE &size_) {
- RECT rcDst = { ptDst.x, ptDst.y, ptDst.x + size_.cx, ptDst.y + size_.cy};
- RECT rcSrc = { ptSrc.x, ptSrc.y, ptSrc.x + size_.cx, ptSrc.y + size_.cy};
- return postRender (& rcDst, & rcSrc);
- }
- // CTOR, 析构
- ~CDirectDraw () {
- if ( m_Direct3D9_surface != NULL) {
- m_Direct3D9_surface->Release ();
- m_Direct3D9_surface = NULL;
- }
- if ( m_Direct3D9_device != NULL) {
- m_Direct3D9_device->Release ();
- m_Direct3D9_device = NULL;
- }
- return ;
- }
- // DTOR, 构造
- CDirectDraw (HWND attach, SIZE &VSize, SIZE &BSize) {
- initSettings ();
- // 设置空刷子, 免得系统重画, 可能还会引起闪烁.
- SetClassLongPtr (attach, GCLP_HBRBACKGROUND, (LONG_PTR) GetStockObject (NULL_BRUSH)) ;
- m_AttachWindow = attach;
- CreateD3dppSurface (VSize.cx, VSize.cy);
- resetBackSurface (BSize.cx, BSize.cy);
- }
- static int __POW2 (int nc) {
- int n;
- for (n= 1; n < nc; n<<=1) {}
- return n;
- }
- // 加载纹理资源
- int LoadImage (TCHAR *fname, int width, int height, graph_desc &gd) {
- {
- IDirect3DTexture9 *tex;
- D3DXIMAGE_INFO infos;
- if (FAILED ( D3DXCreateTextureFromFileEx (m_Direct3D9_device, fname,
- D3DX_DEFAULT_NONPOW2,
- D3DX_DEFAULT_NONPOW2,
- D3DX_FROM_FILE,
- 0,
- D3DFMT_UNKNOWN,
- D3DPOOL_MANAGED,
- D3DX_DEFAULT, // D3DX_DEFAULT
- D3DX_DEFAULT, // D3DX_DEFAULT
- 0, //D3DCOLOR_XRGB (0, 0, 0),
- & infos, NULL, & tex)) )
- return -1;
- {
- D3DLOCKED_RECT Vdesc;
- HRESULT sig;
- DWORD id2;
- // lock it
- sig = tex->LockRect (0, & Vdesc, NULL, D3DLOCK_READONLY);
- assert (SUCCEEDED (sig));
- gd.max_width = infos.Width;
- gd.max_height = infos.Height;
- gd.pitch = __POW2 (Vdesc.Pitch); // step 4 * RGB-depth
- gd.__vptr = (DWORD *) _aligned_malloc (gd.pitch *gd.max_height, 64);
- for (id2 = 0; id2 != infos.Height; id2++)
- memcpy ( & ( ((char *)gd.__vptr)[id2 * gd.pitch]),
- & ( ((char *)Vdesc.pBits)[id2 * Vdesc.Pitch]) ,
- infos.Width *4);
- // unlock., release.
- tex->UnlockRect (0);
- tex->Release ();
- return 0;
- }
- return -1;
- }
- }
- int LoadImage (int resid, int width, int height, graph_desc &gd) {
- {
- IDirect3DTexture9 *tex;
- D3DXIMAGE_INFO infos;
- if (FAILED ( D3DXCreateTextureFromResourceEx (m_Direct3D9_device, NULL,
- MAKEINTRESOURCE (resid),
- D3DX_DEFAULT_NONPOW2,
- D3DX_DEFAULT_NONPOW2,
- D3DX_FROM_FILE,
- 0,
- D3DFMT_UNKNOWN,
- D3DPOOL_MANAGED,
- D3DX_DEFAULT, // D3DX_DEFAULT
- D3DX_DEFAULT, // D3DX_DEFAULT
- 0, //D3DCOLOR_XRGB (0, 0, 0),
- & infos, NULL, & tex)) )
- return -1;
- {
- D3DLOCKED_RECT Vdesc;
- HRESULT sig;
- DWORD id2;
- // lock it
- sig = tex->LockRect (0, & Vdesc, NULL, D3DLOCK_READONLY);
- assert (SUCCEEDED (sig));
- gd.max_width = infos.Width;
- gd.max_height = infos.Height;
- gd.pitch = __POW2 (Vdesc.Pitch); // step 4 * RGB-depth
- gd.__vptr = (DWORD *) _aligned_malloc (gd.pitch *gd.max_height, 64);
- for (id2 = 0; id2 != infos.Height; id2++)
- memcpy ( & ( ((char *)gd.__vptr)[id2 * gd.pitch]),
- & ( ((char *)Vdesc.pBits)[id2 * Vdesc.Pitch]) ,
- infos.Width *4);
- // unlock., release.
- tex->UnlockRect (0);
- tex->Release ();
- return 0;
- }
- return -1;
- }
- }
- int FreeImage (graph_desc &gd) {
- if (gd.__vptr != NULL) {
- _aligned_free (gd.__vptr);
- gd.__vptr = NULL;
- }
- }
- };
- // 静态类成员初始化
- IDirect3D9 *CDirectDraw::sm_Direct3D9_root = nullptr;
- // 用来画按键信息. 这段写的相对烂的多.数据没测准.注释中关于方向大小位置的信息可能不太准.真是抱歉》。
- namespace CPianoDraw__ {
- # define HALF_MASK 0x80
- static struct dummt_ {
- TCHAR *harmonica_scale;
- int octave_step;
- int note;
- int midi_pos;
- BYTE mapDIK;
- } keyboard_mapper[36] = {
- // 低音
- { _T(" (1)"), 0, 1, 0, DIK_Z }, // 1
- { _T(" (#1)"), 0, 1 | HALF_MASK, 1, DIK_S }, //#1
- { _T(" (2)"), 0, 2, 2, DIK_X }, // 2
- { _T(" (#2)"), 0, 2 | HALF_MASK, 3, DIK_D }, //#2
- { _T(" (3)"), 0, 3, 4, DIK_C }, // 3
- { _T(" (4)"), 0, 4, 5, DIK_V }, // 4
- { _T(" (#4)"), 0, 4 | HALF_MASK, 6, DIK_F }, //#4
- { _T(" (5)"), 0, 5 , 7, DIK_B }, // 5
- { _T(" (#5)"), 0, 5 | HALF_MASK, 8, DIK_G }, //#5
- { _T(" (6)"), 0, 6 , 9, DIK_N }, // 6
- { _T(" (#6)"), 0, 6 | HALF_MASK,10, DIK_H }, //#6
- { _T(" (7)"), 0, 7 , 11, DIK_M }, // 7
- // 中音
- { _T(" 1"), 1, 1, 0+12, DIK_Q }, // 1
- { _T(" #1"), 1, 1 | HALF_MASK, 1+12, DIK_2 }, // #1
- { _T(" 2"), 1, 2, 2+12, DIK_W }, // 2
- { _T(" #2"), 1, 2 | HALF_MASK, 3+12, DIK_3 }, // #2
- { _T(" 3"), 1, 3, 4+12, DIK_E }, // 3
- { _T(" 4"), 1, 4, 5+12, DIK_R }, // 4
- { _T(" #4"), 1, 4 | HALF_MASK, 6+12, DIK_4 }, // #4
- { _T(" 5"), 1, 5 , 7+12, DIK_T }, // 5
- { _T(" #5"), 1, 5 | HALF_MASK, 8+12, DIK_5 }, // #5
- { _T(" 6"), 1, 6 , 9+12, DIK_Y }, // 6
- { _T(" #6"), 1, 6 | HALF_MASK,10+12, DIK_6 }, // #6
- { _T(" 7"), 1, 7 , 11+12, DIK_U }, // 7
- // 高音
- { _T(" [1]"), 2, 1, 0+24, DIK_I }, // 1
- { _T(" [#1]"), 2, 1 | HALF_MASK, 1+24, DIK_9 }, // #1
- { _T(" [2]"), 2, 2, 2+24, DIK_O }, // 2
- { _T(" [#2]"), 2, 2 | HALF_MASK, 3+24, DIK_0 }, // #2
- { _T(" [3]"), 2, 3, 4+24, DIK_P }, // 3
- { _T(" [4]"), 2, 4, 5+24, DIK_LBRACKET }, // 4
- { _T(" [#4]"), 2, 4 | HALF_MASK, 6+24, DIK_MINUS }, // #4
- { _T(" [5]"), 2, 5 , 7+24, DIK_RBRACKET }, // 5
- { _T(" [#5]"), 2, 5 | HALF_MASK, 8+24, DIK_EQUALS }, // #5
- { _T(" [6]"), 2, 6 , 9+24, DIK_BACKSLASH }, // 6
- { _T(" [#6]"), 2, 6 | HALF_MASK,10+24, DIK_BACK }, // #6
- { _T(" [7]"), 2, 7 , 11+24, DIK_RETURN } // 7
- };
- static const DWORD sm_ColBlack = 0xffd200; // 钢琴黑键着色
- static const DWORD sm_ColWhite = 0x00fffc; // 钢琴白键着色
- static const BYTE sm_ShadowBlackAlpha = 32; // 黑键Alpha百分比
- static const BYTE sm_ShadowWhiteAlpha = 32; // 白键Alpha百分比
- // 黑键音阶基偏移
- static const int left_remain = 3;
- static const POINT sm_note_half1 = { 11 - left_remain, 1 }; // #1
- static const POINT sm_note_half2 = { 47 - left_remain, 1 }; // #2
- static const POINT sm_note_half4 = {103 - left_remain, 1 }; // #4
- static const POINT sm_note_half5 = {138 - left_remain, 1 }; // #5
- static const POINT sm_note_half6 = {169 - left_remain, 1 }; // #6
- // 白键音阶基偏移
- static const POINT sm_note_1 = { 3 - left_remain, 1 }; // 1 二次矩形绘制 X0Y54 W20H106 | X0Y0 W7H54
- static const POINT sm_note_2 = { 33 - left_remain, 1 }; // 2 二次矩形绘制 X0Y54 W21H106 | X6Y0 W7H54
- static const POINT sm_note_3 = { 64 - left_remain, 1 }; // 3 二次矩形绘制 X0Y54 W21H106 | X11Y0 W10H54
- static const POINT sm_note_4 = { 94 - left_remain, 1 }; // 4 二次矩形绘制 X0Y54 W22H106 | X0Y0 W8H54
- static const POINT sm_note_5 = {126 - left_remain, 1 }; // 5 二次矩形绘制 X0Y54 W20H106 | X5Y0 W6H154
- static const POINT sm_note_6 = {156 - left_remain, 1 }; // 6 二次矩形绘制 X0Y54 W20H106 | X10Y0 W2H154
- static const POINT sm_note_7 = {186 - left_remain, 1 }; // 7 二次矩形绘制 X0Y54 W20H106 | X11Y0 W9H54
- // 三音阶基偏移
- static const int octave_0 = 3;
- static const int octave_1 = 215;
- static const int octave_2 = 427;
- static const int octave_set[3] = { octave_0, octave_1, octave_2} ;
- void drawPiano (CDirectDraw ::graph_desc &gd, int octave_step, int note /* 从1开始计数*/) {
- int octave_step_ = octave_step & 3;
- int note_ = note & 0x7;
- const int base_x = octave_set [octave_step_];
- if (FALSE != !! (note & HALF_MASK)) {
- // 画黑键
- const POINT *pt;
- switch (note_) {
- case 1: pt = & sm_note_half1; break ;
- case 2: pt = & sm_note_half2; break ;
- case 4: pt = & sm_note_half4; break ;
- case 5: pt = & sm_note_half5; break ;
- case 6: pt = & sm_note_half6; break ;
- default : assert (0); break ;
- }
- CUtil ::CAlphaSingle (gd.__vptr, gd.pitch, pt->x + base_x + 1,
- pt->y + 1,
- 27, 53,
- sm_ColBlack,
- sm_ShadowBlackAlpha,
- 255 - sm_ShadowBlackAlpha);
- } else {
- // 画白键
- int pos_x;
- RECT part2 = { 0, 3, 0, 57};
- POINT *base_pos = NULL;
- const POINT *base_pc = NULL;
- switch (note_) {
- case 1: base_pc = & sm_note_1; pos_x = 20; part2.right = 7; break ;
- case 2: base_pc = & sm_note_2; pos_x = 21; part2.left = 6; part2.right = 13; break ;
- case 3: base_pc = & sm_note_3; pos_x = 21; part2.left = 11; part2.right = 21; break ;
- case 4: base_pc = & sm_note_4; pos_x = 22; part2.right = 8; break ;
- case 5: base_pc = & sm_note_5; pos_x = 20; part2.left = 5; part2.right = 11; break ;
- case 6: base_pc = & sm_note_6; pos_x = 20; part2.left = 10; part2.right = 12; break ;
- case 7: base_pc = & sm_note_7; pos_x = 20; part2.left = 11; part2.right = 20; break ;
- default : assert (0);
- }
- CUtil ::CAlphaSingle (gd.__vptr, gd.pitch, base_pc->x + base_x + 1, 56, pos_x, 180,
- sm_ColWhite,
- sm_ShadowWhiteAlpha,
- 255 - sm_ShadowWhiteAlpha);
- CUtil ::CAlphaSingle (gd.__vptr, gd.pitch, base_pc->x + base_x + 1 + part2.left , 2,
- part2.right - part2.left,
- part2.bottom - part2.top,
- sm_ColWhite,
- sm_ShadowWhiteAlpha,
- 255 - sm_ShadowWhiteAlpha);
- }
- }
- };
- // DirectInput8 对象, 用来快速获取按键消息状态
- class CDirectInput8 {
- private:
- // 全局 DirectInput8 COM根.
- static IDirectInput8 *sm_DirectInput8_root;
- public:
- IDirectInputDevice8 *m_input;
- void initSettings (void) {
- m_input = NULL;
- ZeroMemory (m_keyBoardBuffer, sizeof (m_keyBoardBuffer));
- m_keyBoardBank = NULL;
- }
- void InitDeviceKeyboard (HWND hWindow) {
- HRESULT sig = sm_DirectInput8_root->CreateDevice ( GUID_SysKeyboard, & m_input, NULL);
- assert (SUCCEEDED (sig));
- BOOL bOldisVisual = !! IsWindowVisible (hWindow);
- if (bOldisVisual == FALSE) // 不可见将会设置失败, 有趣.
- ShowWindow (hWindow, SW_SHOWNORMAL);
- sig = m_input->SetCooperativeLevel (hWindow, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); // 设置非独占, 前台模式
- assert (SUCCEEDED (sig));
- sig = m_input->SetDataFormat ( (LPDIDATAFORMAT) & c_dfDIKeyboard);
- assert (SUCCEEDED (sig));
- if (bOldisVisual == FALSE) // 还原旧状态
- ShowWindow (hWindow, SW_HIDE);
- }
- static void InitDInput8 (void) {
- if (sm_DirectInput8_root == NULL) {
- HRESULT sig = DirectInput8Create (GetModuleHandle (NULL),
- DIRECTINPUT_VERSION,
- IID_IDirectInput8,
- (void **)& sm_DirectInput8_root, NULL);
- assert (SUCCEEDED (sig));
- }
- }
- static void UninitDInput8 (void) {
- if (sm_DirectInput8_root != NULL) {
- sm_DirectInput8_root->Release ();
- sm_DirectInput8_root = NULL;
- }
- }
- void PollBuffer (void) {
- int s = m_keyBoardBank;
- s *= 256;
- // 尝试获得设备
- if ( FAILED( m_input->GetDeviceState (256, & m_keyBoardBuffer[s])) ) {
- // 获取失败, 可能是设备丢失, 方便处理就是假设设备丢失了
- if (FAILED (m_input->Acquire ())) {
- // 获取失败, 清零当前buffer状态
- ZeroMemory (& m_keyBoardBuffer[s], 256);
- } else {
- if ( FAILED( m_input->GetDeviceState (256, & m_keyBoardBuffer[s])) ) {
- ZeroMemory (& m_keyBoardBuffer[s], 256);
- }
- }
- }
- m_keyBoardBank ^= 1; // 切换bank
- }
- static const int JP_MASK_PRESS = 1; // 指示按下
- static const int JP_MASK_LAST = 2; // 指示是否持续按下/松开
- typedef int JP_MASK;
- JP_MASK getMask (BYTE DIK_idx) {
- JP_MASK t = 0;
- int s = m_keyBoardBank ^ 1;
- s *= 256;
- if ( ( m_keyBoardBuffer[s+DIK_idx] & 0x80) != 0) {
- t |= JP_MASK_PRESS;
- if ( ( m_keyBoardBuffer[(s^256)+DIK_idx] & 0x80) != 0) {
- // 按下-持续
- t |= JP_MASK_LAST;
- }
- } else {
- if ( ( m_keyBoardBuffer[(s^256)+DIK_idx] & 0x80) == 0) {
- // 松开-持续
- t |= JP_MASK_LAST;
- }
- }
- return t;
- }
- BOOL isPressedFirst (BYTE DIK_idx) {
- JP_MASK t = 0;
- int s = m_keyBoardBank ^ 1;
- s <<= 8;
- if ( ( m_keyBoardBuffer[s+DIK_idx] & 0x80) != 0
- && (( m_keyBoardBuffer[(s^256)+DIK_idx] & 0x80) == 0) ) {
- return TRUE;
- }
- return FALSE;
- }
- private:
- BYTE m_keyBoardBuffer[512]; // 按键记录缓冲.
- BYTE m_keyBoardBank; // 新旧按键缓冲切换指示
- public:
- // 构造
- CDirectInput8 (void) {
- initSettings ();
- }
- // 析构
- ~CDirectInput8 (void) {
- if ( m_input != NULL) {
- m_input->Unacquire ();
- m_input->Release ();
- m_input = NULL;
- }
- };
- };
- IDirectInput8 *CDirectInput8::sm_DirectInput8_root = nullptr;
- // DirectMusc 部分
- // DMUS_PORTCAPS 的可变字符集版本
- // 主要用来枚举设备输入和输出
- typedef struct _DMUS_PORTCAPS_T {
- DWORD dwSize;
- DWORD dwFlags;
- GUID guidPort;
- DWORD dwClass;
- DWORD dwType;
- DWORD dwMemorySize;
- DWORD dwMaxChannelGroups;
- DWORD dwMaxVoices;
- DWORD dwMaxAudioChannels;
- DWORD dwEffectFlags;
- TCHAR szDescription[DMUS_MAX_DESCRIPTION];
- } DMUS_PORTCAPS_T, *LPDMUS_PORTCAPS_T;
- // 音效合集
- // 这里, 翻遍google也没找到应用效果的例子程序.
- // 可能DirectSound的音效和DirectMusic音效混用的
- // 想法真的, 可能行不通(?)...
- // 熟悉的请告诉我, 谢谢.
- struct DirectMusic_EffectSet {
- IDirectSoundFXGargle8 *efs_Gargle; // 音效-漱口
- IDirectSoundFXChorus8 *efs_Chorus; // 音效-合唱
- IDirectSoundFXFlanger8 *efs_Flanger; // 音效-排雪板
- IDirectSoundFXEcho8 *efs_Echo; // 音效-回声
- IDirectSoundFXDistortion8 *efs_Distortion; // 音效-扭曲
- IDirectSoundFXCompressor8 *efs_Compressor; // 音效-压气
- IDirectSoundFXParamEq8 *efs_ParamEq; // 音效- 均衡器
- IDirectSoundFXWavesReverb8 *efs_Reverb; // 音效- 混响
- IDirectSoundFXI3DL2Reverb8 *efs_Reverb2; // 音效- 混响_level2
- // 音效描述结构.
- DSFXGargle dsfx_Gargle;
- DSFXChorus dsfxChorus;
- DSFXFlanger dsfx_Flanger;
- DSFXEcho dsfx_Echo;
- DSFXDistortion dsfx_Distortion;
- DSFXCompressor dsfx_Compressor;
- DSFXParamEq dsfx_ParamEq;
- DSFXWavesReverb dsfx_Reverb;
- DSFXI3DL2Reverb dsfx_Reverb2;
- };
- // 力反馈结构
- class CStrengthFeedback {
- private:
- BOOL m_EnableUse;
- BYTE m_InitValue;
- BYTE m_MaxValue;
- INT m_ticksToMax;
- INT m_ticksToMin;
- public :
- CStrengthFeedback () {
- m_EnableUse = FALSE;
- m_InitValue = 0x12;
- m_MaxValue = 0x7F;
- m_ticksToMax = 2000;
- m_ticksToMin = 0;
- }
- BOOL UseDescentEdge (void) {
- return (m_ticksToMin >= 0);
- }
- BOOL UseStrengthFeedback (void) {
- return !! m_EnableUse;
- }
- BOOL SetStrengthFeedback (BOOL Enable) {
- m_EnableUse = Enable;
- }
- void SetMaxValue (INT value) {
- m_MaxValue = value;
- }
- void SetInitValue (INT value) {
- m_InitValue = value;
- }
- INT GetMaxValue (void) {
- return m_MaxValue;
- }
- INT GetInitValue (void) {
- return m_InitValue;
- }
- void Set_ticksToMax (INT value) {
- m_ticksToMax = value;
- }
- void Set_ticksToMin (INT value) {
- m_ticksToMin = value;
- }
- INT Set_ticksToMax (void) {
- return m_ticksToMax;
- }
- INT Set_ticksToMin (void) {
- return m_ticksToMin;
- }
- };
- // DirectMusic类
- // 这个类中大部分代码参考自网络程式和SDK文档.对此表示感谢.
- class CDirectMusic_ {
- public :
- // 类成员变量
- BYTE m_bFixedVelocity; // 固定力度指示.
- IDirectMusicLoader8 *m_DLSloader; // DLS加载器.
- IDirectMusicDownloadedInstrument8* m_pDLSInstrument; // DLS 乐器指令集
- IDirectMusicInstrument8* m_pInstrument; // 乐器指令集
- IDirectMusicPort8* m_pOutputPort; // 基本端口 (输出·)。
- IDirectMusicCollection8 * m_DLSCollection;
- IDirectMusicBuffer8* m_DUS_soundbuffer;
- IDirectMusicPortDownload8 * m_PortDownload; //
- IReferenceClock* m_pClock; // 参考时钟计数.
- // IDirectMusicPort8* m_pInputPort; // 基本端口 (不使用_) 。
- //
- DMUS_PORTPARAMS8 m_OutputParams;
- // DMUS_PORTPARAMS8 m_InputParams;
- GUID m_GuidSelOutputPort; // 当前选择的输出端口号的GUID.
- BOOL m_bSynthesizer; // DirectMusic强化合成器致能
- BOOL m_bUseStrengthFeedback; // 使用力反馈键位
- int m_SelInstructment; // 当前选择的乐器指令号/补丁号码.
- int m_DefaultStartOctaveLevel; // 默认基调性..
- HWND m_AttahStatus; // 设置链接的状态栏
- std::vector <DMUS_PORTCAPS_T> m_OutputPortCache; // 输出端口缓存
- void SetMiddleOctave (int level) {
- m_DefaultStartOctaveLevel = level;
- }
- int GetMiddleOctave (void) {
- return m_DefaultStartOctaveLevel;
- }
- void SetFixedVelocity (BYTE vel) {
- m_bFixedVelocity = vel;
- }
- int GetFixedVelocity (void) {
- return m_bFixedVelocity;
- }
- void SetInstructment (int id) {
- m_SelInstructment = id;
- }
- int GetInstructment (void) {
- return m_SelInstructment;
- }
- void SetOutportGUID (GUID &guid) {
- CopyMemory (& m_GuidSelOutputPort, & guid, sizeof (guid));
- }
- GUID & GetOutportGUID (void) {
- return m_GuidSelOutputPort;
- }
- public:
- void ReleaseCollection (void) {
- if (m_DLSloader && m_DLSCollection) {
- m_DLSloader->ReleaseObjectByUnknown (m_DLSCollection);
- m_DLSCollection->Release ();
- m_DLSCollection = NULL;
- }
- }
- void ReleaseInstructment (void) {
- if (m_pDLSInstrument && m_pOutputPort) {
- m_pOutputPort->UnloadInstrument (m_pDLSInstrument);
- m_pDLSInstrument->Release ();
- m_pDLSInstrument = NULL;
- }
- if (m_pInstrument) {
- m_pInstrument->Release ();
- m_pInstrument = NULL;
- }
- }
- void ReleaseClock (void) {
- if (m_pClock) {
- m_pClock->Release ();
- m_pClock = NULL;
- }
- }
- void LoadDefaultDLS (void) {
- HRESULT sig = -1;
- DMUS_OBJECTDESC dmusdesc;
- // Sets to 0 the DMUS structure
- ZeroMemory(&dmusdesc,sizeof(DMUS_OBJECTDESC));
- dmusdesc.dwSize = sizeof(DMUS_OBJECTDESC);
- dmusdesc.guidClass = CLSID_DirectMusicCollection;
- dmusdesc.guidObject = GUID_DefaultGMCollection;
- dmusdesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_OBJECT;
- ReleaseCollection ();
- sig = m_DLSloader->GetObject(&dmusdesc,IID_IDirectMusicCollection,(void**)& m_DLSCollection);
- assert (SUCCEEDED (sig));
- }
- void LoadDefaultDLS (IDirectMusicCollection **p) {
- HRESULT sig = -1;
- DMUS_OBJECTDESC dmusdesc;
- // Sets to 0 the DMUS structure
- ZeroMemory(&dmusdesc,sizeof(DMUS_OBJECTDESC));
- dmusdesc.dwSize = sizeof(DMUS_OBJECTDESC);
- dmusdesc.guidClass = CLSID_DirectMusicCollection;
- dmusdesc.guidObject = GUID_DefaultGMCollection;
- dmusdesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_OBJECT;
- assert (m_DLSloader != NULL);
- sig = m_DLSloader->GetObject(&dmusdesc,IID_IDirectMusicCollection,(void**)p);
- assert (SUCCEEDED (sig));
- }
- void ReleaseDLS (IDirectMusicCollection *p) {
- if (m_DLSloader && p) {
- m_DLSloader->ReleaseObjectByUnknown (p);
- p->Release ();
- }
- }
- void ReleaseOutputPort (void) {
- if (m_pOutputPort) {
- m_pOutputPort->Release ();
- m_pOutputPort = NULL;
- }
- }
- void initSettings (void) {
- m_DLSloader = NULL; // DLS加载器.
- m_pDLSInstrument = NULL; // DLS 乐器指令集
- m_pInstrument = NULL; // 乐器指令集
- m_pOutputPort = NULL; // 基本端口 (输出·)。
- m_DLSCollection = NULL;
- m_DUS_soundbuffer = NULL;
- m_PortDownload = NULL; //
- m_pClock = NULL; // 参考时钟计数.
- m_AttahStatus = NULL;
- m_DefaultStartOctaveLevel = 8;
- m_bFixedVelocity = 127;
- }
- //刷新输出端口缓存》
- void FlushOutPortCache (void) {
- m_OutputPortCache.clear (); // 清空之前的.
- DMUS_PORTCAPS_T t;
- int port_nums = CDirectMusic_ :: GetOutputPortNums ();
- for (int id = 0; id != port_nums; id++) {
- GetOutputPortInfos (id, & t);
- m_OutputPortCache.push_back (t);
- }
- }
- std::vector <DMUS_PORTCAPS_T>& GetOutPortCache (void) {
- return m_OutputPortCache;
- }
- HRESULT SendMidiMsg (DWORD dwMsg)
- {
- HRESULT sig = -1;
- REFERENCE_TIME rt;
- sig = m_pClock->GetTime(&rt);
- assert (SUCCEEDED (sig));
- sig = m_DUS_soundbuffer->PackStructured(rt, m_OutputParams.dwChannelGroups, dwMsg);
- assert (SUCCEEDED (sig));
- sig = m_pOutputPort->PlayBuffer (m_DUS_soundbuffer);
- assert (SUCCEEDED (sig));
- sig = m_DUS_soundbuffer->Flush ();
- assert (SUCCEEDED (sig));
- return sig;
- }
- // 设置GUID表示和引用索引.
- void SetGuidAndIndex (GUID &guid) {
- CopyMemory (& m_GuidSelOutputPort, & guid, sizeof (GUID));
- }
- BOOL isEqualOutputPort (GUID &guid) {
- return IsEqualGUID (m_GuidSelOutputPort, guid);
- }
- void ResetOutport (int outid, int instructid, DWORD effectFlags) {
- // 重置
- ZeroMemory(&m_OutputParams,sizeof(DMUS_PORTPARAMS8));
- m_OutputParams.dwSize = sizeof(DMUS_PORTPARAMS8);
- // 创建输入输出端口, 默认选择口琴乐器指令集
- m_SelInstructment = instructid;
- m_bSynthesizer = FALSE;
- // 释放之前获得所有接口.
- ReleaseInstructment ();
- ReleaseCollection ();
- ReleaseClock ();
- ReleaseOutputPort ();
- int nsel;
- int nsize = m_OutputPortCache.size ();
- assert (nsize> 0);
- nsel = outid;
- DMUS_PORTCAPS_T &pt = m_OutputPortCache[nsel];
- pt.dwMaxChannelGroups = 1;
- SetOutputPortInfos ( 0, 0, 0, effectFlags,0);
- // 创建输出端口.
- HRESULT sig = directMusic_base->CreatePort (pt.guidPort, & m_OutputParams, & m_pOutputPort, NULL);
- // 使其活跃.
- sig = m_pOutputPort->Activate (TRUE);
- assert (SUCCEEDED (sig));
- // 获取参考时钟》
- sig = m_pOutputPort->GetLatencyClock (& m_pClock);
- assert (SUCCEEDED (sig));
- // 创建音频缓冲
- DMUS_BUFFERDESC BufferDesc; // Create the DirectMusic buffer to store MIDI messages
- ZeroMemory(&BufferDesc,sizeof(DMUS_BUFFERDESC));
- BufferDesc.dwSize = sizeof(DMUS_BUFFERDESC);
- BufferDesc.guidBufferFormat = GUID_NULL;
- BufferDesc.cbBuffer = DMUS_EVENT_SIZE(32); // at least 32 bytes to store messages
- sig = CDirectMusic_::directMusic_base->CreateMusicBuffer(&BufferDesc,& m_DUS_soundbuffer,NULL);
- assert (SUCCEEDED (sig));
- // 这啥叼接口...删了好像不报错..
- m_PortDownload->Release ();
- DWORD bInstruction = instructid;
- DMUS_PORTCAPS t;
- m_pOutputPort->GetCaps (& t);
- assert (SUCCEEDED (sig));
- // 通用波表和mapper一般23号是口琴
- SetGuidAndIndex (pt.guidPort);
- if ((pt.dwFlags & DMUS_PC_DLS) || (pt.dwFlags & DMUS_PC_DLS2))
- {
- sig = m_pOutputPort->QueryInterface (IID_IDirectMusicPortDownload8,(void**)& m_PortDownload);
- assert (SUCCEEDED (sig));
- m_bSynthesizer = TRUE;
- // 加载默认的DLS 波表.
- LoadDefaultDLS ();
- WCHAR szBuf[MAX_PATH]; // 47是口琴
- sig = m_DLSCollection->EnumInstrument (instructid, (DWORD *)& m_SelInstructment, szBuf, sizeof (szBuf)/ sizeof (szBuf[0]));
- assert (SUCCEEDED (sig));
- SetGuidAndIndex (pt.guidPort);
- ReleaseInstructment ();
- sig = m_DLSCollection->GetInstrument (m_SelInstructment, & m_pInstrument);
- assert (SUCCEEDED (sig));
- sig = m_pInstrument->SetPatch (1);
- assert (SUCCEEDED (sig));
- DMUS_NOTERANGE t;
- t.dwLowNote = 0;
- t.dwHighNote = 127; // 标准midi调性范围.
- sig = m_pOutputPort->DownloadInstrument (m_pInstrument,
- &m_pDLSInstrument, & t, 1);// 调性组为1 ...
- assert (SUCCEEDED (sig));
- bInstruction = 1;
- m_SelInstructment = instructid;
- }
- // 发送消息. 应用改变.
- SendMidiMsg ( EncodeMidiMessage (0xC0, 0, bInstruction, 0));
- }
- CDirectMusic_ (void) {
- initSettings ();
- // 初始化 DLS加载器.
- HRESULT sig = CoCreateInstance(CLSID_DirectMusicLoader,NULL,
- CLSCTX_INPROC_SERVER,IID_IDirectMusicLoader8,(LPVOID*)& m_DLSloader);
- assert (SUCCEEDED (sig));
- // 重置
- ZeroMemory(&m_OutputParams,sizeof(DMUS_PORTPARAMS8));
- m_OutputParams.dwSize = sizeof(DMUS_PORTPARAMS8);
- // 创建输入输出端口, 默认选择口琴乐器指令集
- m_SelInstructment = 23;
- m_bSynthesizer = FALSE;
- // 刷新端口缓存
- FlushOutPortCache ();
- int nsel;
- int nsize = m_OutputPortCache.size ();
- assert (nsize> 0);
- nsel = nsize >= 2 ? 2 : 0;
- DMUS_PORTCAPS_T &pt = m_OutputPortCache[nsel];
- pt.dwMaxChannelGroups = 1;
- SetOutputPortInfos ( 0, 0, 0, ( (pt.dwEffectFlags & DMUS_EFFECT_REVERB) ? DMUS_EFFECT_REVERB : 0),0);
- // 创建输出端口.
- sig = directMusic_base->CreatePort (pt.guidPort, & m_OutputParams, & m_pOutputPort, NULL);
- // 使其活跃.
- sig = m_pOutputPort->Activate (TRUE);
- assert (SUCCEEDED (sig));
- // 获取参考时钟》
- sig = m_pOutputPort->GetLatencyClock (& m_pClock);
- assert (SUCCEEDED (sig));
- // 创建音频缓冲
- DMUS_BUFFERDESC BufferDesc; // Create the DirectMusic buffer to store MIDI messages
- ZeroMemory(&BufferDesc,sizeof(DMUS_BUFFERDESC));
- BufferDesc.dwSize = sizeof(DMUS_BUFFERDESC);
- BufferDesc.guidBufferFormat = GUID_NULL;
- BufferDesc.cbBuffer = DMUS_EVENT_SIZE(32); // at least 32 bytes to store messages
- sig = CDirectMusic_::directMusic_base->CreateMusicBuffer(&BufferDesc,& m_DUS_soundbuffer,NULL);
- assert (SUCCEEDED (sig));
- sig = m_pOutputPort->QueryInterface (IID_IDirectMusicPortDownload8,(void**)& m_PortDownload);
- assert (SUCCEEDED (sig));
- DWORD bInstruction = 0;
- DMUS_PORTCAPS t;
- m_pOutputPort->GetCaps (& t);
- assert (SUCCEEDED (sig));
- // 通用波表和mapper一般23号是口琴
- SetGuidAndIndex (pt.guidPort);
- if ((pt.dwFlags & DMUS_PC_DLS) || (pt.dwFlags & DMUS_PC_DLS2))
- {
- m_bSynthesizer = TRUE;
- // 加载默认的DLS 波表.
- LoadDefaultDLS ();
- WCHAR szBuf[MAX_PATH]; // 47是口琴
- sig = m_DLSCollection->EnumInstrument (47, (DWORD *)& m_SelInstructment, szBuf, sizeof (szBuf)/ sizeof (szBuf[0]));
- assert (SUCCEEDED (sig));
- SetGuidAndIndex (pt.guidPort);
- ReleaseInstructment ();
- sig = m_DLSCollection->GetInstrument (m_SelInstructment, & m_pInstrument);
- assert (SUCCEEDED (sig));
- sig = m_pInstrument->SetPatch (1);
- assert (SUCCEEDED (sig));
- DMUS_NOTERANGE t;
- t.dwLowNote = 0;
- t.dwHighNote = 127; // 标准midi调性范围.
- sig = m_pOutputPort->DownloadInstrument (m_pInstrument,
- &m_pDLSInstrument, & t, 1);// 调性组为1 ...
- assert (SUCCEEDED (sig));
- bInstruction = 1;
- m_SelInstructment = 47;
- }
- // 发送消息. 应用改变.
- SendMidiMsg ( EncodeMidiMessage (0xC0, 0, bInstruction, 0));
- // 不枚举输入,
- // 破软件根本不会有人真的拿着外接设备连起来弹琴的...
- // 而且处理输入更加复杂, 本身DirectMusic就是一个复杂的东西..
- // 降低下难度...
- // -----------------------------------------------------------------------
- }
- // 设置输出端口信息
- void SetOutputPortInfos (
- DWORD dwVoices,
- DWORD dwAudioChannels,
- DWORD dwChannelGroups,
- DWORD dwEffectFlags,
- DWORD dwSampleRate ) {
- m_OutputParams.dwValidParams = 0;
- if (dwVoices) m_OutputParams.dwValidParams = DMUS_PORTPARAMS_VOICES;
- if (dwAudioChannels) m_OutputParams.dwValidParams |= DMUS_PORTPARAMS_AUDIOCHANNELS;
- if (dwChannelGroups) m_OutputParams.dwValidParams |= DMUS_PORTPARAMS_CHANNELGROUPS;
- if (dwEffectFlags) m_OutputParams.dwValidParams |= DMUS_PORTPARAMS_EFFECTS;
- if (dwSampleRate) m_OutputParams.dwValidParams |= DMUS_PORTPARAMS_SAMPLERATE;
- m_OutputParams.dwVoices = dwVoices;
- m_OutputParams.dwAudioChannels = dwAudioChannels;
- m_OutputParams.dwChannelGroups = dwChannelGroups;
- m_OutputParams.dwEffectFlags = dwEffectFlags;
- m_OutputParams.dwSampleRate = dwSampleRate;
- }
- // 获取指定输出端口的信息
- HRESULT GetOutputPortInfos (DWORD dwNumPort, DMUS_PORTCAPS_T *lpInfoPort) {
- HRESULT hr = -1;
- DMUS_PORTCAPS portinf;
- DWORD dwIndex = 0, dwNum = -1;
- ZeroMemory(&portinf,sizeof(portinf));
- portinf.dwSize = sizeof(DMUS_PORTCAPS);
- while ((hr = directMusic_base->EnumPort(dwIndex++,&portinf))==S_OK)
- {
- if (portinf.dwClass == DMUS_PC_OUTPUTCLASS) dwNum++;
- if (dwNum == dwNumPort) break;
- }
- if (SUCCEEDED(hr) && (hr!=S_FALSE))
- {
- ZeroMemory(lpInfoPort,sizeof(DMUS_PORTCAPS_T));
- CopyMemory(&(lpInfoPort->guidPort),&portinf.guidPort,sizeof(GUID));
- #ifdef _UNICODE
- _tcscpy(lpInfoPort->szDescription,portinf.wszDescription);
- #else
- wcstombs(lpInfoPort->szDescription,portinf.wszDescription,DMUS_MAX_DESCRIPTION);
- #endif
- lpInfoPort->dwClass = portinf.dwClass;
- lpInfoPort->dwEffectFlags = portinf.dwEffectFlags;
- lpInfoPort->dwFlags = portinf.dwFlags;
- lpInfoPort->dwMemorySize = portinf.dwMemorySize;
- lpInfoPort->dwMaxAudioChannels = portinf.dwMaxAudioChannels;
- lpInfoPort->dwMaxChannelGroups = portinf.dwMaxChannelGroups;
- lpInfoPort->dwMaxVoices = portinf.dwMaxVoices;
- lpInfoPort->dwType = portinf.dwType;
- }
- return hr;
- }
- // 标准midi编码消息.
- // 参考: https://www.midi.org/specifications/item/table-1-summary-of-midi-message
- //
- // typedef struct DMUS_MIDI_PMSGG {
- // DMUS_PMSG_PART
- // BYTE bStatus;
- // BYTE bByte1;
- // BYTE bByte2;
- // BYTE bPad[1];
- // } DMUS_MIDI_PMSG;
- static DWORD EncodeMidiMessage (BYTE cmd, BYTE chan, BYTE data, BYTE data2)
- {
- DWORD msg;
- msg = cmd | chan;
- msg |= ( data << 8);
- msg |= (data2 << 16);
- return msg;
- }
- static DWORD EncodeMidiMessage (BYTE status, BYTE data, BYTE data2)
- {
- DWORD msg = status;
- msg |= ( data << 8);
- msg |= (data2 << 16);
- return msg;
- }
- static IDirectMusic8* directMusic_base; // DirectMusic 演奏对象COM根
- static IDirectSound8* directSound_attach; // 附加的DirectSound对象
- // 获取midi输入 or 端口数量
- static int GetPortNums (DWORD portType) {
- DMUS_PORTCAPS portinf;
- DWORD dwIndex = 0, dwNum = 0;
- HRESULT hr = -1;
- ZeroMemory(&portinf,sizeof(portinf));
- portinf.dwSize = sizeof(DMUS_PORTCAPS);
- while ((hr = directMusic_base->EnumPort (dwIndex++, &portinf))==S_OK)
- { if (portinf.dwClass == portType) dwNum++; }
- assert (hr == S_FALSE || (hr == S_OK));
- return dwNum;
- }
- static int GetInputPortNums (void) {
- return GetPortNums (DMUS_PC_INPUTCLASS);
- }
- static int GetOutputPortNums (void) {
- return GetPortNums (DMUS_PC_OUTPUTCLASS);
- }
- static void InitDirectMusic (HWND hWindow) {
- HRESULT sig = CoCreateInstance (CLSID_DirectMusic,NULL,
- CLSCTX_INPROC,IID_IDirectMusic8,(void**)& directMusic_base);
- assert (SUCCEEDED (sig));
- sig = directMusic_base->SetDirectSound (NULL, hWindow);
- assert (SUCCEEDED (sig));
- int nums = GetOutputPortNums ();
- }
- };
- IDirectMusic8* CDirectMusic_::directMusic_base = NULL; // DirectMusic 演奏对象COM根
- IDirectSound8* CDirectMusic_::directSound_attach = NULL; // 附加的DirectSound对象
- // 全局变量集合
- namespace GlobalObject {
- static enum RES_ID {
- ID_STATUS_BAR = 1007
- };
- static LONGLONG FreshPer = 60; // 每秒屏幕刷新的次数
- static HWND hWindowMain; // 主窗口句柄
- static TCHAR szClassName[] = _T ("midi piano class"); // 主类名
- static TCHAR szCaption[] = _T ("midi piano"); // 标题
- static UINT uiWindowStyle = WS_OVERLAPPEDWINDOW & ~ WS_SIZEBOX & ~WS_MAXIMIZE & ~WS_MAXIMIZEBOX;
- static UINT uiWindowStyleEx = 0;
- static LONGLONG liTiming ; // NT高精度计时器基测计数
- static SIZE sClientSize = { 637, 240 }; // 客户区尺寸
- static LONGLONG liStartTiming = 0;
- static HINSTANCE instance = NULL;
- static HWND hStatus = NULL; // 状态栏句柄
- static GUID guidOutputPort; // 当前获得输出端口GUID标识.
- static CDirectDraw ::graph_desc gd_piano;
- static CDirectDraw *DirectDrawObj;
- static CDirectMusic_ *DirectMusicObj;
- static CDirectInput8 *DirectInput8Obj;
- static TCHAR *piano = _T ("piano.png");
- static int DlgPortId = 0;
- static int DlgInstructId = 0;
- static void ResetVel (HWND hDlg) {
- SetDlgItemInt (hDlg, IDET_VELOCITY, DirectMusicObj->GetFixedVelocity (), FALSE);
- }
- static void ResetOutputPort (HWND hDlg, int outid, int instructment = -1) {
- int id = 0, ic = outid;
- std::vector <DMUS_PORTCAPS_T>&t = DirectMusicObj->GetOutPortCache ();
- std::vector <DMUS_PORTCAPS_T>::iterator p= t.begin ();
- DMUS_PORTCAPS_T *c;
- ComboBox_ResetContent (GetDlgItem (hDlg, IDCB_OUTPORT));
- ComboBox_ResetContent (GetDlgItem (hDlg, IDCB_INSTRUCTMENTS));
- SendMessage (GetDlgItem (hDlg, IDCK_WINMM), BM_SETCHECK, BST_UNCHECKED, 0);
- SendMessage (GetDlgItem (hDlg, IDCK_SYNTH), BM_SETCHECK, BST_UNCHECKED, 0);
- SendMessage (GetDlgItem (hDlg, IDCK_SYNTH), BM_SETCHECK, BST_UNCHECKED, 0);
- SendMessage (GetDlgItem (hDlg, IDCK_REVERB), BM_SETCHECK, BST_UNCHECKED, 0);
- SendMessage (GetDlgItem (hDlg, IDCK_CHORUS), BM_SETCHECK, BST_UNCHECKED, 0);
- SendMessage (GetDlgItem (hDlg, IDCK_DELAY), BM_SETCHECK, BST_UNCHECKED, 0);
- SendMessage (GetDlgItem (hDlg, IDCK_DLS), BM_SETCHECK, BST_UNCHECKED, 0);
- SendMessage (GetDlgItem (hDlg, IDCK_DLS2), BM_SETCHECK, BST_UNCHECKED, 0);
- for (; p != t.end (); id ++, p++) {
- ComboBox_InsertString (GetDlgItem (hDlg, IDCB_OUTPORT), -1, (*p).szDescription);
- if (id == outid)
- c = & (*p);
- }
- ComboBox_SetCurSel ( GetDlgItem (hDlg, IDCB_OUTPORT), ic);
- if ((c->dwFlags & DMUS_PC_DLS) || (c->dwFlags & DMUS_PC_DLS2)) {
- if ((c->dwFlags & DMUS_PC_DLS))
- SendMessage (GetDlgItem (hDlg, IDCK_DLS), BM_SETCHECK, BST_CHECKED, 0);
- if ((c->dwFlags & DMUS_PC_DLS2))
- SendMessage (GetDlgItem (hDlg, IDCK_DLS2), BM_SETCHECK, BST_CHECKED, 0);
- }
- EnableWindow (GetDlgItem (hDlg, IDCK_DLS), FALSE);
- EnableWindow (GetDlgItem (hDlg, IDCK_DLS2), FALSE);
- // 设置合成器类型
- switch (c->dwType) {
- case DMUS_PORT_WINMM_DRIVER: // windows多媒体库渲染驱动.
- EnableWindow (GetDlgItem (hDlg, IDCK_WINMM), TRUE);
- SendMessage (GetDlgItem (hDlg, IDCK_WINMM), BM_SETCHECK, BST_CHECKED, 0);
- break ;
- case DMUS_PORT_USER_MODE_SYNTH: // 用户模式软件合成器
- EnableWindow (GetDlgItem (hDlg, IDCK_SYNTH), TRUE);
- SendMessage (GetDlgItem (hDlg, IDCK_SYNTH), BM_SETCHECK, BST_CHECKED, 0);
- break ;
- case DMUS_PORT_KERNEL_MODE: // 基于NT内核模式的WDM驱动模型
- EnableWindow (GetDlgItem (hDlg, IDCK_SYNTH), TRUE);
- SendMessage (GetDlgItem (hDlg, IDCK_SYNTH), BM_SETCHECK, BST_CHECKED, 0);
- break ;
- }
- EnableWindow (GetDlgItem (hDlg, IDCK_SYNTH), FALSE);
- EnableWindow (GetDlgItem (hDlg, IDCK_WDM), FALSE);
- EnableWindow (GetDlgItem (hDlg, IDCK_WINMM), FALSE);
- EnableWindow (GetDlgItem (hDlg, IDCK_REVERB), FALSE);
- EnableWindow (GetDlgItem (hDlg, IDCK_DELAY), FALSE);
- EnableWindow (GetDlgItem (hDlg, IDCK_CHORUS), FALSE);
- if (c->dwEffectFlags & DMUS_EFFECT_REVERB) { // 默认DirectMusic效果 标准混响.
- EnableWindow (GetDlgItem (hDlg, IDCK_REVERB), TRUE);
- SendMessage (GetDlgItem (hDlg, IDCK_REVERB), BM_SETCHECK, BST_CHECKED, 0);
- }
- if (c->dwEffectFlags & DMUS_EFFECT_CHORUS) { // 默认DirectMusic效果 标准合唱.
- EnableWindow (GetDlgItem (hDlg, IDCK_CHORUS), TRUE);
- SendMessage (GetDlgItem (hDlg, IDCK_CHORUS), BM_SETCHECK, BST_CHECKED, 0);
- }
- if (c->dwEffectFlags & DMUS_EFFECT_DELAY) { // 默认DirectMusic效果 标准延迟.
- EnableWindow (GetDlgItem (hDlg, IDCK_DELAY), TRUE);
- SendMessage (GetDlgItem (hDlg, IDCK_DELAY), BM_SETCHECK, BST_CHECKED, 0);
- }
- if ((c->dwFlags & DMUS_PC_DLS) || (c->dwFlags & DMUS_PC_DLS2)) {
- IDirectMusicCollection8 *dc;
- DirectMusicObj->LoadDefaultDLS (& dc);
- for (int id = 0; TRUE; id++) {
- WCHAR wszInstName[MAX_PATH];
- TCHAR szInstName[MAX_PATH];
- DWORD patch;
- int cs = _stprintf (szInstName, _T("%d "), id+1);
- HRESULT sig =
- dc->EnumInstrument (id, & patch, wszInstName, sizeof (wszInstName)/ sizeof (wszInstName[0]));
- assert ( SUCCEEDED (sig));
- if (sig == S_FALSE) break ;
- # ifdef _UNICODE
- _tcscpy (& szInstName[cs],wszInstName);
- # else
- wcstombs (& szInstName[cs],wszInstName,MAX_PATH);
- # endif
- ComboBox_InsertString (GetDlgItem (hDlg, IDCB_INSTRUCTMENTS), -1, szInstName);
- }
- DirectMusicObj->ReleaseDLS (dc);
- } else {
- for (int id = 0; id != sizeof (CUtil ::std_instruments_set)/ sizeof (CUtil ::std_instruments_set[0]); id++) {
- ComboBox_InsertString ( GetDlgItem (hDlg, IDCB_INSTRUCTMENTS), -1, CUtil ::std_instruments_set[id]);
- }
- }
- ComboBox_SetCurSel ( GetDlgItem (hDlg, IDCB_INSTRUCTMENTS), (instructment < 0) ?0:instructment);
- }
- static void ResetOutputPort (HWND hDlg, int instructment = -1) {
- std::vector <DMUS_PORTCAPS_T>&t = DirectMusicObj->GetOutPortCache ();
- std::vector <DMUS_PORTCAPS_T>::iterator p= t.begin ();
- DMUS_PORTCAPS_T *c;
- for (int id =0; p != t.end (); id ++, p++) {
- if (DirectMusicObj->isEqualOutputPort ((*p).guidPort)) {
- ResetOutputPort (hDlg, id, instructment);
- return ;
- }
- }
- }
- static int GetOutportPortByGUID (GUID &guid) {
- std::vector <DMUS_PORTCAPS_T>&t = DirectMusicObj->GetOutPortCache ();
- std::vector <DMUS_PORTCAPS_T>::iterator p= t.begin ();
- DMUS_PORTCAPS_T *c;
- for (int id =0; p != t.end (); id ++, p++) {
- if (IsEqualGUID (guid, (*p).guidPort)) {
- return id;
- }
- }
- return -1;
- }
- static INT_PTR WINAPI DlgCallback_IoInstructments_ (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
- UNREFERENCED_PARAMETER(lParam);
- switch (msg)
- {
- case WM_INITDIALOG:
- // 枚举Midi输出输出端口/乐器指令集合.
- ( (void (*) (HWND, int))ResetOutputPort) (hDlg, DirectMusicObj->GetInstructment ());
- DlgInstructId = GetOutportPortByGUID (DirectMusicObj->GetOutportGUID ());
- DlgPortId = DirectMusicObj->GetInstructment ();
- EnableWindow (GetDlgItem (hDlg, IDBT_FLUSH_CACHE), FALSE);
- SetDlgItemInt (hDlg, IDET_VELOCITY, DirectMusicObj->GetFixedVelocity (), FALSE);
- return (INT_PTR)TRUE;
- case WM_COMMAND:
- WORD wCtlId = LOWORD (wParam);
- WORD wCmdMessage = HIWORD (wParam);
- switch (wCtlId) {
- case IDOK:
- case IDCANCEL:
- if (wCtlId == IDOK) {
- TCHAR szBuf[1024];
- szBuf[0] =0;
- GetWindowText (GetDlgItem (hDlg, IDBT_FLUSH_CACHE), szBuf, sizeof (szBuf)/ sizeof (szBuf[0]));
- if (szBuf[0] == 0) {
- MessageBox (NULL, _T ("Please set vel"), _T ("IOSettings"), MB_ICONERROR);
- return INT_PTR(FALSE);
- }
- BOOL t;
- DirectMusicObj->SetFixedVelocity ( GetDlgItemInt (hDlg, IDET_VELOCITY, & t, FALSE) & 0x7F);
- // 重新设置端口.
- int pt = ComboBox_GetCurSel (GetDlgItem (hDlg, IDCB_OUTPORT));
- int instructment = ComboBox_GetCurSel (GetDlgItem (hDlg, IDCB_INSTRUCTMENTS));
- DirectMusicObj->ResetOutport (pt, instructment, 0);
- }
- EndDialog (hDlg, LOWORD(wParam));
- return (INT_PTR)TRUE;
- case IDCB_OUTPORT:
- case IDCB_INPUT_PORT:
- switch (wCmdMessage) {
- case CBN_SELCHANGE:
- // 获取当前端口索引.
- {
- int id = ComboBox_GetCurSel ((HWND) lParam);
- if (wCtlId == IDCB_OUTPORT) {
- if (id != DlgPortId) {
- DlgInstructId = 0;
- DlgPortId = id;
- ResetOutputPort (hDlg, id, 0);
- }
- } else {
- DlgInstructId = id;
- }
- }
- default:
- break;
- }
- default:
- break ;
- }
- break;
- }
- return (INT_PTR)FALSE;
- }
- static int OnCreate (HWND hWindow) {
- // 禁用中文输入法
- ImmDisableIME(-1);
- // 添加状态栏基础设置
- InitCommonControls();
- // 添加 状态栏 输入端口/输出端口/指令集/效果/中音基调
- hStatus = CreateStatusWindow ( WS_CHILD | WS_VISIBLE, _T (""),
- hWindow, ID_STATUS_BAR);
- UINT widths[2];
- RECT rcClient;
- GetClientRect (hStatus, &rcClient);
- int status_height = rcClient.bottom - rcClient.top;
- widths[0] = 180;
- widths[1] = rcClient.right;
- SendMessage (hStatus, SB_SETPARTS, (WPARAM)(sizeof widths / sizeof widths[0]), (LPARAM)widths);
- DirectDrawObj = new CDirectDraw (hWindow, sClientSize, sClientSize);
- DirectDrawObj->LoadImage (IDBITMAP_PNG_PIANO_S3, sClientSize.cx, sClientSize.cy, gd_piano);
- DirectInput8Obj = new CDirectInput8 ();
- DirectInput8Obj->InitDeviceKeyboard (hWindow);
- // 初始化NT计数器频率
- QueryPerformanceFrequency ((PLARGE_INTEGER) & liTiming);
- // 读取位图
- // 枚举DirectMusic输出端口
- CUtil ::ReSizeClient (hWindow,
- GlobalObject::sClientSize.cx,
- GlobalObject::sClientSize.cy + status_height,
- GlobalObject :: uiWindowStyle,
- 0, TRUE);
- MoveWindow (hStatus, 0, 0, 0, 0,TRUE);
- return 0;
- }
- static LRESULT CALLBACK WndProc (HWND hWindow, UINT meesage, WPARAM wParam, LPARAM lParam) {\
- WORD id;
- switch (meesage) {
- case WM_COMMAND:
- id = LOWORD (wParam);
- // 分析菜单
- switch (id) {
- case ID_IO_INSTRUCTMENTS:
- // midi输入输出设置模态对话框
- DialogBox (instance, MAKEINTRESOURCE (IDD_IO_INSTRUCTMENTS), hWindow, DlgCallback_IoInstructments_);
- default:
- break ;
- }
- case WM_CREATE:
- OnCreate (hWindow);
- return 0;
- case WM_DESTROY:
- // 退出Windows 消息循环
- PostQuitMessage (0);
- return 0;
- case WM_KEYDOWN:
- case WM_KEYUP:
- case WM_CHAR:
- return 0;
- case WM_PAINT:
- // 去除无效矩形防止重复 WM_PAINT, 除此之外不做任何处理
- RECT rcUpdate;
- GetUpdateRect (hWindow, & rcUpdate, NULL);
- OutputDebugString (_T ("WM_PAINT hit !...\n"));
- if ( rcUpdate.bottom >= GlobalObject ::sClientSize.cy) {
- OutputDebugString (_T ("DrawStatusBar hit !...\n"));
- break ;
- } else {
- ValidateRect (hWindow, NULL);
- OutputDebugString (_T ("NoDraw hit !...\n"));
- }
- return 0;
- case WM_ERASEBKGND:
- // 返回非0表示已经擦除背景防止闪烁
- // https://msdn.microsoft.com/en-us/library/ms648055(VS.85).aspx
- return !0;
- default:
- break;
- }
- return DefWindowProc (hWindow, meesage, wParam, lParam);
- }
- };
- void doMain () {
- // 测试是否需要更新画面
- LONGLONG nCompFrep = GlobalObject ::liTiming / GlobalObject::FreshPer;
- LONGLONG nCountCurrent;
- QueryPerformanceCounter ((PLARGE_INTEGER) &nCountCurrent);
- LONGLONG nTickProc = nCountCurrent - GlobalObject::liStartTiming;
- BOOL bUpdateDraw = FALSE;
- OutputDebugString (_T("HIT\n"));
- if ( nTickProc >= nCompFrep) {
- bUpdateDraw = TRUE;
- GlobalObject::liStartTiming = nCountCurrent;
- }
- if (bUpdateDraw != FALSE) {
- CDirectDraw ::graph_desc gd;
- // 锁表面
- GlobalObject::DirectDrawObj->lockBuffer (NULL, gd);
- CUtil ::CSurfaceCopy32 (gd.__vptr, 0, 0,
- gd.pitch, GlobalObject ::gd_piano.__vptr, 0, 0,
- GlobalObject ::gd_piano.pitch, GlobalObject ::sClientSize.cx,GlobalObject ::sClientSize.cy);
- GlobalObject ::DirectInput8Obj->PollBuffer ();
- # define PRIVATE_UNWIND(id)\
- if (GlobalObject ::DirectInput8Obj->isPressedFirst (DIK_F##id))\
- { GlobalObject::DirectMusicObj->SetMiddleOctave (id); \
- SendMessage (GlobalObject::hStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)_T ( "MiddleOctave:" )_T(#id)); }
- PRIVATE_UNWIND (1);
- PRIVATE_UNWIND (2);
- PRIVATE_UNWIND (3);
- PRIVATE_UNWIND (4);
- PRIVATE_UNWIND (5);
- PRIVATE_UNWIND (6);
- PRIVATE_UNWIND (7);
- PRIVATE_UNWIND (8);
- PRIVATE_UNWIND (9);
- PRIVATE_UNWIND (10);
- TCHAR szBuf[1024];
- int pos = 0;
- BYTE oct =GlobalObject ::DirectMusicObj->GetFixedVelocity () & 0x7F;
- for (int id= 0; id != sizeof (CPianoDraw__ ::keyboard_mapper)/ sizeof (CPianoDraw__ ::keyboard_mapper[0]); id++) {
- struct CPianoDraw__::dummt_ &c = CPianoDraw__ ::keyboard_mapper[id];
- int mask = GlobalObject ::DirectInput8Obj->getMask (c.mapDIK);
- if ( mask & CDirectInput8 ::JP_MASK_PRESS)
- { CPianoDraw__ :: drawPiano (gd, c.octave_step, c.note);
- int n = GlobalObject::DirectMusicObj->GetMiddleOctave () + c.octave_step - 1;
- int cs = 12*n+c.midi_pos;
- cs &= 127;
- if ( ! (mask & CDirectInput8 ::JP_MASK_LAST))
- {
- GlobalObject ::DirectMusicObj->SendMidiMsg ( GlobalObject ::DirectMusicObj->EncodeMidiMessage (0x90, 0, cs, oct));
- }
- // 把按键信息推入缓冲
- int nc = _tcslen (c.harmonica_scale);
- memcpy (& szBuf[pos], c.harmonica_scale, nc * sizeof (TCHAR));
- pos += nc;
- }
- else
- {
- int n = GlobalObject::DirectMusicObj->GetMiddleOctave () + c.octave_step - 1;
- int cs = 12*n+c.midi_pos;
- cs &= 127;
- if ( ! (mask & CDirectInput8 ::JP_MASK_LAST))
- {
- GlobalObject ::DirectMusicObj->SendMidiMsg ( GlobalObject ::DirectMusicObj->EncodeMidiMessage (0x80, 0, cs, oct));
- }
- }
- }
- if (pos != 0) {
- szBuf[pos] = 0;
- SendMessage (GlobalObject::hStatus, SB_SETTEXT, (WPARAM)1, (LPARAM)szBuf);
- }
- // 解锁表面
- GlobalObject::DirectDrawObj->unlockBuffer ();
- }
- if (bUpdateDraw != FALSE) {
- POINT ptOrg = { 0, 0 };
- SIZE sSize = { GlobalObject ::sClientSize.cx, GlobalObject ::sClientSize.cy};
- GlobalObject::DirectDrawObj->BlitBtoV (NULL, NULL, NULL);
- GlobalObject::DirectDrawObj->postRender (ptOrg, ptOrg, sSize);
- }
- }
- int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
- PSTR szCmdLine, int iCmdShow)
- {
- MSG msg ;
- HRESULT sig = S_OK;
- WNDCLASS wndclass = { CS_HREDRAW | CS_VREDRAW,
- GlobalObject :: WndProc, 0, 0, hInstance,
- LoadIcon (NULL, IDI_APPLICATION),
- LoadCursor (NULL, IDC_ARROW),
- (HBRUSH) GetStockObject (NULL_BRUSH),
- (LPCTSTR) MAKEINTRESOURCE (IDRM_MAIN), GlobalObject ::szClassName };
- if (!RegisterClass (&wndclass)) {
- MessageBox ( NULL, TEXT ("This program requires Windows NT!"),
- GlobalObject::szClassName, MB_ICONERROR) ;
- return 0 ;
- }
- CoInitialize (NULL); // 初始化COM (DirectMusic).
- CDirectDraw ::InitDirect3D ();
- CDirectInput8 ::InitDInput8 ();
- GlobalObject ::instance = hInstance;
- GlobalObject ::hWindowMain = CreateWindow ( GlobalObject::szClassName,
- GlobalObject ::szCaption,
- GlobalObject :: uiWindowStyle,
- CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT, NULL,
- NULL, hInstance,
- NULL) ;
- // 初始化 DirectMusic COM根.
- CDirectMusic_::InitDirectMusic (GlobalObject ::hWindowMain);
- // create direct3d 9
- // sm_Direct3D9_root = Direct3DCreate9 (DIRECT3D_VERSION);
- //assert (sm_Direct3D9_root != NULL);
- // create device
- // D3DPRESENT_PARAMETERS d3dpp;
- // ResetD3dpp (d3dpp, hwnd, 0, 0);
- HRESULT si = 0;
- // HRESULT si = sm_Direct3D9_root->CreateDevice (0,
- // D3DDEVTYPE_HAL,
- // hwnd,
- // D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, & sm_Direct3D9_device);
- assert (SUCCEEDED (si));
- //si = sm_Direct3D9_device->CreateOffscreenPlainSurface (256, 256, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM,
- // & sm_Direct3D9_surface, NULL);
- assert (SUCCEEDED (si));
- // 创建DirectMusic对象
- GlobalObject :: DirectMusicObj = new CDirectMusic_ ();
- TCHAR szBuf[32];
- _stprintf (szBuf, _T ("MiddleOctave:%d"), GlobalObject :: DirectMusicObj->GetMiddleOctave ());
- SendMessage (GlobalObject::hStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)szBuf);
- ShowWindow (GlobalObject ::hWindowMain, iCmdShow) ;
- UpdateWindow (GlobalObject ::hWindowMain) ;
- for (;;)
- {
- // 取出消息, 没有直接跳过.
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- if (msg.message == WM_QUIT)
- return TRUE;
- TranslateMessage(&msg);
- DispatchMessage (&msg);
- }
- // 处理我们想要做的事情.
- doMain ();
- }
- CDirectDraw ::UninitDirect3D ();
- CDirectInput8 ::UninitDInput8 ();
- return msg.wParam ;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement