Hi Bai,
FlushEvents may sound promising, but isn't it possible that it would accidentally flush away mouse clicks/keypresses you don't want it to?
I agree with you that the reason might be the way your program waits for the mouse to release: If you release a button and then press a button within the time " timeQueue=[timeQueue GetSecs];"
is executed, then the program would think you have never released the button and will wait until this button is released for the second time. Thus, one button click would be missed. Unfortunately, "
timeQueue=[timeQueue GetSecs];" is not a very effective way to construct arrays. It will take longer and longer to run this line since the size of 'timeQueue' is ever increasing, and therefore you
have greater danger of missing button clicks.
My idea is that don't wait for the key to press/release(the 'blocking' way). Use the 'unblocking' way to keep polling as frequently as possible, and store the current status of the button in an 'event array' . If the button is down at the time of query, then add the current time to the end of the event array; If unpressed, add '0'. In the end, the event array would look like:
000000 6e4 6.1e4 6.2e4 00000000 7e4 7.1e4 0000000000 8.3e4 8.4e4 0000000...
And the number of non-zero clusters (such as '6e4 6.1e4 6.2e4') would equal that of the mouse clicks.
The following is a demonstration of my idea:
% ------ MouseClickTester.m ---------
NUM_MAX_EVENTS = 1000000
event_array = zeros(NUM_MAX_EVENTS, 1);
% Make it as big as possible
i = 0;
duration = 10
startTime = GetSecs;
while 1
[x,y,buttons]=GetMouse;
i = i + 1;
event_array(i) = any(buttons).*GetSecs;
if GetSecs - startTime > duration
break;
end
end
% convert the event array to logical
event_binary = logical(event_array);
% Right shift event_binary by 1 element to make a mask
event_mask = ~[false event_binary(1:end-1)];
% select only the first timestamp of each non-zero cluster
event_stamps = event_binary & event_mask;
% Get the actual timestamps (the onset time of the clicks)
timeQueue = event_array(event_stamps);
%---- End of MouseClickTester.m --------
It works perfectly on my machine. The only problem is that it takes too much memory while running.
Hope that helps
Matthias
--- In psychtoolbox@yahoogroups.com, "bai.shui" <bai.shui@...> wrote:
>
> I'm trying to record a row of key presses/mouse clicks that occur during each trial.The interval between consecutive presses/clicks varies within a large range and can be as small as 150ms.I used the following lines to record clicks:
> while 1
>
> while ~any(buttons)
> [x,y,buttons]=GetMouse;
> end
>
> timeQueue=[timeQueue GetSecs];
>
> while any(buttons)
> [x,y,buttons]=GetMouse;
> end
>
> end
> But clicks were frequently missed and the same occured when key presses were collected. Would anyone here help me work around this?
>
> As I guess, the problem might lie in the part I designed to wait for mouse release before next enquiry. Is there a better way to do this?For example, what if FlushEvents command is used instead of the while loop? Thanks go to anyone who might help.
>