HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2008
0928
MK心理学実験:音声反応による反応時間の取得4解決


MK

リンク

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



この記事に返信する


GENKI

リンク

2008/9/29(Mon) 01:36:02|NO.19853

むう。ここの掲示板は技術系・ハード系の質問はレスされにくい気がします。
当たり前か…。


時間の計測はもう少しお手軽に、こうすることも出来ます。

#include "d3m.hsp" 時間 = d3timer()
まあ、本題じゃないんでどうでもいいところなんですが…。


本題行きます。

> 「PCに接続したマイクがほんのわずかでも音声入力を感じ取ったら、
> その瞬間にtimeGetTime()が実行される」

マイクから入力された音声の時系列波形データをリアルタイムで取得できればいいようですね。
入力のレベルがある程度以上になったら、timeGetTime()が実行するようにする。
で、出来そうですね。

が、大きな問題が…どうやったら入力された音声信号をリアルタイムで取得できるのか分かりません。orz
何かAPIを使えば出来そうな気はしますが…何を使えばいいのやら。
オシロスコープ関連だと思うんですが、あまりいい情報を見つけることができませんでした。
短時間(0.1秒ぐらい)録音して表示…を繰り返す方法などがあるようですが、音関係は分からないのでこれ以上は…。(分かる人に任せよう。^ ^;)


最後にもうひとつ。
スクリプトは改行で整理せずに、コメントやタブを使って整形したほうが見やすくなりますよ。



New Monkey

リンク

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
を参考にしました



New Monkey

リンク

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



MK

リンク

2008/9/29(Mon) 16:53:56|NO.19867

>GENKI様

ご専門領域でないにも関わらず考えて頂き、
ヒントまで頂きまして本当にありがとうございました。
また、スクリプトの整理の仕方も是非参考にさせて頂きます。


>New Monkey様

様々なHPを調べて頂きました上にスクリプトまでご提示いただきまして、
本当にありがとうございました。

実行してみました。
HSPはこんなことまでできるのですね。
本当にびっくりしております。

自分で調べたつもりでしたが、やはり調べ方が足りなかったのだと、
反省しております。

本当にありがとうございました。



ONION software Copyright 1997-2023(c) All rights reserved.