AIM-PIbd-32-Kurbanova-A-A/aimenv/Lib/site-packages/win32comext/directsound/test/ds_test.py
2024-10-02 22:15:59 +04:00

403 lines
13 KiB
Python

import os
import struct
import sys
import unittest
import pythoncom
import pywintypes
import win32api
import win32com.directsound.directsound as ds
import win32event
from pywin32_testutil import TestSkipped, find_test_fixture
# next two lines are for for debugging:
# import win32com
# import directsound as ds
WAV_FORMAT_PCM = 1
WAV_HEADER_SIZE = struct.calcsize("<4sl4s4slhhllhh4sl")
def wav_header_unpack(data):
(
riff,
riffsize,
wave,
fmt,
fmtsize,
format,
nchannels,
samplespersecond,
datarate,
blockalign,
bitspersample,
data,
datalength,
) = struct.unpack("<4sl4s4slhhllhh4sl", data)
if riff != b"RIFF":
raise ValueError("invalid wav header")
if fmtsize != 16 or fmt != b"fmt " or data != b"data":
# fmt chuck is not first chunk, directly followed by data chuck
# It is nowhere required that they are, it is just very common
raise ValueError("cannot understand 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
def wav_header_pack(wfx, datasize):
return struct.pack(
"<4sl4s4slhhllhh4sl",
b"RIFF",
36 + datasize,
b"WAVE",
b"fmt ",
16,
wfx.wFormatTag,
wfx.nChannels,
wfx.nSamplesPerSec,
wfx.nAvgBytesPerSec,
wfx.nBlockAlign,
wfx.wBitsPerSample,
b"data",
datasize,
)
class WAVEFORMATTest(unittest.TestCase):
def test_1_Type(self):
"WAVEFORMATEX type"
w = pywintypes.WAVEFORMATEX()
self.assertTrue(type(w) == pywintypes.WAVEFORMATEXType)
def test_2_Attr(self):
"WAVEFORMATEX attribute access"
# A wav header for a soundfile from a CD should look like this...
w = pywintypes.WAVEFORMATEX()
w.wFormatTag = pywintypes.WAVE_FORMAT_PCM
w.nChannels = 2
w.nSamplesPerSec = 44100
w.nAvgBytesPerSec = 176400
w.nBlockAlign = 4
w.wBitsPerSample = 16
self.assertTrue(w.wFormatTag == 1)
self.assertTrue(w.nChannels == 2)
self.assertTrue(w.nSamplesPerSec == 44100)
self.assertTrue(w.nAvgBytesPerSec == 176400)
self.assertTrue(w.nBlockAlign == 4)
self.assertTrue(w.wBitsPerSample == 16)
class DSCAPSTest(unittest.TestCase):
def test_1_Type(self):
"DSCAPS type"
c = ds.DSCAPS()
self.assertTrue(type(c) == ds.DSCAPSType)
def test_2_Attr(self):
"DSCAPS attribute access"
c = ds.DSCAPS()
c.dwFlags = 1
c.dwMinSecondarySampleRate = 2
c.dwMaxSecondarySampleRate = 3
c.dwPrimaryBuffers = 4
c.dwMaxHwMixingAllBuffers = 5
c.dwMaxHwMixingStaticBuffers = 6
c.dwMaxHwMixingStreamingBuffers = 7
c.dwFreeHwMixingAllBuffers = 8
c.dwFreeHwMixingStaticBuffers = 9
c.dwFreeHwMixingStreamingBuffers = 10
c.dwMaxHw3DAllBuffers = 11
c.dwMaxHw3DStaticBuffers = 12
c.dwMaxHw3DStreamingBuffers = 13
c.dwFreeHw3DAllBuffers = 14
c.dwFreeHw3DStaticBuffers = 15
c.dwFreeHw3DStreamingBuffers = 16
c.dwTotalHwMemBytes = 17
c.dwFreeHwMemBytes = 18
c.dwMaxContigFreeHwMemBytes = 19
c.dwUnlockTransferRateHwBuffers = 20
c.dwPlayCpuOverheadSwBuffers = 21
self.assertTrue(c.dwFlags == 1)
self.assertTrue(c.dwMinSecondarySampleRate == 2)
self.assertTrue(c.dwMaxSecondarySampleRate == 3)
self.assertTrue(c.dwPrimaryBuffers == 4)
self.assertTrue(c.dwMaxHwMixingAllBuffers == 5)
self.assertTrue(c.dwMaxHwMixingStaticBuffers == 6)
self.assertTrue(c.dwMaxHwMixingStreamingBuffers == 7)
self.assertTrue(c.dwFreeHwMixingAllBuffers == 8)
self.assertTrue(c.dwFreeHwMixingStaticBuffers == 9)
self.assertTrue(c.dwFreeHwMixingStreamingBuffers == 10)
self.assertTrue(c.dwMaxHw3DAllBuffers == 11)
self.assertTrue(c.dwMaxHw3DStaticBuffers == 12)
self.assertTrue(c.dwMaxHw3DStreamingBuffers == 13)
self.assertTrue(c.dwFreeHw3DAllBuffers == 14)
self.assertTrue(c.dwFreeHw3DStaticBuffers == 15)
self.assertTrue(c.dwFreeHw3DStreamingBuffers == 16)
self.assertTrue(c.dwTotalHwMemBytes == 17)
self.assertTrue(c.dwFreeHwMemBytes == 18)
self.assertTrue(c.dwMaxContigFreeHwMemBytes == 19)
self.assertTrue(c.dwUnlockTransferRateHwBuffers == 20)
self.assertTrue(c.dwPlayCpuOverheadSwBuffers == 21)
class DSBCAPSTest(unittest.TestCase):
def test_1_Type(self):
"DSBCAPS type"
c = ds.DSBCAPS()
self.assertTrue(type(c) == ds.DSBCAPSType)
def test_2_Attr(self):
"DSBCAPS attribute access"
c = ds.DSBCAPS()
c.dwFlags = 1
c.dwBufferBytes = 2
c.dwUnlockTransferRate = 3
c.dwPlayCpuOverhead = 4
self.assertTrue(c.dwFlags == 1)
self.assertTrue(c.dwBufferBytes == 2)
self.assertTrue(c.dwUnlockTransferRate == 3)
self.assertTrue(c.dwPlayCpuOverhead == 4)
class DSCCAPSTest(unittest.TestCase):
def test_1_Type(self):
"DSCCAPS type"
c = ds.DSCCAPS()
self.assertTrue(type(c) == ds.DSCCAPSType)
def test_2_Attr(self):
"DSCCAPS attribute access"
c = ds.DSCCAPS()
c.dwFlags = 1
c.dwFormats = 2
c.dwChannels = 4
self.assertTrue(c.dwFlags == 1)
self.assertTrue(c.dwFormats == 2)
self.assertTrue(c.dwChannels == 4)
class DSCBCAPSTest(unittest.TestCase):
def test_1_Type(self):
"DSCBCAPS type"
c = ds.DSCBCAPS()
self.assertTrue(type(c) == ds.DSCBCAPSType)
def test_2_Attr(self):
"DSCBCAPS attribute access"
c = ds.DSCBCAPS()
c.dwFlags = 1
c.dwBufferBytes = 2
self.assertTrue(c.dwFlags == 1)
self.assertTrue(c.dwBufferBytes == 2)
class DSBUFFERDESCTest(unittest.TestCase):
def test_1_Type(self):
"DSBUFFERDESC type"
c = ds.DSBUFFERDESC()
self.assertTrue(type(c) == ds.DSBUFFERDESCType)
def test_2_Attr(self):
"DSBUFFERDESC attribute access"
c = ds.DSBUFFERDESC()
c.dwFlags = 1
c.dwBufferBytes = 2
c.lpwfxFormat = pywintypes.WAVEFORMATEX()
c.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM
c.lpwfxFormat.nChannels = 2
c.lpwfxFormat.nSamplesPerSec = 44100
c.lpwfxFormat.nAvgBytesPerSec = 176400
c.lpwfxFormat.nBlockAlign = 4
c.lpwfxFormat.wBitsPerSample = 16
self.assertTrue(c.dwFlags == 1)
self.assertTrue(c.dwBufferBytes == 2)
self.assertTrue(c.lpwfxFormat.wFormatTag == 1)
self.assertTrue(c.lpwfxFormat.nChannels == 2)
self.assertTrue(c.lpwfxFormat.nSamplesPerSec == 44100)
self.assertTrue(c.lpwfxFormat.nAvgBytesPerSec == 176400)
self.assertTrue(c.lpwfxFormat.nBlockAlign == 4)
self.assertTrue(c.lpwfxFormat.wBitsPerSample == 16)
def invalid_format(self, c):
c.lpwfxFormat = 17
def test_3_invalid_format(self):
"DSBUFFERDESC invalid lpwfxFormat assignment"
c = ds.DSBUFFERDESC()
self.assertRaises(ValueError, self.invalid_format, c)
class DSCBUFFERDESCTest(unittest.TestCase):
def test_1_Type(self):
"DSCBUFFERDESC type"
c = ds.DSCBUFFERDESC()
self.assertTrue(type(c) == ds.DSCBUFFERDESCType)
def test_2_Attr(self):
"DSCBUFFERDESC attribute access"
c = ds.DSCBUFFERDESC()
c.dwFlags = 1
c.dwBufferBytes = 2
c.lpwfxFormat = pywintypes.WAVEFORMATEX()
c.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM
c.lpwfxFormat.nChannels = 2
c.lpwfxFormat.nSamplesPerSec = 44100
c.lpwfxFormat.nAvgBytesPerSec = 176400
c.lpwfxFormat.nBlockAlign = 4
c.lpwfxFormat.wBitsPerSample = 16
self.assertTrue(c.dwFlags == 1)
self.assertTrue(c.dwBufferBytes == 2)
self.assertTrue(c.lpwfxFormat.wFormatTag == 1)
self.assertTrue(c.lpwfxFormat.nChannels == 2)
self.assertTrue(c.lpwfxFormat.nSamplesPerSec == 44100)
self.assertTrue(c.lpwfxFormat.nAvgBytesPerSec == 176400)
self.assertTrue(c.lpwfxFormat.nBlockAlign == 4)
self.assertTrue(c.lpwfxFormat.wBitsPerSample == 16)
def invalid_format(self, c):
c.lpwfxFormat = 17
def test_3_invalid_format(self):
"DSCBUFFERDESC invalid lpwfxFormat assignment"
c = ds.DSCBUFFERDESC()
self.assertRaises(ValueError, self.invalid_format, c)
class DirectSoundTest(unittest.TestCase):
# basic tests - mostly just exercise the functions
def testEnumerate(self):
"""DirectSoundEnumerate() sanity tests"""
devices = ds.DirectSoundEnumerate()
# this might fail on machines without a sound card
self.assertTrue(len(devices))
# if we have an entry, it must be a tuple of size 3
self.assertTrue(len(devices[0]) == 3)
def testCreate(self):
"""DirectSoundCreate()"""
try:
d = ds.DirectSoundCreate(None, None)
except pythoncom.com_error as exc:
if exc.hresult != ds.DSERR_NODRIVER:
raise
raise TestSkipped(exc)
def testPlay(self):
"""Mesdames et Messieurs, la cour de Devin Dazzle"""
# relative to 'testall.py' in the win32com test suite.
extra = os.path.join(
os.path.dirname(sys.argv[0]), "../../win32comext/directsound/test"
)
fname = find_test_fixture("01-Intro.wav", extra)
with open(fname, "rb") as f:
hdr = f.read(WAV_HEADER_SIZE)
wfx, size = wav_header_unpack(hdr)
try:
d = ds.DirectSoundCreate(None, None)
except pythoncom.com_error as exc:
if exc.hresult != ds.DSERR_NODRIVER:
raise
raise TestSkipped(exc)
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)
class DirectSoundCaptureTest(unittest.TestCase):
# basic tests - mostly just exercise the functions
def testEnumerate(self):
"""DirectSoundCaptureEnumerate() sanity tests"""
devices = ds.DirectSoundCaptureEnumerate()
# this might fail on machines without a sound card
self.assertTrue(len(devices))
# if we have an entry, it must be a tuple of size 3
self.assertTrue(len(devices[0]) == 3)
def testCreate(self):
"""DirectSoundCreate()"""
try:
d = ds.DirectSoundCaptureCreate(None, None)
except pythoncom.com_error as exc:
if exc.hresult != ds.DSERR_NODRIVER:
raise
raise TestSkipped(exc)
def testRecord(self):
try:
d = ds.DirectSoundCaptureCreate(None, None)
except pythoncom.com_error as exc:
if exc.hresult != ds.DSERR_NODRIVER:
raise
raise TestSkipped(exc)
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)
event.Close()
data = buffer.Update(0, 352800)
fname = os.path.join(win32api.GetTempPath(), "test_directsound_record.wav")
f = open(fname, "wb")
f.write(wav_header_pack(sdesc.lpwfxFormat, 352800))
f.write(data)
f.close()
if __name__ == "__main__":
unittest.main()