関数randによる音発生のタイミングの制御がうまくできないことについて

144 views
Skip to first unread message

takahiro hisazaki

unread,
May 9, 2018, 1:15:12 AM5/9/18
to 心理学実験について話そう
黒木先生

 お世話になります。九州ルーテル学院大学の久崎と申します。2年以上前ですが、FB上でPTBの導入についてお尋ねしたことがあります。

 今回、標記の件に助言いただけると幸いです。rand関数で音声や視覚刺激をランダムなタイミングで提示したいと思い、プログラムを作成しました。randは0~1の範囲の値を毎回提示する関数ですが、5*randをプログラム内に組み込んでも、0~5秒の適当なタイミングで提示がされることなく、10秒以上待って音・刺激がともに提示されることが多々あります。また、画面上に5*randの値を表示させて実行すると、毎回0.1秒未満の値が表示され、どのようにプログラムが処理されているのか見当がつきません。簡単なDemoプログラム(test0501)を以下に示しますので、もしよろしければ、そのプログラムで上記のトラブルをご確認いただき、お気づきのことなどがありましたら教えていただけないでしょうか。Demoは、音とと同時に画面中央に点が提示されますが、その回数を左下に、前の音・点提示からその提示までの時間(秒:理論的には5*rand秒)を右下に表示するようにしています。情報が不十分かもしれませんので、その他に何か必要な情報がありましたらお知らせください。

 どうぞよろしくお願いいたします。

久崎孝浩


function test0501
% Clear the workspace and the screen
sca;
close all;
clearvars;
Screen('Preference', 'SkipSyncTests', 0);
InitializePsychSound(1);

black=[0 0 0];

KbName('UnifyKeyNames');
myKeyCheck;

[mainWindow,wRect]=Screen('OpenWindow',0);
[xCenter,yCenter]=RectCenter(wRect);
fixposition=[xCenter-10 yCenter-10 xCenter+10 yCenter+10];
sr = 44100;
dur = 1;
fr = 300;
beep = MakeBeep(fr, dur, sr); 
nrchannels=size(beep,1);
if nrchannels < 2
    beep = [beep; beep];
    nrchannels = 2;
end
pahandle = PsychPortAudio('Open');
PsychPortAudio('FillBuffer', pahandle, beep);
    
%z,x,cのいずれかのキーが押されるのを待機
keyOn=0; i=0;
while keyOn == 0
    [keyIsDown, secs, keyCode] = KbCheck;
    if keyIsDown == 0
        t = GetSecs; rng('shuffle'); beepTime = 5*rand;
        if beepTime <= (GetSecs-t)
            i=i+1;
            PsychPortAudio('start', pahandle, 1);
            %Snd('Play',beep);
            Screen('FillOval',mainWindow,black,fixposition);
            Screen('DrawText', mainWindow,[num2str(beepTime,3) 's'], xCenter*1.6, yCenter*1.8);
            Screen('DrawText', mainWindow,[num2str(i) 'times'], xCenter*0.1, yCenter*1.8);
            Screen('Flip', mainWindow); t1 = GetSecs;
            while 1 > (GetSecs - t1) %母親の笑顔表情をsmileTime秒間ほど呈示
                [keyIsDown, secs, keyCode] = KbCheck;%反応待機
                if keyIsDown == 1
                    keyOn=1; break
                end
            end
        end
        Screen('Flip', mainWindow); 
    else
        keyOn=1; break
    end
end

%終了処理
sca;
Screen('CloseAll');

黒木@九州大学

unread,
May 9, 2018, 3:27:35 AM5/9/18
to 心理学実験について話そう
久崎先生

九州大学の黒木です。

ご相談をいただいた件について、ご提示いただいたコードを動かしてみようとしましたが、視覚刺激も聴覚刺激もなにも呈示されません。
とりあえず、気がついた点をお伝えしておきますと、
beepTimeは0から5の値を取り得ますが、
 if beepTime <= (GetSecs-t)
において、(GetSecs-t)はほとんどゼロになりますよね?
つまり、このif文の条件が満たされることはほとんどないと思われます。
なので、なんの刺激も呈示されないまま、
while keyOn == 0
のところが、ぐるぐる回り続けるのではないかと・・・。

while 1 > (GetSecs - t1) 
のところも気になります。
1秒間だけwhile文が回ることになりますが、それは想定通りでしょうか?

 t = GetSecs;
