816 lines
28 KiB
C
816 lines
28 KiB
C
/* IDirectMusicSegment8 Implementation
|
|
*
|
|
* Copyright (C) 2003 Rok Mandeljc
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
#include "winuser.h"
|
|
#include "wingdi.h"
|
|
#include "wine/debug.h"
|
|
|
|
#include "dmime_private.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
|
|
WINE_DECLARE_DEBUG_CHANNEL(dmfile);
|
|
|
|
/*****************************************************************************
|
|
* IDirectMusicSegment8Impl implementation
|
|
*/
|
|
/* IDirectMusicSegment8 IUnknown part: */
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_QueryInterface (LPDIRECTMUSICSEGMENT8 iface, REFIID riid, LPVOID *ppobj)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
if (IsEqualIID (riid, &IID_IUnknown) ||
|
|
IsEqualIID (riid, &IID_IDirectMusicSegment) ||
|
|
IsEqualIID (riid, &IID_IDirectMusicSegment8)) {
|
|
IDirectMusicSegment8Impl_AddRef(iface);
|
|
*ppobj = This;
|
|
return S_OK;
|
|
}
|
|
|
|
WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
ULONG WINAPI IDirectMusicSegment8Impl_AddRef (LPDIRECTMUSICSEGMENT8 iface)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
TRACE("(%p) : AddRef from %ld\n", This, This->ref);
|
|
return ++(This->ref);
|
|
}
|
|
|
|
ULONG WINAPI IDirectMusicSegment8Impl_Release (LPDIRECTMUSICSEGMENT8 iface)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
ULONG ref = --This->ref;
|
|
TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
|
|
if (ref == 0) {
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
}
|
|
return ref;
|
|
}
|
|
|
|
/* IDirectMusicSegment8 IDirectMusicSegment part: */
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_GetLength (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtLength)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
TRACE("(%p, %p)\n", This, pmtLength);
|
|
*pmtLength = This->segHeader.mtLength;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_SetLength (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtLength)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
TRACE("(%p, %ld)\n", This, mtLength);
|
|
This->segHeader.mtLength = mtLength;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_GetRepeats (LPDIRECTMUSICSEGMENT8 iface, DWORD* pdwRepeats)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
TRACE("(%p, %p)\n", This, pdwRepeats);
|
|
*pdwRepeats = This->segHeader.dwRepeats;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_SetRepeats (LPDIRECTMUSICSEGMENT8 iface, DWORD dwRepeats)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
TRACE("(%p, %ld)\n", This, dwRepeats);
|
|
This->segHeader.dwRepeats = dwRepeats;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_GetDefaultResolution (LPDIRECTMUSICSEGMENT8 iface, DWORD* pdwResolution)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
TRACE("(%p, %p)\n", This, pdwResolution);
|
|
*pdwResolution = This->segHeader.dwResolution;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_SetDefaultResolution (LPDIRECTMUSICSEGMENT8 iface, DWORD dwResolution)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
TRACE("(%p, %ld)\n", This, dwResolution);
|
|
This->segHeader.dwResolution = dwResolution;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_GetTrack (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, IDirectMusicTrack** ppTrack)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %s, %ld, %ld, %p): stub\n", This, debugstr_guid(rguidType), dwGroupBits, dwIndex, ppTrack);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_GetTrackGroup (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack, DWORD* pdwGroupBits)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %p, %p): stub\n", This, pTrack, pdwGroupBits);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_InsertTrack (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack, DWORD dwGroupBits)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %p, %ld): stub\n", This, pTrack, dwGroupBits);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_RemoveTrack (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %p): stub\n", This, pTrack);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_InitPlay (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicSegmentState** ppSegState, IDirectMusicPerformance* pPerformance, DWORD dwFlags)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %p, %p, %ld): stub\n", This, ppSegState, pPerformance, dwFlags);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_GetGraph (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicGraph** ppGraph)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %p): stub\n", This, ppGraph);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_SetGraph (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicGraph* pGraph)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %p): stub\n", This, pGraph);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_AddNotificationType (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidNotificationType)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %s): stub\n", This, debugstr_guid(rguidNotificationType));
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_RemoveNotificationType (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidNotificationType)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %s): stub\n", This, debugstr_guid(rguidNotificationType));
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_GetParam (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, MUSIC_TIME* pmtNext, void* pParam)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %s, %ld, %ld, %ld, %p, %p): stub\n", This, debugstr_guid(rguidType), dwGroupBits, dwIndex, mtTime, pmtNext, pParam);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_SetParam (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, void* pParam)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %s, %ld, %ld, %ld, %p): stub\n", This, debugstr_guid(rguidType), dwGroupBits, dwIndex, mtTime, pParam);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_Clone (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart, MUSIC_TIME mtEnd, IDirectMusicSegment** ppSegment)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %ld, %ld, %p): stub\n", This, mtStart, mtEnd, ppSegment);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_SetStartPoint (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
TRACE("(%p, %ld): stub\n", This, mtStart);
|
|
This->segHeader.mtPlayStart = mtStart;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_GetStartPoint (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtStart)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
TRACE("(%p, %p): stub\n", This, pmtStart);
|
|
*pmtStart = This->segHeader.mtPlayStart;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_SetLoopPoints (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart, MUSIC_TIME mtEnd)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
TRACE("(%p, %ld, %ld): stub\n", This, mtStart, mtEnd);
|
|
This->segHeader.mtLoopStart = mtStart;
|
|
This->segHeader.mtLoopEnd = mtEnd;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_GetLoopPoints (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtStart, MUSIC_TIME* pmtEnd)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
TRACE("(%p, %p, %p): stub\n", This, pmtStart, pmtEnd);
|
|
*pmtStart = This->segHeader.mtLoopStart;
|
|
*pmtEnd = This->segHeader.mtLoopEnd;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_SetPChannelsUsed (LPDIRECTMUSICSEGMENT8 iface, DWORD dwNumPChannels, DWORD* paPChannels)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %ld, %p): stub\n", This, dwNumPChannels, paPChannels);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/* IDirectMusicSegment8 IDirectMusicSegment8 part: */
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_SetTrackConfig (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidTrackClassID, DWORD dwGroupBits, DWORD dwIndex, DWORD dwFlagsOn, DWORD dwFlagsOff)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %s, %ld, %ld, %ld, %ld): stub\n", This, debugstr_guid(rguidTrackClassID), dwGroupBits, dwIndex, dwFlagsOn, dwFlagsOff);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_GetAudioPathConfig (LPDIRECTMUSICSEGMENT8 iface, IUnknown** ppAudioPathConfig)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %p): stub\n", This, ppAudioPathConfig);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_Compose (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtTime, IDirectMusicSegment* pFromSegment, IDirectMusicSegment* pToSegment, IDirectMusicSegment** ppComposedSegment)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %ld, %p, %p, %p): stub\n", This, mtTime, pFromSegment, pToSegment, ppComposedSegment);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_Download (LPDIRECTMUSICSEGMENT8 iface, IUnknown *pAudioPath)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %p): stub\n", This, pAudioPath);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegment8Impl_Unload (LPDIRECTMUSICSEGMENT8 iface, IUnknown *pAudioPath)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegment8Impl,iface);
|
|
|
|
FIXME("(%p, %p): stub\n", This, pAudioPath);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
ICOM_VTABLE(IDirectMusicSegment8) DirectMusicSegment8_Vtbl =
|
|
{
|
|
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
|
IDirectMusicSegment8Impl_QueryInterface,
|
|
IDirectMusicSegment8Impl_AddRef,
|
|
IDirectMusicSegment8Impl_Release,
|
|
IDirectMusicSegment8Impl_GetLength,
|
|
IDirectMusicSegment8Impl_SetLength,
|
|
IDirectMusicSegment8Impl_GetRepeats,
|
|
IDirectMusicSegment8Impl_SetRepeats,
|
|
IDirectMusicSegment8Impl_GetDefaultResolution,
|
|
IDirectMusicSegment8Impl_SetDefaultResolution,
|
|
IDirectMusicSegment8Impl_GetTrack,
|
|
IDirectMusicSegment8Impl_GetTrackGroup,
|
|
IDirectMusicSegment8Impl_InsertTrack,
|
|
IDirectMusicSegment8Impl_RemoveTrack,
|
|
IDirectMusicSegment8Impl_InitPlay,
|
|
IDirectMusicSegment8Impl_GetGraph,
|
|
IDirectMusicSegment8Impl_SetGraph,
|
|
IDirectMusicSegment8Impl_AddNotificationType,
|
|
IDirectMusicSegment8Impl_RemoveNotificationType,
|
|
IDirectMusicSegment8Impl_GetParam,
|
|
IDirectMusicSegment8Impl_SetParam,
|
|
IDirectMusicSegment8Impl_Clone,
|
|
IDirectMusicSegment8Impl_SetStartPoint,
|
|
IDirectMusicSegment8Impl_GetStartPoint,
|
|
IDirectMusicSegment8Impl_SetLoopPoints,
|
|
IDirectMusicSegment8Impl_GetLoopPoints,
|
|
IDirectMusicSegment8Impl_SetPChannelsUsed,
|
|
IDirectMusicSegment8Impl_SetTrackConfig,
|
|
IDirectMusicSegment8Impl_GetAudioPathConfig,
|
|
IDirectMusicSegment8Impl_Compose,
|
|
IDirectMusicSegment8Impl_Download,
|
|
IDirectMusicSegment8Impl_Unload
|
|
};
|
|
|
|
/* for ClassFactory */
|
|
HRESULT WINAPI DMUSIC_CreateDirectMusicSegment (LPCGUID lpcGUID, LPDIRECTMUSICSEGMENT8 *ppDMSeg, LPUNKNOWN pUnkOuter)
|
|
{
|
|
IDirectMusicSegment8Impl *segment;
|
|
|
|
TRACE("(%p,%p,%p)\n", lpcGUID, ppDMSeg, pUnkOuter);
|
|
if (IsEqualIID (lpcGUID, &IID_IDirectMusicSegment)
|
|
|| IsEqualIID (lpcGUID, &IID_IDirectMusicSegment2)
|
|
|| IsEqualIID (lpcGUID, &IID_IDirectMusicSegment8)) {
|
|
segment = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicSegment8Impl));
|
|
if (NULL == segment) {
|
|
*ppDMSeg = (LPDIRECTMUSICSEGMENT8) NULL;
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
segment->lpVtbl = &DirectMusicSegment8_Vtbl;
|
|
segment->ref = 1;
|
|
*ppDMSeg = (LPDIRECTMUSICSEGMENT8) segment;
|
|
return S_OK;
|
|
}
|
|
|
|
WARN("No interface found\n");
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
* IDirectMusicSegmentObject implementation
|
|
*/
|
|
/* IDirectMusicSegmentObject IUnknown part: */
|
|
HRESULT WINAPI IDirectMusicSegmentObject_QueryInterface (LPDIRECTMUSICOBJECT iface, REFIID riid, LPVOID *ppobj)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegmentObject,iface);
|
|
|
|
if (IsEqualGUID(riid, &IID_IUnknown)
|
|
|| IsEqualGUID(riid, &IID_IDirectMusicObject)) {
|
|
IDirectMusicSegmentObject_AddRef(iface);
|
|
*ppobj = This;
|
|
return S_OK;
|
|
} else if (IsEqualGUID (riid, &IID_IPersistStream)) {
|
|
IDirectMusicSegmentObjectStream_AddRef ((LPPERSISTSTREAM)This->pStream);
|
|
*ppobj = This->pStream;
|
|
return S_OK;
|
|
} else if (IsEqualGUID (riid, &IID_IDirectMusicSegment)
|
|
|| IsEqualGUID (riid, &IID_IDirectMusicSegment8)) {
|
|
IDirectMusicSegment8Impl_AddRef ((LPDIRECTMUSICSEGMENT8)This->pSegment);
|
|
*ppobj = This->pSegment;
|
|
return S_OK;
|
|
}
|
|
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
ULONG WINAPI IDirectMusicSegmentObject_AddRef (LPDIRECTMUSICOBJECT iface)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegmentObject,iface);
|
|
TRACE("(%p) : AddRef from %ld\n", This, This->ref);
|
|
return ++(This->ref);
|
|
}
|
|
|
|
ULONG WINAPI IDirectMusicSegmentObject_Release (LPDIRECTMUSICOBJECT iface)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegmentObject,iface);
|
|
ULONG ref = --This->ref;
|
|
TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
|
|
if (ref == 0)
|
|
{
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
}
|
|
return ref;
|
|
}
|
|
|
|
/* IDirectMusicSegmentObject IDirectMusicObject part: */
|
|
HRESULT WINAPI IDirectMusicSegmentObject_GetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegmentObject,iface);
|
|
|
|
TRACE("(%p, %p)\n", This, pDesc);
|
|
pDesc = This->pDesc;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegmentObject_SetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegmentObject,iface);
|
|
|
|
TRACE("(%p, %p)\n", This, pDesc);
|
|
This->pDesc = pDesc;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegmentObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface, LPSTREAM pStream, LPDMUS_OBJECTDESC pDesc)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegmentObject,iface);
|
|
|
|
FIXME("(%p, %p, %p): stub\n", This, pStream, pDesc);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
ICOM_VTABLE(IDirectMusicObject) DirectMusicSegmentObject_Vtbl =
|
|
{
|
|
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
|
IDirectMusicSegmentObject_QueryInterface,
|
|
IDirectMusicSegmentObject_AddRef,
|
|
IDirectMusicSegmentObject_Release,
|
|
IDirectMusicSegmentObject_GetDescriptor,
|
|
IDirectMusicSegmentObject_SetDescriptor,
|
|
IDirectMusicSegmentObject_ParseDescriptor
|
|
};
|
|
|
|
/* for ClassFactory */
|
|
HRESULT WINAPI DMUSIC_CreateDirectMusicSegmentObject (LPCGUID lpcGUID, LPDIRECTMUSICOBJECT* ppObject, LPUNKNOWN pUnkOuter)
|
|
{
|
|
IDirectMusicSegmentObject *obj;
|
|
|
|
TRACE("(%p,%p,%p)\n", lpcGUID, ppObject, pUnkOuter);
|
|
if (IsEqualGUID (lpcGUID, &IID_IDirectMusicObject)) {
|
|
obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicSegmentObject));
|
|
if (NULL == obj) {
|
|
*ppObject = (LPDIRECTMUSICOBJECT) NULL;
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
obj->lpVtbl = &DirectMusicSegmentObject_Vtbl;
|
|
obj->ref = 1;
|
|
/* prepare IPersistStream */
|
|
obj->pStream = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicSegmentObjectStream));
|
|
obj->pStream->lpVtbl = &DirectMusicSegmentObjectStream_Vtbl;
|
|
obj->pStream->ref = 1;
|
|
obj->pStream->pParentObject = obj;
|
|
/* prepare IDirectMusicSegment8 */
|
|
DMUSIC_CreateDirectMusicSegment (&IID_IDirectMusicSegment8, (LPDIRECTMUSICSEGMENT8*)&obj->pSegment, NULL);
|
|
obj->pSegment->pObject = obj;
|
|
*ppObject = (LPDIRECTMUSICOBJECT) obj;
|
|
return S_OK;
|
|
}
|
|
WARN("No interface found\n");
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* IDirectMusicSegmentObjectStream implementation
|
|
*/
|
|
/* IDirectMusicSegmentObjectStream IUnknown part: */
|
|
HRESULT WINAPI IDirectMusicSegmentObjectStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegmentObjectStream,iface);
|
|
|
|
if (IsEqualGUID(riid, &IID_IUnknown)
|
|
|| IsEqualGUID(riid, &IID_IPersistStream)) {
|
|
IDirectMusicSegmentObjectStream_AddRef (iface);
|
|
*ppobj = This;
|
|
return S_OK;
|
|
}
|
|
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
ULONG WINAPI IDirectMusicSegmentObjectStream_AddRef (LPPERSISTSTREAM iface)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegmentObjectStream,iface);
|
|
TRACE("(%p) : AddRef from %ld\n", This, This->ref);
|
|
return ++(This->ref);
|
|
}
|
|
|
|
ULONG WINAPI IDirectMusicSegmentObjectStream_Release (LPPERSISTSTREAM iface)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegmentObjectStream,iface);
|
|
ULONG ref = --This->ref;
|
|
TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
|
|
if (ref == 0)
|
|
{
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
}
|
|
return ref;
|
|
}
|
|
|
|
/* IDirectMusicSegmentObjectStream IPersist part: */
|
|
HRESULT WINAPI IDirectMusicSegmentObjectStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/* IDirectMusicSegmentObjectStream IPersistStream part: */
|
|
HRESULT WINAPI IDirectMusicSegmentObjectStream_IsDirty (LPPERSISTSTREAM iface)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegmentObjectStream_Load (LPPERSISTSTREAM iface, IStream* pStm)
|
|
{
|
|
ICOM_THIS(IDirectMusicSegmentObjectStream,iface);
|
|
FOURCC chunkID;
|
|
DWORD chunkSize, StreamSize, StreamCount, ListSize[10], ListCount[10];
|
|
LARGE_INTEGER liMove; /* used when skipping chunks */
|
|
IDirectMusicSegment8Impl* pSegment = This->pParentObject->pSegment; /* that's where we load data */
|
|
DMUS_IO_TRACK_HEADER tempHeader;
|
|
DMUS_IO_TRACK_EXTRAS_HEADER tempXHeader;
|
|
|
|
IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
|
|
IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
|
|
TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID), chunkSize);
|
|
switch (chunkID)
|
|
{
|
|
case FOURCC_RIFF: {
|
|
IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
|
|
TRACE_(dmfile)(": RIFF chunk containing %s", debugstr_fourcc (chunkID));
|
|
StreamSize = chunkSize - sizeof(FOURCC);
|
|
StreamCount = 0;
|
|
switch (chunkID)
|
|
{
|
|
case DMUS_FOURCC_SEGMENT_FORM: {
|
|
TRACE_(dmfile)(": segment form\n");
|
|
do {
|
|
IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
|
|
IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
|
|
StreamCount += sizeof (FOURCC) + sizeof (DWORD) + chunkSize;
|
|
TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID), chunkSize);
|
|
switch (chunkID) {
|
|
case DMUS_FOURCC_SEGMENT_CHUNK: {
|
|
TRACE_(dmfile)(": segment header chunk\n");
|
|
IStream_Read (pStm, &pSegment->segHeader, chunkSize, NULL);
|
|
break;
|
|
}
|
|
case DMUS_FOURCC_GUID_CHUNK: {
|
|
TRACE_(dmfile)(": GUID chunk\n");
|
|
IStream_Read (pStm, &pSegment->vVersion, chunkSize, NULL);
|
|
break;
|
|
}
|
|
case DMUS_FOURCC_VERSION_CHUNK: {
|
|
TRACE_(dmfile)(": version chunk\n");
|
|
IStream_Read (pStm, &pSegment->guidID, chunkSize, NULL);
|
|
break;
|
|
}
|
|
case FOURCC_LIST: {
|
|
IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
|
|
TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(chunkID));
|
|
ListSize[0] = chunkSize - sizeof(FOURCC);
|
|
ListCount[0] = 0;
|
|
switch (chunkID) {
|
|
case DMUS_FOURCC_UNFO_LIST: {
|
|
TRACE_(dmfile)(": UNFO list\n");
|
|
do {
|
|
IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
|
|
IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
|
|
ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
|
|
TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID), chunkSize);
|
|
switch (chunkID) {
|
|
case DMUS_FOURCC_UNAM_CHUNK: {
|
|
TRACE_(dmfile)(": name chunk\n");
|
|
pSegment->wszName = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, chunkSize);
|
|
IStream_Read (pStm, pSegment->wszName, chunkSize, NULL);
|
|
break;
|
|
}
|
|
case DMUS_FOURCC_UART_CHUNK: {
|
|
TRACE_(dmfile)(": artist chunk\n");
|
|
pSegment->wszArtist = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, chunkSize);
|
|
IStream_Read (pStm, pSegment->wszArtist, chunkSize, NULL);
|
|
break;
|
|
}
|
|
case DMUS_FOURCC_UCOP_CHUNK: {
|
|
TRACE_(dmfile)(": copyright chunk\n");
|
|
pSegment->wszCopyright = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, chunkSize);
|
|
IStream_Read (pStm, pSegment->wszCopyright, chunkSize, NULL);
|
|
break;
|
|
}
|
|
case DMUS_FOURCC_USBJ_CHUNK: {
|
|
TRACE_(dmfile)(": subject chunk\n");
|
|
pSegment->wszSubject = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, chunkSize);
|
|
IStream_Read (pStm, pSegment->wszSubject, chunkSize, NULL);
|
|
break;
|
|
}
|
|
case DMUS_FOURCC_UCMT_CHUNK: {
|
|
TRACE_(dmfile)(": comment chunk\n");
|
|
pSegment->wszComment = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, chunkSize);
|
|
IStream_Read (pStm, pSegment->wszComment, chunkSize, NULL);
|
|
break;
|
|
}
|
|
default: {
|
|
TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
|
|
liMove.QuadPart = chunkSize;
|
|
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
|
|
break;
|
|
}
|
|
}
|
|
TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
|
|
} while (ListCount[0] < ListSize[0]);
|
|
break;
|
|
}
|
|
case DMUS_FOURCC_TRACK_LIST: {
|
|
TRACE_(dmfile)(": track list\n");
|
|
do {
|
|
IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
|
|
IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
|
|
ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
|
|
TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID), chunkSize);
|
|
switch (chunkID)
|
|
{
|
|
case FOURCC_RIFF: {
|
|
TRACE_(dmfile)(": RIFF chunk");
|
|
IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
|
|
switch (chunkID)
|
|
{
|
|
case DMUS_FOURCC_TRACK_FORM: {
|
|
TRACE_(dmfile)(": containing %s: track form\n", debugstr_fourcc(chunkID));
|
|
ListSize[1] = chunkSize - sizeof(FOURCC);
|
|
ListCount[1] = 0;
|
|
do {
|
|
IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
|
|
IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
|
|
ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
|
|
TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID), chunkSize);
|
|
switch (chunkID) {
|
|
case DMUS_FOURCC_TRACK_CHUNK: {
|
|
TRACE_(dmfile)(": track header chunk\n");
|
|
IStream_Read (pStm, &tempHeader, chunkSize, NULL);
|
|
break;
|
|
}
|
|
case DMUS_FOURCC_TRACK_EXTRAS_CHUNK: {
|
|
TRACE_(dmfile)(": track extra header chunk\n");
|
|
IStream_Read (pStm, &tempXHeader, chunkSize, NULL);
|
|
break;
|
|
}
|
|
/* add other stuff (look at note below) */
|
|
default: {
|
|
TRACE_(dmfile)(": unknown chunk (skipping)\n");
|
|
liMove.QuadPart = chunkSize;
|
|
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
|
|
break;
|
|
}
|
|
}
|
|
TRACE_(dmfile)(": ListCount[1] = %ld < ListSize[1] = %ld\n", ListCount[1], ListSize[1]);
|
|
} while (ListCount[1] < ListSize[1]);
|
|
FIXME(": loading tracks not supported yet\n");
|
|
/* sigh... now comes track creation... currently I have some problems with implementing
|
|
this one because my test are contradicting:
|
|
- tracks are not loaded by loader (at least my dxdiag test with native dmime doesn't show it)
|
|
therefore i guess they're created with CoCreateInstance with CLSID specified in header and
|
|
IID_IDirectMusicTrack(8). Tracks are then probably passed to IDirectMusicSegment_Insert
|
|
(not quite sure, but behaviour complies with the one described in MSDN (about calling IDirectMusicTrack_Init)
|
|
- but on the other hand, track's stream implementation gets only <data> chunk (look in MSDN for more info)
|
|
(tested with native dmime and builtin dmband and dmstyle) => this means that all info about track (header, extra header
|
|
UNFO, GUID and version are read by segment's stream... now, how the hell is all this info set on track?!
|
|
=> I believe successful approach would be to create structure like this:
|
|
_DMUSIC_PRIVATE_TRACK_ENTRY {
|
|
DMUS_IO_TRACK_HEADER trkHeader;
|
|
DMUS_IO_TRACK_EXTRAS_HEADER trkXHeader;
|
|
WCHAR* name, ...;
|
|
GUID guidID;
|
|
DMUS_VERSION vVersion;
|
|
...
|
|
IDirectMusicTrack* pTrack;
|
|
} DMUSIC_PRIVATE_TRACK_ENTRY;
|
|
and then load all stuff into it
|
|
=> anyway, I'll try to implement it when I find some time again, but this note is here for anyone that wants to give it a try :)
|
|
*/
|
|
break;
|
|
}
|
|
default: {
|
|
TRACE_(dmfile)(": unknown chunk (only DMTK expected; skipping)\n");
|
|
liMove.QuadPart = chunkSize - sizeof(FOURCC);
|
|
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
TRACE_(dmfile)("(unexpected) non-RIFF chunk (skipping, but expect errors)\n");
|
|
liMove.QuadPart = chunkSize;
|
|
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
|
|
break;
|
|
}
|
|
}
|
|
TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
|
|
} while (ListCount[0] < ListSize[0]);
|
|
break;
|
|
}
|
|
default: {
|
|
TRACE_(dmfile)(": unknown (skipping)\n");
|
|
liMove.QuadPart = chunkSize - sizeof(FOURCC);
|
|
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
TRACE_(dmfile)(": unknown chunk (skipping)\n");
|
|
liMove.QuadPart = chunkSize;
|
|
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
|
|
break;
|
|
}
|
|
}
|
|
TRACE_(dmfile)(": StreamCount = %ld < StreamSize = %ld\n", StreamCount, StreamSize);
|
|
} while (StreamCount < StreamSize);
|
|
break;
|
|
}
|
|
default: {
|
|
TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
|
|
liMove.QuadPart = StreamSize;
|
|
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
TRACE_(dmfile)(": reading finished\n");
|
|
break;
|
|
}
|
|
default: {
|
|
TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
|
|
liMove.QuadPart = chunkSize;
|
|
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegmentObjectStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT WINAPI IDirectMusicSegmentObjectStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
ICOM_VTABLE(IPersistStream) DirectMusicSegmentObjectStream_Vtbl =
|
|
{
|
|
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
|
IDirectMusicSegmentObjectStream_QueryInterface,
|
|
IDirectMusicSegmentObjectStream_AddRef,
|
|
IDirectMusicSegmentObjectStream_Release,
|
|
IDirectMusicSegmentObjectStream_GetClassID,
|
|
IDirectMusicSegmentObjectStream_IsDirty,
|
|
IDirectMusicSegmentObjectStream_Load,
|
|
IDirectMusicSegmentObjectStream_Save,
|
|
IDirectMusicSegmentObjectStream_GetSizeMax
|
|
};
|