winsound string abspielen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
INFACT
User
Beiträge: 385
Registriert: Freitag 5. Dezember 2008, 16:08

Hi
The sound parameter may be a filename, audio data as a string
Ich möchte einen sound string abspielen, aber ich weiß nicht so genau wie.
Ich hab das hier versucht:

Code: Alles auswählen

>>> winsound.PlaySound(u"\x12\x42", winsound.SND_NODEFAULT)
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    winsound.PlaySound(u"\x12\x42", winsound.SND_NODEFAULT)
RuntimeError: Failed to play sound
>>> f = open("Windows Error.wav")
>>> data = f.read()
>>> len(data)
225
>>> winsound.PlaySound(data, winsound.SND_NODEFAULT)
Traceback (most recent call last):
  File "<pyshell#34>", line 1, in <module>
    winsound.PlaySound(data, winsound.SND_NODEFAULT)
RuntimeError: Failed to play sound
Hat jemand ne idee was ich da einsetzen muss?

Danke
[b][i]ein kleines game für die die lust haben http://konaminut.mybrute.com[/i][/b]
;-)
Benutzeravatar
Kiffi
User
Beiträge: 6
Registriert: Samstag 13. November 2010, 11:32

Hallo INFACT,

Deinen 'String' kann ich auch nicht abspielen,
aber folgendes funktioniert bei mir einwandfrei:

Code: Alles auswählen

>>> import winsound
>>> winsound.PlaySound(r"C:\Windows\Media\chord.wav", winsound.SND_NODEFAULT)
>>> winsound.PlaySound("SystemExit", winsound.SND_NODEFAULT)
(Python 2.6.6 / Windows 7 prof.)

Grüße ... Kiffi

Nachtrag: Das hier funktioniert auch:

Code: Alles auswählen

>>> winsound.PlaySound(data, winsound.SND_MEMORY)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Und wie sollte man es auch in der Dokumentation finden, da es ganz versteckt ist ;-)
http://docs.python.org/library/winsound.html#winsound.PlaySound hat geschrieben:The sound parameter may be a filename, audio data as a string, or None. Its interpretation depends on the value of flags, which can be a bitwise ORed combination of the constants described below
http://docs.python.org/library/winsound.html#winsound.SND_MEMORY hat geschrieben:winsound.SND_MEMORY¶

The sound parameter to PlaySound() is a memory image of a WAV file, as a string.
Das Leben ist wie ein Tennisball.
INFACT
User
Beiträge: 385
Registriert: Freitag 5. Dezember 2008, 16:08

Hmm, ok ich hab memory falsch interpretiert als ich das gelesen habe... :oops:

Ich hab jetzt versucht mir das zu vereinfachen, mit der anleitung hier: https://ccrma.stanford.edu/courses/422/ ... aveFormat/

hier ist mein code der aber nicht funktioniert:

Code: Alles auswählen

class Wav:
    def __init__(self, **kwargs):

        self.samples = 4
        self.data = "abcd"
        self.channels = 1
        self.bitspersample = 8
        self.byterate = 8000
        
        self.headers = [
            ("Chunk ID", Bytes(4, "RIFF", "big")),
            ("Chunk Data Size", Bytes(4, "", "little")), # filesize-8
            ("RIFF Type", Bytes(4, "WAVE", "big")),
            ("Subchunk1ID", Bytes(4, "fmt ", "big")),
            ("Subchunk1Size", Bytes(4, "\x16", "little")),
            ("AudioFormat", Bytes(2, "\x01", "little")),
            ("NumChannels", Bytes(2, "\x01", "little")), # 1= mono, 2=stereo...
            ("SampleRate", Bytes(4, numToAscii(self.byterate), "little")),
            ("ByteRate", Bytes(4, numToAscii(int(self.byterate*self.channels*self.bitspersample/8.0)), "little")), # == SampleRate * NumChannels * BitsPerSample/8
            ("BlockAlign", Bytes(4, numToAscii(int(1*self.bitspersample/8)), "little")), #== NumChannels * BitsPerSample/8
            ("BitsPerSample", Bytes(2, numToAscii(self.bitspersample), "little")),
            ("Subchunk2ID", Bytes(4, "data", "big")),
            ("Subchunk2Size", Bytes(4, numToAscii(self.samples * self.channels * self.bitspersample), "little")),
            ("Data", Bytes(self.samples, self.data, "little"))
             ]
        
    def __str__(self):
        ret = ""
        for key, value in self.headers:
            ret += str(value)
        return ret



>>> f = Wav()
>>> str(f)
'RIFF\x00\x00\x00\x00WAVEfmt \x16\x00\x00\x00\x01\x00\x01\x00\xf4\x1f\x00\x00\xf4\x1f\x00\x00\x10\x00\x00\x00\x80\x00data \x00\x00\x00dcba'
>>> winsound.PlaySound('RIFF\x00\x00\x00\x00WAVEfmt \x16\x00\x00\x00\x01\x00\x01\x00\xf4\x1f\x00\x00\xf4\x1f\x00\x00\x10\x00\x00\x00\x80\x00data \x00\x00\x00dcba', winsound.SND_MEMORY|winsound.SND_NODEFAULT)
Traceback (most recent call last):
  File "<pyshell#153>", line 1, in <module>
    winsound.PlaySound('RIFF\x00\x00\x00\x00WAVEfmt \x16\x00\x00\x00\x01\x00\x01\x00\xf4\x1f\x00\x00\xf4\x1f\x00\x00\x10\x00\x00\x00\x80\x00data \x00\x00\x00dcba', winsound.SND_MEMORY|winsound.SND_NODEFAULT)