の位置も不適切なような気がしますが、なんとも分かりません・・・。
(おそらく、while文より前で呼び出さないといけないような・・・)

まだ久崎先生が作りたいプログラムを理解できていない状況でして、あまり具体的なアドバイスを差し上げられず、申し訳ありません。


takahiro hisazaki

unread,
May 11, 2018, 5:01:56 AM5/11/18
to 心理学実験について話そう
黒木先生

 お世話になります。久崎です。
 どのようなプログラムの作成したいのかをお伝えせずにご相談をしまして申し訳ありません。プログラム内容は次のとおりです。

 白紙画面の提示→ランダムな時間の待機(待機中にどこかのキーが押されたらプログラム終了)→音と画面中央ドットの(beepTime秒と提示回数timeも)1秒間提示(提示中にどこかのキーが押されたらプログラム終了)→白紙画面の提示(どこかのキーが押されない限り,上記プログラムが繰り返される)

 はじめに先生に送りましたtest0501デモ(添付ファイル)は最初はPCで再現できていたのですが,再度PCで駆動させると再現できずに白紙画面で何の提示もなく止まってしまい、先生のご指摘おとおりでした。そこで、test0510(添付ファイル)として作成しなおしてみたのですが,やはり駆動しません。よろしければ,test0510をご覧頂いて,上記プログラムの目的に照らして問題をご指摘いただけると助かります。ご面倒をおかけしますが,よろしくお願いいたします。

久崎
test0510.txt
test0501.txt

黒木@九州大学

unread,
May 14, 2018, 1:11:01 AM5/14/18
to 心理学実験について話そう
久崎先生

再度の投稿をありがとうございます。
test0510
について私の環境で動作確認をしましたが、問題なく動作しているように見えます。
どういった不具合があるのでしょうか? 駆動しないとのことですが、まったく動かないということでしょうか?

takahiro hisazaki

unread,
May 14, 2018, 12:08:57 PM5/14/18
to 心理学実験について話そう
黒木先生

 動作確認をしていただき、ありがとうございます。OSの問題もあるのだと思っています。

 私の確認では、はじめにお送りしましたtest0501は、Windows8.1ですと音・ドット・提示回数・提示時間間隔が提示されていましたが、提示時間間隔が0.01秒以下の値で表示されるという現象が起こります(実際にどのような時間間隔で提示されているのか分かりませんでした)。また、Windows10では、音が一度鳴って画面が白くなってフリーズしてしまいます。
 修正したtest0510は幸いにも、Windows8.1ですと音・ドット・提示回数・提示時間間隔がプログラムどおり提示されているようでした(提示時間間隔が0.01秒以下の値で表示されるという現象はなくなりました)が、2回目以降の実行ではPTB内部エラーでプログラムが停止して駆動しないため、一旦Matlabを閉じてから再度開いて実行すれば駆動しました。一方、Windows10ではやはり、音が一度鳴って画面が白くなってフリーズしてしまいます。

 できればtest0510をWindows10でも駆動させたいと思っていますので、Windows10で駆動しない理由を特定したいところです。これについて先生のご見解をいただければと存じます。お忙しいところに恐縮ですが、よろしくお願いいたします。

久崎

 

黒木@九州大学

unread,
May 16, 2018, 12:43:48 AM5/16/18
to 心理学実験について話そう
久崎先生

お返事が遅くなりました。

まずtest0501については、すでにお伝えした通りバグが含まれているので、とりあえず無視したほうがよいかと思います。

test0510について。
OSによって挙動が違うということですが、もちろんその可能性もあるのですが、必要なライブラリーがそろっていないなど別の理由も考えられます。
音が鳴らないWindows 10 において、BasicSoundOutputDemo が正しく動作をするか確認してみてください。

それから2回目以降の実行ができない点について、エラーメッセージをご確認ください。
もしMatlabごとフリーズしてエラーメッセージが確認できない場合は、

[mainWindow,wRect]=Screen('OpenWindow',0);

[mainWindow,wRect] = Screen('OpenWindow', 0, [], [50 50 1000 700]);

のように書き換えて、フルスクリーンではなく、ウィンドウ表示にして動作確認をしてみるとよいと思います。

エラーが出ているときは、Matlabのコマンドウィンドウ上に表示されます。

takahiro hisazaki

