Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

Sound recording with sound.Microphone()

edited December 2022 in OpenSesame

Hi all,

I was wondering if anyone has found a good solution for sound recording in the latest versions of OpenSesame. The sound_recorder plugin does not really seem to be an option anymore.

I did try the sound.Microphone() function from psychopy. Using the Opensesame 3.3.12 megapack for windows build, I can record sounds using this function, but the terminal keeps throwing errors (notably, from the moment the recording starts):

PsychPortAudio('Close' [, pahandle]); Error in function Close: Usage error

Even after the experiment has finished and closed. The terminal then also does not get released anymore.

I tried all the available backends with the various sound driver options, but got the same results each time. This issue occurs on multiple win10 computers. Interestingly, if I just run the code from the terminal directly (or in Rapunzel) everything goes fine, and no errors are thrown. Only if the experiment is actually run does the problem occur.

I tried updating the psychopy library to the latest stable version, this did remove the warnings in the terminal, but still the terminal does not get released after the experiment finishes and the whole GUI get extremely slow and buggy.

I'm also very open for alternative methods. I did see some ideas for different implementations floating around on the forum, but no worked-out recent examples.

from psychopy import sound

def my_cleanup_function():

print(u'Closing mic')

mic.close()

register_cleanup_function(my_cleanup_function)

# parameters

micPref = "Microphone (Logitech Webcam C930e)" # preffered mic name

recTime = 20 # expected recording time in seconds


#check which devices are available

myDev = sound.Microphone.getDevices()



#check if any are found

if not myDev: raise Exception("No microphones present, please check hardware")


# find the preferred mic or if not present, any available mic

anySet = False

for idx, x in enumerate(myDev):

if x.deviceName == micPref or anySet == False:

micIdx = idx

anySet = True


# raise warning if the preferred mic is not found

if micPref != myDev[micIdx].deviceName:

warnings.warn(f"Warning preferred mic not found, instead using: {myDev[micIdx].deviceName}")

#set the recording buffer to be large enough

recBuffer = .010 * recTime * myDev[micIdx].defaultSampleRate * myDev[micIdx].inputChannels


# open the microphone (do this only once per study)

mic = sound.Microphone(device=myDev[micIdx].deviceIndex,channels =myDev[micIdx].inputChannels,streamBufferSecs=10, maxRecordingSize=recBuffer,sampleRateHz=myDev[micIdx].defaultSampleRate,audioRunMode = 1, audioLatencyMode = 3)


mic.start() # start recording


clock.sleep(2000)

mic.stop() # stop recording


audioClip = mic.getRecording()


print(audioClip.duration) # should be ~10 seconds

