-
Notifications
You must be signed in to change notification settings - Fork 2
/
demo_play_wav_hp.py
93 lines (82 loc) · 2.58 KB
/
demo_play_wav_hp.py
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
82
83
84
85
86
87
88
89
90
91
92
93
"""Demo play WAV from SD to headphones."""
# The MIT License (MIT)
# Copyright (c) 2022 Mike Teachman
# https://opensource.org/licenses/MIT
# Purpose: Play a WAV audio file out of a speaker or headphones
#
# - read audio samples from a WAV file on SD Card
# - write audio samples to an I2S amplifier or DAC module
# - the WAV file will play continuously in a loop until
# a keyboard interrupt is detected or the board is reset
#
# blocking version
# - the write() method blocks until the entire sample buffer is written
# to the I2S interface
import os
from machine import I2C, I2S, Pin, SPI # type: ignore
# from machine import SDCard # Teensy 4.1 Built-in SD Card
from sdcard import SDCard # Teensy 4.0 Audio adapter SD Card
from sgtl5000 import CODEC
spisd = SPI(0)
sd = SDCard(spisd, Pin(10), baudrate=10000000) # Teensy 4.0 Audio SD Card
# sd = SDCard(1) # Teensy 4.1: sck=45, mosi=43, miso=42, cs=44
os.mount(sd, "/sd")
# ======= I2S CONFIGURATION =======
SCK_PIN = 21
WS_PIN = 20
SD_PIN = 7
MCK_PIN = 23
I2S_ID = 1
BUFFER_LENGTH_IN_BYTES = 80000
# ======= AUDIO CONFIGURATION =======
WAV_FILE = "wav_music-44k-16bits-stereo.wav"
WAV_SAMPLE_SIZE_IN_BITS = 16
FORMAT = I2S.STEREO
SAMPLE_RATE_IN_HZ = 44100
audio_out = I2S(
I2S_ID,
sck=Pin(SCK_PIN),
ws=Pin(WS_PIN),
sd=Pin(SD_PIN),
mck=Pin(MCK_PIN),
mode=I2S.TX,
bits=WAV_SAMPLE_SIZE_IN_BITS,
format=FORMAT,
rate=SAMPLE_RATE_IN_HZ,
ibuf=BUFFER_LENGTH_IN_BYTES,
)
i2c = I2C(0, freq=400000)
codec = CODEC(0x0A, i2c)
codec.mute_dac(False)
codec.dac_volume(0.9, 0.9)
codec.headphone_select(codec.AUDIO_HEADPHONE_DAC)
codec.mute_headphone(False)
codec.volume(0.7, 0.7)
wav = open("/sd/{}".format(WAV_FILE), "rb")
_ = wav.seek(44) # advance to first byte of Data section in WAV file
# allocate sample array
# memoryview used to reduce heap allocation
wav_samples = bytearray(10000)
wav_samples_mv = memoryview(wav_samples)
# continuously read audio samples from the WAV file
# and write them to an I2S DAC
print("========== START PLAYBACK ==========")
try:
while True:
num_read = wav.readinto(wav_samples_mv)
# end of WAV file?
if num_read == 0:
# end-of-file, advance to first byte of Data section
_ = wav.seek(44)
else:
_ = audio_out.write(wav_samples_mv[:num_read])
except (KeyboardInterrupt, Exception) as e:
print("caught exception {} {}".format(type(e).__name__, e))
# cleanup
wav.close()
os.umount("/sd")
# sd.deinit() # Teensy 4.1 Built-in SD Card
spisd.deinit() # Teensy 4.0 Audio adapter SD Card
codec.deinit()
audio_out.deinit()
print("Done")