Generierung von Audio-Testfiles

Für den Test unserer Audio-Aufzeichnungs-Lösung Saraswati überlege ich gerade wie wir passende Audio-Test-Files oder -Test-Streams generieren.

Vielleicht wäre die Zeitansage mit Zusatzinfo wie “Audio-Kanal 1” usw. ganz gut. Als Idee eine Sprachsynthese die wir wieder einlesen:

Wenn es einfacher sein soll: Ein Handy, das über Klinke verbunden ist und die Zeit per App “ansagt”, etwa für Android Zeitansage - Sag mir die Zeit bei der konkreten App ist leider das kleinstmögliche Intervall 1 Sekunde, bei der “richtigen” Zeitansage alle 10 Sekunden.

GStreamer kann das bereits out-of-the box. Vielleicht reicht Dir das ja schon.

Wäre gut, wenn man damit auch die Parallelität / Versatz checken könnte, als ein definierter “piep” bei dem ich weiß, dass er 20:38:40 und 50ms :-) anfängt wäre schon cool, was können denn die GStreamer-Test-Streams nur Sinus rauf und runter?

@weef kennt sich hier auch ganz gut aus, vielleicht kann er einen kurzen Überblick geben.

Die gstreamer- audiotestsrc beherrscht folgende Generatoren:

sine ( 0 ) – Sine
square ( 1 ) – Square
saw ( 2 ) – Saw
triangle ( 3 ) – Triangle
silence ( 4 ) – Silence
white-noise ( 5 ) – White uniform noise
pink-noise ( 6 ) – Pink noise
sine-table ( 7 ) – Sine table
ticks ( 8 ) – Periodic Ticks
gaussian-noise ( 9 ) – White Gaussian noise
red-noise ( 10 ) – Red (brownian) noise
blue-noise ( 11 ) – Blue noise
violet-noise ( 12 ) – Violet noise

Bei ganz neuen gstreamer-Versionen kann ticks noch mit weiteren Parametern getuned werden. - Alles davon (auch silence) ist sinnvoll und kann einer bestehenden queue einfach ‘untergeschoben’ werden.

Wenn mehr als die eine Testquelle gleichzeitig gebraucht wird, ist ein mixer nötig, z.B.:

tiefer dreistimmiger Akkord mit rosa Rauschen und sekündlichen Sinus-ticks (Achtung: ticks sind hier 100% Pegel, also leiser machen!)

gst-launch-1.0 audiomixer name=mix mix. ! audioconvert ! audioresample ! autoaudiosink audiotestsrc volume=0.2 freq=220 ! mix. audiotestsrc volume=0.2 freq=120  ! mix. audiotestsrc volume=0.2 freq=280 ! mix. audiotestsrc wave=5 volume=0.01 ! mix. audiotestsrc wave=8 ! mix.

Vorschlagen möchte ich etwas, das diese exakte Position in der Zeit anzeigen kann sowie das Audiosignal selbst darstellt: nämlich die Verwendung von LTC (wp en), einer Darstellung von SMPTE-Timecode (wp de).

Dabei handelt es sich um einen im Audio-Frequenzband kodierbaren Timecode zum Synchronisieren von AV-Gerätschaft. Er bietet (ganz knapp) 24 Stunden mit 40 Millisekunden Auflösung (framerate=25) bis zu 33.33… ms (30 fps). Es gibt außerdem einstellbare userbits, die häufig das Datum kodieren (!). Als Audiokanal reichen schlimmstenfalls 8 ksps mit 8 bit, und selbst bei so geringer Auflösung werden glitches natürlich frame-genau erkannt.

Die ganze semi-pro- und pro-AV-Hardware und deren Fähigkeiten interessieren hier nicht, es geht mir hier um Software, die auf dem BeagleBone ein derartiges Signal kontrolliert erzeugen und auf der Empfängerseite interpretieren kann. Dadurch, daß der Empfänger das Signal maschinell auswerten und qualifizieren kann, sind automatisierbare Tests möglich!
Auch kann/sollte später bei Mehrkanalaudio (nicht joint stereo!) der timecode mitübertragen werden, um das Nutz-Audio ordentlich feingranular mit einem timestamp anzureichern.

gstreamer kann LTC bislang nur in video-Modulen (nicht allzu verwunderlich;) ) , und leider keinen LTC im audio generieren.

Hierfür gibt es aber die POSIX-Bibliothek libltc (linkt die libsoundio auf linux, mac und win) mit den Kommandozeilen-Helfern ltcgen und ltcdump:

Ausgabe von "ltcgen -h"
ltcgen - generate linear time code audio-file.
Usage: ltcgen [OPTION] 

Options:
 -d, --date datestring      set date, format is either DDMMYY or MM/DD/YY
 -f, --fps fps              set frame-rate NUM[/DEN][ndf|df] default: 25/1ndf 
 -g, --volume float         set output level in dBFS default -18db
 -h, --help                 display this help and exit
 -l, --duration time        set duration of file to encode [[[HH:]MM:]SS:]FF.
 -m, --timezone tz          set timezone in minutes-west of UTC
 -r, --reverse              encode backwards from start-time
 -s, --samplerate sr        specify samplerate (default 48000)
 -t, --timecode time        specify start-time/timecode [[[HH:]MM:]SS:]FF
 -u, --userbits bcd         specify fixed BCD user bits (max. 8 BCD digits)
                            CAUTION: This ignores any date/timezone settings!
 -V, --version              print version information and exit
 -z, --timezone tz          set timezone +HHMM

