Keine Musik von Audio CD auf RaspBerry Pi 4 mit PyGame

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
ManfredSch
User
Beiträge: 5
Registriert: Mittwoch 13. Mai 2020, 17:24

Mittwoch 13. Mai 2020, 18:58

Ich möchte für meine Frau zwei nutzerfreundliche Anwendungen entwickeln. Das Ganze läuft auf einem RaspBerry Pi4 mit 7“ Touchscreen, HiFiBerry AMP2, Schaltnetzteil, Retro-Holzgehäuse, etc.:
1. Internetradio
2. CD-Spieler
Das Internetradio habe ich mit VLC realisiert. Läuft wunderbar, mit einer spartanischen Oberfläche.
Zuerst wollte ich den CD-Player auch mit VLC realisieren, bin aber an den fehlenden, bzw. nicht gefundenen, Statusmeldungen gescheitert. Ich fand auch keinen Weg die Infos über die CD auszulesen und habe mir die mit dem UNIX-Befehl cdparanoia -Q selbst erstellt. Ich fand keinen Weg sowohl die ganze CD abzuspielen – als auch beliebige Titel auszuwählen. Ich konnte nur entweder das eine oder das andere realisieren. Also frustriert aufgegeben und einen anderen Player gesucht.
Deswegen wollte ich nun mit PyGame meine Audio-CD-Sammlung auf dem Raspberry Pi4 mit Python3 abzuspielen.
Ich fand hier im Forum eine Lösung von ‚‘ Bueroklammer_xy‘ vom 28 Juli 2018 (CD auslesen und abspielen) die unter Windows einwandfrei funktioniert, allerdings nicht auf meinem RaspBerry Pi. Die CD wird gesteuert, jedoch kommt keine Musik vom Lautsprecher. Zur Verdeutlichung ein einfaches Beispiel.
Funktioniert unter Windows 10 über die Python-Befehlszeile und in PyCharm:

from pygame import cdrom
import pygame
import time
pygame.init()
cdrom.init()
cdrom.CD(0).init()
i = 0
while i == 0:
cdrom.CD(0).play(5)
time.sleep(10)
i = 1
cdrom.CD(0).stop()

Auf meinem RaspBerry Pi 4 läuft das Programm ohne Fehler, gibt jedoch keinen Ton aus.

pi@raspberrypi:~ $ python3
Python 3.7.3 (default, Dec 20 2019, 18:57:59)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> #!/usr/bin/python3
... import pygame
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
>>> from pygame import *
>>> from pygame import cdrom
>>> import time
>>>
>>> pygame.init()
(6, 0)
>>> cdrom.init()
>>> cdrom.CD(0).init()
>>>
>>> i = 0
>>> while i == 0:
... print('cdrom bussy, but I hear no music')
... cdrom.CD(0).play(5)
... time.sleep(20)
... i = 1
... cdrom.CD(0).stop()
... print("no idea what's went wrong :-(")

Das CD-Laufwerk beginnt zu arbeiten, aber es kommt kein Ton.
Ich gebe den Ton über die analogen Buchse aus.
Spiele ich dieselbe CD mit VLC ab, wird der Ton ausgegeben.

Folgende Tests zeigen keine Fehler:

pi@raspberrypi:~ $ speaker-test -t wav -c 2
speaker-test 1.1.8
Playback device is default
Stream parameters are 48000 Hz, S16_LE, 2 channels
WAV file (s)
Rate is 48000 Hz (requested: 48000 Hz)
Buffer size from 480 to 32768
Period size from 480 to 32768
Use maximum buffer size 32768
Periods = 4
set: period_size = 8192
set: buffer_size = 32768
0 - Front left
1 - Front right

pi@raspberrypi:~ $ omxplayer /home/pi/test.wav
Audio codec pcm_u8 channels 1 samplerate 11025 bitspersample 8
Subtitle count: 0, state: off, index: 1, delay: 0
have a nice day ;)

pi@raspberrypi:~ $ omxplayer /home/pi/song1.mp3
Audio codec mp3float channels 2 samplerate 44100 bitspersample 16
Subtitle count: 0, state: off, index: 1, delay: 0
have a nice day ;)

