mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-25 14:26:23 +00:00
dmime: Semi-support creating an audio path from config.
This commit is contained in:
parent
e9a52308bb
commit
8daf207bf7
|
@ -645,6 +645,89 @@ static const IUnknownVtbl path_config_unk_vtbl =
|
|||
path_config_IUnknown_Release,
|
||||
};
|
||||
|
||||
HRESULT path_config_get_audio_path_params(IUnknown *iface, WAVEFORMATEX *format, DSBUFFERDESC *desc, DMUS_PORTPARAMS *params)
|
||||
{
|
||||
struct audio_path_config *This = impl_from_IUnknown(iface);
|
||||
struct list *first_port_config, *first_pchannel_to_buffer;
|
||||
struct audio_path_port_config *port_config;
|
||||
struct audio_path_pchannel_to_buffer *pchannel_to_buffer;
|
||||
GUID *guids;
|
||||
|
||||
first_port_config = list_head(&This->port_config_entries);
|
||||
if (list_next(&This->port_config_entries, first_port_config))
|
||||
FIXME("Only one port config supported. %p -> %p\n", first_port_config, list_next(&This->port_config_entries, first_port_config));
|
||||
port_config = LIST_ENTRY(first_port_config, struct audio_path_port_config, entry);
|
||||
first_pchannel_to_buffer = list_head(&port_config->pchannel_to_buffer_entries);
|
||||
if (list_next(&port_config->pchannel_to_buffer_entries, first_pchannel_to_buffer))
|
||||
FIXME("Only one pchannel to buffer entry supported.\n");
|
||||
pchannel_to_buffer = LIST_ENTRY(first_pchannel_to_buffer, struct audio_path_pchannel_to_buffer, entry);
|
||||
|
||||
/* Secondary buffer description */
|
||||
memset(format, 0, sizeof(*format));
|
||||
format->wFormatTag = WAVE_FORMAT_PCM;
|
||||
format->nChannels = 1;
|
||||
format->nSamplesPerSec = 44000;
|
||||
format->nAvgBytesPerSec = 44000 * 2;
|
||||
format->nBlockAlign = 2;
|
||||
format->wBitsPerSample = 16;
|
||||
format->cbSize = 0;
|
||||
|
||||
memset(desc, 0, sizeof(*desc));
|
||||
desc->dwSize = sizeof(*desc);
|
||||
desc->dwFlags = DSBCAPS_CTRLFX | DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS;
|
||||
desc->dwBufferBytes = DSBSIZE_MIN;
|
||||
desc->dwReserved = 0;
|
||||
desc->lpwfxFormat = format;
|
||||
desc->guid3DAlgorithm = GUID_NULL;
|
||||
|
||||
guids = pchannel_to_buffer->guids;
|
||||
if (pchannel_to_buffer->header.dwBufferCount == 2)
|
||||
{
|
||||
if ((!IsEqualGUID(&guids[0], &GUID_Buffer_Reverb) && !IsEqualGUID(&guids[0], &GUID_Buffer_Stereo)) ||
|
||||
(!IsEqualGUID(&guids[1], &GUID_Buffer_Reverb) && !IsEqualGUID(&guids[1], &GUID_Buffer_Stereo)) ||
|
||||
IsEqualGUID(&guids[0], &guids[1]))
|
||||
FIXME("Only a stereo plus reverb buffer is supported\n");
|
||||
else
|
||||
{
|
||||
desc->dwFlags |= DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY;
|
||||
format->nChannels = 2;
|
||||
format->nBlockAlign *= 2;
|
||||
format->nAvgBytesPerSec *= 2;
|
||||
}
|
||||
}
|
||||
else if (pchannel_to_buffer->header.dwBufferCount == 1)
|
||||
{
|
||||
if (IsEqualGUID(guids, &GUID_Buffer_Stereo))
|
||||
{
|
||||
desc->dwFlags |= DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY;
|
||||
format->nChannels = 2;
|
||||
format->nBlockAlign *= 2;
|
||||
format->nAvgBytesPerSec *= 2;
|
||||
}
|
||||
else if (IsEqualGUID(guids, &GUID_Buffer_3D_Dry))
|
||||
desc->dwFlags |= DSBCAPS_CTRL3D | DSBCAPS_CTRLFREQUENCY | DSBCAPS_MUTE3DATMAXDISTANCE;
|
||||
else if (IsEqualGUID(guids, &GUID_Buffer_Mono))
|
||||
desc->dwFlags |= DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY;
|
||||
else
|
||||
FIXME("Unsupported buffer guid %s\n", debugstr_dmguid(guids));
|
||||
}
|
||||
else
|
||||
FIXME("Multiple buffers not supported\n");
|
||||
|
||||
*params = port_config->params;
|
||||
if (!(params->dwValidParams & DMUS_PORTPARAMS_CHANNELGROUPS))
|
||||
{
|
||||
params->dwValidParams |= DMUS_PORTPARAMS_CHANNELGROUPS;
|
||||
params->dwChannelGroups = (port_config->header.dwPChannelCount + 15) / 16;
|
||||
}
|
||||
if (!(params->dwValidParams & DMUS_PORTPARAMS_AUDIOCHANNELS))
|
||||
{
|
||||
params->dwValidParams |= DMUS_PORTPARAMS_AUDIOCHANNELS;
|
||||
params->dwAudioChannels = format->nChannels;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* for ClassFactory */
|
||||
HRESULT create_dmaudiopath(REFIID riid, void **ppobj)
|
||||
{
|
||||
|
|
|
@ -93,6 +93,8 @@ extern HRESULT performance_send_segment_tick(IDirectMusicPerformance8 *iface, MU
|
|||
extern HRESULT performance_send_segment_end(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time,
|
||||
IDirectMusicSegmentState *state, BOOL abort);
|
||||
|
||||
HRESULT path_config_get_audio_path_params(IUnknown *iface, WAVEFORMATEX *format, DSBUFFERDESC *desc, DMUS_PORTPARAMS *params);
|
||||
|
||||
/*****************************************************************************
|
||||
* Auxiliary definitions
|
||||
*/
|
||||
|
|
|
@ -1651,16 +1651,65 @@ static HRESULT WINAPI performance_CreateAudioPath(IDirectMusicPerformance8 *ifac
|
|||
{
|
||||
struct performance *This = impl_from_IDirectMusicPerformance8(iface);
|
||||
IDirectMusicAudioPath *pPath;
|
||||
IDirectMusicObject *dmo;
|
||||
IDirectSoundBuffer *buffer, *primary_buffer;
|
||||
DMUS_OBJECTDESC objDesc;
|
||||
DMUS_PORTPARAMS8 port_params;
|
||||
HRESULT hr;
|
||||
WAVEFORMATEX format;
|
||||
DSBUFFERDESC desc;
|
||||
|
||||
FIXME("(%p, %p, %d, %p): stub\n", This, pSourceConfig, fActivate, ret_iface);
|
||||
FIXME("(%p, %p, %d, %p): semi-stub\n", This, pSourceConfig, fActivate, ret_iface);
|
||||
|
||||
if (!ret_iface || !pSourceConfig) return E_POINTER;
|
||||
if (!This->audio_paths_enabled) return DMUS_E_AUDIOPATH_INACTIVE;
|
||||
|
||||
hr = IUnknown_QueryInterface(pSourceConfig, &IID_IDirectMusicObject, (void **)&dmo);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
hr = IDirectMusicObject_GetDescriptor(dmo, &objDesc);
|
||||
IDirectMusicObject_Release(dmo);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (!IsEqualCLSID(&objDesc.guidClass, &CLSID_DirectMusicAudioPathConfig))
|
||||
{
|
||||
ERR("Unexpected object class %s for source config.\n", debugstr_dmguid(&objDesc.guidClass));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
hr = path_config_get_audio_path_params(pSourceConfig, &format, &desc, &port_params);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
hr = perf_dmport_create(This, &port_params);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
hr = IDirectSound_CreateSoundBuffer(This->dsound, &desc, &buffer, NULL);
|
||||
if (FAILED(hr))
|
||||
return DSERR_BUFFERLOST;
|
||||
|
||||
/* Update description for creating primary buffer */
|
||||
desc.dwFlags |= DSBCAPS_PRIMARYBUFFER;
|
||||
desc.dwFlags &= ~DSBCAPS_CTRLFX;
|
||||
desc.dwBufferBytes = 0;
|
||||
desc.lpwfxFormat = NULL;
|
||||
|
||||
hr = IDirectSound_CreateSoundBuffer(This->dsound, &desc, &primary_buffer, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IDirectSoundBuffer_Release(buffer);
|
||||
return DSERR_BUFFERLOST;
|
||||
}
|
||||
|
||||
create_dmaudiopath(&IID_IDirectMusicAudioPath, (void **)&pPath);
|
||||
set_audiopath_perf_pointer(pPath, iface);
|
||||
set_audiopath_dsound_buffer(pPath, buffer);
|
||||
set_audiopath_primary_dsound_buffer(pPath, primary_buffer);
|
||||
TRACE(" returning IDirectMusicAudioPath interface at %p.\n", *ret_iface);
|
||||
|
||||
/** TODO */
|
||||
*ret_iface = pPath;
|
||||
return IDirectMusicAudioPath_Activate(*ret_iface, fActivate);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue