Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/amstream/audiodata.c
4389 views
1
/*
2
* Implementation of IAudioData Interface
3
*
4
* Copyright 2012 Christian Costa
5
*
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
10
*
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
*/
20
21
#include "wine/debug.h"
22
23
#define COBJMACROS
24
25
#include "winbase.h"
26
#include "amstream_private.h"
27
28
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
29
30
typedef struct {
31
IAudioData IAudioData_iface;
32
LONG ref;
33
DWORD size;
34
BYTE *data;
35
BOOL data_owned;
36
DWORD actual_data;
37
WAVEFORMATEX wave_format;
38
} AMAudioDataImpl;
39
40
static inline AMAudioDataImpl *impl_from_IAudioData(IAudioData *iface)
41
{
42
return CONTAINING_RECORD(iface, AMAudioDataImpl, IAudioData_iface);
43
}
44
45
/*** IUnknown methods ***/
46
static HRESULT WINAPI IAudioDataImpl_QueryInterface(IAudioData *iface, REFIID riid, void **ret_iface)
47
{
48
TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ret_iface);
49
50
if (IsEqualGUID(riid, &IID_IUnknown) ||
51
IsEqualGUID(riid, &IID_IAudioData))
52
{
53
IAudioData_AddRef(iface);
54
*ret_iface = iface;
55
return S_OK;
56
}
57
58
ERR("(%p)->(%s,%p),not found\n", iface, debugstr_guid(riid), ret_iface);
59
return E_NOINTERFACE;
60
}
61
62
static ULONG WINAPI IAudioDataImpl_AddRef(IAudioData* iface)
63
{
64
AMAudioDataImpl *This = impl_from_IAudioData(iface);
65
ULONG ref = InterlockedIncrement(&This->ref);
66
67
TRACE("(%p)->(): new ref = %lu\n", iface, This->ref);
68
69
return ref;
70
}
71
72
static ULONG WINAPI IAudioDataImpl_Release(IAudioData* iface)
73
{
74
AMAudioDataImpl *audiodata = impl_from_IAudioData(iface);
75
ULONG ref = InterlockedDecrement(&audiodata->ref);
76
77
TRACE("%p decreasing refcount to %lu.\n", audiodata, ref);
78
79
if (!ref)
80
{
81
if (audiodata->data_owned)
82
free(audiodata->data);
83
free(audiodata);
84
}
85
86
return ref;
87
}
88
89
/*** IMemoryData methods ***/
90
static HRESULT WINAPI IAudioDataImpl_SetBuffer(IAudioData* iface, DWORD size, BYTE *data, DWORD flags)
91
{
92
AMAudioDataImpl *This = impl_from_IAudioData(iface);
93
94
TRACE("(%p)->(%lu,%p,%lx)\n", iface, size, data, flags);
95
96
if (!size)
97
{
98
return E_INVALIDARG;
99
}
100
101
if (This->data_owned)
102
{
103
free(This->data);
104
This->data_owned = FALSE;
105
}
106
107
This->size = size;
108
This->data = data;
109
110
if (!This->data)
111
{
112
This->data = malloc(This->size);
113
This->data_owned = TRUE;
114
if (!This->data)
115
{
116
return E_OUTOFMEMORY;
117
}
118
}
119
120
return S_OK;
121
}
122
123
static HRESULT WINAPI IAudioDataImpl_GetInfo(IAudioData* iface, DWORD *length, BYTE **data, DWORD *actual_data)
124
{
125
AMAudioDataImpl *This = impl_from_IAudioData(iface);
126
127
TRACE("(%p)->(%p,%p,%p)\n", iface, length, data, actual_data);
128
129
if (!This->data)
130
{
131
return MS_E_NOTINIT;
132
}
133
134
if (length)
135
{
136
*length = This->size;
137
}
138
if (data)
139
{
140
*data = This->data;
141
}
142
if (actual_data)
143
{
144
*actual_data = This->actual_data;
145
}
146
147
return S_OK;
148
}
149
150
static HRESULT WINAPI IAudioDataImpl_SetActual(IAudioData* iface, DWORD data_valid)
151
{
152
AMAudioDataImpl *This = impl_from_IAudioData(iface);
153
154
TRACE("(%p)->(%lu)\n", iface, data_valid);
155
156
if (data_valid > This->size)
157
{
158
return E_INVALIDARG;
159
}
160
161
This->actual_data = data_valid;
162
163
return S_OK;
164
}
165
166
/*** IAudioData methods ***/
167
static HRESULT WINAPI IAudioDataImpl_GetFormat(IAudioData* iface, WAVEFORMATEX *wave_format_current)
168
{
169
AMAudioDataImpl *This = impl_from_IAudioData(iface);
170
171
TRACE("(%p)->(%p)\n", iface, wave_format_current);
172
173
if (!wave_format_current)
174
{
175
return E_POINTER;
176
}
177
178
*wave_format_current = This->wave_format;
179
180
return S_OK;
181
}
182
183
static HRESULT WINAPI IAudioDataImpl_SetFormat(IAudioData* iface, const WAVEFORMATEX *wave_format)
184
{
185
AMAudioDataImpl *This = impl_from_IAudioData(iface);
186
187
TRACE("(%p)->(%p)\n", iface, wave_format);
188
189
if (!wave_format)
190
{
191
return E_POINTER;
192
}
193
194
if (WAVE_FORMAT_PCM != wave_format->wFormatTag)
195
{
196
return E_INVALIDARG;
197
}
198
199
This->wave_format = *wave_format;
200
201
return S_OK;
202
}
203
204
static const struct IAudioDataVtbl AudioData_Vtbl =
205
{
206
/*** IUnknown methods ***/
207
IAudioDataImpl_QueryInterface,
208
IAudioDataImpl_AddRef,
209
IAudioDataImpl_Release,
210
/*** IMemoryData methods ***/
211
IAudioDataImpl_SetBuffer,
212
IAudioDataImpl_GetInfo,
213
IAudioDataImpl_SetActual,
214
/*** IAudioData methods ***/
215
IAudioDataImpl_GetFormat,
216
IAudioDataImpl_SetFormat
217
};
218
219
HRESULT AMAudioData_create(IUnknown *pUnkOuter, LPVOID *ppObj)
220
{
221
AMAudioDataImpl *object;
222
223
TRACE("(%p,%p)\n", pUnkOuter, ppObj);
224
225
if (pUnkOuter)
226
return CLASS_E_NOAGGREGATION;
227
228
if (!(object = calloc(1, sizeof(*object))))
229
return E_OUTOFMEMORY;
230
231
object->IAudioData_iface.lpVtbl = &AudioData_Vtbl;
232
object->ref = 1;
233
234
object->wave_format.wFormatTag = WAVE_FORMAT_PCM;
235
object->wave_format.nChannels = 1;
236
object->wave_format.nSamplesPerSec = 11025;
237
object->wave_format.wBitsPerSample = 16;
238
object->wave_format.nBlockAlign = object->wave_format.wBitsPerSample * object->wave_format.nChannels / 8;
239
object->wave_format.nAvgBytesPerSec = object->wave_format.nBlockAlign * object->wave_format.nSamplesPerSec;
240
241
*ppObj = &object->IAudioData_iface;
242
243
return S_OK;
244
}
245
246