Forum: PC-Programmierung Übergang LInux Consolen-Programm -> Daemon


von Audio (Gast)


Lesenswert?

Hallo,
ich habe schon seit etlichen Jahren einen selbst-geschriebenen Linux 
Audio-Sampler im eigenen Gebrauch.
Dabei sollte er auf schwachen Maschinen nutzbar sein, und verzichtete 
auf GUI, Eingaben (Klangwechsel, Metronom ein/aus, Aufnahme als 
Midi-Datei speichern ...) machte ich mit primitiven Consolen-Eingaben, 
(nicht einmal ncurses)
Das GUI hätte den Sampler ausgebremst.

Jetzt würde ich gerne den Sampler auf einen RPi OHNE Bildschirm laufen 
lassen, und die Bedienung/Steuerung durch ein anderes 
Notebook/Web-Interface erledigen (mit lokaler Netzwerk-Anbindung).

D.h. auf den RPi mit Sampler müsste ein schlanker Web-Server laufen, 
z.B. lighttpd, und den Sampler steuern, d.h. Klangwechsel, Tempo 
Metronom ...
D.h. auf der Website sind einigen Buttons (Metronom on/off, Klänge, ...) 
und bei Betätigen beeinflusst das den Sampler auf dem RPi.

Fragen:
- Kostet der Webserver viele Rechenleistung, was den Sampler in die Knie 
zwingt ( Buffer-Underruns, "Knacksen"), d.h. mehr Rechenleistung als die 
Tastaturabfrage?

- Wie macht man die Steuerung/Kommunikation Webserver/Sampler? Lokale 
Sockets (localhost) ?

- Wo schreibt man eventuelle printf-Ausgaben hin? Als Daemon hat er ja 
keine Konsole mehr.

von NurEinGast (Gast)


Lesenswert?

Kannst Du dich nicht einfach vom Notebook mit ssh / telnet auf dem PI 
anmelden und den Audio-Sampler einfach so weiter verwenden wir bisher 
auch ?

von 50c (Gast)


Lesenswert?

NurEinGast schrieb:
> Kannst Du dich nicht einfach vom Notebook mit ssh / telnet auf dem PI
> anmelden und den Audio-Sampler einfach so weiter verwenden wir bisher
> auch ?

...oder den Audio-Sampler so erweitern, dass er z.B. via MQTT Kommandos 
empfangen kann. Der dazu notwendige Broker kann dazu auch auf der 
"schwachbrüstigen" Maschine laufen... Der verbraucht auf jeden Fall 
weniger Ressourcen, als ein Webserver und man ist auch viel flexibler.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Audio schrieb:
> - Kostet der Webserver viele Rechenleistung, was den Sampler in die Knie
> zwingt ( Buffer-Underruns, "Knacksen"), d.h. mehr Rechenleistung als die
> Tastaturabfrage?

Grundsätzlich hält sich das sehr in Grenzen, aber ein Webserver ist 
natürlich empfänglich für DoS und ähnliche Späße. Solange er nur im 
lokalen Netz hängt und nicht "nach draußen" exponiert ist, sollte das 
überschaubar bleiben.

> - Wie macht man die Steuerung/Kommunikation Webserver/Sampler? Lokale
> Sockets (localhost) ?

Lokale Sockets wären eine Möglichkeit, aber auch sog. Named Pipes wären 
hierfür sehr interessant.

> - Wo schreibt man eventuelle printf-Ausgaben hin? Als Daemon hat er ja
> keine Konsole mehr.

Hierfür gibt es die syslog-Funktionen:
http://man7.org/linux/man-pages/man3/syslog.3.html

Wenn es aber um "normale" Ausgaben geht, die dem Benutzer über das 
Webfrontend angezeigt werden sollen, muss die Ausgabe ebenfalls per 
Socket oder Named Pipe erfolgen. Insbesondere letztere sind ja auch für 
solche Anwendungen geschaffen worden.

Schwierig kann es bloß werden, dem Webserver beizubringen, fortwährend 
auf solch einem Kanal eintreffende Nachrichten an den Client 
weiterzureichen, insbesondere wenn dieser z.B. die HTTP-Verbindung 
schließt.

von Audio (Gast)


Lesenswert?

NurEinGast schrieb:
> Kannst Du dich nicht einfach vom Notebook mit ssh / telnet auf dem PI
> anmelden und den Audio-Sampler einfach so weiter verwenden wir bisher
> auch ?

Ja, das war mein erster Ansatz.
Allerdings ist damit das Notebook zwingend notwendig zum Betrieb.

Ich hätte gern, dass er ohne Notebook laufen kann, wenn man nur spielt.
Einige Einstellungen kann ich sogar mit dem Midi-Keyboard mit 
"Magic-Keys" erledigen (also Tasten, die keinen Ton erzeugen, sondern 
eine bestimmte Funktion im Sampler auslösen).

Wenn man allerdings komplexe Sachen macht, z.B. Aufnehmen und die 
Midi-Dateien bearbeiten will und sowieso ein Notebook braucht, dann das 
Web-Interface.

Wenn man das Projekt auch anderen zur Verfügung stellen möchte, dann ist 
ein grafischen (Web-) Interface ansprechender.
Praktischer sind die Magic-Keys, aber zum Einstieg total verwirrend.

von Otto Mans (Gast)


Lesenswert?

Vielleicht kannst Du Dein um einen simplen Webserver erweitern? Du 
brauchst hier ja nur einen rudimentären Teil von HTTP zu implementieren.

von Audio (Gast)


Lesenswert?

Otto Mans schrieb:
> einen simplen Webserver erweitern?

