diff --git a/sh/argc b/sh/argc new file mode 100644 index 0000000..c1e4baf --- /dev/null +++ b/sh/argc @@ -0,0 +1,81 @@ +#!/usr/bin/env sh +# YES_ZSH +# YES_BASH +# YES_DASH +# YES_ASH + +argc() { ### @- + ### ```sh + ### # usage: + ### + ### myfunc() { + ### argc X "$0" "$@" || return; + ### # ^-- replace X with one of the following: + ### # * N to expect an *exact* (==) number of arguments, + ### # * +N to expect *at least* (>=) some number of arguments, + ### # * -N to expect *at most* (<=) some number of arguments, + ### # where N is an integer between 0 and 9. + ### } + ### ``` + + if [ $# -lt 2 ] || [ -z "$1" ] || [ -z "$2" ]; then + printf 'usage: %s (N|+N|-N) "$0" "$@" || return\n' "$0" >&2 + return 2 + fi + + local want="$1"; shift + local zero="$1"; shift + local err='' + + case "$want" in + # i realize hardcoding each case like this *looks* terrible, + # but consider: there's only thirty cases we need to handle. + # plus, i can write a specific error message for each. + + 0) [ $# -eq 0 ] || err='expected no arguments, got';; + 1) [ $# -eq 1 ] || err='expected exactly one argument, got';; + 2) [ $# -eq 2 ] || err='expected exactly two arguments, got';; + 3) [ $# -eq 3 ] || err='expected exactly three arguments, got';; + 4) [ $# -eq 4 ] || err='expected exactly four arguments, got';; + 5) [ $# -eq 5 ] || err='expected exactly five arguments, got';; + 6) [ $# -eq 6 ] || err='expected exactly six arguments, got';; + 7) [ $# -eq 7 ] || err='expected exactly seven arguments, got';; + 8) [ $# -eq 8 ] || err='expected exactly eight arguments, got';; + 9) [ $# -eq 9 ] || err='expected exactly nine arguments, got';; + + +0) :;; # anything goes + +1) [ $# -ge 1 ] || err='expected at least one argument, got';; + +2) [ $# -ge 2 ] || err='expected at least two arguments, got';; + +3) [ $# -ge 3 ] || err='expected at least three arguments, got';; + +4) [ $# -ge 4 ] || err='expected at least four arguments, got';; + +5) [ $# -ge 5 ] || err='expected at least five arguments, got';; + +6) [ $# -ge 6 ] || err='expected at least six arguments, got';; + +7) [ $# -ge 7 ] || err='expected at least seven arguments, got';; + +8) [ $# -ge 8 ] || err='expected at least eight arguments, got';; + +9) [ $# -ge 9 ] || err='expected at least nine arguments, got';; + + -0) [ $# -le 0 ] || err='expected no arguments, got';; + -1) [ $# -le 1 ] || err='expected at most one argument, got';; + -2) [ $# -le 2 ] || err='expected at most two arguments, got';; + -3) [ $# -le 3 ] || err='expected at most three arguments, got';; + -4) [ $# -le 4 ] || err='expected at most four arguments, got';; + -5) [ $# -le 5 ] || err='expected at most five arguments, got';; + -6) [ $# -le 6 ] || err='expected at most six arguments, got';; + -7) [ $# -le 7 ] || err='expected at most seven arguments, got';; + -8) [ $# -le 8 ] || err='expected at most eight arguments, got';; + -9) [ $# -le 9 ] || err='expected at most nine arguments, got';; + + *) + printf 'usage: %s (N|+N|-N) "$0" "$@" || return\n' "$0" >&2 + return 2;; + esac + + if [ -n "$err" ]; then + printf '%s: %s %s\n' "$zero" "$err" "$#" >&2 + return 1 + fi + + return 0 +} + +[ "${SOURCING:-0}" -gt 0 ] || argc "$@" diff --git a/sh/streamcrap b/sh/streamcrap index 2edf088..47b6e79 100644 --- a/sh/streamcrap +++ b/sh/streamcrap @@ -24,7 +24,7 @@ _M_LESS_INSANE="$_M_PRE_EMPH,acompressor=threshold=0.0020:ratio=1.41:attack=1000 _M_NEO="equalizer=700:o:1.3:-5,equalizer=1200:o:1.3:-3,equalizer=1090:o:0.5:-5,equalizer=970:o:1.2:-10,equalizer=4100:o:0.3:-6" getladspa() { - [ $# -eq 1 ] || { printf "%s\n" "$0: expected exactly one argument" >&2; return 1; } + argc 1 "$0" "$@" || return REPLY=volume if [ -e "/usr/lib/ladspa/${1}.so" ]; then REPLY="ladspa=f=${1}:p=${1}" @@ -37,7 +37,7 @@ _M_LEVEL="$REPLY" _nn="$(uname -n | tr A-Z a-z)" earphones() { - [ $# -eq 0 ] || { printf "%s\n" "$0: unexpected arguments" >&2; return 1; } + argc 0 "$0" "$@" || return _M_PROCESS="lowpass=8000:p=1,$_M_KILL,alimiter=level_out=0.707" } @@ -46,7 +46,7 @@ if [ "$_nn" = spectre ]; then fi if [ "$_nn" = neobanshee ]; then speakers() { - [ $# -eq 0 ] || { printf "%s\n" "$0: unexpected arguments" >&2; return 1; } + argc 0 "$0" "$@" || return _M_PROCESS="highpass=311,$_M_KILL,$_M_NEO,alimiter=level_in=2" } speakers @@ -55,7 +55,7 @@ if [ "$_nn" = banshee ]; then getladspa crap_eq_const_T420 _M_SPEAKERS="$REPLY" speakers() { - [ $# -eq 0 ] || { printf "%s\n" "$0: unexpected arguments" >&2; return 1; } + argc 0 "$0" "$@" || return _M_PROCESS="$_M_LEVEL,$_M_SPEAKERS,alimiter=level_in=0.5" } speakers @@ -65,7 +65,7 @@ unset _nn mpv_watch() { ### @- ### watch something in mpv with a bunch of extra audio filtering crap. - [ $# -gt 0 ] || { printf "%s\n" "$0: too few arguments" >&2; return 1; } + argc +1 "$0" "$@" || return pushd ~/play >/dev/null local url="$1"; shift mpv \ @@ -77,7 +77,7 @@ mpv_watch() { ### @- mpv_stream() { ### @- ### watch a stream in mpv with a bunch of extra audio filtering crap. - [ $# -gt 0 ] || { printf "%s\n" "$0: too few arguments" >&2; return 1; } + argc +1 "$0" "$@" || return pushd ~/play >/dev/null local url="$1"; shift mpvs --af=lavfi="[$_M_PROCESS]" "$@" "$url" @@ -86,7 +86,7 @@ mpv_stream() { ### @- twitch() { ### @- ### watch a twitch stream in mpv with a bunch of extra audio filtering crap. - [ $# -gt 0 ] || { printf "%s\n" "$0: too few arguments" >&2; return 1; } + argc +1 "$0" "$@" || return local user="$1"; shift mpv_stream "http://twitch.tv/$user" "$@" } @@ -97,7 +97,7 @@ yt() { ### @- ### remaining arguments are passed to mpv. ### ### there exist several variants for more specific use cases. - [ $# -gt 0 ] || { printf "%s\n" "$0: too few arguments" >&2; return 1; } + argc +1 "$0" "$@" || return local vid="$1"; shift [ -e "$vid" ] || [ "$vid" != "${vid#http}" ] || vid="ytdl://$vid" mpv_watch "$vid" "$@" @@ -105,7 +105,7 @@ yt() { ### @- ytg() { ### @- ### watch a youtube video. like `yt`, but with a preference for different formats. - [ $# -gt 0 ] || { printf "%s\n" "$0: too few arguments" >&2; return 1; } + argc +1 "$0" "$@" || return local vid="$1"; shift yt "$vid" --ytdl-format=22/95/300/best "$@" } @@ -113,26 +113,26 @@ ytg() { ### @- ytll() { ### @- ### watch a stream on youtube in mpv, etcetera etcetera. ### this is the low latency version that does not support seeking. - [ $# -gt 0 ] || { printf "%s\n" "$0: too few arguments" >&2; return 1; } + argc +1 "$0" "$@" || return youtube-dl -q -f best "$1" -o - | mpv_stream - --no-ytdl } ytgll() { ### @- ### watch a stream on youtube in mpv. like `ytll`, but with a preference for different formats. - [ $# -gt 0 ] || { printf "%s\n" "$0: too few arguments" >&2; return 1; } + argc +1 "$0" "$@" || return youtube-dl -q -f 22/95/300/best "$1" -o - | mpv_stream - --no-ytdl } ai() { # @- # hai domo! - [ $# -gt 0 ] || { printf "%s\n" "$0: too few arguments" >&2; return 1; } + argc +1 "$0" "$@" || return yt "$@" --slang=en --sub-font='Tekton Pro' --sub-bold=yes \ --sub-font-size=60 --sub-border-color='#DD6180' --sub-margin-y=52 } asmr() { # @- # for your aural pleasure. - [ $# -gt 0 ] || { printf "%s\n" "$0: too few arguments" >&2; return 1; } + argc +1 "$0" "$@" || return _M_PROCESS="acompressor=threshold=0.001:ratio=1.33:attack=900:release=6000:makeup=6:knee=8:mix=0.9,alimiter" \ yt "$@" --volume=90 --ytdl-format=251/300/best }