dtas 0.13.1 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/Documentation/.gitignore +1 -0
  3. data/Documentation/GNUmakefile +28 -5
  4. data/Documentation/dtas-archive.pod +74 -0
  5. data/Documentation/dtas-console.pod +94 -0
  6. data/Documentation/{dtas-ctl.txt → dtas-ctl.pod} +21 -19
  7. data/Documentation/dtas-cueedit.pod +38 -0
  8. data/Documentation/dtas-enq.pod +43 -0
  9. data/Documentation/dtas-env.pod +75 -0
  10. data/Documentation/{dtas-msinkctl.txt → dtas-msinkctl.pod} +18 -14
  11. data/Documentation/{dtas-player.txt → dtas-player.pod} +34 -33
  12. data/Documentation/dtas-player_effects.pod +103 -0
  13. data/Documentation/dtas-player_protocol.pod +460 -0
  14. data/Documentation/{dtas-player_sink_examples.txt → dtas-player_sink_examples.pod} +25 -21
  15. data/Documentation/{dtas-sinkedit.txt → dtas-sinkedit.pod} +34 -24
  16. data/Documentation/{dtas-sourceedit.txt → dtas-sourceedit.pod} +34 -25
  17. data/Documentation/dtas-splitfx.pod +271 -0
  18. data/Documentation/dtas-tl.pod +129 -0
  19. data/Documentation/dtas-xdelay.pod +96 -0
  20. data/Documentation/update-footer.rb +16 -12
  21. data/GIT-VERSION-GEN +1 -1
  22. data/GNUmakefile +1 -1
  23. data/INSTALL +3 -3
  24. data/Rakefile +11 -4
  25. data/bin/dtas-console +1 -1
  26. data/bin/dtas-mlib +3 -1
  27. data/bin/dtas-tl +0 -1
  28. data/lib/dtas/format.rb +1 -1
  29. data/lib/dtas/mlib.rb +28 -19
  30. data/lib/dtas/partstats.rb +1 -1
  31. data/lib/dtas/player.rb +1 -1
  32. data/lib/dtas/player/client_handler.rb +18 -4
  33. data/lib/dtas/source/av_ff_common.rb +1 -0
  34. data/lib/dtas/source/mp3gain.rb +1 -1
  35. data/lib/dtas/source/sox.rb +8 -4
  36. data/lib/dtas/source/splitfx.rb +4 -0
  37. data/lib/dtas/tracklist.rb +19 -8
  38. metadata +20 -18
  39. data/Documentation/dtas-archive.txt +0 -62
  40. data/Documentation/dtas-console.txt +0 -73
  41. data/Documentation/dtas-cueedit.txt +0 -36
  42. data/Documentation/dtas-enq.txt +0 -41
  43. data/Documentation/dtas-env.txt +0 -60
  44. data/Documentation/dtas-player_effects.txt +0 -57
  45. data/Documentation/dtas-player_protocol.txt +0 -326
  46. data/Documentation/dtas-splitfx.txt +0 -188
  47. data/Documentation/dtas-tl.txt +0 -96
  48. data/Documentation/dtas-xdelay.txt +0 -76