Ja, der Webserver selbst ist ja nicht das Problem.
Der Webserver / CGI-Programme müssen dann dem Sampler (im laufenden 
Betrieb) sagen, was er machen soll.
Meine erste Idee war, statt der PC-Tastatur-Abfrage (Klangwechsel ...) 
eine Socket-Abfrage zu machen.
Das CGI öffnet bei entsprechender Clicks einen Socket und schreibt den 
entsprechenden Befehl rein. Der Sampler interpretiert diesen Befehl und 
führt ihn aus.
Mittlerweilen

MQTT kenne ich bisher noch nicht. Das schaue ich mir mal an.


Andreas S. schrieb:
> fortwährend
> auf solch einem Kanal eintreffende Nachrichten an den Client
> weiterzureichen

Mittlerweilen gibt es ja Websockets, die ständig geöffnet bleiben. Wäre 
das eine Möglichkeit, die Nachrichten weiterzureichen?

von foobar (Gast)


Lesenswert?

Ne einfache, flexible und leichtgewichtige Methode wäre, statt von einem 
tty von einem UDP-socket die Kommandos entgegen zu nehmen und Ergebnisse 
passend zurückzuschicken[1]. Nen einfaches Konsolenprogramm zum 
Verschicken der Kommandos per UDP vervollständig das dann. Dies kann 
dann remote benutzt werden oder von lokalen CGIs aufgerufen werden.


[1] Die Konsequenzen eines komplett ungesicherten Protokolls muß man 
selbst abschätzen.

von Εrnst B. (ernst)


Lesenswert?

Ganz einfache Lösung aus der Unix-Steinzeit:

inetd oder etwas moderner xinetd

kümmert sich um das ganze Netzwerk-Daemon-Zeuchs, rudimentäre 
Zugriffskontrolle usw, und du musst dein Programm nicht viel, vielleicht 
garnicht, anpassen:

inetd öffnet den Listening socket, bei Connect wird dein Programm 
gestartet, und der TCP-Stream mit STDIN + STDOUT verkoppelt.

Optionen wie "nur eine Instanz gleichzeig", "erhöhte Priorität", uvm. 
findest du in der xinetd manpage.


"Blind" getipptes Beispiel:
1
# /etc/xinetd.d/sampler
2
service sampler {
3
                     type                = UNLISTED
4
                     socket_type         = stream
5
                     protocol            = tcp
6
                     wait                = no
7
                     server              = /home/rpiuser/bin/audio_sampler
8
                     port                = 12345
9
                     instances           = 1
10
                     user                = rpiuser
11
                     nice                = -5
12
                     only_from           = 192.168.123.0/24
13
}

usw.

von foobar (Gast)


Lesenswert?

> inetd oder etwas moderner xinetd

Das hatte ich bei meiner Antwort oben auch überlegt. Bei TCP hat er aber 
das gleiche Problem wie mit ssh (evtl mehrere parallele sampler, wird 
beendet wenn der Socket geschlossen wird, etc). Und bei UDP war ich mir 
nicht ganz sicher über das "wait"-Verhalten vom inetd bei UDP - könnte 
gehen, spätestens beim Verschicken von Antworten werden aber kleine 
Anpassungen nötig (recvfrom mit passendem sendto).

von Audio (Gast)


Lesenswert?

ich habe schon angefangen, mit (Barkeley-) Sockets zu implementieren.
Also anstatt der Loop, die die PC-tastatur-Eingaben verarbeitet, so 
etwas:
1
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
2
listen(sockfd,5);
3
while (TRUE) {
4
  newsockfd= accept(sockfd,(struct sockaddr*)&cli_addr,&clilen);
5
  n = read(newsockfd,buffer,256,0);
6
  ...
7
  n = write(newsockfd,"...",n2,0);
8
  ...
9
  close(newsockfd);
10
}

von den inetd wusste ich noch gar nichts.
Damit könnte ich den Socket-Stream auf die stdi/o umlenken?

lässt man den CGI<-->Sampler - Socket ständig offen (Sampler=Server, 
CGI=Client), oder öffnet man diesen bei jedem Click?

Ich befürchte, dass bei jedem Öffen die Rechnerlast ansteigt und ein 
Knacksen kommt.
Das wäre bei Klängänderungsbefehlen nicht so schlimm, da der User 
sowieso nicht spielt.
Aber wenn man mit Ajax Nachrichten vom Sampler periodisch abholt, dann 
wäre das blöd, wenn es dann jedesmal "knackst" (d.h. Buffer-Underruns)

von Audio (Gast)


Lesenswert?

Aber wie machen das andere Daemonen?
Wenn man sich die Anleitung anschaut
http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html

dann gibt es nur das "kill" Command, um den Daemon zu beenden.
Sind die Unix-Signale (USR1,URS2) die Standard-Methoden, um mit Daemonen 
zu kommunizieren?

von Bernd K. (prof7bit)


Lesenswert?

Nimm ZeroMQ.

Das ist noch ziemlich low-level aber erschlägt schonmal eine Menge 
langweiligen und fehlerträchtigen Boilerplate.

von Andreas M. (amesser)


Lesenswert?

Audio schrieb:
> Aber wie machen das andere Daemonen?
> Wenn man sich die Anleitung anschaut
> http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html
>
> dann gibt es nur das "kill" Command, um den Daemon zu beenden.
> Sind die Unix-Signale (USR1,URS2) die Standard-Methoden, um mit Daemonen
> zu kommunizieren?

Für Minimal-Kommunikation reicht das ja auch (z.B. Lese deine 
Konfiguration neu ein).

Wie immer führen verschiedene Wege nach Rom
- Klassisch: irgendeine Art von Dateidescriptoren (zB. Unix Domain, UDP, 
TCP, Named Pipes, Standard Ein/Ausgabe) Der Vorteil ist, die Applikation 
macht im wesentlichen "Read" oder "Write" auf einem Dateidescriptor, 
womit der verbunden ist, ist egal. Einzig in der Initialisierung gibt es 
Unterschiede. Ein Lokaler Webserver könnte z.B. mittels PHP-Seite eine 
TCP Verbindung zum lokalen TCP Socket öffnen, das Kommando abschicken 
und wieder schließen. Oder der Wbserver liefert ein Javascript an den 
Browser aus, welches sich wiederum direkt mit dem TCP Socket 
verbindet...
- Dann gibt es diverse fertige RPC Implementierungen, möglicherweise 
können die dann auch per Webserver oder direkt per Javascript 
angesprochen werden.
- Auf Linux gibt es dann auch noch dbus, das wird gerade bei 
Desktopsystemen immer mehr eingesetzt.

