How to use coroutines to collect microphone and joystick responses simultaneously?
In my experiment participants are going to decide whether they have seen a light (or not). Answers are given by (a) moving a joystick or (b) talking into a microphone. I want the participants to give the joystick and microphone responses simultaneously. Accordingly, I need OS to assess the answers at the same time as well.
I have an inline script for joystick movement and voice detection...but how can I perform these two scripts simultaneously with OS?
It seems like like coroutines are the way to go. Unfortunately, I wasn't able to figure out how to implement my scripts.
For joystick movement detection I use:
import time import pygame pygame.init() joystick.__init__(self, device=0, joybuttonlist=None, timeout=None) running = True #down=no light seen, up=light seen t0 = time.time() while running: # get input position, timestamp = joystick.get_joyaxes(timeout=50000) if position > 0.8: joy_dir = "down" joy_rt = time.time() - t0 if var.stimulus_occ == "yes": joy_cor = 0 else: joy_cor = 1 running = False elif position < (-0.8): joy_dir = "up" joy_rt = time.time() - t0 if var.stimulus_occ == "yes": joy_cor = 1 else: joy_cor = 0 running = False else: print(joy_dir) print(joy_rt) print(joy_cor) print(position) print("done") var.joy_y = position var.direc = joy_dir var.rt = joy_rt var.cor=joy_cor
And the microphone works with:
import pyaudio import struct import math import time import wave sound_threshold = 0.3 timeout = 3 FORMAT = pyaudio.paInt16 SHORT_NORMALIZE = (1.0/32768.0) CHANNELS = 2 RATE = 44100 INPUT_BLOCK_TIME = 0.01 INPUT_FRAMES_PER_BLOCK = int(RATE*INPUT_BLOCK_TIME) CHUNK=1024 OUTPUT_FOLDER = "C:\\Users\\Admin\\Desktop\\2017_2018 Ian Masterarbeit\\Preparation\\1_Sound\\Sound_output\\" WAVE_OUTPUT_FILENAME = "sound_" + str(var.mic_part) + "_" + str(self.get("count_mic_tr_1_15")) + ".wav" FINAL_FILENAME=OUTPUT_FOLDER + str(WAVE_OUTPUT_FILENAME) def get_rms(block): """Get root mean square as a measure of loudness""" count = len(block)/2 format = "%dh" % (count) shorts = struct.unpack( format, block ) sum_squares = 0.0 for sample in shorts: n = sample * SHORT_NORMALIZE sum_squares += n*n return math.sqrt( sum_squares / count ) # Open the mic stream = pyaudio.PyAudio().open( format=FORMAT, channels=CHANNELS, rate=RATE, input=True, input_device_index=0, frames_per_buffer=INPUT_FRAMES_PER_BLOCK ) # record until sound or until timeout print("* recording") frames =  start_time = time.time() recording = True for i in range(0, int(RATE / CHUNK)): while recording: if time.time() - start_time >= timeout: mic_rt = timeout response = "no response found" recording = False try: block = stream.read(CHUNK) except IOError as e: print e loudness = get_rms(block) if loudness > sound_threshold: mic_rt = time.time() - start_time response = "response found" recording = False data = stream.read(CHUNK) frames.append(data) print(mic_rt) print(response) # Process the response var.rt = mic_rt var.response = response # Close the audio stream stream.stop_stream() stream.close() pyaudio.PyAudio().terminate() # safe audio input into wave file wf=wave.open(FINAL_FILENAME,'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(pyaudio.PyAudio().get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(b''.join(frames)) wf.close()
(Microphone script credit to Sebastiaan at http://forum.cogsci.nl/index.php?p=/discussion/1772/)
Appreciate your help!