|
|
2008/9/28(Sun) 07:07:09|NO.19810
こんにちは。現在、単語を視覚呈示してから、
口頭で読み始めるまでの反応時間を計測する実験プログラムを、
HSPを用いて作成したいと考えております。
これをHSPで行う方法についてご教授頂ければ幸いです。
例えば、「キー押し」の場合は、以下のようなスクリプトを書けば、
反応時間を計算することができます。
それゆえ、必要なことは、
「PCに接続したマイクがほんのわずかでも音声入力を感じ取ったら、
その瞬間にtimeGetTime()が実行される」
ようなスクリプトが書ければいいのかな、と考えております。
どなたかご存じの方がおられましたら、どうぞよろしくお願い申し上げます。
#uselib "winmm.dll"
#func timeBeginPeriod "timeBeginPeriod" sptr
#func timeEndPeriod "timeEndPeriod" sptr
#cfunc timeGetTime "timeGetTime"
timeBeginPeriod 1
bgscr 0, ginfo_dispx, ginfo_dispy, 0, 0, 0
font "MS ゴシック",48
pos ginfo_dispx/2, ginfo_dispy/2
mes "+"
wait 100
cls
wait 50
pos ginfo_dispx/2, ginfo_dispy/2
mes "本屋"
スタート= timeGetTime()
repeat
getkey a,89
if a {
ストップ= timeGetTime()
break
}
getkey b,78
if b {
ストップ = timeGetTime()
break
}
await
loop
反応時間 = ストップ - スタート
cls
timeEndPeriod 1
end
|
|
2008/9/29(Mon) 01:36:02|NO.19853
むう。ここの掲示板は技術系・ハード系の質問はレスされにくい気がします。
当たり前か…。
時間の計測はもう少しお手軽に、こうすることも出来ます。
#include "d3m.hsp"
時間 = d3timer()
まあ、本題じゃないんでどうでもいいところなんですが…。
本題行きます。
> 「PCに接続したマイクがほんのわずかでも音声入力を感じ取ったら、
> その瞬間にtimeGetTime()が実行される」
マイクから入力された音声の時系列波形データをリアルタイムで取得できればいいようですね。
入力のレベルがある程度以上になったら、timeGetTime()が実行するようにする。
で、出来そうですね。
が、大きな問題が…どうやったら入力された音声信号をリアルタイムで取得できるのか分かりません。orz
何かAPIを使えば出来そうな気はしますが…何を使えばいいのやら。
オシロスコープ関連だと思うんですが、あまりいい情報を見つけることができませんでした。
短時間(0.1秒ぐらい)録音して表示…を繰り返す方法などがあるようですが、音関係は分からないのでこれ以上は…。(分かる人に任せよう。^ ^;)
最後にもうひとつ。
スクリプトは改行で整理せずに、コメントやタブを使って整形したほうが見やすくなりますよ。
|
|
2008/9/29(Mon) 08:19:35|NO.19860
bass.dllという音声処理用のDLLを使うと各種音声入力を取得できるみたいです
データの取得にコールバック関数を使うのですが、HSPでは標準で実装されていないので
コールバック関数を扱うためのプラグインも必要です
適当ですが音声入力を取得する部分を作ってみました
処理速度が追いつかないため(?)不安定で、時々固まるので注意^^;
以下手順
スクリプトを適当な名前で保存
↓
http://www.un4seen.com/ から、BASS 2.4.2(bass24.zip)をダウンロードして
bass.dllをスクリプトと同じフォルダにコピー
↓
http://yokohama.cool.ne.jp/chokuto/ から、コールバック関数実装プラグイン(hscallbk10.zip)をダウンロードして
hscallbk.dllとhscallbk.asをスクリプトと同じフォルダにコピー
↓
実行
#include "hscallbk.as"
#uselib "bass.dll"
#cfunc BASS_Init "BASS_Init" sptr, sptr, sptr, sptr, sptr
#func BASS_Free "BASS_Free"
#func BASS_Stop "BASS_Stop"
#func BASS_ChannelStop "BASS_ChannelStop" sptr
#cfunc BASS_RecordInit "BASS_RecordInit" sptr
#func BASS_RecordFree "BASS_RecordFree"
#cfunc BASS_RecordGetInput "BASS_RecordGetInput" sptr, sptr
#func BASS_RecordSetInput "BASS_RecordSetInput" sptr, sptr, sptr
#cfunc BASS_RecordGetInputName "BASS_RecordGetInputName" sptr
#cfunc BASS_RecordStart "BASS_RecordStart" sptr, sptr, sptr, sptr, sptr
#uselib "kernel32.dll"
#func CopyMemory "RtlMoveMemory" sptr, sptr, sptr
;コールバック関数の設定
#uselib ""
#func RecordingCallback "" int, int, int, int
setcallbk Proc, RecordingCallback, *OnRecordingCallback
;bass.dll初期化
if (BASS_RecordInit(-1)=0)|(BASS_Init(-1, 44100, 0, hwnd, 0)=0) {
BASS_RecordFree
BASS_Free
dialog "初期化失敗"
end
}
onexit *ExitProc
width 300, 50
;Windowsの録音コントロールで選択されている入力ソースのみON
repeat
a = BASS_RecordGetInput(cnt, 0)
if a=-1 {
break
} else {
if (a & $10000)=0 {
BASS_RecordSetInput cnt, $20000/*BASS_INPUT_ON*/, -1
p = BASS_RecordGetInputName(cnt)
dupptr dName, p, 1, 2
title "入力ソース = "+dName
} else {
BASS_RecordSetInput cnt, $10000/*BASS_INPUT_OFF*/, -1
}
}
loop
;録音開始。サンプリングレートは大きくしすぎると処理が追いつかなくて(?)落ちる。量子化ビット数は8ビットにした
rchan = BASS_RecordStart(1000/*サンプリングレート*/, 1/*CH数*/, 1/*BASS_SAMPLE_8BITS*/, varptr(Proc), 0)
stop
*OnRecordingCallback
;録音中に繰り返し呼ばれるコールバック関数
;一定間隔で呼ばれ、その間の録音データがまとめて格納される
;callbkarg(1)が録音データの先頭アドレス、callbkarg(2)が録音データのサイズ
;録音データを取得。処理速度の都合上最初の1サンプルのみ取得
;量子化ビット数を8ビットにしたので値は0〜255(128が振幅なし)
CopyMemory varptr(val), callbkarg(1), 1
redraw 0
color 255, 255, 255 : boxf
color : boxf 0, 0, 255, 20
pos 0, 20 : mes ""+val
color 0, 255, 0 : boxf 0, 0, val, 20
redraw 1
return 1
*ExitProc
BASS_ChannelStop rchan
BASS_RecordFree
BASS_Free
BASS_Stop
end
音声データの構造は http://www13.plala.or.jp/kymats/study/multimedia.html のWAVEの項目を、
bass.dllの使い方はbass24.zipの中に入っているヘルプとサンプル bass24\delphi\RecordTest
を参考にしました