von PittyJ (Gast)


Lesenswert?

Ich habe auf einem Single-Core Arm A7 mit 600MHz einen Webserver und 
SQL-DB-Server laufen. Dazu steuert das Teil noch Hardware.

Ein Raspi ist dagegen sehr leistungsfähig. Der hat 4 Kerne mit 1.4 Ghz. 
Darauf laufen auch Apache, SQL-Server und diverses andere Zeug parallel.
Video-Streaming etc läuft auch.

Probier doch erst einmal den Raspi aus, bevor du Einschränkungen in Kauf 
nehmen möchtest.

von Audio (Gast)


Lesenswert?

> Ein Raspi ist dagegen sehr leistungsfähig.

Das ist richtig.
Mit einem leistungsfähigen Notebook war die Latenz und die 
Buffer-Underruns nicht wesentlich verbessert.
Wobei die größte Performance-Steigerung hatte ich ich durch das 
openwrt-Linux.

Viele System-Prozesse haben eine große Negativ-Auswirkung auf die 
Sampler-Performance.

von Stefan F. (Gast)


Lesenswert?

Audio schrieb:
> Das GUI hätte den Sampler ausgebremst.

Wenn Du Dir da sicher bist, dann wird ein Webserver deinen Sampler 
wahrscheinlich auch ausbremsen.

Mit dem Befehl "screen" kannst du herkömmliche Programme in einer 
virtuellen Text-Konsole starten, auf die du dich später verbinden 
kannst.

So startest du zum Beispiel das Programm "top" in einer solchen 
virtuellen Konsole:
1
stefan@stefanspc:~$ screen -dmS Test top
2
stefan@stefanspc:~$

Sofort nach dem Start bekommst du wieder eine Eingabeaufforderung. Das 
Programm "top" läuft derweil im Hintergrund ähnlich einem Daemon.

Auflisten der screen Sitzungen:
1
stefan@stefanspc:~$ screen -ls
2
There is a screen on:
3
  8121.Test  (15.11.2018 18:32:31)  (Detached)
4
1 Socket in /run/screen/S-stefan.
5
stefan@stefanspc:~$

Interaktiv in eine laufende screen Sitzung einsteigen:
1
stefan@stefanspc:~$ screen -r Test

Danach erscheint die interaktive Bedienoberfläche vom Programm "top". 
Diese kannst du nun wie gewohnt bedienen. Mit der Tastenfolge Strg-A D 
verlässt du die screen Sitzung wieder ohne das darin laufende Programm 
zu beenden.

Diese Methode könntest du mit einem ssh Login kombinieren. Dann brauchst 
du keinen Webserver und den damit verbundenen Overhead. Wenn du die ssh 
Verbindung beendest, wird die screen Sitzung trotzdem weiter laufen.

von Marc (Gast)


Lesenswert?

Statt screen wuerde ich tmux verwenden.
Ich starte meine consolenprogramme per Skript nicht als daemon sondern 
starte sie in tmux.

von Marc (Gast)


Lesenswert?

Nachtrag: mittels

tmux send-keys kann man dem Programm auch aus anderen Prozessen Befehle 
oder Keys schicken. So koennte man es parallel auch per Webserver ... 
steuern.

von Audio (Gast)


Lesenswert?

> screen, tmux

Danke für den wertvollem Tipp! So was habe ich schon länger gesucht.
Allerdings eher für andere Dinge, z.B. wenn man auf einer remote 
Maschine was längeres starten will (z.B. build, make), aber nicht 
ständig mit ssh verbunden sein will.

von Michael D. (nospam2000)


Lesenswert?

Audio schrieb:
>> screen, tmux

ich würde noch "byobu" zur List hinzufügen, setzt auf diesen beiden 
Tools auf und ergänzt noch ein paar Funktionen.

  Michael

von Audio (Gast)


Lesenswert?

Ich habe die PC-Tastatur-Abfrage Loop geändert in einen Socket-Server.
Dazu einen kleinen Client für Console geschrieben.
Damit lässt er sich bedienen. (Client kann auf PC oder Target laufen)

Ich würde gerne Html mit Javascript mal ausprobieren.
Der Webserver muss ja nicht viel machen, einfach nur die statische Seite 
ausliefern, der Rest der Kommunikation erledigen Browser/Client und 
Sampler/Server.

Was nimmt man da? Habe gegoogelt und gesehen, dass es Socket.IO und 
Websockets gibt.

von Stefan F. (Gast)


Lesenswert?

Audio schrieb:
> Ich habe die PC-Tastatur-Abfrage Loop geändert in einen Socket-Server.

Das hättest du dir sparen könne, denn genau das macht der inet Daemon.

https://wiki.ubuntuusers.de/inetd/

von Nano (Gast)


Lesenswert?

Audio schrieb:
> Ich würde gerne Html mit Javascript mal ausprobieren.
> Der Webserver muss ja nicht viel machen, einfach nur die statische Seite
> ausliefern, der Rest der Kommunikation erledigen Browser/Client und
> Sampler/Server.

Spielt Sicherheit eine Rolle?
Wenn ja, dann muss der Server die Eingabedaten, die er vom Client erhält 
auch selber noch einmal prüfen.
Wenn das keine Rolle spielt, dann kann der Server sich auf das 
verlassen, was auf dem Client mit Javascript berechnet und übertragen 
wird.


