mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 17:34:06 +00:00
dmime: Implement GUID_(Download|Unload)FromAudioPath for wave track.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=9027 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=34751 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45135 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48220
This commit is contained in:
parent
7bbd4be52a
commit
4a7a8a7ecc
|
@ -80,6 +80,8 @@ extern HRESULT segment_state_end_play(IDirectMusicSegmentState *iface);
|
|||
extern HRESULT wave_track_create_from_chunk(IStream *stream, struct chunk_entry *parent,
|
||||
IDirectMusicTrack8 **ret_iface);
|
||||
|
||||
extern HRESULT performance_get_dsound(IDirectMusicPerformance8 *iface, IDirectSound **dsound);
|
||||
|
||||
/*****************************************************************************
|
||||
* Auxiliary definitions
|
||||
*/
|
||||
|
|
|
@ -1731,3 +1731,17 @@ HRESULT create_dmperformance(REFIID iid, void **ret_iface)
|
|||
IDirectMusicPerformance_Release(&obj->IDirectMusicPerformance8_iface);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static inline struct performance *unsafe_impl_from_IDirectMusicPerformance8(IDirectMusicPerformance8 *iface)
|
||||
{
|
||||
if (iface->lpVtbl != &performance_vtbl) return NULL;
|
||||
return CONTAINING_RECORD(iface, struct performance, IDirectMusicPerformance8_iface);
|
||||
}
|
||||
|
||||
HRESULT performance_get_dsound(IDirectMusicPerformance8 *iface, IDirectSound **dsound)
|
||||
{
|
||||
struct performance *This = unsafe_impl_from_IDirectMusicPerformance8(iface);
|
||||
if (!This || !(*dsound = This->dsound)) return E_FAIL;
|
||||
IDirectSound_AddRef(*dsound);
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ struct wave_item {
|
|||
struct list entry;
|
||||
DMUS_IO_WAVE_ITEM_HEADER header;
|
||||
IUnknown *object;
|
||||
IDirectSoundBuffer *buffer;
|
||||
};
|
||||
|
||||
struct wave_part {
|
||||
|
@ -97,13 +98,18 @@ static ULONG WINAPI wave_track_Release(IDirectMusicTrack8 *iface)
|
|||
struct wave_item *item, *item2;
|
||||
struct wave_part *part, *part2;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(part, part2, &This->parts, struct wave_part, entry) {
|
||||
LIST_FOR_EACH_ENTRY_SAFE(part, part2, &This->parts, struct wave_part, entry)
|
||||
{
|
||||
list_remove(&part->entry);
|
||||
LIST_FOR_EACH_ENTRY_SAFE(item, item2, &part->items, struct wave_item, entry) {
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(item, item2, &part->items, struct wave_item, entry)
|
||||
{
|
||||
list_remove(&item->entry);
|
||||
if (item->buffer) IDirectSoundBuffer_Release(item->buffer);
|
||||
if (item->object) IUnknown_Release(item->object);
|
||||
free(item);
|
||||
}
|
||||
|
||||
free(part);
|
||||
}
|
||||
|
||||
|
@ -171,9 +177,46 @@ static HRESULT WINAPI wave_track_SetParam(IDirectMusicTrack8 *iface, REFGUID typ
|
|||
FIXME("GUID_Download not handled yet\n");
|
||||
return S_OK;
|
||||
}
|
||||
if (IsEqualGUID(type, &GUID_DownloadToAudioPath)) {
|
||||
FIXME("GUID_DownloadToAudioPath not handled yet\n");
|
||||
return S_OK;
|
||||
if (IsEqualGUID(type, &GUID_DownloadToAudioPath))
|
||||
{
|
||||
IDirectMusicPerformance8 *performance;
|
||||
IDirectMusicAudioPath *audio_path;
|
||||
IUnknown *object = param;
|
||||
struct wave_part *part;
|
||||
struct wave_item *item;
|
||||
IDirectSound *dsound;
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = IDirectMusicAudioPath_QueryInterface(object, &IID_IDirectMusicPerformance8, (void **)&performance))
|
||||
&& SUCCEEDED(hr = IDirectMusicAudioPath_QueryInterface(object, &IID_IDirectMusicAudioPath, (void **)&audio_path)))
|
||||
{
|
||||
hr = IDirectMusicAudioPath_GetObjectInPath(audio_path, DMUS_PCHANNEL_ALL, DMUS_PATH_PERFORMANCE, 0,
|
||||
&GUID_All_Objects, 0, &IID_IDirectMusicPerformance8, (void **)&performance);
|
||||
IDirectMusicAudioPath_Release(audio_path);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = performance_get_dsound(performance, &dsound);
|
||||
IDirectMusicPerformance_Release(performance);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WARN("Failed to get direct sound from param %p, hr %#lx\n", param, hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY(part, &This->parts, struct wave_part, entry)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY(item, &part->items, struct wave_item, entry)
|
||||
{
|
||||
if (item->buffer) continue;
|
||||
if (FAILED(hr = wave_download_to_dsound(item->object, dsound, &item->buffer)))
|
||||
{
|
||||
WARN("Failed to download wave %p to direct sound, hr %#lx\n", item->object, hr);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsEqualGUID(type, &GUID_Enable_Auto_Download)) {
|
||||
FIXME("GUID_Enable_Auto_Download not handled yet\n");
|
||||
|
@ -183,9 +226,20 @@ static HRESULT WINAPI wave_track_SetParam(IDirectMusicTrack8 *iface, REFGUID typ
|
|||
FIXME("GUID_Unload not handled yet\n");
|
||||
return S_OK;
|
||||
}
|
||||
if (IsEqualGUID(type, &GUID_UnloadFromAudioPath)) {
|
||||
FIXME("GUID_UnloadFromAudioPath not handled yet\n");
|
||||
return S_OK;
|
||||
if (IsEqualGUID(type, &GUID_UnloadFromAudioPath))
|
||||
{
|
||||
struct wave_part *part;
|
||||
struct wave_item *item;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(part, &This->parts, struct wave_part, entry)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY(item, &part->items, struct wave_item, entry)
|
||||
{
|
||||
if (!item->buffer) continue;
|
||||
IDirectSoundBuffer_Release(item->buffer);
|
||||
item->buffer = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DMUS_E_TYPE_UNSUPPORTED;
|
||||
|
|
|
@ -32,4 +32,5 @@ struct chunk_entry;
|
|||
extern HRESULT wave_create_from_soundfont(struct soundfont *soundfont, UINT index, IUnknown **out);
|
||||
extern HRESULT wave_create_from_chunk(IStream *stream, struct chunk_entry *parent, IUnknown **out);
|
||||
extern HRESULT wave_download_to_port(IUnknown *iface, IDirectMusicPortDownload *port, DWORD *id);
|
||||
extern HRESULT wave_download_to_dsound(IUnknown *iface, IDirectSound *dsound, IDirectSoundBuffer **ret_iface);
|
||||
extern HRESULT wave_get_duration(IUnknown *iface, REFERENCE_TIME *duration);
|
||||
|
|
|
@ -339,6 +339,45 @@ HRESULT wave_download_to_port(IUnknown *iface, IDirectMusicPortDownload *port, D
|
|||
return hr;
|
||||
}
|
||||
|
||||
HRESULT wave_download_to_dsound(IUnknown *iface, IDirectSound *dsound, IDirectSoundBuffer **ret_iface)
|
||||
{
|
||||
struct wave *This = impl_from_IUnknown(iface);
|
||||
DSBUFFERDESC desc =
|
||||
{
|
||||
.dwSize = sizeof(desc),
|
||||
.dwBufferBytes = This->data_size,
|
||||
.lpwfxFormat = This->format,
|
||||
};
|
||||
IDirectSoundBuffer *buffer;
|
||||
HRESULT hr;
|
||||
void *data;
|
||||
DWORD size;
|
||||
|
||||
TRACE("%p, %p, %p\n", This, dsound, ret_iface);
|
||||
|
||||
if (FAILED(hr = IDirectSound_CreateSoundBuffer(dsound, &desc, &buffer, NULL)))
|
||||
{
|
||||
WARN("Failed to create direct sound buffer, hr %#lx\n", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr = IDirectSoundBuffer_Lock(buffer, 0, This->data_size, &data, &size, NULL, 0, 0)))
|
||||
{
|
||||
memcpy(data, This->data, This->data_size);
|
||||
hr = IDirectSoundBuffer_Unlock(buffer, data, This->data_size, NULL, 0);
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WARN("Failed to download wave to dsound, hr %#lx\n", hr);
|
||||
IDirectSoundBuffer_Release(buffer);
|
||||
return hr;
|
||||
}
|
||||
|
||||
*ret_iface = buffer;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT wave_get_duration(IUnknown *iface, REFERENCE_TIME *duration)
|
||||
{
|
||||
struct wave *This = impl_from_IUnknown(iface);
|
||||
|
|
Loading…
Reference in a new issue