unread,
May 21, 2018, 10:57:07 PM5/21/18
to 心理学実験について話そう
黒木先生

 ご連絡ありがとうございます。先生のご助言は大変参考になり助かっております。

 まず、test0501のプログラムについて、先生のおっしゃるとおりでした。
 Win10でBasicSoundOutputDemoは正しく動作したのでOSの問題ではないことを確認し、先生がアドバイスしていただいたように、test0510内の[mainWindow,wRect] = Screen('OpenWindow', 0, [], [0 0 1920 1080]);に書き換えると、音とドットが表示されるようになりました。

 これで問題はなくなったと言いたいところなのですが、もう少しお尋ねしてよろしいでしょうか。

 Win8.1でtest0510を動作させると、Matlabを開いた初回はScreen(’Preference', 'SkipSyncTests', 0)で動作するのですが、Matlabを開いて2回目以降はそれでは動作せず、Screen(’Preference', 'SkipSyncTests', 1)にしても動作しません。その際のエラーとして、INTERNAL PSYCHTOOLBOX ERRORが表示され、「Portaudio deviceが開けません」という文言と、赤字で「エラー:PsychPortAudio」となります。
 一方、Win10でtest0510を動作させると、Matlabを開いた初回かそれ以降かに関係なく、Screen(’Preference', 'SkipSyncTests', 1)としないと動作しません。Screen(’Preference', 'SkipSyncTests', 0)としたときには動作停止後に「PTB-ERROR: SYNCHRONIZATION FAILURE!」が表示されます。Screen(’Preference', 'SkipSyncTests', 1)には動作しますが、コマンドウィンドウにはやはり「PTB-ERROR: SYNCHRONIZATION FAILURE!」が表示されます。

 同じtest0510のプログラムに対してWin8.1とWin10で動作の違いが生じる理由は何でしょうか。コマンドウィンドウにはASIOのことが触れられていますが、ASIOが関連あるのでしょうか(ちなみに、Win8.1にはASIOドライバーを入れていますが、Win10には入れていません)。

 Screen(’Preference', 'SkipSyncTests', 0)で動作するWin8.1で動作させるのがよいかと思いますが、こうしたことが起きる原因や対処方法についてご存知でしたら、アドバイスをいただけないでしょうか。お忙しいところに恐縮ですが、お手すきのときにでもご回答いただければと思います。よろしくお願いいたします。

久崎
 

黒木@九州大学

unread,
May 22, 2018, 2:42:37 AM5/22/18
to 心理学実験について話そう
久崎先生

2018年5月22日火曜日 11時57分07秒 UTC+9 takahiro hisazaki:

 同じtest0510のプログラムに対してWin8.1とWin10で動作の違いが生じる理由は何でしょうか。コマンドウィンドウにはASIOのことが触れられていますが、ASIOが関連あるのでしょうか(ちなみに、Win8.1にはASIOドライバーを入れていますが、Win10には入れていません)。

ASIOはかなり重要ではないかと思います。
過去に私が和訳した記事なのですが、以下をご参照ください。
サウンドカードがASIOに対応していて、適切なドライバーが入っていれば、音関係のエラーは消えるのではないかと思います。

Screen(’Preference', 'SkipSyncTests', 0)
については、OSも関係あるでしょうし、ビデオカードも関係があると思います。
個人的には、windows7のころが一番不具合なく動作していて、OSがアップグレードするにつれてSyncエラーが出るようになった気がします。
これはMacでも同じ傾向が見られます。

理想から言えば、windowsマシンにlinuxをインストールするのがいいらしいです。開発者が推奨しています。

私はwindows 10でPTBを動かしたことがないため、あまり情報を持っておりません。他の方から、何かコメントがあるとよいのですが・・・。
 

takahiro hisazaki

unread,
May 24, 2018, 9:19:44 PM5/24/18
to 心理学実験について話そう
黒木先生

 こんにちは、久崎です。ご連絡・ご教示いただき、ありがとうございます。

 ASIOについては、Win10PCにASIO4ALLを入れてみて、test0510の駆動状況を確認してみたいと思います。

 また、WinマシンにLinuxを入れることが推奨されているとのことですが、それはWindows Subsystem for Linuxとして導入するということでしょうか。Linuxでどのように駆動するのか試してみたいのですが、PTBオリジナルHPでも詳しい記述がありませんでした。初歩的な質問かもしれませんが、Linux導入についてご存知のことがございましたら、ご教示いただけると有難いです。重ね重ねのお尋ねで申し訳ありませんが、よろしくお願いいたします。

久崎

黒木@九州大学

unread,
Jun 4, 2018, 2:18:04 AM6/4/18
to 心理学実験について話そう
久崎先生

申し訳ありません、この件、お返事をするのを失念しておりました。
Windows Subsystem for Linuxではなく、Linux単体をインストールすることを想定していました。
(デュアルブートでもかまいません)
様々なLinuxがありますが、特にこだわりがなければ、ubuntuがお勧めです。

LinuxのインストールについてはPTBのサイトに詳細はないと思います。
どちらかというと「ubuntu インストール」などのキーワードで検索することをお勧めいたします。

takahiro hisazaki

unread,
Jun 20, 2018, 12:07:30 AM6/20/18
to 心理学実験について話そう
黒木先生

 お返事が遅れまして、申し訳ありません。
 Linuxのインストールについてご丁寧に教示いただき、ありがとうございます。試してみて、また困難が生じた際にはご相談に乗っていただければと思います。今後とも、どうぞよろしくお願いいたします。

久崎

takahiro hisazaki

unread,
Jun 23, 2018, 5:00:49 AM6/23/18
to 心理学実験について話そう
黒木先生

 お世話になります、久崎です。
 申し訳ありませんが、test0510のプログラム(下参照)について再度、ご確認とご助言をお願いしたく連絡いたしました。
 test0510のプログラムを駆動させてみて気になっているのが、次のことです。「while beepTime>time && keyOn==0」のループ内で、keyIsDown=1になった際に、keyOn=1によって本来上位ループの「while keyOn==0」からも抜けたいのですが、抜けることができずに「while beepTime>time && keyOn==0」終了後のドット表示が瞬間的に表示されてビープ音が発生してしまいます。よろしければ、そのようになるのかを先生のほうでもご確認いたただけないでしょうか。本来はドット表示をビープ音発生を通り越してプログラムを終了するような構成にしたいと思っています。そのようにするための構文や構文配置について、先生のほうでよいアイディアがございましたらご助言いただけないでしょうか。
 再度test0510のことでお尋ねして恐縮ではございますが、よろしくお願いいたします。

久崎

function test0510
% Clear the workspace and the screen
sca;
close all;
clearvars;
Screen('Preference', 'SkipSyncTests', 0);
InitializePsychSound(1);

black=[0 0 0];

KbName('UnifyKeyNames');
myKeyCheck;

[mainWindow,wRect]=Screen('OpenWindow',0);
[xCenter,yCenter]=RectCenter(wRect);
fixposition=[xCenter-10 yCenter-10 xCenter+10 yCenter+10];
sr = 44100;
dur = 1;
fr = 300;
beep = MakeBeep(fr, dur, sr); 
nrchannels=size(beep,1);
if nrchannels < 2
    beep = [beep; beep];
    nrchannels = 2;
end
pahandle = PsychPortAudio('Open');
PsychPortAudio('FillBuffer', pahandle, beep);

keyOn=0;i=0;
while keyOn==0%どのキーも押されていない間に以下のプログラムが進行
    time=0; start = GetSecs; rng('shuffle'); beepTime = 2*rand;
    Screen('FillRect',mainWindow);Screen('Flip', mainWindow);
    while beepTime>time && keyOn==0%音が出るまでのbeepTime時間を待機
        time=GetSecs-start;
        [keyIsDown, secs, keyCode] = KbCheck;
        if keyIsDown==1%待機中にどこかのキーが押されたらプログラム終了
            keyOn=1;
        end
    end%beepTimeの時間を過ぎたら中央にドットと音を提示
    i=i+1;%提示回数がカウントされる
    PsychPortAudio('start', pahandle, 1);%音の再生スタート(1秒間)
    Screen('FillOval',mainWindow,black,fixposition);%中央ドットの表示
    Screen('DrawText', mainWindow,[num2str(beepTime,3) 's'], xCenter*1.6, yCenter*1.8);%beepTimeの時間を表示
    Screen('DrawText', mainWindow,[num2str(i) 'times'], xCenter*0.1, yCenter*1.8);%提示回数の表示
    Screen('Flip', mainWindow);
    time1=0; start1=GetSecs;
    while 1>time1 && keyOn==0%音が提示される1秒間を待機
        time1=GetSecs-start1;
        [keyIsDown, secs, keyCode] = KbCheck;
        if keyIsDown==1%待機中にどこかのキーが押されたらプログラム終了
            keyOn=1;
        end
    end
    Screen('Flip', mainWindow);
end

%終了処理
sca;
Screen('CloseAll');

takahiro hisazaki

unread,
Jun 24, 2018, 1:27:20 PM6/24/18
to 心理学実験について話そう
黒木先生

 度々のメールで失礼します。久﨑です。
 先日ご相談のメールをいたしましたtest0510の不具合について、自分なりに以下のプログラムのとおりに修正してみました。自己解決したとみてよいか分かりませんが、ひとまず、「while beepTime>time && keyOn==0」のループ内で、keyIsDown=1になった際に、keyOn=1によって本来上位ループの「while keyOn==0」からも抜けるようになったことを自前のWIN10で確認できました。
 もしよろしければ、先生にも以下のプログラムをご確認いただけると助かります。そのうえで、何か不具合やより良い方向での修正がありましたらご教示いただけると幸いです。よろしくお願いいたします。

久﨑

function test0510
% Clear the workspace and the screen
sca;
close all;
clearvars;
Screen('Preference', 'SkipSyncTests', 0);
InitializePsychSound(1);
black=[0 0 0];
KbName('UnifyKeyNames');
myKeyCheck;
[mainWindow,wRect]=Screen('OpenWindow',0, [], [0 0 1366 768]);

[xCenter,yCenter]=RectCenter(wRect);
fixposition=[xCenter-10 yCenter-10 xCenter+10 yCenter+10];
sr = 44100;
dur = 1;
fr = 300;
beep = MakeBeep(fr, dur, sr);
nrchannels=size(beep,1);
if nrchannels < 2
    beep = [beep; beep];
    nrchannels = 2;
end
pahandle = PsychPortAudio('Open');
PsychPortAudio('FillBuffer', pahandle, beep);
keyOn=0;keyPress=0;i=0;
while keyPress==0%どのキーも押されていない間に以下のプログラムが進行
    time=0; start=GetSecs; rng('shuffle'); beepTime = 5*rand;

    Screen('FillRect',mainWindow);Screen('Flip', mainWindow);
    while beepTime>time&&keyOn==0%音が出るまでのbeepTime時間を待機
        time=GetSecs-start;
        [keyIsDown, secs, keyCode] = KbCheck;
        if keyIsDown==1%待機中にどこかのキーが押されたらプログラム終了
            keyOn=1;keyPress=1;
        end
    end%beepTimeの時間を過ぎたら中央にドットと音を提示
    if keyOn==0

        i=i+1;%提示回数がカウントされる
        PsychPortAudio('start', pahandle, 1);%音の再生スタート(1秒間)
        Screen('FillOval',mainWindow,black,fixposition);%中央ドットの表示
        Screen('DrawText', mainWindow,[num2str(beepTime,3) 's'], xCenter*1.6, yCenter*1.8);%beepTimeの時間を表示
        Screen('DrawText', mainWindow,[num2str(i) 'times'], xCenter*0.1, yCenter*1.8);%提示回数の表示
        Screen('Flip', mainWindow);
        time1=0; start1=GetSecs;
        while 1>time1&&keyOn==0%音が提示される1秒間を待機
            time1=GetSecs-start1;
            [keyIsDown, secs, keyCode] = KbCheck;
            if keyIsDown==1%待機中にどこかのキーが押されたらプログラム終了
                keyOn=1;keyPress=1;

            end
        end
        Screen('Flip', mainWindow);
    end
end

黒木@九州大学

unread,
Jun 24, 2018, 9:42:37 PM6/24/18
to 心理学実験について話そう
久崎先生

最後のプログラムで確かにご希望通りに動いているようですが、変数 keyPressは不要な気がします。
それから主旨から少しそれますが、プログラムの最後で、

PsychPortAudio('Close', pahandle);

を呼んだほうがよいです。Closeしないと例えばプログラムを連続して実行するときにエラーが生じそうです。


詳細は添付ファイルをご覧ください。

test0510d.m

takahiro hisazaki

unread,
Jun 30, 2018, 3:55:58 AM6/30/18
to 心理学実験について話そう
黒木先生

 返事が遅くなり失礼しました。
 上記ご助言いただき、ありがとうございました。不要な変数は排除して、プログラム終了時にPsychPortAudio('Close', pahandle)を呼ぶことについて了解しました。
 先生が送っていただいたtest0510dwをベースにしたプログラムで特に問題なく動いております。
 Linuxインストールについては、なかなか時間がなく、余裕のあるときに試したいと思います。
 ありがとうございます。

久崎
 

Reply all
Reply to author
Forward
0 new messages