Aber was spräche gegen eine klassische GUI Anwendung auf dem Client, die 
mit dem Server und einem schlanken Netzwerkprotokoll kommuniziert?
Dann bräuchtest du keinen Webserver auf dem Server laufen lassen.
Mit RAW TCP und RAW UDP bist du ziemlich frei, du könntest aber auch 
Netwzerk libs einbinden die das für dich machen.
Da ich mal schätze, das bei einem Audio Sampler auch die Latenz eine 
Rolle spielen könnte, könntest du dir auch diverse Game 
Netzwerklibraries mit einem Client/Server Modell ansehen. Die sind auf 
geringe Latenzen getrimmt.

Aber wenn das eh Audio ist, warum dann nicht einfach etwas Jack Audio 
Connection Kit konformes?
http://jackaudio.org/faq/netjack.html

von Audio (Gast)


Lesenswert?

"denn genau das macht der inet Daemon."

Die Overall Performance wird beim Einsatz zusätzlicher Tools nicht 
besser.

Erfahrungsgemäß muss ich den Code öfters umschreiben, bis es 
zufriedenstellend ist.
Aber für Lösungen, wo es auf Performance nicht ankommt, ist inetd 
durchaus nützlich und brauchbar.
Es kommt halt auf dem speziellen Fall drauf an.

Ich hatte schon gedacht, die Kommunikation zum Sampler mit einem 
virtuellen Midi-Port zu erledigen.
Ob der Sampler 2 oder 3 Midi In-Ports hat, wird bestimmt weniger 
Unterschied machen, als das zusätzliche Socket-Handling.

von ernst (Gast)


Lesenswert?

Audio schrieb:
> Die Overall Performance wird beim Einsatz zusätzlicher Tools nicht
> besser.

xinetd verwendet "dup2", um den TCP-Socket mit STDIN/STOUT des 
Daemon-Prozesses zu verheiraten.
Nach dem Connect&Startup gibt es also keinen Performance-Impact mehr, 
zumindest im Vergleich zu deiner while(true) { read  ... write ) 
Variante von oben.

Gibt natürlich viele andere Gründe, das Netzwerkhandling selber zu 
schreiben, aber "Performance" brauchst du nicht als Ausrede vorschieben.

von Audio (Gast)


Lesenswert?

> aber "Performance" brauchst du nicht als Ausrede vorschieben.

Das ist aber so.
Bereits mit einer lokalen Verbindung OHNE Applikation habe ich 
Buffer-Underruns.

Stecke ich das Netzwerkkabel aus, sind deutlich weniger Knackser zu 
hören.

Performance in meinen speziellen Fall meint nicht die 
Gesamt-Rechenleistung, sondern die zeitkritische rechtzeitige Ausgabe 
der der Audio-Buffer.

von Bernd K. (prof7bit)


Lesenswert?

Audio schrieb:
> Das ist aber so.
> Bereits mit einer lokalen Verbindung OHNE Applikation habe ich
> Buffer-Underruns.
>
> Stecke ich das Netzwerkkabel aus, sind deutlich weniger Knackser zu
> hören.

Mir schwant daß Deine Anwendung irgendwie was grundsätzlich falsch 
machen muß. Alle anderen Anwendungen die mit audio umgehen sind nicht so 
empfindlich.

von Audio (Gast)


Lesenswert?

> Alle anderen Anwendungen die mit audio umgehen

Hast Du da Erfahrung?
Wohlgemerkt, ich habe einen Sampler, der an ein Masterkeyboard 
angeschlossen ist, da soll man dann Klavier spielen!! In Echtzeit, d.h. 
Latenz nicht mehr hörbar.

Also ich bin mit meiner Anwendung schon sehr gut, ich komme mit 
Buffergröße 64 @ 44100Hz zurecht.
(der Buffer hat dann 256 Bytes, da eine Sample 4 Bytes hat, linker und 
rechter kanal je 16Bit)

Das sind 1.4 ms Abspielzeit pro Buffer. (64 / 44100)
Das ist das maximale, was man z.B. bei Windows mit den sog. 
"Asio-Treibern" rausholen kann.

Aber das war bei mir nur möglich mit openWrt.
Mit (Lite-) Raspbian oder archlinuxarm bin ich wesentlich schlechter.

von Sheeva P. (sheevaplug)


Lesenswert?

Audio schrieb:
> - Kostet der Webserver viele Rechenleistung, was den Sampler in die Knie
> zwingt ( Buffer-Underruns, "Knacksen"), d.h. mehr Rechenleistung als die
> Tastaturabfrage?

Ein aktuellerer Raspberry Pi hat vier Prozessorkerne mit je > 1 GHz. 
Wenn Dein Sampler single-threaded ist -- wovon ich ausgehe, sonst würde 
ihn eine einfache (n)curses-"GUI" nicht einmal auf einem 486er 
ausbremsen -- dürfte also auf einem der Prozessorkerne laufen, während 
die übrigen Programme des Systems und der Webserver sich die restlichen 
drei Cores teilen.

Zur Not läßt sich der Sampler mit taskset(1) an einen spezifischen Core 
binden. Dieser CPU-Core kann schlimmstenfalls auch noch beim Boot 
mittels des Kernelparameters isolcpus vom normalen Scheduler des 
Betriebssystems ausgeklammert werden, so daß Dein Sampler einen gesamten 
CPU-Core beinahe exklusiv für sich alleine hat (einige Interrupts 
ausgenommen...). Sollten 1,2 (RasPi 3) oder 1,4 (3+) GHz für Deinen 
Sampler nicht ausreichen, dann ist es wohl sinnvoller, die Performance 
des Samplers zu tunen. ;-)

Ansonsten ist es natürlich sinnvoll, den RasPi so weit wie möglich frei 
zu räumen, also unnötige Programme (GUI?) zu stoppen, zu entfernen, oder 
am Besten gar nicht erst zu installieren. SSH würde ich zu 
Wartungszwecken allerdings immer laufen lassen. ;-)