| |
|
2008/9/29(Mon) 10:54:54|NO.19861
改良しました、今度のはばっちりです
HSP単体で実行できます
こことか参考にしました
http://wisdom.sakura.ne.jp/system/winapi/media/mm7.html
#uselib "winmm.dll"
#func waveInOpen "waveInOpen" sptr, sptr, sptr, sptr, sptr, sptr
#func waveInPrepareHeader "waveInPrepareHeader" sptr, sptr, sptr
#func waveInAddBuffer "waveInAddBuffer" sptr, sptr, sptr
#func waveInStart "waveInStart" sptr
#func waveInStop "waveInStop" sptr
#func waveInUnprepareHeader "waveInUnprepareHeader" sptr, sptr, sptr
#func waveInClose "waveInClose" sptr
#define SAMPRATE 1000
oncmd gosub *OnWimData, $000003C0/*MM_WIM_DATA*/
onexit *ExitProc
hWaveIn = 0
dim wfe, 5
wfe(0) = 1 + ($00000001/*WAVE_FORMAT_PCM*/<<16)
wfe(1) = SAMPRATE
wfe(2) = SAMPRATE
wfe(3) = (1*8/8) + (8<<16)
wfe(4) = 18
sdim bWave, 1
dim whdr, 8
whdr(0) = varptr(bWave)
whdr(1) = 1
whdr(2) = 1
waveInOpen varptr(hWaveIn), $FFFFFFFF/*WAVE_MAPPER*/, varptr(wfe), hwnd, 0, $00010000/*CALLBACK_WINDOW*/
waveInPrepareHeader hWaveIn, varptr(whdr), 32
waveInAddBuffer hWaveIn, varptr(whdr), 32
waveInStart hWaveIn
width 640, 300
i = 0
stop
*OnWimData
val = peek(bWave, 0)
waveInAddBuffer hWaveIn, varptr(whdr), 32
redraw 0
if i\ginfo_winx=0 {
color : boxf
color 128, 128, 128
line 0, ginfo_winy/2, ginfo_winx, ginfo_winy/2
line 0, ginfo_winy/2-128, ginfo_winx, ginfo_winy/2-128
line 0, ginfo_winy/2+128, ginfo_winx, ginfo_winy/2+128
pos 0, ginfo_winy/2+(val-128)
}
color 0, 255, 0 : line i\ginfo_winx, ginfo_winy/2+(val-128)
redraw 1
i ++
return
*ExitProc
waveInStop hWaveIn
waveInClose hWaveIn
WaveInUnprepareHeader hWaveIn, varptr(whdr), 32
end

| |
|
2008/9/29(Mon) 16:53:56|NO.19867
>GENKI様
ご専門領域でないにも関わらず考えて頂き、
ヒントまで頂きまして本当にありがとうございました。
また、スクリプトの整理の仕方も是非参考にさせて頂きます。
>New Monkey様
様々なHPを調べて頂きました上にスクリプトまでご提示いただきまして、
本当にありがとうございました。
実行してみました。
HSPはこんなことまでできるのですね。
本当にびっくりしております。
自分で調べたつもりでしたが、やはり調べ方が足りなかったのだと、
反省しております。
本当にありがとうございました。
|
|