Seite 1 von 1

winsound string abspielen

Verfasst: Dienstag 16. November 2010, 20:40
von INFACT
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

Re: winsound string abspielen

Verfasst: Dienstag 16. November 2010, 20:59
von Kiffi
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)

Re: winsound string abspielen

Verfasst: Dienstag 16. November 2010, 22:08
von EyDu
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.

Re: winsound string abspielen

Verfasst: Mittwoch 17. November 2010, 17:36
von INFACT
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.

Re: winsound string abspielen

Verfasst: Mittwoch 17. November 2010, 18:42
von 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.

Re: winsound string abspielen

Verfasst: Mittwoch 17. November 2010, 19:51
von INFACT
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: :)))

Re: winsound string abspielen

Verfasst: Mittwoch 17. November 2010, 20:30
von 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.