Unless a timecode (-t) is given, the current time/date are used.
Date (-d) and timezone (-z, -m) are only used if a timecode is given.
The timezome may be specified either as HHMM zone, or in minutes-west of UTC.

If the duration is <=0, ltcgen write until it receives SIGINT.

The output file-format is WAV, signed 16 bit, mono.

Report bugs to .
Website and manual: 
$

Das hier z.B. generiert ein File mit der (beim Erzeugen aktuellen) Uhrzeit für die Folgesekunde:

$ ltcgen -f 25 -l 00:00:01:00 -s 8000 ltc_1s.wav
console output
LTC framerate: 25/1 fps (non-drop-frame) -- TV 625/50
writing to 'ltc_1s.wav'
samplerate: 8000, duration 1000.0 ms
cfg LTC:   17/10/19 (DD/MM/YY) 21:38:44:04 +0000
wrote 8032 audio-samples
$

Aus diesem Audiofile macht ltcdump :

$ ltcdump -f 25/1 ltc_1s.wav

#User bits  Timecode   |    Pos. (samples)
#DISCONTINUITY
00191017   21:38:44:04 |        0      319  
00191017   21:38:44:05 |      320      639  
00191017   21:38:44:06 |      640      959  
00191017   21:38:44:07 |      960     1279  
00191017   21:38:44:08 |     1280     1599  
00191017   21:38:44:09 |     1600     1919  
00191017   21:38:44:10 |     1920     2239  
00191017   21:38:44:11 |     2240     2559  
00191017   21:38:44:12 |     2560     2879  
00191017   21:38:44:13 |     2880     3199  
00191017   21:38:44:14 |     3200     3519  
00191017   21:38:44:15 |     3520     3839  
00191017   21:38:44:16 |     3840     4159  
00191017   21:38:44:17 |     4160     4479  
00191017   21:38:44:18 |     4480     4799  
00191017   21:38:44:19 |     4800     5119  
00191017   21:38:44:20 |     5120     5439  
00191017   21:38:44:21 |     5440     5759  
00191017   21:38:44:22 |     5760     6079  
00191017   21:38:44:23 |     6080     6399  
00191017   21:38:44:24 |     6400     6719  
00191017   21:38:45:00 |     6720     7039  
00191017   21:38:45:01 |     7040     7359  
00191017   21:38:45:02 |     7360     7679  
00191017   21:38:45:03 |     7680     7999 

Auf diese Weise bringt der (Test-)Audiokanal seinen eigenen präzisen timestamp mit!


Die tools ltcgen und ltcdump brauchen zwingend ein file. Auch mkfifo hilft hier nicht weiter. Außerdem ist deren Natur die zeitsynchrone Abbildung, auch will auf einem SBC niemand ein vorproduziertes 24h-timecode-File bauen, lagern und danach verwerfen, und dann um 0 Uhr den nächsten Aufruf zu generieren.

Deshalb gibt es diese Helper auch als JACK-Variante jltcdump und jltcgen.

(Außerdem hat der Programmierer Robin Gareus für die JACK-Domäne noch die tools jltcntp (JACK LTC parser with NTP SHM support) und jltctrigger (JACK app to trigger actions on given LTC). Achja. und noch MIDI-timecode mit jltc2mtc)…


Als Nachteil hier könnte man anführen, daß dieses Signal nicht menschenlesbar bzw. -verständlich ist, wie die von @clemens angeführte Zeitansage. Tatsächlich kann man als Mensch in so einem Audiosignal bestenfalls Sekunden akustisch unterscheiden - immerhin.
Ebenso ist hier Entropie natürlich anders als bei dem geplanten Audiosignal, was für den FLAC-encoder wichtig sein könnte.


Das alles funktioniert bei mir auf x86_64 für ein aktuelles Linux; Mac und Win habe ich nicht probiert. JACK auf einem BeagleBoneX geht bestimmt, muß ich aber noch probieren; ein cross- und/oder native build für den BeagleBone(x) (Cortex-A8) könnte am kommenden Wochenende mal angedacht werden - wenn das hier außer @clemens und vielleicht @tox oder @Diren noch jemanden interessiert! ;)

2 Likes

This. Would. Be. Awesome!

Vielen Dank für diesen Hinweis!

1 Like

Noch eine Info zum Hintergrund, wir wollten bisher mit den BB das cape4all einsetzen, das git es nicht von der Stange und müsste erst produziert werden. @Diren hat nun 4 USB-Sound"karten" testweise mit Saraswati angeschubst und augenscheinlich läuft das gut, wäre eben toll das auch nochmal auf Datenebene zu verifizieren, bzw. zu schauen wie groß / klein der Versatz der damit aufgenommenen 4 Audio-Spuren tatsächlich ist.

1 Like