Introduction¶
Driver for interacting and playing media files with the VS1053 audio codec over a SPI connection.
NOTE: This is not currently working for audio playback of files. Only sine wave test currently works. The problem is that pure Python code is currently too slow to keep up with feeding data to the VS1053 fast enough. There’s no interrupt support so Python code has to monitor the DREQ line and provide a small buffer of data when ready, but the overhead of the interpreter means we can’t keep up. Optimizing SPI to use DMA transfers could help but ultimately an interrupt-based approach is likely what can make this work better (or C functions built in to custom builds that monitor the DREQ line and feed a buffer of data).
Dependencies¶
This driver depends on:
Please ensure all dependencies are available on the CircuitPython filesystem. This is easily achieved by downloading the Adafruit library and driver bundle.
Installing from PyPI¶
On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally from PyPI. To install for current user:
pip3 install adafruit-circuitpython-vs1053
To install system-wide (this may be required in some cases):
sudo pip3 install adafruit-circuitpython-vs1053
To install in a virtual environment in your current project:
mkdir project-name && cd project-name
python3 -m venv .env
source .env/bin/activate
pip3 install adafruit-circuitpython-vs1053
Usage Example¶
See examples/sdfile_play.py.
Contributing¶
Contributions are welcome! Please read our Code of Conduct before contributing to help this project stay welcoming.
Documentation¶
For information on building library documentation, please check out this guide.
Table of Contents¶
Simple test¶
Ensure your device works with this simple test.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | # Example of sound playback from VS1053 FeatherWing. Can be modified to work
# with the breakout by changing the SD card and SPI pins mentioned below.
# NOTE:
# Unfortunately this doesn't work--the loop isn't fast enough to feed the VS1053
# data at the rate it needs for playback. You'll see very erratic behavior with
# the VS1053 making static, stopping, and eventually requiring a hard reset.
# We'll need to look into interrupt support perhaps to monitor DREQ like in the
# arduino library. Basic sine wave playback does however work and monitoring
# of attributes like status register and other VS1053 state is accessible.
import board
import busio
import digitalio
import storage
import adafruit_sdcard
import adafruit_vs1053
# Define pins connected to VS1053:
# For FeatherWing with Feather M0:
SDCS = board.D5 # Pin connected to SD card CS line.
MP3CS = board.D6 # Pin connected to VS1053 CS line.
DREQ = board.D9 # Pin connected to VS1053 DREQ line.
XDCS = board.D10 # Pin connected to VS1053 D/C line.
# Other configuration:
PLAYBACK_FILE = "/sd/test.wav" # Name of file to play.
# This should be the full path
# including /sd prefix if on
# sd card.
BUFFER_SIZE = 128 # Size in bytes of the MP3 data buffer for sending data to
# the VS1053.
# Setup SPI bus (hardware SPI).
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# Setup SD card and mount it in the filesystem.
sd_cs = digitalio.DigitalInOut(SDCS)
sdcard = adafruit_sdcard.SDCard(spi, sd_cs)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")
# To list all the files on the SD card root uncomment:
# import os
# print('SD card root contains:')
# print(os.listdir('/sd'))
# Setup VS1053.
vs1053 = adafruit_vs1053.VS1053(spi, MP3CS, XDCS, DREQ)
# Set volume of left and right channels.
# Value ranges from 0 to 255 for each channel, the lower the higher volume.
vs1053.set_volume(0, 0)
# Play a test tone (this works).
print("Playing test tone for two seconds...")
vs1053.sine_test(0x44, 2.0)
print("Done playing tone!")
# Play back a MP3 file by starting playback, then reading a buffer of data
# at a time and sending it to the VS1053.
# Unfortunately this doesn't work--the loop isn't fast enough to feed the VS1053
# data at the rate it needs for playback. You'll see very erratic behavior with
# the VS1053 making static, stopping, and eventually requiring a hard reset.
# We'll need to look into interrupt support perhaps to monitor DREQ like in the
# arduino library.
print("Playing {}...".format(PLAYBACK_FILE))
vs1053.start_playback()
with open(PLAYBACK_FILE, "rb") as infile:
music_data = infile.read(BUFFER_SIZE)
while music_data is not None and music_data != "":
while not vs1053.ready_for_data:
pass
vs1053.play_data(music_data, end=len(music_data))
music_data = infile.read(BUFFER_SIZE)
print("Done!")
|
adafruit_vs1053
¶
Driver for interacting and playing media files with the VS1053 audio codec over a SPI connection.
NOTE: This is not currently working for audio playback of files. Only sine wave test currently works. The problem is that pure Python code is currently too slow to keep up with feeding data to the VS1053 fast enough. There’s no interrupt support so Python code has to monitor the DREQ line and provide a small buffer of data when ready, but the overhead of the interpretor means we can’t keep up. Optimizing SPI to use DMA transfers could help but ultimately an interrupt-based approach is likely what can make this work better (or C functions built in to custom builds that monitor the DREQ line and feed a buffer of data).
- Author(s): Tony DiCola
Implementation Notes¶
Hardware:
- Adafruit Music Maker FeatherWing - Synth Player
- Music Maker FeatherWing w/ Amp - Synth Player
- VS1053B MP3/WAV/OGG/MIDI Player & Recorder (CODEC) Chip
- VS1053 Codec + MicroSD Breakout - Play + Record - v4
Software and Dependencies:
- Adafruit CircuitPython firmware for the supported boards: https://github.com/adafruit/circuitpython/releases
- Adafruit’s Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
-
class
adafruit_vs1053.
VS1053
(spi, cs, xdcs, dreq)¶ Class-level buffer for read and write commands.
-
byte_rate
¶ Return the bit rate in bytes per second (computed each second). Useful to know if a song is being played and how fast it’s happening.
-
decode_time
¶ Return the decode time register value. This is the amount of time the current file has been played back in seconds.
-
play_data
(data_buffer, start=0, end=None)¶ Send a buffer of file data to the VS1053 for playback. Make sure the ready_for_data property is True before calling!
-
ready_for_data
¶ Return True if the VS1053 is ready to accept data, false otherwise.
-
reset
()¶ Perform a longer full reset with clock and volume reset too.
-
set_volume
(left, right)¶ Set the volume of the left and right channels to the provided byte value (0-255), the lower the louder.
-
sine_test
(n, seconds)¶ Play a sine wave for the specified number of seconds. Useful to test the VS1053 is working.
-
soft_reset
()¶ Perform a quick soft reset of the VS1053.
-
start_playback
()¶ Prepare for playback of a file. After calling this check the ready_for_data property continually until true and then send in buffers of music data to the play_data function.
-
stop_playback
()¶ Stop any playback of audio.
-
version
¶ Return the status register version value.
-