bixb922 / umidiparser

MIDI file parser for Micropython, CircuitPython and Python
MIT License
27 stars 4 forks source link

CircuitPython Asyncio Support appears broken #1

Closed YurgenJurgensen closed 1 year ago

YurgenJurgensen commented 1 year ago

I'm trying to use this with Asyncio in CircuitPython on an RP2040-based Adafruit MacroPad and I'm getting import errors and/or attribute errors whenever I try to use any of the async features.

Seems like it's trying to import the Micropython version of Asyncio, and to install that alongside CircuitPython doesn't look very viable (as the dependancies aren't drop-in replacements). I hacked the module a bit to get it working with CircuitPython's asyncio and it doesn't seem like you need to make that many changes.

I don't know if this is doing it right, and it's not thoroughly tested as I'm not that familiar with how the module's internals work but this appears to run as intended, I think you just need to make all the async functions use ints everywhere and import asyncio instead of uasyncio:

(This deletes the try-except, which I think is necessary for some CircuitPython versions that can't support asyncio due to memory limitations, I only removed the block so that in my case it'd fail if I didn't have the correct deps installed.)

elif _implementation == "circuitpython": from micropython import const import asyncio time_sleep_us = lambda usec: time.sleep( usec/1_000_000 ) time_now_us = lambda: int(time.monotonic_ns() / 1_000) time_diff_us = lambda x, y: x - y asyncio_sleep_ms = lambda x: asyncio.sleep_ms( x )

bixb922 commented 1 year ago

Thanks for reporting! I'll look into this asap

bixb922 commented 1 year ago

I think I'll change that part as follows:

elif _implementation == "circuitpython":
    from micropython import const
    try:
        import asyncio
    except:
        pass
    time_sleep_us = lambda usec: time.sleep( usec/1_000_000 )
    time_now_us = lambda: (time.monotonic_ns()+500)//1_000
    time_diff_us = lambda x, y: x - y
    asyncio_sleep_ms = lambda x: asyncio.sleep_ms( x )

You are completely right about importing asyncio instead of uasyncio on Circuitpython. I tested now with on a RP 2020 "Adafruit CircuitPython 7.3.3 on 2022-08-29; Raspberry Pi Pico with rp2040". Since asyncio might not be installed, I left the try/except.

I have tried to avoid floating point so I put a integer division with rounding instead. The code you proposed should also work.

I ran the regression tests and it seems to work fine. I added the asyncio tests for cp.

bixb922 commented 1 year ago

Is it working well now for you?

YurgenJurgensen commented 1 year ago

Works now, but the version in the commit has "ttime_now_us" instead of "time_now_us". Fixing that typo fixes everything.

bixb922 commented 1 year ago

Thanks so much for pointing that out!! Now corrected.