> - Wie macht man die Steuerung/Kommunikation Webserver/Sampler? Lokale
> Sockets (localhost) ?
>
> - Wo schreibt man eventuelle printf-Ausgaben hin? Als Daemon hat er ja
> keine Konsole mehr.

Warum denn nicht einfach wir bisher über stdin/stdout und etwa einfache 
Pipes (wie sie Pythons subprocess-Modul benutzt), oder Named Pipes? Das 
sind alles erprobte Konzepte -- und Du mußt den Sampler nicht anfassen.

Ich ganz persönlich glaube, daß dabei nichtmal ein kompletter Webserver 
notwendig ist, sondern daß -- wenn Du das Ganze nicht zum Internet hin 
exponieren möchtest -- sogar der eingebaute Entwicklungs-Webserver von 
Pythons Flask-Framework ausreicht. Der ist ebenfalls single-treaded und 
belegt also genau wie Dein Sampler lediglich einen Kern -- und hat dazu 
außerdem noch den Vorteil, daß stdin/-out/-err des Sampler-Prozesses in 
einer globalen Variablen gespeichert und von allen Funktionen/Handlern 
verwendet werden können. Vielleicht probierst Du erst einmal so einen 
Ansatz aus -- die beiden wichtigsten Wahrheiten des Performance-Tunings 
sind schließlich:

 "Premature optimization is the root of all evil." (Donald E. Knuth)

und

 "Measure, don't guess." (Kirk Pepperdine)

Oder, anders gesagt: Gedanken über Performancetuning macht man sich 
erst, wenn die Performance erwiesenermaßen nicht ausreicht. Und wenn man 
ein Performanceproblem hat, sollte man erstmal messen, welche Ressource 
überhaupt ausgelastet ist, damit man gezielt an dieser Stelle ansetzen 
kann. Alles andere ist absolut sinnlos!

von Rolf M. (rmagnus)


Lesenswert?

Audio schrieb:
>> Alle anderen Anwendungen die mit audio umgehen
>
> Hast Du da Erfahrung?
> Wohlgemerkt, ich habe einen Sampler, der an ein Masterkeyboard
> angeschlossen ist, da soll man dann Klavier spielen!! In Echtzeit, d.h.
> Latenz nicht mehr hörbar.

Nutzt du da auch ein low-latency-Audiosystem wie Jack und einen 
Realtime-Kernel?

> Also ich bin mit meiner Anwendung schon sehr gut, ich komme mit
> Buffergröße 64 @ 44100Hz zurecht.
> (der Buffer hat dann 256 Bytes, da eine Sample 4 Bytes hat, linker und
> rechter kanal je 16Bit)
>
> Das sind 1.4 ms Abspielzeit pro Buffer. (64 / 44100)
> Das ist das maximale, was man z.B. bei Windows mit den sog.
> "Asio-Treibern" rausholen kann.

Ja, das ist tatsächlich extrem kurz. Dass es bei so kurzen Puffern sehr 
empfindlich ist, kann ich mir vorstellen. Das dürfte auch vom 
verwendeten Audio-Interface abhängen, bzw. wenn es USB ist, vom 
USB-Controller.

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Jetzt betreten wir wahrscheinlich gleich Esoterik-Territorium aber ich 
behaupte daß eine Latenz von 1.4ms (und auch das doppelte und dreifache 
und mehr) nicht mehr wahrnehmbar ist. 1ms wären 30cm Distanz in der 
Luft. Ein Klavierspieler müßte den Kopf in den Klavierkasten stecken 
wenn ihn ein paar Millisekunden mehr oder weniger beim Spielen stören 
würden. Wie weit stehen die Monitorboxen entfernt?

: Bearbeitet durch User
von Audio (Gast)


Lesenswert?

> Nutzt du da auch ein low-latency-Audiosystem wie Jack und einen
> Realtime-Kernel?

Natürlich nicht auf einem Raspberry.
Ich hatte mal ein RT-Linux drauf, aber das war nix für diese Anwendung.
Mit low-tatency bin jetzt am Optimum, 1.4ms.
Ich habe jetzt das hotplugging (alsa, aconnect) vom Midi-Eingang zu 
Sampler beseitigt, und öffne das Midi-Handle von der Applikation.
D.h. Keyboard muss vor Starten des Programms eingesteckt sein.
Aber es hat was gebracht in Sachen Performance.

> Jetzt betreten wir wahrscheinlich gleich Esoterik-Territorium

DAW ist Neuland für Dich? (DAW = Digital Audio Workstation)
Dann informier Dich mal über die Größenordnung von akzeptabler Latenz.

von Rolf M. (rmagnus)


Lesenswert?

Mit der Latenz kommst du in den Bereich, den MIDI hat. Die reine 
Übertragung einer MIDI-NoteOn-Botschaft braucht alleine schon eine 
knappe Millisekunde.

Audio schrieb:
>> Nutzt du da auch ein low-latency-Audiosystem wie Jack und einen
>> Realtime-Kernel?
>
> Natürlich nicht auf einem Raspberry.

Warum "natürlich"? Jack ist genau für sowas gemacht, und ich wüsste 
nicht, warum das auf nem Raspi nicht gehen sollte.

> Ich hatte mal ein RT-Linux drauf, aber das war nix für diese Anwendung.

Ich weiß jetzt nicht genau, was du mit "RT-Linux" meinst. Ich spreche 
vom PREEMPT_RT-Kernel. Den halte iich dafür für essenziell. Jack starten 
und mit Realtime-Priorität laufen lassen. So wird es auch auf dem PC für 
Low-Latency-Audio empfohlen. Ich sehe keinen Grund, warum das für den 
Raspi anders sein sollte.

> Mit low-tatency bin jetzt am Optimum, 1.4ms.

