play the Audio file from a URL
Hi Mike,
first i would like to thank you for the code and explainations. I have request if you don't mind. can i play the WAV file from a URL insted of an SD card?
Yes. It is possible to play a WAV file from a URL. Here is some example code for an ESP32 with SPIRAM. Tested with MicroPython v1.20
#
# Purpose: plays a WAV file stored on GitHub using an I2S DAC
#
# Notes:
# 1. the example below works on an ESP32 with SPIRAM (WROVER module).
# 2. the example does not work on a generic ESP32 (WROOM module). urequests will
# fail with "OSError: [Errno 12] ENOMEM", which is a failure to allocate memory.
import time
import network
import urequests as requests
from machine import I2S
from machine import Pin
#
# WIFI connection information
#
# replace WIFI-SSID and WIFI-PASSWORD with access information for the WIFI network you will connect to
#
wifiSSID = "WIFI-SSID" # EDIT 1 - enter name of WiFi connection point
wifiPassword = "WIFI-PASSWORD" # EDIT 2 - enter WiFi password
#
# create an interface that can connnect to a WIFI network
#
wifi = network.WLAN(network.STA_IF)
#
# activate the WIFI interface
#
wifi.active(True)
#
# connect the ESP32 device to the WIFI network
#
wifi.connect(wifiSSID, wifiPassword)
time.sleep(1)
#
# wait until the ESP8266 has successfully connected to the WIFI network
#
while not wifi.isconnected():
pass
print('connected')
# ======= I2S CONFIGURATION =======
SCK_PIN = 33
WS_PIN = 25
SD_PIN = 32
I2S_ID = 0
BUFFER_LENGTH_IN_BYTES = 50000
# ======= I2S CONFIGURATION =======
# ======= AUDIO CONFIGURATION =======
WAV_FILE = "music-16k-16bits-mono.wav"
WAV_SAMPLE_SIZE_IN_BITS = 16
FORMAT = I2S.MONO
SAMPLE_RATE_IN_HZ = 16000
# ======= AUDIO CONFIGURATION =======
audio_out = I2S(
I2S_ID,
sck=Pin(SCK_PIN),
ws=Pin(WS_PIN),
sd=Pin(SD_PIN),
mode=I2S.TX,
bits=WAV_SAMPLE_SIZE_IN_BITS,
format=FORMAT,
rate=SAMPLE_RATE_IN_HZ,
ibuf=BUFFER_LENGTH_IN_BYTES,
)
wav_samples = bytearray(10000)
wav_samples_mv = memoryview(wav_samples)
# GitHub repository information
repo_owner = 'miketeachman'
repo_name = 'micropython-i2s-examples'
file_path = 'wav/'+WAV_FILE
# URL of the binary file on GitHub
url = f'https://raw.githubusercontent.com/{repo_owner}/{repo_name}/master/{file_path}'
# Retrieve the binary file from the URL using requests
response = requests.get(url, stream=True)
_ = response.raw.read(44) # advance to first byte of Data section in WAV file
# Check if the request was successful
if response.status_code == 200:
# play WAV file, continuously
while True:
num_read = response.raw.readinto(wav_samples_mv)
if num_read == 0:
# end of WAV file, loop back to start of WAV file
response.close()
response = requests.get(url, stream=True)
_ = response.raw.read(44) # advance to first byte of Data section in WAV file
else:
_ = audio_out.write(wav_samples_mv[:num_read])
else:
# Handle the error
print(f'Error retrieving binary file. Status code: {response.status_code}')
I keep getting errors on esp32 when executing audio_out()
connected
E (5662) I2S: Error malloc dma buffer
/home/micropython/esp-idf-v4.2/components/freertos/queue.c:1816 (vQueueDelete)- assert failed!
abort() was called at PC 0x400978e4 on core 1
Backtrace:0x40093f46:0x3ffccf40 0x400946ad:0x3ffccf60 0x400982be:0x3ffccf80 0x400978e4:0x3ffccff0 0x40169e39:0x3ffcd010 0x40169f91:0x3ffcd030 0x4016aa1a:0x3ffcd070 0x4016b3b5:0x3ffcd0e0 0x400d6c80:0x3ffcd120 0x400d6dd9:0x3ffcd1a0 0x400e20dd:0x3ffcd1d0 0x400e3eda:0x3ffcd1f0 0x400846c6:0x3ffcd210 0x400dd10a:0x3ffcd2b0 0x400e3eda:0x3ffcd2e0 0x400e3f02:0x3ffcd300 0x400f1ae7:0x3ffcd320 0x400f1eb7:0x3ffcd3b0 0x400d5e32:0x3ffcd3d0
ELF file SHA256: d0595d695c66ca30
And when this error doesnt happen then another one happens on requests.get()
Traceback (most recent call last):
File "main.py", line 108, in <module>
File "urequests.py", line 180, in get
File "urequests.py", line 76, in request
OSError: -202
Any ideas?
Which board are you using, and also what MicroPython release. thanks!
ESP32 v1.20.0 (2023-04-26) .bin
It seems like every time it tries to create audio_out it runs out of memory?
audio_out = I2S(
I2S_ID,
sck=Pin(SCK_PIN),
ws=Pin(WS_PIN),
sd=Pin(SD_PIN),
mode=I2S.TX,
bits=WAV_SAMPLE_SIZE_IN_BITS,
format=FORMAT,
rate=SAMPLE_RATE_IN_HZ,
ibuf=BUFFER_LENGTH_IN_BYTES,
)
E (6603) I2S: Error malloc dma buffer
/home/micropython/esp-idf-v4.2/components/freertos/queue.c:1816 (vQueueDelete)- assert failed!
abort() was called at PC 0x400978e4 on core 1
Backtrace:0x40093f46:0x3ffccf40 0x400946ad:0x3ffccf60 0x400982be:0x3ffccf80 0x400978e4:0x3ffccff0 0x40169e39:0x3ffcd010 0x40169f91:0x3ffcd030 0x4016aa1a:0x3ffcd070 0x4016b3b5:0x3ffcd0e0 0x400d6c80:0x3ffcd120 0x400d6dd9:0x3ffcd1a0 0x400e20dd:0x3ffcd1d0 0x400e3eda:0x3ffcd1f0 0x400846c6:0x3ffcd210 0x400dd10a:0x3ffcd2b0 0x400e3eda:0x3ffcd2e0 0x400e3f02:0x3ffcd300 0x400f1ae7:0x3ffcd320 0x400f1eb7:0x3ffcd3b0 0x400d5e32:0x3ffcd3d0
ELF file SHA256: d0595d695c66ca30
And the request has issues sometimes, its not always though.
response = requests.get(url, stream=True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "urequests.py", line 180, in get
File "urequests.py", line 76, in request
OSError: -202
So I removed the stream=True and it worked, but now it stopped working again.
Thanks!