こんにちわ
>マイク入力を録音する方法は見つかったのですが、マイク入力をそのまま遅延なく再生する方法がわかりません。
マイク入力が出来たのであれば、出力も同じような感じでできます。(winmmを使われている想定でInをOutにすればよい)
遅延に関してはどこまでを許容とするかにもよりますが(パソコン通す以上絶対遅延するので)
小さめのバッファサイズで再生すると遅延が少なくなりますが、処理が重いと音飛びしてしまいます。
一例ですがどおぞ(命令すくないので、必要あれば増やしてみてください)
#ifndef __WaveInOut__
#define __WaveInOut__
#module WaveInOut
#include "winmm.as"
// 定数
#define WAVE_MAPPER 0xFFFFFFFF // WAVE_MAPPER
#define WAVE_FORMAT_PCM 0x00000001 // PCM
#define CALLBACK_WINDOW 0x00010000 // コールバック
#define MM_WIM_DATA 0x000003C0 // コールバックメッセージ
#define WHDR_DONE 0x00000001 // 再生完了
#define BUFFER_NUM 3 // マルチバッファリングする
state = 0
#deffunc openWaveInOut array pbuff, int nSamplesPerSec
if state == 1 : return
state = 1
dup dbuff,pbuff
// 入力 ---------------------------------------------------------
wBytesPerSample = 2 // 16bit
// WAVEFORMATEX 構造体
wFormatTag = WAVE_FORMAT_PCM // フォーマット
nChannels = 1 // チャンネル
// nSamplesPerSec = 48000 // サンプルレート (引数で指定)
wBitsPerSample = wBytesPerSample * 8 // 量子化バイト数
nBlockAlign = nChannels * wBytesPerSample // ブロックアライメント
nAvgBytesPerSec = nSamplesPerSec * nBlockAlign // 平均ビットレート
cbSize = 0 // 追加フォーマット
wfx = wFormatTag | (nChannels << 16), nSamplesPerSec, nAvgBytesPerSec, nBlockAlign | (wBitsPerSample << 16), cbSize
// オープン : waveInOpen 関数
hwi = 0 // Device識別ハンドル
uDeviceID = WAVE_MAPPER // Device識別子
//pwfx // WAVEFORMATEX 構造体
dwCallBack = hwnd // Callback Message対象 /*ウインドウハンドル*/
oncmd gosub *ON_MM_WIM_DATA, MM_WIM_DATA
dwCallbackInstance = 0 // Callbackへ渡すデータ /*なし*/
fdwOpen = CALLBACK_WINDOW // Deviceフラグ $00010000/*CALLBACK_WINDOW*/
waveInOpen varptr(hwi), uDeviceID, varptr(wfx), dwCallBack, dwCallbackInstance, fdwOpen
if stat { dialog "ERROR: waveInOpne("+stat+")" : end }
// バッファ作成
bufferLength = length(dbuff) * wBytesPerSample
sdim inbuff, bufferLength, BUFFER_NUM
//WAVEHDR構造体 (一部)
dim in_wh, 8, BUFFER_NUM // 32byte用意
cbwh = 32 // WAVWHDR 構造体のサイズ (32)
repeat BUFFER_NUM
in_wh(0,cnt) = varptr(inbuff.cnt) // lpData ウェーブフォームバッファへのポインタ
in_wh(1,cnt) = varsize(inbuff.cnt) // dwBufferLength バッファのサイズ(バイト)
waveInPrepareHeader hwi, varptr(in_wh(0,cnt)), cbwh // 入力バッファ準備
waveInAddBuffer hwi, varptr(in_wh(0,cnt)), cbwh // デバイスにバッファーの追加
loop
// 出力 ---------------------------------------------------------
hwo = 0
waveOutOpen varptr(hwo), uDeviceID, varptr(wfx), dwCallBack, dwCallbackInstance, fdwOpen
if stat { dialog "ERROR: waveOutOpne("+stat+")" : end }
// バッファ作成
sdim outbuff, bufferLength, BUFFER_NUM
dim out_wh, 8, BUFFER_NUM
repeat BUFFER_NUM
out_wh(0,cnt) = varptr(outbuff.cnt)
out_wh(1,cnt) = varsize(outbuff.cnt)
waveOutPrepareHeader hwo, varptr(out_wh(0,cnt)), cbwh
waveOutWrite hwo, varptr(out_wh.0.cnt), cbwh
loop
// 入力のスタート
waveInStart hwi
if stat { dialog "ERROR: waveInStart("+stat+")" : end }
return
#deffunc closeWaveInOut
if state == 0 : return
state = 0
_exit
return
#deffunc local _exit onexit
waveInReset hwi
waveOutReset hwo
repeat BUFFER_NUM
waveInUnprepareHeader hwi, varptr(in_wh), cbwh
waveOutUnprepareHeader hwo, varptr(out_pwh), cbwh
loop
waveInClose hwi
waveOutClose hwo
return
*ON_MM_WIM_DATA
// wparam: 入力終了した デバイスのハンドル
// lparam: 入力終了した WAVEHDR構造体のポインタ
dupptr pwh, lparam, 32
dupptr pbuff, pwh.0, bufferLength, 2
// 入力を表示用バッファにコピー
repeat length(dbuff)
t = wpeek(pbuff, cnt*2)
if t & 0x8000 : t |= 0xffff0000
dbuff.cnt = double(t)/32768.0
loop
// 出力書き込み
repeat BUFFER_NUM
if out_wh.4.cnt & WHDR_DONE {
memcpy outbuff.cnt, pbuff, bufferLength
waveOutWrite hwo, varptr(out_wh.0.cnt), cbwh
break
}
loop
// 終了した入力を追加
waveInAddBuffer wparam, lparam, cbwh
return
#global
#endif
// サンプル
screen 0, 512, 400
ddim buff, 1024
button gosub "オープン", *MIC_OPEN
button gosub "クローズ", *MIC_CLOSE
while
redraw 0
color : boxf
color 255,255,255 : pos 0,200
repeat length(buff)
line cnt, -buff.cnt*200.0+200
loop
redraw 1
await 32
wend
*MIC_OPEN
openWaveInOut buff, 32000
return
*MIC_CLOSE
closeWaveInOut
return