Abfrage der Laufzeit entfernen und weiteres

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
__deets__
User
Beiträge: 7710
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sonntag 10. November 2019, 21:27

Das muss schon mit der bestehenden Logik verbaut werden. Und es kann sein, dass du den Pygame Event Loop treiben musst. Also gelegentlich mal aufrufen.
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Dienstag 26. November 2019, 18:04

Hallo,

bin jetzt etwas weiter mit dem Sound, allerdings funktioniert es noch nicht so richtig. Momentan sieht der Code folgendermaßen aus:

Code: Alles auswählen

import gpiozero
import time
import random
import pygame
from itertools import repeat, chain
pygame.init()
sound = pygame.mixer.Sound('/home/pi/Documents/test.wav')

def play_leds(leds):
    on_time = 0.1  # Leuchtdauer der LED
    delays = chain(repeat(on_time, 20 * len(leds) - 1), [5])
    for delay in delays:
        led = random.choice(leds)
        led.on()
        sound.play()
        time.sleep(delay)
        led.off()

def main():
    leds = gpiozero.LEDBoard(17, 18, 27, 22, 23, 24, 25, 4, 12)
    button = gpiozero.Button(16)
    while True:
        button.wait_for_press()
        play_leds(leds)

if __name__ == '__main__':
    main()
Ich vermute mal, dass das nicht optimal ist :?: Ich habe das Problem, dass der Sound, wenn er nicht genau so lang bzw. kurz ist wie das Aufblinken, völlig falsch abgespielt wird. d.h. wenn ich den Sound nicht auf 0.1 Sekunden kürze, funktioniert die Wiedergabe nicht richtig. Und am Ende soll ein ANDERER Sound entsprechend des delays, also hier 5 Sekunden lang abgespielt werden.
Sirius3
User
Beiträge: 11625
Registriert: Sonntag 21. Oktober 2012, 17:20

Dienstag 26. November 2019, 20:24

Wenn Du in 18 sekunde 180 mal einen Sound abspielen willst, dann rate mal, wie lange ein Ton sein kann ...
Was soll man sonst noch sagen? Du mußt das was Du willst programmieren. Das passiert nicht von alleine.
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Dienstag 26. November 2019, 20:51

Natürlich nur 0.1 Sekunden, wie oben geschrieben. Mich interessiert eher, ob denn der Code an sich so ok ist, oder ob der Einbau des sound.play() anders gelöst werden sollte.
Sirius3
User
Beiträge: 11625
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 27. November 2019, 11:29

Man könnte natürlich auch parallel dazu einen Sound abspielen, der halt so lang ist, wie die ganze Würfelei.
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Mittwoch 27. November 2019, 11:47

Ja, die Idee hatte ich auch. Da könnte ich wohl was basteln. Ich muss den Code sowieso noch anpassen, die Würfelei sollte höchstens 10 bis 15 Sekunden dauern. Also entsprechend weniger Durchläufe.
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Donnerstag 6. Februar 2020, 11:45

Moin Forum, kleines Update hierzu. Ich habe den Code erweitert, um insgesamt 5 verschiedene Sounds abzuspielen. Jetzt gibt es nur ein Problem. Obwohl die Sounds vorhanden sind, können sie nicht abgespielt werden. Hier mal der aktuelle Code:

Code: Alles auswählen

import gpiozero
import time
import random
import pygame.mixer
import glob
from itertools import repeat, chain

pygame.mixer.init()
soundfiles = glob.glob("/home/pi/Documents/*.mp3")

def play_leds(leds):
    pygame.mixer.Sound(random.choice(soundfiles)).play()
    on_time = 0.1  # Leuchtdauer der LED
    delays = chain(repeat(on_time, 11 * len(leds) - 1), [5])
    for delay in delays:
        led = random.choice(leds)
        led.on()
        time.sleep(delay)
        led.off()

