-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcapture-direct.sh
191 lines (147 loc) · 5.96 KB
/
capture-direct.sh
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#!/bin/bash
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2023 Rene Wolf
CLOCK_GEN_ALSA_DEVICE=hw:CARD=CXADCADCClockGe
# NOTE should be adapted to your needs untill cli parsing is implemented
CLOCK_GEN_OUT_VIDEO=0
CXCARD_VIDEO_DEVICE=0
CXCARD_VIDEO_LEVEL=0
CXCARD_VIDEO_VMUX=0
# NOTE should be adapted to your needs untill cli parsing is implemented
CLOCK_GEN_OUT_AUDIO=1
CXCARD_AUDIO_DEVICE=1
CXCARD_AUDIO_LEVEL=0
CXCARD_AUDIO_VMUX=0
# https://stackoverflow.com/questions/192319/how-do-i-know-the-script-file-name-in-a-bash-script
MY_NAME=$(basename "$0")
function die
{
echo "$@" >&2
exit 1
}
function card_sysfs
{
echo -n "/sys/class/cxadc/$1/device/parameters"
}
function f_str_to_switch_name
{
echo "CXADC-$1"
}
function clock_gen_out_number_to_switch_name
{
echo "CXADC-Clock $1 Select Playback Source,0"
}
function setup_clock_gen
{
local clock_gen_out_number=$1 # 0 or 1
local clock_gen_fstr=$2 # frequency of the clock gen as a string: '20MHz' '28.63MHz' '40MHz' '50MHz'
local switch_name="$(f_str_to_switch_name $clock_gen_fstr)"
amixer -D $CLOCK_GEN_ALSA_DEVICE sset "$(clock_gen_out_number_to_switch_name $clock_gen_out_number)" "$switch_name" > /dev/null
# amixer output contains this line
# Item0: 'CXADC-28.63MHz'
local current_selection="$(amixer -D $CLOCK_GEN_ALSA_DEVICE sget "$(clock_gen_out_number_to_switch_name $clock_gen_out_number)" | grep Item0 | cut -d ":" -f 2 | tr -d " '")"
if [[ "$current_selection" != "$switch_name" ]] ; then
die "Setting switch $clock_gen_out_number to '$switch_name' failed, current value is '$current_selection'"
fi
}
function setup_audio_card
{
local sysfs_dir="$(card_sysfs cxadc${CXCARD_AUDIO_DEVICE})"
if [[ ! -d "$sysfs_dir" ]] ; then die "Can't find audio cxadc card at '$sysfs_dir'" ; fi
echo $CXCARD_AUDIO_VMUX > $sysfs_dir/vmux
echo 0 > $sysfs_dir/sixdb # 0 off 1 +6db
echo $CXCARD_AUDIO_LEVEL > $sysfs_dir/level # 0 min gain ... 31 max gain
echo 0 > $sysfs_dir/tenxfsc # 0=1.0 1=1.24 2=1.4
echo 0 > $sysfs_dir/tenbit # 0= 8bit 1=10bit (half rate)
# NOTE 40MHz seems to yield the best result in terms of noise etc
setup_clock_gen $CLOCK_GEN_OUT_AUDIO '40MHz'
}
function setup_video_card
{
local sysfs_dir="$(card_sysfs cxadc${CXCARD_VIDEO_DEVICE})"
if [[ ! -d "$sysfs_dir" ]] ; then die "Can't find video cxadc card at '$sysfs_dir'" ; fi
echo $CXCARD_VIDEO_VMUX > $sysfs_dir/vmux
echo 0 > $sysfs_dir/sixdb # 0 off 1 +6db
echo $CXCARD_VIDEO_LEVEL > $sysfs_dir/level # 0 min gain ... 31 max gain
echo 0 > $sysfs_dir/tenxfsc # 0=1.0 1=1.24 2=1.4
echo 0 > $sysfs_dir/tenbit # 0= 8bit 1=10bit (half rate)
# NOTE 40MHz seems to yield the best result in terms of noise etc
setup_clock_gen $CLOCK_GEN_OUT_VIDEO '40MHz'
}
function wait_for_ctrl_c
{
local keep_running=true
echo "Press Ctrl+C to stop recording"
trap "keep_running=false" SIGINT
while [[ $keep_running == true ]] ; do
sleep 1
done
trap - SIGINT
echo ""
}
function do_capture
{
local output_dir="$1"
local date_iso_now=$(date +%Y.%m.%d-%H.%M.%S)
local alsa_sample_rate=46875 # 48000 is possible but has reduced quality
local file_rf_video="$output_dir/$date_iso_now-rf-video-40msps.u8"
local file_rf_audio="$output_dir/$date_iso_now-rf-audio-40msps.u8"
local file_baseband_audio="$output_dir/$date_iso_now-baseband-audio-${alsa_sample_rate}sps-3ch-24bit-le.wav"
pid_0=0
pid_1=0
pid_2=0
local rf_buffer_size=256m # about 6 seconds of buffer on the rf streams at 40MByte/s
cat /dev/cxadc${CXCARD_VIDEO_DEVICE} | pv --timer --rate --bytes --buffer-size $rf_buffer_size > "$file_rf_video" &
pid_0=$!
echo "Capturing to '$file_rf_video'"
cat /dev/cxadc${CXCARD_AUDIO_DEVICE} | pv --timer --rate --bytes --buffer-size $rf_buffer_size > "$file_rf_audio" &
pid_1=$!
echo "Capturing to '$file_rf_audio'"
local alsa_period=12000 # about 250ms / 4-times per sec.
local alsa_buffer=$((48000 * 5)) # about 5 seconds of ALSA buffer
arecord -D $CLOCK_GEN_ALSA_DEVICE -c 3 -r $alsa_sample_rate -f S24_3LE --period-size=$alsa_period --buffer-size=$alsa_buffer "$file_baseband_audio" 2>&1 | grep -v "Aborted by signal Interrupt" &
pid_2=$!
echo "Capturing to '$file_baseband_audio'"
wait_for_ctrl_c
for pid in $pid_0 $pid_1 $pid_2 ; do
kill -SIGINT $pid 2>&1 | grep -v "No such process"
echo "Signal pid $pid"
done
for pid in $pid_0 $pid_1 $pid_2 ; do
wait $pid
echo "End pid $pid"
done
echo "Done capturing :D"
}
function sanity_checks
{
arecord --version | grep -q "Jaroslav" || die "arecord does not seem to be installed"
arecord -L | grep -q "^$CLOCK_GEN_ALSA_DEVICE" || die "arecrod can't find the clock gen '$CLOCK_GEN_ALSA_DEVICE' check that device is plugged in, and user $(whoami) is in 'audio' group"
amixer --version | grep -q "amixer version" || die "amixer does not seem to be installed"
sox --version | grep -q "SoX" || die "SoX does not seem to be installed"
pv --version | grep -q "Andrew" || die "pv does not seem to be installed"
}
function usage
{
local url="https://gitlab.com/wolfre/cxadc-clock-generator-audio-adc"
echo "A script to capture 3 streams of VHS in sync"
echo "Copyright (c) Rene Wolf"
echo "Copyright (c) Harry Munday"
echo ""
echo "Expects to have a $url installed, and ready as '$CLOCK_GEN_ALSA_DEVICE'"
echo ""
echo "Usage:"
echo "./$MY_NAME /media/lots-of-space/1984-oceania-holiday-tape"
echo " Will record RF streams from 2 CX cards and a 3ch wav from baseband audio."
echo " All stored as individual files into the given directory."
echo ""
echo "For more details, see $url"
}
output_dir="$1"
if [[ "$output_dir" == "--help" ]] || [[ "$output_dir" == "-h" ]] ; then usage ; exit 0 ; fi
if [[ "$output_dir" == "" ]] ; then die "Need an output directory, see --help for help" ; fi
if [[ ! -d "$output_dir" ]] ; then die "Output directory '$output_dir' does not exist" ; fi
sanity_checks
setup_video_card
setup_audio_card
do_capture "$output_dir"