From 0df96700a00a0bd9740c30d42cd9a5dc280fbdf1 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Mon, 8 Apr 2024 01:55:17 -0400 Subject: soxdial: support ms for times, k for rate, expand docs. --- soxdial | 96 +++++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 73 insertions(+), 23 deletions(-) diff --git a/soxdial b/soxdial index 428f351..a8556b9 100755 --- a/soxdial +++ b/soxdial @@ -53,32 +53,39 @@ writes raw samples to standard output. =item B<-r>, B<--rate> I -Set the bitrate in Hz. Default is 8000. You should probably stick with -standard bitrates such as 22050, 44100, 48000, etc, although this is -not enforced. +Set the bitrate in hertz (or kilohertz if followed by B. Default is +8000 (or 8k). You should probably stick with standard bitrates such as +22050, 44100, 48000, etc, although this is not enforced. This option +B occur on the command line B any dial string. =item B<-b>, B<--bits> I Set the bits per sample. Default is 8. The only other choice is 16. 8-bit samples will be encoded as unsigned, and 16-bit will be encoded -as signed. +as signed. This option B occur on the command line B any +dial string. =item B<-v>, B<--verbose> -Print verbose information, including the generated B command on stdout +Print verbose information, including the generated B command, on standard +error. =item B<-n>, B<--no-exec> Do not execute the generated B command. This option also enables B<-v>. +=item B<-V>, B<--version> + +Print the version number of B, then exit. + =item B<--help> -Prints this help text, via B(1). +Prints this help text, via B(1), then exit. =item B<--man> -Prints this help text as a man page, via B(1). Suggested use: +Prints this help text as a man page, via B(1), then exit. Suggested use: soxdial --man > soxdial.1 @@ -95,17 +102,20 @@ dial strings, until the same option is seen again. =over 4 -=item B<-l> I, B<--length> I +=item B<-l>, B<--length> [ I | IB ] -Sets the time each digit's tones are played. Default is 0.25. +Sets the time each digit's tones are played. Default is 0.25 +or 250ms. -=item B<-d> I, B<--delay> I +=item B<-d> I, B<--delay> [ I | IB ] -Sets the delay between consecutive digits. Default is 0.1. +Sets the delay between consecutive digits. Default is 0.1 +or 100ms. -=item B<-c> I, B<--comma> I +=item B<-c> I, B<--comma> [ I | IB ] -Sets the delay added by commas in the dial strings. Default is 0.5. +Sets the delay added by commas in the dial strings. Default is 0.5 +or 500ms. =item B<-x>, B<--extended> @@ -145,6 +155,23 @@ All characters that aren't mentioned above, will be silently ignored. This allows you to paste a phone number in the form B<(555) 555-1212> and have it work correctly. +=head1 NOTES + +B<1.> B works by iterating over the words on the command line, +and building up an array of B commands for each dial string or +segment of dial tone. At the end, all the B commands are run +and their combined output (as raw samples) is piped to another B +command that writes the output as a single audio stream (raw, .wav, +or whatever format the B<-o>, B<--output> filename indicates). Because +the final B command reads only raw audio, it's impossible to +change the bitrate or sample size in between dial strings. + +B<2.> If anything on the command line starts with B<-> but isn't a +recognized option, it's not an error: it gets treated as a dial +string. This allows e.g. I<555 -1212> to work correctly, but +mistyped options will result in them being dialled as alphabetic +characters. This may be a bit surprising the first time it happens. + =head1 AUTHOR soxdial was written by B. Watson and released @@ -288,6 +315,25 @@ sub make_sox_cmd { return "( " . $subcmds . " ) | " . $cmd; } +# support either seconds (possibly with decimal point, e.g. 0.5) or +# milliseconds (e.g. 500ms). +sub parse_sec { + $_ = shift || 0; + if(/^(.+)ms$/) { + $_ = $1 / 1000; + } + return $_; +} + +# support either Hz (e.g. 8000) or KHz (e.g. 8k or 8K). +sub parse_rate { + $_ = shift || 0; + if(/^(.+)k$/i) { + $_ = $1 * 1000; + } + return $_; +} + # main() if(!@ARGV) { warn "$SELF: no dial strings. Try $SELF --help.\n"; @@ -297,11 +343,9 @@ if(!@ARGV) { for ($argc = 0; $argc < @ARGV; $argc++) { $_ = $ARGV[$argc]; - # note: unusually, if anything starts with - but isn't a recognized - # option, it's not an error (it gets treated as a dial string). this - # allows e.g. 555 -1212 to work correctly, but mistyped options will - # result in them being dialled as alphabetic characters. - if(/--?version$/) { + if(/=/) { + die "$SELF: GNU-style --option=value not supported, use --option value.\n"; + } elsif(/--?(?:V|version)$/) { print "$SELF $VERSION\n"; exit 0; } elsif(/^--?man$/) { @@ -319,6 +363,9 @@ for ($argc = 0; $argc < @ARGV; $argc++) { $output = $ARGV[++$argc]; warn "$SELF: output set to '$output'\n" if $verbose; } elsif(/^--?b(?:its)?$/) { + if(@sox_subcmds) { + die "$SELF: can't change bits after a dial string.\n"; + } $bits = $ARGV[++$argc]; if($bits == 8) { $encoding = "-eun"; @@ -329,11 +376,14 @@ for ($argc = 0; $argc < @ARGV; $argc++) { } warn "$SELF: bits set to '$bits'\n" if $verbose; } elsif(/^--?r(?:ate)?$/) { - $rate = $ARGV[++$argc]; + if(@sox_subcmds) { + die "$SELF: can't change bitrate after a dial string.\n"; + } + $rate = parse_rate($ARGV[++$argc]); warn "$SELF: bitrate set to '$rate'\n" if $verbose; die "$SELF: invalid bitrate.\n" unless $rate > 0; } elsif(/^--?l(?:ength)?$/) { - $digittime = $ARGV[++$argc]; + $digittime = parse_sec($ARGV[++$argc]); warn "$SELF: digit length set to '$digittime'\n" if $verbose; die "$SELF: invalid --length argument.\n" unless $digittime > 0; } elsif(/^--?(?:x|extended)$/) { @@ -343,15 +393,15 @@ for ($argc = 0; $argc < @ARGV; $argc++) { $extended = 0; warn "$SELF: extended DTMF (ABCD) disabled.\n" if $verbose; } elsif(/^--?d(?:elay)?$/) { - $intertime = $ARGV[++$argc]; + $intertime = parse_sec($ARGV[++$argc]); warn "$SELF: inter-digit delay set to '$intertime'\n" if $verbose; die "$SELF: invalid --delay argument.\n" unless $intertime > 0; } elsif(/^--?c(?:omma)?$/) { - $pausetime = $ARGV[++$argc]; + $pausetime = parse_sec($ARGV[++$argc]); warn "$SELF: comma delay set to '$pausetime'\n" if $verbose; die "$SELF: invalid --comma argument.\n" unless $pausetime > 0; } elsif(/^--?(?:t|dialtone)$/) { - push @sox_subcmds, dialtone_subcmd($ARGV[++$argc]); + push @sox_subcmds, dialtone_subcmd(parse_sec($ARGV[++$argc])); } else { warn "$SELF: start dial string '$_'\n" if $verbose; for (split "", $_) { -- cgit v1.2.3