Developing Saraswati: A robust, multi-channel audio recording, transmission and storage system

Specifications

Placeholder.

We have been able to make some progress, ultimately decided to use GStreamer, made some experiments using the GStreamer Rust bindings and finally settled the prototype implementation on the GStreamer Python bindings.

The working example flac-timestamp-chunked.py has been tested successfully with Python 2.x, Python 3.x, GStreamer 1.10.4 and GStreamer 1.14.4, on Linux and macOS.

If you want to try this at home, please follow up at the setup documentation, read about how to run the example and have fun.


The Linux machine we use for testing is a BeagleBone Black running Debian GNU/Linux 9 (stretch) on ARM. Thanks, @einsiedlerkrebs!

@weef just suggested to add support for WavPack (see also Lossless Audio Compression Codecs) which doesn’t sound bad, thanks!

As the Debian system conveniently covers many ARM targets, you should be able to run the software on other RaspberryPi- and BeagleBone-variants like the BeagleBone Green and the Raspberry Pi Zero W without many deviations to the setup procedure.

We will be happy about any reports if you manage to get this working on different hardware. Especially, we are looking at other Linux targets like OpenWRT on MIPS ;].

1 Like

I asked @weef about reasonable USB 2.0 hubs the other day. It should be suitable to accept a bunch of cheap audio interfaces like the VT1630A (see below) which just don’t fit well into regular USB hubs as the physical dimensions (their width) is too large to be able to operate them in a multi-device mode, i.e. to plug more than one audio interface dongle side-by-side.

This one seems to fit the requirements well, as the sockets are arranged on edge. Exactly what I was asking for, so thanks again @weef!

Please recognize that this is mainly for workbench operations, in the field we are about to use real more professional devices we are discussing at Audio hardware for BeagleBone.

EX-1177HMV

7 Port USB 2.0 Metall HUB für Trägerschiene, verschraubbar-EX-1177HMV

– Via: USB 2.0 Hubs mit vertikal angeordneten Ports

VIA VT1630A USB audio interface

image

VIA VT1630A USB audio interface from Uwe Greggers, Aron Dür and @BenB of http://www.honeybee.neurobiologie.fu-berlin.de/ fame - thanks!

Hallo,

ich weiß nicht ob das hier noch die richtige Stelle für meine Fragen ist. Ich hab mich jetzt auch mal in das Thema eingearbeitet.

Die erste grundlegende Feststellung nach Schreiben eines kleinen Bash-Skriptes ist, dass der BeagleBone ganz gut damit klar zu kommen scheint 4 Kanäle gleichzeitig über USB-Soundkarten aufzunehmen. Vielleicht ist das doch die einfache Alternative zu Cape4All.

Dann hab ich Saraswati ausprobiert und es auch geschafft darüber etwas aufzunehmen.

Ich habe dazu folgende Fragen:

  • Habt ihr eine Liste von GStreamer Plugins, die auf jeden Fall installiert werden müssen?

Wenn man die Plugins so wie in der Saraswati-Anleitung installiert, ist der Beaglebone schon bis zu 99% oder 100% belegt.

  • Um mit Saraswati mehrkanälig aufzunehmen, könnte man theoretisch die Pipeline 4 mal starten, oder hat GStreamer da irgendwelche Begrenzungen?

  • Ich hing ganz schön lange an der GStreamer-Installation, einerseits weil ich herausfinden wollte, welche Plugins wirklich notwendig sind, anderseits, weil immer noch irgendwas fehlte. Z.B. hat zuletzt splitmuxsink nicht funktioniert. Irgendwelche Tipps, wie GStreamer vernünftig installiert werden kann?

  • Mein Plan ist, die Dateien zunächst (damit es auf jeden Fall noch vor dem Winter klappt) über einen Rsync-Daemon mit dem Server zu synchronisieren. Natürlich muss man die Rechte auf dem Server für den Beaglebone Nutzer einschränken, und ggf. den Key verschlüsseln, aber ich halte das erst mal für eine simple und brauchbare Lösung. Habt ihr Gedanken dazu?

Vielen Dank,
Diren

3 Likes

rsync via ssh mit key ist quasi ‘industriestandard’ ;) das wird viel benutzt und funktioniert gut.

