DirectSound examples

Example

Our raison d'etre - playing sounds:

WAV_HEADER_SIZE = struct.calcsize('<4sl4s4slhhllhh4sl')



def wav_header_unpack(data):

    '''Unpack a wav header and stuff it into a WAVEFORMATEX structure'''

    (riff, riffsize, wave, fmt, fmtsize, format, nchannels, samplespersecond,

     datarate, blockalign, bitspersample, data, datalength) \\

 struct.unpack('<4sl4s4slhhllhh4sl', data)



    if riff != 'RIFF' or fmtsize != 16 or fmt != 'fmt ' or data != 'data':

	raise ValueError, 'illegal wav header'



    wfx = pywintypes.WAVEFORMATEX()

    wfx.wFormatTag = format

    wfx.nChannels = nchannels

    wfx.nSamplesPerSec = samplespersecond

    wfx.nAvgBytesPerSec = datarate

    wfx.nBlockAlign = blockalign

    wfx.wBitsPerSample = bitspersample



    return wfx, datalength



# Play a wav file and wait until it's finished

fname = os.path.join(os.path.dirname(__file__), "01-Intro.wav")

f = open(fname, 'rb')



# Read and unpack the wav header

hdr = f.read(WAV_HEADER_SIZE)

wfx, size = wav_header_unpack(hdr)



d = ds.DirectSoundCreate(None, None)

d.SetCooperativeLevel(None, ds.DSSCL_PRIORITY)



sdesc = ds.DSBUFFERDESC()

sdesc.dwFlags = ds.DSBCAPS_STICKYFOCUS | ds.DSBCAPS_CTRLPOSITIONNOTIFY

sdesc.dwBufferBytes = size

sdesc.lpwfxFormat = wfx



buffer = d.CreateSoundBuffer(sdesc, None)



event = win32event.CreateEvent(None, 0, 0, None)



  notify = buffer.QueryInterface(ds.IID_IDirectSoundNotify)

notify.SetNotificationPositions((ds.DSBPN_OFFSETSTOP, event))



buffer.Update(0, f.read(size))

buffer.Play(0)

win32event.WaitForSingleObject(event, -1)

This example shows how to record into a wav file:

import pywintypes

import struct

import win32event

import win32com.directsound.directsound as ds



def wav_header_pack(wfx, datasize):

    return struct.pack('<4sl4s4slhhllhh4sl', 'RIFF', 36 + datasize,

		       'WAVE', 'fmt ', 16,

		       wfx.wFormatTag, wfx.nChannels, wfx.nSamplesPerSec,

		       wfx.nAvgBytesPerSec, wfx.nBlockAlign,

		       wfx.wBitsPerSample, 'data', datasize);



d = ds.DirectSoundCaptureCreate(None, None)



sdesc = ds.DSCBUFFERDESC()

sdesc.dwBufferBytes = 352800 # 2 seconds

sdesc.lpwfxFormat = pywintypes.WAVEFORMATEX()

sdesc.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM

sdesc.lpwfxFormat.nChannels = 2

sdesc.lpwfxFormat.nSamplesPerSec = 44100

sdesc.lpwfxFormat.nAvgBytesPerSec = 176400

sdesc.lpwfxFormat.nBlockAlign = 4

sdesc.lpwfxFormat.wBitsPerSample = 16



buffer = d.CreateCaptureBuffer(sdesc)



event = win32event.CreateEvent(None, 0, 0, None)

notify = buffer.QueryInterface(ds.IID_IDirectSoundNotify)



notify.SetNotificationPositions((ds.DSBPN_OFFSETSTOP, event))



buffer.Start(0)



win32event.WaitForSingleObject(event, -1)



# in real life, more, smaller buffers should be retrieved

data = buffer.Update(0, 352800)



f = open('recording.wav', 'wb')

f.write(wav_header_pack(sdesc.lpwfxFormat, 352800))

f.write(data)