Pygame- ist es möglich, die Abtastrate während der Laufzeit zu ändern?

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
ReinhardT
User
Beiträge: 8
Registriert: Dienstag 29. Dezember 2020, 14:12

Hallo,

ist es irgendwie möglich, die Abtastrate eines Soundfiles während der Laufzeit zu ändern?
Ich meine, wenn es fertig abgespielt ist, vor dem nächsten Aufruf.
Ich hab ein sehr kurzes Soundfile, wie zB. das Geräusch einer Dampflok und das soll
immer wieder abgespielt werden, allerdings mit variabler Geschwindigkeit in
Abhängigkeit zur Drehzahl.
Hätte gedacht, das es mit pygame.mixer.pre_init funktioniert, macht es aber nicht.

Gruß Reinhard
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst das sample resamplen https://stackoverflow.com/questions/290 ... umpy-array und dann in sound Objekte wandeln.
ReinhardT
User
Beiträge: 8
Registriert: Dienstag 29. Dezember 2020, 14:12

Danke für die schnelle Antwort!
Sieht kompliziert aus, muß ich mich erst mal einlesen. Einfach
zwischendurch die Abtastrate ändern geht also wirklich nicht?
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nein.

Wenn dir das zu kompliziert ist, kannst du auch mit audacity verschiedene samples Vorbereiten.
ReinhardT
User
Beiträge: 8
Registriert: Dienstag 29. Dezember 2020, 14:12

Wenn dir das zu kompliziert ist, kannst du auch mit audacity verschiedene samples Vorbereiten.
Wird das Beste sein.

Vielen Dank! :)
ReinhardT
User
Beiträge: 8
Registriert: Dienstag 29. Dezember 2020, 14:12

Hallo,

mit pyaudio scheint es zu funktionieren. Zumindest habe ich es erst mal hinbekommen,
die gleiche Datei mit zwei Geschwindigkeiten abzuspielen.

Code: Alles auswählen

import pyaudio
import wave
import time
import sys

CHUNK = 1024

wf = wave.open("kn.wav", 'rb')
p = pyaudio.PyAudio()

def callback(in_data, frame_count, time_info, status):
    data = wf.readframes(frame_count)  # <== (2)
    return (data, pyaudio.paContinue)

stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                channels=2,
                rate=44000,
                output=True,
                stream_callback=callback)
stream.start_stream()

while stream.is_active():  # <== (1)
    continue
stream.stop_stream()
stream.close()
wf.close()
p.terminate()

wf = wave.open("kn.wav", 'rb')
p = pyaudio.PyAudio()

stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                channels=wf.getnchannels(),
                rate=22000,
                output=True,
                stream_callback=callback)
stream.start_stream()
while stream.is_active():  # <== (1)
    continue

stream.stop_stream()
stream.close()
wf.close()
p.terminate()
Das Programm ist hab ich gefunden und etwas abgeändert.
Was hat es mit der Callback Funktion auf sich? Hab auch Varianten gesehen, wo die nicht verwendet wurde, die habe ich
allerdings nicht zum Laufen bekommen.
Kann das Programm noch "eingedampft" werden, was wäre die absolute Minimalvariante um die Datei
mit zwei Geschwindigkeiten abzuspielen?

Vielen Dank!

Gruß Reinhard
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

In dem callback müssen die nächsten samples geliefert werden.

Es ist wirklich von hinten durch die Brust ins Auge, was du da treibst. Die Audio Systeme sind nicht so gedacht. Wenn es eh nur um zwei samples geht, erzeug die dir einfach.
ReinhardT
User
Beiträge: 8
Registriert: Dienstag 29. Dezember 2020, 14:12

Code: Alles auswählen

Es ist wirklich von hinten durch die Brust ins Auge, was du da treibst. Die Audio Systeme sind nicht so gedacht. Wenn es eh nur um zwei samples geht, erzeug die dir einfach.
Ich verstehe dein Argument, es geht aber darum, das die Abspielgeschwindigkeit kontinuierlich veränderbar sein muß.
Das scheint ja mit pyaudio erst mal zu funktionieren. Ist für ein Animatronicprojekt, meine Stärken liegen offensichtlich
nicht gerade bei der Programmierung mit Python. Der Rest ist fast fertig, das mit der Audiowiedergabe hängt aber mit dran.

Über einen GPIO Pin empfange ich ein Startsignal und beim nächsten Signal wird die Zeitdifferenz bestimmt.
Danach richtet sich die Abspielgeschwindigkeit. Je schneller die Signale kommen, umso schneller soll das
Soundfile halt abgespielt werden. Wie ich schon geschrieben hatte, wie zB. eine anfahrende Lokomotive.
Die Taktfrequenz liegt im Bereich von 0.5- 2 Hz.

Hättest du eine bessere Idee?
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Resampling ist immer noch die Lösung. Denn nur damit erreichst du dein Ziel auch wirklich. Die Sample Rates zur Wiedergabe sind auch nicht beliebig einstellbarer.

Wobei mir auch noch nicht klar ist, ob du diese Frequenzänderung überhaupt brauchst. Ein und denselben Ton in kürzeren Intervallen abzuspielen ist davon ja losgelöst, welche Frequenz der hat.
ReinhardT
User
Beiträge: 8
Registriert: Dienstag 29. Dezember 2020, 14:12

Code: Alles auswählen

Wobei mir auch noch nicht klar ist, ob du diese Frequenzänderung überhaupt brauchst. Ein und denselben Ton in kürzeren Intervallen abzuspielen ist davon ja losgelöst, welche Frequenz der hat.
Das Zeitintervall soll ja möglichst komplett ausgefüllt werden, also kein kein kurzer Signalton in unterschiedlichen Abständen.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der kann ja auch länger sein, und ausgefadet werden wenn der nächste kommt. Wenn du die Veränderung der Samplerate nur machst, um unterschiedliche Länge zu bekommen, ist es nicht die richtige Wahl.
Antworten