hier ein kleines/r cheatsheet/primer:

rsync -avz --bwlimit=80 --rsh=ssh . foo.bar.de:/space/backups/foo/bar/fnord

mal als beispiel… das wuerde das lokale verzeichnis (man bemerke den . ) auf den server foo.bar.de syncen mit maximal 80kbyte bandbreitenlimit. a ist archive mode, z steht fuer compression (bringt bei compressed audio nix, aber bei den filelistings), v ist verbose → alles anzeigen was passiert. “archive mode” heisst: Alle permissions, symlinks etc bleiben erhalten.

damit das ganze auch einfach so tut musst du natuerlich einen ssh key in .ssh/config fuer foo.bar.de eingetragen haben:

Host foo.bar.de
IdentityFile ~/.ssh/bienenfookey
Protocol 2
User upload

damit das nicht mit first-connect-fragen nervt… einfach am anfang mal ssh foo.bar.de machen. will man eh testen.

das impliziert natuerlich das man das immer als der user unter dem dann der kram laeuft testet/installiert/configuriert.

spiel einfach mal damit, das sieht nur kompliziert aus, tut aber sehr zuverlaessig und ist eigentl. recht simpel.
du kannst z.b. auch fuer jeden stock einen frischen key und user auf dem server benutzten… wegen der security.

4 Likes

Hier mein aktueller Stand. Es läuft für 4-Kanäle und es gibt einen Servertransfer mit Rsync: GitHub - DieDiren/saraswati: Saraswati is a robust, multi-channel audio recording, transmission and storage system
(Sorry, ich komme gerade nicht dazu, hier mehr zu schreiben und die Doku im Repo ist auch schlecht formatiert)
Den Drift will ich mir unbedingt als nächstes anschauen, da werde ich dann auch noch mal in Ruhe alles durchlesen, was ihr hier schon gepostet habt.

2 Likes

Hi @Diren,

Ich habe es bisher leider auch nicht geschafft, auf Deinen Beitrag zu antworten, mea culpa.

Exzellent. Vielen Dank für Deine Verbesserung des Codes und der Dokumentation per version for four channels, accurate timestamp, server transfer. nothi… · DieDiren/saraswati@96ac1b7 · GitHub.

Anlässlich von @MKO’s Frage bei Audioaufzeichnungen an der Beute - #2 by MKO wäre es ja grandios, wenn wir diese Angelegenheit vielleicht (wieder-)beleben könnten?

Um einen Anfang zu machen, habe ich Deinen Patch gerade per Add capability for recording four channels, use accurate timestamp and add server transfer by amotl · Pull Request #3 · hiveeyes/saraswati · GitHub eingereicht.

Viele Grüße,
Andreas.

Saraswati 0.1.0 wurde gerade eben veröffentlicht, siehe saraswati · PyPI. Aus der Codesammlung ist nun ein halbwegs anständiges Programm geworden.

Aufnahmen können nun per "saraswati record" vorgenommen werden und die Kanaldefinition (Name sowie Audioquelle/-gerät) kann per Kommandozeile übergeben werden.

Vielen Dank nochmals an @Diren für die Mehrkanalerweiterung! Ich freue mich über Eure Tests mit echter Hardware.

# Record two channels with different sine waves.
saraswati record \
    --channel="channel1 source=audiotestsrc wave=3 freq=200" \
    --channel="channel2 source=audiotestsrc wave=3 freq=400"

# Record four channels from real audio hardware.
saraswati record \
    --channel='channel1 source=alsasrc device="hw:1"' \
    --channel='channel2 source=alsasrc device="hw:2"' \
    --channel='channel3 source=alsasrc device="hw:3"' \
    --channel='channel4 source=alsasrc device="hw:4"' \
    --spool=/var/spool/saraswati
1 Like

