Clavier OSx appuie sur C

Je suis en train de coder un modèle expérimental et je dois pouvoir jouer les sons de plusieurs haut-parleurs / canaux, puis demander à l’utilisateur d’appuyer sur la touche correspondante lorsqu’il pense que le son provient d’un certain haut-parleur / canal. (Par exemple, si le participant pense que le son provient du haut-parleur 4, appuyez sur la touche 4). Je veux pouvoir enregistrer le temps qu’il faut entre le son joué et le temps que l’utilisateur met à appuyer sur une touche.

Comme je joue des sons de la même application, je ne veux pas vraiment la verrouiller en attendant continuellement les entrées de l’utilisateur. J’imagine que je pourrais jeter les commentaires de l’utilisateur sur un autre sujet, mais quel est le meilleur moyen d’y parvenir? Je ne veux évidemment pas que l’utilisateur ait à appuyer sur Entrée après chaque pression sur une touche.

J’utilise OSx et C.

Sous forme de synopsis , votre code contiendra entre autres 2 fils. Exécuter dans un fil secondaire, un initiateur de tonalité iOS . Dans le thread principal, une timer écasting, une boucle while comprenant une interception de clé et une condition d’échappement, permettant de quitter la boucle lorsque la condition est remplie.

Quelques pseudo-codes: (utilisant certaines fonctions de Windows pour illustrer le concept)

 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" } 

Les fonctions suivantes pourraient être utilisées dans une implémentation réelle:

 short GetAsyncKeyState(int); 

et

 time_t clock() 

GetAsyncKeyState () est couramment utilisé dans les applications console pour permettre la surveillance ou la réponse aux touches de l’utilisateur. Si la fonction réussit, la valeur de retour spécifie si la touche a été enfoncée depuis le dernier appel à GetAsyncKeyState et si la clé est actuellement active ou inactive. Si le bit le plus significatif est défini, la clé est enfoncée et si le bit le moins significatif est défini, la touche a été enfoncée après le précédent appel à GetAsyncKeyState. Cependant, vous ne devriez pas compter sur ce dernier comportement; pour plus d’informations, voir les Remarques.

Par exemple, pour attraper quand la touche ‘k’ ou ‘K’ a été touchée (vous pouvez en coder une série dans une fonction “keyHandler” pour obtenir plusieurs clés), puis appelez dans une boucle while:

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

clock () Retourne le nombre de cycles d’horloge système qui ont eu lieu depuis le début de l’exécution du programme. Le nombre de ticks d’horloge peut inclure le temps utilisé par d’autres processus. Pour convertir le nombre de cycles d’horloge en secondes, divisez par CLOCKS_PER_SEC pour obtenir une approximation à la milliseconde près.

Remarque time.h dans mon environnement définit CLOCKS_PER_SEC comme suit:

 #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 

Donc, pour le Mac, il semble que votre meilleure résolution soit de 1 seconde avec clock()

Une autre option, celle-ci donnant une résolution en millisecondes:
GetLocalTime ()

par exemple:

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

Où SYSTEMTIME est défini:

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