Adding more button clicks

I want to add more clicks to my pisound. click 1 for patch 1, click 2 for patch 2, all the way up to maybe 6 (?) clicks? clicks 1 - 3 are easy to modify obviously.

How can i go about adding more click events?

Edit: https://github.com/BlokasLabs/pisound/blob/master/pisound-btn/pisound-btn.c

Seems like I just need to do a bit of hacking here, and (I guess) recompile this for my pi? Not sure how to do that, is there a broad outline of how to do that somewhere?

Thanks!

Hey, it’s actually pretty easy and doesn’t require modifying pisound-btn.c, unless you want to go beyond the limit of 8 clicks.

Just put your script in /usr/local/pisound/scripts/pisound-btn (make sure to chmod +x the script) and using pisound-config, set all of single, double, triple and other actions to execute your script.

The click scripts receive the number of clicks that ocurred as the first argument ($1), so you can differentiate which patch to launch from the same script file.

Some more useful info can be found in the docs.

Hi Giedrius,

I tried the above last night, but wasn’t able to get what I wanted.

I want something like:

/etc/pisound.conf:

CLICK_1      /usr/local/pisound/scripts/pisound-btn/start_patch_one.sh
CLICK_2      /usr/local/pisound/scripts/pisound-btn/start_patch_two.sh
CLICK_3      /usr/local/pisound/scripts/pisound-btn/start_patch_three.sh
CLICK_4      /usr/local/pisound/scripts/pisound-btn/start_patch_four.sh
CLICK_5      /usr/local/pisound/scripts/pisound-btn/start_patch_five.sh
.
.
.
CLICK_8      /usr/local/pisound/scripts/pisound-btn/start_patch_eight.sh

Basically 8 identical scripts, once for each pure data patch, with each patch looking for main.pd in a different folder.

start_patch_one.sh:

	if [ -z "$PURE_DATA_PATCH" ]; then
		log "No patch found in attached media, checking /usr/local/puredata-patches..."
		PURE_DATA_PATCH=`find /usr/local/puredata-patches/patch_one/ 2> /dev/null | grep main.pd | head -1`
	fi 

My /usr/local/puredata-patches/ folder looks like:

/usr/local/puredata-patches/
/patch_one/
/patch_two/
/patch_three/

etc

I’m sure I’m missing something obvious, I will have a look again later…

Hey, you should use a single script for all kinds of clicks to either start the individual script, or to look for the patch, somehing like:

# I have not tested this script, but it should show the general idea.

case $1 in  # Might need to use case "$1" in instead (added double-quotes for $1)
    1) # Might need to use "1" instead
        PATCH_DATA_DIR="/usr/local/puredata-patches/patch_one"
        ;;
    2)
        PATCH_DATA_DIR="/usr/local/puredata-patches/patch_two"
        ;;
    #...
esac

PURE_DATA_PATCH=`find ${PATCH_DATA_DIR} 2> /dev/null | grep main.pd | head -1`
#...

$1 will be equal to the amount of clicks you made, so you can use it to figure out what to do. :slight_smile:

1 Like

Shell scripting is sometimes tricky, you can always forward processing the action to another language instead, such as python:

python my_script.py $@ #@ just forwards all of the provided arguments to the script

my_script.py:

import sys
click_count=int(sys.argv[1])
print("Button clicked %u times" % click_count)

ah ok, I knew I was probably being a bit silly thinking about this. Thank you! I will give that a go.

just getting back to this now, but i still can’t make this work, are you sure the above suggestion is correct?

:slight_smile:

Hey, what issue are you seeing? How far did you get?

hi giedrius.

the pi just seems to ignore any clicks beyond 3 clicks. I have the following script mapped to CLICK_OTHER in pisound-config:

/usr/local/pisound/scripts/pisound-btn/mulit_clicks.sh:

#!/bin/sh

. /usr/local/pisound/scripts/common/common.sh
. /usr/local/pisound/scripts/common/start_puredata.sh

case "$1" in
    "1")
        PATCH_DATA_DIR="/usr/local/puredata-patches/first"
        ;;
    "2")
        PATCH_DATA_DIR="/usr/local/puredata-patches/second"
        ;;
    "3")
        PATCH_DATA_DIR="/usr/local/puredata-patches/third"
        ;;                    
    "4")
        PATCH_DATA_DIR="/usr/local/puredata-patches/fourth"
        ;;
    "5")
        PATCH_DATA_DIR="/usr/local/puredata-patches/fifth"
        ;;
    "6")
        PATCH_DATA_DIR="/usr/local/puredata-patches/sixth"
        ;;
    "7")
        PATCH_DATA_DIR="/usr/local/puredata-patches/seventh"
        ;;
     "8")
        PATCH_DATA_DIR="/usr/local/puredata-patches/eighth"
        ;;
