SparkFun Top pHAT Hookup Guide
WM8960 Audio Codec
Getting the audio components up an operational involves two steps; installing the driver for the WM8960 audio codec and configuring the default sound card in the OS. We will be following the installation instructions from Waveshare for their Audio HAT.
Audio Codec Driver
To install the driver for the WM8960 audio codec, enter the following lines into the terminal or CLI.
language:bash
git clone https://github.com/waveshare/WM8960-Audio-HAT
cd WM8960-Audio-HAT
sudo ./install.sh
sudo reboot
If the installation is done properly, the output in the terminal should look like this:
language:bash
pi@raspberrypi:~ $ git clone https://github.com/waveshare/WM8960-Audio-HAT
Cloning into 'WM8960-Audio-HAT'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 51 (delta 0), reused 0 (delta 0), pack-reused 48
Unpacking objects: 100% (51/51), done.
pi@raspberrypi:~ $ cd WM8960-Audio-HAT
pi@raspberrypi:~ $ sudo ./install.sh
pi@raspberrypi:~/WM8960-Audio-HAT $ sudo ./install.sh
Get:1 http://archive.raspberrypi.org/debian stretch InRelease [25.4 kB]
Get:2 http://raspbian.raspberrypi.org/raspbian stretch InRelease [15.0 kB]
Get:3 http://archive.raspberrypi.org/debian stretch/main armhf Packages [220 kB]
Get:4 http://raspbian.raspberrypi.org/raspbian stretch/main armhf Packages [11.7 MB]
Fetched 11.9 MB in 17s (699 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
52 packages can be upgraded. Run 'apt list --upgradable' to see them.
Reading package lists... Done
Building dependency tree
Reading state information... Done
raspberrypi-kernel is already the newest version (1.20190819~stretch-1).
raspberrypi-kernel-headers is already the newest version (1.20190819~stretch-1).
0 upgraded, 0 newly installed, 0 to remove and 52 not upgraded.
1 not fully installed or removed.
After this operation, 0 B of additional disk space will be used.
Setting up python-sense-emu (1.1) ...
Traceback (most recent call last):
File "/usr/bin/pycompile", line 35, in <module>
from debpython.version import SUPPORTED, debsorted, vrepr, \
File "/usr/share/python/debpython/version.py", line 24, in <module>
from ConfigParser import SafeConfigParser
ImportError: No module named 'ConfigParser'
dpkg: error processing package python-sense-emu (--configure):
subprocess installed post-installation script returned error exit status 1
Errors were encountered while processing:
python-sense-emu
E: Sub-process /usr/bin/dpkg returned an error code (1)
Reading package lists... Done
Building dependency tree
Reading state information... Done
dkms is already the newest version (2.3-2).
i2c-tools is already the newest version (3.1.2-3).
i2c-tools set to manually installed.
Suggested packages:
git-daemon-run | git-daemon-sysvinit git-doc git-el git-email git-gui gitk gitweb git-arch git-cvs git-mediawiki
git-svn
The following NEW packages will be installed:
libasound2-plugins
The following packages will be upgraded:
git
1 upgraded, 1 newly installed, 0 to remove and 51 not upgraded.
1 not fully installed or removed.
Need to get 3,462 kB of archives.
After this operation, 293 kB of additional disk space will be used.
Get:1 http://mirror.sjc02.svwh.net/raspbian/raspbian stretch/main armhf git armhf 1:2.11.0-3+deb9u5 [3,389 kB]
Get:2 http://mirror.sjc02.svwh.net/raspbian/raspbian stretch/main armhf libasound2-plugins armhf 1.1.1-1 [72.9 kB]
Fetched 3,462 kB in 1s (2,536 kB/s)
apt-listchanges: Reading changelogs...
(Reading database ... 141372 files and directories currently installed.)
Preparing to unpack .../git_1%3a2.11.0-3+deb9u5_armhf.deb ...
Unpacking git (1:2.11.0-3+deb9u5) over (1:2.11.0-3+deb9u4) ...
Selecting previously unselected package libasound2-plugins:armhf.
Preparing to unpack .../libasound2-plugins_1.1.1-1_armhf.deb ...
Unpacking libasound2-plugins:armhf (1.1.1-1) ...
Setting up python-sense-emu (1.1) ...
Traceback (most recent call last):
File "/usr/bin/pycompile", line 35, in <module>
from debpython.version import SUPPORTED, debsorted, vrepr, \
File "/usr/share/python/debpython/version.py", line 24, in <module>
from ConfigParser import SafeConfigParser
ImportError: No module named 'ConfigParser'
dpkg: error processing package python-sense-emu (--configure):
subprocess installed post-installation script returned error exit status 1
Setting up libasound2-plugins:armhf (1.1.1-1) ...
Setting up git (1:2.11.0-3+deb9u5) ...
Errors were encountered while processing:
python-sense-emu
E: Sub-process /usr/bin/dpkg returned an error code (1)
Creating symlink /var/lib/dkms/wm8960-soundcard/1.0/source ->
/usr/src/wm8960-soundcard-1.0
DKMS: add completed.
Kernel preparation unnecessary for this kernel. Skipping...
Building module:
cleaning build area....
make -j4 KERNELRELEASE=4.19.66-v7+ -C /lib/modules/4.19.66-v7+/build M=/var/lib/dkms/wm8960-soundcard/1.0/build............
cleaning build area....
DKMS: build completed.
snd-soc-wm8960:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/4.19.66-v7+/kernel/sound/soc/codecs/
snd-soc-wm8960-soundcard.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/4.19.66-v7+/kernel/sound/soc/bcm/
depmod....
DKMS: install completed.
Created symlink /etc/systemd/system/sysinit.target.wants/wm8960-soundcard.service → /lib/systemd/system/wm8960-soundcard.service.
------------------------------------------------------
Please reboot your raspberry pi to apply all settings
Enjoy!
------------------------------------------------------
pi@raspberrypi:~ $ sudo reboot
Driver Installation Verification
To verify that the audio driver installation was successful and the kernel was rebuilt, use the sudo dkms status
command in the terminal or CLI. Users should a response similar to:
language:bash
wm8960-soundcard, 1.0, 4.19.66-v7+, armv7l: installed
Playback Devices
For further verification, users can list the playback devices using the aplay -l
command in the terminal or CLI. Users should a response similar to:
language:bash
**** List of PLAYBACK Hardware Devices ****
card 0: wm8960soundcard [wm8960-soundcard], device 0: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 []
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA]
Subdevices: 7/7
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
card 1: ALSA [bcm2835 ALSA], device 1: bcm2835 IEC958/HDMI [bcm2835 IEC958/HDMI]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: ALSA [bcm2835 ALSA], device 2: bcm2835 IEC958/HDMI1 [bcm2835 IEC958/HDMI1]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 2: vc4hdmi [vc4-hdmi], device 0: MAI PCM vc4-hdmi-hifi-0 []
Subdevices: 1/1
Subdevice #0: subdevice #0
The important information users need to identify is the card number listed for the WM8960:
card 0:
wm8960soundcard [wm8960-soundcard], device 0: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 []
Capture Devices
For further verification, users can also list the capture devices using the arecord -l
command in the terminal or CLI. Users should a response similar to:
language:bash
**** List of CAPTURE Hardware Devices ****
card 0: wm8960soundcard [wm8960-soundcard], device 0: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 []
Subdevices: 1/1
Subdevice #0: subdevice #0
The important information users need to identify is the card number listed for the WM8960:
card 0:
wm8960soundcard [wm8960-soundcard], device 0: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 []
Test
To test that the speaker and microphone are working with the WM8960 audio codec, use the sudo arecord -f cd -D hw:0 | aplay -D hw:0
command in the terminal or CLI. This will cause the microphones to record and playback the audio to the mono speaker in real time. The entries for the hardware (hw:0
) should correspond with the card number for the playback and capture devices. Users can also use the following commands to record and play files:
- Record File:
sudo arecord -D hw:0 -f S32_LE -r 16000 -c 2 test.wav
- Play File:
sudo aplay -D hw:0 test.wav
Configure Default Sound Card
The last part of the installation process requires the default sound card to be configured, using the sudo alsamixer
command in the terminal or CLI. From the system menu, use the F6 key to list devices and note the number indicating the WM8960 sound card.
To modify and configure the default sound card, use the sudo nano /usr/share/alsa/alsa.conf
command in the terminal or CLI. In the alsa.conf
file, users will modify the following lines to the number indicating the WM8960 sound card device value:
language:bash
defaults.ctl.card 0
defaults.pcm.card 0
defaults.pcm.device 0
Note: Users may need to test the values for defaults.pcm.device
between with 0 or 1. If they run into the following error:
ALSA lib pcm_dmix.c:1108:(snd_pcm_dmix_open) unable to open peripheral
Traceback (most recent call last):
File "playwav.py", line 59, in
device = alsaaudio.PCM(device="default")
alsaaudio.ALSAAudioError: No such file or directory [default]
when running the Python playback code sudo python playwav.py test2.wav
in the examples below.
Once these modifications have been made, users should go back an verify that the modifications have taken effect, using the sudo alsamixer
command in the terminal or CLI.
Python Examples
In order to use the Python examples provided by Waveshare, users will need to install the libasound2-dev
ALSA library and the pyalsaaudio
Python package.
- ALSA Library:
sudo apt-get install libasound2-dev
- Python Package:
sudo pip3 install pyalsaaudio
Users will need to download example code from the Waveshare website and extract the files:
language:bash
wget https://www.waveshare.com/w/upload/1/19/WM8960_Audio_HAT_Code.tar.gz
tar -xzf WM8960_Audio_HAT_Code.tar.gz
Once extracted, users will need to change the directory into the extracted folder. There they can use the following sample codes to record and play .wav
files.
- Record to File:
sudo python3 recordwav.py test2.wav
- Play File:
sudo python3 playwav.py test2.wav
Note: Users may run into a type error, when running the Python playback code sudo python playwav.py test2.wav
:
Traceback (most recent call last):
File "playwav.py", line 61, in
play(device, f)
File "playwav.py", line 35, in play
device.setperiodsize(periodsize)
TypeError: integer argument expected, got float
The issue is in line 35 of the playwav.py
file, which needs to be modified to periodsize = int(f.getframerate() / 8)
.