audioClip.save("test.wav') # save the recorded audio as a 'wav' file


mic.close()


Comments

  • UPDATE:

    So I tried implementing the sounddevice method instead, and was getting very similar results: it records the file but the experiment take a long time to close up to 2 minutes (i.e. the editor stays greyed out) even with just a 5 second sound file. Notably, the sound file is already saved and available before the experiment has closed properly. Once it has closed the terminal will then also still stay unresponsive for up to a minute or 2. I also tried removing the clean up function, but this didn't seem to make a difference.


    import sounddevice as sd
    
    import warnings
    
    import datetime
    
    from scipy.io.wavfile import write
    
    
    
    
    # make sure any open mic stream is closed on exit
    
    # def my_cleanup_function():
    
    # print(u'Closing mic')
    
    # #sd.stop()
    
    
    
    
    # register_cleanup_function(my_cleanup_function)
    
    
    
    
    # parameters
    
    micPref = "Microphone Array (Intel® Smart , MME (4 in, 0 out)" # preffered mic name
    
    duration = 5 # expected recording time in seconds
    
    
    
    
    #check which devices are available
    
    myDev = sd.query_devices()
    
    
    
    
    #check if any are found
    
    if not myDev: raise Exception("No microphones present, please check hardware")
    
    
    
    
    # find the preferred mic or if not present, any available mic
    
    anySet = False
    
    for idx, x in enumerate(myDev):
    
    if x['name'] == micPref or (anySet == False and x['name'].find('Microphone') > -1):
    
    micIdx = idx
    
    anySet = True
    
    
    
    
    # raise warning if the preferred mic is not found
    
    if micPref != myDev[micIdx]['name']:
    
    warnings.warn(f"Warning preferred mic not found, instead using: {myDev[micIdx]['name']}")
    
    # set default parameters based on device
    
    sd.default.samplerate = myDev[micIdx]['default_samplerate']
    
    sd.default.channels = min(myDev[micIdx]['max_input_channels'],4)
    
    sd.default.device = myDev[micIdx]['name']
    
    
    
    
    # start recording
    
    myrecording = sd.rec(int(duration * sd.default.samplerate))
    
    # wait for recording to finish
    
    sd.wait()
    
    # write recording to file
    
    write(f'C:\\Users\\olferskjf\\{datetime.datetime.now():%Y-%m-%d %H:%M}.wav', int(sd.default.samplerate), myrecording) # Save as WAV file
    
    # close to be sure
    
    sd.stop()
    
    print(sd.get_status())
    


  • edited December 2022

    Hi kolfers,

    I used this code:

    import sounddevice as sd
    from scipy.io.wavfile import write
    
    fs = 44100  # Sample rate
    seconds = 3  # Duration of recording
    
    myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=2)
    sd.wait()  # Wait until recording is finished
    write('output.wav', fs, myrecording)  # Save as WAV file 
    

    from this website, and it seems to work quite well. No unresponsiveness or anything alike. Perhaps you could use that?

    edit: I just see that you basically use the same approach in the second posting. Is the delay also present, if you don't do the extra bits related to selecting the correct device, that is, with this basic example here?

    If not, it might be related to your system? I used sounddevice version 0.4.1 on Ubuntu 18.

    Eduard

    Buy Me A Coffee

  • Hi Eduard,

    Thanks for checking in! The delay is also present with the default mic, and I can replicate it on my laptop (win10) with the internal or an external mic, and with desktop tower in the lab (also win10) which only has an external mic. So perhaps it's a Win10 / WASAPI issue.. I was on sounddevice '0.3.14' and tried again after updating to 0.4.5. If anything, it made the problem worse unfortunately, because now the rest of the machines starts locking up as well. Looking at task manager, I can see RAM used by Opensesame rapidly fluctuating between 800mb and 2-3 GB (this is with 1 editor open, after the experiment has finished, and I'm not interacting with it at all). It feels like some stream or buffer is not closed properly, but I don't know how to investigate this further. For instance sd.get_status() does seem to indicate that everything stopped properly.

    I ended up also trying the pyaudio approach (code below for anyone interesting). Notable, while it still took some time for the editor to become available after the experiment finished, the terminal was the also released at the same time, and there was no unresponsiveness or lag remaining in the interface .

    A drawback of the pyaudio approach does seem to be that the default way of recording blocks your script until it's finished (as opposed to the sounddevice and psychopy methods) .

    op

    import pyaudio
    
    import wave
    
    import warnings
    
    import datetime
    
    
    
    
    # make sure any open mic stream is closed on exit
    
    # def my_cleanup_function():
    
    # print(u'Closing mic')
    
    # #sd.stop()
    
    
    
    
    # register_cleanup_function(my_cleanup_function)
    
    
    
    
    # pyaudio parameters
    
    chunk = 1024 # Record in chunks of 1024 samples
    
    sample_format = pyaudio.paInt16 # 16 bits per sample
    
    p = pyaudio.PyAudio() # Create an interface to PortAudio
    
    
    
    
    
    
    
    # parameters
    
    micPref = "Microphone Array (Intel® Smart " # preffered mic name
    
    duration = 5 # expected recording time in seconds
    
    
    
    
    #check which devices are available
    
    info = p.get_host_api_info_by_index(0)
    
    if not info:
    
    raise Exception("No devices present, please check hardware")
    
    else:
    
    numdevices = info.get('deviceCount')
    
    
    
    
    anySet = False
    
    devTmp =[]
    
    for i in range(0, numdevices):
    
    if (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:
    
    devTmp = p.get_device_info_by_host_api_device_index(0, i)
    
    print("Input Device id ", i, " - ", devTmp['name'])
    
    if devTmp['name'] == micPref or anySet == False:
    
    anySet = True
    
    myDev = devTmp
    
    if not myDev: raise Exception("No microphone present, please check hardware")
    
    
    
    
    if myDev['name']!= micPref:
    
    warnings.warn(f'preferred mic not found, instead using {myDev["name"]}')
    
    
    
    
    print('Stream open')
    
    
    
    
    stream = p.open(format=sample_format,
    
    channels=myDev['maxInputChannels'],
    
    rate=int(myDev['defaultSampleRate']),
    
    frames_per_buffer=chunk,
    
    input=True)
    
    
    
    
    
    
    
    # Store data in chunks for 3 seconds
    
    frames = []
    
    for i in range(0, int(myDev['defaultSampleRate'] / chunk * duration)):
    
    data = stream.read(chunk)
    
    frames.append(data)
    
    
    
    
    # Stop and close the stream
    
    stream.stop_stream()
    
    stream.close()
    
    # Terminate the PortAudio interface
    
    p.terminate()
    
    
    
    
    
    
    
    print('Finished recording')
    
    
    
    
    # Save the recorded data as a WAV file
    
    wf = wave.open(f'C:\\Users\\olferskjf\\test - {datetime.datetime.now():%Y-%m-%d %H-%M}.wav', 'wb')
    
    wf.setnchannels(myDev['maxInputChannels'])
    
    wf.setsampwidth(p.get_sample_size(sample_format))
    
    wf.setframerate(myDev['defaultSampleRate'])
    
    wf.writeframes(b''.join(frames))
    
    wf.close()
    
    
    
    
    
    
    
    
Sign In or Register to comment.

agen judi bola , sportbook, casino, togel, number game, singapore, tangkas, basket, slot, poker, dominoqq, agen bola. Semua permainan bisa dimainkan hanya dengan 1 ID. minimal deposit 50.000 ,- bonus cashback hingga 10% , diskon togel hingga 66% bisa bermain di android dan IOS kapanpun dan dimana pun. poker , bandarq , aduq, domino qq , dominobet. Semua permainan bisa dimainkan hanya dengan 1 ID. minimal deposit 10.000 ,- bonus turnover 0.5% dan bonus referral 20%. Bonus - bonus yang dihadirkan bisa terbilang cukup tinggi dan memuaskan, anda hanya perlu memasang pada situs yang memberikan bursa pasaran terbaik yaitu http://45.77.173.118/ Bola168. Situs penyedia segala jenis permainan poker online kini semakin banyak ditemukan di Internet, salah satunya TahunQQ merupakan situs Agen Judi Domino66 Dan BandarQ Terpercaya yang mampu memberikan banyak provit bagi bettornya. Permainan Yang Di Sediakan Dewi365 Juga sangat banyak Dan menarik dan Peluang untuk memenangkan Taruhan Judi online ini juga sangat mudah . Mainkan Segera Taruhan Sportbook anda bersama Agen Judi Bola Bersama Dewi365 Kemenangan Anda Berapa pun akan Terbayarkan. Tersedia 9 macam permainan seru yang bisa kamu mainkan hanya di dalam 1 ID saja. Permainan seru yang tersedia seperti Poker, Domino QQ Dan juga BandarQ Online. Semuanya tersedia lengkap hanya di ABGQQ. Situs ABGQQ sangat mudah dimenangkan, kamu juga akan mendapatkan mega bonus dan setiap pemain berhak mendapatkan cashback mingguan. ABGQQ juga telah diakui sebagai Bandar Domino Online yang menjamin sistem FAIR PLAY disetiap permainan yang bisa dimainkan dengan deposit minimal hanya Rp.25.000. DEWI365 adalah Bandar Judi Bola Terpercaya & resmi dan terpercaya di indonesia. Situs judi bola ini menyediakan fasilitas bagi anda untuk dapat bermain memainkan permainan judi bola. Didalam situs ini memiliki berbagai permainan taruhan bola terlengkap seperti Sbobet, yang membuat DEWI365 menjadi situs judi bola terbaik dan terpercaya di Indonesia. Tentunya sebagai situs yang bertugas sebagai Bandar Poker Online pastinya akan berusaha untuk menjaga semua informasi dan keamanan yang terdapat di POKERQQ13. Kotakqq adalah situs Judi Poker Online Terpercayayang menyediakan 9 jenis permainan sakong online, dominoqq, domino99, bandarq, bandar ceme, aduq, poker online, bandar poker, balak66, perang baccarat, dan capsa susun. Dengan minimal deposit withdraw 15.000 Anda sudah bisa memainkan semua permaina pkv games di situs kami. Jackpot besar,Win rate tinggi, Fair play, PKV Games