gstlal 1.13.0
Loading...
Searching...
No Matches
gstlal_play
1#!/usr/bin/env python3
2#
3# Copyright (C) 2011--2013 Kipp Cannon, Chad Hanna, Drew Keppel
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the
7# Free Software Foundation; either version 2 of the License, or (at your
8# option) any later version.
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13# Public License for more details.
14#
15# You should have received a copy of the GNU General Public License along
16# with this program; if not, write to the Free Software Foundation, Inc.,
17# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19
20from optparse import OptionParser
21
22from ligo.lw import lsctables, ligolw
23from ligo.lw import utils as ligolw_utils
24from ligo.lw.utils import segments as ligolw_segments
25
26from gstlal import datasource
27from gstlal.psd import read_psd
28from gstlal.stream import Stream
29
30
122
123
124@lsctables.use_in
125class LIGOLWContentHandler(ligolw.LIGOLWContentHandler):
126 pass
127
128
129def parse_command_line():
130
131 parser = OptionParser(description = __doc__)
132
133 #
134 # First append the datasource common options
135 #
136
137 datasource.append_options(parser)
138
139 parser.add_option("--output", metavar = "filename", help = "Set the filename in which to save the output. If not given, output is sent to the default audio device. The filename's extension determines the format, the following are recognized: .wav, .flac, .ogg, .txt, /dev/stdout, /dev/stderr")
140 parser.add_option("--sample-format", metavar = "name", help = "Force a specific sample format for the output. If not specified, the format is chosen by auto-negotiation with the encoder. Allowed values are any GStreamer-recognized format that is compatible with the requested encoder. Examples include \"F32LE\", \"F64LE\".")
141 parser.add_option("--rate", metavar = "Hz", type = "int", default = 4096, help = "Downsample input to this sample rate. Default = 4096 Hz. Must be <= input sample rate or else you will get a caps negotiation error.")
142 parser.add_option("--whiten", action = "store_true", help = "Whiten the time series (default = do not whiten).")
143 parser.add_option("--veto-segments-file", metavar = "filename", help = "Set the name of the LIGO light-weight XML file from which to load vetoes (optional). Must coincide with --whiten")
144 parser.add_option("--veto-segments-name", metavar = "name", help = "Set the name of the segments to extract from the segment tables and use as the veto list. Must coincide with --whiten", default = "vetoes")
145 parser.add_option("--reference-psd", metavar = "file", help = "When whitening, normalize the time series to the spectrum described in this XML file. If this option is not given, the spectrum is measured from the data.")
146 parser.add_option("--low-pass-filter", metavar = "Hz", type = "float", help = "Low pass filter frequency (default = no low-pass filter). Low-pass filter is applied after whitening.")
147 parser.add_option("--high-pass-filter", metavar = "Hz", type = "float", help = "High pass filter frequency (default = no high-pass filter). High-pass filter is applied after whitening.")
148 parser.add_option("--amplification", metavar = "num", type = "float", default = 1.0, help = "Amplify the timeseries this much (default = no amplification). Amplification is applied after low- and high-pass filtering. For unwhitened h(t) that is bandpassed to the most sensitive region you might need to set this to 1e20 to make it audible")
149 parser.add_option("-v", "--verbose", action = "store_true", help = "Be verbose.")
150
151 #
152 # parse the arguments and sanity check
153 #
154
155 options, filenames = parser.parse_args()
156
157 if options.low_pass_filter is not None and options.high_pass_filter is not None:
158 if options.low_pass_filter <= options.high_pass_filter:
159 raise ValueError("--low-pass-filter must be > --high-pass-filter")
160
161 if (options.reference_psd or options.veto_segments_file) and not options.whiten:
162 raise ValueError("--reference-psd and --veto-segments-file requires --whiten")
163
164 if len(options.channel_name) > 1:
165 raise ValueError("only one --channel-name allowed")
166
167 return options, filenames
168
169
170# parsing and setting up some core structures
171options, filenames = parse_command_line()
172
173gw_data_source_info = datasource.DataSourceInfo.from_optparse(options)
174instrument, = gw_data_source_info.channel_dict
175
176if options.reference_psd is not None:
177 psd = read_psd(options.reference_psd, verbose = options.verbose)[instrument]
178else:
179 psd = None
180
181if options.veto_segments_file is not None:
182 veto_segments = ligolw_segments.segmenttable_get_by_name(ligolw_utils.load_filename(options.veto_segments_file, verbose = options.verbose, contenthandler = LIGOLWContentHandler), options.veto_segments_name).coalesce()[instrument]
183else:
184 veto_segments = None
185
186#
187# the pipeline
188#
189# A basic src
190stream = Stream.from_datasource(gw_data_source_info, instrument, name="gstlal_play", verbose=options.verbose)
191
192# if not whitening, just resample
193if options.whiten:
194 stream = stream.condition(options.rate, instrument, psd=psd, track_psd=True, veto_segments=veto_segments)
195else:
196 stream = stream.resample(quality=9).capsfilter(f"audio/x-raw, rate={options.rate:d}")
197
198# handle filtering
199if options.high_pass_filter is not None and options.low_pass_filter is not None:
200 stream = stream.audiochebband(lower_frequency=options.high_pass_filter, upper_frequency=options.low_pass_filter)
201elif options.high_pass_filter is not None:
202 stream = stream.audiocheblimit(cutoff=options.high_pass_filter, mode="high-pass")
203elif options.low_pass_filter is not None:
204 stream = stream.audiocheblimit(cutoff=options.low_pass_filter, mode="low-pass")
205
206# necessary audio convert and amplify
207stream = stream.audioamplify(options.amplification).audioconvert()
208if options.sample_format is not None:
209 stream = stream.capsfilter(f"audio/x-raw, format={options.sample_format}")
210
211if options.output is None:
212 stream.autoaudiosink()
213elif options.output.endswith(".wav"):
214 stream.wavenc().filesink(options.output)
215elif options.output.endswith(".flac"):
216 stream.flacenc().filesink(options.output)
217elif options.output.endswith(".ogg"):
218 stream.vorbisenc().oggmux().filesink(options.output)
219elif options.output.endswith(".txt") or options.output in ("/dev/stdout", "/dev/stderr"):
220 stream.nxydumpsink(options.output)
221else:
222 raise ValueError("unrecognized format for --output")
223
224# play
225stream.start()
This program will play data in a variety of ways.
Definition gstlal_play:125