Created
April 30, 2017 16:43
-
-
Save skymonsters-Ks/e900312eb046de22aaf9cf0457cb7429 to your computer and use it in GitHub Desktop.
HSPプログラムコンテスト2016 HSPTV部門 応募作品「Mk-Synth」ソースコード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Mk-Synth | |
http://dev.onionsoft.net/seed/info.ax?id=1199 | |
required Shift-JIS | |
tested: HSP 3.5b3 | |
license: NYSL 0.9982 (http://www.kmonos.net/nysl/) | |
*/ | |
; #runtime "hsptv" ; for HSPTV | |
#packopt name "start" | |
#uselib "winmm" | |
#func timeGetTime "timeGetTime" | |
#func waveOutOpen "waveOutOpen" var, int, var, int, int, int | |
#func waveOutClose "waveOutClose" int | |
#func waveOutReset "waveOutReset" int | |
#func waveOutWrite "waveOutWrite" int, sptr, int | |
#func waveOutPrepareHeader "waveOutPrepareHeader" int, sptr, int | |
#func waveOutUnprepareHeader "waveOutUnprepareHeader" int, sptr, int | |
#const WAVE_MAPPER $ffffffff | |
#const WHDR_DONE 1 | |
#const M_PI2 M_PI * 2 | |
#const WAVE_FORMAT_PCM 1 | |
#const CHANNELS 1 | |
#const BITS_PER_SAMPLE 16 | |
#const SAMPLES_PER_SEC 44100 | |
#const BLOCK_ALIGN CHANNELS * BITS_PER_SAMPLE / 8 | |
#const WAVBUFNUM 5 | |
#const WFEX0 (WAVE_FORMAT_PCM | (CHANNELS << 16)) | |
#const WFEX1 SAMPLES_PER_SEC | |
#const WFEX2 SAMPLES_PER_SEC * BLOCK_ALIGN | |
#const WFEX3 BLOCK_ALIGN | (BITS_PER_SAMPLE << 16) | |
#const TRACK_NUM 4 | |
#const BYTE_PER_SEC WFEX2 | |
#const REC_SEC_MAX 120 | |
#const REC_BUF_BYTE BYTE_PER_SEC * REC_SEC_MAX | |
#const REC_BUF_DEF BYTE_PER_SEC * 10 | |
#enum TR_PRMA = 0 | |
#enum TR_PRMB | |
#enum TR_PRMC | |
#enum TR_AMAX | |
#enum TR_AATK | |
#enum TR_ARLS | |
#enum TR_BASE | |
#enum TR_AVAL | |
#enum TR_THET | |
#enum TRACK_DP_NUM | |
#enum TRI_KPRS = 0 | |
#enum TRI_KCOD | |
#enum TRI_TONE | |
#enum TRI_WCNT | |
#enum TRACK_IP_NUM | |
#enum MT_PRMA = 0 | |
#enum MT_PRMB | |
#enum MT_PRMC | |
#enum MT_AMAX | |
#enum MT_AATK | |
#enum MT_ARLS | |
#enum MT_BASE | |
#enum MT_RLEN | |
#enum MT_RVAL | |
#enum METER_NUM | |
#undef int | |
#define ctype int(%1) (0 + (%1)) | |
#undef double | |
#define ctype double(%1) (0.0 + (%1)) | |
;*start | |
getkey k, 49 | |
waittime = (k == 0) | |
wbufblock = 800 | |
repeat 8 | |
getkey k, 57 - cnt | |
if (k) { | |
wbufblock = 1600 - 100 * cnt | |
break | |
} | |
loop | |
wbufsize = wbufblock * BLOCK_ALIGN | |
/* | |
keymap( 0) = 90, 88, 67, 86, 66, 78, 77, 188, 190, 191, 226, 16 | |
keymap(12) = 65, 83, 68, 70, 71, 72, 74, 75, 76, 187, 186, 221 | |
keymap(24) = 81, 87, 69, 82, 84, 89, 85, 73, 79, 80, 192, 219 | |
keymap(36) = 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 189, 222, 220 | |
ts = "" | |
repeat 49 | |
ts += strf("%02x", keymap(cnt)) | |
loop | |
mesbox ts, 640, 480 | |
*/ | |
ts = "5a584356424e4dbcbebfe2104153444647484a4b4cbbbadd51574552545955494f50c0db31323334353637383930bddedc" | |
repeat 49 | |
keymap(cnt) = int("$" + strmid(ts, cnt * 2, 2)) | |
loop | |
dim trackival, TRACK_IP_NUM, TRACK_NUM | |
ddim trackval, TRACK_DP_NUM, TRACK_NUM | |
ts = "prm-a/prm-b/prm-c/amp/atk/rls/frq/rev-l/rev-v" | |
split ts, "/", meterstr | |
meterval = 8.5, 15.0, 2.0, 0.3, 0.0, 0.0, 40.0, 2000.0, 0.3 | |
metermax = 20, 20, 20, 1, 200, 200, 80, 7999, 1 | |
meterpx = 10, 380, 510 | |
basekey = 36 | |
dim revp | |
ddim revbuf, 8000 | |
sdim recbuf, REC_BUF_BYTE | |
reclen = REC_BUF_DEF | |
/* | |
wpoke wheader, $16, CHANNELS | |
lpoke wheader, $18, SAMPLES_PER_SEC | |
lpoke wheader, $1c, SAMPLES_PER_SEC * BLOCK_ALIGN | |
wpoke wheader, $20, BLOCK_ALIGN | |
wpoke wheader, $22, BITS_PER_SAMPLE | |
*/ | |
wheader = $46464952, $00000000, $45564157, $20746d66, $00000010, $00010001, $0000ac44, $00015888, $00100002, $61746164, $00000000 | |
; デバイス オープン | |
wfx = WFEX0, WFEX1, WFEX2, WFEX3 ; WAVEFORMATEX | |
waveOutOpen hwo, WAVE_MAPPER, wfx | |
if stat { | |
dialog "デバイスのオープンに失敗しました" | |
stop | |
} | |
; マルチバッファリング用のバッファ準備 | |
sdim wavBuf, wbufsize * WAVBUFNUM | |
dim whd, 8, WAVBUFNUM ; WAVEHDR | |
ptwhd = varptr(whd) | |
repeat WAVBUFNUM | |
whd(0, cnt) = varptr(wavBuf) + wbufsize * cnt, wbufsize | |
p = ptwhd + cnt * 32 | |
waveOutPrepareHeader hwo, p, 32 | |
waveOutWrite hwo, p, 32 | |
loop | |
font msgothic, 13 | |
*mainLoop | |
mpx = mousex | |
mpy = mousey | |
getkey lbtn, 1 | |
await waittime | |
if (whd(4, nowBufId) & WHDR_DONE) { ; バッファの再生が終了しているか | |
stick stk, 64 ; 非トリガー[Ctrl] | |
if (stk & 32) : if (stk & 64) { ; [Ctrl + Enter] | |
gosub *saveWave | |
} | |
if (stk & 16) { ; [Space] | |
if (stk & 64) { | |
if (playflag) : else { | |
playflag = 1 | |
} | |
recflag ^= 1 | |
} else { | |
if (recflag) { | |
dim recflag | |
} | |
playflag ^= 1 | |
} | |
} | |
if (stk & 128) { ; [Esc] | |
dim recpos | |
getkey k, 13 ; [Enter] | |
if (k) { | |
sdim recbuf, REC_BUF_BYTE | |
} | |
} | |
x = ((stk & 4) > 0) - (stk & 1) | |
y = ((stk & 2) > 0) - ((stk & 8) > 0) | |
if (stk & 64) { | |
reclen = limit(reclen + (x + y * 10) * BYTE_PER_SEC, BYTE_PER_SEC, REC_BUF_BYTE) | |
} else { | |
basekey = limit(basekey + x + y * 12, 0, 60) | |
} | |
dim keymapidx | |
repeat TRACK_NUM | |
tr = cnt | |
dup trival, trackival(0, tr) | |
trival = 0 | |
if (trival(TRI_KCOD)) { | |
; 前回押されていたキーのパラメータが変わっているかチェック | |
getkey k, trival(TRI_KCOD) | |
checkprm_tr = tr | |
gosub *checkprm | |
if ((k) && (basekey == prebasekey) && stat) { | |
trival = 1 | |
} | |
} else { | |
repeat 49 - keymapidx, keymapidx | |
kc = keymap(keymapidx) | |
keymapidx++ | |
getkey k, kc | |
if (k) { | |
tn = basekey + cnt | |
dim tc | |
repeat TRACK_NUM | |
checkprm_tr = cnt | |
gosub *checkprm | |
if ((trackival(TRI_TONE, cnt) != tn) || (stat == 0)) : tc++ | |
loop | |
if (tc == TRACK_NUM) { | |
trival = 1, kc, tn, 0 | |
#define MTT_PRM meterval(MT_PRMA), meterval(MT_PRMB), meterval(MT_PRMC) | |
#define MTT_AMP meterval(MT_AMAX), 0.002 / (meterval(MT_AATK) + 1), 0.002 / (meterval(MT_ARLS) + 1) | |
#define TMP_THET M_PI2 / int(44100.0 / ((meterval(MT_BASE) + 400) * powf(2, double(tn - 68) / 12))) | |
trackval(0, tr) = MTT_PRM, MTT_AMP, meterval(MT_BASE), 0.0, TMP_THET | |
break | |
} | |
} | |
loop | |
} | |
loop | |
prebasekey = basekey | |
timeGetTime | |
sgt = stat | |
p = nowBufId * wbufsize | |
repeat wbufblock | |
w = 0.0 | |
repeat TRACK_NUM | |
dup trival, trackival(0, cnt) | |
if (trival(TRI_KCOD)) : else : continue | |
dup trdval, trackval(0, cnt) | |
dup ampval, trackval(TR_AVAL, cnt) | |
if (trival) { | |
ampval = limitf(ampval + trdval(TR_AATK), 0, trdval(TR_AMAX)) | |
} else { | |
ampval -= trdval(TR_ARLS) | |
} | |
if (ampval < 0.000001) { | |
trival(TRI_KCOD) = 0 | |
trival(TRI_TONE) = 0 | |
continue | |
} | |
t = trdval(TR_THET) * trival(TRI_WCNT) | |
w += sin(trdval * t + trdval(TR_PRMB) * sin(trdval(TR_PRMC) * t)) * ampval | |
trival(TRI_WCNT)++ | |
loop | |
w += revbuf(revp) * meterval(MT_RVAL) | |
revbuf(revp) = w | |
revp++ | |
revp \= (meterval(MT_RLEN) + 1) | |
smp = limit(w * $7fff + playflag * (wpeek(recbuf, recpos) << 16 >> 16), -$7fff, $7fff) | |
wpoke wavBuf, cnt * 2 + p, smp | |
if (recflag) { | |
wpoke recbuf, recpos, smp | |
} | |
recpos += 2 * ((playflag) || (recflag)) | |
recpos \= reclen | |
loop | |
waveOutWrite hwo, ptwhd + nowBufId * 32, 32 | |
nowBufId++ | |
nowBufId \= WAVBUFNUM | |
timeGetTime | |
delta = stat - sgt | |
redraw 0 | |
color 30, 30, 50 | |
boxf | |
color 80, 80, 200 | |
repeat 3 | |
y = 20 + 160 * cnt | |
line -1, y, 640, y | |
loop | |
color 220, 250, 120 | |
dim getWaveH_p : gosub *getWaveH | |
pos , refdval | |
repeat 641 | |
getWaveH_p = cnt * 2 : gosub *getWaveH | |
line cnt, refdval | |
loop | |
repeat TRACK_NUM | |
x = 12 + cnt * 20 | |
circle x - 5, 5, x + 5, 15, (trackival(TRI_KPRS, cnt) > 0) | |
loop | |
pos 500, 4 | |
mes strf("%2d /%4d /%2d /%5d", basekey, delta, waittime, wbufblock) | |
sdim ts | |
if (playflag) : ts += "> " | |
if (recflag) : ts += "○" | |
pos 534, 354 | |
mes strf("/%7.2f ", reclen / BYTE_PER_SEC) + ts | |
if (lbtn) : else { | |
activemeter = -1 | |
} | |
mbox_mode = 1 | |
mbox_id = 99 | |
td = double(recpos) | |
dup mbox_val, td | |
mbox_px = 12 | |
mbox_py = 350 | |
mbox_w = 460 | |
mbox_max = reclen - 1 | |
gosub *meterBox | |
recpos = int(td) / 2 * 2 | |
dim mbox_mode | |
repeat METER_NUM | |
color 220, 250, 120 | |
mbox_id = cnt | |
mbox_str = meterstr(cnt) | |
dup mbox_val, meterval(cnt) | |
mbox_px = meterpx(cnt / 3) | |
mbox_py = 391 + 32 * (cnt \ 3) | |
mbox_w = 120 + 240 * (cnt < 3) | |
mbox_max = metermax(cnt) | |
gosub *meterBox | |
loop | |
redraw | |
} | |
goto *mainLoop | |
#deffunc bye onexit | |
if (hwo) { | |
waveOutReset hwo | |
repeat WAVBUFNUM | |
waveOutUnprepareHeader hwo, ptwhd + cnt * 32, 32 | |
loop | |
waveOutClose hwo | |
} | |
return | |
*saveWave | |
dialog "wav", 17 | |
if (stat) { | |
lpoke wheader, $04, reclen + 36 | |
lpoke wheader, $28, reclen | |
sdim wavData, reclen + 44 | |
memcpy wavData, wheader, 44 | |
memcpy wavData, recbuf, reclen, 44 | |
bsave refstr, wavData | |
} | |
return | |
*checkprm | |
dim res | |
repeat 5 | |
i = cnt + (cnt == 4) * 2 | |
res += trackval(i, checkprm_tr) == meterval(i) | |
loop | |
return res == 5 | |
*getWaveH | |
return double(wpeek(wavBuf, getWaveH_p) << 16 >> 16) / $7fff * 160 + 180 | |
*meterBox | |
mbox_xw = mbox_px + mbox_w | |
mbox_yw = mbox_py + 15 | |
if ((activemeter < 0) && (mpx >= mbox_px) && (mpx <= mbox_xw) && (mpy >= mbox_py) && (mpy <= mbox_yw)) { | |
color 180, 220, 90 | |
if (stk & 256) { | |
activemeter = mbox_id | |
mdpx = mpx | |
} | |
} | |
if (mbox_id == activemeter) { | |
color 180, 255, 255 | |
if (lbtn) { | |
mbox_val = limitf(double(mpx - mbox_px) / mbox_w * mbox_max, 0, mbox_max) | |
} | |
} | |
mbox_tx = mbox_px + (mbox_val / mbox_max * mbox_w) | |
if (mbox_mode) { | |
line mbox_xw, 360, mbox_px, 360 | |
boxf mbox_tx - 1, 353, mbox_tx, 366 | |
pos , 354 | |
mes strf("%8.2f", mbox_val / BYTE_PER_SEC) | |
} else { | |
pos mbox_px, mbox_py | |
line mbox_xw, mbox_py | |
line mbox_xw, mbox_yw | |
line mbox_px, mbox_yw | |
line mbox_px, mbox_py | |
pos , mbox_py - 13 | |
mes strf("%s %.3f", mbox_str, mbox_val / mbox_max) | |
boxf mbox_px, mbox_py, mbox_tx, mbox_yw | |
} | |
return |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment