こんにちわ
面白い事おこなってますね〜。
マイクなら標準搭載されてるwinmm使うのが簡単かと思います。
宜しかったら参考にどうぞ。
// 簡易マイク入力モジュール
// ----------------------------------------------
#module _WaveIn_
#uselib "WINMM.DLL"
#func waveInOpen "waveInOpen" var,int,var,int,int,int
#func waveInClose "waveInClose" int
#func waveInStart "waveInStart" int
#func waveInReset "waveInReset" int
#func waveInPrepareHeader "waveInPrepareHeader" int,var,int
#func waveInUnprepareHeader "waveInUnprepareHeader" int,var,int
#func waveInAddBuffer "waveInAddBuffer" int,var,int
#deffunc mic_open array _buff, int _rate
dup m_buff, _buff
// 入力のオープン(既定のマイクとフォーマットを設定)PCM: ? KHz 16bit mono
hwi = 0 : wfx = 1 | (1 << 16), _rate, _rate * 2, 2 | (16 << 16), 0
waveInOpen hwi, /*WAVE_MAPPER*/ 0xFFFFFFFF, wfx, hwnd, 0, /*CALLBACK_WINDOW*/ 0x10000
// マイク入力用バッファ作成(ダブル)
bufferLength = length(_buff) * 2
sdim buff1, bufferLength
sdim buff2, bufferLength
wh1 = varptr(buff1), varsize(buff1), 0,0,0,0,0,0
wh2 = varptr(buff2), varsize(buff2), 0,0,0,0,0,0
waveInPrepareHeader hwi, wh1, 32 : waveInAddBuffer hwi, wh1, 32
waveInPrepareHeader hwi, wh2, 32 : waveInAddBuffer hwi, wh2, 32
// 入力スタート
waveInStart hwi : if stat { dialog "ERROR: waveInStart("+stat+")" : end }
oncmd gosub *On_MM_WIM_DATA, /*MM_WIM_DATA*/0x03C0
return
*On_MM_WIM_DATA
dupptr wh, lparam, 32 : dupptr buff, wh.0, wh.1, 2
foreach m_buff : m_buff.cnt = double(wpeek(buff, cnt * 2) << 16 >> 16) / 32768.0 : loop
peak = 0.0 : foreach m_buff : peak = limitf(peak, absf(m_buff.cnt)) : loop
rms = 0.0 : foreach m_buff : rms += m_buff.cnt * m_buff.cnt : loop : rms = sqrt(rms / length(m_buff))
waveInAddBuffer wparam, wh, 32
return
#defcfunc mic_peak
return peak
#defcfunc mic_rms
return rms
#deffunc local exit onexit
waveInReset hwi : waveInUnprepareHeader hwi, wh, 32 : waveInClose hwi : return
#global
// サンプル
// ----------------------------------------------
#use a2d
// 画面とバッファ
screen 0, 320,512 : title "マイクで簡易口パク"
alCreateImageByFile 1, dir_tv+"up_tar.png" : alCreateImage 0, 512, 512 : alFont
// 設定値
gain = 10.0 // マイクの入力感度
dumping = 0.3 // 口の滑らかさ
vN = 52, 53, 70, 45, 52, 53, 30, 45 // 口(閉) 頂点データ 100*100
vO = 50, 30, 62, 45, 50, 58, 38, 45 // 口(お)
vE = 50, 35, 80, 43, 50, 55, 20, 43 // 口(え)
vA = 50, 30, 75, 47, 50, 65, 25, 47 // 口(あ)
// マイクオープン
ddim buff, 256 : mic_open buff, 8000 // ★追加した命令
*MAIN
// アップデート
// ----------------------------------------------
// 感度調整
stick pad : gain = limitf(gain + 0.5*(pad>>2&1)-0.5*(pad&1), 0, 100)
// まばたき更新
blink = limit(blink-1, 0, 2) : if rnd(120) = 0 { blink = 2 }
// 口の頂点ブレンド更新
blend = limitf(blend + (mic_rms() * gain - blend) * dumping, 0.0, 1.0) // ★入力の二乗平均を使う
repeat 1
if blend <= 0.25 { foreach vN : vC.cnt = vN.cnt : loop : break }
if blend <= 0.50 { foreach vN : vC.cnt = int((double(vO.cnt)-double(vN.cnt))*(blend-0.25)*4. + double(vN.cnt)) : loop : break }
if blend <= 0.75 { foreach vN : vC.cnt = int((double(vE.cnt)-double(vO.cnt))*(blend-0.50)*4. + double(vO.cnt)) : loop : break }
if blend <= 1.00 { foreach vN : vC.cnt = int((double(vA.cnt)-double(vE.cnt))*(blend-0.75)*4. + double(vE.cnt)) : loop : break }
loop
// ドロー
// ----------------------------------------------
alErase : alResetTransMode
// キャラ描画
alTransModeOffsetRotateZoom 0,0, 0, 0.5,0.5 // 頭体
alCopyImageToImage 1,0, 0,0, 640, 1024
alTransModeOffsetRotateZoom 64,165, 0, 0.5,0.5 // 眉
alCopyImageToImage 1,0, 0,0, 385, 128, 640, 0
alTransModeOffsetRotateZoom 65,217, 0, 0.5,0.5 // 目
alCopyImageToImage 1,0, 0,0, 385, 128, 640, 512+blink*128
alTransModeOffsetRotateZoom 123,271, 0, 0.7, 0.7 // 口描画
alColor 212,140,143 : alFillClosedCurve vC, 4, 0.8 // 口の塗
alColor : alDrawClosedCurve vC, 4, 0.8 // 口の線
// 入力波形描画
alTransModeOffsetRotateZoom ,32,,1.25, 0.3 : alColor 84,84,255
x2 = 0 : y2 = 100 : repeat length(buff) : x1 = x2 : y1 = y2 : x2 = cnt : y2 = -buff.cnt*100.0+100 : alDrawLine x1, y1, x2, y2 : loop
// 情報描画
alResetTransMode
alColor 255,122,0,64 : alFillRect 0,0, 320,16
alColor 255,122,0 : repeat 3,1 : alDrawLine 80*cnt, 0, 80*cnt, 16 : loop
txt = "閉じ", "お","え","あ" : repeat 4 : alDrawText txt.cnt, 80*cnt, 0, 80,16,1 :loop
alDrawText strf("口パク感度(← →): %3.1f", gain), 0,24
alColor 255,122,0,128 : alFillRect 0,4, blend*320,8
// 画面更新と待ち
alCopyImageToScreen 0, 0 : redraw : await 16 : redraw 0 : rgbcolor $FFFFFF : boxf
goto *MAIN
★余談★
音量は信号のピークを使うよりRMS使った方が好みです。
また、音量だと口が開きっぱなしになってしまいますので、
ある程度"音素"は判定した方が良いですね。