Der Raspberry hat offensichtlich keine Probleme mit wav/mp3 der VLC hat keine mit PCM von der CD.
Spiele ich die CD mit VLC ab und öffne parallel ```alsamixer```, kann ich die Lautstärke steuern.
Meine Vermutungen/Befürchtungen:
1. Das Problem liegt zwischen meinen Ohren.
2. Ich muss für PyGame irgend etwas am RaspBerry Pi einstellen.
3. PyGame kann keine Musik über ALSA wiedergeben. Ich meine nicht Sound oder MIDI.
4. PyCharm kann keine CD-Musik-Daten verarbeiten.

Ich bin mit meinem Latein am Ende und hoffe auf Hilfe aus dem Forum..
Benutzeravatar
__blackjack__
User
Beiträge: 6012
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Donnerstag 14. Mai 2020, 14:34

@ManfredSch: Wenn Du mit PyGame dem CD-Laufwerk sagst es soll einen Titel spielen, dann spielt das CD-Laufwerk den ab. CD-Laufwerke haben dafür in der Regel einen Audio-Out-Anschluss den man in Desktop-PCs üblicherweise mit der Soundkarte verbindet, damit das dann durch die Soundkarte und deren Mixer läuft und man beispielsweise einen Lautstärkeregler hat. Kein Ahnung wie das so bei externen USB-Laufwerken aussieht.
long long ago; /* in a galaxy far far away */
ManfredSch
User
Beiträge: 5
Registriert: Mittwoch 13. Mai 2020, 17:24

Donnerstag 14. Mai 2020, 17:31

Ich habe ein externes USB-LW angeschlossen OHNE Audio-Ausgang. Die modernen Geräte bieten das i. d. R. nicht mehr an. Ich habe den analogen Audio-Ausgang des Raspi an meine BOSE SoundTouch 10 angeschlossen. Der VLC-Player spielt die Audio-CD ohne Murren ab und gibt gewählte Song-Tracks am Lautsprecher aus. Das o. g. Mini-Programm steuert die Audio-CD zwar an, ich vernehme auch den Track-Wechsel. Nur gibt der Lautsprecher leider keinen Pips von sich. Das Problem scheint also nicht in der Ansteuerung des CDROM-LW zu liegen, vielmehr in der Soundverarbeitung von PyGame (vermute ich).

Wie ich das korrekt programmieren muss ist mit nicht klar.
__deets__
User
Beiträge: 8106
Registriert: Mittwoch 14. Oktober 2015, 14:29

Donnerstag 14. Mai 2020, 18:57

Wie taucht denn der angeschlossene CD-Spieler im Geraetemanager auf? Wenn das zB ein eigenes Audio-Device ist, dann musst du das oeffnen, und in einen Audio-Ausgang "schaufeln".
ManfredSch
User
Beiträge: 5
Registriert: Mittwoch 13. Mai 2020, 17:24

Freitag 15. Mai 2020, 15:15

Auf dem Raspi taucht mein CD-Laufwerk auf dem Desktop als 'Audio CD' auf. Es ist nicht über mount eingebunden, hat ja auch kein Filesystem drauf. Wenn ich mir über lsusb die Liste anschaue erscheint es wie folgt:
pi@raspberrypi:~ $ lsusb
...
Bus 001 Device 004: ID 04a5:1005 Acer Peripherals Inc. (now BenQ Corp.)
...
Wie schaufelt man denn Audio-Tracks dorthin? Ich dachte das macht der Raspi automatisch über den analogen Audio-Ausgang.
__deets__
User
Beiträge: 8106
Registriert: Mittwoch 14. Oktober 2015, 14:29

Freitag 15. Mai 2020, 15:26

Na offensichtlich macht er das ja nicht automatisch. Und es war erstmal auch nur eine Hypothese - dass die Audio-Daten als Audio-Input-Device ankommen, und du sie an ein geoeffnetes output-Device weiterschaufeln musst. Was Buffer-Weise geschieht.

Wenn das so nicht der Fall ist (und es sieht nicht danach aus), dann kann es sein, dass einem die play-Funktion von pygame einfach nichts bringt. Und man stattdessen die Daten von der Audio-CD lesen muss, und selbst abspielen. Oder wen anderes wie cdda2wav das machen lassen. Der Code von VLC legt das nahe: https://github.com/videolan/vlc/blob/7f ... ess/cdda.c

Da sieht man, dass der wirklich selbst auf die Daten zugreift. Also nix mit "play".
ManfredSch
User
Beiträge: 5
Registriert: Mittwoch 13. Mai 2020, 17:24

