Repository: psychopy/psychopy

Issue:
Overlapping recordings problem
I am having a problem with mic.record and mic.stop - I am currently on psychopy 1.81.00, but I have had the same problem in earlier versions. I have written some code which records until the participant hits a key, or until a time-limit is reached. I am getting occasional truncated recordings or zero-length recordings - these occur when I test the code myself, so it's not just the participants being trigger-happy. I think the problem occurs when the timer on some past recording runs out, it stops the current recording. So say you set a recording running with a limit of 10 seconds, send a mic.stop() after 5 seconds, then start a new recording, that new recording will be stopped after 5 seconds, when the timer on the original recording runs out - it doesn't seem to be quite as neat as that in practice, which is confusing, but you can see this in action with something like the following little program. How often to occurs depends on how unlucky you are, but if you run through the for loop 10-15 times you will get some truncated recordings. 

from psychopy import microphone,core,event, visual

def recording(window,trialNum,mic):
    print('recording ' + str(trialNum))
    mic.reset()
    instructionText = visual.TextStim(window, text='Count to five, then press space',color="black",pos=(0,0.0),wrapWidth=2)
    instructionText.draw()
    window.flip()
    mic.record(7,block=False,filename=str(trialNum)+'.wav') #start recording
    event.waitKeys(maxWait='inf', keyList=['space']) #wait for a space from participant
    core.wait(0.1) #so you can hear the click of the spacebar
    window.flip()
    mic.stop() #stop the mic
    core.wait(0.1) #to get a flicker between screens
# set up mic and window

microphone.switchOn(sampleRate=44100)
mic = microphone.AudioCapture()
myWin = visual.Window((800,600), allowGUI=True,color='white')
for t in range(100): #shouldn't need to do as many as 100 to get some truncated recordings!
    recording(myWin,t,mic)
microphone.switchOff()
core.quit()



Discussion:
I ran your example for 100 trials, and none of the resulting files were 0 bytes long. Overlapping recordings are not supported intentionally. In practice, I suggest that two recordings are not very close in time -- which I think you've done with the core.wait(0.1). Perhaps try making that separation a bit longer, perhaps 0.25s or even more.

If this solves it for you, please close the issue here on github. Otherwise leave open.

Ah, now I see you are not getting 0-length recordings, but shorter-than-expected on the following trial. This is more effort to try to detect, I did not attempt it.

You could also try adding an extra mic.stop within the loop. See if this helps:

```
for t in range(100): #shouldn't need to do as many as 100 to get some truncated recordings!
    recording(myWin,t,mic)
    mic.stop()
```

Great, that extra mic.stop() solves the truncated recordings (although I am not sure why). Many thanks!


Resolving patch:
diff --git a/psychopy/app/builder/components/microphone.py b/psychopy/app/builder/components/microphone.py
--- a/psychopy/app/builder/components/microphone.py
+++ b/psychopy/app/builder/components/microphone.py
@@ -70,7 +70,8 @@ def writeRoutineEndCode(self,buff):
             currLoop = self.exp._expHandler
 
         #write the actual code
-        buff.writeIndented("# check responses\n" %self.params)
+        buff.writeIndented("# %(name)s stop & responses\n" %self.params)
+        buff.writeIndented("%s.stop()  # sometimes helpful\n" % self.params['name'])
         buff.writeIndented("if not %(name)s.savedFile:\n"%self.params)
         buff.writeIndented("    %(name)s.savedFile = None\n" %(self.params))
         buff.writeIndented("# store data for %s (%s)\n" %(currLoop.params['name'], currLoop.type))


Test patch: