This repository has been archived on 2023-08-15. You can view files and clone it, but cannot push or open issues or pull requests.
libsox.sh/libsox.sh

129 lines
5.3 KiB
Bash
Executable File

#!/bin/bash
: '
Copyright (C) 2022 Job Bautista
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
'
# notes
c=(16 32 65 130 261 523 1046 2093 4186)
cs=(17 34 69 138 277 554 1108 2217 4434)
d=(18 36 73 146 293 587 1174 2349 4698)
ds=(19 38 77 155 311 622 1244 2489 4978)
e=(20 41 82 164 329 659 1318 2637 5274)
f=(21 43 87 174 349 698 1396 2793 5587)
fs=(23 46 92 184 369 739 1479 2959 5919)
g=(24 48 97 195 391 783 1567 3135 6271)
gs=(25 51 103 207 415 830 1661 3322 6644)
a=(27 55 110 220 440 880 1760 3520 7040)
as=(29 58 116 233 466 932 1864 3729 7458)
b=(30 61 123 246 493 987 1975 3951 7902)
# flats as references to their respective sharps
declare -n df db ef eb gf gb af ab bf bb
df="cs" db="cs"
ef="ds" eb="ds"
gf="fs" gb="fs"
af="gs" ab="gs"
bf="as" bb="as"
declare -rg c cs d ds e f g gs a as b df db ef eb gf gb af ab bf bb
function setTempo {
declare -g BPM=$1
# durations
declare -g fu=$(echo "scale=3; 240 / $BPM" | bc -l) # Whole note
declare -g ha=$(echo "scale=3; 120 / $BPM" | bc -l) # Half note
declare -g qu=$(echo "scale=3; 60 / $BPM" | bc -l) # Quarter note
declare -g ei=$(echo "scale=3; 30 / $BPM" | bc -l) # Eighth note
declare -g si=$(echo "scale=3; 15 / $BPM" | bc -l) # Sixteenth note
declare -g dha=$(echo "scale=3; 190 / $BPM" | bc -l) # Dotted-half note
declare -g dqu=$(echo "scale=3; 90 / $BPM" | bc -l) # Dotted-quarter note
declare -g dei=$(echo "scale=3; 45 / $BPM" | bc -l) # Dotted-eighth note
declare -g dsi=$(echo "scale=3; 22.5 / $BPM" | bc -l) # Dotted-sixteenth note
declare -g tqu=$(echo "scale=3; 40 / $BPM" | bc -l) # Triplet-quarter note
declare -g tei=$(echo "scale=3; 20 / $BPM" | bc -l) # Triplet-eighth note
declare -g tsi=$(echo "scale=3; 10 / $BPM" | bc -l) # Triplet-sixteenth note
}
declare -ag notes # In the following format - "$duration:${key[pitch]}"
# For a two-note harmony - "$duration:${key1[pitch1]},${key2[pitch2]}"
# 3-note: "$duration:${k1[p1]},${k2[p2]}*${k3[p3]}"
# 4-note: "$duration:${k1[p1]},${k2[p2]}*${k3[p3]}_${k4[p4]}"
# 5: "$duration:${k1[p1]},${k2[p2]}*${k3[p3]}_${k4[p4]}@${k5[p5]}"
# 6: "$duration:${k1[p1]},${k2[p2]}*${k3[p3]}_${k4[p4]}@${k5[p5]}^${k6[p6]}"
declare -g defaultsynth="sin" # for backwards compatibility with previous
synthtype="$defaultsynth" # child scripts that only used sine
function setDefaultSynthType {
defaultsynth=$1
synthtype="$defaultsynth"
}
function silence { # needed because pluck synth doesn't support zero frequency
declare -n duration=$1 # we want $1 to be recognized as a variable name
createSoxPipes # necessary because we will be changing synth type
synthtype="sin" # sin, square, sawtooth, trapezium, and exp support freq=0
notes+=( "$duration:0" )
createSoxPipes # get the silence printed before we return to default synth
synthtype="$defaultsynth"
}
function createSoxPipes { # default behavior
for note in "${notes[@]}"
do
printf '"|sox -n -p synth '$(echo "$note" |
sed 's/:.*//')' '$synthtype' '$(echo "$note" |
sed 's/.*://;s/,.*//')' '$synthtype' '$(echo "$note" |
sed 's/.*://;s/.*,//;s/\*.*//')'"\n'
done
notes=() # You usually want to reset the notes array after calling this
}
function enable3456Harmony { # enables 3/4/5/6-note harmony support
# The reason this is not default behavior is because in ALSA, it requires an
# audio processing buffer size of 16384 bytes. A larger buffer can cause sox
# to be slow to respond. Also, SoX in ALSA for some reason requires at least
# 4 channels if you want to hear the third note in a 3-note harmony.
function createSoxPipes { # redefine createSoxPipes
if [[ -n $notes ]] # Check if notes array has items; otherwise do nothing
then
for note in "${notes[@]}"
do
printf '"|sox -n -p synth '$(echo "$note" |
sed 's/:.*//')' '$synthtype' '$(echo "$note" |
sed 's/.*://;s/,.*//')' '$synthtype' '$(echo "$note" |
sed 's/.*://;s/.*,//;s/\*.*//')' '$synthtype' '$(echo "$note" |
sed 's/.*,//;s/.*://;s/.*\*//;
s/_.*//')' '$synthtype' '$(echo "$note" | sed 's/.*,//;
s/.*://;s/.*\*//;s/@.*//;s/\^.*//;
s/.*_//')' '$synthtype' '$(echo "$note" | sed 's/.*_//;
s/.*@//;s/\^.*//;s/.*\*//;s/.*://;
s/.*,//')' '$synthtype' '$(echo "$note" | sed 's/.*,//;
s/.*\*//;s/.*_//;s/.*://;s/.*@//;s/.*\^//')'"\n'
done
notes=()
fi
}
}