miketeachman/micropython-i2s-examples

play the Audio file from a URL

CRCbary opened this issue · 4 comments

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}')