我正在编码一个实验设计,我需要能够播放来自多个扬声器/声道的声音,然后让用户在他们认为声音来自某个扬声器/声道时按下相应的键。 (即:参与者认为声音来自扬声器4,因此请按键4)。我希望能够记录从播放声音到用户按下琴键所花费的时间。

当我从同一个应用程序播放声音时,我真的不想通过持续等待用户输入来锁定应用程序。我猜我可以将用户输入放在另一个线程上,但是实现此目的的最佳方法是什么?我显然不希望用户每次按键后都必须按Enter键。

我正在使用OSx和C。

最佳答案

以大纲的形式,您的代码将包含2个线程。在辅助线程iOS tone initiator中运行。在主线程中,有一个经过的计时器,一个包含键陷阱的while循环以及一个转义条件,由此可以在条件满足时退出该循环。

一些伪代码:(使用一些Windows功能进行概念说明)

int gRunning = 1;
//Initiate tone in a secondary thread
//initialize elapsed time keeper to start
while(gRunning)
{
    //Call key trap function here
    //if Key Hit, set gRunning == 0;
}
//Get elapsed time here
//Kill tone and secondary thread

int KeyTrap(void)
{
    //Write code here using GetAsyncKeyState() to check hits on relevant keys
    return "any key hit"
}


在实际的实现中可以使用以下功能:

short GetAsyncKeyState(int);




time_t clock()


GetAsyncKeyState()通常在控制台应用程序中使用,以允许监视或响应用户按键。如果函数成功,则返回值指定自上次调用GetAsyncKeyState以来是否按下了该键,以及该键当前是向上还是向下。如果设置了最高有效位,则该键处于按下状态;如果设置了最低有效位,则在上一次调用GetAsyncKeyState之后按下了该键。但是,您不应该依赖于此最后的行为。有关更多信息,请参见备注。

例如,要捕获何时按下“ k”或“ K”键(您可以将其中的一系列代码编写到“ keyHandler”函数中以获取多个键),然后在while循环内调用:

    state = GetAsyncKeyState('k');
    state1 = GetAsyncKeyState('K');
    if ((0x80000000 & state) ||
        (0x80000000 & state1))
    {
             //do something here
    }


clock()返回自程序开始执行以来发生的系统时钟周期数。时钟滴答声的数量可以包括其他进程使用的时间。要将时钟周期数转换为秒,请除以CLOCKS_PER_SEC以获得近似的毫秒数。

注意我的环境中的time.h定义CLOCKS_PER_SEC如下:

#if defined(_NI_unix_) || defined(_NI_sparc_)
#define CLOCKS_PER_SEC 1000000
#elif defined(_NI_mswin16_) || defined(_NI_mswin32_) || defined(_NI_mswin64_)
#define CLOCKS_PER_SEC 1000
#elif defined(_NI_mac_)
#define CLOCKS_PER_SEC 1


因此,对于Mac,使用clock()似乎您的最佳分辨率为1秒

另一个选择,这个选择提供毫秒级的分辨率:
GetLocalTime()

例如:

SYSTEMTIME s;
GetLocalTime(&s);
swprintf_s(buff, L"[%02d:%02d:%02d:%d]\t", s.wHour, s.wMinute, s.wSecond, s.wMilliseconds);


定义SYSTEMTIME的位置:

typedef struct _SYSTEMTIME {
    WORD wYear;
    WORD wMonth;
    WORD wDayOfWeek;
    WORD wDay;
    WORD wHour;
    WORD wMinute;
    WORD wSecond;
    WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;

10-07 21:57