micropython / micropython/micropython
Simple I2S streaming code only works for sample rates <22050
Open
Nobody has claimed this yet.
bug
port-esp32
- Dominant language
- C
- Stars
- 22.1k
- Forks
- 9k
- Avg merge
- 6d 4h
- Merged PRs (30d)
- 16
Description
notes:
- Using ESP32 and v1.21.0
- As for web.py I am using the great https://github.com/wybiral/micropython-aioweb
- As for queue.py I am using https://github.com/peterhinch/micropython-async/blob/master/v3/primitives/queue.py
from machine import I2S
from machine import Pin
import web
import asyncio
from queue import Queue
bck_pin = Pin(33) # Bit clock output
ws_pin = Pin(32) # Word clock output
sdin_pin = Pin(25) # Serial data input
au_chunk_len = 8192
au_chunks = 8 # must be power of 2
audio_in = I2S(1, # create I2S peripheral to read audio
sck=bck_pin, ws=ws_pin, sd=sdin_pin, # sample data from an INMP441
mode=I2S.RX,
bits=32,
format=I2S.MONO,
rate=8000,
ibuf=au_chunk_len)
sreader = asyncio.StreamReader(audio_in)
queue = Queue(au_chunks)
async def produce():
print("Running produce()")
#ring buffer
dma_buffer = memoryview(bytearray(au_chunk_len*au_chunks))
f=0
while True:
b = dma_buffer[f*au_chunk_len:(f+1)*au_chunk_len]
t = au_chunk_len
while t>0:
t -= await sreader.readinto(b[au_chunk_len-t:])
await queue.put(b)
f= (f+1)&(au_chunks-1)
app = web.App(host='0.0.0.0', port=80)
@app.route('/')
async def scan_network_handler(r, w):
w.write(b'HTTP/1.0 200 OK\r\n')
w.write(b'Content-Type: application/octet-stream\r\n')
w.write(b'\r\n')
# empty queue
for i in range(au_chunks):
_ = await queue.get()
for i in range(30):
print(f"c {i}, {queue.qsize()}")
samples = await queue.get()
w.write(samples)
await w.drain()
# Start event loop and create server task
loop = asyncio.get_event_loop()
loop.create_task(app.serve())
loop.create_task(produce())
loop.run_forever()
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the provided ESP32 I2S reproducer and compare its streaming behavior across the reported sample rates. Read the I2S and asyncio stream interfaces used by the example, then determine what evidence is needed to reproduce the failure. Done means the same streaming example works reliably at rates below and above 22050.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- audio-video-rtc, embedded-iot
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100