esac

PURE_DATA_PATCH=`find ${PATCH_DATA_DIR} 2> /dev/null | grep main.pd | head -1`

start_puredata "$PURE_DATA_PATCH" &
  1. Have you mapped all the clicks to the new script?
  2. Did you chmod +x the new script?

Here’s some suggested steps on how to debug this issue:

First you should verify that your script does get executed. This can be done by using a simple echo or log from common.sh which for convenience includes the current timestamp in the beginning of the line.

Before case "$1" in add:

...

log Executing multi_click.sh $@

case "$1" in
...

The $@ will be replaced by all of the arguments that were used to exeucte the script. You can place log lines in more locations to inspect some variables or whether some particular lines get executed.

Another good location to place a log line would be near the end:

...
log Used "${PATCH_DATA_DIR}" for searching, found "${PURE_DATA_PATCH}"

start_puredata "$PURE_DATA_PATCH" &

The output can be seen by running sudo journalctl -f -u pisound-btn. Once you execute this command, try triggering different actions to see some output being produced.

Also you may manually trigger the script in a terminal and check whether you’re getting the expected results:

/usr/local/pisound/scripts/pisound-btn/mulit_clicks.sh 1
/usr/local/pisound/scripts/pisound-btn/mulit_clicks.sh 2
/usr/local/pisound/scripts/pisound-btn/mulit_clicks.sh 7
...

The pisound-btn runs as root, so you may want to trigger the scripts above with ‘sudo’ at the beginning of the command.

Thank you for the detailed response Giedrius! Very much appreciated. I am sure that will be enough to get me sorted. :ok_hand:

Ok, so i got this working. I now know a little bit more about linux scripting and how to debug a script. thank you!

Here is the script, if anyone is curious. I guess you could map this to every click option in pisound-config. The script looks for a usb drive with main.pd, and if it doesn’t find that, it counts the button clicks and launches the corresponding patch.

/usr/local/pisound/scripts/pisound-btn/multi_clicks.sh:

#!/bin/sh

. /usr/local/pisound/scripts/common/common.sh
. /usr/local/pisound/scripts/common/start_puredata.sh

log "Searching for main.pd in USB storage!"

PURE_DATA_PATCH=`find /media 2> /dev/null | grep main.pd | head -1`

if [ -z "$PURE_DATA_PATCH" ]; then
    log "No patch found in attached media, trying to mount USB devices..."
    for usb_dev in `ls /dev/disk/by-id/ | grep usb`; do
        DISKPATH="/dev/disk/by-id/$usb_dev"
        DEV=$(readlink -f $DISKPATH)

        LABEL=`sudo blkid -s LABEL -o value $DEV`
        if [ -z "$LABEL" ]; then
            log "Skipping $DISKPATH"
            continue
        fi

        MEDIAPATH="/media/$USER/$LABEL"
        log "Mounting $DEV ($LABEL) to $MEDIAPATH"
        sudo mkdir -p "$MEDIAPATH"
        sudo chown $USER "$MEDIAPATH"
        sudo chgrp $USER "$MEDIAPATH"
        sudo mount "$DEV" "$MEDIAPATH"
    done

    log Executing multi_click.sh $@
    
    case "$1" in
        "1")
            PATCH_DATA_DIR="/usr/local/puredata-patches/pd_patches/first"
            ;;
        "2")
            PATCH_DATA_DIR="/usr/local/puredata-patches/pd_patches/second"
            ;;
        "3")
            PATCH_DATA_DIR="/usr/local/puredata-patches/pd_patches/third"
            ;;        
        "4")
            PATCH_DATA_DIR="/usr/local/puredata-patches/pd_patches/fourth"
            ;;
        "5")
            PATCH_DATA_DIR="/usr/local/puredata-patches/pd_patches/fifth"
            ;;
        "6")
            PATCH_DATA_DIR="/usr/local/puredata-patches/pd_patches/sixth"
            ;;
        "7")
            PATCH_DATA_DIR="/usr/local/puredata-patches/pd_patches/seventh"
            ;;
        "8")
            PATCH_DATA_DIR="/usr/local/puredata-patches/pd_patches/eighth"
            ;;
        #...
    esac
    
    PURE_DATA_PATCH=`find ${PATCH_DATA_DIR}/ 2> /dev/null | grep main.pd | head -1`
    
    log Used "${PATCH_DATA_DIR}" for searching, found "${PURE_DATA_PATCH}"
    
#...
fi

if [ -z "$PURE_DATA_PATCH" ]; then
    log "No patch found! Doing nothing..."
    sleep 0.5
    flash_leds 100
    exit 0
else
    log "Found patch: $PURE_DATA_PATCH"
fi

log "All sanity checks succeeded."

start_puredata "$PURE_DATA_PATCH" &
1 Like