@@ -1,41 +0,0 @@
1
- % dtas-enq(1) dtas user manual
2
- %
3
-
4
- # NAME
5
-
6
- dtas-enq - enqueue audio files for playback with dtas-player
7
-
8
- # SYNOPSYS
9
-
10
- dtas-enq [FILE...]
11
-
12
- # DESCRIPTION
13
-
14
- dtas-enq will enqueue a list of files given on the command-line to a
15
- running instance of dtas-player(1). dtas-player will start playing the
16
- newly enqueued files in the order given.
17
-
18
- # EXAMPLE
19
-
20
- $ dtas-enq /path/to/your/favorite/album/*.flac
21
-
22
- # ENVIRONMENT
23
-
24
- DTAS_PLAYER_SOCK - the path to the dtas-player listen socket.
25
- This defaults to ~/.dtas/player.sock
26
-
27
- # CONTACT
28
-
29
- All feedback welcome via plain-text mail to: <dtas-all@nongnu.org>\
30
- Mailing list archives available at <http://80x24.org/dtas-all/> and
31
- <ftp://lists.gnu.org/dtas-all/>\
32
- No subscription is necessary to post to the mailing list.
33
-
34
- # COPYRIGHT
35
-
36
- Copyright 2013-2016 all contributors <dtas-all@nongnu.org>.\
37
- License: GPL-3.0+ <http://www.gnu.org/licenses/gpl-3.0.txt>
38
-
39
- # SEE ALSO
40
-
41
- dtas-player(1), dtas-ctl(1)
@@ -1,60 +0,0 @@
1
- % dtas-env(7) dtas user manual
2
- %
3
-
4
- # NAME
5
-
6
- dtas-env - environment variables used through DTAS
7
-
8
- # DESCRIPTION
9
-
10
- As dtas uses Bourne shell and exposes it to users, dtas should have
11
- a cohesive set of common environment variables across its audio
12
- production and playback environments. This attempts to document
13
- them. Most of these environments are set and managed by dtas
14
- itself, but users editing commands (e.g. via dtas-sourcedit(1)
15
- should be aware of them.
16
-
17
- # ENVIRONMENT
18
-
19
- ECAFMT - an snippet of command-line switches for ecasound describing
20
- audio format parameters (such as word length, channels, sample rate),
21
- see dtas-player_protocol(7) for more info. (e.g. "-fs32_le,2,44100")
22
-
23
- INFILE - the primary input file for playback or processing.
24
- (e.g. "/path/to/ex.flac")
25
-
26
- RGFX - the sox effect used for applying ReplayGain compensation.
27
- Only used during playback in dtas-player. (e.g. "gain -6.0").
28
- Removing this prevents ReplayGain from working and may damage
29
- playback equipment with loudly mastered music.
30
-
31
- SOXFMT - an snippet of command-line switches for sox describing
32
- audio format parameters (such as word length, channels, sample rate),
33
- see dtas-player_protocol(7) for more info. (e.g. "-ts32 -c2 -r44100")
34
-
35
- TRIMFX - the sox effect used for seeking during playback with dtas-player
36
- and track offsets for dtas-splitfx. (e.g. "trim 36000s")
37
-
38
- Additionally, dtas-splitfx(1) documents more environment variables
39
- which are not used elsewhere.
40
-
41
- # ENVIRONMENT FOR OTHER EXECUTABLES
42
-
43
- By virtue of running other programs, dtas indirectly uses many
44
- commonly-accepted environment variables such as EDITOR / VISUAL for
45
- selecting a text editor, and SOX_OPTS, AUDIODEV, AUDIODRIVER for sox(1)
46
- and play(1) commands and LADSPA_PATH for anything using LADSPA plugins
47
- (including sox). The TMPDIR environment variable controls where
48
- temporary files are placed for most programs.
49
-
50
- # CONTACT
51
-
52
- All feedback welcome via plain-text mail to: <dtas-all@nongnu.org>\
53
- Mailing list archives available at <http://80x24.org/dtas-all/> and
54
- <ftp://lists.gnu.org/dtas-all/>\
55
- No subscription is necessary to post to the mailing list.
56
-
57
- # COPYRIGHT
58
-
59
- Copyright 2015-2016 all contributors <dtas-all@nongnu.org>.\
60
- License: GPL-3.0+ <http://www.gnu.org/licenses/gpl-3.0.txt>
@@ -1,57 +0,0 @@
1
- Effects in dtas-player may be applied either at the source or the sink.
2
- They are applied in the order described.
3
-
4
- 1. source effects
5
-
6
- Source effects are effects which should be applied per-source and do not
7
- rely on inter-track information.
8
-
9
- Examples include:
10
- - ReplayGain (simple gain changes)
11
- - anything which does not change the length of the audio:
12
- gain, stereo, highpass, lowpass, loudness, bass, treble, equalizer, ...
13
-
14
- Modifying source effects should introduce no extra gaps in playback.
15
- Effects which modify the length of the audio is not recommended here,
16
- as seek functionality will be impaired.
17
-
18
- 2. sink effects
19
-
20
- Sink effects are any effects which:
21
-
22
- 1) should only be applied to a specific sink
23
- 2) effects which require inter-track information
24
- (multiband delays/compressors/expanders)
25
- 3) alter the length of the audio
26
-
27
- In a multi-zone audio system (where each zone has its own sink), sink
28
- effects may also customize the sound of a certain zone while not
29
- affecting others.
30
-
31
- Examples include:
32
- - equalizer effects (highpass/bass/treble/equalizer)
33
- - loudness
34
- - delaying a certain channel or frequency range for time-alignment
35
- - compressors/limiters
36
- - reverb
37
- - gain
38
- - remix (for stereo image adjustments)
39
-
40
- Additionally, effects which are necessary due to the limitation of the
41
- playback hardware are applied at the sink:
42
-
43
- - rate
44
- - dither
45
- - remix (static channel mappings)
46
-
47
- # CONTACT
48
-
49
- All feedback welcome via plain-text mail to: <dtas-all@nongnu.org>\
50
- Mailing list archives available at <http://80x24.org/dtas-all/> and
51
- <ftp://lists.gnu.org/dtas-all/>\
52
- No subscription is necessary to post to the mailing list.
53
-
54
- # COPYRIGHT
55
-
56
- Copyright 2013-2016 all contributors <dtas-all@nongnu.org>.\
57
- License: GPL-3.0+ <http://www.gnu.org/licenses/gpl-3.0.txt>
@@ -1,326 +0,0 @@
1
- % dtas-player_protocol(7) dtas user manual
2
- %
3
-
4
- # NAME
5
-
6
- dtas-player_protocol - protocol for controling dtas-player
7
-
8
- # DESCRIPTION
9
-
10
- NOTE - NOTE - NOTE - NOTE - NOTE - NOTE - NOTE - NOTE
11
-
12
- I'm considering a heavy revamp of this protocol. The "OK" responses for
13
- a lot of commands may not be necessary since this is Unix sockets and
14
- not TCP, and I may move away from a request-response model and towards
15
- an entirely listen/notification model. I have little experience in
16
- non-TCP-based application protocols, so this is an area of
17
- experimentation for me.
18
-
19
- This must stay over Unix sockets because filesystem permissions are
20
- needed to enforce code execution permissions. dtas-player is really a
21
- shell in disguise, after all.
22
-
23
- Protocol feedback greatly appreciated, email us at dtas-all@nongnu.org
24
-
25
- *********************************************************
26
-
27
- This gives a specification of the dtas-player protocol over a local Unix
28
- SOCK_SEQPACKET socket. The dtas-player protocol should NOT be
29
- considered stable at this point and compatibility will break.
30
-
31
- Inspiration is taken from MPRIS and MPRIS 2.0 specifications (e.g.
32
- play_pause, play, pause), and there will be a proxy in the future to
33
- support MPRIS/MPRIS 2.0 clients.
34
-
35
- The DTAS_PLAYER_SOCK is the standard environment determining the control
36
- socket for dtas-player(1). This defaults to $HOME/.dtas/player.sock if
37
- unset.
38
-
39
- Most low-level commands may be issued using the dtas-ctl(1) command.
40
-
41
- Higher-level commands such as dtas-console(1), dtas-sourceedit(1),
42
- dtas-sinkedit(1), and dtas-enq(1) also implement this protocol.
43
-
44
- # ARGUMENT TYPES
45
-
46
- - BOOLEAN - must be "true" or "false"
47
- - INTEGER - a signed integer in decimal notation (base 10)
48
- - UNSIGNED - an unsigned integer in decimal or hex notation
49
- - ENVNAME - must be a suitable environment variable (setenv(3))
50
- - ENVVALUE - must be a suitable environment variable (setenv(3))
51
- - COMMAND, this may be quoted string passed to sh -c "",
52
- variable/argument expansion will be performed by the shell
53
- - SOURCENAME - "sox" or "av", more backends may be supported in the future
54
- - TIMESTAMP - a time stamp formatted in HH:MM:SS.FRAC (for seeking)
55
- - TRACKID - a unique unsigned integer in decimal (base-10) representing a
56
- track in the tracklist
57
- - FILENAME - an expanded pathname relative to / is recommended since
58
- dtas-player and the client may run in different directories
59
-
60
- # VARIABLE EXPANSION
61
-
62
- For source and sink "command" arguments, the $SOXFMT and $ECAFMT
63
- environment variables are exported automatically to source to ease
64
- integration with sox(1) and ecasound(1).
65
-
66
- Both $SOXFMT and $ECAFMT are based on the configured "format" of
67
- the dtas-player (see below).
68
-
69
- For all machines, $SOXFMT defaults to: -ts32 -c2 -r44100
70
- For little-endian machines, $ECAFMT defaults to: -fs32_le,2,44100
71
-
72
- # COMMANDS
73
-
74
- Commands here should be alphabetized according to `LC_ALL=C sort'
75
-
76
- * cd - change the current working directory of the player
77
-
78
- * clear - clear current queue (current track/command continues running)
79
- PENDING: this may be renamed to "queue clear" or "queue-clear"
80
-
81
- * cue - display the index/offsets of the file based on the embedded
82
- cue sheet, if any
83
-
84
- * cue next - skip to the next section of the track based on the
85
- embedded cue sheet. This may skip to the next track if there is
86
- no embedded cue sheet or if playing the last (embedded) track
87
-
88
- * cue prev - skip to the previous section of the track based on
89
- the embedded cue sheet. This may just seek to the beginning
90
- if there is no embedded cue sheet or if we are playing the first
91
- (embedded) track.
92
-
93
- * cue goto INTEGER - go to the embedded track with cue index denoted
94
- by INTEGER (0 is first track as returned by "cue"). Negative
95
- values of INTEGER allows selecting track relative to the last
96
- track (-1 is the last track, -2 is the penultimate, and so on).
97
-
98
- * current - output information about the currently-playing track/command
99
- in YAML. The structure of this is unstable and subject to change.
100
-
101
- * enq FILENAME - enqueue the given FILENAME for playback
102
- An expanded (full) pathname relative to '/' is recommended, as
103
- dtas-player and the client may be in different directories.
104
- PENDING: this may be renamed to "queue add"
105
-
106
- * enq-cmd "COMMAND" - run the following command for playback.
107
- The COMMAND is expected to output audio in the audio format matching
108
- the current audio format of the player. This may be a shell pipeline
109
- and include multiple commands. The $SOXFMT and $ECAFMT variables are
110
- available here.
111
- PENDING: this may be renamed to "queue add-cmd"
112
-
113
- * env ENVTOSET=ENVVALUE ENVTOSET2=ENVVALUE2
114
- Set environment variables. This affects all future source/sink
115
- processes as well as helper commands dtas-player may spawn
116
- (e.g. soxi(1)). Environment variables set this way are currently not
117
- preserved across invocations of dtas-player(1), but may change in the
118
- future.
119
-
120
- * env ENVTOUNSET1# ENVTOUNSET#
121
- Unset the given environment variable.
122
- PENDING: the '#' is ugly and inconsistent with the per-sink/source.
123
- env.
124
-
125
- * format FORMATARGS - configure the format between source and sink
126
- Changing this will affect the $SOXFMT and $ECAFMT environments passed
127
- to source and sink commands. Changing this implies a "restart"
128
- Changing rate to 48000 is probably useful if you plan on playing to some
129
- laptop sound cards. In all cases where "bypass" is supported, it
130
- removes the guarantee of gapless playback as the audio device(s)
131
- will likely need to be restarted.
132
-
133
-
134
- + channels=(UNSIGNED|bypass) - (default: 2 (stereo)) - number of
135
- channels to use internally. sox will internally invoke the remix
136
- effect when decoding. This supports the value "bypass" (without
137
- quotes) to avoid the automatic remix effect. Using "bypass" mode
138
- removes the guarantee of gapless playback, as the audio device will
139
- likely need to be restarted, introducing an audible gap.
140
- + endian=(big|little|swap) - (default: native) - there is probably no
141
- point in changing this unless you output over a network sink to
142
- a machine of different endianess.
143
- + bits=(UNSIGNED|bypass) - (default: implied from type) - sample precision
144
- (decoded)
145
- This may be pointless and removed in the future, since the sample
146
- precision is implied from type. This supports the value of "bypass"
147
- to avoid dither/truncation in later stages.
148
- + rate=(UNSIGNED|bypass) - (default: 44100) - sample rate of audio
149
- Typical values of rate are 44100, 48000, 88200, 96000. Not all
150
- DSP effects are compatible with all sampling rates/channels.
151
- This supports the value of "bypass" as well to avoid introducing
152
- software resamplers into the playback chain.
153
- + type=(s16|s24|s32|u16|u24|u32|f32|f64) - (default: s32)
154
- change the raw PCM format. s32 currently offers the best performance
155
- when only sox/play are used. f32 may offer better performance if
156
- piping to/from non-sox applications (e.g. ecasound)
157
-
158
- * pause - pause playback
159
- Player pause state is preserved across dtas-player invocations.
160
-
161
- * play - restart playback from pause. Playback sinks will yield
162
- control of the audio playback device once no source is playing.
163
-
164
- * play_pause - toggle the play/pause state. This starts playback if
165
- paused, and pauses playback if playing.
166
-
167
- * queue cat - dump the contents of the queue as YAML
168
- This may include arbitrary commands to be executed, filenames,
169
- and offsets for playback. The format is not intended to be
170
- stable and subject to internal changes in dtas-player.
171
-
172
- * restart - restarts all processes in the current pipeline. Playback
173
- will be momentarily interrupted while this change occurs. This is
174
- necessary if one of the commands (e.g. sox or ecasound) or loaded
175
- libraries (e.g. a LADSPA plugin) is upgraded. Use "source restart"
176
- instead to only restart the source chain, leaving the sinks
177
- untouched.
178
-
179
- * rg RGARGS - configure ReplayGain support
180
- All FLOAT values may be adjusted via '+=' or '-=' instead of simple
181
- assignment ('='). If RGARGS is empty, the current rg state of
182
- non-default values will be dumped in YAML.
183
- + fallback_gain=FLOAT (-6.0) - dB value
184
- Adjust the volume by this level (usually negative) for tracks
185
- missing ReplayGain tags. This is useful when the queue contains
186
- a mix of tracks with and without ReplayGain tags.
187
- + fallback_track=BOOLEAN (true)
188
- When in album_gain mode, fallback to track_gain if the
189
- REPLAYGAIN_ALBUM_GAIN metadata is missing.
190
- + mode=(album_gain|track_gain|track_norm|album_norm|off)
191
- This controls the ReplayGain tag to use. The *_norm options
192
- are used for peak normalization and not commonly found in other
193
- players.
194
- + preamp=FLOAT (0) - dB value
195
- Adjust the album_gain or track_gain amount by this value (in dB).
196
- + norm_level=FLOAT (1.0 == dBFS)
197
- Controls the level to normalize to when using album_norm or track_norm.
198
-
199
- * seek [+-]TIMESTAMP - seek the current track to a specified time.
200
- This is passed directly as the first argument for the sox(1) "trim"
201
- command. See the sox(1) manpage for details.
202
- Seeking to a relative time is also supported by prefixing the time
203
- with '+' or '-'
204
-
205
- * skip - abort current track/command (via closing the output pipe)
206
- Running the "clear" command before this will abort playback.
207
-
208
- * sink ls - list names of current sinks
209
-
210
- * sink cat SINKNAME - dump SINKNAME config in YAML
211
-
212
- * sink rm SINKNAME - remove SINKNAME
213
-
214
- * sink ed SINKNAME SINKARGS - create/edit SINKNAME
215
- This currently does not restart running (active) sinks.
216
- This will stop active sinks if active is set to false, and start
217
- active sinks if active is set to true.
218
- See dtas-sinkedit(1) for an example of using this.
219
- + command=COMMAND - change the command-line used for playback
220
- + active=BOOLEAN - whether or not the sink will be in use (default: false)
221
- + env.ENVNAME=ENVVALUE - set ENVNAME to ENVVALUE for the sink process
222
- + env#ENVNAME - unset ENVNAME in the sink process (only)
223
- + prio=INTEGER - priority of the sink, lower values run first
224
- + nonblock=BOOLEAN - drop audio data to avoid holding back other sinks
225
- + pipe_size=UNSIGNED - set the size of the pipe for the sink (Linux-only)
226
-
227
- * source cat SOURCENAME - dump the current source command and env in YAML
228
-
229
- * source ed SOURCENAME SOURCEARGS - edit the source parameters.
230
- This changes here will immediately restart the source process.
231
- See the code for dtas-sourceedit(1) for an example of using this.
232
- + command=COMMAND - change the command-line used to decode audio
233
- + env.ENVNAME=ENVVALUE - set ENVNAME to ENVVALUE for the source process
234
- + env#ENVNAME - unset ENVNAME in the source process (only)
235
- + tryorder=INTEGER - lower values are tried first
236
- PENDING: tryorder here is wrong and may be removed or changed.
237
- We need to account for at least two variables input file:
238
- 1. input type (flac/opus/mp3/etc)
239
- 2. transport protocol (local FS/http/ftp/sftp/etc)
240
-
241
- * source ls - dump the names of sources sorted by tryorder
242
-
243
- * source restart - restart the current source command
244
- This can be useful if the source file is changed during playback
245
- and the current player process is holding onto an unlinked inode.
246
- This is advantageous over a full "restart" as there is no audible
247
- gap on most systems.
248
-
249
- * state dump [FILENAME]
250
- Immediately dump the state of the player. If a FILENAME is specified,
251
- the state is written to that file. Otherwise, the default state file
252
- (configured via DTAS_PLAYER_STATE environment variable, defaulting
253
- to ~/.dtas/player_state.yml) is written to. This does not use fsync(2),
254
- users requiring fsync should open(2) that file and fsync(2) it
255
- themselves if necessary.
256
-
257
- * tl add FILENAME [TRACKID [BOOLEAN]] - add files to the tracklist
258
- With one arg, adds FILENAME to the head of the tracklist.
259
- If TRACKID is specified, FILENAME is added immediately after TRACKID
260
- on the existing tracklist. The final BOOLEAN argument replaces the
261
- currently playing track with the newly-added one.
262
- Returns the TRACKID of the newly added track
263
-
264
- * tl clear - clear current tracklist
265
-
266
- * tl current - display the pathname to the currently playing track
267
-
268
- * tl current-id - display the TRACKID of the currently playing track
269
-
270
- * tl remove TRACKID - remove the track with the given TRACKID from
271
- the track list and returns the FILENAME if successful
272
-
273
- * tl get [TRACKIDS]
274
- returns a list of TRACKIDS mapped to shell-escaped filenames.
275
-
276
- * tl goto TRACKID [TIMESTAMP] - plays the given TRACKID
277
- An optional timestamp may be added to prevent playing the
278
- same part(s) repeatedly
279
-
280
- * tl max [MAXIMUM] - sets or gets the maximum number of tracks
281
- allowed in the tracklist
282
-
283
- * tl next - jump to the next track in the tracklist
284
-
285
- * tl prev - jump to the previous track in the tracklist
286
-
287
- * tl repeat [BOOLEAN|1] - show/or change repeat status of the tracklist.
288
- With no args, this will show "true", "false", or "1"
289
- If set to "1", dtas-player will repeat the current track.
290
- Returns the previous repeat status.
291
-
292
- * tl shuffle [BOOLEAN] - show/or change the current shuffle status of
293
- the tracklist. Returns the previous shuffle status.
294
-
295
- * tl swap TRACKID_A TRACKID_B - swaps the positions of two tracks.
296
-
297
- * tl tracks
298
- returns a list of all TRACKIDS in the tracklist
299
-
300
- * trim [off|TBEG [TLEN]]
301
- Limits playback of all tracks in the tracklist to the time starting
302
- at TBEG and ending after TLEN has elapsed. Not specifying TLEN will
303
- cause sox. Like the sox "trim" effect, prefixing TLEN with a '='
304
- will be interpreted as an absolute stop time.
305
- Both TBEG and TLEN should be specified in seconds, not sample counts.
306
- Specifying "off" (without quotes) disables trim.
307
- This feature is intended to allow users to "zoom-in" on a particular
308
- portion of a track to tweak parameters (either with
309
- dtas-sourceedit(1) or via playback of splitfx YAML files) and often
310
- combined with looping the tracklist (via "tl repeat").
311
-
312
- * watch - adds the client to the passive watch list for notifications.
313
- It is recommended clients issue no further commands and open
314
- another client socket to issue non-watch commands.
315
-
316
- # CONTACT
317
-
318
- All feedback welcome via plain-text mail to: <dtas-all@nongnu.org>\
319
- Mailing list archives available at <http://80x24.org/dtas-all/> and
320
- <ftp://lists.gnu.org/dtas-all/>\
321
- No subscription is necessary to post to the mailing list.
322
-
323
- # COPYRIGHT
324
-
325
- Copyright 2013-2016 all contributors <dtas-all@nongnu.org>.\
326
- License: GPL-3.0+ <http://www.gnu.org/licenses/gpl-3.0.txt>