stecke gerade im Frühjahrshonig (gerade noch rechtzeitig vor der Linde; diesmal weniger Ahorn, dafür mit Robinie) - gerade keine Zeit zum Ausprobieren. ;(

2 Likes

Hi again,

Saraswati is growing up. Version 0.3.0 brings in the following improvements, partly based on different kinds of suggestions from the community. Thanks a stack and kudos to @weef, @roh, @clemens and @Diren.

Features

This is a more detailed overview of the recently added features summarized within the change log at saraswati/CHANGES.rst at 0.3.0 · hiveeyes/saraswati · GitHub.

Run recorder subsystem in separate thread

This was needed to be able to integrate the uploader subsystem (see below) using another thread.

Use 5 minutes recording chunk size as default

It can be adjusted be using the --chunk-duration= option, which takes an integer value in seconds.

Add uploader based on rsync

When the --upload= option is given, Saraswati will attempt to upload its spool directory to an rsync target. By default, it will do this each 5 minutes, which can be adjusted by using the --upload-interval= option.

# Record a single channel and upload via rsync.
saraswati record \
    --channel="testdrive source=autoaudiosrc" \
    --upload="rsync://foobar@daq.example.org:/var/spool/saraswati/testdrive/wp0Kel53aw/area-42/audionode-01"

Please note: By using rsync’s --remove-source-files option under the hood, the spooled files on the local machine will get purged after a successful upload.

Further parameters taken into account here, are, in SaraswatiUploader:

  • PICKUP_AGE_THRESHOLD = 25
    This makes sure no files will be touched which are still actively written to by the recorder subsystem. Only after the last modification time is min. 25 seconds ago, the file will be considered for uploading. This is implemented by using an appropriate find command with an option -not -newermt '-{PICKUP_AGE_THRESHOLD} seconds' operating on Saraswati’s spool directory.

  • BANDWIDTH_MAX = 80
    This value will get passed to rsync's --bwlimit= option.

  • IO_TIMEOUT = 15
    This value will get passed to rsync's --timeout= option.

Protect against running out of disk space

Disk space availability will be checked regularly. When a minimum threshold value is undershot, the recording will be suspended. After enough disk space is free again, the recording will be resumed. This is implemented by toggling GStreamer’s pipeline state flags between Gst.State.PLAYING and Gst.State.NULL.

By default, disk space checks will run each 60 seconds and will check for a minimum free disk space of 10%. Both values are defined per:

  • SaraswatiRecorder.SERVICE_TASK_INTERVAL = 60 and
  • SaraswatiRecorder.DISK_SPACE_MINIMUM_THRESHOLD = 0.1.

Conclusion

We believe all those features will contribute to make Saraswati ready for use in production-like environments. By trying to implement them in a resilient manner, we are aiming for low maintenance overhead in different situations when operating this software.

We will be happy to hear about any outcome, feel free to create respective issues about bug reports or feature requests at GitHub - hiveeyes/saraswati: Saraswati is a robust, multi-channel audio recording, transmission and storage system.

With kind regards,
Andreas.

/cc @Diren, @tox, @weef, @roh, @MKO

1 Like

Great Work @Andreas and @all others.

On my system, it works fine out of the box.

However, I have only tested 1 channel without rsync upload at the moment. I will be testing all features in the next days.

1 Like

Hi Roh,

Vielen Dank. Der aktuelle Stand der Implementierung ist der Folgende. Die --compress (aka. -z) Option habe ich weggelassen, um die CPU nicht unnötig mit weiteren Kompressionsarbeiten zu belasten, während gerade weitere Aufnahmen laufen. Da das Audiomaterial bereits per FLAC komprimiert wurde, ist das u.U. vertretbar. Ob das für den Praxisbetrieb richtig so ist, oder ob mich meine Intuition trügt, kann ich momentan noch nicht einschätzen. Bitte hakt hier ggf. noch einmal nach!

Dazu (davor) kommt noch der folgende find-Aufruf, die Idee dazu kam von @Diren per automaticRsync.sh. Vielen Dank!

Folgendes müsste noch besser adressiert werden, also vermutlich passend in die Doku gelangen:

@Diren hatte laut automaticRsync.sh scheinbar auch noch Bedarf für die Einstellung des SSH-Ports per -e 'ssh -p <port> -i <path-to-key>'. Dieses Detail müsste im Vergleich zum aktuellen Stand ebenfalls noch adressiert werden (per Implementierung und/oder Dokumentation).

Sagt gern Bescheid, wenn wir an dieser Stelle noch entscheidende Details vergessen haben oder die Implementierung derzeit noch für bestimmte Lebenslagen unzureichend ist.

Viele Grüße,
Andreas.

Hi again,

I tried it using Unlock WavPack codec for recorder by amotl · Pull Request #8 · hiveeyes/saraswati · GitHub but I am still failing. It is either that I need to improve my GStreamer pipeline syntax skills, or that the "wavpackenc" element needs special treatment when combined with "splitmuxsink", where it worked (almost) out of the box together with "flacenc".

I reported about more details at Add WavPack codec for recording · Issue #7 · hiveeyes/saraswati · GitHub. The relevant warning message we are getting from GStreamer is

2021-06-21 17:49:43,993 [saraswati.recorder] WARNING: Pipeline warning: gst_parse_error: Delayed linking failed. (7) (gst/parse/grammar.y(540): gst_parse_no_more_pads (): /GstPipeline:pipeline0/GstWavpackEnc:wavpackenc0:
failed delayed linking some pad of GstWavpackEnc named wavpackenc0 to pad  audio_0 of GstSplitMuxSink named muxer)

The pipeline definition in question, using wavpackenc, is

audiotestsrc wave=3 freq=200 ! audioconvert ! queue ! wavpackenc ! muxer.audio_0 splitmuxsink name=muxer muxer=matroskamux max-size-time=300000000000 max-files=9999

With kind regards,
Andreas.

P.S.: The pipeline definition which works, using flacenc and friends, is:

audiotestsrc wave=3 freq=200 ! audioconvert ! queue ! flacenc ! flactag ! flacparse ! muxer.audio_0 splitmuxsink name=muxer muxer=matroskamux max-size-time=300000000000 max-files=9999

Hi there,

in order to better support autonomous field operation, Saraswati 0.4.1 supports being invoked as a systemd service. Configuration will take place in /etc/default/saraswati. There is now a setup subcommand which saves you a few keystrokes to make this happen.

# Install Saraswati as systemd service
sudo saraswati setup --systemd

As the service will be invoked as user saraswati, it has been added to the audio user group in order to be able to access the audio hardware devices [1].

Further documentation about this has been added at Running Saraswati in production.

With kind regards,
Andreas.

/cc @MKO, @Diren, @clemens, @roh, @wtf


  1. Unfortunately, I have not been able to finally test this kind of operation on a Linux machine with real audio hardware, so I will be more than happy about any feedback on this. ↩︎

6 posts were merged into an existing topic: Installation von Saraswati auf einem Industrie PC, mit Upload auf Synology NAS

Michael hatte gerade noch erwähnt, dass es für Langzeitaufzeichnungen praktisch wäre, wenn der Zeitstempel noch besser im Ablagepfad reflektiert würde.

Also z.B.

/var/spool/saraswati/{year}/{month:02d}/{day:02d}/recording_{channel}_{timestamp}_{fragment:04d}.mka

Es sind schließlich doch einige viele Dateien, die dabei anfallen werden. Bei einer Fragmentdauer von fünf Minuten pro Datei sind es bereits 480 Dateien pro Kanal und Tag.

Einsprüche? Anmerkungen?

1 Like
  • ‘recording’ als Dateinamen-Beginn ist redundant, kann weg
  • timestamp als Namensbeginn würde z.B. eine bessere auto-Sortierung ermöglichen

Hi @weef,

merci für Deine Gedanken.

Sehr gut, das hatte ich auch schon überlegt.

Auch darüber hatte ich nachgedacht, ob der Kanalname oder der Timestamp vorgelagert sein sollte.

Am Anwendungsfall “ich will alle Dateien eines bestimmten Stocks (aka. Kanal) im Schwung haben” entlang gedacht, wäre ersteres ja durchaus sinnvoll, nicht? Sonst wird es schwierig, im Dateisystem-Archiv interaktiv per “browse & sort & select” entsprechend nach bestimmten Beuten (Kanälen) filtern zu können.

Wenn wir den Dateinamen mit dem Timestamp beginnen lassen wollen, wäre es wohl sinnvoll, dem Kanalnamen (zusätzlich?) ein übergeordnetes Verzeichnis zu spendieren?

Also vielleicht so?

/var/spool/saraswati/{year}/{month:02d}/{day:02d}/{channel}/{timestamp}_{channel}_{fragment:04d}.mka

Viele Grüße,
Andreas.

2 Likes