RuntimeError: Failed to play sound
Warum funktioniert das denn nicht?
Das sollte jetzt eine wav datei im memory bauen und die dann abspielen.

Edit:

Code: Alles auswählen

class Bytes:
    def __init__(self, num=4, data="", endian="little"):
        self.num = num
        self.endian = endian
        self.data = self.setData(data)

    def __str__(self):
        return self.data
    def __repr__(self):
        return self.data

    def setData(self, data):
        if len(data) > self.num:
            raise ValueError, "data to long"
        zeroBytes = "\x00"*(self.num-len(data))
        data = zeroBytes + data
        if self.endian == "little":
            data = data[::-1]
        return data

def numToAscii(num):
    Hex = hex(num)[2:]
    al = ""
    if len(Hex) %2:
        Hex += "0" + Hex
    for i in xrange(len(Hex)/2):
        exec "al += '\\x%s'" %(Hex[i:i+2])
    return al
hab ich einfach nur so hingeklatscht.
Zuletzt geändert von INFACT am Mittwoch 17. November 2010, 19:27, insgesamt 1-mal geändert.
[b][i]ein kleines game für die die lust haben http://konaminut.mybrute.com[/i][/b]
;-)
BlackJack

@INFACT: Wenn man Deine Zeichenkette aus dem Beispiel abspeichert, dann gibt ``file`` folgendes aus:

Code: Alles auswählen

$ file test.wav
test.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, mono 8180 Hz
Die Samplerate ist also schonmal nicht 8000. ``play`` sagt folgendes:

Code: Alles auswählen

$ play test.wav
play FAIL formats: can't open input file `test.wav': Sorry, don't understand .wav size
``kfile`` kann gar keine Metadaten auslesen:

Code: Alles auswählen

$ kfile -la test.wav
test.wav: WAV Audio (audio/x-wav)
test.wav: Cannot determine metadata
Die Gesamtgrösse ist nicht hinterlegt. Die Grösse von ersten "subchunk" hast Du mit 0x16 angegeben, wo es eigentlich nur dezimale 16 sein sollten. Die Samplerate ist falsch, bei Bits-Per-Sample steht 0 (Null) in der Datei, usw.
INFACT
User
Beiträge: 385
Registriert: Freitag 5. Dezember 2008, 16:08

fehler 1:

Code: Alles auswählen

def numToAscii(num):
    Hex = hex(num)[2:]
    al = ""
    if len(Hex) %2:
        
        Hex = "0" + Hex
    print Hex
    for i in xrange(0,len(Hex),2):
        h = Hex[i:i+2]
        print "al += '\\x%s'" %(h)
        exec "al += '\\x%s'" %(h)
    return al

def asciiToNum(ascii):
    ret = 0
    for i in xrange(len(ascii)):
        p = len(ascii) -i-1
        print p
        ret += 256**p * ord(ascii[i])
    return ret
fehler 2:

Code: Alles auswählen

        
        self.headers = [
            ("Chunk ID", Bytes(4, "RIFF", "big")),
            ("Chunk Data Size", Bytes(4, numToAscii(36+(self.samples * self.channels * self.bitspersample)), "little")), # filesize-8
            ("RIFF Type", Bytes(4, "WAVE", "big")),
            ("Subchunk1ID", Bytes(4, "fmt ", "big")),
            ("Subchunk1Size", Bytes(4, numToAscii(16), "little")),
            ("AudioFormat", Bytes(2, "\x01", "little")),
            ("NumChannels", Bytes(2, "\x01", "little")), # 1= mono, 2=stereo...
            ("SampleRate", Bytes(4, numToAscii(self.byterate), "little")),
            ("ByteRate", Bytes(4, numToAscii(int(self.byterate*self.channels*self.bitspersample/8.0)), "little")), # == SampleRate * NumChannels * BitsPerSample/8
            ("BlockAlign", Bytes(2, numToAscii(int(1*self.bitspersample/8)), "little")), #== NumChannels * BitsPerSample/8
            ("BitsPerSample", Bytes(2, numToAscii(self.bitspersample), "little")),
            ("Subchunk2ID", Bytes(4, "data", "big")),
            ("Subchunk2Size", Bytes(4, numToAscii(self.samples * self.channels * self.bitspersample), "little")),
            ("Data", Bytes(self.samples, self.data, "little"))
             ]
Jetzt scheint wmp das schon mal abzuspielen, aber nur für GANZ kurz.
Liegt das daran das das immernoch falsch ist oder das das einfach nur so kurz ist?
Ich höre nämlich nichts... :)


Erfolg: Mit winsound höre ich ein kurzes knacken: :)))
[b][i]ein kleines game für die die lust haben http://konaminut.mybrute.com[/i][/b]
;-)
BlackJack

@INFACT: Die Funktionen sehen ja schrecklich aus. ``exec``!? Argh. Bitte denk da nochmal drüber nach was da gemacht werden soll und drücke das in Rechenoperationen und `chr()`/`ord()` aus, statt mit Zeichenkettenrepräsentationen zu verschiedenen Basen und ``exec`` rumzuwurschteln. Ansonsten kann man dafür auch prima das `struct`-Modul verwenden.

Du hast da vier Amplitudenwerte bei einer Abspielfrequenz von 8 kHz -- das ist also eine halbe Millisekunde lang. Und die Werte sind ja auch nicht gerade dazu geeignet den Lautsprecher in Schwingungen zu versetzen.
Antworten