Hallo, ich habe ein eigenes C-Programm auf dem Raspberry Pi B+ (unter Raspbian) laufen, gestartet von der Konsole mit Adminrechten, da ich die Library wiringpi nutze. Gibt es eine Möglichkeit, parallel dazu eine Audiodatei auf dem I2S-Ausgang auszugeben? So in der Art, daß man ein weiteres Programm mit dem Namen der Audiodatei als Parameter aufruft, daß sozusagen im Hintertrund läuft und die Audiodatei auf dem I2S-Ausgang abspielt. Hardware, die das I2S-Signal weiterverarbeitet ist vorhanden (das Ganze wird ein digitaler Mehrkanal Vorverstärker und Heimkinozentrale), darum kümmert sich meine C-Software (nicht zeitkritisch, nur Initialisierung). Oder gibt es eine Library, mit der man Audiodateien auf dem I2S ausgeben kann? Es würde mir schon genügen, wenn lediglich WAV-Files abgespielt werden können, MP3 und FLAC wären als Zugabe natürlich nicht verkehrt, ginge aber notfalls auch ohne. Natürlich geht so nur Stereo, da nur ein I2S-Ausgang am Raspi vorhanden ist.. Das ganze ist eben eine zusätzliche Funktion, auch Audiodaten von einem Memorystick oder einer USB-Festplatte direkt im Verstärker abspielen zu können. Es gibt ja viele Anwendungen für Audioausgabe, auch ein Projekt für den I2S mit eigenen DACs, aber die machen nur das und können wohl nicht von anderen, eigenen Programmen aufgerufen werden. Das eigene Programm sollte dabei selber weiter laufen, wenn auch mit weniger Geschwindigkeit, das ist Bedingung. Gibt es da Möglichkeiten, evtl. auch eine, die vorhandene Audioabspielsoftware als eigene Task parall laufen läßt? Graphikausgabe des Audioprogramms ist nicht möglich, ebenso ist dann keine Maus und Tastatur an USB vorhanden (wird nur für Debuggingzwecke angeschlossen), da ich eine eigene Ausgabe über den Framebuffer mache und Drehgeber und Tasten über SPI oder direkt über Ports mache. Das Audioprogramm sollte also auch ausschließlich über die Konsole bedienbar sein. Ich hoffe, die Funktion "system", mit der man Konsolenbefehle vom eigenen C-Programm geben kann, funktioniert auch hier... Gruß Andy
Andreas W. schrieb: > Gibt es eine Möglichkeit, parallel dazu eine Audiodatei auf dem > I2S-Ausgang auszugeben? Wenn Du ein entsprechendes Programm hast und das Programm keine Ressourcen benutzt, die Dein anderes Programm bereits verwendet, ja. Raspian ist ein Linux, das ist ein Multitasking-Betriebssystem, das also konzeptionell dafür vorgesehen ist, mehrere Dinge gleichzeitig zu tun.
Hallo, I2S wird von meinem Programm nicht benutzt, das steuert ja sonst nur den Verstärker, die digitalen Audiosignale laufen nicht über den Raspi, Er soll eben nur eine zusätzliche Quelle sein. Einige Portpins und den SPI-Bus nutze ich, den I2C-Bus evtl. auch. aplay soll wohl wav abspielen können und wird von der Console bedient. Aber noch ist es mir ein Rätsel, wie man den I2S-Ausgang aktiviert und nutzt. Normalerweise hat man ja nur die Wahl zwischen dem analogen PWM-Sound (lausige Qualität) und digitalem Ton über HDMI. In Beitrag "Vorstellung digitaler Audioausgang für Raspberry Pi" im 8. Posting sind ein paar Zeilen angegeben, die man wahrscheinlich in /etc/modules hinzufügen soll. Ich weiß aber nicht, ob das speziell für das dortige Projekt mit der entsprechenden Software ist, z.B. muß ja die Hardware evtl. initialisiert werden, z.B. über den I2C-Bus. Ich brauche nur den I2S-Ausgang selber, mit der Abtastrate, die dem Audiofile entspricht, mein Verstärker bekommt Abtastratenwandler in Hardware, die das auf die internen 48kHz/24Bit in höchster Qualität umsetzen (120dB digitales SNR). Was muß man denn für aplay reinschreiben, wenn man nur den I2S-Ausgang selber braucht, aber sonst keinerlei sonstige Ansteuerung? Ich habe schon irgendwo gelesen, daß der Raspi 44.1kHz Abtastrate nicht exakt treffen kann, da der Takt von 19.2MHz kein Vielfaches davon ist. mit 48kHz müßte es dagegen passen. Hat man bei 44.1kHz dann Jitter oder ist die Abtastrate geringfügig höher oder niedriger, jedoch ohne Jitter? Letzteres wäre kein Problem, da die Abtastratenwandler beliebige Abtastraten (innerhalb Min- und Maxwerten) umsetzen können. Sonst brauche ich wohl doch so eine Art USB-Soundkarte oder USB->SP/DIF Konverter. Hat jemand evtl. noch Tipps, was man für Abspielsoftware sonst noch so nutzen könnte, Bedienung von der Konsole und Ausgabe über I2S? Kann man den Player auch während des Abspielens über die Konsole bedienen, also vor-/zurückspulen, Pause oder Stop, natürlich auch Beenden der Playersoftware (außer mit kill)? Gruß Andy
Ich habe auch ein paar Versuche durch. z.B. mit der Wolfson Audio Card. Zum Schluss bin ich bei einem USB-Adapter (HiRes USB-DAC SABRE) geblieben. War am einfachsten anzuschließen. Die Treiber waren schon im Kernel. Abspielen geht mit aplay -D hw:1,0 file.wav mpg123 -a hw:1,0 file.mp3 Bestimmt gehen andere Programme auch. Der Adapter kostet zwar 50 Euro, spart aber eine Menge Nerven bei der Anwendung.
Hallo, den HiRes USB-DAC SABRE werde ich mir wohl auch kaufen. Der hat zwar nur einen analogen Ausgang, aber praktisch jeder Audio-DAC hat ein I2S-Interface. Ich muß also nur die Signale dort abgreifen und habe dann mein digitales I2S-Signal. Die Wandler im Verstärker sind sicher noch besser (24Bit, ca. 120dB SNR am analogen Ausgang, sehr hochwertige Spannungsversorgung, symmetrische XLR-Ausgänge), deshalb muß es unbedingt ein digitaler Ausgang sein. Kann man den aplay auch während der Wiedergabe mit der Console steuern, zumindest stoppen und beenden? Gruß Andy
wie wäre es mit mplayer mplayer kontrollieren http://ubuntuforums.org/showthread.php?t=1629000 // pipe erstellen für die Verbindung zum mPlayer mkfifo /tmp/mplayer-control // Player im slave Modus starten mplayer -slave -input file=/tmp/mplayer-control /path/to/some/file/to/play // Komandos durch die Pipe zum mplayer schreiben echo "pause" > /tmp/mplayer-control echo "quit" > /tmp/mplayer-control // Lautstärke erhöhen echo "volume +1" > /tmp/mplayer-control echo "volume -1" > /tmp/mplayer-control // bestimmten Lautstärkepegel einstellen echo "set_property volume 0" > /tmp/mplayer-control
ich habe an meinen Pi ein TDA 7801 angeklemmt. Das ist ein vier Kanal Automotive Verstärker mit I2S Eingang. Habe ihn vorerst nur im legacy Mode laufen ohne I2C Bus. Dafür verwende ich die bei Raspbian bereits vorhandenen Hifi Gerry Treiber. https://www.hifiberry.com/upgrading-raspbian-to-jessie/ sudo echo "dtoverlay=hifiberry-dac" /boot/config.txt in /etc/modules/ snd_bcm2835 auskommentieren und dadurch alle anderen Ausgabemöglichkeiten abschalten wie Klinke(PWM) und HDMI ist glaube ich nicht mehr notwendig, war nur beim Kernel 3.18 drin pcm.!default { type hw card 0 } ctl.!default { type hw card 0 } in /etc/asound.conf aplay -l sollte nur ein device anzeigen, wenn man die anderen deaktiviert hat
Hifi Berry, immer diese Autokorrektur
Hallo, das wären schon mal ein paar Alternativen, wahrschenlich bleibe ich bei aplay und der USB-Hardware. Die hat offensichtlich keinen Jitter und einen FIFO. Lautstärkeregelung braucht der Player auch nicht, die ist viel besser in der Verstärkerhardware vorhanden. aplay spielt eine Audiodatei, mit kill kann ich das stoppen, ein- und ausblenden mache ich mit der Verstärkerhardware, um Clicks zu vermeiden. Schnellen Vor- und Rücklauf bieten die anderen Player evtl. auch nicht. Aber als Alternative, falls der ursprüngliche Plan nicht funktioniert, behalte ich die auch im Auge. Gruß Andy
Hallo,
eine Weile gab es den HiRes USB-DAC SABRE nicht mehr bei Amazon,
unbekannt, wann es den wieder geben wird. Etwas später gab es ihn dann
wieder, ich habe zwei bestellt und nach längerer Lieferzeit kam das
Paket dann auch an.
Funktioniert, wenn ich direkt in der Konsole "aplay -D hw:1,0
filename.wav" eingebe. während das Stück spielt, wird kein Promt an der
Konsole ausgegeben, der kommt erst, wenn das Stück zuende ist oder wenn
man mit CTRL-C abbricht. Die Audioqualität scheint gut zu sein, wenn ich
das digitale Signal abgreife, wird das sicher gut sein. Außerdem ist
auch offensichtlich ein optischer Ausgang voŕhanden, den habe ich aber
noch nicht getestet.
Ich kann auch in meinem eigenen C-Programm die Wiedergabe mit
system("aplay -D hw:1,0 filename.wav"); starten. Allerdings macht die
system-Funktion erst einen return, wenn das Stück fertig abgespielt ist.
So kann ich das nicht brauchen, ich muß irgendwie aplay von meinem
Programm aus starten können und während es läuft, soll auch mein
Programm gleich weiter laufen. System() wartet auf das Ende der
Kommandoausführung, ich brauche aber eine Möglichkeit, lediglich das
Kommando absetzen zu können und dann soll mein Programm gleich
weiterlaufen.
Gibt es so eine Möglichkeit? Kann man irgendwie von einem eigenen
Programm aus ein anderes starten, das dann parallel läuft und einen
nicht solange blockiert, bis es wieder beendet ist? Eine passende
C-Funktion ist mir nicht bekannt.
Es genügt, wenn ich aplay mit den Parametern starten und irgendwie auch
vorzeitig beenden kann (und wenn das mit kill gemacht wird, mit einer
zweiten Konsole von Hand geht das), weitere Funktionen brauche ich
nicht.
Gruß
Andreas
Das vorherige Posting ist von mir, ich war aus irgendeinem Grund ausgeloggt und hatte den Text schon komplett eingegeben...
Häng mal am Ende der Kommandozeile eine '&' an, dann sollte es im Hintergrund laufen.
Hallo, ich habe das mal von Hand in der Konsole probiert: Das Kommando wird abgesetzt, es gibt als Antwort "[1] nnnn" (nnnn ist die PID, kann man z.B. mit kill verwenden), anschließend kommt ein Promt. Aber gleich danach kommt "PLAYING WAVE 'aplay -D...Name.wav' : SIGNAL 16Bit..." hinterher und da kommt der Prompt erst, wenn man CTRL-C macht. Die Musik spielt aber weiter, man muß dann noch ein kill hinterherschicken. Mein Aufruf system() wird also wieder da festhängen, wo ich eben CTRL-C eingegeben habe. Was bewirkt das "&" denn am Ende? Gruß Andy
Andreas W. schrieb: > Was bewirkt das "&" denn am Ende? So startet man normalerweise Daemons - Programme, die im Hintergrund laufen sollen, die Kontrolle aber nach dem Start gleich wieder an die Konsole zurückgeben.
Andreas W. schrieb: > ich habe ein eigenes C-Programm auf dem Raspberry Pi B+ (unter Raspbian) > laufen, gestartet von der Konsole mit Adminrechten, da ich die Library > wiringpi nutze. Gibt es eine Möglichkeit, parallel dazu eine Audiodatei > auf dem I2S-Ausgang auszugeben? Da gibt es viele Möglichkeiten. Vielleicht möchtest Du Dir einmal den Music Player Daemon [1] anschauen, für den es in den Raspbian-Repositories ein fertiges Paket namens "mpd" gibt und der für solche Aufgaben IMHO besonders gut geeignet ist. [1] http://www.musicpd.org/
Das & am Ende veranlasst die Shell, das Programm im Hintergrund zu
starten und die Shell wieder frei zu geben. Du bekommst sofort wieder
ein Prompt. Das bleibt auch da, du kannst weitere Programme starten.
Allerdings ist die Ausgabe des ersten Programms noch mit der Shell
verknüpft und jede Ausgabe wird weiterhin dort hin geschrieben. Das ist
aber nur ein optisches Problem, du kannst trotzdem in der Shell normal
weiter arbeiten.
Wenn du die Ausgabe woanders hinhaben willst musst du sie umleiten, z.B.
mit
> aplay ... & > /dev/null
wird sie ins Nirwana gelenkt und stört nicht weiter.
Gerhard
Hallo,
inm der Zwischenzeit habe ich auch eine Lösung gefunden: Wenn ich eine
Musikdatei abspielen will, mache ich ein
pid = fork();
pid erhält im Childprozess eine Null, der Parentprozess die PID des
Childprozesses. danach kommt ein
if (pid == 0)
ist die Bedingung erfüllt, ist es der Childprozess, es folgt der Aufruf
von system(), danach ein exit.
Ist die Bedingung nichtz erfüllt, läuft währenddessen mein Programm
normal weiter. Wenn das Audiofile fertig gespielt ist, beendet sich der
Childprozess wieder.
Wenn ich die Wiedergabe abbrechen will, muß ich sowohl den Childprozess
als auch aplay killen. Für den Childprozess habe ich die pid, für aplay
rufe ich
system("top -b -n 1 > commande_top.txt")
auf. -b -n 1 sorgt dafür, daß die Liste der Prozesse nur einmal
ausgegeben werden und nich in einer Dauerschleife, die Ausgab e wird in
eine Datei umgeleitet. Die fird in einer Funktion von mir geöffnet und
dort die PID zum zugehörigen Prozess gesucht, der Prozessname ist
Parameter meiner Funktion, hier ist er "aplay". Damit habe ich die PID
von aplay und kann das auch killen. Ebenso kann ich so auch
feststellen, ob schon eine Wiedergabe läuft, dann gibt es die Prozesse
aplay und zweimal preamp (der Parent- und Childprozess von meinem
Programm), sonst nur einmal preamp.
Das ist zwar vielleicht recht umständlich, aber es funktioniert.
Gruß
Andy
es gibt doch auch killall wann irgendwo aplay läuft, reicht doch ein einfaches killall aplay um das zu beenden. Jedenfalls gibg das bei mir.
Matthias S. schrieb: > Andreas W. schrieb: >> Was bewirkt das "&" denn am Ende? > > So startet man normalerweise Daemons - Programme, die im Hintergrund > laufen sollen, die Kontrolle aber nach dem Start gleich wieder an die > Konsole zurückgeben. Jaein. Um einen richtigen Daemon zu starten, muß der Prozes von seinem kontrollierenden Terminal abgekoppelt werden. Wenn der Prozeß nur mit "&" am Ende gestartet wird, wird er beim Beenden der Shell (seines kontrollierenden Terminals) mit beendet, was man bei "richtigen" Daemons natürlich tunlichst vermeiden will. Deswegen müssen "richtige" Daemons mit Programmen wie "nohup" oder "daemon" gestartet werden, damit sie von der aufrufenden Shell abgekoppelt werden und bei deren Beendigung weiterlaufen.
Andreas W. schrieb: > inm der Zwischenzeit habe ich auch eine Lösung gefunden: Wenn ich eine > Musikdatei abspielen will, mache ich ein > > pid = fork(); > > pid erhält im Childprozess eine Null, der Parentprozess die PID des > Childprozesses. danach kommt ein > > if (pid == 0) > > ist die Bedingung erfüllt, ist es der Childprozess, es folgt der Aufruf > von system(), danach ein exit. Der Aufruf von "system" ist möglich, aber nicht sehr schön und auch nicht gerade sicher.Besser (tm) wäre es daher, der üblichen Vorgehensweise zu folgen und statt "system" eine Funktion der "exec"-Familie zu benutzen. > Wenn ich die Wiedergabe abbrechen will, muß ich sowohl den Childprozess > als auch aplay killen. Für den Childprozess habe ich die pid, für aplay > rufe ich > > system("top -b -n 1 > commande_top.txt") > > auf. Ohnehin wäre hier "ps" besser geeignet, aber noch viel einfacher kannst Du das mit "pidof" haben:
1 | FILE* pidof = popen("/bin/pidof <programmname>", "r"); |
2 | char buffer[BUFLEN+1]; |
3 | fgets(buffer, BUFLEN, pidof); |
4 | pclose(pidof); |
Jetzt stehen in Deiner Variablen "buffer" die Prozess-Ids des gesuchten Programms mit Leerzeichen getrennt in einer Zeile. Eine andere Variante wäre "pgrep", das die Pids zeilenweise ausgibt. Die IMHO beste Lösung wäre jedoch, das alles dem bereits genannten Music Player Daemon zu überlassen und dann in Deinem Programm den "mpc"-Client aufzurufen. Da kannst Du Dir das ganze Geforke etc. komplett sparen, weil der "mpc"-Client sofort zurückkommt, wenn er sein Kommando an den Server geschickt hat. Dann kannst Du mit "/usr/bin/mpc load <playlist>" eine Playlist laden, mit "mpc play" das Abspielen starten, und mit "mpc stop" das Abspielen der Playlist stoppen.
Hallo, der mpc ist bei mir nicht drauf, den müßte ich installieren. Aber der Raspi bekommt aus Sicherheitsgründen keinen Netzanschluß. Ich könnte zwar ein Image der SD-Karte speichern und notfalls wieder zurückspielen, aber der Aufwand, das Ganze jetzt wieder völlig anders aufzuziehen ist recht hoch, wahrscheinlich höher als die Arbeit, die ich jetzt hineingesteckt habe. Und es funktioniert bei mir mit dem HiRes USB-DAC SABRE 24/96 jetzt mit sehr guter Audioqualität. Speicherplatz ist immer noch mehr als genug da, die Rechenleistung reicht auch. Playlisten wird es bei mir auch geben, einzelne, gerade laufende Stücke oder die ganze Playlist lassen sich dann auch abbrechen. Sollte Internetradio interessant werden (das muß aber schon ganz anders und besser als der normale Rundfunk auf UKW sein!), kommt dafür ein zweiter Raspi zum Einsatz - als eigenes Gerät, sozusagen ein Internetradiotuner oder etwas fertiges. Wichtig wäre nur eine Möglichkeit, auch daraus was aufnehmen zu können, was eher wieder auf einen Eigenbau hinausläuft. Gruß Andy
Andreas W. schrieb: > der mpc ist bei mir nicht drauf, den müßte ich installieren. Aber der > Raspi bekommt aus Sicherheitsgründen keinen Netzanschluß. Was für Hochsicherheits-Anwendungen hast Du denn mit dem Maschinchen vor? Ich meine, immerhin ist Linux für seine Sicherheit bekannt, und irgendwie willst Du doch vermutlich auch mal Updates einspielen... Außerdem kann man einen RasPi auch ganz einfach wieder vom Netz trennen, indem man wahlweise den RJ45-Stecker oder den Wifi-Dongle herauszieht, das Netzwerkinterface herunterfährt oder es gleich nur temporär manuell konfiguriert. :-) > Ich könnte zwar ein Image der SD-Karte speichern und notfalls wieder > zurückspielen, aber der Aufwand, das Ganze jetzt wieder völlig anders > aufzuziehen ist recht hoch, wahrscheinlich höher als die Arbeit, die ich > jetzt hineingesteckt habe. Und es funktioniert bei mir mit dem HiRes > USB-DAC SABRE 24/96 jetzt mit sehr guter Audioqualität. Du kannst die betreffenden Pakete und ihre Abhängigkeiten auch einfach auf einen USB-Stick herunterladen und von dort in Dein Zielsystem einspielen. Vermutlich wäre der Aufwand sehr überschaubar, zumal Du dann auf den ganzen Kram mit dem fork()en etc. verzichten kannst, und eine gute Audioqualität bekommst Du mit dem mpd genauso.
Andreas W. schrieb: > Letzteres wäre kein Problem, da die Abtastratenwandler beliebige > Abtastraten (innerhalb Min- und Maxwerten) umsetzen können. Nur, dass Dir dann Bild und Ton auseinander laufen ... Für Jitter-Geschichten ist der Samplerateconverter eigentlich genau die richtige Anwendung. Andreas W. schrieb: > aber praktisch jeder Audio-DAC hat ein > I2S-Interface. Nö. Gerade bei den USB-Wandlern nicht. Aber vielleicht hast Du Glück und er gibt SPDIF mit aus. Ausserdem können die meisten USB-ADCs nur 16 Bit. Was mich etwas wundert: Der RPi bringt seine eigene Linux-Distri mit, die eigentlich komplett für diese Hardware optimiert ist. Wird da wirklich kein Kernelmodul für die I²S-Schnittstelle mitgeliefert, welches man mittels modprobe einbinden kann und dann eine weitere Soundkarte hat? Gruß Jobst
Hallo, wegen des Samplerateconverters laufen Bild und Ton nicht auseinander. Der Verstärker verarbeitet nur Ton, kein Bild. Der Samplerateconverter von Analog Devices hat je einen Input für den Inputclock und den Outputclock, der Sound kommt dabei mit exakt der gleichen Geschwindigkeit raus, wie er reingeht. Der digitale SNR beträgt dabei ca. 120dB. Die Sache mit dem fork() ist relativ einfach, am meisten Arbeit hat die Funktion gemacht, die die PID für das aplay heraussucht. Jetzt funktioniert es, da habe ich keine Lust, das Problem noch einmal ganz von vorne anzugehen. Der Erfolg ist dann ja auch nicht garantiert. Der Sabre Audiodac hat auch einen optischen Ausgang, da kann ich sicher das SP/DIF-Signal vor dem optischen Sender abgreifen und dem SP/DIF-Decoder in meinem Verstärker geben, heraus kommt dann das I²Signal. Und notfalls kommt noch ein optischer Empfänger und ein optisches Kabel dazu, wenn es gar nicht anders geht. Gruß Andy
Andreas W. schrieb: > wegen des Samplerateconverters laufen Bild und Ton nicht auseinander. Nö. Aber wenn die Samplerate mit 44100 angegeben ist, jedoch leicht daneben liegt, dann schon. Im Übrigen ist 44100 eine ganz blöde Zahl zur Takterzeugung. Sie besteht aus den Quadraten aller Primzahlen <10. (2²*3²*5²*7²) Gruß Jobst
Hallo, wenn Ton und Bild synchron aus dem Player kommen und dann durch den Abtastratenwandler gehen, bleibt es absolut synchron. Der Abtastratenwandler wandelt beliebige Abtastfrequenzen um, solange die etwa im Bereich 15kKHz-200KHz liegen. Intern wird mein Verstärker mit 48KHz laufen. Wenn z.B. die interne Abtastrate 48002Hz und die ankommende Abtastrate 47999Hz beträgt, dann wird auch dieses passend gewandelt. Man hat lediglch ein konstantes Delay von ein paar Abtastwerten. Wäre es asynchron, müßte ein Puffer irgendwann volllaufen oder leer werden, das passiert aber nicht. Gruß Andy
Wie wäre es mit gstreamer? den kannst du in deinem Code per api benutzen ;)
Andreas W. schrieb: > wenn Ton und Bild synchron aus dem Player kommen und dann durch den > Abtastratenwandler gehen, bleibt es absolut synchron. Okay, Du hast nicht einmal Interesse daran, zu verstehen, welches Problem ich meine. Egal. Es wird Deins bleiben, nicht meins. Gruß Jobst
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.