Update of /cvsroot/pywin32/pywin32/com/win32comext/directsound/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6405/com/win32comext/directsound/src
Added Files:
PyDSBCAPS.cpp PyDSBUFFERDESC.cpp PyDSCAPS.cpp
PyIDirectSound.cpp PyIDirectSound.h PyIDirectSoundBuffer.cpp
PyIDirectSoundBuffer.h PyIDirectSoundNotify.cpp
PyIDirectSoundNotify.h directsound.cpp directsound_pch.h
Log Message:
Added (some) DirectSound support.
The bulk is in com/win32comext/directsound, including a test directory with
a sample soundfile and a unittest-based test script.
Supported are:
- IDirectSound
- IDirectSoundBuffer
- IDirectSoundNotify.
Also added support for:
- WAVEFORMATEX (in PyWinTypes)
- DSBUFFERDESC
- DSBCAPS
- DSCAPS
- various constants used in these structures
Missing is:
- IDirectSoundCapture
- complete documentation
--- NEW FILE: PyIDirectSound.h ---
// This file declares the IDirectSound Interface for Python.
// ---------------------------------------------------
//
// Interface Declaration
class PyIDirectSound : public PyIUnknown
{
public:
MAKE_PYCOM_CTOR(PyIDirectSound);
static IDirectSound *GetI(PyObject *self);
static PyComTypeObject type;
// The Python methods
static PyObject *Initialize(PyObject *self, PyObject *args);
static PyObject *SetCooperativeLevel(PyObject *self, PyObject *args);
static PyObject *CreateSoundBuffer(PyObject *self, PyObject *args);
static PyObject *Compact(PyObject *self, PyObject *args);
static PyObject *GetCaps(PyObject *self, PyObject *args);
static PyObject *GetSpeakerConfig(PyObject *self, PyObject *args);
static PyObject *SetSpeakerConfig(PyObject *self, PyObject *args);
PyIDirectSound(IUnknown *pdisp);
~PyIDirectSound();
};
--- NEW FILE: PyIDirectSound.cpp ---
// This file implements the IDirectSound Interface for Python.
#include "directsound_pch.h"
#include "PySoundObjects.h"
#include "PyIDirectSound.h"
#include "PyIDirectSoundBuffer.h"
// @doc - This file contains autoduck documentation
// ---------------------------------------------------
//
// Interface Implementation
PyIDirectSound::PyIDirectSound(IUnknown *pdisp):
PyIUnknown(pdisp)
{
ob_type = &type;
}
PyIDirectSound::~PyIDirectSound()
{
}
/* static */ IDirectSound *PyIDirectSound::GetI(PyObject *self)
{
return (IDirectSound *)PyIUnknown::GetI(self);
}
// @pymethod |PyIDirectSound|Initialize|Description of Initialize.
PyObject *PyIDirectSound::Initialize(PyObject *self, PyObject *args)
{
PyObject *obGUID;
IDirectSound *pIDS = GetI(self);
if ( pIDS == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, "|O:Initialize", &obGUID) )
return NULL;
GUID guid;
LPGUID pguid = NULL;
if (!obGUID && obGUID != Py_None)
{
if (!PyWinObject_AsIID(obGUID, &guid))
return NULL;
pguid = &guid;
}
HRESULT hr;
PY_INTERFACE_PRECALL;
hr = pIDS->Initialize(pguid);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("Initialize", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
// @pymethod |PyIDirectSound|SetCooperativeLevel|Description of SetCooperativeLevel.
PyObject *PyIDirectSound::SetCooperativeLevel(PyObject *self, PyObject *args)
{
int level;
PyObject *obHWND = NULL;
HWND hwnd;
IDirectSound *pIDS = GetI(self);
if ( pIDS == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, "Oi:SetCooperativeLevel", &obHWND, &level) )
return NULL;
if (obHWND == Py_None)
{
hwnd = GetForegroundWindow();
if (hwnd == NULL)
{
hwnd = GetDesktopWindow();
}
}
else if (PyInt_Check(obHWND))
{
hwnd = (HWND)PyInt_AS_LONG(obHWND);
}
else
{
PyErr_SetString(PyExc_TypeError, "argument 1 must be a window handle or None");
return NULL;
}
HRESULT hr;
PY_INTERFACE_PRECALL;
hr = pIDS->SetCooperativeLevel(hwnd, level);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("SetCooperativeLevel", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
// @pymethod |PyIDirectSound|CreateSoundBuffer|Description of CreateSoundBuffer.
PyObject *PyIDirectSound::CreateSoundBuffer(PyObject *self, PyObject *args)
{
PyObject *obDSBD = NULL;
PyObject *obUnk = NULL;
IUnknown *pUnkIn = NULL;
IDirectSound *pIDS = GetI(self);
if ( pIDS == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, "O|O:CreateSoundBuffer", &obDSBD, &obUnk) )
return NULL;
if (!PyDSBUFFERDESC_Check(obDSBD)) {
PyErr_SetString(PyExc_TypeError, "Argument 1 must be of type PyDSBUFFERDESC");
return NULL;
}
if (!PyCom_InterfaceFromPyInstanceOrObject(obUnk, IID_IUnknown, (void **)&pUnkIn, TRUE)) {
return NULL;
}
DSBUFFERDESC *pdsbd = &((PyDSBUFFERDESC*)obDSBD)->m_dsbd;
HRESULT hr;
IDirectSoundBuffer *buffer;
PY_INTERFACE_PRECALL;
hr = pIDS->CreateSoundBuffer(pdsbd, &buffer, pUnkIn);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("CreateSoundBuffer", hr);
return NULL;
}
PyIDirectSoundBuffer *rc = new PyIDirectSoundBuffer(buffer);
Py_INCREF(self);
rc->m_DS = self;
return rc;
}
// @pymethod |PyIDirectSound|GetCaps|Description of GetCaps.
PyObject *PyIDirectSound::GetCaps(PyObject *self, PyObject *args)
{
IDirectSound *pIDS = GetI(self);
if ( pIDS == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, ":GetCaps") )
return NULL;
HRESULT hr;
PyDSCAPS *caps = new PyDSCAPS();
PY_INTERFACE_PRECALL;
hr = pIDS->GetCaps(caps->GetCAPS());
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("GetCaps", hr);
return NULL;
}
Py_INCREF(caps);
return caps;
}
// @pymethod |PyIDirectSound|Compact|Description of Compact.
PyObject *PyIDirectSound::Compact(PyObject *self, PyObject *args)
{
IDirectSound *pIDS = GetI(self);
if ( pIDS == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, ":Compact") )
return NULL;
HRESULT hr;
PY_INTERFACE_PRECALL;
hr = pIDS->Compact();
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("GetCaps", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
// @pymethod |PyIDirectSound|GetSpeakerConfig|Description of GetSpeakerConfig.
PyObject *PyIDirectSound::GetSpeakerConfig(PyObject *self, PyObject *args)
{
IDirectSound *pIDS = GetI(self);
if ( pIDS == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, ":GetSpeakerConfig") )
return NULL;
HRESULT hr;
DWORD config;
PY_INTERFACE_PRECALL;
hr = pIDS->GetSpeakerConfig(&config);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("GetSpeakerConfig", hr);
return NULL;
}
return PyInt_FromLong(config);
}
// @pymethod |PyIDirectSound|SetSpeakerConfig|Description of SetSpeakerConfig.
PyObject *PyIDirectSound::SetSpeakerConfig(PyObject *self, PyObject *args)
{
DWORD config;
IDirectSound *pIDS = GetI(self);
if ( pIDS == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, "i:SetSpeakerConfig", &config) )
return NULL;
HRESULT hr;
PY_INTERFACE_PRECALL;
hr = pIDS->SetSpeakerConfig(config);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("SetSpeakerConfig", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
// @object PyIDirectSound|Description of the interface
static struct PyMethodDef PyIDirectSound_methods[] =
{
{ "Initialize", PyIDirectSound::Initialize, 1 }, // @pymeth Initialize|Description of Initialize.
{ "SetCooperativeLevel", PyIDirectSound::SetCooperativeLevel, 1 }, // @pymeth SetCooperativeLevel|Description of SetCooperativeLevel.
{ "CreateSoundBuffer", PyIDirectSound::CreateSoundBuffer, 1 }, // @pymeth CreateSoundBuffer|Description of CreateSoundBuffer.
{ "GetCaps", PyIDirectSound::GetCaps, 1 }, // @pymeth GetCaps|Description of GetCaps.
{ "Compact", PyIDirectSound::Compact, 1 }, // @pymeth Compact|Description of Compact.
{ NULL }
};
PyComTypeObject PyIDirectSound::type("PyIDirectSound",
&PyIUnknown::type,
sizeof(PyIDirectSound),
PyIDirectSound_methods,
GET_PYCOM_CTOR(PyIDirectSound));
--- NEW FILE: PyIDirectSoundBuffer.cpp ---
// This file implements the IDirectSound Interface for Python.
#include "directsound_pch.h"
#include "PySoundObjects.h"
#include "PyIDirectSoundBuffer.h"
#include "PyIDirectSoundNotify.h"
// @doc - This file contains autoduck documentation
// ---------------------------------------------------
//
// Interface Implementation
PyIDirectSoundBuffer::PyIDirectSoundBuffer(IUnknown *pdisp):
PyIUnknown(pdisp), m_DS(NULL)
{
ob_type = &type;
}
PyIDirectSoundBuffer::~PyIDirectSoundBuffer()
{
if (m_DS)
Py_DECREF(m_DS);
}
/* static */ IDirectSoundBuffer *PyIDirectSoundBuffer::GetI(PyObject *self)
{
return (IDirectSoundBuffer*)PyIUnknown::GetI(self);
}
/* static */ PyObject *PyIDirectSoundBuffer::QueryInterface(PyObject *self, PyObject *args)
{
PyObject *obiid;
PyObject *obUseIID = NULL;
if (!PyArg_ParseTuple(args, "O|O:QueryInterface", &obiid, &obUseIID ))
return NULL;
PyObject *rc = PyIUnknown::QueryInterface(self, args);
// Special treatment for PyIDirectSoundNotify
// This is a workaround for a reference counting bug in IDirectSound:
// If IDirectSound->Release() is called before IDirectSoundBuffer->Release()
// or IDirectSoundNotify->->Release(), we will get an Access Violation
// We work around this by manipulating the reference count on the Python objects
// that encapsulate them
if (PyIBase::is_object(rc, &PyIDirectSoundNotify::type))
{
PyIDirectSoundNotify *notify = (PyIDirectSoundNotify*)rc;
PyIDirectSoundBuffer *me = (PyIDirectSoundBuffer*)self;
Py_INCREF(me->m_DS);
notify->m_DS = me->m_DS;
}
return rc;
}
// @pymethod |PyIDirectSoundBuffer|GetCaps|Description of GetCaps.
PyObject *PyIDirectSoundBuffer::GetCaps(PyObject *self, PyObject *args)
{
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, ":GetCaps") )
return NULL;
HRESULT hr;
PyDSBCAPS *caps = new PyDSBCAPS();
PY_INTERFACE_PRECALL;
hr = pIDSB->GetCaps(caps->GetCAPS());
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("GetCaps", hr);
return NULL;
}
Py_INCREF(caps);
return caps;
}
// @pymethod |PyIDirectSoundBuffer|GetFormat|Description of GetFormat.
PyObject *PyIDirectSoundBuffer::GetFormat(PyObject *self, PyObject *args)
{
int level;
HWND hwnd;
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, ":GetFormat", &hwnd, &level) )
return NULL;
HRESULT hr;
PyWAVEFORMATEX *wfx = new PyWAVEFORMATEX();
PY_INTERFACE_PRECALL;
// We don't support getting more than standard wave headers
hr = pIDSB->GetFormat(&wfx->m_wfx, sizeof(WAVEFORMATEX), NULL);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("GetFormat", hr);
return NULL;
}
Py_INCREF(wfx);
return wfx;
}
// @pymethod |PyIDirectSoundBuffer|GetStatus|Description of GetStatus.
PyObject *PyIDirectSoundBuffer::GetStatus(PyObject *self, PyObject *args)
{
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, ":GetStatus") )
return NULL;
HRESULT hr;
DWORD dwStatus;
PY_INTERFACE_PRECALL;
hr = pIDSB->GetStatus(&dwStatus);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("GetStatus", hr);
return NULL;
}
return PyInt_FromLong(dwStatus);
}
// @pymethod |PyIDirectSoundBuffer|SetFormat|Description of SetFormat.
PyObject *PyIDirectSoundBuffer::SetFormat(PyObject *self, PyObject *args)
{
PyObject *obWfx;
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, "O:SetFormat", &obWfx) )
return NULL;
if (!PyWAVEFORMATEX_Check(obWfx)) {
PyErr_SetString(PyExc_TypeError, "Argument 1 must be of type PyWAVEFORMATEX");
return NULL;
}
HRESULT hr;
PY_INTERFACE_PRECALL;
hr = pIDSB->SetFormat(&((PyWAVEFORMATEX*)obWfx)->m_wfx);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("SetFormat", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
// @pymethod |PyIDirectSoundBuffer|Initialize|Description of Initialize.
PyObject *PyIDirectSoundBuffer::Initialize(PyObject *self, PyObject *args)
{
PyObject *obDSBD = NULL;
PyObject *obDS = NULL;
IDirectSound *pIDS = NULL;
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, "OO:Initialize", &obDS, &obDSBD) )
return NULL;
// Todo - check and initialize pIDS
if (!PyDSBUFFERDESC_Check(obDSBD)) {
PyErr_SetString(PyExc_TypeError, "Argument 2 must be of type PyDSBUFFERDESC");
return NULL;
}
HRESULT hr;
PY_INTERFACE_PRECALL;
hr = pIDSB->Initialize(pIDS, &((PyDSBUFFERDESC*)obDSBD)->m_dsbd);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("Initialize", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
// @pymethod |PyIDirectSoundBuffer|Restore|Description of Initialize.
PyObject *PyIDirectSoundBuffer::Restore(PyObject *self, PyObject *args)
{
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, ":Restore") )
return NULL;
HRESULT hr;
PY_INTERFACE_PRECALL;
hr = pIDSB->Restore();
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("Restore", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
// @pymethod |PyIDirectSoundBuffer|GetCurrentPosition|Description of GetCurrentPosition.
PyObject *PyIDirectSoundBuffer::GetCurrentPosition(PyObject *self, PyObject *args)
{
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, ":GetCurrentPosition") )
return NULL;
HRESULT hr;
DWORD dwPlay = 0, dwWrite = 0;
PY_INTERFACE_PRECALL;
hr = pIDSB->GetCurrentPosition(&dwPlay, &dwWrite);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("GetCurrentPosition", hr);
return NULL;
}
PyObject *result = PyTuple_New(2);
if (!result)
return NULL;
PyTuple_SetItem(result, 0, PyInt_FromLong(dwPlay));
PyTuple_SetItem(result, 1, PyInt_FromLong(dwWrite));
return result;
}
// @pymethod |PyIDirectSoundBuffer|Play|Description of Play.
PyObject *PyIDirectSoundBuffer::Play(PyObject *self, PyObject *args)
{
DWORD dwFlags;
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, "i:Play", &dwFlags) )
return NULL;
HRESULT hr;
PY_INTERFACE_PRECALL;
hr = pIDSB->Play(0, 0, dwFlags);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("Play", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
// @pymethod |PyIDirectSoundBuffer|SetCurrentPosition|Description of SetCurrentPosition.
PyObject *PyIDirectSoundBuffer::SetCurrentPosition(PyObject *self, PyObject *args)
{
DWORD dwNewPosition;
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, "i:SetCurrentPosition", &dwNewPosition) )
return NULL;
HRESULT hr;
PY_INTERFACE_PRECALL;
hr = pIDSB->SetCurrentPosition(dwNewPosition);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("SetCurrentPosition", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
// @pymethod |PyIDirectSoundBuffer|Stop|Description of Stop.
PyObject *PyIDirectSoundBuffer::Stop(PyObject *self, PyObject *args)
{
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, ":Stop") )
return NULL;
HRESULT hr;
PY_INTERFACE_PRECALL;
hr = pIDSB->Stop();
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("Stop", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
// @pymethod |PyIDirectSoundBuffer|Update|Description of Update.
PyObject *PyIDirectSoundBuffer::Update(PyObject *self, PyObject *args)
{
DWORD dwWriteCursor = 0;
DWORD dwFlags = 0;
PyObject *obData = NULL;
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, "iS|i:Update", &dwWriteCursor, &obData, &dwFlags) )
return NULL;
HRESULT hr;
LPVOID lpAudioPtr1 = NULL;
DWORD dwAudioBytes1 = 0;
LPVOID lpAudioPtr2 = NULL;
DWORD dwAudioBytes2 = 0;
PY_INTERFACE_PRECALL;
hr = pIDSB->Lock(dwWriteCursor, PyString_Size(obData), &lpAudioPtr1, &dwAudioBytes1,
&lpAudioPtr2, &dwAudioBytes2, dwFlags);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("Update(Lock)", hr);
return NULL;
}
// The play buffer is circular, so we may get two pointers and have to
// do the wrap-around ourselves.
// Raise error if assumption isn't met
if (dwAudioBytes1 + dwAudioBytes2 != PyString_Size(obData)) {
PY_INTERFACE_PRECALL;
hr = pIDSB->Unlock(lpAudioPtr1, dwAudioBytes1, lpAudioPtr2, dwAudioBytes2);
PY_INTERFACE_POSTCALL;
PyErr_SetString(PyExc_RuntimeError, "Size mismatch from Unlock");
return NULL;
}
memcpy(lpAudioPtr1, PyString_AsString(obData), dwAudioBytes1);
if (dwAudioBytes2) {
memcpy(lpAudioPtr2, PyString_AsString(obData) + dwAudioBytes1, dwAudioBytes2);
}
{
// need extra block for local variables from PY_INTERFACE_UPCALL macro
PY_INTERFACE_PRECALL;
hr = pIDSB->Unlock(lpAudioPtr1, dwAudioBytes1, lpAudioPtr2, dwAudioBytes2);
PY_INTERFACE_POSTCALL;
}
if (FAILED(hr)) {
PyWin_SetAPIError("Update(Unlock)", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
// @pymethod |PyIDirectSoundBuffer|GetFrequency|Description of GetFrequency.
PyObject *PyIDirectSoundBuffer::GetFrequency(PyObject *self, PyObject *args)
{
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, ":GetFrequency") )
return NULL;
HRESULT hr;
DWORD dwFrequency;
PY_INTERFACE_PRECALL;
hr = pIDSB->GetFrequency(&dwFrequency);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("GetFrequency", hr);
return NULL;
}
return PyInt_FromLong(dwFrequency);
}
// @pymethod |PyIDirectSoundBuffer|GetPan|Description of GetPan.
PyObject *PyIDirectSoundBuffer::GetPan(PyObject *self, PyObject *args)
{
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, ":GetPan") )
return NULL;
HRESULT hr;
LONG pan;
PY_INTERFACE_PRECALL;
hr = pIDSB->GetPan(&pan);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("GetPan", hr);
return NULL;
}
return PyInt_FromLong(pan);
}
// @pymethod |PyIDirectSoundBuffer|GetVolume|Description of GetVolume.
PyObject *PyIDirectSoundBuffer::GetVolume(PyObject *self, PyObject *args)
{
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, ":GetVolume") )
return NULL;
HRESULT hr;
LONG pan;
PY_INTERFACE_PRECALL;
hr = pIDSB->GetVolume(&pan);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("GetVolume", hr);
return NULL;
}
return PyInt_FromLong(pan);
}
// @pymethod |PyIDirectSoundBuffer|SetFrequency|Description of SetFrequency.
PyObject *PyIDirectSoundBuffer::SetFrequency(PyObject *self, PyObject *args)
{
DWORD dwNewFrequency;
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, "i:SetFrequency", &dwNewFrequency) )
return NULL;
HRESULT hr;
PY_INTERFACE_PRECALL;
hr = pIDSB->SetFrequency(dwNewFrequency);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("SetFrequency", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
// @pymethod |PyIDirectSoundBuffer|SetPan|Description of SetPan.
PyObject *PyIDirectSoundBuffer::SetPan(PyObject *self, PyObject *args)
{
LONG dwNewPan;
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, "i:SetPan", &dwNewPan) )
return NULL;
HRESULT hr;
PY_INTERFACE_PRECALL;
hr = pIDSB->SetPan(dwNewPan);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("SetPan", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
// @pymethod |PyIDirectSoundBuffer|SetVolume|Description of SetVolume.
PyObject *PyIDirectSoundBuffer::SetVolume(PyObject *self, PyObject *args)
{
LONG dwNewVolume;
IDirectSoundBuffer *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, "i:SetVolume", &dwNewVolume) )
return NULL;
HRESULT hr;
PY_INTERFACE_PRECALL;
hr = pIDSB->SetVolume(dwNewVolume);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
PyWin_SetAPIError("SetVolume", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
// @object PyIDirectSoundBuffer|Description of the interface
static struct PyMethodDef PyIDirectSoundBuffer_methods[] =
{
{ "QueryInterface", PyIDirectSoundBuffer::QueryInterface, 1 },
{ "GetCaps", PyIDirectSoundBuffer::GetCaps, 1 }, // @pymeth Initialize|Description of Initialize.
{ "GetFormat", PyIDirectSoundBuffer::GetFormat, 1 }, // @pymeth SetCooperativeLevel|Description of SetCooperativeLevel.
{ "GetStatus", PyIDirectSoundBuffer::GetStatus, 1 }, // @pymeth GetStatus|Description of GetStatus.
{ "SetFormat", PyIDirectSoundBuffer::SetFormat, 1 }, // @pymeth GetCaps|Description of GetCaps.
{ "Initialize", PyIDirectSoundBuffer::Initialize, 1 }, // @pymeth Initialize|Description of GetCaps.
{ "Restore", PyIDirectSoundBuffer::Restore, 1 }, // @pymeth Restore|Description of Restore.
{ "GetCurrentPosition", PyIDirectSoundBuffer::GetCurrentPosition, 1 }, // @pymeth GetCurrentPosition|Description of GetCaps.
{ "Play", PyIDirectSoundBuffer::Play, 1 }, // @pymeth Play|Description of GetCaps.
{ "SetCurrentPosition", PyIDirectSoundBuffer::SetCurrentPosition, 1 }, // @pymeth SetCurrentPosition|Description of GetCaps.
{ "Stop", PyIDirectSoundBuffer::Stop, 1 }, // @pymeth Stop|Description of GetCaps.
{ "Update", PyIDirectSoundBuffer::Update, 1 }, // @pymeth Unlock|Description of Unlock.
{ "GetFrequency", PyIDirectSoundBuffer::GetFrequency, 1 }, // @pymeth GetFrequency|Description of GetCaps.
{ "GetPan", PyIDirectSoundBuffer::GetPan, 1 }, // @pymeth GetPan|Description of GetCaps.
{ "GetVolume", PyIDirectSoundBuffer::GetVolume, 1 }, // @pymeth GetVolume|Description of GetCaps.
{ "SetFrequency", PyIDirectSoundBuffer::SetFrequency, 1 }, // @pymeth SetFrequency|Description of GetCaps.
{ "SetPan", PyIDirectSoundBuffer::SetPan, 1 }, // @pymeth SetPan|Description of GetCaps.
{ "SetVolume", PyIDirectSoundBuffer::SetVolume, 1 }, // @pymeth SetVolume|Description of GetCaps.
{ NULL }
};
PyComTypeObject PyIDirectSoundBuffer::type("PyIDirectSoundBuffer",
&PyIUnknown::type,
sizeof(PyIDirectSoundBuffer),
PyIDirectSoundBuffer_methods,
GET_PYCOM_CTOR(PyIDirectSoundBuffer));
--- NEW FILE: PyDSCAPS.cpp ---
//
// @doc
#include "PyWinTypes.h"
#include "PyWinObjects.h"
#include "PySoundObjects.h"
#include "structmember.h"
#include "directsound_pch.h"
// @pymethod <o PyDSCAPS>|pywintypes|DSCAPS|Creates a new DSCAPS object
PyObject *PyWinMethod_NewDSCAPS(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":DSCAPS"))
return NULL;
return new PyDSCAPS();
}
PyObject *PyWinObject_FromDSCAPS(const DSCAPS &caps)
{
return new PyDSCAPS(caps);
}
BOOL PyWinObject_AsDSCAPS(PyObject *ob, DSCAPS **ppDSCAPS, BOOL bNoneOK /*= TRUE*/)
{
if (bNoneOK && ob==Py_None) {
*ppDSCAPS = NULL;
} else if (!PyDSCAPS_Check(ob)) {
PyErr_SetString(PyExc_TypeError, "The object is not a PyDSCAPS object");
return FALSE;
} else {
PyDSCAPS *pycaps= (PyDSCAPS *)ob;
*ppDSCAPS = pycaps->GetCAPS();
}
return TRUE;
}
// @object PyDSCAPS|A Python object, representing a DSCAPS structure
static struct PyMethodDef PyDSCAPS_methods[] = {
{NULL}
};
PyTypeObject PyDSCAPSType =
{
PyObject_HEAD_INIT(&PyType_Type)
0,
"PyDSCAPSType",
sizeof(PyDSCAPSType),
0,
PyDSCAPS::deallocFunc,
0, // tp_print;
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
0,
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr,
PyObject_GenericSetAttr,
0, // tp_as_buffer;
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags;
0, // tp_doc; /* Documentation string */
0, // traverseproc tp_traverse;
0, // tp_clear;
0, // tp_richcompare;
0, // tp_weaklistoffset;
0, // tp_iter
0, // iternextfunc tp_iternext
0, // methods
PyDSCAPS::members,
0, // tp_getset;
0, // tp_base;
0, // tp_dict;
0, // tp_descr_get;
0, // tp_descr_set;
0, // tp_dictoffset;
0, // tp_init;
0, // tp_alloc;
0 // newfunc tp_new;
};
#define OFF(e) offsetof(PyDSCAPS, e)
/*static*/ struct PyMemberDef PyDSCAPS::members[] = {
{"dwFlags", T_INT, OFF(m_caps.dwFlags), 0, "Specifies device capabilities."},
// @prop integer|dwFlags|Specifies device capabilities.
{"dwMinSecondarySampleRate", T_INT, OFF(m_caps.dwMinSecondarySampleRate), 0, "Minimum sample rate supported by this device's hardware secondary sound buffers."},
// @prop integer|dwMinSecondarySampleRate|Minimum sample rate supported by this device's hardware secondary sound buffers.
{"dwMaxSecondarySampleRate", T_INT, OFF(m_caps.dwMaxSecondarySampleRate), 0, "Maximum sample rate supported by this device's hardware secondary sound buffers."},
// @prop integer|dwMaxSecondarySampleRate|Maximum sample rate supported by this device's hardware secondary sound buffers.
{"dwPrimaryBuffers", T_INT, OFF(m_caps.dwPrimaryBuffers), 0, "Number of primary buffers supported. This value will always be 1."},
// @prop integer|dwPrimaryBuffers|Number of primary buffers supported. This value will always be 1.
{"dwMaxHwMixingAllBuffers", T_INT, OFF(m_caps.dwMaxHwMixingAllBuffers), 0, "Specifies the total number of buffers that can be mixed in hardware. This member can be less than the sum of dwMaxHwMixingStaticBuffers and dwMaxHwMixingStreamingBuffers. Resource tradeoffs frequently occur."},
// @prop integer|dwMaxHwMixingAllBuffers|Specifies the total number of buffers that can be mixed in hardware. This member can be less than the sum of dwMaxHwMixingStaticBuffers and dwMaxHwMixingStreamingBuffers. Resource tradeoffs frequently occur.
{"dwMaxHwMixingStaticBuffers", T_INT, OFF(m_caps.dwMaxHwMixingStaticBuffers), 0, "Specifies the maximum number of static sound buffers."},
// @prop integer|dwMaxHwMixingStaticBuffers|Specifies the maximum number of static sound buffers.
{"dwMaxHwMixingStreamingBuffers", T_INT, OFF(m_caps.dwMaxHwMixingStreamingBuffers), 0, "Specifies the maximum number of streaming sound buffers."},
// @prop integer|dwMaxHwMixingStreamingBuffers|Specifies the maximum number of streaming sound buffers.
{"dwFreeHwMixingAllBuffers", T_INT, OFF(m_caps.dwFreeHwMixingAllBuffers), 0, "Description of the free mixing hardware capabilities of the device. An application can use these values to determine whether hardware resources are available for allocation to a secondary sound buffer. Also, by comparing this value to the members that specify maximum mixing capabilities, the resources that are already allocated can be determined. "},
// @prop integer|dwFreeHwMixingAllBuffers|Description of the free hardware mixing capabilities of the device. An application can use this value to determine whether hardware resources are available for allocation to a secondary sound buffer. Also, by comparing these values to the members that specify maximum mixing capabilities, the resources that are already allocated can be determined.
{"dwFreeHwMixingStaticBuffers", T_INT, OFF(m_caps.dwFreeHwMixingStaticBuffers), 0, "Description of the free hardware mixing capabilities of the device. An application can use this value to determine whether hardware resources are available for allocation to a secondary sound buffer. Also, by comparing these values to the members that specify maximum mixing capabilities, the resources that are already allocated can be determined."},
// @prop integer|dwFreeHwMixingStaticBuffers|Description of the free hardware mixing capabilities of the device. An application can use this value to determine whether hardware resources are available for allocation to a secondary sound buffer. Also, by comparing these values to the members that specify maximum mixing capabilities, the resources that are already allocated can be determined.
{"dwFreeHwMixingStreamingBuffers", T_INT, OFF(m_caps.dwFreeHwMixingStreamingBuffers), 0, "Description of the free hardware mixing capabilities of the device. An application can use this value to determine whether hardware resources are available for allocation to a secondary sound buffer. Also, by comparing these values to the members that specify maximum mixing capabilities, the resources that are already allocated can be determined."},
// @prop integer|dwFreeHwMixingStreamingBuffers|Description of the free hardware mixing capabilities of the device. An application can use this value to determine whether hardware resources are available for allocation to a secondary sound buffer. Also, by comparing these values to the members that specify maximum mixing capabilities, the resources that are already allocated can be determined.
{"dwMaxHw3DAllBuffers", T_INT, OFF(m_caps.dwMaxHw3DAllBuffers), 0, "Description of the hardware 3-D positional capabilities of the device."},
// @prop integer|dwMaxHw3DAllBuffers|Description of the hardware 3-D positional capabilities of the device.
{"dwMaxHw3DStaticBuffers", T_INT, OFF(m_caps.dwMaxHw3DStaticBuffers), 0, "Description of the hardware 3-D positional capabilities of the device. "},
// @prop integer|dwMaxHw3DStaticBuffers|Description of the hardware 3-D positional capabilities of the device.
{"dwMaxHw3DStreamingBuffers", T_INT, OFF(m_caps.dwMaxHw3DStreamingBuffers), 0, "Description of the hardware 3-D positional capabilities of the device."},
// @prop integer|dwMaxHw3DStreamingBuffers|Description of the hardware 3-D positional capabilities of the device.
{"dwFreeHw3DAllBuffers", T_INT, OFF(m_caps.dwFreeHw3DAllBuffers), 0, "Description of the free, or unallocated, hardware 3-D positional capabilities of the device."},
// @prop integer|dwFreeHw3DAllBuffers|Description of the free, or unallocated, hardware 3-D positional capabilities of the device.
{"dwFreeHw3DStaticBuffers", T_INT, OFF(m_caps.dwFreeHw3DStaticBuffers), 0, "Description of the free, or unallocated, hardware 3-D positional capabilities of the device."},
// @prop integer|dwFreeHw3DStaticBuffers|Description of the free, or unallocated, hardware 3-D positional capabilities of the device.
{"dwFreeHw3DStreamingBuffers", T_INT, OFF(m_caps.dwFreeHw3DStreamingBuffers), 0, "Description of the free, or unallocated, hardware 3-D positional capabilities of the device."},
// @prop integer|dwFreeHw3DStreamingBuffers|Description of the free, or unallocated, hardware 3-D positional capabilities of the device.
{"dwTotalHwMemBytes", T_INT, OFF(m_caps.dwTotalHwMemBytes), 0, "Size, in bytes, of the amount of memory on the sound card that stores static sound buffers."},
// @prop integer|dwTotalHwMemBytes|Size, in bytes, of the amount of memory on the sound card that stores static sound buffers.
{"dwFreeHwMemBytes", T_INT, OFF(m_caps.dwFreeHwMemBytes), 0, "Size, in bytes, of the free memory on the sound card."},
// @prop integer|dwFreeHwMemBytes|Size, in bytes, of the free memory on the sound card.
{"dwMaxContigFreeHwMemBytes", T_INT, OFF(m_caps.dwMaxContigFreeHwMemBytes), 0, "Size, in bytes, of the largest contiguous block of free memory on the sound card."},
// @prop integer|dwMaxContigFreeHwMemBytes|Size, in bytes, of the largest contiguous block of free memory on the sound card.
{"dwUnlockTransferRateHwBuffers", T_INT, OFF(m_caps.dwUnlockTransferRateHwBuffers), 0, "Description of the rate, in kilobytes per second, at which data can be transferred to hardware static sound buffers. This and the number of bytes transferred determines the duration of a call to the IDirectSoundBuffer::Update method."},
// @prop integer|dwUnlockTransferRateHwBuffers|Description of the rate, in kilobytes per second, at which data can be transferred to hardware static sound buffers. This and the number of bytes transferred determines the duration of a call to the IDirectSoundBuffer::Update method.
{"dwPlayCpuOverheadSwBuffers", T_INT, OFF(m_caps.dwPlayCpuOverheadSwBuffers), 0, "Description of the processing overhead, as a percentage of the central processing unit, needed to mix software buffers (those located in main system memory). This varies according to the bus type, the processor type, and the clock speed. The unlock transfer rate for software buffers is 0 because the data need not be transferred anywhere. Similarly, the play processing overhead for hardware buffers is 0 because the mixing is done by the sound device."},
// @prop integer|dwPlayCpuOverheadSwBuffers|Description of the processing overhead, as a percentage of the central processing unit, needed to mix software buffers (those located in main system memory). This varies according to the bus type, the processor type, and the clock speed. The unlock transfer rate for software buffers is 0 because the data need not be transferred anywhere. Similarly, the play processing overhead for hardware buffers is 0 because the mixing is done by the sound device.
{NULL} /* Sentinel */
};
PyDSCAPS::PyDSCAPS(void)
{
ob_type = &PyDSCAPSType;
_Py_NewReference(this);
memset(&m_caps, 0, sizeof(m_caps));
}
PyDSCAPS::PyDSCAPS(const DSCAPS &caps)
{
ob_type = &PyDSCAPSType;
_Py_NewReference(this);
m_caps = caps;
m_caps.dwSize = sizeof(DSCAPS);
}
PyDSCAPS::~PyDSCAPS()
{
}
/*static*/ void PyDSCAPS::deallocFunc(PyObject *ob)
{
delete (PyDSCAPS *)ob;
}
--- NEW FILE: PyIDirectSoundBuffer.h ---
// This file declares the IDirectSound Interface for Python.
// ---------------------------------------------------
//
// Interface Declaration
class PyIDirectSoundBuffer : public PyIUnknown
{
public:
MAKE_PYCOM_CTOR(PyIDirectSoundBuffer);
static IDirectSoundBuffer *GetI(PyObject *self);
static PyComTypeObject type;
static PyObject *QueryInterface(PyObject *self, PyObject *args);
// The Python methods
// Information methods
static PyObject *GetCaps(PyObject *self, PyObject *args);
static PyObject *GetFormat(PyObject *self, PyObject *args);
static PyObject *GetStatus(PyObject *self, PyObject *args);
static PyObject *SetFormat(PyObject *self, PyObject *args);
// Memory management
static PyObject *Initialize(PyObject *self, PyObject *args);
static PyObject *Restore(PyObject *self, PyObject *args);
// Play management
static PyObject *GetCurrentPosition(PyObject *self, PyObject *args);
static PyObject *Play(PyObject *self, PyObject *args);
static PyObject *SetCurrentPosition(PyObject *self, PyObject *args);
static PyObject *Stop(PyObject *self, PyObject *args);
static PyObject *Update(PyObject *self, PyObject *args);
// Sound management
static PyObject *GetFrequency(PyObject *self, PyObject *args);
static PyObject *GetPan(PyObject *self, PyObject *args);
static PyObject *GetVolume(PyObject *self, PyObject *args);
static PyObject *SetFrequency(PyObject *self, PyObject *args);
static PyObject *SetPan(PyObject *self, PyObject *args);
static PyObject *SetVolume(PyObject *self, PyObject *args);
PyIDirectSoundBuffer(IUnknown *pdisp);
~PyIDirectSoundBuffer();
PyObject *m_DS;
};
--- NEW FILE: directsound.cpp ---
// directsound.cpp :
// $Id: directsound.cpp,v 1.1 2004/11/30 21:30:28 larsimmisch Exp $
// directsound wrapper contributed by Lars Immisch <la...@ib...>
/***
Note that this source file contains embedded documentation.
This documentation consists of marked up text inside the
C comments, and is prefixed with an '@' symbol. The source
files are processed by a tool called "autoduck" which
generates Windows .hlp files.
@doc
***/
#include "directsound_pch.h"
#include "stddef.h" // for offsetof
#include "PythonCOMRegister.h" // For simpler registration of IIDs etc.
#include "PyIDirectSound.h"
#include "PyIDirectSoundBuffer.h"
#include "PyIDirectSoundNotify.h"
// @pymethod <o PyIUnknown>|directsound|DirectSoundCreate|Creates and initializes a new object that supports the IDirectSound interface.
static PyObject *directsound_DirectSoundCreate(PyObject *, PyObject *args)
{
PyObject *ret = NULL;
PyObject *obGUID = NULL, *obUnk = NULL;
IUnknown *pUnkIn = NULL;
GUID guid, *pguid = NULL;
LPDIRECTSOUND ds;
HRESULT hr;
if (!PyArg_ParseTuple(args, "|OO:DirectSoundCreate",
&obGUID, // @pyparm <o PyIID>||guid|The identifier of the interface describing the type of interface pointer to return
&obUnk)) // @pyparm <o PyIUknown>|unk||The IUnknown for COM aggregation.
{
return NULL;
}
if (obUnk)
{
if (!PyCom_InterfaceFromPyInstanceOrObject(obUnk, IID_IUnknown, (void **)&pUnkIn, TRUE))
goto done;
}
if (obGUID && obGUID != Py_None)
{
if (!PyWinObject_AsIID(obGUID, &guid))
goto done;
pguid = &guid;
}
Py_BEGIN_ALLOW_THREADS
hr = ::DirectSoundCreate(pguid, &ds, pUnkIn);
Py_END_ALLOW_THREADS
if (FAILED(hr)) {
PyCom_BuildPyException(hr);
goto done;
}
ret = new PyIDirectSound(ds);
done:
if (pUnkIn)
pUnkIn->Release();
return ret;
}
BOOL CALLBACK dsEnumCallback(LPGUID guid, LPCSTR desc, LPCSTR module, LPVOID context)
{
PyObject *list = (PyObject*)context;
PyObject *item = PyTuple_New(3);
PyObject *oguid;
// abort enumeration if we cannot create a tuple
if (!item)
{
return FALSE;
}
if (guid)
{
oguid = PyWinObject_FromIID(*guid);
}
else
{
Py_INCREF(Py_None);
oguid = Py_None;
}
if (PyTuple_SetItem(item, 0, oguid))
return FALSE;
if (PyTuple_SetItem(item, 1, desc ? PyString_FromString(desc) : PyString_FromString("")))
return FALSE;
if (PyTuple_SetItem(item, 2, module ? PyString_FromString(module) : PyString_FromString("")))
return FALSE;
if (PyList_Append(list, item))
return FALSE;
return TRUE;
}
// @pymethod <o list|directsound|DirectSoundEnumerate|Enumerates DirectSound drivers installed in the system.
static PyObject *directsound_DirectSoundEnumerate(PyObject *, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":DirectSoundEnumerate"))
{
return NULL;
}
PyObject *list = PyList_New(0);
if (!list)
{
return NULL;
}
HRESULT hr;
Py_BEGIN_ALLOW_THREADS
hr = ::DirectSoundEnumerate(dsEnumCallback, list);
Py_END_ALLOW_THREADS
if (PyErr_Occurred())
{
return NULL;
}
if (FAILED(hr)) {
PyCom_BuildPyException(hr);
return NULL;
}
return list;
}
/* List of module functions */
// @module directsound|A module, encapsulating the DirectSound interfaces
static struct PyMethodDef directsound_methods[]=
{
{ "DirectSoundCreate", directsound_DirectSoundCreate, 1 }, // @pymeth DirectSoundCreate|Creates and initializes a new object that supports the IDirectSound interface.
{ "DirectSoundEnumerate", directsound_DirectSoundEnumerate, 1 }, // @pymeth DirectSoundEnumerate|The DirectSoundEnumerate function enumerates the DirectSound drivers installed in the system.
// { "DirectSoundCaptureCreate", directsound_DirectSoundCaptureCreate, 1}, // @pymeth DirectSoundCaptureCreate|The DirectSoundCaptureCreate function creates and initializes an object that supports the IDirectSoundCapture interface
// { "DirectSoundCaptureEnumerate", directsound_DirectSoundCaptureEnumerate, 1}, // @pymeth DirectSoundCaptureEnumerate|The DirectSoundCaptureEnumerate function enumerates the DirectSoundCapture objects installed in the system.
{"DSCAPS", PyWinMethod_NewDSCAPS, 1 }, // @pymeth DSCAPS|Creates a new <o PyDSCAPS> object.
{"DSBCAPS", PyWinMethod_NewDSBCAPS, 1 }, // @pymeth DSBCAPS|Creates a new <o PyDSBCAPS> object.
{"DSBUFFERDESC", PyWinMethod_NewDSBUFFERDESC, 1 }, // @pymeth DSBUFFERDESC|Creates a new <o PyDSBUFFERDESC> object.
{ NULL, NULL },
};
static int AddConstant(PyObject *dict, const char *key, long value)
{
PyObject *oval = PyInt_FromLong(value);
if (!oval)
{
return 1;
}
int rc = PyDict_SetItemString(dict, (char*)key, oval);
Py_DECREF(oval);
return rc;
}
#define ADD_CONSTANT(tok) AddConstant(dict, #tok, tok)
static const PyCom_InterfaceSupportInfo g_interfaceSupportData[] =
{
PYCOM_INTERFACE_CLIENT_ONLY (DirectSound),
PYCOM_INTERFACE_CLIENT_ONLY (DirectSoundBuffer),
PYCOM_INTERFACE_CLIENT_ONLY (DirectSoundNotify),
};
/* Module initialisation */
extern "C" __declspec(dllexport) void initdirectsound()
{
char *modName = "directsound";
PyObject *oModule;
// Create the module and add the functions
oModule = Py_InitModule(modName, directsound_methods);
if (!oModule) /* Eeek - some serious error! */
return;
PyObject *dict = PyModule_GetDict(oModule);
if (!dict) return; /* Another serious error!*/
// Register all of our interfaces, gateways and IIDs.
PyCom_RegisterExtensionSupport(dict, g_interfaceSupportData, sizeof(g_interfaceSupportData)/sizeof(g_interfaceSupportData[0]));
ADD_CONSTANT(DSCAPS_PRIMARYMONO);
ADD_CONSTANT(DSCAPS_PRIMARYSTEREO);
ADD_CONSTANT(DSCAPS_PRIMARY8BIT);
ADD_CONSTANT(DSCAPS_PRIMARY16BIT);
ADD_CONSTANT(DSCAPS_CONTINUOUSRATE);
ADD_CONSTANT(DSCAPS_EMULDRIVER);
ADD_CONSTANT(DSCAPS_CERTIFIED);
ADD_CONSTANT(DSCAPS_SECONDARYMONO);
ADD_CONSTANT(DSCAPS_SECONDARYSTEREO);
ADD_CONSTANT(DSCAPS_SECONDARY8BIT);
ADD_CONSTANT(DSCAPS_SECONDARY16BIT);
ADD_CONSTANT(DSBPLAY_LOOPING); // @const directsound|DSBPLAY_LOOPING|text.
ADD_CONSTANT(DSBSTATUS_PLAYING);
ADD_CONSTANT(DSBSTATUS_BUFFERLOST);
ADD_CONSTANT(DSBSTATUS_LOOPING);
ADD_CONSTANT(DSBLOCK_FROMWRITECURSOR);
ADD_CONSTANT(DSBLOCK_ENTIREBUFFER);
ADD_CONSTANT(DSSCL_NORMAL);
ADD_CONSTANT(DSSCL_PRIORITY);
ADD_CONSTANT(DSSCL_EXCLUSIVE);
ADD_CONSTANT(DSSCL_WRITEPRIMARY);
ADD_CONSTANT(DS3DMODE_NORMAL);
ADD_CONSTANT(DS3DMODE_HEADRELATIVE);
ADD_CONSTANT(DS3DMODE_DISABLE);
ADD_CONSTANT(DSBCAPS_PRIMARYBUFFER);
ADD_CONSTANT(DSBCAPS_STATIC);
ADD_CONSTANT(DSBCAPS_LOCHARDWARE);
ADD_CONSTANT(DSBCAPS_LOCSOFTWARE);
ADD_CONSTANT(DSBCAPS_CTRL3D);
ADD_CONSTANT(DSBCAPS_CTRLFREQUENCY);
ADD_CONSTANT(DSBCAPS_CTRLPAN);
ADD_CONSTANT(DSBCAPS_CTRLVOLUME);
ADD_CONSTANT(DSBCAPS_CTRLPOSITIONNOTIFY);
ADD_CONSTANT(DSBCAPS_CTRLDEFAULT);
ADD_CONSTANT(DSBCAPS_CTRLALL);
ADD_CONSTANT(DSBCAPS_STICKYFOCUS);
ADD_CONSTANT(DSBCAPS_GLOBALFOCUS);
ADD_CONSTANT(DSBCAPS_GETCURRENTPOSITION2);
ADD_CONSTANT(DSBCAPS_MUTE3DATMAXDISTANCE);
ADD_CONSTANT(DSCBCAPS_WAVEMAPPED);
ADD_CONSTANT(DSSPEAKER_HEADPHONE);
ADD_CONSTANT(DSSPEAKER_MONO);
ADD_CONSTANT(DSSPEAKER_QUAD);
ADD_CONSTANT(DSSPEAKER_STEREO);
ADD_CONSTANT(DSSPEAKER_SURROUND);
ADD_CONSTANT(DSSPEAKER_GEOMETRY_MIN);
ADD_CONSTANT(DSSPEAKER_GEOMETRY_NARROW);
ADD_CONSTANT(DSSPEAKER_GEOMETRY_WIDE);
ADD_CONSTANT(DSSPEAKER_GEOMETRY_MAX);
// real macros - todo if can be bothered
// ADD_CONSTANT(DSSPEAKER_COMBINED);
// ADD_CONSTANT(DSSPEAKER_CONFIG);
// ADD_CONSTANT(DSSPEAKER_GEOMETRY);
ADD_CONSTANT(DSBFREQUENCY_MIN);
ADD_CONSTANT(DSBFREQUENCY_MAX);
ADD_CONSTANT(DSBFREQUENCY_ORIGINAL);
ADD_CONSTANT(DSBPAN_LEFT);
ADD_CONSTANT(DSBPAN_CENTER);
ADD_CONSTANT(DSBPAN_RIGHT);
ADD_CONSTANT(DSBVOLUME_MIN);
ADD_CONSTANT(DSBVOLUME_MAX);
ADD_CONSTANT(DSBSIZE_MIN);
ADD_CONSTANT(DSBSIZE_MAX);
ADD_CONSTANT(DSCCAPS_EMULDRIVER);
ADD_CONSTANT(DSCBLOCK_ENTIREBUFFER);
ADD_CONSTANT(DSCBSTATUS_CAPTURING);
ADD_CONSTANT(DSCBSTATUS_LOOPING);
ADD_CONSTANT(DSCBSTART_LOOPING);
ADD_CONSTANT(DSBPN_OFFSETSTOP);
PyDict_SetItemString(dict, "DSCAPSType", (PyObject *)&PyDSCAPSType);
PyDict_SetItemString(dict, "DSBCAPSType", (PyObject *)&PyDSBCAPSType);
PyDict_SetItemString(dict, "DSBUFFERDESCType", (PyObject *)&PyDSBUFFERDESCType);
}
--- NEW FILE: directsound_pch.h ---
// directsound_pch.h : header file for PCH generation for the directsound COM extension
#include <windows.h>
#include <Python.h>
#include <PythonCOM.h>
#include <dsound.h>
/*
** DSBUFFERDESC support
*/
PyObject *PyWinMethod_NewDSBUFFERDESC(PyObject *self, PyObject *args);
PyObject *PyWinObject_FromWAVEFROMATEX(const DSBUFFERDESC &dsbd);
BOOL PyWinObject_AsDSBUFFERDESC(PyObject *ob, DSBUFFERDESC **ppDSBUFFERDESC, BOOL bNoneOK = TRUE);
extern PyTypeObject PyDSBUFFERDESCType;
#define PyDSBUFFERDESC_Check(ob) ((ob)->ob_type == &PyDSBUFFERDESCType)
/*
** DSCAPS support
*/
PyObject *PyWinMethod_NewDSCAPS(PyObject *self, PyObject *args);
PyObject *PyWinObject_FromDSCAPS(const DSBUFFERDESC &dsbd);
BOOL PyWinObject_AsDSCAPS(PyObject *ob, DSCAPS **ppDSCAPS, BOOL bNoneOK = TRUE);
extern PyTypeObject PyDSCAPSType;
#define PyDSCAPS_Check(ob) ((ob)->ob_type == &PyDSCAPSType)
/*
** DSBCAPS support
*/
PyObject *PyWinMethod_NewDSBCAPS(PyObject *self, PyObject *args);
PyObject *PyWinObject_FromDSBCAPS(const DSBUFFERDESC &dsbd);
BOOL PyWinObject_AsDSBCAPS(PyObject *ob, DSBCAPS **ppDSBCAPS, BOOL bNoneOK = TRUE);
extern PyTypeObject PyDSBCAPSType;
#define PyDSBCAPS_Check(ob) ((ob)->ob_type == &PyDSBCAPSType)
class PyDSBUFFERDESC : public PyObject
{
public:
PyDSBUFFERDESC(void);
PyDSBUFFERDESC(const DSBUFFERDESC &);
~PyDSBUFFERDESC();
/* Python support */
static void deallocFunc(PyObject *ob);
static int setattro(PyObject *self, PyObject *obname, PyObject *obvalue);
PyObject *m_obWFX;
#ifdef _MSC_VER
#pragma warning( disable : 4251 )
#endif // _MSC_VER
static struct PyMemberDef members[];
#ifdef _MSC_VER
#pragma warning( default : 4251 )
#endif // _MSC_VER
DSBUFFERDESC m_dsbd;
};
class PyDSCAPS : public PyObject
{
public:
DSCAPS *GetCAPS() {return &m_caps;}
PyDSCAPS(void);
PyDSCAPS(const DSCAPS &);
~PyDSCAPS();
/* Python support */
static void deallocFunc(PyObject *ob);
#ifdef _MSC_VER
#pragma warning( disable : 4251 )
#endif // _MSC_VER
static struct PyMemberDef members[];
#ifdef _MSC_VER
#pragma warning( default : 4251 )
#endif // _MSC_VER
DSCAPS m_caps;
};
class PyDSBCAPS : public PyObject
{
public:
DSBCAPS *GetCAPS() {return &m_caps;}
PyDSBCAPS(void);
PyDSBCAPS(const DSBCAPS &);
~PyDSBCAPS();
/* Python support */
static void deallocFunc(PyObject *ob);
#ifdef _MSC_VER
#pragma warning( disable : 4251 )
#endif // _MSC_VER
static struct PyMemberDef members[];
#ifdef _MSC_VER
#pragma warning( default : 4251 )
#endif // _MSC_VER
DSBCAPS m_caps;
};
--- NEW FILE: PyDSBUFFERDESC.cpp ---
//
// @doc
#include "PyWinTypes.h"
#include "PyWinObjects.h"
#include "PySoundObjects.h"
#include "structmember.h"
#include "directsound_pch.h"
// @pymethod <o PyDSBUFFERDESC>|pywintypes|DSBUFFERDESC|Creates a new DSBUFFERDESC object
PyObject *PyWinMethod_NewDSBUFFERDESC(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":DSBUFFERDESC"))
return NULL;
return new PyDSBUFFERDESC();
}
PyObject *PyWinObject_FromDSBUFFERDESC(const DSBUFFERDESC &dsbd)
{
return new PyDSBUFFERDESC(dsbd);
}
BOOL PyWinObject_AsDSBUFFERDESC(PyObject *ob, DSBUFFERDESC **ppDSBUFFERDESC, BOOL bNoneOK /*= TRUE*/)
{
if (bNoneOK && ob==Py_None) {
*ppDSBUFFERDESC = NULL;
} else if (!PyDSBUFFERDESC_Check(ob)) {
PyErr_SetString(PyExc_TypeError, "The object is not a PyDSBUFFERDESC object");
return FALSE;
} else {
PyDSBUFFERDESC *pydsbd= (PyDSBUFFERDESC *)ob;
*ppDSBUFFERDESC = &pydsbd->m_dsbd;
// in case the PyWAVEFORMATEX has been manipulated and points to a different address now
((DSBUFFERDESC *)*ppDSBUFFERDESC)->lpwfxFormat =
&((PyWAVEFORMATEX *)pydsbd->m_obWFX)->m_wfx;
}
return TRUE;
}
// @object PyDSBUFFERDESC|A Python object, representing a DSBUFFERDESC structure
static struct PyMethodDef PyDSBUFFERDESC_methods[] = {
{NULL}
};
PyTypeObject PyDSBUFFERDESCType =
{
PyObject_HEAD_INIT(&PyType_Type)
0,
"PyDSBUFFERDESC",
sizeof(PyDSBUFFERDESC),
0,
PyDSBUFFERDESC::deallocFunc,
0, // tp_print;
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
0,
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr,
PyDSBUFFERDESC::setattro,
0, // tp_as_buffer;
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags;
0, // tp_doc; /* Documentation string */
0, // traverseproc tp_traverse;
0, // tp_clear;
0, // tp_richcompare;
0, // tp_weaklistoffset;
0, // tp_iter
0, // iternextfunc tp_iternext
0, // methods
PyDSBUFFERDESC::members,
0, // tp_getset;
0, // tp_base;
0, // tp_dict;
0, // tp_descr_get;
0, // tp_descr_set;
0, // tp_dictoffset;
0, // tp_init;
0, // tp_alloc;
0 // newfunc tp_new;
};
#define OFF(e) offsetof(PyDSBUFFERDESC, e)
/*static*/ struct PyMemberDef PyDSBUFFERDESC::members[] = {
{"dwFlags", T_INT, OFF(m_dsbd.dwFlags), 0, "Identifies the capabilities to include when creating a new DirectSoundBuffer object"},
// @prop integer|dwFlags|Identifies the capabilities to include when creating a new DirectSoundBuffer object.
{"dwBufferBytes", T_INT, OFF(m_dsbd.dwBufferBytes), 0, "Size of the new buffer, in bytes. This value must be 0 when creating primary buffers. For secondary buffers, the minimum and maximum sizes allowed are specified by DSBSIZE_MIN and DSBSIZE_MAX"},
// @prop integer|dwBufferBytes|Size of the new buffer, in bytes. This value must be 0 when creating primary buffers. For secondary buffers, the minimum and maximum sizes allowed are specified by DSBSIZE_MIN and DSBSIZE_MAX.
{"lpwfxFormat", T_OBJECT, OFF(m_obWFX), 0, "Structure specifying the waveform format for the buffer. This value must be None for primary buffers. The application can use IDirectSoundBuffer::SetFormat to set the format of the primary buffer."},
// @prop WAVEFORMATEX|lpwfxFormat|Structure specifying the waveform format for the buffer. This value must be None for primary buffers. The application can use IDirectSoundBuffer::SetFormat to set the format of the primary buffer.
{NULL} /* Sentinel */
};
PyDSBUFFERDESC::PyDSBUFFERDESC(void)
{
ob_type = &PyDSBUFFERDESCType;
_Py_NewReference(this);
memset(&m_dsbd, 0, sizeof(m_dsbd));
m_dsbd.dwSize = sizeof(DSBUFFERDESC);
Py_INCREF(Py_None);
m_obWFX = Py_None;
}
PyDSBUFFERDESC::PyDSBUFFERDESC(const DSBUFFERDESC &dsbd)
{
m_dsbd.dwSize = sizeof(DSBUFFERDESC);
ob_type = &PyDSBUFFERDESCType;
_Py_NewReference(this);
m_dsbd = dsbd;
if (dsbd.lpwfxFormat) {
m_obWFX = new PyWAVEFORMATEX(*dsbd.lpwfxFormat);
m_dsbd.lpwfxFormat = &((PyWAVEFORMATEX*)m_obWFX)->m_wfx;
}
else {
Py_INCREF(Py_None);
m_obWFX = Py_None;
}
}
PyDSBUFFERDESC::~PyDSBUFFERDESC()
{
Py_XDECREF( m_obWFX );
}
/*static*/ void PyDSBUFFERDESC::deallocFunc(PyObject *ob)
{
delete (PyDSBUFFERDESC *)ob;
}
int PyDSBUFFERDESC::setattro(PyObject *self, PyObject *obname, PyObject *obvalue)
{
PyDSBUFFERDESC *obself = (PyDSBUFFERDESC*)self;
char *name=PyString_AsString(obname);
if (name==NULL)
return -1;
if (strcmp(name,"lpwfxFormat") == 0) {
if (obvalue == Py_None)
{
obself->m_dsbd.lpwfxFormat = NULL;
}
else if (!PyWAVEFORMATEX_Check(obvalue)) {
PyErr_SetString(PyExc_ValueError,"lpwfxFormat must be a WAVEFORMATEX instance");
return -1;
}
else {
obself->m_dsbd.lpwfxFormat = &((PyWAVEFORMATEX*)obvalue)->m_wfx;
}
}
return PyObject_GenericSetAttr(self, obname, obvalue);
}
--- NEW FILE: PyIDirectSoundNotify.h ---
// This file declares the IDirectSoundNotify Interface for Python.
// ---------------------------------------------------
//
// Interface Declaration
class PyIDirectSoundNotify : public PyIUnknown
{
public:
MAKE_PYCOM_CTOR(PyIDirectSoundNotify);
static IDirectSoundNotify *GetI(PyObject *self);
static PyComTypeObject type;
// The Python methods
static PyObject *SetNotificationPositions(PyObject *self, PyObject *args);
PyIDirectSoundNotify(IUnknown *pdisp);
~PyIDirectSoundNotify();
PyObject *m_DS;
};
--- NEW FILE: PyDSBCAPS.cpp ---
//
// @doc
#include "PyWinTypes.h"
#include "PyWinObjects.h"
#include "structmember.h"
#include "directsound_pch.h"
// @pymethod <o PyDSBCAPS>|pywintypes|DSBCAPS|Creates a new DSBCAPS object
PyObject *PyWinMethod_NewDSBCAPS(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":DSBCAPS"))
return NULL;
return new PyDSBCAPS();
}
PyObject *PyWinObject_FromDSBCAPS(const DSBCAPS &caps)
{
return new PyDSBCAPS(caps);
}
BOOL PyWinObject_AsDSBCAPS(PyObject *ob, DSBCAPS **ppDSBCAPS, BOOL bNoneOK /*= TRUE*/)
{
if (bNoneOK && ob==Py_None) {
*ppDSBCAPS = NULL;
} else if (!PyDSBCAPS_Check(ob)) {
PyErr_SetString(PyExc_TypeError, "The object is not a PyDSBCAPS object");
return FALSE;
} else {
PyDSBCAPS *pycaps= (PyDSBCAPS *)ob;
*ppDSBCAPS = pycaps->GetCAPS();
}
return TRUE;
}
// @object PyDSBCAPS|A Python object, representing a DSBCAPS structure
static struct PyMethodDef PyDSBCAPS_methods[] = {
{NULL}
};
PyTypeObject PyDSBCAPSType =
{
PyObject_HEAD_INIT(&PyType_Type)
0,
"PyDSBCAPS",
sizeof(PyDSBCAPS),
0,
PyDSBCAPS::deallocFunc,
0, // tp_print;
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
0,
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr,
PyObject_GenericSetAttr,
0, // tp_as_buffer;
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags;
0, // tp_doc; /* Documentation string */
0, // traverseproc tp_traverse;
0, // tp_clear;
0, // tp_richcompare;
0, // tp_weaklistoffset;
0, // tp_iter
0, // iternextfunc tp_iternext
0, // methods
PyDSBCAPS::members,
0, // tp_getset;
0, // tp_base;
0, // tp_dict;
0, // tp_descr_get;
0, // tp_descr_set;
0, // tp_dictoffset;
0, // tp_init;
0, // tp_alloc;
0 // newfunc tp_new;
};
#define OFF(e) offsetof(PyDSBCAPS, e)
/*static*/ struct PyMemberDef PyDSBCAPS::members[] = {
{"dwFlags", T_INT, OFF(m_caps.dwFlags), 0, "Flags that specify buffer-object capabilities."}, // @prop integer|dwFlags|Flags that specify buffer-object capabilities.
{"dwBufferBytes", T_INT, OFF(m_caps.dwBufferBytes), 0, "Size of the buffer, in bytes"}, // @prop integer|nChannels|Size of the buffer, in bytes.
{"dwUnlockTransferRate", T_INT, OFF(m_caps.dwUnlockTransferRate), 0,
"Specifies the rate, in kilobytes per second, at which data is transferred to the buffer memory when IDirectSoundBuffer::Update is called. High-performance applications can use this value to determine the time required for IDirectSoundBuffer::Update to execute. For software buffers located in system memory, the rate will be very high because no processing is required. For hardware buffers, the rate might be slower because the buffer might have to be downloaded to the sound card, which might have a limited transfer rate."},
// @prop integer|dwUnlockTransferRate|Specifies the rate, in kilobytes per second, at which data is transferred to the buffer memory when IDirectSoundBuffer::Unlock is called. High-performance applications can use this value to determine the time required for IDirectSoundBuffer::Unlock to execute. For software buffers located in system memory, the rate will be very high because no processing is required. For hardware buffers, the rate might be slower because the buffer might have to be downloaded to the sound card, which might have a limited transfer rate.
{"dwPlayCpuOverhead", T_INT, OFF(m_caps.dwPlayCpuOverhead)}, // @prop integer|nAvgBytesPerSec|Specifies whether the returned handle is inherited when a new process is created. If this member is TRUE, the new process inherits the handle.
{NULL} /* Sentinel */
};
PyDSBCAPS::PyDSBCAPS(void)
{
ob_type = &PyDSBCAPSType;
_Py_NewReference(this);
memset(&m_caps, 0, sizeof(m_caps));
m_caps.dwSize = sizeof(DSBCAPS);
}
PyDSBCAPS::PyDSBCAPS(const DSBCAPS &caps)
{
ob_type = &PyDSBCAPSType;
_Py_NewReference(this);
m_caps = caps;
m_caps.dwSize = sizeof(DSBCAPS);
}
PyDSBCAPS::~PyDSBCAPS()
{
}
/*static*/ void PyDSBCAPS::deallocFunc(PyObject *ob)
{
delete (PyDSBCAPS *)ob;
}
--- NEW FILE: PyIDirectSoundNotify.cpp ---
// This file implements the IDirectSoundNotify Interface for Python.
#include "directsound_pch.h"
#include "PySoundObjects.h"
#include "PyIDirectSoundNotify.h"
// @doc - This file contains autoduck documentation
// ---------------------------------------------------
//
// Interface Implementation
PyIDirectSoundNotify::PyIDirectSoundNotify(IUnknown *pdisp):
PyIUnknown(pdisp), m_DS(NULL)
{
ob_type = &type;
}
PyIDirectSoundNotify::~PyIDirectSoundNotify()
{
// Release should be called before IDirectSound::Release, which may be
// triggered below
SafeRelease(this);
// This may trigger IDirectSOund::Release
if (m_DS)
Py_DECREF(m_DS);
}
/* static */ IDirectSoundNotify *PyIDirectSoundNotify::GetI(PyObject *self)
{
return (IDirectSoundNotify*)PyIUnknown::GetI(self);
}
static BOOL unpack(PyObject *tuple, DSBPOSITIONNOTIFY *¬ify, int pos)
{
if (!PyTuple_Check(tuple) || PyTuple_Size(tuple) < 2)
return FALSE;
PyObject *o0 = PyTuple_GET_ITEM(tuple, 0);
PyObject *o1 = PyTuple_GET_ITEM(tuple, 1);
if (!o0 || !PyInt_Check(o0) || !o1 || !PyHANDLE_Check(o1))
return FALSE;
notify[pos].dwOffset = PyInt_AS_LONG(o0);
if (!PyWinObject_AsHANDLE(o1, ¬ify[pos].hEventNotify))
return FALSE;
return TRUE;
}
// @pymethod |PyIDirectSoundNotify|SetNotificationPositions|Description of GetCaps.
PyObject *PyIDirectSoundNotify::SetNotificationPositions(PyObject *self, PyObject *args)
{
int i;
PyObject *obPos = NULL;
IDirectSoundNotify *pIDSB = GetI(self);
if ( pIDSB == NULL )
return NULL;
if ( !PyArg_ParseTuple(args, "O:SetNotificationPositions", &obPos) )
return NULL;
int size = 0;
DSBPOSITIONNOTIFY *notify = NULL;
if (PyTuple_Check(obPos)){
size = PyTuple_Size(obPos);
if (size < 1)
goto argerror;
if (PyTuple_Check(PyTuple_GET_ITEM(obPos, 0))) {
// nested tuples
notify = new DSBPOSITIONNOTIFY[size];
for (i = 0; i < size; ++i) {
if (!unpack(PyTuple_GET_ITEM(obPos, i), notify, i))
goto argerror;
}
}
else {
notify = new DSBPOSITIONNOTIFY[1];
size = 1;
if (!unpack(obPos, notify, 0))
goto argerror;
}
}
else if (PyList_Check(obPos)) {
size = PyList_Size(obPos);
if (size < 1)
goto argerror;
notify = new DSBPOSITIONNOTIFY[size];
for (i = 0; i < size; ++i) {
if (!unpack(PyList_GET_ITEM(obPos, i), notify, i))
goto argerror;
}
}
else
goto argerror;
HRESULT hr;
{
PY_INTERFACE_PRECALL;
hr = pIDSB->SetNotificationPositions(size, notify);
PY_INTERFACE_POSTCALL;
}
delete[] notify;
if (FAILED(hr)) {
PyWin_SetAPIError("SetNotificationPositions", hr);
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
argerror:
delete[] notify;
PyErr_SetString(PyExc_TypeError, "Argument must be a tuple (or a list of tuples) with two items: position and win32 Event handle");
return NULL;
}
// @object PyIDirectSoundNotify|Description of the interface
static struct PyMethodDef PyIDirectSoundNotify_methods[] =
{
{ "SetNotificationPositions", PyIDirectSoundNotify::SetNotificationPositions, 1 }, // @pymeth Initialize|Description of SetNotificationPositions.
{ NULL }
};
PyComTypeObject PyIDirectSoundNotify::type("PyIDirectSoundNotify",
&PyIUnknown::type,
sizeof(PyIDirectSoundNotify),
PyIDirectSoundNotify_methods,
GET_PYCOM_CTOR(PyIDirectSoundNotify));
|