diff --git a/.github/workflows/raspOVOS-gui.yaml b/.github/workflows/raspOVOS-gui.yaml index b3d724d..39a00d5 100644 --- a/.github/workflows/raspOVOS-gui.yaml +++ b/.github/workflows/raspOVOS-gui.yaml @@ -1,4 +1,4 @@ -name: Build raspOVOS-gui +name: Build raspOVOS-mark2 on: workflow_dispatch: @@ -13,14 +13,14 @@ jobs: id: build with: # Final image name. - image-name: raspOVOS-gui-dev + image-name: raspOVOS-mark2-dev # List of stage name to execute in given order. Relative and absolute paths to # custom stage directories are allowed here. Note that by default pi-gen exports # images in stage2 (lite), stage4 and stage5. You probably want to hook in custom # stages before one of the exported stages. Otherwise, the action will make sure # any custom stage will include an image export directive. - stage-list: stage0 stage1 stage2 ./stage-prep ./stage-core ./stage-phal ./stage-audio ./stage-skills ./stage-hivemind ./stage-ggwave ./stage-gui ./stage-finalize + stage-list: stage0 stage1 stage2 ./stage-prep ./stage-splash ./stage-core ./stage-hivemind ./stage-skills ./stage-phal ./stage-audio ./stage-speech ./stage-listener ./stage-ggwave ./stage-gui ./stage-finalize # Host name of the image. hostname: raspOvos diff --git a/.github/workflows/raspOVOS-headless.yaml b/.github/workflows/raspOVOS-headless.yaml index 1752f07..b667639 100644 --- a/.github/workflows/raspOVOS-headless.yaml +++ b/.github/workflows/raspOVOS-headless.yaml @@ -20,7 +20,7 @@ jobs: # images in stage2 (lite), stage4 and stage5. You probably want to hook in custom # stages before one of the exported stages. Otherwise, the action will make sure # any custom stage will include an image export directive. - stage-list: stage0 stage1 stage2 ./stage-prep ./stage-core ./stage-phal ./stage-audio ./stage-skills ./stage-hivemind ./stage-ggwave ./stage-finalize + stage-list: stage0 stage1 stage2 ./stage-prep ./stage-splash ./stage-core ./stage-hivemind ./stage-skills ./stage-audio ./stage-speech ./stage-listener ./stage-ggwave ./stage-phal ./stage-finalize # Host name of the image. hostname: raspOvos diff --git a/.github/workflows/raspOVOS-mark2.yaml b/.github/workflows/raspOVOS-mark2.yaml new file mode 100644 index 0000000..d2d323d --- /dev/null +++ b/.github/workflows/raspOVOS-mark2.yaml @@ -0,0 +1,135 @@ +name: Build raspOVOS-mark2 +on: + workflow_dispatch: + +jobs: + pi-gen-ovos: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. + - uses: usimd/pi-gen-action@v1 + id: build + with: + # Final image name. + image-name: raspOVOS-mark2-dev + + # List of stage name to execute in given order. Relative and absolute paths to + # custom stage directories are allowed here. Note that by default pi-gen exports + # images in stage2 (lite), stage4 and stage5. You probably want to hook in custom + # stages before one of the exported stages. Otherwise, the action will make sure + # any custom stage will include an image export directive. + stage-list: stage0 stage1 stage2 ./stage-prep ./stage-splash ./stage-core ./stage-hivemind ./stage-skills ./stage-phal ./stage-audio ./stage-speech ./stage-listener ./stage-ggwave ./stage-gui ./stage-mark2 ./stage-finalize + + # Host name of the image. + hostname: raspOvos + + # Default keyboard keymap. + keyboard-keymap: us + + # Default keyboard layout. + keyboard-layout: English (US) + + # Default locale of the system image. + locale: en_US.UTF-8 + + # Default wifi country + wpa-country: US + + # Default timezone + timezone: America/Denver + + # Name of the initial user account. + username: ovos + + # Password of the intial user account, locked if empty. + password: 'ovos' + + # Compression to apply on final image (either "none", "zip", "xz" or "gz"). + compression: zip + + # Compression level to be used. From 0 to 9 (refer to the tool man page for more + # information on this. Usually 0 is no compression but very fast, up to 9 with the + # best compression but very slow). + compression-level: 6 + + # Disable the renaming of the first user during the first boot. This make it so + # 'username' stays activated. 'username' must be set for this to work. Please be + # aware of the implied security risk of defining a default username and password + # for your devices. + disable-first-boot-user-rename: 1 + + # Additional options to include in PIGEN_DOCKER_OPTS + docker-opts: '' + + # Set whether a NOOBS image should be built as well. If enabled, the output + # directory containing the NOOBS files will be saved as output variable + # 'image-noobs-path'. + enable-noobs: false + + # Enable SSH access to Pi. + enable-ssh: 1 + + # If this feature is enabled, the action will configure pi-gen to not export any + # stage as image but the last one defined in property 'stage-list'. This is + # helpful when building a single image flavor (in contrast to building a + # lite/server and full-blown desktop image), since it speeds up the build process + # significantly. + export-last-stage-only: true + + # Comma or whitespace separated list of additional packages to install on host + # before running pi-gen. Use this list to add any packages your custom stages may + # require. Note that this is not affecting the final image. In order to add + # additional packages, you need to add a respective 'XX-packages' file in your + # custom stage. + extra-host-dependencies: '' + + # Comma or whitespace separated list of additional modules to load on host before + # running pi-gen. If your custom stage requires additional software or kernel + # modules to be loaded, add them here. Note that this is not meant to configure + # modules to be loaded in the target image. + extra-host-modules: '' + + # Token to use for checking out pi-gen repo. + github-token: ${{ github.token }} + + # Path where selected pi-gen ref will be checked out to. If the path does not yet + # exist, it will be created (including its parents). + pi-gen-dir: pi-gen + + # GitHub repository to fetch pi-gen from, must be a fork from RPi-Distro/pi-gen. + + pi-gen-repository: RPi-Distro/pi-gen + + # Release version of pi-gen to use. This can both be a branch or tag name known in + # the pi-gen repository. + pi-gen-version: arm64 + + # The release version to build images against. Valid values are jessie, stretch, + # buster, bullseye, and testing. + release: bookworm + + # Setting to `1` will prevent pi-gen from dropping the "capabilities" feature. + # Generating the root filesystem with capabilities enabled and running it from a + # filesystem that does not support capabilities (like NFS) can cause issues. Only + # enable this if you understand what it is. + setfcap: '' + + # Use qcow2 images to reduce space and runtime requirements. + use-qcow2: 1 + + # Print all output from pi-gen. + verbose-output: true + + - name: copy file via ssh password + uses: appleboy/scp-action@master + with: + host: ovosimages.ziggyai.online + username: ${{ secrets.USERNAME }} + password: ${{ secrets.PASSWORD }} + port: ${{ secrets.SSH_PORT }} + source: "${{ steps.build.outputs.image-path }}" + target: "raspbian/development" + strip_components: 4 + diff --git a/BUILD_LOCAL.md b/BUILD_LOCAL.md new file mode 100644 index 0000000..b0bcda9 --- /dev/null +++ b/BUILD_LOCAL.md @@ -0,0 +1,206 @@ +# Build raspOVOS locally + +It is possible to build this image locally for development purposes or for fun. + +## Understanding this repository + +This repository contains several directories with the `stage-` prefix. Each one is executed in the order specified in a config file. [example here](#) + +A few of the stages are needed for an OVOS image. Once a `headless` image is built, other stages can be added for other usage such as a GUI system, or Mark2 device. + +## Needed for Headless Image + +### stage-prep + +This is where all of the system setup happens. + +- Adds an apt repository for `mimic` +- Configures locale +- Installs essential packages with apt +- Patches `cmdline.txt` for zram +- Sets up automounting of USB media +- Adds `system` and `user` systemd preset files +- Disables WiFi powersave +- Sets up rules for NetworkManager +- Creates `.bashrc`, `.bash_profile`, and other `.` files in the users home directory + +### stage-splash + +**Optional** + +Add a little pizazz and give it a splash screen + +### stage-core + +This is where [ovos-core](https://github.com/OpenVoiceOS/ovos-core) and [ovos-messagebus](https://github.com/OpenVoiceOS/ovos-messagebus) are installed. + +This also creates the `ovos.service`, `ovos-skills.service` and `ovos-messagebus.service` + +### stage-hivemind + +**Optional** + +This is here so you can make your device a [HiveMind listener](https://github.com/JarbasHiveMind/HiveMind-core). + +The service `hivemind-listener.service` is created, but disabled by default. + +On a running image, issue the command `systemctl --user enable hivemind-listener.service` and `systemctl --user start hivemind-listener.service` to start it automatically on boot. + +### stage-skills + +Duh!! Install the skills here. The service was created in `stage-core`, but skills are installed here. This is just a MINIMAL set of skills to get your OVOS assistant up and running. More can be installed on a running system. + +**At this point, with `hivemind-listener.service` enabled, you can skip to the last step, [stage-finalize](#), and have a working HiveMind master** + +### stage-audio + +This stage is where pulseaudio, or eventually pipewire is installed and configured. + +There is a `hardware` section here that has a service for autodetection of HAT's, including `respeakers` and the `sj201` *(implemented later)*. This section is a **WIP** and any feedback would be great. + +### stage-speech + +[ovos-audio](https://github.com/OpenVoiceOS/ovos-audio) is installed and configured. + +TTS engines are installed and configured. + +### stage-listener + +This is where [ovos-dinkum-listener](https://github.com/OpenVoiceOS/ovos-dinkum-listener) is installed and configured. + +You can also configure your microphone and VAD plugins here. + +### stage-ggwave + +**Optional** + +This is installed after `stage-audio` because it depends on sound to work. + +For more informaton on how to use the [ovos-audio-transformer-plugin-ggwave](https://github.com/OpenVoiceOS/ovos-audio-transformer-plugin-ggwave). + +### stage-phal + +[ovos_PHAL](https://github.com/OpenVoiceOS/ovos-PHAL) (Plugin based Hardware Abstraction Layer) is where OVOS interacts with the device hardware. + +**From here you can skip to [stage-finalize](stage-finalize) and have a complete `raspOVOS headless` system which will even run on a RPi3b** + +## Optional and a WIP for now + +### stage-shareport + +Apple AirPlay support + +### stage-spotify + +Premium Spotify support + +## Needed for GUI Image + +### stage-gui + +This stage adds all of the components to have a working OVOS GUI device. **You must have at least a RPi4 2G for this to run** + +[ovos-shell](#) and [ovos-gui](#) are installed and configured here. + +The `/boot/firmware/config.txt` is modified to allow a GUI + +**Skip to [stage-finalize](stage-finalize) to build a simple raspOVOS-GUI image** + +## Optional Special Stages + +### stage-mark1 + +**WIP** + +Special configuration to support the Mycroft Mark1 device + +### stage-mark2 + +**WIP** + +Special configuration to support the Mycroft Mark2 device + +## And the Final Stage + +### stage-finalize + +This is where the final things happen. + +- system links to log files +- enabling systemd service files +- naming the image + +# Pi-gen + +In order to build an image, we use the official image builder of raspbianOS...[pi-gen](https://github.com/RPi-Distro/pi-gen). + +pi-gen is organized into branches depending on the version you would like to build. + +- master + - The default branch - 32b `bookworm` +- arm64 + - The branch we normally use - 64b `bookworm` +- bullseye + - 32b `bullseye` +- bullseye-arm64 + - 64b `bullseye` + +For specific information on using pi-gen, consult the [README](https://github.com/RPi-Distro/pi-gen/blob/master/README.md)file. + +# Building an Image + +From this point, we will assume you are working from your `home` directory + +`cd ~` + +Clone the required repositories + +`git clone https://github.com/OpenVoiceOS/raspbian-ovos` + +`git clone https://github.com/RPi-Distro/pi-gen` + +Copy the `raspbian-ovos-config.example` file to make the required changes to it. + +`cp raspbian-ovos/raspbian-ovos-config.example ./raspbian-ovos-config` + +Edit the file + +`nano ./raspbian-ovos-config` + +Change all references to `` to where you cloned the `raspbian-ovos` repository. For this example it would be `/home//raspbian-ovos/` + +The example file is configured for a headless image. Add the stages from above for a GUI or other image. + +You can also change the name of the image and other configuration settings, such as the default locale. + +After making your changes, save and exit + +`Ctl-o` + +`Ctl-x` + +Move into the pi-gen directory. + +`cd pi-gen` + +Switch to the `arm64` branch of `pi-gen` + +`git checkout arm64` + +To actually build an image, you need root privileges. + +#### Start the build process + +`sudo ./build.sh -c /home//raspbian-ovos-config` + +The `-c` flag should point to your edited configuration file. + +Sit back and wait. The build process can last several hours. + +#### Getting the image + +After the build process, a compressed image will be avaliable in the directory `~/pi-gen/deploy` + +Write the image to a USB3 drive or a SSD drive. SD cards may work, but have not been tested. + +Boot your new OVOS assistant and enjoy!! diff --git a/README.md b/README.md index 8defa52..b73767e 100644 --- a/README.md +++ b/README.md @@ -14,30 +14,47 @@ This guide was originally designed for a headless, (No GUI) Raspberry Pi 3. The Please, if any mistakes, including spelling mistakes are found, or if a more detailed explanation of a step is needed, open an issue here and I will address it ASAP. -## Shairport +## Features -Shairport-sync is available for this device as `raspOvos` +Built on the official rasbianOS lite image (latest is bookworm). + +Multiple image variants can be built with the files in this repository. This includes "headless", "GUI", "Mark 2", "Mark 1", and any other custom image you would like to build. + +### Auto Hardware Detection + +**WIP (Feedback Welcome)** -#### Playback issues +#### Supported devices -It has been noted that there is no audio playback with certain output devices due to sampling rates...but there is a fix +- USB Devices + - PS3 Eye + - BlueSnowball + - Generic WebCam + - Possibly more, but not tested +- Seed voicecard + - 2 mic + - 4 mic + - 6 mic + - 8 mic +- SJ201 + - Daughter card for the Mark 2 +- Google AIY-VoiceBonnet V2 -- ssh into your device -- `shairport-sync -h` - - at the end of the output will be the devices that are available. make note of the name of the device you want to use -- `sudo nano /etc/shairport-sync.conf` - - find the line that contains `output_device = "default"` - - change to read `output_device = "plughw:" - - save the file -- `sudo systemctl restart shairport-sync.service` +### KDEConnect -Playback should now work +Available with the GUI images + +### Shairport + +**WIP not yet implemented** + +Shairport-sync is available for this device as `raspOvos` -## Raspotify +### Raspotify -This loads and the you can see the device in the `available devices` on the spotify app, but a premium account is needed to connect to it. As of this writing, I do not have a premium account to test with. Any feedback would be great. +**WIP not yet implemented** -## ISSUES +### ISSUES All issues and/or feedback is more than welcome. diff --git a/manual_user_install.sh b/manual_user_install.sh index 0620f1a..54f28e8 100755 --- a/manual_user_install.sh +++ b/manual_user_install.sh @@ -96,8 +96,8 @@ function install_systemd (){ # install the hook files cp $SCRIPT_DIR/stage-core/01-ovos-core/files/ovos-systemd-skills ${BINDIR}/ cp $SCRIPT_DIR/stage-core/02-messagebus/files/ovos-systemd-messagebus ${BINDIR}/ - cp $SCRIPT_DIR/stage-audio/01-speech/files/ovos-systemd-audio ${BINDIR}/ - cp $SCRIPT_DIR/stage-audio/02-voice/files/ovos-systemd-dinkum-listener ${BINDIR}/ + cp $SCRIPT_DIR/stage-speech/01-speech/files/ovos-systemd-audio ${BINDIR}/ + cp $SCRIPT_DIR/stage-listener/01-listener/files/ovos-systemd-dinkum-listener ${BINDIR}/ cp $SCRIPT_DIR/stage-phal/01-user/files/ovos-systemd-phal ${BINDIR}/ echo $sudoPW | sudo -S cp $SCRIPT_DIR/stage-phal/02-admin/files/ovos-systemd-admin-phal /usr/libexec @@ -114,8 +114,8 @@ function install_systemd (){ cp $SCRIPT_DIR/stage-core/01-ovos-core/files/ovos.service $HOME/.config/systemd/user/ cp $SCRIPT_DIR/stage-core/01-ovos-core/files/ovos-skills.service $HOME/.config/systemd/user/ cp $SCRIPT_DIR/stage-core/02-messagebus/files/ovos-messagebus.service $HOME/.config/systemd/user/ - cp $SCRIPT_DIR/stage-audio/01-speech/files/ovos-audio.service $HOME/.config/systemd/user/ - cp $SCRIPT_DIR/stage-audio/02-voice/files/ovos-dinkum-listener.service $HOME/.config/systemd/user/ + cp $SCRIPT_DIR/stage-speech/01-speech/files/ovos-audio.service $HOME/.config/systemd/user/ + cp $SCRIPT_DIR/stage-listener/01-listener/files/ovos-dinkum-listener.service $HOME/.config/systemd/user/ cp $SCRIPT_DIR/stage-phal/01-user/files/ovos-phal.service $HOME/.config/systemd/user/ echo $sudoPW | sudo -S cp $SCRIPT_DIR/stage-phal/02-admin/files/ovos-admin-phal.service /etc/systemd/system/ @@ -168,7 +168,7 @@ function install_extra_skills (){ done # Add some fun - INSTALL="$INSTALL git+https://github.com/JarbasSkills/skill-icanhazdadjokes" + INSTALL="$INSTALL git+https://github.com/OpenVoiceOS/skill-ovos-icanhazdadjokes" # Do all the installs at once to allow pip to sort out dependencies nicely pip3 install $INSTALL diff --git a/raspbian-ovos-config b/raspbian-ovos-config.example similarity index 77% rename from raspbian-ovos-config rename to raspbian-ovos-config.example index 3fb0863..8561178 100644 --- a/raspbian-ovos-config +++ b/raspbian-ovos-config.example @@ -1,7 +1,9 @@ # Final image name. -IMG_NAME="raspbian-ovos-dev" -IMG_FILENAME="raspbian-ovos-dev" -ARCHIVE_FILENAME="raspbian-ovos-dev" +IMG_NAME="raspOVOS-dev" +# Name of build directory +IMG_FILENAME="raspOVOS-dev" +# Name of compressed image without chosen suffix +ARCHIVE_FILENAME="raspOVOS-dev" # List of stage name to execute in given order. Relative and absolute paths to # custom stage directories are allowed here. Note that by default pi-gen exports @@ -9,8 +11,7 @@ ARCHIVE_FILENAME="raspbian-ovos-dev" # stages before one of the exported stages. Otherwise, the action will make sure # any custom stage will include an image export directive. -# Edit this list to full path of stages -STAGE_LIST="stage0 stage1 stage2 /software/OVOS/IMAGE_BUILDING/venv/raspbian-ovos/stage-prep /software/OVOS/IMAGE_BUILDING/venv/raspbian-ovos/stage-core /software/OVOS/IMAGE_BUILDING/venv/raspbian-ovos/stage-phal /software/OVOS/IMAGE_BUILDING/venv/raspbian-ovos/stage-audio /software/OVOS/IMAGE_BUILDING/venv/raspbian-ovos/stage-skills /software/OVOS/IMAGE_BUILDING/venv/raspbian-ovos/stage-hivemind /software/OVOS/IMAGE_BUILDING/venv/raspbian-ovos/stage-finalize" +STAGE_LIST="stage0 stage1 stage2 //raspbian-ovos/stage-prep //raspbian-ovos/stage-core //raspbian-ovos/stage-phal //raspbian-ovos/stage-speech //raspbian-ovos/stage-listener //raspbian-ovos/stage-skills //raspbian-ovos/stage-hivemind //raspbian-ovos/stage-ggwave //raspbian-ovos/stage-finalize" # Host name of the image. TARGET_HOSTNAME="raspOvos" diff --git a/stage-audio/01-install-packages/01-packages b/stage-audio/01-install-packages/01-packages new file mode 100644 index 0000000..e0463f3 --- /dev/null +++ b/stage-audio/01-install-packages/01-packages @@ -0,0 +1,7 @@ +libfann2 libfann-dev portaudio19-dev libpulse-dev +mpg123 +i2c-tools +pulseaudio-module-zeroconf +gstreamer1.0-plugins-good +gstreamer1.0-plugins-bad +gstreamer1.0-plugins-ugly diff --git a/stage-audio/01-speech/01-run.sh b/stage-audio/01-speech/01-run.sh deleted file mode 100755 index 6d1b912..0000000 --- a/stage-audio/01-speech/01-run.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -e - -#audio -install -v -d -m 0755 "${ROOTFS_DIR}/etc/pulse" -install -v -m 0644 files/pulseaudio-daemon.conf "${ROOTFS_DIR}/etc/pulse/" -install -v -m 0644 files/pulseaudio-system.pa "${ROOTFS_DIR}/etc/pulse/" - -# Comment out `suspend_on_idle` from both system.pa and default.pa -sed -i "s\load-module module-suspend-on-idle\#load-module module-suspend-on-idle\g" ${ROOTFS_DIR}/etc/pulse/default.pa -sed -i "s\load-module module-suspend-on-idle\#load-module module-suspend-on-idle\g" ${ROOTFS_DIR}/etc/pulse/system.pa -sed -i "s\load-module module-udev-detect\load-module module-udev-detect tsched=0\g" ${ROOTFS_DIR}/etc/pulse/system.pa - -install -v -m 0644 files/asound.conf "${ROOTFS_DIR}/etc/asound.conf" - -install -v -d -m 0755 "${ROOTFS_DIR}/etc/udev" -install -v -d -m 0755 "${ROOTFS_DIR}/etc/udev/rules.d" -install -v -m 0644 files/91-pulseaudio-GeneralPlus.rules "${ROOTFS_DIR}/etc/udev/rules.d/" - -install -v -d -m 0755 "${ROOTFS_DIR}/home/ovos/.local/share" -install -v -d -m 0755 "${ROOTFS_DIR}/home/ovos/.local/share/piper_tts" -install -v -d -m 0755 "${ROOTFS_DIR}/home/ovos/.local/share/piper_tts/voice-en-gb-alan-low" - -wget https://github.com/rhasspy/piper/releases/download/v0.0.2/voice-en-gb-alan-low.tar.gz -P "${ROOTFS_DIR}/home/ovos/.local/share/piper_tts/voice-en-gb-alan-low/" -on_chroot << EOF - -tar -xvzf /home/ovos/.local/share/piper_tts/voice-en-gb-alan-low/voice-en-gb-alan-low.tar.gz - -EOF - -install -v -m 0644 files/ovos-audio.service "${ROOTFS_DIR}/etc/systemd/user/ovos-audio.service" -install -v -m 0755 files/ovos-systemd-audio "${ROOTFS_DIR}/usr/libexec/ovos-systemd-audio" - -echo "enable ovos-audio.service" >> "${ROOTFS_DIR}/etc/systemd/user-preset/10-ovos-user.preset" diff --git a/stage-audio/02-pulseaudio/01-run.sh b/stage-audio/02-pulseaudio/01-run.sh new file mode 100755 index 0000000..c8213d2 --- /dev/null +++ b/stage-audio/02-pulseaudio/01-run.sh @@ -0,0 +1,53 @@ +#!/bin/bash -e + +# Remove old configurations +if [ -f "${ROOTFS_DIR}/etc/pulse/system.pa" ] ; then +rm "${ROOTFS_DIR}/etc/pulse/system.pa" +fi +if [ -f "${ROOTFS_DIR}/etc/pulse/default.pa" ] ; then +rm "${ROOTFS_DIR}/etc/pulse/default.pa" +fi +if [ -f "${ROOTFS_DIR}/etc/pulse/daemon.conf" ] ; then +rm "${ROOTFS_DIR}/etc/pulse/daemon.conf" +fi +if [ -f "${ROOTFS_DIR}/var/lib/alsa/asound.state" ] ; then +rm "${ROOTFS_DIR}/var/lib/alsa/asound.state" +fi +if [ -f "${ROOTFS_DIR}/etc/ovos_asound.state" ] ; then +rm "${ROOTFS_DIR}/etc/ovos_asound.state" +fi +install -v -m 0644 files/pulseaudio-daemon.conf "${ROOTFS_DIR}/etc/pulse/pulseaudio-daemon.conf" +install -v -m 0644 files/pulseaudio-system.pa "${ROOTFS_DIR}/etc/pulse/system.pa.d/pulseaudio-system.pa" +install -v -m 0644 files/default-asound.state "${ROOTFS_DIR}/var/lib/alsa/default-asound.state" + +install -v -m 0644 files/asound.conf "${ROOTFS_DIR}/etc/asound.conf" + +on_chroot << EOF + +ln -s /var/lib/alsa/default-asound.state /etc/ovos_asound.state +ln -s /var/lib/alsa/default-asound.state /var/lib/alsa/asound.state +ln -s /etc/pulse/pulseaudio-daemon.conf /etc/pulse/daemon.conf +ln -s /etc/pulse/system.pa.d/pulseaudio-system.pa /etc/pulse/system.pa +ln -s /etc/pulse/system.pa.d/pulseaudio-system.pa /etc/pulse/default.pa + +EOF + +install -v -d -m 0755 "${ROOTFS_DIR}/etc/udev" +install -v -d -m 0755 "${ROOTFS_DIR}/etc/udev/rules.d" +install -v -m 0644 files/91-pulseaudio-GeneralPlus.rules "${ROOTFS_DIR}/etc/udev/rules.d/" + +install -v -m 0644 files/GeneralPlus.conf "${ROOTFS_DIR}/usr/share/pulseaudio/alsa-mixer/profile-sets/GeneralPlus.conf" + +install -v -m 0644 files/seeed-voicecard-4mic-daemon.conf "${ROOTFS_DIR}/usr/share/pulseaudio/alsa-mixer/profile-sets/seeed-voicecard-4mic-daemon.conf" +install -v -m 0644 files/seeed-voicecard-4mic-default.pa "${ROOTFS_DIR}/etc/pulse/default.pa.d/seeed-voicecard-4mic-default.pa" + +install -v -m 0644 files/seeed-voicecard-8mic-daemon.conf "${ROOTFS_DIR}/usr/share/pulseaudio/alsa-mixer/profile-sets/seeed-voicecard-8mic-daemon.conf" +install -v -m 0644 files/seeed-voicecard-8mic-default.pa "${ROOTFS_DIR}/etc/pulse/default.pa.d/seeed-voicecard-8mic-default.pa" + +install -v -m 0644 files/sj201-daemon.conf "${ROOTFS_DIR}/usr/share/pulseaudio/alsa-mixer/profile-sets/sj201-daemon.conf" +install -v -m 0644 files/sj201-default.pa "${ROOTFS_DIR}/etc/pulse/default.pa.d/sj201-default.pa" + +install -v -m 0644 files/aiy-voicebonnet-v2.conf "${ROOTFS_DIR}/usr/share/pulseaudio/alsa-mixer/profile-sets/aiy-voicebonnet-v2.conf" + +echo "enable pulseaudio.socket" >> "${ROOTFS_DIR}/etc/systemd/user-preset/10-ovos-user.preset" +echo "enable pulseaudio.service" >> "${ROOTFS_DIR}/etc/systemd/user-preset/10-ovos-user.preset" diff --git a/stage-shareport-spotify/SKIP b/stage-audio/02-pulseaudio/02-run-chroot.sh old mode 100644 new mode 100755 similarity index 100% rename from stage-shareport-spotify/SKIP rename to stage-audio/02-pulseaudio/02-run-chroot.sh diff --git a/stage-audio/01-speech/files/91-pulseaudio-GeneralPlus.rules b/stage-audio/02-pulseaudio/files/91-pulseaudio-GeneralPlus.rules similarity index 100% rename from stage-audio/01-speech/files/91-pulseaudio-GeneralPlus.rules rename to stage-audio/02-pulseaudio/files/91-pulseaudio-GeneralPlus.rules diff --git a/stage-audio/02-pulseaudio/files/GeneralPlus.conf b/stage-audio/02-pulseaudio/files/GeneralPlus.conf new file mode 100644 index 0000000..e203b3d --- /dev/null +++ b/stage-audio/02-pulseaudio/files/GeneralPlus.conf @@ -0,0 +1,484 @@ +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of the +# License, or (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see . + +; Default profile definitions for the ALSA backend of PulseAudio. This +; is used as fallback for all cards that have no special mapping +; assigned (and should be good enough for the vast majority of +; cards). If you want to assign a different profile set than this one +; to a device, either set the udev property PULSE_PROFILE_SET for the +; card, or use the "profile_set" module argument when loading +; module-alsa-card. +; +; So what is this about? Simply, what we do here is map ALSA devices +; to how they are exposed in PA. We say which ALSA device string to +; use to open a device, which channel mapping to use then, and which +; mixer path to use. This is encoded in a 'mapping'. Multiple of these +; mappings can be bound together in a 'profile' which is then directly +; exposed in the UI as a card profile. Each mapping assigned to a +; profile will result in one sink/source to be created if the profile +; is selected for the card. +; +; Additionally, the path set configuration files can describe the +; decibel values assigned to the steps of the volume elements. This +; can be used to work around situations when the alsa driver doesn't +; provide any decibel information, or when the information is +; incorrect. + + +; [General] +; auto-profiles = no | yes # Instead of defining all profiles manually, autogenerate +; # them by combining every input mapping with every output mapping. +; +; [Mapping id] +; device-strings = ... # ALSA device string. %f will be replaced by the card identifier. +; channel-map = ... # Channel mapping to use for this device +; description = ... # Description for the mapping. Note that it's better to set the description +; # in the well_known_descriptions table in alsa-mixer.c than with this +; # option, because the descriptions in alsa-mixer.c are translatable. +; description-key = ... # A custom key for the well_known_descriptions table (by default the mapping +; # name is used). +; paths-input = ... # A list of mixer paths to use. Every path in this list will be probed. +; # If multiple are found to be working they will be available as device ports +; paths-output = ... +; element-input = ... # Instead of configuring a full mixer path simply configure a single +; # mixer element for volume/mute handling. The value can be an element +; # name, or name and index separated by a comma. +; element-output = ... +; priority = ... +; direction = any | input | output # Only useful for? +; +; exact-channels = yes | no # If no, and the exact number of channels is not supported, +; # allow device to be opened with another channel count +; fallback = no | yes # This mapping will only be considered if all non-fallback mappings fail +; intended-roles = ... # Set the device.intended_roles property for the sink/source. +; +; [Profile id] +; input-mappings = ... # Lists mappings for sources on this profile, those mapping must be +; # defined in this file too +; output-mappings = ... # Lists mappings for sinks on this profile, those mappings must be +; # defined in this file too +; description = ... +; priority = ... # Numeric value to deduce priority for this profile +; skip-probe = no | yes # Skip probing for availability? If this is yes then this profile +; # will be assumed as working without probing. Makes initialization +; # a bit faster but only works if the card is really known well. +; +; fallback = no | yes # This profile will only be considered if all non-fallback profiles fail +; [DecibelFix element] # Decibel fixes can be used to work around missing or incorrect dB +; # information from alsa. A decibel fix is a table that maps volume steps +; # to decibel values for one volume element. The "element" part in the +; # section title is the name of the volume element (or name and index +; # separated by a comma). +; # +; # NOTE: This feature is meant just as a help for figuring out the correct +; # decibel values. PulseAudio is not the correct place to maintain the +; # decibel mappings! +; # +; # If you need this feature, then you should make sure that when you have +; # the correct values figured out, the alsa driver developers get informed +; # too, so that they can fix the driver. +; +; db-values = ... # The option value consists of pairs of step numbers and decibel values. +; # The pairs are separated with whitespace, and steps are separated from +; # the corresponding decibel values with a colon. The values must be in an +; # increasing order. Here's an example of a valid string: +; # +; # "0:-40.50 1:-38.70 3:-33.00 11:0" +; # +; # The lowest step imposes a lower limit for hardware volume and the +; # highest step correspondingly imposes a higher limit. That means that +; # that the mixer will never be set outside those values - the rest of the +; # volume scale is done using software volume. +; # +; # As can be seen in the example, you don't need to specify a dB value for +; # each step. The dB values for skipped steps will be linearly interpolated +; # using the nearest steps that are given. + +[General] +auto-profiles = yes + +[Mapping analog-stereo] +device-strings = front:%f +channel-map = left,right +paths-output = analog-output analog-output-lineout analog-output-speaker analog-output-headphones analog-output-headphones-2 +paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic +priority = 15 + +# If everything else fails, try to use hw:0 as a stereo device... +[Mapping stereo-fallback] +device-strings = hw:%f +fallback = yes +channel-map = front-left,front-right +paths-output = analog-output analog-output-lineout analog-output-speaker analog-output-headphones analog-output-headphones-2 +paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic +priority = 1 + +# ...and if even that fails, try to use hw:0 as a mono device. +[Mapping mono-fallback] +device-strings = hw:%f +fallback = yes +channel-map = mono +paths-output = analog-output analog-output-lineout analog-output-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono +paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headset-mic +priority = 1 + +[Mapping analog-surround-21] +device-strings = surround21:%f +channel-map = front-left,front-right,lfe +paths-output = analog-output analog-output-lineout analog-output-speaker +priority = 13 +direction = output + +[Mapping analog-surround-40] +device-strings = surround40:%f +channel-map = front-left,front-right,rear-left,rear-right +paths-output = analog-output analog-output-lineout analog-output-speaker +priority = 12 +direction = output + +[Mapping analog-surround-41] +device-strings = surround41:%f +channel-map = front-left,front-right,rear-left,rear-right,lfe +paths-output = analog-output analog-output-lineout analog-output-speaker +priority = 13 +direction = output + +[Mapping analog-surround-50] +device-strings = surround50:%f +channel-map = front-left,front-right,rear-left,rear-right,front-center +paths-output = analog-output analog-output-lineout analog-output-speaker +priority = 12 +direction = output + +[Mapping analog-surround-51] +device-strings = surround51:%f +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +paths-output = analog-output analog-output-lineout analog-output-speaker +priority = 13 +direction = output + +[Mapping analog-surround-71] +device-strings = surround71:%f +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right +description = Analog Surround 7.1 +paths-output = analog-output analog-output-lineout analog-output-speaker +priority = 12 +direction = output + +[Mapping iec958-stereo] +device-strings = iec958:%f +channel-map = left,right +paths-input = iec958-stereo-input +paths-output = iec958-stereo-output +priority = 5 + +[Mapping iec958-ac3-surround-40] +device-strings = a52:%f +channel-map = front-left,front-right,rear-left,rear-right +paths-output = iec958-stereo-output +priority = 2 +direction = output + +[Mapping iec958-ac3-surround-51] +device-strings = a52:%f +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +paths-output = iec958-stereo-output +priority = 3 +direction = output + +[Mapping iec958-dts-surround-51] +device-strings = dca:%f +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +paths-output = iec958-stereo-output +priority = 3 +direction = output + +[Mapping hdmi-stereo] +description = Digital Stereo (HDMI) +device-strings = hdmi:%f +paths-output = hdmi-output-0 +channel-map = left,right +priority = 9 +direction = output + +[Mapping hdmi-surround] +description = Digital Surround 5.1 (HDMI) +device-strings = hdmi:%f +paths-output = hdmi-output-0 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 8 +direction = output + +[Mapping hdmi-surround71] +description = Digital Surround 7.1 (HDMI) +device-strings = hdmi:%f +paths-output = hdmi-output-0 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right +priority = 8 +direction = output + +[Mapping hdmi-dts-surround] +description = Digital Surround 5.1 (HDMI/DTS) +device-strings = dcahdmi:%f +paths-output = hdmi-output-0 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping hdmi-stereo-extra1] +description = Digital Stereo (HDMI 2) +device-strings = hdmi:%f,1 +paths-output = hdmi-output-1 +channel-map = left,right +priority = 7 +direction = output + +[Mapping hdmi-surround-extra1] +description = Digital Surround 5.1 (HDMI 2) +device-strings = hdmi:%f,1 +paths-output = hdmi-output-1 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping hdmi-surround71-extra1] +description = Digital Surround 7.1 (HDMI 2) +device-strings = hdmi:%f,1 +paths-output = hdmi-output-1 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right +priority = 6 +direction = output + +[Mapping hdmi-dts-surround-extra1] +description = Digital Surround 5.1 (HDMI 2/DTS) +device-strings = dcahdmi:%f,1 +paths-output = hdmi-output-1 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping hdmi-stereo-extra2] +description = Digital Stereo (HDMI 3) +device-strings = hdmi:%f,2 +paths-output = hdmi-output-2 +channel-map = left,right +priority = 7 +direction = output + +[Mapping hdmi-surround-extra2] +description = Digital Surround 5.1 (HDMI 3) +device-strings = hdmi:%f,2 +paths-output = hdmi-output-2 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping hdmi-surround71-extra2] +description = Digital Surround 7.1 (HDMI 3) +device-strings = hdmi:%f,2 +paths-output = hdmi-output-2 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right +priority = 6 +direction = output + +[Mapping hdmi-dts-surround-extra2] +description = Digital Surround 5.1 (HDMI 3/DTS) +device-strings = dcahdmi:%f,2 +paths-output = hdmi-output-2 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping hdmi-stereo-extra3] +description = Digital Stereo (HDMI 4) +device-strings = hdmi:%f,3 +paths-output = hdmi-output-3 +channel-map = left,right +priority = 7 +direction = output + +[Mapping hdmi-surround-extra3] +description = Digital Surround 5.1 (HDMI 4) +device-strings = hdmi:%f,3 +paths-output = hdmi-output-3 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping hdmi-surround71-extra3] +description = Digital Surround 7.1 (HDMI 4) +device-strings = hdmi:%f,3 +paths-output = hdmi-output-3 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right +priority = 6 +direction = output + +[Mapping hdmi-dts-surround-extra3] +description = Digital Surround 5.1 (HDMI 4/DTS) +device-strings = dcahdmi:%f,3 +paths-output = hdmi-output-3 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping hdmi-stereo-extra4] +description = Digital Stereo (HDMI 5) +device-strings = hdmi:%f,4 +paths-output = hdmi-output-4 +channel-map = left,right +priority = 7 +direction = output + +[Mapping hdmi-surround-extra4] +description = Digital Surround 5.1 (HDMI 5) +device-strings = hdmi:%f,4 +paths-output = hdmi-output-4 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping hdmi-surround71-extra4] +description = Digital Surround 7.1 (HDMI 5) +device-strings = hdmi:%f,4 +paths-output = hdmi-output-4 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right +priority = 6 +direction = output + +[Mapping hdmi-dts-surround-extra4] +description = Digital Surround 5.1 (HDMI 5/DTS) +device-strings = dcahdmi:%f,4 +paths-output = hdmi-output-4 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping hdmi-stereo-extra5] +description = Digital Stereo (HDMI 6) +device-strings = hdmi:%f,5 +paths-output = hdmi-output-5 +channel-map = left,right +priority = 7 +direction = output + +[Mapping hdmi-surround-extra5] +description = Digital Surround 5.1 (HDMI 6) +device-strings = hdmi:%f,5 +paths-output = hdmi-output-5 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping hdmi-surround71-extra5] +description = Digital Surround 7.1 (HDMI 6) +device-strings = hdmi:%f,5 +paths-output = hdmi-output-5 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right +priority = 6 +direction = output + +[Mapping hdmi-dts-surround-extra5] +description = Digital Surround 5.1 (HDMI 6/DTS) +device-strings = dcahdmi:%f,5 +paths-output = hdmi-output-5 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping hdmi-stereo-extra6] +description = Digital Stereo (HDMI 7) +device-strings = hdmi:%f,6 +paths-output = hdmi-output-6 +channel-map = left,right +priority = 7 +direction = output + +[Mapping hdmi-surround-extra6] +description = Digital Surround 5.1 (HDMI 7) +device-strings = hdmi:%f,6 +paths-output = hdmi-output-6 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping hdmi-surround71-extra6] +description = Digital Surround 7.1 (HDMI 7) +device-strings = hdmi:%f,6 +paths-output = hdmi-output-6 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right +priority = 6 +direction = output + +[Mapping hdmi-dts-surround-extra6] +description = Digital Surround 5.1 (HDMI 7/DTS) +device-strings = dcahdmi:%f,6 +paths-output = hdmi-output-6 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping hdmi-stereo-extra7] +description = Digital Stereo (HDMI 8) +device-strings = hdmi:%f,7 +paths-output = hdmi-output-7 +channel-map = left,right +priority = 7 +direction = output + +[Mapping hdmi-surround-extra7] +description = Digital Surround 5.1 (HDMI 8) +device-strings = hdmi:%f,7 +paths-output = hdmi-output-7 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping hdmi-surround71-extra7] +description = Digital Surround 7.1 (HDMI 8) +device-strings = hdmi:%f,7 +paths-output = hdmi-output-7 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right +priority = 6 +direction = output + +[Mapping hdmi-dts-surround-extra7] +description = Digital Surround 5.1 (HDMI 8/DTS) +device-strings = dcahdmi:%f,7 +paths-output = hdmi-output-7 +channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe +priority = 6 +direction = output + +[Mapping multichannel-output] +device-strings = hw:%f +channel-map = left,right,rear-left,rear-right +exact-channels = false +fallback = yes +priority = 1 +direction = output + +[Mapping multichannel-input] +device-strings = hw:%f +channel-map = left,right,rear-left,rear-right +exact-channels = false +fallback = yes +priority = 1 +direction = input + +[Profile analog-stereo+iec958-stereo] +description = Analog Stereo Duplex + Digital Stereo Output +input-mappings = analog-stereo +output-mappings = analog-stereo iec958-stereo +skip-probe = yes diff --git a/stage-audio/02-pulseaudio/files/aiy-voicebonnet-v2.conf b/stage-audio/02-pulseaudio/files/aiy-voicebonnet-v2.conf new file mode 100644 index 0000000..951ddad --- /dev/null +++ b/stage-audio/02-pulseaudio/files/aiy-voicebonnet-v2.conf @@ -0,0 +1,30 @@ +options snd_rpi_googlevoicehat_soundcard index=0 + +pcm.softvol { + type softvol + slave.pcm dmix + control { + name Master + card 0 + } +} + +pcm.micboost { + type route + slave.pcm dsnoop + ttable { + 0.0 30.0 + 1.1 30.0 + } +} + +pcm.!default { + type asym + playback.pcm "plug:softvol" + capture.pcm "plug:micboost" +} + +ctl.!default { + type hw + card 0 +} diff --git a/stage-audio/01-speech/files/asound.conf b/stage-audio/02-pulseaudio/files/asound.conf similarity index 100% rename from stage-audio/01-speech/files/asound.conf rename to stage-audio/02-pulseaudio/files/asound.conf diff --git a/stage-audio/02-pulseaudio/files/default-asound.state b/stage-audio/02-pulseaudio/files/default-asound.state new file mode 100644 index 0000000..f60b64b --- /dev/null +++ b/stage-audio/02-pulseaudio/files/default-asound.state @@ -0,0 +1,57 @@ +state.ALSA { + control.1 { + iface MIXER + name 'PCM Playback Volume' + value -31 + comment { + access 'read write' + type INTEGER + count 1 + range '-10239 - 400' + dbmin -9999999 + dbmax 400 + dbvalue.0 -31 + } + } + control.2 { + iface MIXER + name 'PCM Playback Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.3 { + iface MIXER + name 'PCM Playback Route' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 3' + } + } + control.4 { + iface PCM + name 'IEC958 Playback Default' + value '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + comment { + access 'read write' + type IEC958 + count 1 + } + } + control.5 { + iface PCM + name 'IEC958 Playback Con Mask' + value '0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + comment { + access read + type IEC958 + count 1 + } + } +} diff --git a/stage-audio/01-speech/files/pulseaudio-daemon.conf b/stage-audio/02-pulseaudio/files/pulseaudio-daemon.conf similarity index 100% rename from stage-audio/01-speech/files/pulseaudio-daemon.conf rename to stage-audio/02-pulseaudio/files/pulseaudio-daemon.conf diff --git a/stage-audio/01-speech/files/pulseaudio-system.pa b/stage-audio/02-pulseaudio/files/pulseaudio-system.pa similarity index 97% rename from stage-audio/01-speech/files/pulseaudio-system.pa rename to stage-audio/02-pulseaudio/files/pulseaudio-system.pa index 1065450..abe3b00 100644 --- a/stage-audio/01-speech/files/pulseaudio-system.pa +++ b/stage-audio/02-pulseaudio/files/pulseaudio-system.pa @@ -65,12 +65,13 @@ load-module module-position-event-sounds # load-module module-suspend-on-idle ### OpenVoiceOS Audio Settings +#load-module module-alsa-sink device=hdmi:0 load-module module-role-ducking load-module module-combine-sink sink_name=OpenVoiceOS set-default-sink OpenVoiceOS ### Enable Echo/Noise-Cancellation -#load-module module-echo-cancel aec_method=webrtc source_name=echoCancel_source sink_name=echoCancel_sink +#load-module module-echo-cancel aec_method=webrtc source_name=echoCancel_source #sink_name=echoCancel_sink #set-default-source echoCancel_source #set-default-sink echoCancel_sink diff --git a/stage-audio/02-pulseaudio/files/seeed-voicecard-4mic-daemon.conf b/stage-audio/02-pulseaudio/files/seeed-voicecard-4mic-daemon.conf new file mode 100644 index 0000000..faee7ca --- /dev/null +++ b/stage-audio/02-pulseaudio/files/seeed-voicecard-4mic-daemon.conf @@ -0,0 +1,95 @@ +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see . + +## Configuration file for the PulseAudio daemon. See pulse-daemon.conf(5) for +## more information. Default values are commented out. Use either ; or # for +## commenting. + +; daemonize = no +; fail = yes +; allow-module-loading = yes +; allow-exit = yes +; use-pid-file = yes +; system-instance = no +; local-server-type = user +; enable-shm = yes +; enable-memfd = yes +; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB +; lock-memory = no +; cpu-limit = no + +; high-priority = yes +; nice-level = -11 + +; realtime-scheduling = yes +; realtime-priority = 5 + +; exit-idle-time = 20 +; scache-idle-time = 20 + +; dl-search-path = (depends on architecture) + +; load-default-script-file = yes +; default-script-file = /etc/pulse/default.pa + +; log-target = auto +; log-level = notice +; log-meta = no +; log-time = no +; log-backtrace = 0 + +; resample-method = speex-float-1 +; enable-remixing = yes +; enable-lfe-remixing = no +; lfe-crossover-freq = 0 + +; flat-volumes = yes + +; rlimit-fsize = -1 +; rlimit-data = -1 +; rlimit-stack = -1 +; rlimit-core = -1 +; rlimit-as = -1 +; rlimit-rss = -1 +; rlimit-nproc = -1 +; rlimit-nofile = 256 +; rlimit-memlock = -1 +; rlimit-locks = -1 +; rlimit-sigpending = -1 +; rlimit-msgqueue = -1 +; rlimit-nice = 31 +; rlimit-rtprio = 9 +; rlimit-rttime = 200000 + +; default-sample-format = s16le +; default-sample-rate = 96000 +; alternate-sample-rate = 48000 +; default-sample-channels = 4 +; default-channel-map = front-left,front-right + +; default-fragments = 4 +; default-fragment-size-msec = 25 + +; enable-deferred-volume = yes +; deferred-volume-safety-margin-usec = 8000 +; deferred-volume-extra-delay-usec = 0 + +# OpenVoiceOS Audio Settings +resample-method = ffmpeg +default-sample-format = s16le +default-sample-rate = 96000 +default-sample-channels = 4 +avoid-resampling = true +; flat-volumes = no diff --git a/stage-audio/02-pulseaudio/files/seeed-voicecard-4mic-default.pa b/stage-audio/02-pulseaudio/files/seeed-voicecard-4mic-default.pa new file mode 100644 index 0000000..af6c0c2 --- /dev/null +++ b/stage-audio/02-pulseaudio/files/seeed-voicecard-4mic-default.pa @@ -0,0 +1,72 @@ +#!/usr/bin/pulseaudio -nF +# +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see . + +# This startup script is used only if PulseAudio is started in system +# mode. + +### Automatically restore the volume of streams and devices +load-module module-device-restore +load-module module-stream-restore +load-module module-card-restore + +### Automatically load driver modules depending on the hardware available +.ifexists module-udev-detect.so +load-module module-udev-detect tsched=0 +.else +### Use the static hardware detection module (for systems that lack udev support) +load-module module-detect +.endif + +### Automatically load driver modules for Bluetooth hardware +.ifexists module-bluetooth-policy.so +load-module module-bluetooth-policy +.endif + +.ifexists module-bluetooth-discover.so +load-module module-bluetooth-discover +.endif + +### Load several protocols +.ifexists module-esound-protocol-unix.so +load-module module-esound-protocol-unix +.endif +load-module module-native-protocol-unix auth-anonymous=1 + +### Network access (may be configured with paprefs, so leave this commented + ### here if you plan to use paprefs) +#load-module module-esound-protocol-tcp +load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/16;172.16.0.0/12;10.0.0.0/8 auth-anonymous=1 +load-module module-zeroconf-publish + +### Automatically restore the default sink/source when changed by the user +### during runtime +### NOTE: This should be loaded as early as possible so that subsequent modules +### that look up the default sink/source get the right value +load-module module-default-device-restore + +# Enable positioned event sounds +load-module module-position-event-sounds + +### OpenVoiceOS Audio Settings +load-module module-role-ducking +load-module module-combine-sink sink_name=OpenVoiceOS +set-default-sink OpenVoiceOS + +### Enable Echo/Noise-Cancellation +#load-module module-echo-cancel aec_method=webrtc source_name=echoCancel_source sink_name=echoCancel_sink +#set-default-source echoCancel_source +#set-default-sink echoCancel_sink diff --git a/stage-audio/02-pulseaudio/files/seeed-voicecard-8mic-daemon.conf b/stage-audio/02-pulseaudio/files/seeed-voicecard-8mic-daemon.conf new file mode 100644 index 0000000..42b6e75 --- /dev/null +++ b/stage-audio/02-pulseaudio/files/seeed-voicecard-8mic-daemon.conf @@ -0,0 +1,95 @@ +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see . + +## Configuration file for the PulseAudio daemon. See pulse-daemon.conf(5) for +## more information. Default values are commented out. Use either ; or # for +## commenting. + +; daemonize = no +; fail = yes +; allow-module-loading = yes +; allow-exit = yes +; use-pid-file = yes +; system-instance = no +; local-server-type = user +; enable-shm = yes +; enable-memfd = yes +; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB +; lock-memory = no +; cpu-limit = no + +; high-priority = yes +; nice-level = -11 + +; realtime-scheduling = yes +; realtime-priority = 5 + +; exit-idle-time = 20 +; scache-idle-time = 20 + +; dl-search-path = (depends on architecture) + +; load-default-script-file = yes +; default-script-file = /etc/pulse/default.pa + +; log-target = auto +; log-level = notice +; log-meta = no +; log-time = no +; log-backtrace = 0 + +; resample-method = speex-float-1 +; enable-remixing = yes +; enable-lfe-remixing = no +; lfe-crossover-freq = 0 + +; flat-volumes = yes + +; rlimit-fsize = -1 +; rlimit-data = -1 +; rlimit-stack = -1 +; rlimit-core = -1 +; rlimit-as = -1 +; rlimit-rss = -1 +; rlimit-nproc = -1 +; rlimit-nofile = 256 +; rlimit-memlock = -1 +; rlimit-locks = -1 +; rlimit-sigpending = -1 +; rlimit-msgqueue = -1 +; rlimit-nice = 31 +; rlimit-rtprio = 9 +; rlimit-rttime = 200000 + +; default-sample-format = s32le +; default-sample-rate = 96000 +; alternate-sample-rate = 48000 +; default-sample-channels = 8 +; default-channel-map = front-left,front-right + +; default-fragments = 4 +; default-fragment-size-msec = 25 + +; enable-deferred-volume = yes +; deferred-volume-safety-margin-usec = 8000 +; deferred-volume-extra-delay-usec = 0 + +# OpenVoiceOS Audio Settings +resample-method = ffmpeg +default-sample-format = s32le +default-sample-rate = 96000 +default-sample-channels = 8 +avoid-resampling = true +; flat-volumes = no diff --git a/stage-audio/02-pulseaudio/files/seeed-voicecard-8mic-default.pa b/stage-audio/02-pulseaudio/files/seeed-voicecard-8mic-default.pa new file mode 100644 index 0000000..790342a --- /dev/null +++ b/stage-audio/02-pulseaudio/files/seeed-voicecard-8mic-default.pa @@ -0,0 +1,72 @@ +#!/usr/bin/pulseaudio -nF +# +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see . + +# This startup script is used only if PulseAudio is started in system +# mode. + +### Automatically restore the volume of streams and devices +load-module module-device-restore +load-module module-stream-restore +load-module module-card-restore + +### Automatically load driver modules depending on the hardware available +.ifexists module-udev-detect.so +load-module module-udev-detect tsched=0 +.else +### Use the static hardware detection module (for systems that lack udev support) +load-module module-detect +.endif + +### Automatically load driver modules for Bluetooth hardware +.ifexists module-bluetooth-policy.so +load-module module-bluetooth-policy +.endif + +.ifexists module-bluetooth-discover.so +load-module module-bluetooth-discover +.endif + +### Load several protocols +.ifexists module-esound-protocol-unix.so +load-module module-esound-protocol-unix +.endif +load-module module-native-protocol-unix auth-anonymous=1 + +### Network access (may be configured with paprefs, so leave this commented + ### here if you plan to use paprefs) +#load-module module-esound-protocol-tcp +load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/16;172.16.0.0/12;10.0.0.0/8 auth-anonymous=1 +load-module module-zeroconf-publish + +### Automatically restore the default sink/source when changed by the user +### during runtime +### NOTE: This should be loaded as early as possible so that subsequent modules +### that look up the default sink/source get the right value +load-module module-default-device-restore + +### Enable positioned event sounds +load-module module-position-event-sounds + +### OpenVoiceOS Audio Settings +load-module module-role-ducking +load-module module-combine-sink sink_name=OpenVoiceOS +set-default-sink OpenVoiceOS + +### Enable Echo/Noise-Cancellation +#load-module module-echo-cancel aec_method=webrtc source_name=echoCancel_source sink_name=echoCancel_sink +#set-default-source echoCancel_source +#set-default-sink echoCancel_sink diff --git a/stage-audio/02-pulseaudio/files/sj201-daemon.conf b/stage-audio/02-pulseaudio/files/sj201-daemon.conf new file mode 100644 index 0000000..0ff1469 --- /dev/null +++ b/stage-audio/02-pulseaudio/files/sj201-daemon.conf @@ -0,0 +1,98 @@ +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see . + +## Configuration file for the PulseAudio daemon. See pulse-daemon.conf(5) for +## more information. Default values are commented out. Use either ; or # for +## commenting. + +; daemonize = no +; fail = yes +; allow-module-loading = yes +; allow-exit = yes +; use-pid-file = yes +; system-instance = no +; local-server-type = user +; enable-shm = yes +; enable-memfd = yes +; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB +; lock-memory = no +; cpu-limit = no + +; high-priority = yes +; nice-level = -11 + +; realtime-scheduling = yes +; realtime-priority = 5 + +; exit-idle-time = 20 +; scache-idle-time = 20 + +; dl-search-path = (depends on architecture) + +; load-default-script-file = yes +; default-script-file = /etc/pulse/default.pa + +; log-target = auto +; log-level = notice +; log-meta = no +; log-time = no +; log-backtrace = 0 + +; resample-method = speex-float-1 +; avoid-resampling = false +; enable-remixing = yes +; remixing-use-all-sink-channels = yes +; enable-lfe-remixing = no +; lfe-crossover-freq = 0 + +; flat-volumes = yes + +; rlimit-fsize = -1 +; rlimit-data = -1 +; rlimit-stack = -1 +; rlimit-core = -1 +; rlimit-as = -1 +; rlimit-rss = -1 +; rlimit-nproc = -1 +; rlimit-nofile = 256 +; rlimit-memlock = -1 +; rlimit-locks = -1 +; rlimit-sigpending = -1 +; rlimit-msgqueue = -1 +; rlimit-nice = 31 +; rlimit-rtprio = 9 +; rlimit-rttime = 200000 + +; default-sample-format = s16le +; default-sample-rate = 44100 +; alternate-sample-rate = 48000 +; default-sample-channels = 2 +; default-channel-map = front-left,front-right + +; default-fragments = 4 +; default-fragment-size-msec = 25 + +; enable-deferred-volume = yes +; deferred-volume-safety-margin-usec = 8000 +; deferred-volume-extra-delay-usec = 0 + +# OpenVoiceOS Audio Settings +resample-method = ffmpeg +default-sample-format = s32le +default-sample-rate = 48000 +alternate-sample-rate = 44100 +default-sample-channels = 2 +default-channel-map = front-left,front-right +; flat-volumes = no diff --git a/stage-audio/02-pulseaudio/files/sj201-default.pa b/stage-audio/02-pulseaudio/files/sj201-default.pa new file mode 100644 index 0000000..d573670 --- /dev/null +++ b/stage-audio/02-pulseaudio/files/sj201-default.pa @@ -0,0 +1,75 @@ +#!/usr/bin/pulseaudio -nF +# +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see . + +# This startup script is used only if PulseAudio is started in system +# mode. + +### Automatically restore the volume of streams and devices +load-module module-device-restore +load-module module-stream-restore +load-module module-card-restore + +### Automatically load driver modules depending on the hardware available +.ifexists module-udev-detect.so +load-module module-udev-detect tsched=0 +.else +### Use the static hardware detection module (for systems that lack udev/hal support) +load-module module-detect +.endif + +### Automatically load driver modules for Bluetooth hardware +.ifexists module-bluetooth-policy.so +load-module module-bluetooth-policy +.endif + +.ifexists module-bluetooth-discover.so +load-module module-bluetooth-discover +.endif + +### Load several protocols +.ifexists module-esound-protocol-unix.so +load-module module-esound-protocol-unix +.endif +load-module module-native-protocol-unix auth-anonymous=1 + +### Network access (may be configured with paprefs, so leave this commented + ### here if you plan to use paprefs) +#load-module module-esound-protocol-tcp +load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/16;172.16.0.0/12;10.0.0.0/8 auth-anonymous=1 +load-module module-zeroconf-publish + +### Automatically restore the default sink/source when changed by the user +### during runtime +### NOTE: This should be loaded as early as possible so that subsequent modules +### that look up the default sink/source get the right value +load-module module-default-device-restore + +### Enable positioned event sounds +load-module module-position-event-sounds + +### OpenVoiceOS Audio Settings +load-module module-role-ducking +load-module module-combine-sink sink_name=OpenVoiceOS +load-module module-remap-source source_name=VF_ASR_L source_properties="device.description='VocalFusion ASR recording'" master=alsa_input.platform-asoc-simple-card.0.xvf3510-2mic remix=no master_channel_map=front-left channel_map=mono +load-module module-remap-source source_name=VF_Comms_R source_properties="device.description='VocalFusion Comms recording'" master=alsa_input.platform-asoc-simple-card.0.xvf3510-2mic remix=no master_channel_map=front-right channel_map=mono +set-default-source VF_ASR_L +set-default-sink OpenVoiceOS + +### Enable Echo/Noise-Cancellation +#load-module module-echo-cancel aec_method=webrtc source_name=echoCancel_source sink_name=echoCancel_sink +#set-default-source echoCancel_source +#set-default-sink echoCancel_sink diff --git a/stage-audio/03-hardware/01-run.sh b/stage-audio/03-hardware/01-run.sh new file mode 100755 index 0000000..e4d251e --- /dev/null +++ b/stage-audio/03-hardware/01-run.sh @@ -0,0 +1,27 @@ +#!/bin/bash -e + +install -v -d -m 0755 "${ROOTFS_DIR}/etc/modules-load.d" +install -v -m 0644 files/i2c.conf "${ROOTFS_DIR}/etc/modules-load.d/i2c.conf" + +install -v -m 0644 files/i2csound.service "${ROOTFS_DIR}/etc/systemd/system/i2csound.service" +install -v -m 0755 files/ovos-i2csound "${ROOTFS_DIR}/usr/libexec/ovos-i2csound" +install -v -m 0644 files/99-i2c.rules "${ROOTFS_DIR}/usr/lib/udev/rules.d/99-i2c.rules" + +install -v -d -m 0755 "${ROOTFS_DIR}/etc/voicecard" +install -v -m 0644 files/wm8960_asound.state "${ROOTFS_DIR}/etc/voicecard/wm8960_asound.state" +install -v -m 0644 files/ac108_asound.state "${ROOTFS_DIR}/etc/voicecard/ac108_asound.state" +install -v -m 0644 files/ac108_6mic.state "${ROOTFS_DIR}/etc/voicecard/ac108_6mic.state" + +install -v -m 0644 files/xvf3510-flash "${ROOTFS_DIR}/usr/libexec/xvf3510-flash" +install -v -m 0644 files/xvf3510.dtbo "${ROOTFS_DIR}/boot/firmware/xvf3510.dtbo" +install -v -d -m 0755 "${ROOTFS_DIR}/usr/lib/firmware" +install -v -d -m 0755 "${ROOTFS_DIR}/usr/lib/firmware/xvf3510" +install -v -m 0644 files/app_xvf3510_int_spi_boot_v4_1_0.bin "${ROOTFS_DIR}/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_1_0.bin" +install -v -m 0644 files/sj201-reset-led "${ROOTFS_DIR}/usr/bin/sj201-reset-led" +install -v -m 0644 files/tas5806-init "${ROOTFS_DIR}/usr/bin/tas5806-init" + +install -v -m 0644 files/91-vocalfusion.rules "${ROOTFS_DIR}/etc/udev/rules.d/91-vocalfusion.rules" +install -v -m 0644 files/99-gpio.rules "${ROOTFS_DIR}/etc/udev/rules.d/99-gpio.rules" + + +echo "enable i2csound.service" >> "${ROOTFS_DIR}/etc/systemd/system-preset/10-ovos-system.preset" diff --git a/stage-audio/03-hardware/02-run-chroot.sh b/stage-audio/03-hardware/02-run-chroot.sh new file mode 100755 index 0000000..900817b --- /dev/null +++ b/stage-audio/03-hardware/02-run-chroot.sh @@ -0,0 +1,38 @@ +#/bin/bash -e + +if [[ ! ${VIRTUAL_ENV} ]]; then +source /home/ovos/.venv/bin/activate; +fi + +kernels=($(ls /lib/modules)) +echo "Looking for kernel with build dir in ${kernels[*]}" +for k in "${kernels[@]}"; do +if [[ "${k}" == *2712 ]]; then +echo "RPi5 kernel" +else +kernel="${k}" +echo "Selected kernel ${kernel}" +break +fi +done + +# VocalFusion SJ201 drivers +cd /home/ovos +git clone https://github.com/OpenVoiceOS/VocalFusionDriver +cd VocalFusionDriver/driver +sed -i "s|\$(shell uname -r)|$kernel|" Makefile +make all +mkdir -p "/lib/modules/${kernel}/kernel/drivers/vocalfusion" +cp vocalfusion* "/lib/modules/${kernel}/kernel/drivers/vocalfusion" +cd /home/ovos +rm -rf VocalFusionDriver +depmod "${kernel}" -a + +pip3 install smbus smbus2 spidev rpi.gpio + +pip3 install git+https://github.com/NeonGeckoCom/sj201-interface +pip3 install git+https://github.com/NeonGeckoCom/neon-phal-plugin-linear_led +pip3 install git+https://github.com/NeonGeckoCom/neon-phal-plugin-switches +pip3 install git+https://github.com/NeonGeckoCom/neon-phal-plugin-fan + +deactivate diff --git a/stage-audio/03-hardware/files/91-vocalfusion.rules b/stage-audio/03-hardware/files/91-vocalfusion.rules new file mode 100644 index 0000000..c853946 --- /dev/null +++ b/stage-audio/03-hardware/files/91-vocalfusion.rules @@ -0,0 +1,7 @@ +SUBSYSTEM!="sound", GOTO="vocalfusion_end" +ACTION!="change", GOTO="vocalfusion_end" +KERNEL!="card*", GOTO="vocalfusion_end" + +ATTR{id}=="sndxmosvocalfus",ENV{PULSE_PROFILE_SET}="xvf3510.conf" + +LABEL="vocalfusion_end" diff --git a/stage-audio/03-hardware/files/99-gpio.rules b/stage-audio/03-hardware/files/99-gpio.rules new file mode 100644 index 0000000..02364de --- /dev/null +++ b/stage-audio/03-hardware/files/99-gpio.rules @@ -0,0 +1,3 @@ +SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", ACTION=="add", PROGRAM="/bin/sh -c 'chown -R root:gpio /sys/class/bcm2835-gpiomem/gpiomem/ ; chmod -R 660 /sys/class/bcm2835-gpiomem/gpiomem'" +SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'" +SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value /dev/gpiomem ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value /dev/gpiomem'" diff --git a/stage-audio/03-hardware/files/99-i2c.rules b/stage-audio/03-hardware/files/99-i2c.rules new file mode 100644 index 0000000..dcd254e --- /dev/null +++ b/stage-audio/03-hardware/files/99-i2c.rules @@ -0,0 +1 @@ +SUBSYSTEM=="i2c-dev", TAG+="systemd", ENV{SYSTEMD_WANTS}="i2csound.service" diff --git a/stage-audio/03-hardware/files/ac108_6mic.state b/stage-audio/03-hardware/files/ac108_6mic.state new file mode 100644 index 0000000..0920cdb --- /dev/null +++ b/stage-audio/03-hardware/files/ac108_6mic.state @@ -0,0 +1,337 @@ +state.ALSA { + control.1 { + iface MIXER + name 'PCM Playback Volume' + value 400 + comment { + access 'read write' + type INTEGER + count 1 + range '-10239 - 400' + dbmin -9999999 + dbmax 400 + dbvalue.0 400 + } + } + control.2 { + iface MIXER + name 'PCM Playback Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.3 { + iface MIXER + name 'PCM Playback Route' + value 1 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 2' + } + } + control.4 { + iface PCM + name 'IEC958 Playback Default' + value '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + comment { + access 'read write' + type IEC958 + count 1 + } + } + control.5 { + iface PCM + name 'IEC958 Playback Con Mask' + value '0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + comment { + access read + type IEC958 + count 1 + } + } + control.6 { + iface PCM + name 'IEC958 Playback PCM Stream' + value '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + comment { + access 'read write inactive' + type IEC958 + count 1 + } + } +} +state.seeed8micvoicec { + control.1 { + iface MIXER + name 'CH1 digital volume' + value 208 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 255' + dbmin -11925 + dbmax 7200 + dbvalue.0 3675 + } + } + control.2 { + iface MIXER + name 'CH2 digital volume' + value 208 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 255' + dbmin -11925 + dbmax 7200 + dbvalue.0 3675 + } + } + control.3 { + iface MIXER + name 'CH3 digital volume' + value 208 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 255' + dbmin -11925 + dbmax 7200 + dbvalue.0 3675 + } + } + control.4 { + iface MIXER + name 'CH4 digital volume' + value 208 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 255' + dbmin -11925 + dbmax 7200 + dbvalue.0 3675 + } + } + control.5 { + iface MIXER + name 'ADC1 PGA gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + dbmin 0 + dbmax 3100 + dbvalue.0 0 + } + } + control.6 { + iface MIXER + name 'ADC2 PGA gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + dbmin 0 + dbmax 3100 + dbvalue.0 0 + } + } + control.7 { + iface MIXER + name 'ADC3 PGA gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + dbmin 0 + dbmax 3100 + dbvalue.0 0 + } + } + control.8 { + iface MIXER + name 'ADC4 PGA gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + dbmin 0 + dbmax 3100 + dbvalue.0 0 + } + } + control.9 { + iface MIXER + name 'CH5 digital volume' + value 208 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 255' + dbmin -11925 + dbmax 7200 + dbvalue.0 3675 + } + } + control.10 { + iface MIXER + name 'CH6 digital volume' + value 208 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 255' + dbmin -11925 + dbmax 7200 + dbvalue.0 3675 + } + } + control.11 { + iface MIXER + name 'CH7 digital volume' + value 198 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 255' + dbmin -11925 + dbmax 7200 + dbvalue.0 2925 + } + } + control.12 { + iface MIXER + name 'CH8 digital volume' + value 198 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 255' + dbmin -11925 + dbmax 7200 + dbvalue.0 2925 + } + } + control.13 { + iface MIXER + name 'ADC5 PGA gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + dbmin 0 + dbmax 3100 + dbvalue.0 0 + } + } + control.14 { + iface MIXER + name 'ADC6 PGA gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + dbmin 0 + dbmax 3100 + dbvalue.0 0 + } + } + control.15 { + iface MIXER + name 'ADC7 PGA gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + dbmin 0 + dbmax 3100 + dbvalue.0 0 + } + } + control.16 { + iface MIXER + name 'ADC8 PGA gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + dbmin 0 + dbmax 3100 + dbvalue.0 0 + } + } + control.17 { + iface MIXER + name 'DAC Playback Volume' + value.0 0 + value.1 0 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 255' + dbmin -11925 + dbmax 7200 + dbvalue.0 -11925 + dbvalue.1 -11925 + } + } + control.18 { + iface MIXER + name 'Speaker Playback Volume' + value 25 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + dbmin -4800 + dbmax -150 + dbvalue.0 -1050 + } + } + control.19 { + iface MIXER + name 'Headphone Playback Volume' + value 52 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 63' + dbmin -6300 + dbmax 0 + dbvalue.0 -1100 + } + } +} diff --git a/stage-audio/03-hardware/files/ac108_asound.state b/stage-audio/03-hardware/files/ac108_asound.state new file mode 100644 index 0000000..103bfb4 --- /dev/null +++ b/stage-audio/03-hardware/files/ac108_asound.state @@ -0,0 +1,181 @@ +state.ALSA { + control.1 { + iface MIXER + name 'PCM Playback Volume' + value 400 + comment { + access 'read write' + type INTEGER + count 1 + range '-10239 - 400' + dbmin -9999999 + dbmax 400 + dbvalue.0 400 + } + } + control.2 { + iface MIXER + name 'PCM Playback Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.3 { + iface MIXER + name 'PCM Playback Route' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 2' + } + } + control.4 { + iface PCM + name 'IEC958 Playback Default' + value '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + comment { + access 'read write' + type IEC958 + count 1 + } + } + control.5 { + iface PCM + name 'IEC958 Playback Con Mask' + value '0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + comment { + access read + type IEC958 + count 1 + } + } + control.6 { + iface PCM + name 'IEC958 Playback PCM Stream' + value '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + comment { + access 'read write inactive' + type IEC958 + count 1 + } + } +} +state.seeed4micvoicec { + control.1 { + iface MIXER + name 'CH1 digital volume' + value 222 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 255' + dbmin -11925 + dbmax 7200 + dbvalue.0 4725 + } + } + control.2 { + iface MIXER + name 'CH2 digital volume' + value 222 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 255' + dbmin -11925 + dbmax 7200 + dbvalue.0 4725 + } + } + control.3 { + iface MIXER + name 'CH3 digital volume' + value 222 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 255' + dbmin -11925 + dbmax 7200 + dbvalue.0 4725 + } + } + control.4 { + iface MIXER + name 'CH4 digital volume' + value 222 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 255' + dbmin -11925 + dbmax 7200 + dbvalue.0 4725 + } + } + control.5 { + iface MIXER + name 'ADC1 PGA gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + dbmin 0 + dbmax 3100 + dbvalue.0 0 + } + } + control.6 { + iface MIXER + name 'ADC2 PGA gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + dbmin 0 + dbmax 3100 + dbvalue.0 0 + } + } + control.7 { + iface MIXER + name 'ADC3 PGA gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + dbmin 0 + dbmax 3100 + dbvalue.0 0 + } + } + control.8 { + iface MIXER + name 'ADC4 PGA gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + dbmin 0 + dbmax 3100 + dbvalue.0 0 + } + } +} diff --git a/stage-audio/03-hardware/files/app_xvf3510_int_spi_boot_v4_1_0.bin b/stage-audio/03-hardware/files/app_xvf3510_int_spi_boot_v4_1_0.bin new file mode 100644 index 0000000..7a9ef5f Binary files /dev/null and b/stage-audio/03-hardware/files/app_xvf3510_int_spi_boot_v4_1_0.bin differ diff --git a/stage-audio/03-hardware/files/i2c.conf b/stage-audio/03-hardware/files/i2c.conf new file mode 100644 index 0000000..0cdf71f --- /dev/null +++ b/stage-audio/03-hardware/files/i2c.conf @@ -0,0 +1 @@ +i2c-dev diff --git a/stage-prep/03-sys-tweaks/files/i2csound.service b/stage-audio/03-hardware/files/i2csound.service similarity index 88% rename from stage-prep/03-sys-tweaks/files/i2csound.service rename to stage-audio/03-hardware/files/i2csound.service index 19071c3..96deacb 100644 --- a/stage-prep/03-sys-tweaks/files/i2csound.service +++ b/stage-audio/03-hardware/files/i2csound.service @@ -10,3 +10,6 @@ Before=pulseaudio.service [Service] Type=oneshot ExecStart=/usr/libexec/ovos-i2csound + +[Install] +WantedBy=multi-user.target diff --git a/stage-prep/03-sys-tweaks/files/ovos-i2csound b/stage-audio/03-hardware/files/ovos-i2csound similarity index 74% rename from stage-prep/03-sys-tweaks/files/ovos-i2csound rename to stage-audio/03-hardware/files/ovos-i2csound index 4cc6c87..e70f50c 100644 --- a/stage-prep/03-sys-tweaks/files/ovos-i2csound +++ b/stage-audio/03-hardware/files/ovos-i2csound @@ -17,15 +17,15 @@ # Set default configurations ASOUND_STATE=/var/lib/alsa/default-asound.state -PULSE_SYSTEM=/etc/pulse/pulseaudio-system.pa +PULSE_SYSTEM=/etc/pulse/system.pa.d/pulseaudio-system.pa PULSE_DAEMON=/etc/pulse/pulseaudio-daemon.conf # Scanning the I2C bus for know addresses -is_1a=$(i2cdetect -y 1 0x1a 0x1a | egrep "(1a|UU)" | awk '{print $2}') # ReSpeaker 2-mic / WM8960 -if [ "${is_1a}" == "1a" ] || [ "${is_1a}" == "UU" ] ; then -RESPEAKER2=found -echo "ReSpeaker 2-mic $RESPEAKER2" -fi +# is_1a=$(i2cdetect -y 1 0x1a 0x1a | egrep "(1a|UU)" | awk '{print $2}') # ReSpeaker 2-mic / WM8960 +# if [ "${is_1a}" == "1a" ] || [ "${is_1a}" == "UU" ] ; then +# RESPEAKER2=found +# echo "ReSpeaker 2-mic $RESPEAKER2" +# fi is_35=$(i2cdetect -y 1 0x35 0x35 | egrep "(35|UU)" | awk '{print $2}') # ReSpeaker 4-mic squared if [ "${is_35}" == "35" ] || [ "${is_35}" == "UU" ] ; then @@ -57,6 +57,10 @@ SJ201LED=found echo "Mark2-Devkit SJ201 Leds $SJ201LED" fi +is_52=$(i2cdetect -y -a 1 0x52 0x52 | egrep "(52|UU)" | awk '{print $2}') # AIY-VoiceBonnet V2 +if [ "${is_52}" == "52" ] || [ "${is_52}" == "UU" ] ; then +AIYVOICEBONNET=found +echo "AIY VoiceBonnet V2 $AIYVOICEBONNET" # Remove old configurations if [ -f /etc/pulse/system.pa ] ; then @@ -75,26 +79,26 @@ if [ -f /etc/ovos_asound.state ] ; then rm /etc/ovos_asound.state fi -if [ "$RESPEAKER2" == "found" ] && [ "$RESPEAKER4" != "found" ] ; then -echo "Installing and configuring ReSpeaker 2-mic" -dtoverlay seeed-2mic-voicecard -ASOUND_STATE=/etc/voicecard/wm8960_asound.state -fi +# if [ "$RESPEAKER2" == "found" ] && [ "$RESPEAKER4" != "found" ] ; then +# echo "Installing and configuring ReSpeaker 2-mic" +# dtoverlay seeed-2mic-voicecard +# ASOUND_STATE=/etc/voicecard/wm8960_asound.state +# fi if [ "${RESPEAKER6}" == "found" ] && [ "${RESPEAKER4}" != "found" ] ; then echo "Installing and configuring ReSpeaker 4-mic" dtoverlay seeed-4mic-voicecard ASOUND_STATE=/etc/voicecard/ac108_asound.state -PULSE_SYSTEM=/etc/pulse/seeed-voicecard-4mic-default.pa -PULSE_DAEMON=/etc/pulse/seeed-voicecard-4mic-daemon.conf +PULSE_SYSTEM=/etc/pulse/default.pa.d/seeed-voicecard-4mic-default.pa +PULSE_DAEMON=/usr/share/pulseaudio/alsa-mixer/profile-sets/seeed-voicecard-4mic-daemon.conf fi if [ "{$RESPEAKER6}" == "found" ] && [ "${RESPEAKER4}" == "found" ] ; then echo "Installing and configuring ReSpeaker 6mic" dtoverlay seeed-8mic-voicecard ASOUND_STATE=/etc/voicecard/ac108_6mic.state -PULSE_SYSTEM=/etc/pulse/seeed-voicecard-8mic-default.pa -PULSE_DAEMON=/etc/pulse/seeed-voicecard-8mic-daemon.conf +PULSE_SYSTEM=/etc/pulse/default.pa.d/seeed-voicecard-8mic-default.pa +PULSE_DAEMON=/usr/share/pulseaudio/alsa-mixer/profile-sets/seeed-voicecard-8mic-daemon.conf fi if [ "$ADAFRUIT" ] ; then @@ -116,10 +120,14 @@ fi # Reset FAN to low speed /usr/sbin/i2cset -a -y 1 0x04 101 30 i -PULSE_SYSTEM=/etc/pulse/mycroft-sj201-default.pa -PULSE_DAEMON=/etc/pulse/mycroft-sj201-daemon.conf +PULSE_SYSTEM=/etc/pulse/default.pa.d/sj201-default.pa +PULSE_DAEMON=/usr/share/pulseaudio/alsa-mixer/profile-sets/mycroft-sj201-daemon.conf fi +if [ "$AIYVOICEBONNET" ] ; then +ASOUND_STATE=/usr/share/pulseaudio/alsa-mixer/profile-sets/aiy-voicebonnet-v2.conf + +fi # Install soundstate echo "create asound status file" ln -s $ASOUND_STATE /etc/ovos_asound.state diff --git a/stage-audio/03-hardware/files/sj201-reset-led b/stage-audio/03-hardware/files/sj201-reset-led new file mode 100644 index 0000000..08b5c7c --- /dev/null +++ b/stage-audio/03-hardware/files/sj201-reset-led @@ -0,0 +1,97 @@ +#!/usr/bin/env python +########################################################################## +# sj201-reset-led +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################## +''' + Color ring test interface for Mycroft SJ201 over Pi I2C + +''' +import os +import time + +class mycroftSJ201: + DeviceAddr = 0x04 + num_pixels = 12 + + def setColor(self, pixel,colors ): + redVal = colors[0] + greenVal = colors[1] + blueVal = colors[2] + + commandOS = "i2cset -a -y 1 %d %d %d %d %d i " % ( + self.DeviceAddr, + pixel, + redVal, + greenVal, + blueVal) + + #print(commandOS) + os.system(commandOS) + + + def readMemory(self): + commandOS = " i2cget " + str(self.DeviceAddr) + " 0 16" + #print(commandOS) + os.system(commandOS) + + for x in range(4): + os.system(self.vfctrl +" GET_I2C ") + + def wheel(self, pos): + # Input a value 0 to 255 to get a color value. + # The colours are a transition r - g - b - back to r. + if pos < 0 or pos > 255: + return (0, 0, 0) + if pos < 85: + return (255 - pos * 3, pos * 3, 0) + if pos < 170: + pos -= 85 + return (0, 255 - pos * 3, pos * 3) + pos -= 170 + return (pos * 3, 0, 255 - pos * 3) + + def rainbow_cycle(self, wait): + for j in range(255): + for i in range(self.num_pixels): + rc_index = (i * 256 // self.num_pixels) + j + colors = self.wheel(rc_index & 255) + self.setColor(i,colors) + + def color_chase(self, color, wait): + for i in range(self.num_pixels): + self.setColor(i,color) + time.sleep(wait) + + def setState(self, stateNum): + self.setColor( stateNum + 12, (255, 0, 0, 0) ) + + +sj = mycroftSJ201() + +pixel = 1 +redVal = 49 +greenVal = 30 +blueVal = 255 +RED = (255, 0, 0, 0) +YELLOW = (255, 150, 0, 0) +GREEN = (0, 255, 0, 0) +CYAN = (0, 255, 255, 0) +BLUE = (0, 0, 255, 0) +PURPLE = (180, 0, 255, 0) +BLACK = (0, 0, 0, 0) + +sj.color_chase(RED,0) +time.sleep(1) +sj.color_chase(BLACK,0) diff --git a/stage-audio/03-hardware/files/tas5806-init b/stage-audio/03-hardware/files/tas5806-init new file mode 100644 index 0000000..a2e1c69 --- /dev/null +++ b/stage-audio/03-hardware/files/tas5806-init @@ -0,0 +1,195 @@ +#!/usr/bin/env python +########################################################################## +# tas5806-init +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################## +''' +install: + pip3 install smbus2 + +run: + python3 tas5806Test.py +''' +from smbus2 import SMBus +# Open i2c bus 1 and read one byte from address 80, offset 0 + +import os +import time +import subprocess +from math import log, exp + +MAX_VOL = 84 + +class tasTest: + devAddr = 0x2f + bus = "" + + commandReturn = "" + + def __init__(self): + self.bus = SMBus(1) + + def dumpData(self): + #for i in range(0x10): + # b = self.bus.read_byte_data(self.devAddr, i) + # print("%s: %s" % (hex(i), hex(b)) ) + + #print("------------------") + commandSend = 'i2cdump -y 1 ' +str( self.devAddr) +' W' + #os.system(commandSend) + self.commandReturn = os.popen(commandSend).read() + #print(self.commandReturn) + self.checkErrors() + + ''' + Check through error codes in i2cDump + ''' + def checkErrors(self): + + # register 0x37 + fsMon = self.commandReturn.splitlines()[4][25:27] + fsMonBin = "{0:08b}".format(int(fsMon, 16)) + fsMonStr = ["FS Error","","","","","","32KHz","","Reserved","48KHz","","96KHz"] + #print("FS_MON: %s (0x37)" % (fsMon)) + print("FS_MON: %s (reg: 0x37)" % fsMonStr[int(fsMon)] ) + + + # (reg: 0x70) + errorString = self.commandReturn.splitlines()[8][4:6] + errorStringBin = "{0:08b}".format(int(errorString, 16)) + if(errorStringBin[-4] == "1" ): + print("Left channel DC fault" ) + if(errorStringBin[-3] == "1" ): + print("Right channel DC fault" ) + if(errorStringBin[-2] == "1" ): + print("Left channel over current fault" ) + if(errorStringBin[-1] == "1" ): + print("Right channel over current fault" ) + + # (reg: 0x71) + errorString = self.commandReturn.splitlines()[8][7:9] + errorStringBin = "{0:08b}".format(int(errorString, 16)) + if(errorStringBin[-3] == "1" ): + print("Clock fault (reg: 0x71)" ) + + + # register 0x68 + runStatus = self.commandReturn.splitlines()[7][29:31] + runStatusBin = "{0:08b}".format(int(runStatus, 16)) + #print(runStatus) + runStatusStr = ["Deep sleep","Sleep","HIZ","Play"] + print("Run Status: %s (reg: 0x68)" % runStatusStr[int(runStatus)] ) + + def writeData(self, addr, val, comment = "" ): + self.bus.write_byte_data(self.devAddr, addr , val) + #print("write: %s: %s - %s" %(hex(addr),hex(val), comment ) ) + time.sleep(0.1) + + def close(self): + self.bus.close() + + ''' + Start Sequence for the TAS5806 + ''' + def startSequence(self): + self.writeData(0x01,0x11, "Reset Chip") #reset chip + self.writeData(0x78,0x80, "Clear Faults") #clear fault - works + self.dumpData() + self.writeData(0x01,0x00 , "Remove Reset") #remove reset + self.writeData(0x78,0x00 , "Remove Clear Fault") #remove clear fault + self.dumpData() + + #self.writeData(51,3) # 0x33 h set bit rate + #self.writeData(118,64) # 0x76 + ##self.writeData(0x6A,3 , "") + ##self.dumpData() + + #self.writeData(0x33,0x00, "16-bit") + #self.writeData(0x33,0x01, "20-bit") + #self.writeData(0x33,0x02, "24-bit") + self.writeData(0x33,0x03, "32-bit") + self.dumpData() + self.setVolume(0x60) + self.writeData(0x30,0x01, "SDOUT is the DSP input (pre-processing)") + + + self.writeData(0x03,0x00, "Deep Sleep") #Deep Sleep + self.dumpData() + #self.writeData(0x03,0x01) #Sleep + #self.dumpData() + + + self.writeData(0x03,0x02, "HiZ") #HiZ + self.dumpData() + + self.writeData(0x5C,0x01, "coefficient") #Indicate the first coefficient of a BQ is starting to write + self.dumpData() + self.writeData(0x03,0x03 , "Play") #Play + self.dumpData() + + def calc_log_y(self, x): + """ given x produce y. takes in an int + 0-100 returns a log oriented hardware + value with larger steps for low volumes + and smaller steps for loud volumes """ + if x < 0: + x = 0 + + if x > 100: + x = 100 + + x0 = 0 # input range low + x1 = 100 # input range hi + + y0 = MAX_VOL # max hw vol + y1 = 210 # min hw val + + p1 = (x - x0) / (x1 - x0) + p2 = log(y0) - log(y1) + pval = p1 * p2 + log(y1) + + return round(exp(pval)) + + def calc_log_x(self, y): + """ given y produce x. takes in an int + 30-210 returns a value from 0-100 """ + if y < 0: + y = MAX_VOL + + if y > 210: + y = 210 + + x0 = 0 # input range low + x1 = 100 # input range hi + + y0 = MAX_VOL # max hw vol + y1 = 210 # min hw val + + x = x1 - x0 + p1 = (log(y) - log(y0)) / (log(y1) - log(y0)) + + return x * p1 + x0 + + def setVolume(self, vol=1.0): + # vol takes a float from 0.0 - 1.0 + # default vol 0.5 = 50% + hw_vol = self.calc_log_y(vol * 100.0) + setVolStr = "Set Volume %s" %( str (hw_vol) ) + self.writeData(0x4c, hw_vol, setVolStr) #Set volume + +if __name__ == '__main__': + tt = tasTest() + tt.startSequence() + tt.setVolume() + tt.close() diff --git a/stage-audio/03-hardware/files/wm8960_asound.state b/stage-audio/03-hardware/files/wm8960_asound.state new file mode 100644 index 0000000..9c47ad2 --- /dev/null +++ b/stage-audio/03-hardware/files/wm8960_asound.state @@ -0,0 +1,717 @@ +state.Headphones { + control.1 { + iface MIXER + name 'Headphone Playback Volume' + value 400 + comment { + access 'read write' + type INTEGER + count 1 + range '-10239 - 400' + dbmin -9999999 + dbmax 400 + dbvalue.0 400 + } + } + control.2 { + iface MIXER + name 'Headphone Playback Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } +} +state.wm8960soundcard { + control.1 { + iface MIXER + name 'Capture Volume' + value.0 63 + value.1 63 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 63' + dbmin -1725 + dbmax 3000 + dbvalue.0 3000 + dbvalue.1 3000 + } + } + control.2 { + iface MIXER + name 'Capture Volume ZC Switch' + value.0 0 + value.1 0 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 1' + } + } + control.3 { + iface MIXER + name 'Capture Switch' + value.0 true + value.1 true + comment { + access 'read write' + type BOOLEAN + count 2 + } + } + control.4 { + iface MIXER + name 'Left Input Boost Mixer LINPUT3 Volume' + value 1 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -9999999 + dbmax 600 + dbvalue.0 -1200 + } + } + control.5 { + iface MIXER + name 'Left Input Boost Mixer LINPUT2 Volume' + value 1 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -9999999 + dbmax 600 + dbvalue.0 -1200 + } + } + control.6 { + iface MIXER + name 'Right Input Boost Mixer RINPUT3 Volume' + value 1 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -9999999 + dbmax 600 + dbvalue.0 -1200 + } + } + control.7 { + iface MIXER + name 'Right Input Boost Mixer RINPUT2 Volume' + value 1 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -9999999 + dbmax 600 + dbvalue.0 -1200 + } + } + control.8 { + iface MIXER + name 'Right Input Boost Mixer RINPUT1 Volume' + value 1 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 3' + dbmin 0 + dbmax 2900 + dbvalue.0 1300 + } + } + control.9 { + iface MIXER + name 'Left Input Boost Mixer LINPUT1 Volume' + value 1 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 3' + dbmin 0 + dbmax 2900 + dbvalue.0 1300 + } + } + control.10 { + iface MIXER + name 'Playback Volume' + value.0 255 + value.1 255 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 255' + dbmin -9999999 + dbmax 0 + dbvalue.0 0 + dbvalue.1 0 + } + } + control.11 { + iface MIXER + name 'Headphone Playback Volume' + value.0 127 + value.1 127 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 127' + dbmin -9999999 + dbmax 600 + dbvalue.0 600 + dbvalue.1 600 + } + } + control.12 { + iface MIXER + name 'Headphone Playback ZC Switch' + value.0 false + value.1 false + comment { + access 'read write' + type BOOLEAN + count 2 + } + } + control.13 { + iface MIXER + name 'Speaker Playback Volume' + value.0 127 + value.1 127 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 127' + dbmin -9999999 + dbmax 600 + dbvalue.0 600 + dbvalue.1 600 + } + } + control.14 { + iface MIXER + name 'Speaker Playback ZC Switch' + value.0 false + value.1 false + comment { + access 'read write' + type BOOLEAN + count 2 + } + } + control.15 { + iface MIXER + name 'Speaker DC Volume' + value 5 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 5' + } + } + control.16 { + iface MIXER + name 'Speaker AC Volume' + value 5 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 5' + } + } + control.17 { + iface MIXER + name 'PCM Playback -6dB Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.18 { + iface MIXER + name 'ADC Polarity' + value 'No Inversion' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'No Inversion' + item.1 'Left Inverted' + item.2 'Right Inverted' + item.3 'Stereo Inversion' + } + } + control.19 { + iface MIXER + name 'ADC High Pass Filter Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.20 { + iface MIXER + name 'DAC Polarity' + value 'No Inversion' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'No Inversion' + item.1 'Left Inverted' + item.2 'Right Inverted' + item.3 'Stereo Inversion' + } + } + control.21 { + iface MIXER + name 'DAC Deemphasis Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.22 { + iface MIXER + name '3D Filter Upper Cut-Off' + value High + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 High + item.1 Low + } + } + control.23 { + iface MIXER + name '3D Filter Lower Cut-Off' + value Low + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Low + item.1 High + } + } + control.24 { + iface MIXER + name '3D Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.25 { + iface MIXER + name '3D Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.26 { + iface MIXER + name 'ALC Function' + value Off + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Off + item.1 Right + item.2 Left + item.3 Stereo + } + } + control.27 { + iface MIXER + name 'ALC Max Gain' + value 7 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + } + } + control.28 { + iface MIXER + name 'ALC Target' + value 4 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.29 { + iface MIXER + name 'ALC Min Gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + } + } + control.30 { + iface MIXER + name 'ALC Hold Time' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.31 { + iface MIXER + name 'ALC Mode' + value ALC + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 ALC + item.1 Limiter + } + } + control.32 { + iface MIXER + name 'ALC Decay' + value 3 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.33 { + iface MIXER + name 'ALC Attack' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.34 { + iface MIXER + name 'Noise Gate Threshold' + value 9 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + } + } + control.35 { + iface MIXER + name 'Noise Gate Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.36 { + iface MIXER + name 'ADC PCM Capture Volume' + value.0 195 + value.1 195 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 255' + dbmin -9999999 + dbmax 3000 + dbvalue.0 0 + dbvalue.1 0 + } + } + control.37 { + iface MIXER + name 'Left Output Mixer Boost Bypass Volume' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -2100 + dbmax 0 + dbvalue.0 -1500 + } + } + control.38 { + iface MIXER + name 'Left Output Mixer LINPUT3 Volume' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -2100 + dbmax 0 + dbvalue.0 -1500 + } + } + control.39 { + iface MIXER + name 'Right Output Mixer Boost Bypass Volume' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -2100 + dbmax 0 + dbvalue.0 -1500 + } + } + control.40 { + iface MIXER + name 'Right Output Mixer RINPUT3 Volume' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -2100 + dbmax 0 + dbvalue.0 -1500 + } + } + control.41 { + iface MIXER + name 'ADC Data Output Select' + value 'Left Data = Left ADC; Right Data = Right ADC' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'Left Data = Left ADC; Right Data = Right ADC' + item.1 'Left Data = Left ADC; Right Data = Left ADC' + item.2 'Left Data = Right ADC; Right Data = Right ADC' + item.3 'Left Data = Right ADC; Right Data = Left ADC' + } + } + control.42 { + iface MIXER + name 'DAC Mono Mix' + value Stereo + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Stereo + item.1 Mono + } + } + control.43 { + iface MIXER + name 'Left Boost Mixer LINPUT2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.44 { + iface MIXER + name 'Left Boost Mixer LINPUT3 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.45 { + iface MIXER + name 'Left Boost Mixer LINPUT1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.46 { + iface MIXER + name 'Right Boost Mixer RINPUT2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.47 { + iface MIXER + name 'Right Boost Mixer RINPUT3 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.48 { + iface MIXER + name 'Right Boost Mixer RINPUT1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.49 { + iface MIXER + name 'Left Input Mixer Boost Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.50 { + iface MIXER + name 'Right Input Mixer Boost Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.51 { + iface MIXER + name 'Left Output Mixer PCM Playback Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.52 { + iface MIXER + name 'Left Output Mixer LINPUT3 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.53 { + iface MIXER + name 'Left Output Mixer Boost Bypass Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.54 { + iface MIXER + name 'Right Output Mixer PCM Playback Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.55 { + iface MIXER + name 'Right Output Mixer RINPUT3 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.56 { + iface MIXER + name 'Right Output Mixer Boost Bypass Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.57 { + iface MIXER + name 'Mono Output Mixer Left Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.58 { + iface MIXER + name 'Mono Output Mixer Right Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } +} diff --git a/stage-audio/03-hardware/files/xvf3510-flash b/stage-audio/03-hardware/files/xvf3510-flash new file mode 100644 index 0000000..353d236 --- /dev/null +++ b/stage-audio/03-hardware/files/xvf3510-flash @@ -0,0 +1,207 @@ +#!/usr/bin/python3 +# Copyright (c) 2019-2020, XMOS Ltd, All rights reserved +# requires dtparam=spi=on in /boot/config.txt + +""" +This script configures the XVF3510 board in boot from SPI slave and load a +binary file. It requires a bin file as input parameter. +""" + +import sys +import os +import time +import argparse +import spidev +import RPi.GPIO as GPIO +from smbus2 import SMBus +from pathlib import Path + +if sys.version[0] != '3': + print("Run this script with Python 3") + sys.exit(1) + +def bit_reversed_byte(byte_to_reverse): + """ + Function to reverse the bit-order of a byte + + Args: + byte_to_reverse: byte to process + + Retruns: + byte in reversed order + """ + return int('{:08b}'.format(byte_to_reverse)[::-1], 2) + +def set_boot_sel(): + """ + Function to set XVF3510 board in SPI slave boot mode + + Args: + None + + Returns: + None + """ + + bus = SMBus(1) + + # reset BOOT_SEL + bus.write_byte_data(0x20, 3, 0xFE) + bus.write_byte_data(0x20, 7, 0xFF) + + state = {} + for i in [2, 6]: + state[i] = bus.read_byte_data(0x20, i) + + # start reset + data_to_write = 0x00 | (state[2] & 0xDF) + bus.write_byte_data(0x20, 2, data_to_write) + data_to_write = 0x00 | (state[6] & 0xDF) + bus.write_byte_data(0x20, 6, data_to_write) + # set BOOT_SEL high + data_to_write = 0x01 + bus.write_byte_data(0x20, 3, data_to_write) + data_to_write = 0xFE + bus.write_byte_data(0x20, 7, data_to_write) + # stop reset + data_to_write = 0x20 | (state[2] & 0xDF) + bus.write_byte_data(0x20, 2, data_to_write) + data_to_write = 0x20 | (state[6] & 0xDF) + bus.write_byte_data(0x20, 6, data_to_write) + + + +def send_image(bin_filename, verbose=False, max_spi_speed_mhz = 5, block_transfer_pause_ms = 1, direct = False, delay = False): + """ + Function to send the given image to the device via SPI slave + + Args: + bin_filename: binary file containing the image to boot + verbose: flag to print debug printouts + direct: Use Pi GPIO outputs rather than the XVF3510 Pi HAT + delay: Release BootSel early to delay startup on version 4.0.0 onwards + + Returns: + None + """ + + if direct: + #setup GPIO + GPIO.setmode(GPIO.BOARD) + GPIO.setwarnings(False) + + #boot_sel = 8 + #rst_n = 10 + ''' + Mycroft board update + ''' + #GPIO.setmode(GPIO.BCM) + + boot_sel = 37 #26 #= 25 # fix these numbers to be Wiring Pi + rst_n = 13 #27 #= 2 + GPIO.setup(boot_sel, GPIO.IN) # Normally, the Pi should not drive this + GPIO.setup(rst_n, GPIO.OUT, initial=GPIO.HIGH) + + #setup SPI + spi = spidev.SpiDev() + bus_spi = 0 + device = 0 + spi.open(bus_spi, device) + + #SPI Settings + spi.max_speed_hz = int(max_spi_speed_mhz * 1000000) + spi.mode = 0b00 #XMOS supports 00 or 11 + + spi_block_size = 4096 #Limitation in spidev and xfer2 doesn't work! + + if direct: + GPIO.output(rst_n, 0) + GPIO.setup(boot_sel, GPIO.OUT, initial=GPIO.HIGH) + GPIO.output(rst_n, 1) + else: + set_boot_sel() + + # Create a table to map byte values to their bit-reversed values + reverse_table = [bit_reversed_byte(byte) for byte in range(256)] + + data = [] + with open(bin_filename, "rb") as f: + bytes_read = f.read() + data = list(bytes_read) + binary_size = len(data) + block_count = 0 + print('Read file "{0}" size: {1} Bytes'.format(args.bin_filename, binary_size)) + if binary_size % spi_block_size != 0: + print("Warning - binary file not a multiple of {} - {} remainder".format( \ + spi_block_size, binary_size % spi_block_size)) + while binary_size > 0: + block = [reverse_table[byte] for byte in data[:spi_block_size]] + del data[:spi_block_size] + binary_size = len(data) + if verbose: + print("Sending {} Bytes in block {} checksum 0x{:X}".format( \ + len(block), block_count, sum(block))) + spi.xfer(block) + + if block_count == 0: + #Long delay for PLL reboot + time.sleep(0.1) + + if delay: + # release boot_sel early to prevent startup + if direct: + GPIO.setup(boot_sel, GPIO.IN) + else: + #bus = smbus.SMBus(1) + bus = SMBus(1) + data_to_write = 0xFE + bus.write_byte_data(0x20, 3, data_to_write) + data_to_write = 0xFF + bus.write_byte_data(0x20, 7, data_to_write) + + elif binary_size > 0: + time.sleep(block_transfer_pause_ms / 1000) + block_count += 1 + print("Sending complete") + + if direct: + GPIO.setup(boot_sel, GPIO.IN) # Once booted, the Pi should not need to drive boot_sel + GPIO.setup(rst_n, GPIO.OUT, initial=GPIO.HIGH) # Once booted, the Pi should not need to drive reset + #GPIO.cleanup() + else: + #bus = smbus.SMBus(1) + bus = SMBus(1) + + # reset BOOT_SEL + data_to_write = 0xFE + bus.write_byte_data(0x20, 3, data_to_write) + data_to_write = 0xFF + bus.write_byte_data(0x20, 7, data_to_write) + + +if __name__ == "__main__": + start_time = time.time() + parser = argparse.ArgumentParser(description='Load an image via SPI slave from an RPi') + parser.add_argument('bin_filename', help='binary file name') + parser.add_argument('--direct', action='store_true', \ + help='Use just direct GPIO outputs rather than using the XVF3510 Development Kit Pi HAT') + parser.add_argument('--delay', action='store_true', \ + help='Delay xvf3510 device start. Release the BootSel pin early to prevent the XVF3510 (V4.0.0 onwards) from starting with the default I2S configuration. This gives AP a chance to configure and start the XVF3510 device.') + parser.add_argument('--max-spi-speed-mhz', type=float, default=5, \ + help='Max SPI speed in MHz') + parser.add_argument('--block-transfer-pause-ms', type=float, default=1, \ + help='pause between SPI transfers in milliseconds, default 1ms') + parser.add_argument('--verbose', action='store_true', \ + help='print debug information') + + args = parser.parse_args() + + if not Path(args.bin_filename).is_file(): + print("Error: input file {} not found".format(args.bin_filename)) + exit(1) + + send_image(args.bin_filename, args.verbose, args.max_spi_speed_mhz, args.block_transfer_pause_ms, args.direct, args.delay) + + end_time = time.time() + if args.verbose: + print("Sending image took {:.3} seconds".format(end_time - start_time)) diff --git a/stage-audio/03-hardware/files/xvf3510.dtbo b/stage-audio/03-hardware/files/xvf3510.dtbo new file mode 100644 index 0000000..b299611 Binary files /dev/null and b/stage-audio/03-hardware/files/xvf3510.dtbo differ diff --git a/stage-core/01-ovos-core/files/mycroft.conf b/stage-core/01-ovos-core/files/mycroft.conf index d099aac..50a51ac 100644 --- a/stage-core/01-ovos-core/files/mycroft.conf +++ b/stage-core/01-ovos-core/files/mycroft.conf @@ -15,7 +15,11 @@ "debug": true } }, - "remove_silence": true + "remove_silence": true, + "microphone": { + "module": "ovos-microphone-plugin-sounddevice" + }, + "device": "pulse" }, "hotwords": { "hey_mycroft": { diff --git a/stage-finalize/01-service-start/01-run.sh b/stage-finalize/01-service-start/01-run.sh index 4878776..73a9fd2 100755 --- a/stage-finalize/01-service-start/01-run.sh +++ b/stage-finalize/01-service-start/01-run.sh @@ -1,5 +1 @@ #/bin/bash -e - -install -v -d -m 0755 "${ROOTFS_DIR}/home/ovos/.local" -install -v -d -m 0755 "${ROOTFS_DIR}/home/ovos/.local/bin" - diff --git a/stage-finalize/01-service-start/02-run-chroot.sh b/stage-finalize/01-service-start/02-run-chroot.sh old mode 100644 new mode 100755 index b0d143d..1347170 --- a/stage-finalize/01-service-start/02-run-chroot.sh +++ b/stage-finalize/01-service-start/02-run-chroot.sh @@ -1,5 +1,4 @@ -# update onnxruntime to working version -pip3 install -U onnxruntime~=1.15.0 +#!/bin/bash -e chown -Rf ovos:ovos /home/ovos @@ -19,4 +18,3 @@ su -c "ln -s /ramdisk/mycroft/phal.log /home/ovos/.local/state/mycroft/" --login su -c "ln -s /ramdisk/mycroft/skills.log /home/ovos/.local/state/mycroft/" --login ovos su -c "ln -s /ramdisk/mycroft/voice.log /home/ovos/.local/state/mycroft/" --login ovos - diff --git a/stage-finalize/01-service-start/files/99-i2c.rules b/stage-finalize/01-service-start/files/99-i2c.rules new file mode 100644 index 0000000..dcd254e --- /dev/null +++ b/stage-finalize/01-service-start/files/99-i2c.rules @@ -0,0 +1 @@ +SUBSYSTEM=="i2c-dev", TAG+="systemd", ENV{SYSTEMD_WANTS}="i2csound.service" diff --git a/stage-finalize/EXPORT_IMAGE b/stage-finalize/EXPORT_IMAGE index 6dbcff4..14779c2 100644 --- a/stage-finalize/EXPORT_IMAGE +++ b/stage-finalize/EXPORT_IMAGE @@ -2,5 +2,3 @@ IMG_SUFFIX="" if [ "${USE_QEMU}" = "1" ]; then export IMG_SUFFIX="${IMG_SUFFIX}-qemu" fi - -ARCHIVE_FILENAME="raspOVOS-dev-bookworm" diff --git a/stage-ggwave/02-install-packages/01-packages b/stage-ggwave/02-install-packages/01-packages index 91f20fa..104251d 100644 --- a/stage-ggwave/02-install-packages/01-packages +++ b/stage-ggwave/02-install-packages/01-packages @@ -1,2 +1,5 @@ libsdl2-dev cmake +gstreamer1.0-plugins-ugly +gstreamer1.0-plugins-good +gstreamer1.0-plugins-bad diff --git a/stage-gui/01-install-packages/01-packages b/stage-gui/01-install-packages/01-packages index 4ab09b8..c423810 100644 --- a/stage-gui/01-install-packages/01-packages +++ b/stage-gui/01-install-packages/01-packages @@ -16,4 +16,3 @@ libkf5plasma-dev libkf5kio-dev qml-module-qtwebengine libqt5virtualkeyboard5 -libinput diff --git a/stage-gui/02-gui/01-run.sh b/stage-gui/02-gui/01-run.sh index 74cc2d5..48ef54f 100755 --- a/stage-gui/02-gui/01-run.sh +++ b/stage-gui/02-gui/01-run.sh @@ -4,5 +4,7 @@ install -v -m 0644 files/ovos-shell.service "${ROOTFS_DIR}/etc/systemd/user/ovos install -v -m 0644 files/ovos-gui.service "${ROOTFS_DIR}/etc/systemd/user/ovos-gui.service" install -v -m 0755 files/ovos-systemd-gui "${ROOTFS_DIR}/usr/libexec/ovos-systemd-gui" +echo "gpu_mem=256" >> "${ROOTFS_DIR}/boot/firmware/config.txt" + echo "enable ovos-shell.service" >> "${ROOTFS_DIR}/etc/systemd/user-preset/10-ovos-user.preset" echo "enable ovos-gui.service" >> "${ROOTFS_DIR}/etc/systemd/user-preset/10-ovos-user.preset" diff --git a/stage-gui/02-gui/02-run-chroot.sh b/stage-gui/02-gui/02-run-chroot.sh index 9e91111..f8fc349 100755 --- a/stage-gui/02-gui/02-run-chroot.sh +++ b/stage-gui/02-gui/02-run-chroot.sh @@ -6,6 +6,8 @@ pip3 install git+https://github.com/OpenVoiceOS/ovos-gui-plugin-shell-companion pip3 install git+https://github.com/OpenVoiceOS/skill-ovos-homescreen pip3 install git+https://github.com/OpenVoiceOS/ovos-gui +pip3 install evdev + # Mycroft-gui-qt5 cd /home/ovos git clone https://github.com/OpenVoiceOS/mycroft-gui-qt5.git @@ -27,7 +29,7 @@ if [[ ! -d build-testing ]] ; then fi cd build-testing cmake .. -DBUILD_WITH_QT6=OFF -DQT_MAJOR_VERSION=5 -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DKDE_INSTALL_LIBDIR=lib -DKDE_INSTALL_USE_QT_SYS_PATHS=ON -make -j4 +make make install cd /home/ovos rm -rf ovos-shell diff --git a/stage-audio/02-voice/01-run.sh b/stage-listener/01-listener/01-run.sh similarity index 100% rename from stage-audio/02-voice/01-run.sh rename to stage-listener/01-listener/01-run.sh diff --git a/stage-audio/02-voice/02-run-chroot.sh b/stage-listener/01-listener/02-run-chroot.sh similarity index 85% rename from stage-audio/02-voice/02-run-chroot.sh rename to stage-listener/01-listener/02-run-chroot.sh index 78d52b9..88df6a9 100755 --- a/stage-audio/02-voice/02-run-chroot.sh +++ b/stage-listener/01-listener/02-run-chroot.sh @@ -9,14 +9,18 @@ if [[ $python_version =~ ".9" ]]; then pip3 install -U -f https://whl.smartgic.io/ tflite_runtime else echo "${python_version} detected" - pip3 install -U -f tflite_runtime + pip3 install -U tflite_runtime fi +pip3 install fann2==1.0.7 +pip3 install git+https://github.com/MycroftAI/padatious + + pip3 install git+https://github.com/OpenVoiceOS/ovos-dinkum-listener pip3 install git+https://github.com/OpenVoiceOS/ovos-vad-plugin-silero pip3 install git+https://github.com/OpenVoiceOS/ovos-stt-plugin-server pip3 install git+https://github.com/OpenVoiceOS/ovos-ww-plugin-precise-lite pip3 install git+https://github.com/OpenVoiceOS/ovos-ww-plugin-pocketsphinx -pip3 install git+https://github.com/OpenVoiceOS/ovos-microphone-plugin-alsa +pip3 install git+https://github.com/OpenVoiceOS/ovos-microphone-plugin-sounddevice deactivate diff --git a/stage-audio/02-voice/files/ovos-dinkum-listener.service b/stage-listener/01-listener/files/ovos-dinkum-listener.service similarity index 88% rename from stage-audio/02-voice/files/ovos-dinkum-listener.service rename to stage-listener/01-listener/files/ovos-dinkum-listener.service index e57e6a8..ec9b70e 100644 --- a/stage-audio/02-voice/files/ovos-dinkum-listener.service +++ b/stage-listener/01-listener/files/ovos-dinkum-listener.service @@ -13,8 +13,6 @@ TimeoutStopSec=1m Restart=on-failure StartLimitInterval=5min StartLimitBurst=4 -#StartLimitAction=reboot-force -#WatchdogSec=30s [Install] WantedBy=ovos.service diff --git a/stage-audio/02-voice/files/ovos-systemd-dinkum-listener b/stage-listener/01-listener/files/ovos-systemd-dinkum-listener similarity index 100% rename from stage-audio/02-voice/files/ovos-systemd-dinkum-listener rename to stage-listener/01-listener/files/ovos-systemd-dinkum-listener diff --git a/stage-listener/prerun.sh b/stage-listener/prerun.sh new file mode 100755 index 0000000..e0ecdec --- /dev/null +++ b/stage-listener/prerun.sh @@ -0,0 +1,6 @@ +#!/bin/bash -e + +if [ ! -d "${ROOTFS_DIR}" ]; then + copy_previous +fi + diff --git a/stage-mark2/00-install-packages/01-packages b/stage-mark2/00-install-packages/01-packages new file mode 100644 index 0000000..20645e6 --- /dev/null +++ b/stage-mark2/00-install-packages/01-packages @@ -0,0 +1 @@ +ffmpeg diff --git a/stage-mark2/01-mark2/01-run.sh b/stage-mark2/01-mark2/01-run.sh new file mode 100755 index 0000000..7c7bbf7 --- /dev/null +++ b/stage-mark2/01-mark2/01-run.sh @@ -0,0 +1,58 @@ +#!/bin/bash -e + +install -v -m 0644 files/91-vocalfusion.rules "${ROOTFS_DIR}/etc/udev/rules.d/91-vocalfusion.rules" +install -v -m 0644 files/99-gpio.rules "${ROOTFS_DIR}/etc/udev/rules.d/99-gpio.rules" + +install -v -m 0644 files/poweroff.sh "${ROOTFS_DIR}/usr/libexec/poweroff.sh" +install -v -m 0644 files/configure_sj201_on_boot.sh "${ROOTFS_DIR}/usr/libexec/configure_sj201_on_boot.sh" +install -v -m 0644 files/shutdown_sj201.sh "${ROOTFS_DIR}/usr/libexec/shutdown_sj201.sh" +install -v -m 0644 files/one_time_sj201.sh "${ROOTFS_DIR}/usr/libexec/one_time_sj201.sh" +install -v -m 0644 files/xvf3510-flash "${ROOTFS_DIR}/usr/libexec/xvf3510-flash" + +install -v -m 0644 files/xvf3510.dtbo "${ROOTFS_DIR}/boot/firmware/xvf3510.dtbo" + +install -v -m 0644 files/poweroff.service "${ROOTFS_DIR}/etc/systemd/system/poweroff.service" +install -v -m 0644 files/sj201-shutdown.service "${ROOTFS_DIR}/etc/systemd/system/sj201-shutdown.service" +install -v -m 0644 files/sj201.service "${ROOTFS_DIR}/etc/systemd/system/sj201.service" + +if [[ -f "${ROOTFS_DIR}/etc/pulse/default.pa" || -L "${ROOTFS_DIR}/etc/pulse/default.pa" ]] ; then +echo "removing existing default.pa" +rm "${ROOTFS_DIR}/etc/pulse/default.pa" +fi +if [[ -f "${ROOTFS_DIR}/etc/pulse/daemon.conf" || -L "${ROOTFS_DIR}/etc/pulse/daemon.conf" ]] ; then +echo "removing existing daemon.conf" +rm "${ROOTFS_DIR}/etc/pulse/daemon.conf" +fi + +install -v -m 0644 files/ovos-sj201-daemon.conf "${ROOTFS_DIR}/etc/pulse/ovos-sj201-daemon.conf" +ln -s "${ROOTFS_DIR}/etc/pulse/ovos-sj201-daemon.conf" "${ROOTFS_DIR}/etc/pulse/default.conf" +install -v -m 0644 files/ovos-sj201-default.pa "${ROOTFS_DIR}/etc/pulse/ovos-sj201-default.pa" +ln -s "${ROOTFS_DIR}/etc/pulse/ovos-sj201-default.pa" "${ROOTFS_DIR}/etc/pulse/default.pa" + +if [[ -f "${ROOTFS_DIR}/etc/asound.conf" ]]; then +rm "${ROOTFS_DIR}/etc/asound.conf" +fi +install -v -m 0644 files/asound.conf "${ROOTFS_DIR}/etc/asound.conf" + +install -v -d -m 0755 "${ROOTFS_DIR}/usr/lib/firmware" +install -v -d -m 0755 "${ROOTFS_DIR}/usr/lib/firmware/xvf3510" +install -v -m 0644 files/app_xvf3510_int_spi_boot_v4_1_0.bin "${ROOTFS_DIR}/usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_1_0.bin" + +# sed -i "s|#dtparam=i2c_arm=on|dtparam=i2c_arm=on|g" "${ROOTFS_DIR}/boot/firmware/config.txt" +# sed -i "s|#dtparam=i2s=on|dtparam=i2s=on|g" "${ROOTFS_DIR}/boot/firmware/config.txt" +# sed -i "s|#dtparam=spi=on|dtparam=spi=on|g" "${ROOTFS_DIR}/boot/firmware/config.txt" +# sed -i "s|#dtparam=audio=on|dtparam=audio=on|g" "${ROOTFS_DIR}/boot/firmware/config.txt" + +cat << EOF >> "${ROOTFS_DIR}/boot/firmware/config.txt" + +dtoverlay=xvf3510 +dtparam=krnbt=on + +[pi4] + +[all] +EOF + +echo "enable poweroff.service" >> "${ROOTFS_DIR}/etc/systemd/system-preset/10-ovos-system.preset" +echo "enable sj201-shutdown.service" >> "${ROOTFS_DIR}/etc/systemd/system-preset/10-ovos-system.preset" +echo "enable sj201.service" >> "${ROOTFS_DIR}/etc/systemd/system-preset/10-ovos-system.preset" diff --git a/stage-mark2/01-mark2/02-run-chroot.sh b/stage-mark2/01-mark2/02-run-chroot.sh new file mode 100755 index 0000000..948a72b --- /dev/null +++ b/stage-mark2/01-mark2/02-run-chroot.sh @@ -0,0 +1,40 @@ +#/bin/bash -e + +if [[ ! ${VIRTUAL_ENV} ]]; then + source /home/ovos/.venv/bin/activate; +fi + +kernels=($(ls /lib/modules)) +echo "Looking for kernel with build dir in ${kernels[*]}" +for k in "${kernels[@]}"; do + if [[ "${k}" == *2712 ]]; then + echo "RPi5 kernel" + else + kernel="${k}" + echo "Selected kernel ${kernel}" + break + fi +done + +# VocalFusion SJ201 drivers +cd /home/ovos +git clone https://github.com/OpenVoiceOS/VocalFusionDriver +cd VocalFusionDriver/driver +sed -i "s|\$(shell uname -r)|$kernel|" Makefile +make all +mkdir -p "/lib/modules/${kernel}/kernel/drivers/vocalfusion" +cp vocalfusion* "/lib/modules/${kernel}/kernel/drivers/vocalfusion" +cd /home/ovos +rm -rf VocalFusionDriver +depmod "${kernel}" -a + +touch /do_sj201_config + +pip3 install smbus smbus2 spidev rpi.gpio + +pip3 install git+https://github.com/NeonGeckoCom/sj201-interface +pip3 install git+https://github.com/NeonGeckoCom/neon-phal-plugin-linear_led +pip3 install git+https://github.com/NeonGeckoCom/neon-phal-plugin-switches +pip3 install git+https://github.com/NeonGeckoCom/neon-phal-plugin-fan + +deactivate diff --git a/stage-mark2/01-mark2/files/91-vocalfusion.rules b/stage-mark2/01-mark2/files/91-vocalfusion.rules new file mode 100644 index 0000000..c853946 --- /dev/null +++ b/stage-mark2/01-mark2/files/91-vocalfusion.rules @@ -0,0 +1,7 @@ +SUBSYSTEM!="sound", GOTO="vocalfusion_end" +ACTION!="change", GOTO="vocalfusion_end" +KERNEL!="card*", GOTO="vocalfusion_end" + +ATTR{id}=="sndxmosvocalfus",ENV{PULSE_PROFILE_SET}="xvf3510.conf" + +LABEL="vocalfusion_end" diff --git a/stage-mark2/01-mark2/files/99-gpio.rules b/stage-mark2/01-mark2/files/99-gpio.rules new file mode 100644 index 0000000..02364de --- /dev/null +++ b/stage-mark2/01-mark2/files/99-gpio.rules @@ -0,0 +1,3 @@ +SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", ACTION=="add", PROGRAM="/bin/sh -c 'chown -R root:gpio /sys/class/bcm2835-gpiomem/gpiomem/ ; chmod -R 660 /sys/class/bcm2835-gpiomem/gpiomem'" +SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'" +SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value /dev/gpiomem ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value /dev/gpiomem'" diff --git a/stage-mark2/01-mark2/files/app_xvf3510_int_spi_boot_v4_1_0.bin b/stage-mark2/01-mark2/files/app_xvf3510_int_spi_boot_v4_1_0.bin new file mode 100644 index 0000000..7a9ef5f Binary files /dev/null and b/stage-mark2/01-mark2/files/app_xvf3510_int_spi_boot_v4_1_0.bin differ diff --git a/stage-mark2/01-mark2/files/asound.conf b/stage-mark2/01-mark2/files/asound.conf new file mode 100644 index 0000000..23e1f11 --- /dev/null +++ b/stage-mark2/01-mark2/files/asound.conf @@ -0,0 +1,14 @@ +# Use PulseAudio by default +pcm.!default { + type pulse + fallback "sysdefault" + hint { + show on + description "Default ALSA Output (currently PulseAudio Sound Server)" + } +} + +ctl.!default { + type pulse + fallback "sysdefault" +} diff --git a/stage-mark2/01-mark2/files/config.txt b/stage-mark2/01-mark2/files/config.txt new file mode 100644 index 0000000..e56454b --- /dev/null +++ b/stage-mark2/01-mark2/files/config.txt @@ -0,0 +1,47 @@ +# +# See /boot/overlays/README for all available options +# + +dtparam=krnbt=on + +[pi4] +dtoverlay=vc4-fkms-v3d +max_framebuffers=2 +arm_64bit=1 +arm_boost=1 + +[all] + +# Enable audio (loads snd_bcm2835) +dtparam=audio=on + +# Enable I2C interfaces on the GPIO header +dtparam=i2c_arm=on +dtparam=i2c1=on + +# Enable SPI for SJ201 Flashing +dtparam=spi=on + +# Enable Camera Support +start_x=1 + +# Set 'force_turbo=1' to disable dynamic overclocking and enable overclocking always +force_turbo=1 + +# have a properly sized image +disable_overscan=1 + +# for sound over HDMI +# hdmi_drive=2 +hdmi_ignore_cec_init=1 + +# Spec GPU Memory +gpu_mem=256 +gpu_mem_256=128 +gpu_mem_512=128 +gpu_mem_1024=128 + +# Disable rainbow splash screen +disable_splash=1 + +dtoverlay=xvf3510 diff --git a/stage-mark2/01-mark2/files/configure-audio b/stage-mark2/01-mark2/files/configure-audio new file mode 100644 index 0000000..7307259 --- /dev/null +++ b/stage-mark2/01-mark2/files/configure-audio @@ -0,0 +1,79 @@ +#!/bin/bash +# NEON AI (TM) SOFTWARE, Software Development Kit & Application Framework +# All trademark and other rights reserved by their respective owners +# Copyright 2008-2022 Neongecko.com Inc. +# Contributors: Daniel McKnight, Guy Daniels, Elon Gasper, Richard Leeds, +# Regina Bloomstine, Casimiro Ferreira, Andrii Pernatii, Kirill Hrymailo +# BSD-3 License +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Already configured +[ -f /etc/pulse/daemon.conf ] && exit 0 + +# Set default configurations +PULSE_SYSTEM=/etc/pulse/pulseaudio-system.pa +PULSE_DAEMON=/etc/pulse/pulseaudio-daemon.conf + +# Check sj201 revision if package is available +if which sj201; then + [ "$(sj201 get-revision)" != "0" ] && prefix="sj201-" +fi + +# Check platform defaults +if [ -z "${prefix}" ]; then + if $(grep -q opi5 /opt/neon/build_info.json); then + # Check for Orange Pi + prefix="opi5-" + # Configure the onboard microphone + card=$(aplay -l | grep "es8388" | cut -d ':' -f 1 | cut -d ' ' -f 2) + # PGA=Programmable Gain Amplifier + tinymix -D "${card}" set 3 4 # Capture Max PGA (0-7) + tinymix -D "${card}" set 4 2 # Capture Min PGA (0-7) + tinymix -D "${card}" set 14 192 # Capture volume (0-192) + tinymix -D "${card}" set 16 0 # Left channel volume (0-8) + tinymix -D "${card}" set 17 0 # Right channel volume (0-8) + tinymix -D "${card}" set 31 1 # Left PGA Mux (enum) + tinymix -D "${card}" set 32 1 # Right PGA Mux (enum) + tinymix -D "${card}" set 33 1 # Differential Mux (enum) + elif which dtoverlay; then + # If dtoverlay command is present, assume RPi + prefix="rpi-" + fi +fi + +if [ -n "${prefix}" ]; then + PULSE_SYSTEM="${prefix}system.pa" + PULSE_DAEMON="${prefix}daemon.conf" +fi + +if [[ -f /etc/pulse/system.pa || -L /etc/pulse/system.pa ]] ; then + echo "removing existing system.pa" + rm /etc/pulse/system.pa +fi +if [[ -f /etc/pulse/daemon.conf || -L /etc/pulse/daemon.conf ]] ; then + echo "removing existing daemon.conf" + rm /etc/pulse/daemon.conf +fi + +ln -s "${PULSE_SYSTEM}" /etc/pulse/system.pa && echo "linked ${PULSE_SYSTEM}" +ln -s "${PULSE_DAEMON}" /etc/pulse/daemon.conf && echo "linked ${PULSE_DAEMON}" diff --git a/stage-mark2/01-mark2/files/configure_sj201_on_boot.sh b/stage-mark2/01-mark2/files/configure_sj201_on_boot.sh new file mode 100644 index 0000000..ed239e7 --- /dev/null +++ b/stage-mark2/01-mark2/files/configure_sj201_on_boot.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# NEON AI (TM) SOFTWARE, Software Development Kit & Application Framework +# All trademark and other rights reserved by their respective owners +# Copyright 2008-2022 Neongecko.com Inc. +# Contributors: Daniel McKnight, Guy Daniels, Elon Gasper, Richard Leeds, +# Regina Bloomstine, Casimiro Ferreira, Andrii Pernatii, Kirill Hrymailo +# BSD-3 License +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# This needs to run as root + +if [[ ! ${VIRTUAL_ENV} ]]; then + source /home/ovos/.venv/bin/activate; +fi + +# Flash xmos firmware +xvf3510-flash --direct /usr/lib/firmware/xvf3510/app_xvf3510_int_spi_boot_v4_1_0.bin +# Init TI Amp +sj201 init-ti-amp +# Reset LEDs +sj201 reset-led green + +# Reset fan speed (NOTE: R10 will always default to 100%) +sj201 set-fan-speed 100 + +deactivate + +if [ -f /do_sj201_config ]; then + echo "Performing one-time sj201 init" + sh /usr/libexec/one_time_sj201.sh + rm /do_sj201_config +fi diff --git a/stage-mark2/01-mark2/files/one_time_sj201.sh b/stage-mark2/01-mark2/files/one_time_sj201.sh new file mode 100644 index 0000000..8184a66 --- /dev/null +++ b/stage-mark2/01-mark2/files/one_time_sj201.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# NEON AI (TM) SOFTWARE, Software Development Kit & Application Framework +# All trademark and other rights reserved by their respective owners +# Copyright 2008-2022 Neongecko.com Inc. +# Contributors: Daniel McKnight, Guy Daniels, Elon Gasper, Richard Leeds, +# Regina Bloomstine, Casimiro Ferreira, Andrii Pernatii, Kirill Hrymailo +# BSD-3 License +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Check if GPIO Fan shutdown service is required + +if [[ ! ${VIRTUAL_ENV} ]]; then + source /home/ovos/.venv/bin/activate; +fi + +rev=$(sj201 get-revision) +if [ "${rev}" == '10' ]; then + mount_firmware + echo "gpio=13=pu" >> /boot/firmware/config.txt + unmount_firmware +fi + +deactivate diff --git a/stage-mark2/01-mark2/files/ovos-sj201-daemon.conf b/stage-mark2/01-mark2/files/ovos-sj201-daemon.conf new file mode 100644 index 0000000..51216d4 --- /dev/null +++ b/stage-mark2/01-mark2/files/ovos-sj201-daemon.conf @@ -0,0 +1,98 @@ +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see . + +## Configuration file for the PulseAudio daemon. See pulse-daemon.conf(5) for +## more information. Default values are commented out. Use either ; or # for +## commenting. + +; daemonize = no +; fail = yes +; allow-module-loading = yes +; allow-exit = yes +; use-pid-file = yes +; system-instance = no +; local-server-type = user +; enable-shm = yes +; enable-memfd = yes +; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB +; lock-memory = no +; cpu-limit = no + +; high-priority = yes +; nice-level = -11 + +; realtime-scheduling = yes +; realtime-priority = 5 + +; exit-idle-time = 20 +; scache-idle-time = 20 + +; dl-search-path = (depends on architecture) + +; load-default-script-file = yes +; default-script-file = /etc/pulse/default.pa + +; log-target = auto +; log-level = notice +; log-meta = no +; log-time = no +; log-backtrace = 0 + +; resample-method = speex-float-1 +; avoid-resampling = false +; enable-remixing = yes +; remixing-use-all-sink-channels = yes +; enable-lfe-remixing = no +; lfe-crossover-freq = 0 + +; flat-volumes = yes + +; rlimit-fsize = -1 +; rlimit-data = -1 +; rlimit-stack = -1 +; rlimit-core = -1 +; rlimit-as = -1 +; rlimit-rss = -1 +; rlimit-nproc = -1 +; rlimit-nofile = 256 +; rlimit-memlock = -1 +; rlimit-locks = -1 +; rlimit-sigpending = -1 +; rlimit-msgqueue = -1 +; rlimit-nice = 31 +; rlimit-rtprio = 9 +; rlimit-rttime = 200000 + +; default-sample-format = s16le +; default-sample-rate = 44100 +; alternate-sample-rate = 48000 +; default-sample-channels = 2 +; default-channel-map = front-left,front-right + +; default-fragments = 4 +; default-fragment-size-msec = 25 + +; enable-deferred-volume = yes +; deferred-volume-safety-margin-usec = 8000 +; deferred-volume-extra-delay-usec = 0 + +# SJ201 Audio Settings +resample-method = ffmpeg +default-sample-format = s32le +default-sample-rate = 48000 +alternate-sample-rate = 44100 +default-sample-channels = 2 +default-channel-map = front-left,front-right +; flat-volumes = no diff --git a/stage-mark2/01-mark2/files/ovos-sj201-default.pa b/stage-mark2/01-mark2/files/ovos-sj201-default.pa new file mode 100644 index 0000000..5f26885 --- /dev/null +++ b/stage-mark2/01-mark2/files/ovos-sj201-default.pa @@ -0,0 +1,77 @@ +#!/usr/bin/pulseaudio -nF +# +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see . + +# This startup script is used only if PulseAudio is started in system +# mode. + +### Automatically restore the volume of streams and devices +load-module module-device-restore +load-module module-stream-restore +load-module module-card-restore + +### Automatically load driver modules depending on the hardware available +.ifexists module-udev-detect.so +load-module module-udev-detect tsched=0 +.else +### Use the static hardware detection module (for systems that lack udev/hal support) +load-module module-detect +.endif + +### Load several protocols +.ifexists module-esound-protocol-unix.so +load-module module-esound-protocol-unix +.endif +load-module module-native-protocol-unix auth-anonymous=1 + +### Network access (may be configured with paprefs, so leave this commented + ### here if you plan to use paprefs) +#load-module module-esound-protocol-tcp +load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/16;172.16.0.0/12;10.0.0.0/8 auth-anonymous=1 +load-module module-zeroconf-publish + +### Automatically restore the default sink/source when changed by the user +### during runtime +### NOTE: This should be loaded as early as possible so that subsequent modules +### that look up the default sink/source get the right value +# load-module module-default-device-restore + +### Automatically move streams to the default sink if the sink they are +### connected to dies, similar for sources +load-module module-rescue-streams + +### Make sure we always have a sink around, even if it is a null sink. +load-module module-always-sink + +### Automatically suspend sinks/sources that become idle for too long +# load-module module-suspend-on-idle + +### Enable positioned event sounds +load-module module-position-event-sounds + +### OpenVoiceOS Audio Settings +unload-module module-suspend-on-idle +load-module module-role-ducking +load-module module-combine-sink sink_name=OpenVoiceOS +load-module module-remap-source source_name=VF_ASR_L source_properties="device.description='VocalFusion ASR recording'" master=alsa_input.platform-asoc-simple-card.0.stereo-fallback remix=no master_channel_map=front-left channel_map=mono +load-module module-remap-source source_name=VF_Comms_R source_properties="device.description='VocalFusion Comms recording'" master=alsa_input.platform-asoc-simple-card.0.stereo-fallback remix=no master_channel_map=front-right channel_map=mono +set-default-source VF_ASR_L +set-default-sink OpenVoiceOS + +### Enable Echo/Noise-Cancellation +#load-module module-echo-cancel aec_method=webrtc source_name=echoCancel_source sink_name=echoCancel_sink +#set-default-source echoCancel_source +#set-default-sink echoCancel_sink diff --git a/stage-mark2/01-mark2/files/poweroff.service b/stage-mark2/01-mark2/files/poweroff.service new file mode 100644 index 0000000..5cdcf0a --- /dev/null +++ b/stage-mark2/01-mark2/files/poweroff.service @@ -0,0 +1,13 @@ +[Unit] +Description=Optionally hold OS in some state instead of shutting down. For SJ201R10, this keeps the fan and screen off. +DefaultDependencies=no +After=umount.target +Before=final.target +Conflicts=reboot.target + +[Service] +Type=oneshot +ExecStart=/bin/bash /usr/libexec/poweroff.sh + +[Install] +WantedBy=shutdown.target diff --git a/stage-mark2/01-mark2/files/poweroff.sh b/stage-mark2/01-mark2/files/poweroff.sh new file mode 100644 index 0000000..8d2da3f --- /dev/null +++ b/stage-mark2/01-mark2/files/poweroff.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# NEON AI (TM) SOFTWARE, Software Development Kit & Application Framework +# All trademark and other rights reserved by their respective owners +# Copyright 2008-2022 Neongecko.com Inc. +# Contributors: Daniel McKnight, Guy Daniels, Elon Gasper, Richard Leeds, +# Regina Bloomstine, Casimiro Ferreira, Andrii Pernatii, Kirill Hrymailo +# BSD-3 License +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +if [[ ! ${VIRTUAL_ENV} ]]; then + source /home/ovos/.venv/bin/activate; +fi +revision=$(sj201 get-revision) + +if [ "${revision}" == "10" ]; then + echo "Setting screen brightness to 0" + echo 0 > /sys/class/backlight/rpi_backlight/brightness + echo "Setting fan speed to 0" + sj201 set-fan-speed 0 + while true; do + sleep 100 + done +fi + +deactivate diff --git a/stage-mark2/01-mark2/files/shutdown_sj201.sh b/stage-mark2/01-mark2/files/shutdown_sj201.sh new file mode 100644 index 0000000..f734745 --- /dev/null +++ b/stage-mark2/01-mark2/files/shutdown_sj201.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# This needs to run as root + +# Turn Off LEDs +sj201 reset-led red +# Set fan speed to 0 +sj201 set-fan-speed 0 diff --git a/stage-mark2/01-mark2/files/sj201-shutdown.service b/stage-mark2/01-mark2/files/sj201-shutdown.service new file mode 100644 index 0000000..38cbe9a --- /dev/null +++ b/stage-mark2/01-mark2/files/sj201-shutdown.service @@ -0,0 +1,10 @@ +[Unit] +Description=SJ201 Shutdown Service + +[Service] +Type=oneshot +RemainAfterExit=true +ExecStop=/bin/bash /usr/libexec/shutdown_sj201.sh + +[Install] +WantedBy=multi-user.target diff --git a/stage-mark2/01-mark2/files/sj201-system.conf b/stage-mark2/01-mark2/files/sj201-system.conf new file mode 100644 index 0000000..f764a7b --- /dev/null +++ b/stage-mark2/01-mark2/files/sj201-system.conf @@ -0,0 +1,74 @@ +#!/usr/bin/pulseaudio -nF +# +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see . + +# This startup script is used only if PulseAudio is started in system +# mode. + +### Automatically restore the volume of streams and devices +load-module module-device-restore +load-module module-stream-restore +load-module module-card-restore + +### Automatically load driver modules depending on the hardware available +.ifexists module-udev-detect.so +load-module module-udev-detect tsched=0 +.else +### Use the static hardware detection module (for systems that lack udev/hal support) +load-module module-detect +.endif + +### Load several protocols +.ifexists module-esound-protocol-unix.so +load-module module-esound-protocol-unix +.endif +load-module module-native-protocol-unix auth-anonymous=1 + +### Network access (may be configured with paprefs, so leave this commented + ### here if you plan to use paprefs) +#load-module module-esound-protocol-tcp +load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/16;172.16.0.0/12;10.0.0.0/8 auth-anonymous=1 +load-module module-zeroconf-publish + +### Automatically restore the default sink/source when changed by the user +### during runtime +### NOTE: This should be loaded as early as possible so that subsequent modules +### that look up the default sink/source get the right value +load-module module-default-device-restore + +### Enable positioned event sounds +load-module module-position-event-sounds + +### Assistant Device Audio Settings +load-module module-role-ducking +load-module module-combine-sink sink_name=CombinedOutput + +# The Comms channel will attenuate all input audio if there is active output +# The ASR channel will subtract active output and isolate input voice audio +# https://github.com/xmos/vocalfusion-rpi-setup/blob/master/resources/asoundrc_vf_xvf3510_int +# https://www.xmos.ai/download/XVF3510-INT-Datasheet(4.1).pdf +load-module module-remap-source source_name=VF_ASR source_properties="device.description='VocalFusion ASR recording'" master=alsa_input.platform-asoc-simple-card.0.xvf3510-2mic remix=no master_channel_map=front-right channel_map=mono +load-module module-remap-source source_name=VF_Comms source_properties="device.description='VocalFusion Comms recording'" master=alsa_input.platform-asoc-simple-card.0.xvf3510-2mic remix=no master_channel_map=front-left channel_map=mono +set-default-source VF_ASR +set-default-sink CombinedOutput + +# Set default volume +set-sink-volume CombinedOutput 32768 + +### Enable Echo/Noise-Cancellation +#load-module module-echo-cancel aec_method=webrtc source_name=echoCancel_source sink_name=echoCancel_sink +#set-default-source echoCancel_source +#set-default-sink echoCancel_sink diff --git a/stage-mark2/01-mark2/files/sj201.service b/stage-mark2/01-mark2/files/sj201.service new file mode 100644 index 0000000..934dc09 --- /dev/null +++ b/stage-mark2/01-mark2/files/sj201.service @@ -0,0 +1,11 @@ +[Unit] +Description=SJ201 Service +Before=pulseaudio.service +Before=configure-audio.service + +[Service] +Type=oneshot +ExecStart=/bin/bash /usr/libexec/configure_sj201_on_boot.sh + +[Install] +WantedBy=multi-user.target diff --git a/stage-mark2/01-mark2/files/xvf3510-flash b/stage-mark2/01-mark2/files/xvf3510-flash new file mode 100644 index 0000000..353d236 --- /dev/null +++ b/stage-mark2/01-mark2/files/xvf3510-flash @@ -0,0 +1,207 @@ +#!/usr/bin/python3 +# Copyright (c) 2019-2020, XMOS Ltd, All rights reserved +# requires dtparam=spi=on in /boot/config.txt + +""" +This script configures the XVF3510 board in boot from SPI slave and load a +binary file. It requires a bin file as input parameter. +""" + +import sys +import os +import time +import argparse +import spidev +import RPi.GPIO as GPIO +from smbus2 import SMBus +from pathlib import Path + +if sys.version[0] != '3': + print("Run this script with Python 3") + sys.exit(1) + +def bit_reversed_byte(byte_to_reverse): + """ + Function to reverse the bit-order of a byte + + Args: + byte_to_reverse: byte to process + + Retruns: + byte in reversed order + """ + return int('{:08b}'.format(byte_to_reverse)[::-1], 2) + +def set_boot_sel(): + """ + Function to set XVF3510 board in SPI slave boot mode + + Args: + None + + Returns: + None + """ + + bus = SMBus(1) + + # reset BOOT_SEL + bus.write_byte_data(0x20, 3, 0xFE) + bus.write_byte_data(0x20, 7, 0xFF) + + state = {} + for i in [2, 6]: + state[i] = bus.read_byte_data(0x20, i) + + # start reset + data_to_write = 0x00 | (state[2] & 0xDF) + bus.write_byte_data(0x20, 2, data_to_write) + data_to_write = 0x00 | (state[6] & 0xDF) + bus.write_byte_data(0x20, 6, data_to_write) + # set BOOT_SEL high + data_to_write = 0x01 + bus.write_byte_data(0x20, 3, data_to_write) + data_to_write = 0xFE + bus.write_byte_data(0x20, 7, data_to_write) + # stop reset + data_to_write = 0x20 | (state[2] & 0xDF) + bus.write_byte_data(0x20, 2, data_to_write) + data_to_write = 0x20 | (state[6] & 0xDF) + bus.write_byte_data(0x20, 6, data_to_write) + + + +def send_image(bin_filename, verbose=False, max_spi_speed_mhz = 5, block_transfer_pause_ms = 1, direct = False, delay = False): + """ + Function to send the given image to the device via SPI slave + + Args: + bin_filename: binary file containing the image to boot + verbose: flag to print debug printouts + direct: Use Pi GPIO outputs rather than the XVF3510 Pi HAT + delay: Release BootSel early to delay startup on version 4.0.0 onwards + + Returns: + None + """ + + if direct: + #setup GPIO + GPIO.setmode(GPIO.BOARD) + GPIO.setwarnings(False) + + #boot_sel = 8 + #rst_n = 10 + ''' + Mycroft board update + ''' + #GPIO.setmode(GPIO.BCM) + + boot_sel = 37 #26 #= 25 # fix these numbers to be Wiring Pi + rst_n = 13 #27 #= 2 + GPIO.setup(boot_sel, GPIO.IN) # Normally, the Pi should not drive this + GPIO.setup(rst_n, GPIO.OUT, initial=GPIO.HIGH) + + #setup SPI + spi = spidev.SpiDev() + bus_spi = 0 + device = 0 + spi.open(bus_spi, device) + + #SPI Settings + spi.max_speed_hz = int(max_spi_speed_mhz * 1000000) + spi.mode = 0b00 #XMOS supports 00 or 11 + + spi_block_size = 4096 #Limitation in spidev and xfer2 doesn't work! + + if direct: + GPIO.output(rst_n, 0) + GPIO.setup(boot_sel, GPIO.OUT, initial=GPIO.HIGH) + GPIO.output(rst_n, 1) + else: + set_boot_sel() + + # Create a table to map byte values to their bit-reversed values + reverse_table = [bit_reversed_byte(byte) for byte in range(256)] + + data = [] + with open(bin_filename, "rb") as f: + bytes_read = f.read() + data = list(bytes_read) + binary_size = len(data) + block_count = 0 + print('Read file "{0}" size: {1} Bytes'.format(args.bin_filename, binary_size)) + if binary_size % spi_block_size != 0: + print("Warning - binary file not a multiple of {} - {} remainder".format( \ + spi_block_size, binary_size % spi_block_size)) + while binary_size > 0: + block = [reverse_table[byte] for byte in data[:spi_block_size]] + del data[:spi_block_size] + binary_size = len(data) + if verbose: + print("Sending {} Bytes in block {} checksum 0x{:X}".format( \ + len(block), block_count, sum(block))) + spi.xfer(block) + + if block_count == 0: + #Long delay for PLL reboot + time.sleep(0.1) + + if delay: + # release boot_sel early to prevent startup + if direct: + GPIO.setup(boot_sel, GPIO.IN) + else: + #bus = smbus.SMBus(1) + bus = SMBus(1) + data_to_write = 0xFE + bus.write_byte_data(0x20, 3, data_to_write) + data_to_write = 0xFF + bus.write_byte_data(0x20, 7, data_to_write) + + elif binary_size > 0: + time.sleep(block_transfer_pause_ms / 1000) + block_count += 1 + print("Sending complete") + + if direct: + GPIO.setup(boot_sel, GPIO.IN) # Once booted, the Pi should not need to drive boot_sel + GPIO.setup(rst_n, GPIO.OUT, initial=GPIO.HIGH) # Once booted, the Pi should not need to drive reset + #GPIO.cleanup() + else: + #bus = smbus.SMBus(1) + bus = SMBus(1) + + # reset BOOT_SEL + data_to_write = 0xFE + bus.write_byte_data(0x20, 3, data_to_write) + data_to_write = 0xFF + bus.write_byte_data(0x20, 7, data_to_write) + + +if __name__ == "__main__": + start_time = time.time() + parser = argparse.ArgumentParser(description='Load an image via SPI slave from an RPi') + parser.add_argument('bin_filename', help='binary file name') + parser.add_argument('--direct', action='store_true', \ + help='Use just direct GPIO outputs rather than using the XVF3510 Development Kit Pi HAT') + parser.add_argument('--delay', action='store_true', \ + help='Delay xvf3510 device start. Release the BootSel pin early to prevent the XVF3510 (V4.0.0 onwards) from starting with the default I2S configuration. This gives AP a chance to configure and start the XVF3510 device.') + parser.add_argument('--max-spi-speed-mhz', type=float, default=5, \ + help='Max SPI speed in MHz') + parser.add_argument('--block-transfer-pause-ms', type=float, default=1, \ + help='pause between SPI transfers in milliseconds, default 1ms') + parser.add_argument('--verbose', action='store_true', \ + help='print debug information') + + args = parser.parse_args() + + if not Path(args.bin_filename).is_file(): + print("Error: input file {} not found".format(args.bin_filename)) + exit(1) + + send_image(args.bin_filename, args.verbose, args.max_spi_speed_mhz, args.block_transfer_pause_ms, args.direct, args.delay) + + end_time = time.time() + if args.verbose: + print("Sending image took {:.3} seconds".format(end_time - start_time)) diff --git a/stage-mark2/01-mark2/files/xvf3510.dtbo b/stage-mark2/01-mark2/files/xvf3510.dtbo new file mode 100644 index 0000000..b299611 Binary files /dev/null and b/stage-mark2/01-mark2/files/xvf3510.dtbo differ diff --git a/stage-mark2/prerun.sh b/stage-mark2/prerun.sh new file mode 100755 index 0000000..e0ecdec --- /dev/null +++ b/stage-mark2/prerun.sh @@ -0,0 +1,6 @@ +#!/bin/bash -e + +if [ ! -d "${ROOTFS_DIR}" ]; then + copy_previous +fi + diff --git a/stage-prep/00-configure-apt/01-run.sh b/stage-prep/00-configure-apt/01-run.sh index e45f0ad..167c3e5 100755 --- a/stage-prep/00-configure-apt/01-run.sh +++ b/stage-prep/00-configure-apt/01-run.sh @@ -4,10 +4,3 @@ install -m 644 files/mimic.list "${ROOTFS_DIR}/etc/apt/sources.list.d/" cat files/mimic.gpg.key | gpg --dearmor > "${STAGE_WORK_DIR}/mimic.gpg" install -m 644 "${STAGE_WORK_DIR}/mimic.gpg" "${ROOTFS_DIR}/etc/apt/trusted.gpg.d/" - -on_chroot << EOF - -apt-get update - -EOF - diff --git a/stage-prep/01-locale/01-debconf b/stage-prep/01-locale/01-debconf index 64cc204..c1ad216 100644 --- a/stage-prep/01-locale/01-debconf +++ b/stage-prep/01-locale/01-debconf @@ -5,3 +5,4 @@ keyboard-configuration keyboard-configuration/layoutcode string us keyboard-configuration keyboard-configuration/layout select English (US) locales locales/default_environment_locale select en_US.UTF-8 +locales locales/locales_to_be_generated multiselect en_US.UTF-8 UTF-8 diff --git a/stage-prep/02-install-packages/01-packages b/stage-prep/02-install-packages/01-packages index 3e59cf0..8920483 100644 --- a/stage-prep/02-install-packages/01-packages +++ b/stage-prep/02-install-packages/01-packages @@ -1,6 +1,4 @@ -python3-dev swig libssl-dev libfann2 libfann-dev portaudio19-dev libpulse-dev -python3-pip python3-wheel python3-setuptools python3-fann2 python3-venv -pulseaudio -mpg123 +python3-dev swig libssl-dev +python3-pip python3-wheel python3-setuptools python3-venv git jq diff --git a/stage-prep/03-sys-tweaks/00-debconf b/stage-prep/03-sys-tweaks/00-debconf deleted file mode 100644 index c1ad216..0000000 --- a/stage-prep/03-sys-tweaks/00-debconf +++ /dev/null @@ -1,8 +0,0 @@ -keyboard-configuration keyboard-configuration/model select Generic 104-key PC -keyboard-configuration keyboard-configuration/variant select English (US) -keyboard-configuration keyboard-configuration/modelcode string pc104 -keyboard-configuration keyboard-configuration/layoutcode string us -keyboard-configuration keyboard-configuration/layout select English (US) - -locales locales/default_environment_locale select en_US.UTF-8 -locales locales/locales_to_be_generated multiselect en_US.UTF-8 UTF-8 diff --git a/stage-prep/03-sys-tweaks/01-run.sh b/stage-prep/03-sys-tweaks/01-run.sh index 580d5d7..1419082 100755 --- a/stage-prep/03-sys-tweaks/01-run.sh +++ b/stage-prep/03-sys-tweaks/01-run.sh @@ -13,6 +13,8 @@ install -v -d -m 0755 "${ROOTFS_DIR}/etc/sudoers.d" install -v -m 0644 files/ovos-sudo "${ROOTFS_DIR}/etc/sudoers.d/ovos" +install -v -m 0644 files/wifi_powersave@.service "${ROOTFS_DIR}/usr/lib/systemd/system/wifi_powersave@.service" + install -v -m 0644 files/media-automount@.service "${ROOTFS_DIR}/usr/lib/systemd/system/media-automount@.service" install -v -d -m 0755 "${ROOTFS_DIR}/etc/udev/automount.d" install -v -m 0644 files/auto "${ROOTFS_DIR}/etc/udev/automount.d/auto" @@ -35,17 +37,14 @@ install -v -d -m 0755 "${ROOTFS_DIR}/tmp/mycroft" # Create directory for systemd hooks install -v -d -m 0755 "${ROOTFS_DIR}/usr/libexec" -on_chroot << EOF - -chown -R ovos:ovos /tmp/ - -if [[ -e /etc/locale.gen ]]; then - rm "/etc/locale.gen" -fi - -dpkg-reconfigure --frontend noninteractive locales +# if [[ -e "${ROOTFS_DIR}/etc/locale.gen" ]]; then +# rm "${ROOTFS_DIR}/etc/locale.gen" +# fi -sed -i 's/^# *\(en_US.UTF-8\)/\1/' /etc/locale.gen -locale-gen +sed -i 's/^# *\(en_US.UTF-8\)/\1/' "${ROOTFS_DIR}/etc/locale.gen" -EOF +# Enable i2c and spi +sed -i "s|#dtparam=i2c_arm=on|dtparam=i2c_arm=on|g" "${ROOTFS_DIR}/boot/firmware/config.txt" +sed -i "s|#dtparam=i2s=on|dtparam=i2s=on|g" "${ROOTFS_DIR}/boot/firmware/config.txt" +sed -i "s|#dtparam=spi=on|dtparam=spi=on|g" "${ROOTFS_DIR}/boot/firmware/config.txt" +sed -i "s|#dtparam=audio=on|dtparam=audio=on|g" "${ROOTFS_DIR}/boot/firmware/config.txt" diff --git a/stage-prep/03-sys-tweaks/02-run-chroot.sh b/stage-prep/03-sys-tweaks/02-run-chroot.sh index f101f1a..9a6860a 100755 --- a/stage-prep/03-sys-tweaks/02-run-chroot.sh +++ b/stage-prep/03-sys-tweaks/02-run-chroot.sh @@ -4,7 +4,10 @@ cd zram-swap cd .. rm -rf zram-swap -cat >> /boot/config.txt << EOF +dpkg-reconfigure --frontend noninteractive locales +locale-gen + +cat >> /boot/firmware/config.txt << EOF disable_splash=1 @@ -16,11 +19,3 @@ boot_delay=1 [all] EOF - -if [[ ! ${VIRTUAL_ENV} ]]; then - source /home/ovos/.venv/bin/activate; -fi - -pip3 install wheel - -deactivate diff --git a/stage-prep/03-sys-tweaks/files/10-ovos-system.preset b/stage-prep/03-sys-tweaks/files/10-ovos-system.preset index 3f05272..ab716df 100644 --- a/stage-prep/03-sys-tweaks/files/10-ovos-system.preset +++ b/stage-prep/03-sys-tweaks/files/10-ovos-system.preset @@ -3,8 +3,9 @@ enable network-online.target enable ssh.service enable resize2fs_once enable media-automount@.service -enable wifi_powersave@.service +enable wifi_powersave@off.service enable zram-swap.service +enable avahi-daemon.service disable apply_noobs_os_config.service disable userconfig.service diff --git a/stage-prep/03-sys-tweaks/files/97-ovos.conf b/stage-prep/03-sys-tweaks/files/97-ovos.conf index 9f6da64..e54698b 100644 --- a/stage-prep/03-sys-tweaks/files/97-ovos.conf +++ b/stage-prep/03-sys-tweaks/files/97-ovos.conf @@ -1,8 +1,16 @@ vm.vfs_cache_pressure = 500 -vm.swappiness = 150 +vm.swappiness = 100 vm.dirty_background_ratio = 1 vm.dirty_ratio = 50 +vm.dirty_expire_centisecs = 500 +vm.dirty_writeback_centisecs = 500 + kernel.panic = 20 +kernel.printk = 3 4 1 3 + fs.inotify.max_user_instances = 512 fs.inotify.max_user_watches = 524288 -kernel.printk = 3 4 1 3 + +kernel.unprivileged_userns_clone = 1 +net.ipv4.ping_group_range = 0 2147483647 +net.ipv4.ip_unprivileged_port_start = 80 diff --git a/stage-prep/04-net-tweaks/01-run.sh b/stage-prep/04-net-tweaks/01-run.sh index bf9d585..bdcffeb 100755 --- a/stage-prep/04-net-tweaks/01-run.sh +++ b/stage-prep/04-net-tweaks/01-run.sh @@ -2,9 +2,12 @@ # NetworkManager install -v -d -m 0755 "${ROOTFS_DIR}/etc/NetworkManager" +install -v -m 0644 files/NetworkManager.conf "${ROOTFS_DIR}/etc/NetworkManager/NetworkManager.conf" + install -v -d -m 0755 "${ROOTFS_DIR}/etc/NetworkManager/conf.d" +install -v -m 0644 files/wifi-powersave-off.conf "${ROOTFS_DIR}/etc/NetworkManager/conf.d/wifi-powersave-off.conf" + install -v -d -m 0755 "${ROOTFS_DIR}/etc/NetworkManager/system-connections" -install -v -m 0644 files/NetworkManager.conf "${ROOTFS_DIR}/etc/NetworkManager/NetworkManager.conf" install -v -d -m 0755 "${ROOTFS_DIR}/etc/polkit-1" install -v -d -m 0755 "${ROOTFS_DIR}/etc/polkit-1/rules.d" @@ -14,7 +17,7 @@ install -v -m 0644 files/50-org.freedesktop.NetworkManager.rules "${ROOTFS_DIR}/ install -v -m 0755 files/wifi-connect.bin "${ROOTFS_DIR}/usr/local/sbin/wifi-connect" cp -rv files/wifi-connect "${ROOTFS_DIR}/usr/local/share/" -on_chroot < Have OVOS speak a phrase to the user" echo " ovos-say-to Send an utterance to OVOS as if spoken by a user" @@ -22,3 +25,9 @@ echo " osm install Install mycroft skills" echo " osm remove Uninstall mycroft skills" echo " osm update Update installed skills" echo +echo "OVOS Docs COMMANDs:" +echo " docs-community View the OVOS Community docs in the terminal" +echo " docs-techincal View the OVOS Technical docs in the terminal" +echo " docs-hivemind View the HiveMind docs in the terminal" +echo " docs-messages View OVOS Message specs in the terminal" +echo diff --git a/stage-shareport-spotify/01-shareport/00-packages-nr b/stage-shareport-spotify/01-shareport/00-packages-nr index 22970d3..08fd533 100644 --- a/stage-shareport-spotify/01-shareport/00-packages-nr +++ b/stage-shareport-spotify/01-shareport/00-packages-nr @@ -1,11 +1,12 @@ -autoconf -automake +dh-autoreconf libpopt-dev libconfig-dev -libsoxr-dev libavahi-client-dev +libsoxr-dev libplist-dev libsodium-dev -libgcrypt-dev libavutil-dev +libavcodec-dev libavformat-dev +libgcrypt20-dev +xxd diff --git a/stage-shareport/01-install-packages/01-packages-nr b/stage-shareport/01-install-packages/01-packages-nr new file mode 100644 index 0000000..9a52e3d --- /dev/null +++ b/stage-shareport/01-install-packages/01-packages-nr @@ -0,0 +1,17 @@ +dh-autoreconf +libtool +libpopt-dev +libconfig-dev +libasound2-dev +avahi-daemon +libavahi-client-dev +libssl-dev +libsoxr-dev +libplist-dev +libsodium-dev +libavutil-dev +libavcodec-dev +libavformat-dev +uuid-dev +libgcrypt-dev +xxd diff --git a/stage-shareport/01-shareport/02-run-chroot.sh b/stage-shareport/01-shareport/02-run-chroot.sh new file mode 100644 index 0000000..07e141c --- /dev/null +++ b/stage-shareport/01-shareport/02-run-chroot.sh @@ -0,0 +1,22 @@ +#!/bin/bash -e + +# Install required daemon + +git clone https://github.com/mikebrady/nqptp.git +cd nqptp +autoreconf -fi +./configure --with-systemd-startup +make +make install +cd .. +rm -rf nqptp + +git clone https://github.com/mikebrady/shairport-sync.git +cd shairport-sync +autoreconf -fi +./configure --sysconfdir=/etc --with-pulse \ + --with-soxr --with-avahi --with-ssl=openssl --with-systemd --with-airplay-2 +make +make install +cd .. +rm -rf shairport-sync diff --git a/stage-shareport/prerun.sh b/stage-shareport/prerun.sh new file mode 100755 index 0000000..e0ecdec --- /dev/null +++ b/stage-shareport/prerun.sh @@ -0,0 +1,6 @@ +#!/bin/bash -e + +if [ ! -d "${ROOTFS_DIR}" ]; then + copy_previous +fi + diff --git a/stage-skills/01-basic/02-run-chroot.sh b/stage-skills/01-basic/02-run-chroot.sh index bcda9c8..e948c28 100755 --- a/stage-skills/01-basic/02-run-chroot.sh +++ b/stage-skills/01-basic/02-run-chroot.sh @@ -4,7 +4,7 @@ fi pip3 install git+https://github.com/OpenVoiceOS/ovos_skill_manager -pip3 install git+https://github.com/OpenVoiceOS/skill-alerts +pip3 install git+https://github.com/OpenVoiceOS/skill-alerts@feat/DAV pip3 install git+https://github.com/OpenVoiceOS/skill-ovos-weather pip3 install git+https://github.com/OpenVoiceOS/skill-ovos-ddg pip3 install git+https://github.com/OpenVoiceOS/skill-ovos-wolfie diff --git a/stage-speech/00-install-packages/00-run-chroot.sh b/stage-speech/00-install-packages/00-run-chroot.sh new file mode 100755 index 0000000..91e9bde --- /dev/null +++ b/stage-speech/00-install-packages/00-run-chroot.sh @@ -0,0 +1,2 @@ +apt update + diff --git a/stage-audio/00-install-packages/00-packages b/stage-speech/00-install-packages/01-packages similarity index 100% rename from stage-audio/00-install-packages/00-packages rename to stage-speech/00-install-packages/01-packages diff --git a/stage-speech/01-speech/01-run.sh b/stage-speech/01-speech/01-run.sh new file mode 100755 index 0000000..71dfcfd --- /dev/null +++ b/stage-speech/01-speech/01-run.sh @@ -0,0 +1,17 @@ +#!/bin/bash -e + +install -v -d -m 0755 "${ROOTFS_DIR}/home/ovos/.local/share" +install -v -d -m 0755 "${ROOTFS_DIR}/home/ovos/.local/share/piper_tts" +install -v -d -m 0755 "${ROOTFS_DIR}/home/ovos/.local/share/piper_tts/voice-en-gb-alan-low" + +wget https://github.com/rhasspy/piper/releases/download/v0.0.2/voice-en-gb-alan-low.tar.gz -P "${ROOTFS_DIR}/home/ovos/.local/share/piper_tts/voice-en-gb-alan-low/" +on_chroot << EOF + +tar -xvzf /home/ovos/.local/share/piper_tts/voice-en-gb-alan-low/voice-en-gb-alan-low.tar.gz -C /home/ovos/.local/share/piper_tts/voice-en-gb-alan-low + +EOF + +install -v -m 0644 files/ovos-audio.service "${ROOTFS_DIR}/etc/systemd/user/ovos-audio.service" +install -v -m 0755 files/ovos-systemd-audio "${ROOTFS_DIR}/usr/libexec/ovos-systemd-audio" + +echo "enable ovos-audio.service" >> "${ROOTFS_DIR}/etc/systemd/user-preset/10-ovos-user.preset" diff --git a/stage-audio/01-speech/02-run-chroot.sh b/stage-speech/01-speech/02-run-chroot.sh similarity index 77% rename from stage-audio/01-speech/02-run-chroot.sh rename to stage-speech/01-speech/02-run-chroot.sh index f8cc6af..09cc132 100755 --- a/stage-audio/01-speech/02-run-chroot.sh +++ b/stage-speech/01-speech/02-run-chroot.sh @@ -10,14 +10,14 @@ pip3 install git+https://github.com/OpenVoiceOS/ovos-vlc-plugin pip3 install espeak_phonemizer -cd /home/ovos -git clone https://github.com/libfann/fann.git -cd fann -cmake . -make install -cd .. -rm -rf fann -pip3 install padatious +# cd /home/ovos +# git clone https://github.com/libfann/fann.git +# cd fann +# cmake . +# make install +# cd .. +# rm -rf fann +apt update deactivate diff --git a/stage-audio/01-speech/files/ovos-audio.service b/stage-speech/01-speech/files/ovos-audio.service similarity index 87% rename from stage-audio/01-speech/files/ovos-audio.service rename to stage-speech/01-speech/files/ovos-audio.service index 38982b9..1e93cf9 100644 --- a/stage-audio/01-speech/files/ovos-audio.service +++ b/stage-speech/01-speech/files/ovos-audio.service @@ -13,8 +13,6 @@ TimeoutStopSec=1m Restart=on-failure StartLimitInterval=5min StartLimitBurst=4 -#StartLimitAction=reboot-force -#WatchdogSec=30s [Install] WantedBy=ovos.service diff --git a/stage-audio/01-speech/files/ovos-systemd-audio b/stage-speech/01-speech/files/ovos-systemd-audio similarity index 100% rename from stage-audio/01-speech/files/ovos-systemd-audio rename to stage-speech/01-speech/files/ovos-systemd-audio diff --git a/stage-speech/prerun.sh b/stage-speech/prerun.sh new file mode 100755 index 0000000..e0ecdec --- /dev/null +++ b/stage-speech/prerun.sh @@ -0,0 +1,6 @@ +#!/bin/bash -e + +if [ ! -d "${ROOTFS_DIR}" ]; then + copy_previous +fi + diff --git a/stage-splash/01-install-packages/01-packages b/stage-splash/01-install-packages/01-packages new file mode 100644 index 0000000..9c5833c --- /dev/null +++ b/stage-splash/01-install-packages/01-packages @@ -0,0 +1 @@ +fbi diff --git a/stage-splash/02-splash/01-run.sh b/stage-splash/02-splash/01-run.sh new file mode 100755 index 0000000..0843e7f --- /dev/null +++ b/stage-splash/02-splash/01-run.sh @@ -0,0 +1,8 @@ +#!/bin/bash -e + +install -v -d -m 0755 "${ROOTFS_DIR}/opt/ovos" +install -v -m 0644 files/splashscreen.png "${ROOTFS_DIR}/opt/ovos/splashscreen.png" + +install -v -m 0644 files/splashscreen.service "${ROOTFS_DIR}/etc/systemd/system/splashscreen.service" + +echo "enable splashscreen.service" >> "${ROOTFS_DIR}/etc/systemd/system-preset/10-ovos-system.preset" diff --git a/stage-splash/02-splash/02-run-chroot.sh b/stage-splash/02-splash/02-run-chroot.sh new file mode 100755 index 0000000..e69de29 diff --git a/stage-splash/02-splash/files/splashscreen.png b/stage-splash/02-splash/files/splashscreen.png new file mode 100644 index 0000000..016844a Binary files /dev/null and b/stage-splash/02-splash/files/splashscreen.png differ diff --git a/stage-splash/02-splash/files/splashscreen.service b/stage-splash/02-splash/files/splashscreen.service new file mode 100644 index 0000000..a08a0f9 --- /dev/null +++ b/stage-splash/02-splash/files/splashscreen.service @@ -0,0 +1,12 @@ +[Unit] +Description=Splash screen +DefaultDependencies=no +After=local-fs.target + +[Service] +ExecStart=/usr/bin/fbi -d /dev/fb0 --noverbose -a /opt/ovos/splashscreen.png +StandardInput=tty +StandardOutput=tty + +[Install] +WantedBy=sysinit.target diff --git a/stage-splash/prerun.sh b/stage-splash/prerun.sh new file mode 100755 index 0000000..e0ecdec --- /dev/null +++ b/stage-splash/prerun.sh @@ -0,0 +1,6 @@ +#!/bin/bash -e + +if [ ! -d "${ROOTFS_DIR}" ]; then + copy_previous +fi + diff --git a/stage-spotify/prerun.sh b/stage-spotify/prerun.sh new file mode 100755 index 0000000..e0ecdec --- /dev/null +++ b/stage-spotify/prerun.sh @@ -0,0 +1,6 @@ +#!/bin/bash -e + +if [ ! -d "${ROOTFS_DIR}" ]; then + copy_previous +fi +