From 878cf4a06bf4e6e24cd67e485b5ec000779a88d5 Mon Sep 17 00:00:00 2001 From: Daniel Follent Date: Wed, 7 Feb 2018 13:35:09 +0000 Subject: [PATCH 01/10] Scripts to configure I2S --- README.md | 43 +++++++++- auto_install.sh | 15 ++++ loader/Makefile | 5 ++ loader/loader.c | 74 ++++++++++++++++ resources/asoundrc | 76 +++++++++++++++++ resources/panel | 173 ++++++++++++++++++++++++++++++++++++++ scripts/convert_times.py | 27 ++++++ scripts/i2s_i2c_setup.sh | 119 ++++++++++++++++++++++++++ snd_driver/Makefile | 5 ++ snd_driver/bclk_patch.txt | 14 +++ 10 files changed, 550 insertions(+), 1 deletion(-) create mode 100644 auto_install.sh create mode 100644 loader/Makefile create mode 100644 loader/loader.c create mode 100644 resources/asoundrc create mode 100644 resources/panel create mode 100755 scripts/convert_times.py create mode 100755 scripts/i2s_i2c_setup.sh create mode 100644 snd_driver/Makefile create mode 100644 snd_driver/bclk_patch.txt diff --git a/README.md b/README.md index 1f7d2b2..aa494e7 100644 --- a/README.md +++ b/README.md @@ -1 +1,42 @@ -# vocalfusion-stereo-setup +# xCORE VocalFusion Stereo Dev Kit on a Raspberry Pi + +The XMOS **xCORE VocalFusion Stereo Dev Kit** provides far-field voice capture using the XMOS XVF3500 voice processor. + +Combined with a Raspberry Pi, this kit allows you to quickly prototype and evaluate VocalFusion Stereo. + + +This repository provides a simple-to-use automated script to configure the Raspberry Pi to use the **xCORE VocalFusion Stereo Dev Kit** for audio. + +## Prerequisites +You will need: + +- **xCORE VocalFusion Stereo Dev Kit**: XK-VF3500-L33-AVS +- Raspberry Pi 3 +- Micro-USB power supply (min. 2A) +- MicroSD card (min. 16GB) +- Powered mono speaker with audio 3.5mm analogue plug +- Monitor with HDMI input +- HDMI cable +- Fast-Ethernet connection with internet connectivity + + +## Hardware and Raspberry Pi audio setup +Setup your hardware by following the **Hardware Setup** at: https://xmos.com/vocalfusion-stereo + +Full instructions on configuring the Raspberry Pi to use the **xCORE VocalFusion Stereo Dev Kit** are detailed in the **Getting Started Guide** available from: https://xmos.com/vocalfusion-stereo. + +Brief instructions and additional notes are below: + +1. Install Raspbian (Stretch) on the Raspberry Pi. + +2. Open a terminal on the Raspberry Pi and clone this respository: +`cd ~; git clone https://github.com/xmos/vocalfusion-stereo-setup` + +3. Run the installation script: `source ~/vocalfusion-stereo-setup/auto_install.sh` +Wait for the script to complete the installation. This can several minutes. + +4. Enter `sudo reboot` to reboot the Raspberry Pi and complete the audio setup. + +5. Enter `arecord -r 48000 -f S32_LE demo_test.wav` to run a demo recording. Press `Ctrl+C` stop recording at any time. + +Enter `aplay demo_test.wav` to play back the recording. diff --git a/auto_install.sh b/auto_install.sh new file mode 100644 index 0000000..0001ad3 --- /dev/null +++ b/auto_install.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +SCRIPTS_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"/scripts + +$SCRIPTS_DIR/i2s_i2c_setup-main.sh + + +if [ -e /usr/share/alsa/pulse-alsa.conf ] ; then + # Rename existing file + sudo mv /usr/share/alsa/pulse-alsa.conf /usr/share/alsa/pulse-alsa.conf.bak + sudo mv ~/.config/lxpanel/LXDE-pi/panels/panel ~/.config/lxpanel/LXDE-pi/panels/panel.bak +fi + + +echo To enable the i2s device, this pi must now be rebooted +echo type 'sudo reboot' below to do this diff --git a/loader/Makefile b/loader/Makefile new file mode 100644 index 0000000..e023675 --- /dev/null +++ b/loader/Makefile @@ -0,0 +1,5 @@ +obj-m := loader.o +KDIR := /lib/modules/$(shell uname -r)/build +PWD := $(shell pwd) +default: + $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules diff --git a/loader/loader.c b/loader/loader.c new file mode 100644 index 0000000..3c2b414 --- /dev/null +++ b/loader/loader.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include +/* +modified for linux 4.1.5 +inspired by https://github.com/msperl/spi-config +with thanks for https://github.com/notro/rpi-source/wiki +as well as Florian Meier for the rpi i2s and dma drivers + +to use a differant (simple-card compatible) codec +change the codec name string in two places and the +codec_dai name string. (see codec's source file) + +fmt flags are set for vanilla i2s with rpi as clock slave + +N.B. playback vs capture is determined by the codec choice +*/ + +void device_release_callback(struct device *dev) { /* do nothing */ }; + +static struct asoc_simple_card_info snd_rpi_simple_card_info = { + .card = "snd_rpi_simple_card", // -> snd_soc_card.name + .name = "simple-card_codec_link", // -> snd_soc_dai_link.name + .codec = "snd-soc-dummy", // -> snd_soc_dai_link.codec_name + .platform = "3f203000.i2s", + .daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, + .cpu_dai = { + .name = "3f203000.i2s", // -> snd_soc_dai_link.cpu_dai_name + .sysclk = 0 + }, + .codec_dai = { + .name = "snd-soc-dummy-dai", // -> snd_soc_dai_link.codec_dai_name + .sysclk = 0 + } +}; + +static struct platform_device snd_rpi_simple_card_device = { + .name = "asoc-simple-card", //module alias + .id = 0, + .num_resources = 0, + .dev = { + .release = &device_release_callback, + .platform_data = &snd_rpi_simple_card_info, // *HACK ALERT* + } +}; + +int hello_init(void) +{ + const char *dmaengine = "bcm2708-dmaengine"; //module name + int ret; + + ret = request_module(dmaengine); + pr_alert("request module load '%s': %d\n",dmaengine, ret); + ret = platform_device_register(&snd_rpi_simple_card_device); + pr_alert("register platform device '%s': %d\n",snd_rpi_simple_card_device.name, ret); + pr_alert("Hello World :)\n"); + return 0; +} + +void hello_exit(void) +{ + // you'll have to sudo modprobe -r the card & codec drivers manually (first?) + platform_device_unregister(&snd_rpi_simple_card_device); + pr_alert("Goodbye World!\n"); +} + +module_init(hello_init); +module_exit(hello_exit); +MODULE_DESCRIPTION("ASoC simple-card I2S setup"); +MODULE_AUTHOR("Plugh Plover"); +MODULE_LICENSE("GPL v2"); diff --git a/resources/asoundrc b/resources/asoundrc new file mode 100644 index 0000000..18ba436 --- /dev/null +++ b/resources/asoundrc @@ -0,0 +1,76 @@ +# +# The I2S hardware device. Refer to it by name as it will not always +# be the same card number in every system. +# +pcm.i2s_48k { + type hw + card sndrpisimplecar + device 0 + + # The device has fixed 32-bit samples + format S32_LE + + # The device runs at 48kHz + rate 48000 +} + +pcm.mix_i2s_48k { + type dmix + ipc_key 115 # Must be unique + slave { + pcm i2s_48k + } +} + +# +# Note that the name must contain "Master" for the task bar to find it +# +pcm.mix_vol { + type softvol + slave { + pcm mix_i2s_48k + } + control { + name "Playback" + card 0 + } +} + +pcm.snoop_i2s_48k { + type dsnoop + ipc_key 116 # Must be unique + slave { + pcm i2s_48k + } +} + +pcm.snoop_vol { + type softvol + slave { + pcm snoop_i2s_48k + } + control { + name "Record" + card 0 + } +} + +# +# Map the default audio playback and recording devices to the I2S device. +# - use plugs in order to support rate and format conversions. +# +pcm.!default { + type asym + playback.pcm { + type plug + slave { + pcm mix_vol + } + } + capture.pcm { + type plug + slave { + pcm snoop_vol + } + } +} diff --git a/resources/panel b/resources/panel new file mode 100644 index 0000000..0ea68e1 --- /dev/null +++ b/resources/panel @@ -0,0 +1,173 @@ +# lxpanel config file. Manually editing is not recommended. +# Use preference dialog in lxpanel to adjust config when you can. + +Global { + edge=top + allign=left + margin=0 + widthtype=percent + width=100 + height=36 + transparent=0 + tintcolor=#000000 + alpha=0 + autohide=0 + heightwhenhidden=2 + setdocktype=1 + setpartialstrut=1 + usefontcolor=0 + fontsize=12 + fontcolor=#ffffff + usefontsize=0 + background=0 + backgroundfile=/usr/share/lxpanel/images/background.png + iconsize=36 +} +Plugin { + type=space + Config { + Size=4 + } +} +Plugin { + type=menu + Config { + image=/usr/share/raspberrypi-artwork/launch.png + system { + } + separator { + } + item { + name=Run... + image=system-run + command=run + } + separator { + } + item { + name=Shutdown... + image=system-shutdown + command=logout + } + } +} +Plugin { + type=space + Config { + Size=8 + } +} +Plugin { + type=launchbar + Config { + Button { + id=lxde-x-www-browser.desktop + } + Button { + id=pcmanfm.desktop + } + Button { + id=lxterminal.desktop + } + Button { + id=wolfram-mathematica.desktop + } + Button { + id=wolfram-language.desktop + } + } +} +Plugin { + type=space + Config { + Size=8 + } +} +Plugin { + type=taskbar + expand=1 + Config { + tooltips=1 + IconsOnly=0 + ShowAllDesks=0 + UseMouseWheel=1 + UseUrgencyHint=1 + FlatButton=0 + MaxTaskWidth=200 + spacing=1 + GroupedTasks=0 + } +} +Plugin { + type=space + Config { + Size=2 + } +} +Plugin { + type=tray + Config { + } +} +Plugin { + type=bluetooth + Config { + } +} +Plugin { + type=space + Config { + Size=2 + } +} +Plugin { + type=dhcpcdui + Config { + } +} +Plugin { + type=space + Config { + Size=2 + } +} +#Plugin { +# type=volumealsabt +# Config { +# } +#} +Plugin { + type=space + Config { + Size=2 + } +} +Plugin { + type=cpu + Config { + ShowPercent=1 + Foreground=#a9a9a9a9a9a9 + Background=#d3d3d3d3d3d3 + } +} +Plugin { + type=dclock + Config { + ClockFmt=%R + TooltipFmt=%A %x + BoldFont=0 + IconOnly=0 + CenterText=0 + } +} +Plugin { + type=space + Config { + Size=2 + } +} +Plugin { + type=ejecter + Config { + } +} diff --git a/scripts/convert_times.py b/scripts/convert_times.py new file mode 100755 index 0000000..c4ba948 --- /dev/null +++ b/scripts/convert_times.py @@ -0,0 +1,27 @@ +#! /usr/bin/env python +import os +import sys +from pprint import pprint + +if len(sys.argv) < 2: + print "Please specify the times file" + sys.exit(1) + +times_file=sys.argv[1] + +with open(os.path.join(times_file), "r") as f: + lines = f.read().splitlines() + +results = [] +prev = 0 +for line in lines: + key, val = line.split(": ") + m, s = divmod((int(val) - prev), 60) + results.append("{}: {}m{}s".format(key, m, s)) + prev = int(val) + total = prev + +pprint(results) +m, s = divmod(prev, 60) +h, m = divmod(m, 60) +print("TOTAL: {}h{}m{}s".format(h, m, s)) diff --git a/scripts/i2s_i2c_setup.sh b/scripts/i2s_i2c_setup.sh new file mode 100755 index 0000000..dcf8895 --- /dev/null +++ b/scripts/i2s_i2c_setup.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash + +# Setup paths +SCRIPTS_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" +source $SCRIPTS_DIR/avs-config.sh + +# The working directory is the parent of the scripts +I2S_ROOT=$(dirname $SCRIPTS_DIR) + +# +# Define folders +# +pushd $(dirname "$0") > /dev/null +popd > /dev/null + +# +# Disable the built-in audio output so there is only one audio +# device in the system +# +sudo sed -i -e 's/dtparam=audio=on/#dtparam=audio=on/' /boot/config.txt + +# +# Enable the i2s device tree +# +sudo sed -i -e 's/#dtparam=i2s=on/dtparam=i2s=on/' /boot/config.txt + +# Add modules to enable the I2C Peripherals and Direct Memory Access +# Controller modules that the sound card driver depends on +sudo sh -c 'echo snd_soc_bcm2708 >> /etc/modules' +sudo sh -c 'echo snd_soc_bcm2708_i2s >> /etc/modules' +sudo sh -c 'echo bcm2708_dmaengine >> /etc/modules' + +# Download kernal source - this will take some time +cd $I2S_ROOT +sudo apt-get -y install bc +sudo apt-get -y install libncurses5-dev +if [ ! -d rpi-source ] ; then + git clone git://github.com/notro/rpi-source.git +fi +pushd $I2S_ROOT/rpi-source > /dev/null +python rpi-source --skip-gcc +popd > /dev/null + +# +# Build simple sound card driver +# Modify the driver source to have the correct BCLK ratio +# +pushd $I2S_ROOT/snd_driver > /dev/null +cp ~/linux/sound/soc/generic/simple-card.c ./asoc_simple_card.c +patch -p1 asoc_simple_card.c < bclk_patch.txt +make +popd > /dev/null + +# +# Build loader and insert it into the kernel +# +pushd $I2S_ROOT/loader > /dev/null +make +popd > /dev/null + +if [ -e ~/.asoundrc ] ; then + cp ~/.asoundrc ~/.asoundrc.bak + chmod a+w ~/.asoundrc +fi + +cp $I2S_ROOT/resources/asoundrc ~/.asoundrc +cp $I2S_ROOT/resources/panel ~/.config/lxpanel/LXDE-pi/panels/panel + +# +# Make the asoundrc file read-only otherwise lxpanel rewrites it +# as it doesn't support anything but a hardware type device +# +chmod a-w ~/.asoundrc + +# Apply changes +sudo /etc/init.d/alsa-utils restart + +# +# Create the script to run after each reboot and make the soundcard available +# +i2s_driver_script=$I2S_ROOT/resources/load_i2s_driver.sh +echo "cd $I2S_ROOT" > $i2s_driver_script +echo "sudo insmod loader/loader.ko" >> $i2s_driver_script + +# +# Configure the I2C - disable the default built-in driver +# +sudo sed -i -e 's/#\?dtparam=i2c_arm=on/dtparam=i2c_arm=off/' /boot/config.txt +sudo sh -c 'echo i2c-bcm2708 >> /etc/modules-load.d/modules.conf' +sudo sh -c 'echo "options i2c-bcm2708 combined=1" >> /etc/modprobe.d/i2c.conf' + +# +# Build a new I2C driver +# +cd $I2S_ROOT +git clone git://github.com/kadamski/i2c-gpio-param.git +pushd $I2S_ROOT/i2c-gpio-param > /dev/null +make +popd > /dev/null + +# +# Create script to insert module into the kernel +# +i2c_driver_script=$I2S_ROOT/resources/load_i2c_gpio_driver.sh + +echo "cd $I2S_ROOT/i2c-gpio-param" > $i2c_driver_script +echo "# Load the i2c bit banged driver" >> $i2c_driver_script +echo "sudo insmod i2c-gpio-param.ko" >> $i2c_driver_script +echo "# Instantiate a driver at bus id=1 on same pins as hw i2c with 1sec timeout" >> $i2c_driver_script +echo "sudo sh -c 'echo "1 2 3 5 100 0 0 0" > /sys/class/i2c-gpio/add_bus'" >> $i2c_driver_script +echo "# Remove the default i2c-gpio instance" >> $i2c_driver_script +echo "sudo sh -c 'echo 7 > /sys/class/i2c-gpio/remove_bus'" >> $i2c_driver_script + +# +# Setup the crontab to restart I2S/I2C at reboot +# +echo "@reboot sh $i2s_driver_script" > $I2S_ROOT/resources/crontab +echo "@reboot sh $i2c_driver_script" >> $I2S_ROOT/resources/crontab +crontab $I2S_ROOT/resources/crontab diff --git a/snd_driver/Makefile b/snd_driver/Makefile new file mode 100644 index 0000000..1bdea7c --- /dev/null +++ b/snd_driver/Makefile @@ -0,0 +1,5 @@ +obj-m := asoc_simple_card.o +KDIR := /lib/modules/$(shell uname -r)/build +PWD := $(shell pwd) +default: + $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules diff --git a/snd_driver/bclk_patch.txt b/snd_driver/bclk_patch.txt new file mode 100644 index 0000000..322e146 --- /dev/null +++ b/snd_driver/bclk_patch.txt @@ -0,0 +1,14 @@ +*************** static int asoc_simple_card_dai_init(str +*** 205,210 **** +--- 205,215 ---- + if (ret < 0) + return ret; + ++ ret = snd_soc_dai_set_bclk_ratio(cpu, 64); ++ if (ret < 0) ++ return ret; ++ pr_alert("BCLK ratio set to 64!\n"); ++ + return 0; + } + From 11a12aeca451745715a5fd978796fca770afe3a2 Mon Sep 17 00:00:00 2001 From: Daniel Follent Date: Wed, 7 Feb 2018 13:39:59 +0000 Subject: [PATCH 02/10] Removed convert_times.py, updated README --- README.md | 4 ++-- scripts/convert_times.py | 27 --------------------------- scripts/i2s_i2c_setup.sh | 1 - 3 files changed, 2 insertions(+), 30 deletions(-) delete mode 100755 scripts/convert_times.py diff --git a/README.md b/README.md index aa494e7..8e539e8 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This repository provides a simple-to-use automated script to configure the Raspb ## Prerequisites You will need: -- **xCORE VocalFusion Stereo Dev Kit**: XK-VF3500-L33-AVS +- **xCORE VocalFusion Stereo Dev Kit**: XK-VF3500-L33 - Raspberry Pi 3 - Micro-USB power supply (min. 2A) - MicroSD card (min. 16GB) @@ -39,4 +39,4 @@ Wait for the script to complete the installation. This can several minutes. 5. Enter `arecord -r 48000 -f S32_LE demo_test.wav` to run a demo recording. Press `Ctrl+C` stop recording at any time. -Enter `aplay demo_test.wav` to play back the recording. +6. Enter `aplay demo_test.wav` to play the recording. diff --git a/scripts/convert_times.py b/scripts/convert_times.py deleted file mode 100755 index c4ba948..0000000 --- a/scripts/convert_times.py +++ /dev/null @@ -1,27 +0,0 @@ -#! /usr/bin/env python -import os -import sys -from pprint import pprint - -if len(sys.argv) < 2: - print "Please specify the times file" - sys.exit(1) - -times_file=sys.argv[1] - -with open(os.path.join(times_file), "r") as f: - lines = f.read().splitlines() - -results = [] -prev = 0 -for line in lines: - key, val = line.split(": ") - m, s = divmod((int(val) - prev), 60) - results.append("{}: {}m{}s".format(key, m, s)) - prev = int(val) - total = prev - -pprint(results) -m, s = divmod(prev, 60) -h, m = divmod(m, 60) -print("TOTAL: {}h{}m{}s".format(h, m, s)) diff --git a/scripts/i2s_i2c_setup.sh b/scripts/i2s_i2c_setup.sh index dcf8895..51884eb 100755 --- a/scripts/i2s_i2c_setup.sh +++ b/scripts/i2s_i2c_setup.sh @@ -2,7 +2,6 @@ # Setup paths SCRIPTS_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" -source $SCRIPTS_DIR/avs-config.sh # The working directory is the parent of the scripts I2S_ROOT=$(dirname $SCRIPTS_DIR) From 0e80724d4ff5f51df40dc8d6ef1aec3e6a336143 Mon Sep 17 00:00:00 2001 From: Daniel Follent Date: Wed, 7 Feb 2018 13:42:01 +0000 Subject: [PATCH 03/10] Correction to file path --- auto_install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auto_install.sh b/auto_install.sh index 0001ad3..86ddaab 100644 --- a/auto_install.sh +++ b/auto_install.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash SCRIPTS_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"/scripts -$SCRIPTS_DIR/i2s_i2c_setup-main.sh +$SCRIPTS_DIR/i2s_i2c_setup.sh if [ -e /usr/share/alsa/pulse-alsa.conf ] ; then From 794999a766622b994dbb7ecaed5cff7c773497cd Mon Sep 17 00:00:00 2001 From: Daniel Follent Date: Mon, 12 Feb 2018 09:45:50 +0000 Subject: [PATCH 04/10] Updated the Readme --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8e539e8..cf914c1 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ The XMOS **xCORE VocalFusion Stereo Dev Kit** provides far-field voice capture u Combined with a Raspberry Pi, this kit allows you to quickly prototype and evaluate VocalFusion Stereo. - This repository provides a simple-to-use automated script to configure the Raspberry Pi to use the **xCORE VocalFusion Stereo Dev Kit** for audio. ## Prerequisites @@ -14,7 +13,7 @@ You will need: - Raspberry Pi 3 - Micro-USB power supply (min. 2A) - MicroSD card (min. 16GB) -- Powered mono speaker with audio 3.5mm analogue plug +- Powered stereo speakers with audio 3.5mm analogue plug - Monitor with HDMI input - HDMI cable - Fast-Ethernet connection with internet connectivity @@ -33,10 +32,8 @@ Brief instructions and additional notes are below: `cd ~; git clone https://github.com/xmos/vocalfusion-stereo-setup` 3. Run the installation script: `source ~/vocalfusion-stereo-setup/auto_install.sh` -Wait for the script to complete the installation. This can several minutes. +Wait for the script to complete the installation. This can take several minutes. 4. Enter `sudo reboot` to reboot the Raspberry Pi and complete the audio setup. -5. Enter `arecord -r 48000 -f S32_LE demo_test.wav` to run a demo recording. Press `Ctrl+C` stop recording at any time. - -6. Enter `aplay demo_test.wav` to play the recording. +You are now ready to start evaluating the VocalFusion Stereo Kit. From 964d623d6b9721508b408d4085e1397647bbb74e Mon Sep 17 00:00:00 2001 From: Daniel Follent Date: Mon, 12 Feb 2018 10:09:35 +0000 Subject: [PATCH 05/10] Extended control for asoundrc --- resources/asoundrc | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/resources/asoundrc b/resources/asoundrc index 18ba436..d6fe2c6 100644 --- a/resources/asoundrc +++ b/resources/asoundrc @@ -14,6 +14,12 @@ pcm.i2s_48k { rate 48000 } +ctl.i2s_48k { + type hw + card sndrpisimplecar + device 0 +} + pcm.mix_i2s_48k { type dmix ipc_key 115 # Must be unique @@ -22,6 +28,13 @@ pcm.mix_i2s_48k { } } +ctl.mix_i2s_48k { + type dmix + slave { + pcm i2s_48k + } +} + # # Note that the name must contain "Master" for the task bar to find it # @@ -44,6 +57,13 @@ pcm.snoop_i2s_48k { } } +ctl.snoop_i2s_48k { + type dsnoop + slave { + pcm i2s_48k + } +} + pcm.snoop_vol { type softvol slave { @@ -70,7 +90,26 @@ pcm.!default { capture.pcm { type plug slave { - pcm snoop_vol + pcm snoop_i2s_48k + } + } +} + +# +# Create the control interfaces +# +ctl.!default { + type asym + playback.pcm { + type plug + slave { + pcm mix_vol + } + } + capture.pcm { + type plug + slave { + pcm snoop_i2s_48k } } } From d21f1723b444dafb49b2d772a864f61d10bd28ba Mon Sep 17 00:00:00 2001 From: Daniel Follent Date: Mon, 12 Feb 2018 16:42:34 +0000 Subject: [PATCH 06/10] Changed order of backup. Change to asoundrc --- auto_install.sh | 5 ++--- resources/asoundrc | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/auto_install.sh b/auto_install.sh index 86ddaab..b408897 100644 --- a/auto_install.sh +++ b/auto_install.sh @@ -1,15 +1,14 @@ #!/usr/bin/env bash SCRIPTS_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"/scripts -$SCRIPTS_DIR/i2s_i2c_setup.sh - if [ -e /usr/share/alsa/pulse-alsa.conf ] ; then - # Rename existing file + # Back up existing files sudo mv /usr/share/alsa/pulse-alsa.conf /usr/share/alsa/pulse-alsa.conf.bak sudo mv ~/.config/lxpanel/LXDE-pi/panels/panel ~/.config/lxpanel/LXDE-pi/panels/panel.bak fi +$SCRIPTS_DIR/i2s_i2c_setup.sh echo To enable the i2s device, this pi must now be rebooted echo type 'sudo reboot' below to do this diff --git a/resources/asoundrc b/resources/asoundrc index d6fe2c6..3f15985 100644 --- a/resources/asoundrc +++ b/resources/asoundrc @@ -90,7 +90,7 @@ pcm.!default { capture.pcm { type plug slave { - pcm snoop_i2s_48k + pcm snoop_vol } } } @@ -109,7 +109,7 @@ ctl.!default { capture.pcm { type plug slave { - pcm snoop_i2s_48k + pcm snoop_vol } } } From e67d5f379290b4cedf74d56e7a9697c2fbc8572c Mon Sep 17 00:00:00 2001 From: Dan Follent Date: Tue, 13 Feb 2018 09:47:26 +0000 Subject: [PATCH 07/10] Update to asoundrc --- resources/asoundrc | 58 ++++++++++------------------------------------ 1 file changed, 12 insertions(+), 46 deletions(-) diff --git a/resources/asoundrc b/resources/asoundrc index 3f15985..33b14a1 100644 --- a/resources/asoundrc +++ b/resources/asoundrc @@ -14,13 +14,11 @@ pcm.i2s_48k { rate 48000 } -ctl.i2s_48k { - type hw - card sndrpisimplecar - device 0 -} - -pcm.mix_i2s_48k { +# +# Mixing for playback and recording. +# Allows multiple applications to access playback and recording simultaneously. +# +pcm.dmixer { type dmix ipc_key 115 # Must be unique slave { @@ -28,39 +26,25 @@ pcm.mix_i2s_48k { } } -ctl.mix_i2s_48k { - type dmix +pcm.snoop_i2s_48k { + type dsnoop + ipc_key 116 # Must be unique slave { pcm i2s_48k } } # -# Note that the name must contain "Master" for the task bar to find it +# Volume control for playback and recording. # pcm.mix_vol { type softvol slave { - pcm mix_i2s_48k + pcm dmixer } control { name "Playback" - card 0 - } -} - -pcm.snoop_i2s_48k { - type dsnoop - ipc_key 116 # Must be unique - slave { - pcm i2s_48k - } -} - -ctl.snoop_i2s_48k { - type dsnoop - slave { - pcm i2s_48k + card sndrpisimplecar } } @@ -71,7 +55,7 @@ pcm.snoop_vol { } control { name "Record" - card 0 + card sndrpisimplecar } } @@ -95,21 +79,3 @@ pcm.!default { } } -# -# Create the control interfaces -# -ctl.!default { - type asym - playback.pcm { - type plug - slave { - pcm mix_vol - } - } - capture.pcm { - type plug - slave { - pcm snoop_vol - } - } -} From 80f1afc77288d2b222c283fcb773ca01a33d5bc4 Mon Sep 17 00:00:00 2001 From: Dan Follent Date: Tue, 13 Feb 2018 12:00:23 +0000 Subject: [PATCH 08/10] Added aplay and arecord at startup --- scripts/i2s_i2c_setup.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/i2s_i2c_setup.sh b/scripts/i2s_i2c_setup.sh index 51884eb..e975194 100755 --- a/scripts/i2s_i2c_setup.sh +++ b/scripts/i2s_i2c_setup.sh @@ -109,6 +109,9 @@ echo "# Instantiate a driver at bus id=1 on same pins as hw i2c with 1sec timeou echo "sudo sh -c 'echo "1 2 3 5 100 0 0 0" > /sys/class/i2c-gpio/add_bus'" >> $i2c_driver_script echo "# Remove the default i2c-gpio instance" >> $i2c_driver_script echo "sudo sh -c 'echo 7 > /sys/class/i2c-gpio/remove_bus'" >> $i2c_driver_script +echo "# Run Alsa at startup so that alsamixer configures" >> $i2c_driver_script +echo "arecord -d 1 > /dev/null 2>&1" >> $i2c_driver_script +echo "aplay dummy > /dev/null 2>&1" >> $i2c_driver_script # # Setup the crontab to restart I2S/I2C at reboot From 9ec7ade5294ffbd9b3f373d645b5132bac2ead96 Mon Sep 17 00:00:00 2001 From: Dan Follent <35460137+dfollent@users.noreply.github.com> Date: Tue, 13 Mar 2018 12:14:41 +0000 Subject: [PATCH 09/10] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf914c1..c0a4a60 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Full instructions on configuring the Raspberry Pi to use the **xCORE VocalFusion Brief instructions and additional notes are below: -1. Install Raspbian (Stretch) on the Raspberry Pi. +1. Install **Raspbian Stretch** on the Raspberry Pi. **Note:** This setup script is incompatiable with earlier versions of Raspbian. 2. Open a terminal on the Raspberry Pi and clone this respository: `cd ~; git clone https://github.com/xmos/vocalfusion-stereo-setup` From 9679b34d88b4253e4f654f238d70c5289a29be79 Mon Sep 17 00:00:00 2001 From: Daniel Follent Date: Mon, 26 Mar 2018 16:26:43 +0100 Subject: [PATCH 10/10] Restructured repo --- README.md | 2 +- auto_install.sh | 18 ++-- loader/Makefile | 5 -- loader/loader.c | 74 ---------------- resources/asoundrc | 81 ------------------ resources/panel | 173 -------------------------------------- scripts/i2s_i2c_setup.sh | 121 -------------------------- snd_driver/Makefile | 5 -- snd_driver/bclk_patch.txt | 14 --- 9 files changed, 10 insertions(+), 483 deletions(-) delete mode 100644 loader/Makefile delete mode 100644 loader/loader.c delete mode 100644 resources/asoundrc delete mode 100644 resources/panel delete mode 100755 scripts/i2s_i2c_setup.sh delete mode 100644 snd_driver/Makefile delete mode 100644 snd_driver/bclk_patch.txt diff --git a/README.md b/README.md index c0a4a60..8c0c200 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Full instructions on configuring the Raspberry Pi to use the **xCORE VocalFusion Brief instructions and additional notes are below: -1. Install **Raspbian Stretch** on the Raspberry Pi. **Note:** This setup script is incompatiable with earlier versions of Raspbian. +1. Install **Raspbian Stretch** on the Raspberry Pi. **Note:** This setup script is incompatible with earlier versions of Raspbian. 2. Open a terminal on the Raspberry Pi and clone this respository: `cd ~; git clone https://github.com/xmos/vocalfusion-stereo-setup` diff --git a/auto_install.sh b/auto_install.sh index b408897..5203e81 100644 --- a/auto_install.sh +++ b/auto_install.sh @@ -1,14 +1,14 @@ #!/usr/bin/env bash -SCRIPTS_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"/scripts +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +pushd . > /dev/null +cd $SCRIPT_DIR -if [ -e /usr/share/alsa/pulse-alsa.conf ] ; then - # Back up existing files - sudo mv /usr/share/alsa/pulse-alsa.conf /usr/share/alsa/pulse-alsa.conf.bak - sudo mv ~/.config/lxpanel/LXDE-pi/panels/panel ~/.config/lxpanel/LXDE-pi/panels/panel.bak -fi +git clone git://github.com/xmos/vocalfusion-rpi-setup.git -$SCRIPTS_DIR/i2s_i2c_setup.sh +# Execute (rather than source) the setup scripts +$SCRIPT_DIR/vocalfusion-rpi-setup/setup.sh -echo To enable the i2s device, this pi must now be rebooted -echo type 'sudo reboot' below to do this +echo "Type 'sudo reboot' below to reboot the Raspberry Pi and complete the audio setup." + +popd > /dev/null diff --git a/loader/Makefile b/loader/Makefile deleted file mode 100644 index e023675..0000000 --- a/loader/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-m := loader.o -KDIR := /lib/modules/$(shell uname -r)/build -PWD := $(shell pwd) -default: - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules diff --git a/loader/loader.c b/loader/loader.c deleted file mode 100644 index 3c2b414..0000000 --- a/loader/loader.c +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include -#include -#include -#include -/* -modified for linux 4.1.5 -inspired by https://github.com/msperl/spi-config -with thanks for https://github.com/notro/rpi-source/wiki -as well as Florian Meier for the rpi i2s and dma drivers - -to use a differant (simple-card compatible) codec -change the codec name string in two places and the -codec_dai name string. (see codec's source file) - -fmt flags are set for vanilla i2s with rpi as clock slave - -N.B. playback vs capture is determined by the codec choice -*/ - -void device_release_callback(struct device *dev) { /* do nothing */ }; - -static struct asoc_simple_card_info snd_rpi_simple_card_info = { - .card = "snd_rpi_simple_card", // -> snd_soc_card.name - .name = "simple-card_codec_link", // -> snd_soc_dai_link.name - .codec = "snd-soc-dummy", // -> snd_soc_dai_link.codec_name - .platform = "3f203000.i2s", - .daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, - .cpu_dai = { - .name = "3f203000.i2s", // -> snd_soc_dai_link.cpu_dai_name - .sysclk = 0 - }, - .codec_dai = { - .name = "snd-soc-dummy-dai", // -> snd_soc_dai_link.codec_dai_name - .sysclk = 0 - } -}; - -static struct platform_device snd_rpi_simple_card_device = { - .name = "asoc-simple-card", //module alias - .id = 0, - .num_resources = 0, - .dev = { - .release = &device_release_callback, - .platform_data = &snd_rpi_simple_card_info, // *HACK ALERT* - } -}; - -int hello_init(void) -{ - const char *dmaengine = "bcm2708-dmaengine"; //module name - int ret; - - ret = request_module(dmaengine); - pr_alert("request module load '%s': %d\n",dmaengine, ret); - ret = platform_device_register(&snd_rpi_simple_card_device); - pr_alert("register platform device '%s': %d\n",snd_rpi_simple_card_device.name, ret); - pr_alert("Hello World :)\n"); - return 0; -} - -void hello_exit(void) -{ - // you'll have to sudo modprobe -r the card & codec drivers manually (first?) - platform_device_unregister(&snd_rpi_simple_card_device); - pr_alert("Goodbye World!\n"); -} - -module_init(hello_init); -module_exit(hello_exit); -MODULE_DESCRIPTION("ASoC simple-card I2S setup"); -MODULE_AUTHOR("Plugh Plover"); -MODULE_LICENSE("GPL v2"); diff --git a/resources/asoundrc b/resources/asoundrc deleted file mode 100644 index 33b14a1..0000000 --- a/resources/asoundrc +++ /dev/null @@ -1,81 +0,0 @@ -# -# The I2S hardware device. Refer to it by name as it will not always -# be the same card number in every system. -# -pcm.i2s_48k { - type hw - card sndrpisimplecar - device 0 - - # The device has fixed 32-bit samples - format S32_LE - - # The device runs at 48kHz - rate 48000 -} - -# -# Mixing for playback and recording. -# Allows multiple applications to access playback and recording simultaneously. -# -pcm.dmixer { - type dmix - ipc_key 115 # Must be unique - slave { - pcm i2s_48k - } -} - -pcm.snoop_i2s_48k { - type dsnoop - ipc_key 116 # Must be unique - slave { - pcm i2s_48k - } -} - -# -# Volume control for playback and recording. -# -pcm.mix_vol { - type softvol - slave { - pcm dmixer - } - control { - name "Playback" - card sndrpisimplecar - } -} - -pcm.snoop_vol { - type softvol - slave { - pcm snoop_i2s_48k - } - control { - name "Record" - card sndrpisimplecar - } -} - -# -# Map the default audio playback and recording devices to the I2S device. -# - use plugs in order to support rate and format conversions. -# -pcm.!default { - type asym - playback.pcm { - type plug - slave { - pcm mix_vol - } - } - capture.pcm { - type plug - slave { - pcm snoop_vol - } - } -} - diff --git a/resources/panel b/resources/panel deleted file mode 100644 index 0ea68e1..0000000 --- a/resources/panel +++ /dev/null @@ -1,173 +0,0 @@ -# lxpanel config file. Manually editing is not recommended. -# Use preference dialog in lxpanel to adjust config when you can. - -Global { - edge=top - allign=left - margin=0 - widthtype=percent - width=100 - height=36 - transparent=0 - tintcolor=#000000 - alpha=0 - autohide=0 - heightwhenhidden=2 - setdocktype=1 - setpartialstrut=1 - usefontcolor=0 - fontsize=12 - fontcolor=#ffffff - usefontsize=0 - background=0 - backgroundfile=/usr/share/lxpanel/images/background.png - iconsize=36 -} -Plugin { - type=space - Config { - Size=4 - } -} -Plugin { - type=menu - Config { - image=/usr/share/raspberrypi-artwork/launch.png - system { - } - separator { - } - item { - name=Run... - image=system-run - command=run - } - separator { - } - item { - name=Shutdown... - image=system-shutdown - command=logout - } - } -} -Plugin { - type=space - Config { - Size=8 - } -} -Plugin { - type=launchbar - Config { - Button { - id=lxde-x-www-browser.desktop - } - Button { - id=pcmanfm.desktop - } - Button { - id=lxterminal.desktop - } - Button { - id=wolfram-mathematica.desktop - } - Button { - id=wolfram-language.desktop - } - } -} -Plugin { - type=space - Config { - Size=8 - } -} -Plugin { - type=taskbar - expand=1 - Config { - tooltips=1 - IconsOnly=0 - ShowAllDesks=0 - UseMouseWheel=1 - UseUrgencyHint=1 - FlatButton=0 - MaxTaskWidth=200 - spacing=1 - GroupedTasks=0 - } -} -Plugin { - type=space - Config { - Size=2 - } -} -Plugin { - type=tray - Config { - } -} -Plugin { - type=bluetooth - Config { - } -} -Plugin { - type=space - Config { - Size=2 - } -} -Plugin { - type=dhcpcdui - Config { - } -} -Plugin { - type=space - Config { - Size=2 - } -} -#Plugin { -# type=volumealsabt -# Config { -# } -#} -Plugin { - type=space - Config { - Size=2 - } -} -Plugin { - type=cpu - Config { - ShowPercent=1 - Foreground=#a9a9a9a9a9a9 - Background=#d3d3d3d3d3d3 - } -} -Plugin { - type=dclock - Config { - ClockFmt=%R - TooltipFmt=%A %x - BoldFont=0 - IconOnly=0 - CenterText=0 - } -} -Plugin { - type=space - Config { - Size=2 - } -} -Plugin { - type=ejecter - Config { - } -} diff --git a/scripts/i2s_i2c_setup.sh b/scripts/i2s_i2c_setup.sh deleted file mode 100755 index e975194..0000000 --- a/scripts/i2s_i2c_setup.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env bash - -# Setup paths -SCRIPTS_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" - -# The working directory is the parent of the scripts -I2S_ROOT=$(dirname $SCRIPTS_DIR) - -# -# Define folders -# -pushd $(dirname "$0") > /dev/null -popd > /dev/null - -# -# Disable the built-in audio output so there is only one audio -# device in the system -# -sudo sed -i -e 's/dtparam=audio=on/#dtparam=audio=on/' /boot/config.txt - -# -# Enable the i2s device tree -# -sudo sed -i -e 's/#dtparam=i2s=on/dtparam=i2s=on/' /boot/config.txt - -# Add modules to enable the I2C Peripherals and Direct Memory Access -# Controller modules that the sound card driver depends on -sudo sh -c 'echo snd_soc_bcm2708 >> /etc/modules' -sudo sh -c 'echo snd_soc_bcm2708_i2s >> /etc/modules' -sudo sh -c 'echo bcm2708_dmaengine >> /etc/modules' - -# Download kernal source - this will take some time -cd $I2S_ROOT -sudo apt-get -y install bc -sudo apt-get -y install libncurses5-dev -if [ ! -d rpi-source ] ; then - git clone git://github.com/notro/rpi-source.git -fi -pushd $I2S_ROOT/rpi-source > /dev/null -python rpi-source --skip-gcc -popd > /dev/null - -# -# Build simple sound card driver -# Modify the driver source to have the correct BCLK ratio -# -pushd $I2S_ROOT/snd_driver > /dev/null -cp ~/linux/sound/soc/generic/simple-card.c ./asoc_simple_card.c -patch -p1 asoc_simple_card.c < bclk_patch.txt -make -popd > /dev/null - -# -# Build loader and insert it into the kernel -# -pushd $I2S_ROOT/loader > /dev/null -make -popd > /dev/null - -if [ -e ~/.asoundrc ] ; then - cp ~/.asoundrc ~/.asoundrc.bak - chmod a+w ~/.asoundrc -fi - -cp $I2S_ROOT/resources/asoundrc ~/.asoundrc -cp $I2S_ROOT/resources/panel ~/.config/lxpanel/LXDE-pi/panels/panel - -# -# Make the asoundrc file read-only otherwise lxpanel rewrites it -# as it doesn't support anything but a hardware type device -# -chmod a-w ~/.asoundrc - -# Apply changes -sudo /etc/init.d/alsa-utils restart - -# -# Create the script to run after each reboot and make the soundcard available -# -i2s_driver_script=$I2S_ROOT/resources/load_i2s_driver.sh -echo "cd $I2S_ROOT" > $i2s_driver_script -echo "sudo insmod loader/loader.ko" >> $i2s_driver_script - -# -# Configure the I2C - disable the default built-in driver -# -sudo sed -i -e 's/#\?dtparam=i2c_arm=on/dtparam=i2c_arm=off/' /boot/config.txt -sudo sh -c 'echo i2c-bcm2708 >> /etc/modules-load.d/modules.conf' -sudo sh -c 'echo "options i2c-bcm2708 combined=1" >> /etc/modprobe.d/i2c.conf' - -# -# Build a new I2C driver -# -cd $I2S_ROOT -git clone git://github.com/kadamski/i2c-gpio-param.git -pushd $I2S_ROOT/i2c-gpio-param > /dev/null -make -popd > /dev/null - -# -# Create script to insert module into the kernel -# -i2c_driver_script=$I2S_ROOT/resources/load_i2c_gpio_driver.sh - -echo "cd $I2S_ROOT/i2c-gpio-param" > $i2c_driver_script -echo "# Load the i2c bit banged driver" >> $i2c_driver_script -echo "sudo insmod i2c-gpio-param.ko" >> $i2c_driver_script -echo "# Instantiate a driver at bus id=1 on same pins as hw i2c with 1sec timeout" >> $i2c_driver_script -echo "sudo sh -c 'echo "1 2 3 5 100 0 0 0" > /sys/class/i2c-gpio/add_bus'" >> $i2c_driver_script -echo "# Remove the default i2c-gpio instance" >> $i2c_driver_script -echo "sudo sh -c 'echo 7 > /sys/class/i2c-gpio/remove_bus'" >> $i2c_driver_script -echo "# Run Alsa at startup so that alsamixer configures" >> $i2c_driver_script -echo "arecord -d 1 > /dev/null 2>&1" >> $i2c_driver_script -echo "aplay dummy > /dev/null 2>&1" >> $i2c_driver_script - -# -# Setup the crontab to restart I2S/I2C at reboot -# -echo "@reboot sh $i2s_driver_script" > $I2S_ROOT/resources/crontab -echo "@reboot sh $i2c_driver_script" >> $I2S_ROOT/resources/crontab -crontab $I2S_ROOT/resources/crontab diff --git a/snd_driver/Makefile b/snd_driver/Makefile deleted file mode 100644 index 1bdea7c..0000000 --- a/snd_driver/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-m := asoc_simple_card.o -KDIR := /lib/modules/$(shell uname -r)/build -PWD := $(shell pwd) -default: - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules diff --git a/snd_driver/bclk_patch.txt b/snd_driver/bclk_patch.txt deleted file mode 100644 index 322e146..0000000 --- a/snd_driver/bclk_patch.txt +++ /dev/null @@ -1,14 +0,0 @@ -*************** static int asoc_simple_card_dai_init(str -*** 205,210 **** ---- 205,215 ---- - if (ret < 0) - return ret; - -+ ret = snd_soc_dai_set_bclk_ratio(cpu, 64); -+ if (ret < 0) -+ return ret; -+ pr_alert("BCLK ratio set to 64!\n"); -+ - return 0; - } -