1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
#!/usr/bin/env ruby
# Copyright (C) 2013-2020 all contributors <dtas-all@nongnu.org>
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
# frozen_string_literal: true
USAGE = "Usage: #$0 [-x FREQ] [-l] /dev/fd/LO /dev/fd/HI DELAY [DELAY ...]"
require 'optparse'
dryrun = false
xover = '80'
delay_lo = []
delay_hi = []
adj_delay = delay_hi
out_channels = out_rate = out_type = nil
lowpass = 'lowpass %s lowpass %s'
highpass = 'highpass %s highpass %s'
op = OptionParser.new('', 24, ' ') do |opts|
opts.banner = USAGE
opts.on('-x', '--crossover-frequency FREQ') do |freq|
xover = freq
end
opts.on('-l', '--lowpass-delay') { adj_delay = delay_lo }
opts.on('-c', '--channels INTEGER') { |val| out_channels = val }
opts.on('-r', '--rate RATE') { |val| out_rate = val }
opts.on('-t', '--type FILE-TYPE') { |val| out_type = val }
opts.on('-n', '--dry-run') { dryrun = true }
opts.on('--lowpass FORMAT_STRING') { |s| lowpass = s }
opts.on('--highpass FORMAT_STRING') { |s| highpass = s }
opts.parse!(ARGV)
end
dev_fd_lo = ARGV.shift
dev_fd_hi = ARGV.shift
if ARGV.delete('-')
# we re-add the '-' below
out_channels && out_rate && out_type or
abort "-c, -r, and -t must all be specified for standard output"
cmd = "sox"
elsif out_channels || out_rate || out_type
abort "standard output (`-') must be specified with -c, -r, or -t"
else
cmd = "play"
end
soxfmt = ENV["SOXFMT"] or abort "#$0 SOXFMT undefined"
# configure the sox "delay" effect
delay = ARGV.dup
delay[0] or abort USAGE
channels = ENV['CHANNELS'] or abort "#$0 CHANNELS env must be set"
channels = channels.to_i
adj_delay.replace(delay.dup)
until adj_delay.size == channels
adj_delay << delay.last
end
adj_delay.unshift("delay")
# prepare two inputs:
delay_lo = delay_lo.join(' ')
delay_hi = delay_hi.join(' ')
lowpass_args = []
lowpass.gsub('%s') { |s| lowpass_args << xover; s }
highpass_args = []
highpass.gsub('%s') { |s| highpass_args << xover; s }
lo = "|exec sox #{soxfmt} #{dev_fd_lo} -p " \
"#{sprintf(lowpass, *lowpass_args)} #{delay_lo}".strip
hi = "|exec sox #{soxfmt} #{dev_fd_hi} -p " \
"#{sprintf(highpass, *highpass_args)} #{delay_hi}".strip
args = [ "-m", "-v1", lo, "-v1", hi ]
case cmd
when "sox"
args.unshift "sox"
args.concat(%W(-t#{out_type} -c#{out_channels} -r#{out_rate} -))
when "play"
args.unshift "-q"
args.unshift "play"
else
abort "BUG: bad cmd=#{cmd.inspect}"
end
if dryrun
p args
else
exec *args, close_others: false
end
|