我正在编写一个实验性设计,我需要能够播放来自多个扬声器/声道的声音,然后让用户在相信声音来自某个扬声器/声道时按下相应的键。 (即:参与者认为声音来自扬声器4,因此按键4)。我希望能够记录正在播放的声音和用户按键所需的时间。
当我在同一个应用程序中播放声音时,我并不想通过不断等待用户输入来锁定应用程序。我猜我可以在另一个线程上抛出用户输入但是实现这个目的的最佳方法是什么?我显然不希望用户在每次按键后都按Enter键。
我正在使用OSx和C.
答案 0 :(得分:0)
在概要表格 中,您的代码将包含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' key已命中,(你可以将一系列密码编码到" 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()
另一个选择,这个选项给出毫秒分辨率:
的 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;