Freitag 15. Mai 2020, 15:48

@_deets_
Wenn ich mit VLC arbeite, dann sieht das z. B. so aus:
'/dev/cdrom', 'cdda:///dev/sr0/', ':cdda-track=5'
Wenn ich das dem VLC übergebe, wird Lied-Nr. 5 gespielt.
Ich übergebe Device(+ Raw-device), 'Filesystem' und Lied-Nr..

Bei PyGame habe ich in der Doku (https://www.pygame.org/docs/ref/cdrom.html) nicht entsprechendes gesehen. Dort steht z. B.
pygame.cdrom.CD.play
start playing audio

Klingt zu schön um wahr zu sein?

Also habe entweder ich einen Fehler gemacht oder PyGame arbeitet nicht wie erwartet.
__deets__
User
Beiträge: 8106
Registriert: Mittwoch 14. Oktober 2015, 14:29

Freitag 15. Mai 2020, 16:09

Ich habe schon verstanden, was du da machst. Du hast nicht verstanden, was __blackjack__ ausgefuehrt hat: diese Funktionalitaet ruehrt aus einer Zeit, in der das CD-ROM einen Audioausgang hatte, der direkt mit der Soundkarte verbunden wurde. Beschrieben zB hier: https://www.deinmeister.de/e_digikab.htm

Und dieses API bedient pygame.

Das geht heute halt nicht mehr. Oder vielleicht geht es sogar noch (ich habe kein CD-Rom an meinem PC, und auch sonst keine mehr im Haushalt), aber eben nich beim PI, und nicht bei USB-CD-ROMs.

Stattdessen muss Software die Audio-Daten der CD direkt abgreifen. Der Begriff heisst CDDA, und kommt ja sogar in der von dir selbst genannten Anweisung an VLC vor.

pygame macht das aber halt nicht. Stattdessen musst du ein anderen Ansatz fahren. Zb cdda2wav, so dass du ein geripptes WAV dann mit pygame sound.play abspielst. Oder du steuerst von Pytho aus VLC fern, mit https://pypi.org/project/python-vlc/
ManfredSch
User
Beiträge: 5
Registriert: Mittwoch 13. Mai 2020, 17:24

Freitag 15. Mai 2020, 16:54

Danke für Eure Hinweise.
Jetzt hab ich es auch verstanden. Eigentlich will ich es aber nicht wahrhaben. :-)

PyGame konnte das CD-Laufwerk schon immer steuern, jedoch keine Audio-Daten lesen. Da muss man erst mal draufkommen.
Also muss ich mich wieder mit VLC rumquälen.

Ich habe mit VLC bereits ein einfaches Internetradio programmiert; mit kindersicherer Oberfläche.
Danach ein Programm mit VLC, dass die gesamte CD abspielt.
Ich bin aber noch nicht in der Lage diesen Vorgang zu unterbrechen - warum?

1. Ich hole mir mit 'cdparanoia -Q' die Anzahl der Tracks und deren Spieldauer.
2. Dann spiele ich die Tracks ab und starte mit 'time.sleep(Spieldauer) eine Wartezeit und starte danach das nächste Lied.
3. Ich habe keine Idee, wie ich diese Schleife unterbrechen kann, um z. B. Next, Previous oder einen beliebigen Track auszuwählen.
Ist ja klar, wenn er schläft, schläft er eben, basta.
4. Ich muss mir also wohl oder übel überlegen, wie ich das asynchron oder eventgesteuert abbilde.
5. Oder gibt es eine Möglichkeit den time.sleep() zu killen, wahrscheinlich nicht.

Also sinngemäß noEvent -> spiele ein Lied nach dem anderen, bis der Strom ausgeht.
Wenn dochEvent -> tu was der Nutzer klickt.

Es gibt noch viel zu tun, lassen wir es sein.

Schönes Wochenende.
__deets__
User
Beiträge: 8106
Registriert: Mittwoch 14. Oktober 2015, 14:29

Freitag 15. Mai 2020, 17:11

Eine Moeglichkeit ist dein sleep ueber eine queue.Queue laufen zu lassen. Da kannst du mit get(timeout) arbeiten, und entweder kommt vorher ein anderes Ereignis (vom Benutzer, per GPIO "interrupt"), oder das ding wartet entsprechend lange.
Antworten