Sound crackling under specific conditions (demo included)

Hi,

I’m using PsychoPy Standalone 1.90.2 on Windows 7 and working on an auditory experiment. However, I have long-standing issues with crackling noises on different hardware whenever I want to play two sounds simultaneously.

In the very simple minimal example I have attached, a wave file and a PsychoPy beep are played at the same time. Removing either the wave or the beep shows that they both work perfectly when isolated.
However, when the beep onset is between 0.22 and 0.61, an annoying crackling sound appears. For onsets <= 0.21 s and >= 0.62 s, there is no crackling.

In case it helps, I have visualized the wave file using Matlab:

Does anyone have an idea why this crackling occurs? Can you reproduce it?

And help would be greatly appreciated!

Best regards
Torge

https://global.discourse-cdn.com/flex020/uploads/psychopy/original/2X/6/6931148434f6233554499c993380cd74397413e5.wav Crackling_Demo.psyexp (5.7 KB)

I found out that the crackling does not occur if I set the audio library in the preferences to [u'pyo', u'pygame'] instead of the default [u'sounddevice', u'pyo', u'pygame', ].

However, using pyo, loops are randomly cancelled if I use condition files, and “the sounddevice library looks like the way of the future”, so it would be great to find a fix for the minimal example above. Does anyone have a clear sound here using the sounddevice library?

Moreover, I thought that maybe mixing a wave file with a PsychoPy tone might cause the problems due to different sound properties (e.g., sampling rate), which is why I created a simple 0.5 s beep using Matlab (see link below). If you replace the ‘A’ with ‘Beep.wav’ in the minimal example uploaded before, the crackling still occurs.

Added up like in PsychoPy with a beep onset of 0.5 s, the two waves look like this. I don’t see a problem (e.g., clipping) here:

Wave file:
https://global.discourse-cdn.com/flex020/uploads/psychopy/original/2X/2/2d3a292ff34a93a72a34cdfe56828df4019b7a1a.wav

Many, many thanks @matthias.geier for solving the problem in this pull request!

In PsychoPy3 Beta 11, the crackling can be fixed by changing line 192 in C:\Program Files (x86)\PsychoPy3\Lib\site-packages\psychopy\sound\backend_sounddevice.py from for thisSound in self.sounds: to for thisSound in self.sounds.copy():

In PsychoPy 2 1.90.2, however, this change (line 185 in this case) produces the following error:

From cffi callback <function callback_ptr at 0x1554F170>:
Traceback (most recent call last):
  File "C:\Program Files (x86)\PsychoPy2\lib\site-packages\sounddevice.py", line 1008, in callback_ptr
    return _wrap_callback(callback, data, frames, time, status)
  File "C:\Program Files (x86)\PsychoPy2\lib\site-packages\sounddevice.py", line 2773, in _wrap_callback
    callback(*args)
  File "C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy\sound\backend_sounddevice.py", line 185, in callback
    for thisSound in self.sounds.copy():
AttributeError: 'list' object has no attribute 'copy'

Hi @TorgeMS, yes if this fix is to be implemented in PsychoPy with Python 2, we may need some additional code, because list.copy() is only available in Python 3. You could instead try the following with a Python 2 module called “copy”. Insert import copy with the imports at the top of the file, and change line 185 to:

for thisSound in copy.copy(self.sounds):

This needs testing, but should work.

Hi @dvbridges,

thanks for your response. I changed line 185 as you said and included import copy before sound is imported in the script:

...
from __future__ import absolute_import, division
import copy
from psychopy import locale_setup, sound, gui, visual, core, data, event, logging, clock
...

However, Python 2 still returns

NameError: global name 'copy' is not defined

By the way, is the stable PsychoPy 2 still going to receive some fixes or are they all going into the PsychoPy 3 betas only?

@TorgeMS, I meant the fix just to be written for the backend_sounddevice.py file in PsychoPy. Did you write the code in an experiment file? If you do not have the copy module in your standalone distribution, you can add the module using these guidelines. Bear in mind, this will not be an officially tested version, so use with care.

Yes, I wrote it in the experiment file because I wanted to change the program files as little as possible. Is it necessary? The copy module is at C:\Program Files (x86)\PsychoPy2\Lib\copy.py, so I thought it should be found there.

@TorgeMS yes that was a fix for the PsychoPy source code. The copy module is not needed in your experiment code. If you are happy using PsychoPy3 Beta 11, then that may be a better option.

@dvbridges:
Looking at it now, I realize how obvious that was - I guess, it was a long day. :wink: The fix works well with PsychoPy 1.90.2 now, too.

Thanks a lot again!