adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.09k stars 1.21k forks source link

audiobusio.PDMIn.record hangs CPX (SAMD21) if a wav file has been played #4600

Closed kevinjwalters closed 2 years ago

kevinjwalters commented 3 years ago

I just noticed this on 6.2.0 on a CPX with fresh (20210413) libraries, mic.record() hangs in a reproducible way under some circumstances. I tried a few things based on my first discovery of this. It looks like playing a wav file to the speaker does it.

Adafruit CircuitPython 6.2.0 on 2021-04-05; Adafruit CircuitPlayground Express with samd21g18
>>>
>>> import board
>>> import audiobusio
>>> import array
>>> mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA,
...                        sample_rate=16000, bit_depth=16)
>>> NUM_SAMPLES = 160
>>> samples = array.array('H', [0] * NUM_SAMPLES)
>>> mic.record(samples, len(samples))
160
>>> mic.record(samples, len(samples))
160
>>> mic.record(samples, len(samples))
160
>>> mic.record(samples, len(samples))
160
>>> mic.record(samples, len(samples))
160
>>> from adafruit_circuitplayground import cp
>>> mic.record(samples, len(samples))
160
>>> mic.record(samples, len(samples))
160
>>> dir(cp)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "adafruit_circuitplayground/express.py", line 82, in _unsupported
NotImplementedError: This feature is not supported on Circuit Playground Express.
>>> mic.record(samples, len(samples))
160
>>> mic.record(samples, len(samples))
160
>>> import gc
>>> gc.collect() ; print(gc.mem_free())
12944
>>> gc.collect() ; print(gc.mem_free())
12944
>>> mic.record(samples, len(samples))
160
>>> mic.record(samples, len(samples))
160
>>> cp.play_file("num/one.wav")  ### 16k 16-bit short mono sample
>>> mic.record(samples, len(samples))  ### CIRCUITPY drive no longer works, serial console non-responsive

I see another issue with record() reported in #4261

sta-c0000 commented 3 years ago

Confirmed: Circuit Playground Express can now freeze/hang after using mic.record using: adafruit-circuitpython-circuitplayground_express-en_US-6.2.0.uf2

Also CircuitPlaygroundExpress_SoundMeter.py apparently no longer works for me now because only 32 samples are returned by mic.record() instead of the expected 160 (as explained in bug #4261), even then, after fixing that code for count, it's prone to freeze/hang later with more code, for example, adding this at the end now crashes the CPX when switch is moved to False (doesn't with 5.x):

    if not switch.value: # setup earlier as DigitalInOut(board.D7) with Direction.INPUT Pull.UP
        import supervisor
        supervisor.reload() # attempting to reload main.py

Power cycle or CPX reset button appear to be only way back.

dhalbert commented 2 years ago

This should be fixed by #5842.