Weniger wirst du nicht rausholen können und halte ich auch nicht für 
sinnvoll, aber du könntest es robuster gegen Aussetzer machen. Gerade 
die Realtime-Priorität ist für sowas hilfreich.

> Ich habe jetzt das hotplugging (alsa, aconnect) vom Midi-Eingang zu
> Sampler beseitigt, und öffne das Midi-Handle von der Applikation.
> D.h. Keyboard muss vor Starten des Programms eingesteckt sein.
> Aber es hat was gebracht in Sachen Performance.

von Audio (Gast)


Lesenswert?

> Weniger wirst du nicht rausholen können und halte ich auch nicht für
> sinnvoll,

Klar, das wäre nicht mehr sinnvoll, besser ist Cubase mit Asio-Treibern 
auch nicht.
Richtig, die anderen Komponenten im System haben ja auch Latenz in 
dieser Größenordnung.
z.B. Midi, wenn man tatsächlich das originale mit 31.25kBaud verwenden 
sollte.
Allerdings ist schon seit 10 Jahren üblich, Masterkeyboards direkt mit 
USB zu verwenden (Keyboard = Device, PC = Host)

Aber es geht auch um die relative Verzögerung: Tasten werden zu 
beliebigen Zeitpunkten gedrückt, aber die Töne klingen erst bei 
"Buffer-Anfang" (also ein 1.4ms Time-Grid)
Ein 128-Sample hätte ein 2.9ms-Grid und das ist dann hörbar, auch wenn 
die sonstige Latenz auch in dieser Größenordnung ist, aber KONSTANT.
D.h. nicht nur die absolute Latenz ist entscheidend, auch eine 
gleich-bleibende.

von BobbyX (Gast)


Lesenswert?

Audio schrieb:

> Das GUI hätte den Sampler ausgebremst.

Nach diesem Satz weiß ich, dass du etwas völlig falsch machst und lese 
nicht weiter.  Schon was von Threads gehört? Was meinst du wie alle DAW 
funktionieren, die extrem aufwendige GUIs haben und trotzdem auf sehr 
niedrige Latenzen kommen....

von BobbyX (Gast)


Lesenswert?

Audio schrieb:

> Ich hatte mal ein RT-Linux drauf, aber das war nix für diese Anwendung.
> Mit low-tatency bin jetzt am Optimum, 1.4ms.

Kannst Du und erklären wie du es schaffst, solche niedrige Latenz mit 
ALSA ( angeblich ) zu erreichen?

von Audio (Gast)


Lesenswert?

> Schon was von Threads gehört?

Der Sampler hat einige davon (pthread_t). Wieso?

> solche niedrige Latenz mit ALSA ( angeblich ) zu erreichen?

Ich habe gemeint, dass die Latenz, die vom Abspielen eines 64-Sample 
Buffer herrührt, 1.4ms beträgt. Da kommt natürlich was dazu, was vom 
System (Alsa) und Ausgabe auf Audio-Device herrührt.


> die extrem aufwendige GUIs haben und trotzdem auf sehr niedrige Latenzen kommen

Mit Sicherheit nicht auf einem Raspberry oder einen kleinen Netbook mit 
1Gb RAM.
Klar, ich habe auch Cubase, und weiß was möglich ist. Aber man braucht 
entsprechende Hardware!

von Rolf M. (rmagnus)


Lesenswert?

Audio schrieb:
>> Schon was von Threads gehört?
>
> Der Sampler hat einige davon (pthread_t). Wieso?

Weil die dafür sorgen sollten, dass die GUI deinen Abspieler nicht 
beeinflusst, sofern die Prioritäten richtig eingstellt sind - vor allem, 
wenn man mehrere Prozessorkerne hat.

>> solche niedrige Latenz mit ALSA ( angeblich ) zu erreichen?
>
> Ich habe gemeint, dass die Latenz, die vom Abspielen eines 64-Sample
> Buffer herrührt, 1.4ms beträgt. Da kommt natürlich was dazu, was vom
> System (Alsa) und Ausgabe auf Audio-Device herrührt.
>
>> die extrem aufwendige GUIs haben und trotzdem auf sehr niedrige Latenzen kommen
>
> Mit Sicherheit nicht auf einem Raspberry oder einen kleinen Netbook mit
> 1Gb RAM.

Hast du eigentlich eine Vorstellung davon, wie viel 1 GB ist? Stabiles 
Audio-Playing bei gleichzeitiger Verwendung einer graphischen Oberfläche 
hatte mach auch schon, als PCs noch 32 MB RAM und um die 100 MHz Takt 
hatten. Der Raspi ist demgegenüber eine Rakete!

von Audio (Gast)


Lesenswert?

Hast Du schon überhaupt etwas von einem Sampler gehört ?

https://en.wikipedia.org/wiki/Sampler_(musical_instrument)

Das ist etwas anderes als "mp3 abspielen".

von Rolf M. (rmagnus)


Lesenswert?

Audio schrieb:
> Hast Du schon überhaupt etwas von einem Sampler gehört ?

Ich habe einen Elektron Octatrack, also ja.

> https://en.wikipedia.org/wiki/Sampler_(musical_instrument)

Dann schau doch mal nach, was die dort abgebildete MPC für Hardware drin 
hat. Und die kann bis zu 32 Stereo-Kanäle mit 44 kHz. Als die gebaut 
wurde, hatten bei Computern die Festplatten 1 GB, aber nicht der RAM. 
Die MPC selbst hatte 2 MB. Und ein Prozessor wurde erstmals in einem 
Labor mit 1 GHz Takt betrieben. Auf dem Markt waren eher 200 Mhz das 
höchste der Gefühle.
Also sollte es für den Raspi ein Klacks sein, noch eine GUI darzustellen 
und nebenher noch ein paar Bitcoins zu minen.

: Bearbeitet durch User
von BobbyX (Gast)


