とりあえず自分的にはうまくいったと思っていますが、よろしければアドバイスして下さい。
下のスクリプト(モジュール)は、試行錯誤しながらテスト用に作ったので無駄が多いと思います。
(そこは無視して下さい)
音声データも改良予定(まぁほとんど改良しますが…)
自分用なのでコメントもほとんどありません。
※起動後1〜2分ほどお待ち下さい。
インクルード用ファイル↓ "waveOutEngine01.hsp"で保存してください。
#uselib "winmm.dll"
#func global waveOutOpen "waveOutOpen" sptr, sptr, sptr, sptr, sptr, sptr
#func global waveOutPrepareHeader "waveOutPrepareHeader" sptr, sptr, sptr
#func global waveOutWrite "waveOutWrite" sptr, sptr, sptr
#func global waveOutReset "waveOutReset" sptr
#func global waveOutUnprepareHeader "waveOutUnprepareHeader" sptr, sptr, sptr
#func global waveOutClose "waveOutClose" sptr
;#define SAMPRATE 11025 //サンプリングレート(変更可)
;#define BITSPERSAMP 8 //量子化ビット数(変更不可)
;#define NCHANNELS 1 //チャンネル数(変更不可)
;#define BUFCNT 2 //多重バッファ数
oncmd gosub *OnWomDone, $000003BD/*MM_WOM_DONE*/
#module
#deffunc Waveloop int kaiten
repeat BUFCNT
bcnt = cnt
repeat bufsize/4
lpoke bWave(bcnt), cnt*4, lpeek(kWave(bcnt,kaiten),cnt*4)
loop
loop
return
#deffunc StartProc
duration = 80
SAMPRATE= 11025 //サンプリングレート(変更可)
BITSPERSAMP= 8 //量子化ビット数(変更不可)
NCHANNELS= 1 //チャンネル数(変更不可)
BUFCNT = 2 //多重バッファ数
//WAVEFORMATEX構造体を用意
dim wfe, 5
wfe(0) = $00000001/*WAVE_FORMAT_PCM*/ + (NCHANNELS<<16) //wFormatTag + (nChannels<<16)
wfe(1) = SAMPRATE //nSamplesPerSec
wfe(2) = SAMPRATE*NCHANNELS*BITSPERSAMP/8 //nAvgBytesPerSec
wfe(3) = (NCHANNELS*BITSPERSAMP/8) + (BITSPERSAMP<<16) //nBlockAlign + (wBitsPerSample<<16)
wfe(4) = 18 //cbSize
//WAVEHDR構造体を用意
bufsize = (duration)*int(1.0*SAMPRATE/1000)
sdim bWave, bufsize, BUFCNT //音声データ格納用バッファ
sdim kWave, bufsize, BUFCNT,401 //音声データ格納用バッファ
dim whdr, 8, BUFCNT
repeat BUFCNT
whdr(0, cnt) = varptr(bWave(cnt))
whdr(1, cnt) = bufsize
whdr(4, cnt) = $00000004|$00000008 //WHDR_BEGINLOOP|WHDR_ENDLOOP
whdr(5, cnt) = 1
loop
//波形データを作成///////////////////////////
PI=3.141592653589793 //円周率
dim otovol,25
dim Hz,25
otovol(0)=127.0*1046.4/20000,127.0*3514.75/20000,127.0*4694.37/20000,127.0*1566.45/20000,127.0*1569.91/20000 //音量
otovol(5)=127.0*607.88/20000,127.0*874.27/20000,127.0*496.59/20000,127.0*512.61/20000,127.0*620.43/20000 //音量
otovol(10)=127.0*1504.62/20000,127.0*1291.39/20000,127.0*541.55/20000,127.0*315.37/20000,127.0*816.32/20000 //音量
otovol(15)=127.0*272.51/20000,127.0*372.11/20000,127.0*210.69/20000,127.0*277.78/20000,127.0*193.45/20000 //音量
otovol(20)=127.0*515.95/20000,127.0*337.9/20000,127.0*316.53/20000,127.0*23.15/20000,127.0*190.67/20000 //音量
Hz(0)=118.4,226.1,344.5,463.0,570.6
Hz(5)=689.1,807.5,915.2,1033.6,1152.0
Hz(10)=1270.5,1378.1,1496.6,1615.0,1722.7
Hz(15)=1841.1,1959.5,2067.2,2185.6,2304.1
Hz(20)=2411.7,2530.2,2648.6,2777.8,2874.7
repeat 401
kaitencnt=cnt
repeat BUFCNT
bcnt = cnt
repeat bufsize
val=128
count=cnt
repeat 25
len=1.0*SAMPRATE/(Hz(cnt)*(1.0*(kaitencnt+1)/(401/4)))
d=PI*2/len*(count)
val+=(sin(d)*otovol(cnt))
loop
poke kWave(bcnt,kaitencnt), cnt, limit(val,0,255)
loop
loop
pset cnt*100/401,cnt*100/401 //進行状況(テスト用)
await 0
loop
repeat BUFCNT
bcnt = cnt
repeat bufsize
poke bWave(bcnt), cnt, 128
loop
loop
//WaveOutの初期化
hWaveOut = 0
waveOutOpen varptr(hWaveOut), $FFFFFFFF/*WAVE_MAPPER*/, varptr(wfe), hwnd, 0, $00010000/*CALLBACK_WINDOW*/
repeat BUFCNT
waveOutPrepareHeader hWaveOut, varptr(whdr(0, cnt)), 32
loop
repeat BUFCNT
waveOutWrite hWaveOut, varptr(whdr(0, cnt)), 32
loop
return
#deffunc StopProc
//WaveOutの後始末
waveOutReset hWaveOut
repeat BUFCNT
WaveOutUnprepareHeader hWaveOut, varptr(whdr(0, cnt)), 32
loop
waveOutClose hWaveOut
return
#deffunc EngineStop
StopProc
flgPlay=0
return
#deffunc EngineStart
StartProc
flgPlay=1
return
#deffunc ExitProc onexit
StopProc
return
#global
goto *@f
*OnWomDone //バッファの再生が終了するごとに呼ばれる
waveOutWrite wparam, lparam, 32
return
*@
インクルード用ファイル↑ "waveOutEngine01.hsp" ここまで
/////////////////////////////////////////////////////////
メインスクリプト↓
screen 0,300,300 : title "[左クリック] = アクセル"
centerpos=300/2 //中心点
kaiten=0 //回転数
onexit gosub *ending
#include "waveOutEngine01.hsp"
EngineStart
*main
redraw 2
getkey ky,1 //[左クリック]
kaiten=limit(kaiten+(ky*50*2)-25*2,800,9999) : kaiten+=((rnd(100)*(kaiten<=800))-(rnd(50)*(kaiten>=9999)))
//エンジン音処理↓
Waveloop 1*kaiten/25
//描画処理↓
color : boxf : color 0,100,255 : pos 50,230 : mes "MIN" : color 255 : pos 230,230 : mes "MAX"
d=3.141593*2/(360*2)*((270.0/10 *kaiten/1000*2)+(135*2))
cx=centerpos+cos(d)*125 : cy=centerpos+sin(d)*125
color 255,240,150
line cx,cy,centerpos,centerpos : circle centerpos-2,centerpos-2,centerpos+3,centerpos+3
mes ""+kaiten+"rpm"
redraw 1
await 16
goto *main
*ending
end