70
AUDIN_LISTENER_CALLBACK * listener_callback;
69
AUDIN_LISTENER_CALLBACK* listener_callback;
71
/* Parsed plugin data */
76
/* Device interface */
74
audin_process_version(IWTSVirtualChannelCallback * pChannelCallback,
75
char * data, uint32 data_size)
80
static int audin_process_version(IWTSVirtualChannelCallback* pChannelCallback, STREAM* s)
77
AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) pChannelCallback;
83
Version = GET_UINT32(data, 0);
84
LLOGLN(10, ("audin_process_version: Version=%d", Version));
87
out_data = (char *) malloc(out_size);
88
memset(out_data, 0, out_size);
89
SET_UINT8(out_data, 0, MSG_SNDIN_VERSION);
90
SET_UINT32(out_data, 1, Version);
91
error = callback->channel->Write(callback->channel, out_size, out_data, NULL);
85
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
87
stream_read_uint32(s, Version);
89
DEBUG_DVC("Version=%d", Version);
92
stream_write_uint8(out, MSG_SNDIN_VERSION);
93
stream_write_uint32(out, Version);
94
error = callback->channel->Write(callback->channel, stream_get_length(s), stream_get_head(s), NULL);
98
audin_send_incoming_data_pdu(IWTSVirtualChannelCallback * pChannelCallback)
100
static int audin_send_incoming_data_pdu(IWTSVirtualChannelCallback* pChannelCallback)
100
AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) pChannelCallback;
103
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
103
SET_UINT8(out_data, 0, MSG_SNDIN_DATA_INCOMING);
105
out_data[0] = MSG_SNDIN_DATA_INCOMING;
104
106
return callback->channel->Write(callback->channel, 1, out_data, NULL);
108
audin_process_formats(IWTSVirtualChannelCallback * pChannelCallback,
109
char * data, uint32 data_size)
109
static int audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback, STREAM* s)
111
AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) pChannelCallback;
111
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
112
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin;
112
117
uint32 NumFormats;
119
int out_format_count;
119
uint32 cbSizeFormatsPacket;
122
NumFormats = GET_UINT32(data, 0);
121
stream_read_uint32(s, NumFormats);
122
DEBUG_DVC("NumFormats %d", NumFormats);
123
123
if ((NumFormats < 1) || (NumFormats > 1000))
125
LLOGLN(0, ("audin_process_formats: bad NumFormats %d",
125
DEBUG_WARN("bad NumFormats %d", NumFormats);
129
/* Ignore cbSizeFormatsPacket */
131
size = sizeof(char *) * (NumFormats + 1);
132
callback->formats_data = (char **) malloc(size);
133
memset(callback->formats_data, 0, size);
135
out_size = data_size + 1;
136
out_data = (char *) malloc(out_size);
137
memset(out_data, 0, out_size);
139
lout_formats = out_data + 9;
140
/* remainder is sndFormats (variable) */
142
out_format_count = 0;
128
stream_seek_uint32(s); /* cbSizeFormatsPacket */
130
callback->formats = (audinFormat*) xzalloc(NumFormats * sizeof(audinFormat));
135
/* SoundFormats (variable) */
143
136
for (i = 0; i < NumFormats; i++)
145
size = 18 + GET_UINT16(ldata, 16);
146
if (wave_in_format_supported(callback->device_data, ldata, size))
138
stream_get_mark(s, fm);
139
stream_read_uint16(s, format.wFormatTag);
140
stream_read_uint16(s, format.nChannels);
141
stream_read_uint32(s, format.nSamplesPerSec);
142
stream_seek_uint32(s); /* nAvgBytesPerSec */
143
stream_read_uint16(s, format.nBlockAlign);
144
stream_read_uint16(s, format.wBitsPerSample);
145
stream_read_uint16(s, format.cbSize);
146
format.data = stream_get_tail(s);
147
stream_seek(s, format.cbSize);
149
DEBUG_DVC("wFormatTag=%d nChannels=%d nSamplesPerSec=%d "
150
"nBlockAlign=%d wBitsPerSample=%d cbSize=%d",
151
format.wFormatTag, format.nChannels, format.nSamplesPerSec,
152
format.nBlockAlign, format.wBitsPerSample, format.cbSize);
154
if (audin->fixed_format > 0 && audin->fixed_format != format.wFormatTag)
156
if (audin->fixed_channel > 0 && audin->fixed_channel != format.nChannels)
158
if (audin->fixed_rate > 0 && audin->fixed_rate != format.nSamplesPerSec)
160
if (audin->device && audin->device->FormatSupported(audin->device, &format))
162
DEBUG_DVC("format ok");
148
164
/* Store the agreed format in the corresponding index */
149
callback->formats_data[out_format_count] = (char *) malloc(size);
150
memcpy(callback->formats_data[out_format_count], ldata, size);
165
callback->formats[callback->formats_count++] = format;
151
166
/* Put the format to output buffer */
152
memcpy(lout_formats, ldata, size);
153
lout_formats += size;
167
stream_check_size(out, 18 + format.cbSize);
168
stream_write(out, fm, 18 + format.cbSize);
158
callback->formats_count = out_format_count;
160
172
audin_send_incoming_data_pdu(pChannelCallback);
162
/* cbSizeFormatsPacket: the size of the entire PDU minus the size of ExtraData */
163
size = lout_formats - out_data;
164
SET_UINT8(out_data, 0, MSG_SNDIN_FORMATS);
165
SET_UINT32(out_data, 1, out_format_count);
166
SET_UINT32(out_data, 5, size);
167
error = callback->channel->Write(callback->channel, size, out_data, NULL);
174
audin_send_format_change_pdu(IWTSVirtualChannelCallback * pChannelCallback, uint32 NewFormat)
176
AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) pChannelCallback;
179
SET_UINT8(out_data, 0, MSG_SNDIN_FORMATCHANGE);
180
SET_UINT32(out_data, 1, NewFormat);
181
return callback->channel->Write(callback->channel, 5, out_data, NULL);
185
audin_send_open_reply_pdu(IWTSVirtualChannelCallback * pChannelCallback, uint32 Result)
187
AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) pChannelCallback;
190
SET_UINT8(out_data, 0, MSG_SNDIN_OPEN_REPLY);
191
SET_UINT32(out_data, 1, Result);
192
return callback->channel->Write(callback->channel, 5, out_data, NULL);
196
audin_receive_wave_data(char * wave_data, int size, void * user_data)
198
AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) user_data;
203
error = audin_send_incoming_data_pdu((IWTSVirtualChannelCallback *) callback);
174
cbSizeFormatsPacket = stream_get_pos(out);
175
stream_set_pos(out, 0);
177
stream_write_uint8(out, MSG_SNDIN_FORMATS); /* Header (1 byte) */
178
stream_write_uint32(out, callback->formats_count); /* NumFormats (4 bytes) */
179
stream_write_uint32(out, cbSizeFormatsPacket); /* cbSizeFormatsPacket (4 bytes) */
181
error = callback->channel->Write(callback->channel, cbSizeFormatsPacket, stream_get_head(out), NULL);
187
static int audin_send_format_change_pdu(IWTSVirtualChannelCallback* pChannelCallback, uint32 NewFormat)
191
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
194
stream_write_uint8(out, MSG_SNDIN_FORMATCHANGE);
195
stream_write_uint32(out, NewFormat);
196
error = callback->channel->Write(callback->channel, 5, stream_get_head(out), NULL);
202
static int audin_send_open_reply_pdu(IWTSVirtualChannelCallback* pChannelCallback, uint32 Result)
206
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
209
stream_write_uint8(out, MSG_SNDIN_OPEN_REPLY);
210
stream_write_uint32(out, Result);
211
error = callback->channel->Write(callback->channel, 5, stream_get_head(out), NULL);
217
static boolean audin_receive_wave_data(uint8* data, int size, void* user_data)
221
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) user_data;
223
error = audin_send_incoming_data_pdu((IWTSVirtualChannelCallback*) callback);
208
out_data = (char *) malloc(out_size);
209
SET_UINT8(out_data, 0, MSG_SNDIN_DATA);
210
memcpy(out_data + 1, wave_data, size);
211
error = callback->channel->Write(callback->channel, out_size, out_data, NULL);
227
out = stream_new(size + 1);
228
stream_write_uint8(out, MSG_SNDIN_DATA);
229
stream_write(out, data, size);
230
error = callback->channel->Write(callback->channel, stream_get_length(out), stream_get_head(out), NULL);
233
return (error == 0 ? true : false);
217
audin_process_open(IWTSVirtualChannelCallback * pChannelCallback,
218
char * data, uint32 data_size)
236
static int audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, STREAM* s)
220
AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) pChannelCallback;
238
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
239
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin;
241
uint32 initialFormat;
221
242
uint32 FramesPerPacket;
222
uint32 initialFormat;
227
FramesPerPacket = GET_UINT32(data, 0);
228
initialFormat = GET_UINT32(data, 4);
229
LLOGLN(10, ("audin_process_open: FramesPerPacket=%d initialFormat=%d",
230
FramesPerPacket, initialFormat));
244
stream_read_uint32(s, FramesPerPacket);
245
stream_read_uint32(s, initialFormat);
247
DEBUG_DVC("FramesPerPacket=%d initialFormat=%d",
248
FramesPerPacket, initialFormat);
231
250
if (initialFormat >= callback->formats_count)
233
LLOGLN(0, ("audin_process_open: invalid format index %d (total %d)",
234
initialFormat, callback->formats_count));
252
DEBUG_WARN("invalid format index %d (total %d)",
253
initialFormat, callback->formats_count);
237
format = callback->formats_data[initialFormat];
238
size = 18 + GET_UINT16(format, 16);
239
wave_in_set_format(callback->device_data, FramesPerPacket, format, size);
240
result = wave_in_open(callback->device_data,
241
audin_receive_wave_data, callback);
257
format = &callback->formats[initialFormat];
245
audin_send_format_change_pdu(pChannelCallback, initialFormat);
260
IFCALL(audin->device->SetFormat, audin->device, format, FramesPerPacket);
261
IFCALL(audin->device->Open, audin->device, audin_receive_wave_data, callback);
247
audin_send_open_reply_pdu(pChannelCallback, result);
264
audin_send_format_change_pdu(pChannelCallback, initialFormat);
265
audin_send_open_reply_pdu(pChannelCallback, 0);
253
audin_process_format_change(IWTSVirtualChannelCallback * pChannelCallback,
254
char * data, uint32 data_size)
270
static int audin_process_format_change(IWTSVirtualChannelCallback* pChannelCallback, STREAM* s)
256
AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) pChannelCallback;
272
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
273
AUDIN_PLUGIN * audin = (AUDIN_PLUGIN *) callback->plugin;
257
274
uint32 NewFormat;
261
NewFormat = GET_UINT32(data, 0);
262
LLOGLN(10, ("audin_process_format_change: NewFormat=%d",
277
stream_read_uint32(s, NewFormat);
279
DEBUG_DVC("NewFormat=%d", NewFormat);
264
281
if (NewFormat >= callback->formats_count)
266
LLOGLN(0, ("audin_process_format_change: invalid format index %d (total %d)",
267
NewFormat, callback->formats_count));
283
DEBUG_WARN("invalid format index %d (total %d)",
284
NewFormat, callback->formats_count);
271
wave_in_close(callback->device_data);
273
format = callback->formats_data[NewFormat];
274
size = 18 + GET_UINT16(format, 16);
275
wave_in_set_format(callback->device_data, 0, format, size);
288
format = &callback->formats[NewFormat];
292
IFCALL(audin->device->Close, audin->device);
293
IFCALL(audin->device->SetFormat, audin->device, format, 0);
294
IFCALL(audin->device->Open, audin->device, audin_receive_wave_data, callback);
276
297
audin_send_format_change_pdu(pChannelCallback, NewFormat);
278
wave_in_open(callback->device_data,
279
audin_receive_wave_data, callback);
285
audin_on_data_received(IWTSVirtualChannelCallback * pChannelCallback,
302
static int audin_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
291
MessageId = GET_UINT8(pBuffer, 0);
292
LLOGLN(10, ("audin_on_data_received: MessageId=0x%x", MessageId));
311
stream_attach(s, pBuffer, cbSize);
313
stream_read_uint8(s, MessageId);
315
DEBUG_DVC("MessageId=0x%x", MessageId);
293
317
switch (MessageId)
295
319
case MSG_SNDIN_VERSION:
296
audin_process_version(pChannelCallback, pBuffer + 1, cbSize - 1);
320
error = audin_process_version(pChannelCallback, s);
298
323
case MSG_SNDIN_FORMATS:
299
audin_process_formats(pChannelCallback, pBuffer + 1, cbSize - 1);
324
error = audin_process_formats(pChannelCallback, s);
301
327
case MSG_SNDIN_OPEN:
302
audin_process_open(pChannelCallback, pBuffer + 1, cbSize - 1);
328
error = audin_process_open(pChannelCallback, s);
304
331
case MSG_SNDIN_FORMATCHANGE:
305
audin_process_format_change(pChannelCallback, pBuffer + 1, cbSize - 1);
332
error = audin_process_format_change(pChannelCallback, s);
308
LLOGLN(0, ("audin_on_data_received: unknown MessageId=0x%x", MessageId));
336
DEBUG_WARN("unknown MessageId=0x%x", MessageId);
315
audin_on_close(IWTSVirtualChannelCallback * pChannelCallback)
317
AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) pChannelCallback;
320
LLOGLN(10, ("audin_on_close:"));
321
wave_in_close(callback->device_data);
322
wave_in_free(callback->device_data);
323
if (callback->formats_data)
325
for (i = 0; i < callback->formats_count; i++)
327
free(callback->formats_data[i]);
329
free(callback->formats_data);
336
audin_on_new_channel_connection(IWTSListenerCallback * pListenerCallback,
337
IWTSVirtualChannel * pChannel,
340
IWTSVirtualChannelCallback ** ppCallback)
342
AUDIN_LISTENER_CALLBACK * listener_callback = (AUDIN_LISTENER_CALLBACK *) pListenerCallback;
343
AUDIN_CHANNEL_CALLBACK * callback;
345
LLOGLN(10, ("audin_on_new_channel_connection:"));
346
callback = (AUDIN_CHANNEL_CALLBACK *) malloc(sizeof(AUDIN_CHANNEL_CALLBACK));
347
memset(callback, 0, sizeof(AUDIN_CHANNEL_CALLBACK));
347
static int audin_on_close(IWTSVirtualChannelCallback* pChannelCallback)
349
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
350
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin;
355
IFCALL(audin->device->Close, audin->device);
357
xfree(callback->formats);
363
static int audin_on_new_channel_connection(IWTSListenerCallback* pListenerCallback,
364
IWTSVirtualChannel* pChannel,
367
IWTSVirtualChannelCallback** ppCallback)
369
AUDIN_CHANNEL_CALLBACK* callback;
370
AUDIN_LISTENER_CALLBACK* listener_callback = (AUDIN_LISTENER_CALLBACK*) pListenerCallback;
374
callback = xnew(AUDIN_CHANNEL_CALLBACK);
349
376
callback->iface.OnDataReceived = audin_on_data_received;
350
377
callback->iface.OnClose = audin_on_close;
351
378
callback->plugin = listener_callback->plugin;
352
379
callback->channel_mgr = listener_callback->channel_mgr;
353
380
callback->channel = pChannel;
354
callback->device_data = wave_in_new();
356
*ppCallback = (IWTSVirtualChannelCallback *) callback;
382
*ppCallback = (IWTSVirtualChannelCallback*) callback;
361
audin_plugin_initialize(IWTSPlugin * pPlugin, IWTSVirtualChannelManager * pChannelMgr)
387
static int audin_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr)
363
AUDIN_PLUGIN * audin = (AUDIN_PLUGIN *) pPlugin;
365
LLOGLN(10, ("audin_plugin_initialize:"));
366
audin->listener_callback = (AUDIN_LISTENER_CALLBACK *) malloc(sizeof(AUDIN_LISTENER_CALLBACK));
367
memset(audin->listener_callback, 0, sizeof(AUDIN_LISTENER_CALLBACK));
389
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin;
393
audin->listener_callback = xnew(AUDIN_LISTENER_CALLBACK);
369
395
audin->listener_callback->iface.OnNewChannelConnection = audin_on_new_channel_connection;
370
396
audin->listener_callback->plugin = pPlugin;
371
397
audin->listener_callback->channel_mgr = pChannelMgr;
372
398
return pChannelMgr->CreateListener(pChannelMgr, "AUDIO_INPUT", 0,
373
(IWTSListenerCallback *) audin->listener_callback, NULL);
399
(IWTSListenerCallback*) audin->listener_callback, NULL);
377
audin_plugin_terminated(IWTSPlugin * pPlugin)
402
static int audin_plugin_terminated(IWTSPlugin* pPlugin)
379
AUDIN_PLUGIN * audin = (AUDIN_PLUGIN *) pPlugin;
381
LLOGLN(10, ("audin_plugin_terminated:"));
382
if (audin->listener_callback)
383
free(audin->listener_callback);
404
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin;
410
IFCALL(audin->device->Close, audin->device);
411
IFCALL(audin->device->Free, audin->device);
412
audin->device = NULL;
414
xfree(audin->listener_callback);
389
DVCPluginEntry(IDRDYNVC_ENTRY_POINTS * pEntryPoints)
391
AUDIN_PLUGIN * audin;
393
audin = (AUDIN_PLUGIN *) malloc(sizeof(AUDIN_PLUGIN));
394
memset(audin, 0, sizeof(AUDIN_PLUGIN));
396
audin->iface.Initialize = audin_plugin_initialize;
397
audin->iface.Connected = NULL;
398
audin->iface.Disconnected = NULL;
399
audin->iface.Terminated = audin_plugin_terminated;
400
return pEntryPoints->RegisterPlugin(pEntryPoints, (IWTSPlugin *) audin);
420
static void audin_register_device_plugin(IWTSPlugin* pPlugin, IAudinDevice* device)
422
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin;
426
DEBUG_WARN("existing device, abort.");
430
DEBUG_DVC("device registered.");
432
audin->device = device;
435
static boolean audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, RDP_PLUGIN_DATA* data)
438
PFREERDP_AUDIN_DEVICE_ENTRY entry;
439
FREERDP_AUDIN_DEVICE_ENTRY_POINTS entryPoints;
441
if (strrchr(name, '.') != NULL)
442
entry = (PFREERDP_AUDIN_DEVICE_ENTRY)freerdp_load_plugin(name, AUDIN_DEVICE_EXPORT_FUNC_NAME);
445
fullname = xzalloc(strlen(name) + 8);
446
strcpy(fullname, "audin_");
447
strcat(fullname, name);
448
entry = (PFREERDP_AUDIN_DEVICE_ENTRY)freerdp_load_plugin(fullname, AUDIN_DEVICE_EXPORT_FUNC_NAME);
456
entryPoints.plugin = pPlugin;
457
entryPoints.pRegisterAudinDevice = audin_register_device_plugin;
458
entryPoints.plugin_data = data;
459
if (entry(&entryPoints) != 0)
461
DEBUG_WARN("%s entry returns error.", name);
468
static boolean audin_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data)
471
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin;
472
RDP_PLUGIN_DATA default_data[2] = { { 0 }, { 0 } };
474
if (data->data[0] && (strcmp((char*)data->data[0], "audin") == 0 || strstr((char*)data->data[0], "/audin.") != NULL) )
476
if (data->data[1] && strcmp((char*)data->data[1], "format") == 0)
478
audin->fixed_format = atoi(data->data[2]);
481
else if (data->data[1] && strcmp((char*)data->data[1], "rate") == 0)
483
audin->fixed_rate = atoi(data->data[2]);
486
else if (data->data[1] && strcmp((char*)data->data[1], "channel") == 0)
488
audin->fixed_channel = atoi(data->data[2]);
491
else if (data->data[1] && ((char*)data->data[1])[0])
493
return audin_load_device_plugin(pPlugin, (char*)data->data[1], data);
497
default_data[0].size = sizeof(RDP_PLUGIN_DATA);
498
default_data[0].data[0] = "audin";
499
default_data[0].data[1] = "pulse";
500
default_data[0].data[2] = "";
501
ret = audin_load_device_plugin(pPlugin, "pulse", default_data);
504
default_data[0].size = sizeof(RDP_PLUGIN_DATA);
505
default_data[0].data[0] = "audin";
506
default_data[0].data[1] = "alsa";
507
default_data[0].data[2] = "default";
508
ret = audin_load_device_plugin(pPlugin, "alsa", default_data);
517
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
522
audin = (AUDIN_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "audin");
525
audin = xnew(AUDIN_PLUGIN);
527
audin->iface.Initialize = audin_plugin_initialize;
528
audin->iface.Connected = NULL;
529
audin->iface.Disconnected = NULL;
530
audin->iface.Terminated = audin_plugin_terminated;
531
error = pEntryPoints->RegisterPlugin(pEntryPoints, "audin", (IWTSPlugin*) audin);
536
audin_process_plugin_data((IWTSPlugin*) audin,
537
pEntryPoints->GetPluginData(pEntryPoints));