Lesenswert?

Audio schrieb:
> Hast Du schon überhaupt etwas von einem Sampler gehört ?
>
> https://en.wikipedia.org/wiki/Sampler_(musical_instrument)
>
> Das ist etwas anderes als "mp3 abspielen".

Der war gut. MP3s abzuspielen ist weit rechenintensiever und komplexer 
als Samples, die gar nicht erst decoded werden müssen, da sie im 
Normalfall als WAV Datei gespeichert werden.

von Sven B. (scummos)


Lesenswert?

Hm, also die typische Lösung für einen Daemon mit Webserver wäre ja 
schon eine systemd-Unit finde ich ... wurde noch gar nicht genannt?

von Rolf M. (rmagnus)


Lesenswert?

BobbyX schrieb:
> MP3s abzuspielen ist weit rechenintensiever und komplexer als Samples,
> die gar nicht erst decoded werden müssen, da sie im Normalfall als WAV
> Datei gespeichert werden.

Allerdings. Mein 486er mit 33 MHz hatte kein Problem, ein Dutzend 
Samples zusammenzumischen, aber ein mp3 hat er nicht in Echtzeit 
dekodiert bekommen.
Anders sieht's natürlich aus, wenn man auch Effekte haben will und die 
auch nach was klingen sollen. Filter, Reverb, Chorus oder was auch 
immer. Die können dann schon etwas mehr Rechenlast produzieren.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Rolf M. schrieb:
> Allerdings. Mein 486er mit 33 MHz hatte kein Problem, ein Dutzend
> Samples zusammenzumischen, aber ein mp3 hat er nicht in Echtzeit
> dekodiert bekommen.

Dafür hatte ich damals auf 100MHz (4x 25MHz) aufgerüstet. Kennst du noch 
diese AMD Prozessoren mit 5V/3,3V Adapterplatine?

von Audio (Gast)


Lesenswert?

> für den Raspi ein Klacks sein, noch eine GUI darzustellen

hängt vom Arbeitseinsatz ab, und von der Frage, ob man das haben will.

OpenWRT bietet für den RPi kein GUI an (out-of-the-box).

Anstatt das zum laufen zu kriegen, würde ich lieber den RPi in 
"bare-metal" programmieren (ohne Display, nur Midi-IN, Audio-OUT und 
SD-Fatfs)

Oder den Sampler auf einen STM32 programmieren, der nur die ersten paar 
millisek jedes Samples im (knappen) RAM hält und den Rest von einer 
Class-10 SD-Karte spielt.
(Wenn man mehrstimmig spielt und mit mehren Klängen, hat man schnell zig 
Waves, die man "gleichzeitig" lesen muss und gemischt ausgeben)
So hat man das vor 20 Jahren mit den PCs auch gemacht.
Aber es ist ein hoher Arbeitsaufwand, den man nicht unbedingt 
investieren kann und will als Hobby-Projekt.

Beim STM32 kenne ich die Techniken schon (fatfs, usb-vcp/midi), beim RPi 
aber gar keine Erfahrung mit Bare-metal.

von Stefan F. (Gast)


Lesenswert?

Audio schrieb:
> würde ich lieber den RPi in "bare-metal" programmieren

Geht das überhaupt? Ist die dazu nötige Doku öffentlich zugänglich?

von Audio (Gast)


Lesenswert?

ich weiß nur, dass es Tutorials gibt.
z.B.
http://www.valvers.com/open-software/raspberry-pi/step01-bare-metal-programming-in-cpt1/

Was man aber mit bare-metal beim Raspberry machen kann, weiß ich nicht.
Interessant wäre es, da der RPi für 35€ ideal wäre für preiswerte 
Embedded-Anwendungen mit viel RAM-Bedarf.

von Sven B. (scummos)


Lesenswert?

Aber warum, für diesen Anwendungsfall? Linux ist halt super viel 
einfacher ...

von Stefan F. (Gast)


Lesenswert?

Sven B. schrieb:
> Aber warum, für diesen Anwendungsfall? Linux ist halt super viel
> einfacher ...

Die Frage wurde bereits mehrmals beantwortet, begründet und dementiert. 
Lass uns nicht im Kreis drehen!

von Audio (Gast)


Lesenswert?

Ich konnte noch einen Latenz-Vorteil bekommen, durch den Einsatz der 
"HifiBerry Soundkarte" (anstatt USB-Audio Adapter)
Das Teil wird auf der Steckerleiste draufgesteckt und hat 2 Cynch 
Audio-Ausgänge.
Allerdings kriege ich es nur mit Raspbian zum laufen.
(Die vorher verwendeten USB-Sound-Devices waren zwar in der 
Klangqualität besser, aber Latenz ist mir wesentlich wichtiger.)

Das verwendete Piano-Sample
https://archive.org/details/SalamanderGrandPianoV3