def main():
    leds = gpiozero.LEDBoard(17, 18, 27, 22, 23, 24, 25, 4, 12)
    button = gpiozero.Button(16)
    while True:
        button.wait_for_press()
        play_leds(leds)

if __name__ == '__main__':
    main()

Sobald das Skript gestartet wurde, und ich den Taster drücke, erscheint folgende Fehlermeldung:

pygame.error: Unable to open file '/home/pi/Documents/versuch5.mp3'

Wobei die Nummer hinter "versuch" immer anders ist, also z.B. versuch3, versuch2 usw. Die "glob" scheint also zu funktionieren, aber warum kann die MP3 nicht geöffnet werden?
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Donnerstag 6. Februar 2020, 17:18

Update: Ich habe jetzt probeweise statt MP3 Dateien Wave Dateien verwendet (die selben MP3 in .wav) umgewandelt, und siehe da: Die Sounds werden tatsächlich OHNE Fehlermeldung abgespielt, auch zufällig. Aber warum klappt das mit MP3 nicht?
Benutzeravatar
__blackjack__
User
Beiträge: 5546
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Donnerstag 6. Februar 2020, 19:32

@Frank R.: Kann Pygame (unter Linux) überhaupt MP3? Ist ja ein nicht-freier Codec.
long long ago; /* in a galaxy far far away */
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Donnerstag 6. Februar 2020, 19:57

Habe eben mal nachgeschaut, pygame kann MP3 abspielen, aber der Code muss dann anders aussehen. Wenn man nur Sounds in Form von .ogg oder .wav Dateien abspielen möchte, sieht der Code so aus wie oben geschrieben. Wenn man aber MP3 Dateien abspielen will, muss es "pygame.mixer.music.play()" heißen, so habe ich das jedenfalls verstanden. Werde ich bei Gelegenheit mal testen.
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Mittwoch 12. Februar 2020, 21:11

Habe noch eine Frage: Ist es möglich, die Zufallswiedergabe der Sounds so zu coden, dass ein und derselbe Sound NICHT zweimal nacheinander abgespielt wird? Also z.B. test1.wav wird abgespielt, dann folgt zufällig test2.wav bis test5.wav, und erst nach diesem Durchlauf darf test1.wav wieder aufgerufen werden.
__deets__
User
Beiträge: 7710
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mittwoch 12. Februar 2020, 21:19

Klar ist das moeglich. Du musst eine Kopie der moeglichen Sounds machen, und bei jeder Auswahl (random.choice(copy_of_available_sounds)) den gewaehlten einfach entfernen. Sobald die Liste dann leer ist, erzeugst du wieder eine Kopie aller Moeglichkeiten.
__deets__
User
Beiträge: 7710
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mittwoch 12. Februar 2020, 21:33

So zB

Code: Alles auswählen

import time
import random

SONGS = ["a", "b", "c"]


def random_song_generator(songs):
    while True:
        selection = list(songs)
        random.shuffle(selection)
        yield from selection


def main():
    rsg = random_song_generator(SONGS)
    while True:
        for _ in SONGS:
            print(next(rsg))
        print("-" * 20)
        time.sleep(.2)


if __name__ == '__main__':
    main()
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Donnerstag 13. Februar 2020, 15:01

Ok, aber wie binde ich diese Funktion in meinen Code ein? So wie ich das verstanden habe muss die Zeile "rsg = random_song_generator(SONGS)" , zusätzlich in "def main():" rein. Nur wie binde ich den Abschnitt "def random_song_generator(songs):" ein? Und was ist mit den pygame.mixer Angaben? Was kann/muss davon weg bzw. geändert werden?
Sirius3
User
Beiträge: 11625
Registriert: Sonntag 21. Oktober 2012, 17:20

Donnerstag 13. Februar 2020, 15:08

`play_leds` braucht als zusätzliches Argument den Sound, der gespielt werden soll.
Und aus der while-True-Schleife machst Du einfach eine for-Schleife über die Sounds, die rsg liefert.
Antworten