Skip to content

Instantly share code, notes, and snippets.

@skymonsters-Ks
Created April 30, 2017 16:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skymonsters-Ks/e900312eb046de22aaf9cf0457cb7429 to your computer and use it in GitHub Desktop.
Save skymonsters-Ks/e900312eb046de22aaf9cf0457cb7429 to your computer and use it in GitHub Desktop.
HSPプログラムコンテスト2016 HSPTV部門 応募作品「Mk-Synth」ソースコード
/*
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