hat 16 Velocity-Layers (d.h. jeder Ton wurde mit 16 Anschlagsstärken 
aufgenommen, und je nach Key-Velocity wird das entsprechendes Sample 
abgespielt.
Da hätte ich 4 GB an RAM gebraucht.
Ich habe die Anzahl der Velocity-Layers auf 5 reduziert, die Samples 
verkürzt um 33% (mit sox und sauberem fade-in/out),
die Töne von 88 auf 73 (6 Oktaven) reduziert, dann komme ich auf 700MB 
und es passt gerade noch in das RAM vom PI rein.
Er braucht aber etwas, um die Samples zu laden.

Weitere Verbesserungen habe ich nicht vor, ich will auf STM32F4 
Discovery umsteigen, und die Samples vom Flash / externe SD-Karte 
spielen.

von Marco H. (damarco)


Lesenswert?

Normalerweise wird mit fork() der Prozeß kopiert und dann beendet. Der 
kopierte Prozeß läuft weiter... Dort braucht man dann einen 
Signalhändler um auf kill etc. Reagieren.. Ausgaben kann man ans syslog 
senden..

von S. R. (svenska)


Lesenswert?

Irgendwie machst du was falsch.

Wenn die Performance tatsächlich das Problem ist, weil deine Buffer zu 
klein sind und der Rest des Systems dein Programm stört, dann lass dein 
Programm separat und alleine auf einem Kern laufen. Ganz bare-metal. Die 
anderen drei Kerne können dann ein Linux laufen lassen, wie sie wollen.

Ansonsten ist für Echtzeitanforderungen ein Echtzeitkernel hilfreich. 
Dafür ist der gebaut.

von Rolf M. (rmagnus)


Lesenswert?

S. R. schrieb:
> Ansonsten ist für Echtzeitanforderungen ein Echtzeitkernel hilfreich.
> Dafür ist der gebaut.

Das hatte ich ja schon am Anfang geschrieben, aber er hat wohl irgendein 
nicht näher beschriebenes Problem mit dem Echtzeitkernel, das er 
anscheinend für normal hält:

Audio schrieb:
>> Nutzt du da auch ein low-latency-Audiosystem wie Jack und einen
>> Realtime-Kernel?
>
> Natürlich nicht auf einem Raspberry.
> Ich hatte mal ein RT-Linux drauf, aber das war nix für diese Anwendung.

: Bearbeitet durch User
von S. R. (svenska)


Lesenswert?

Sag ich ja: Irgendwas macht er falsch.

von Audio (Gast)


Lesenswert?

"Wenn die Performance tatsächlich das Problem ist, weil deine Buffer zu
klein sind"

Wenn man sowas schreibt, hat man wirklich KEINE Ahnung.
(Große Buffer verschlechtern Latenz/Performance)

Troll wo anders

von Rolf M. (rmagnus)


Lesenswert?

Audio schrieb:
> "Wenn die Performance tatsächlich das Problem ist, weil deine Buffer zu
> klein sind"
>
> Wenn man sowas schreibt, hat man wirklich KEINE Ahnung.
> (Große Buffer verschlechtern Latenz/Performance)

Nein. Große Buffer vergrößern die Latenz, entlasten aber das System und 
verbessern damit die Performance und verringern die Wahrscheinlichkeit 
von Aussetzern.
Sonst würde ja auch nichts dagegen sprechen, seine Buffer nur 1 Sample 
groß zu machen.

: Bearbeitet durch User
von Marco H. (damarco)


Lesenswert?

http://man7.org/linux/man-pages/man2/mmap.2.html bekommst du die Samples 
in den RAM..

Der Rest ist simple über pointer zu lösen.

von S. R. (svenska)


Lesenswert?

Audio schrieb:
> Wenn man sowas schreibt, hat man wirklich KEINE Ahnung.

Warum hast du dann überhaupt Buffer?

von Marco H. (damarco)


Lesenswert?

Da zum Ton ja nicht nur ein Sample gehört und der Linuxkernel nicht in 
der Lage ist die i2s Schnittstelle Timing genau zu bedienen. ich würde 
aber erst mal schauen ob nicht im Kernel und der Hardware weiter Buffer 
schon vorhanden sind.

So gesehen meinen Buffer nur so groß zu machen das die samples sicher 
aus dem Userspace dem Kernel übergeben werden können.

: Bearbeitet durch User
von BobbyX (Gast)


Lesenswert?

OMG, eine einfache Audio Anwendung als Daemon oder Web Service machen zu 
wollen, damit die Latenz besser wird, darauf muss man erst kommen ;-)

Leider kommen all zu viele selbst ernannante Programmierer auf solchen 
Unsinn und sind dann noch beleidigt, wenn man denen aufzeigt wie abartig 
das ist, was sie vorhaben. Leider nicht nur im Audio Bereich.

Erinnert mich sehr an SooperLooper. Jedes Loop ist dort eine separater 
Prozess. Entsprechend riesig ist die CPU Last. Auf meinem alten Laptop, 
den ich mal zum Live Looping benutzen wollte erzugte das Ding 40% CPU 
Last im IDLE Zustand, dh ohne das ein Loop aktiv war.... Ein 
Programmchen, das nichts anderes tun soll, als Audio Streams im 
Speicher zu halten, sie Zeit versetzt abzuspielen, und sie zu mischen, 
was eine Simple Addition ist.

Der MIDI Editor für meinen Roland GR-55 ( GR Floorboard ) hat ähnliche 
Talente.... 10% ständiger CPU last nur um ab und zu ein Paar SysEx Daten 
hin und herzuschieben....

Usw... usf...

Overengineering ist eins der grössten Übels in der modernen 
Softwareentwicklung.

von Stefan F. (Gast)


Lesenswert?

BobbyX schrieb:
> Overengineering ist eins der grössten Übels in der modernen
> Softwareentwicklung.

Ja, dafür ein +1

von temp (Gast)


Lesenswert?

Ich werfe mal OSC in den Ring.
https://en.wikipedia.org/wiki/Open_Sound_Control
Ist relativ einfach zu implementieren und UDP basierend. Dafür gibt es 
dann für Handys und Tablets z.B. TouchOSC. Da kann man sich seine 
Bedieneinheit relativ schnell zusammen clicken. Einige DAWs können auch 
mit OSC umgehen.
https://hexler.net/software/touchosc
Besser ein relativ neuer Standard als etwas komplett selbst 
ausgedachtes.

von Marco H. (damarco)


Lesenswert?

Das Problem ist ja dabei, das er alle Samples im Speicher oder Einem 
ähnlichen Medium halten muss. Wenn du ein File Midi etc. Abspielen 
willst kann man im Hintergrund nachladen.

Das ganze ist sowieso für den Arsch. Da die Hardware selbst ohne OS 
dafür ungeeignet ist. Das Leidige Problem der Hardware des RPI..

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.