Working mic redirection for shadow server.
This commit is contained in:
parent
28efbbc01f
commit
106dde9571
@ -85,9 +85,7 @@ struct _AUDIN_PLUGIN
|
||||
AUDIN_LISTENER_CALLBACK* listener_callback;
|
||||
|
||||
/* Parsed plugin data */
|
||||
UINT16 fixed_format;
|
||||
UINT16 fixed_channel;
|
||||
UINT32 fixed_rate;
|
||||
AUDIO_FORMAT* fixed_format;
|
||||
char* subsystem;
|
||||
char* device_name;
|
||||
|
||||
@ -200,7 +198,7 @@ static UINT audin_process_formats(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c
|
||||
}
|
||||
|
||||
Stream_Seek_UINT32(s); /* cbSizeFormatsPacket */
|
||||
callback->formats = (AUDIO_FORMAT*) calloc(NumFormats, sizeof(AUDIO_FORMAT));
|
||||
callback->formats = audio_formats_new(NumFormats);
|
||||
|
||||
if (!callback->formats)
|
||||
{
|
||||
@ -230,17 +228,11 @@ static UINT audin_process_formats(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c
|
||||
goto out;
|
||||
}
|
||||
|
||||
WLog_Print(audin->log, WLOG_DEBUG,
|
||||
"wFormatTag=%s nChannels=%"PRIu16" nSamplesPerSec=%"PRIu32" "
|
||||
"nBlockAlign=%"PRIu16" wBitsPerSample=%"PRIu16" cbSize=%"PRIu16"",
|
||||
audio_format_get_tag_string(format.wFormatTag), format.nChannels, format.nSamplesPerSec,
|
||||
format.nBlockAlign, format.wBitsPerSample, format.cbSize);
|
||||
audio_format_print(audin->log, WLOG_DEBUG, &format);
|
||||
|
||||
if ((audin->fixed_format > 0 && audin->fixed_format != format.wFormatTag) ||
|
||||
(audin->fixed_channel > 0 && audin->fixed_channel != format.nChannels) ||
|
||||
(audin->fixed_rate > 0 && audin->fixed_rate != format.nSamplesPerSec))
|
||||
if (!audio_format_compatible(audin->fixed_format, &format))
|
||||
{
|
||||
rdpsnd_free_audio_format(&format);
|
||||
audio_format_free(&format);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -259,7 +251,7 @@ static UINT audin_process_formats(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c
|
||||
}
|
||||
else
|
||||
{
|
||||
rdpsnd_free_audio_format(&format);
|
||||
audio_format_free(&format);
|
||||
}
|
||||
}
|
||||
|
||||
@ -591,7 +583,6 @@ static UINT audin_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
|
||||
*/
|
||||
static UINT audin_on_close(IWTSVirtualChannelCallback* pChannelCallback)
|
||||
{
|
||||
size_t x;
|
||||
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
|
||||
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin;
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
@ -691,6 +682,7 @@ static UINT audin_plugin_terminated(IWTSPlugin* pPlugin)
|
||||
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||
|
||||
WLog_Print(audin->log, WLOG_TRACE, "...");
|
||||
audio_format_free(audin->fixed_format);
|
||||
|
||||
if (audin->device)
|
||||
{
|
||||
@ -891,7 +883,7 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args)
|
||||
if ((errno != 0) || (val > UINT16_MAX))
|
||||
return FALSE;
|
||||
|
||||
audin->fixed_format = val;
|
||||
audin->fixed_format->wFormatTag = val;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "rate")
|
||||
{
|
||||
@ -900,14 +892,14 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args)
|
||||
if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
|
||||
return FALSE;
|
||||
|
||||
audin->fixed_rate = val;
|
||||
audin->fixed_format->nSamplesPerSec = val;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "channel")
|
||||
{
|
||||
unsigned long val = strtoul(arg->Value, NULL, 0);
|
||||
|
||||
if ((errno != 0) || (val > UINT16_MAX))
|
||||
audin->fixed_channel = val;
|
||||
audin->fixed_format->nChannels = val;
|
||||
}
|
||||
CommandLineSwitchDefault(arg)
|
||||
{
|
||||
@ -980,6 +972,10 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
|
||||
audin->log = WLog_Get(TAG);
|
||||
audin->data = Stream_New(NULL, 4096);
|
||||
audin->fixed_format = audio_format_new();
|
||||
|
||||
if (!audin->fixed_format)
|
||||
goto out;
|
||||
|
||||
if (!audin->data)
|
||||
goto out;
|
||||
|
@ -188,7 +188,7 @@ static UINT audin_server_send_formats(audin_server* audin, wStream* s)
|
||||
static UINT audin_server_recv_formats(audin_server* audin, wStream* s,
|
||||
UINT32 length)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
UINT success = CHANNEL_RC_OK;
|
||||
|
||||
if (length < 8)
|
||||
@ -210,8 +210,7 @@ static UINT audin_server_recv_formats(audin_server* audin, wStream* s,
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
audin->context.client_formats = calloc(audin->context.num_client_formats,
|
||||
sizeof(AUDIO_FORMAT));
|
||||
audin->context.client_formats = audio_formats_new(audin->context.num_client_formats);
|
||||
|
||||
if (!audin->context.client_formats)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
@ -227,6 +226,8 @@ static UINT audin_server_recv_formats(audin_server* audin, wStream* s,
|
||||
WLog_ERR(TAG, "expected length at least 18, but got %"PRIu32"", length);
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
audio_format_print(WLog_Get(TAG), WLOG_DEBUG, format);
|
||||
}
|
||||
|
||||
IFCALLRET(audin->context.Opening, success, &audin->context);
|
||||
|
@ -86,9 +86,7 @@ struct rdpsnd_plugin
|
||||
|
||||
UINT32 latency;
|
||||
BOOL isOpen;
|
||||
UINT16 fixedFormat;
|
||||
UINT16 fixedChannel;
|
||||
UINT32 fixedRate;
|
||||
AUDIO_FORMAT* fixed_format;
|
||||
|
||||
char* subsystem;
|
||||
char* device_name;
|
||||
@ -146,9 +144,7 @@ static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd)
|
||||
if (!rdpsnd->NumberOfServerFormats)
|
||||
return;
|
||||
|
||||
rdpsnd->ClientFormats = (AUDIO_FORMAT*) calloc(
|
||||
rdpsnd->NumberOfServerFormats,
|
||||
sizeof(AUDIO_FORMAT));
|
||||
rdpsnd->ClientFormats = audio_formats_new(rdpsnd->NumberOfServerFormats);
|
||||
|
||||
if (!rdpsnd->ClientFormats)
|
||||
return;
|
||||
@ -157,16 +153,7 @@ static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd)
|
||||
{
|
||||
const AUDIO_FORMAT* serverFormat = &rdpsnd->ServerFormats[index];
|
||||
|
||||
if ((rdpsnd->fixedFormat > 0) &&
|
||||
(rdpsnd->fixedFormat != serverFormat->wFormatTag))
|
||||
continue;
|
||||
|
||||
if ((rdpsnd->fixedChannel > 0) &&
|
||||
(rdpsnd->fixedChannel != serverFormat->nChannels))
|
||||
continue;
|
||||
|
||||
if ((rdpsnd->fixedRate > 0) &&
|
||||
(rdpsnd->fixedRate != serverFormat->nSamplesPerSec))
|
||||
if (!audio_format_compatible(rdpsnd->fixed_format, serverFormat))
|
||||
continue;
|
||||
|
||||
if (freerdp_dsp_supports_format(serverFormat, FALSE) ||
|
||||
@ -265,8 +252,7 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd,
|
||||
if (Stream_GetRemainingLength(s) / 14 < wNumberOfFormats)
|
||||
return ERROR_BAD_LENGTH;
|
||||
|
||||
rdpsnd->ServerFormats = (AUDIO_FORMAT*) calloc(wNumberOfFormats,
|
||||
sizeof(AUDIO_FORMAT));
|
||||
rdpsnd->ServerFormats = audio_formats_new(wNumberOfFormats);
|
||||
|
||||
if (!rdpsnd->ServerFormats)
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
@ -765,7 +751,7 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args)
|
||||
if ((errno != 0) || (val > UINT16_MAX))
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
|
||||
rdpsnd->fixedFormat = val;
|
||||
rdpsnd->fixed_format->wFormatTag = val;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "rate")
|
||||
{
|
||||
@ -774,7 +760,7 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args)
|
||||
if ((errno != 0) || (val > UINT32_MAX))
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
|
||||
rdpsnd->fixedRate = val;
|
||||
rdpsnd->fixed_format->nSamplesPerSec = val;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "channel")
|
||||
{
|
||||
@ -783,7 +769,7 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args)
|
||||
if ((errno != 0) || (val > UINT16_MAX))
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
|
||||
rdpsnd->fixedChannel = val;
|
||||
rdpsnd->fixed_format->nChannels = val;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "latency")
|
||||
{
|
||||
@ -1211,6 +1197,7 @@ static void rdpsnd_virtual_channel_event_terminated(rdpsndPlugin* rdpsnd)
|
||||
{
|
||||
if (rdpsnd)
|
||||
{
|
||||
audio_format_free(rdpsnd->fixed_format);
|
||||
free(rdpsnd->subsystem);
|
||||
free(rdpsnd->device_name);
|
||||
CloseHandle(rdpsnd->stopEvent);
|
||||
@ -1306,6 +1293,14 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p
|
||||
rdpsnd->rdpcontext = pEntryPointsEx->context;
|
||||
}
|
||||
|
||||
rdpsnd->fixed_format = audio_format_new();
|
||||
|
||||
if (!rdpsnd->fixed_format)
|
||||
{
|
||||
free(rdpsnd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rdpsnd->log = WLog_Get("com.freerdp.channels.rdpsnd.client");
|
||||
CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints,
|
||||
sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));
|
||||
|
@ -172,8 +172,7 @@ static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
context->client_formats = (AUDIO_FORMAT*)calloc(context->num_client_formats,
|
||||
sizeof(AUDIO_FORMAT));
|
||||
context->client_formats = audio_formats_new(context->num_client_formats);
|
||||
|
||||
if (!context->client_formats)
|
||||
{
|
||||
|
@ -195,13 +195,17 @@ FREERDP_API UINT32 audio_format_compute_time_length(const AUDIO_FORMAT* format,
|
||||
|
||||
FREERDP_API char* audio_format_get_tag_string(UINT16 wFormatTag);
|
||||
|
||||
FREERDP_API void audio_format_print(const AUDIO_FORMAT* format);
|
||||
FREERDP_API void audio_formats_print(const AUDIO_FORMAT* formats, UINT16 count);
|
||||
FREERDP_API void audio_format_print(wLog* log, DWORD level, const AUDIO_FORMAT* format);
|
||||
FREERDP_API void audio_formats_print(wLog* log, DWORD level, const AUDIO_FORMAT* formats,
|
||||
UINT16 count);
|
||||
|
||||
FREERDP_API BOOL audio_format_read(wStream* s, AUDIO_FORMAT* format);
|
||||
FREERDP_API BOOL audio_format_write(wStream* s, const AUDIO_FORMAT* format);
|
||||
FREERDP_API BOOL audio_format_copy(const AUDIO_FORMAT* srcFormat, AUDIO_FORMAT* dstFormat);
|
||||
FREERDP_API BOOL audio_format_compatible(const AUDIO_FORMAT* formatA, const AUDIO_FORMAT* formatB);
|
||||
FREERDP_API BOOL audio_format_compatible(const AUDIO_FORMAT* with, const AUDIO_FORMAT* what);
|
||||
|
||||
FREERDP_API AUDIO_FORMAT* audio_format_new(void);
|
||||
FREERDP_API AUDIO_FORMAT* audio_formats_new(size_t count);
|
||||
|
||||
FREERDP_API void audio_format_free(AUDIO_FORMAT* format);
|
||||
FREERDP_API void audio_formats_free(AUDIO_FORMAT* formats, size_t count);
|
||||
|
@ -58,7 +58,7 @@ struct _audin_server_context
|
||||
/* Client supported formats. */
|
||||
AUDIO_FORMAT* client_formats;
|
||||
size_t num_client_formats;
|
||||
size_t selected_client_format;
|
||||
SSIZE_T selected_client_format;
|
||||
|
||||
/*** APIs called by the server. ***/
|
||||
/**
|
||||
|
@ -58,7 +58,7 @@ struct _rdpsnd_server_context
|
||||
|
||||
/* Server supported formats. Set by server. */
|
||||
const AUDIO_FORMAT* server_formats;
|
||||
int num_server_formats;
|
||||
size_t num_server_formats;
|
||||
|
||||
/* Server source PCM audio format. Set by server. */
|
||||
AUDIO_FORMAT src_format;
|
||||
|
@ -63,7 +63,7 @@ typedef int (*pfnShadowSubsystemUninit)(rdpShadowSubsystem* subsystem);
|
||||
typedef int (*pfnShadowSubsystemStart)(rdpShadowSubsystem* subsystem);
|
||||
typedef int (*pfnShadowSubsystemStop)(rdpShadowSubsystem* subsystem);
|
||||
|
||||
typedef UINT32 (*pfnShadowEnumMonitors)(MONITOR_DEF* monitors, UINT32 maxMonitors);
|
||||
typedef UINT32(*pfnShadowEnumMonitors)(MONITOR_DEF* monitors, UINT32 maxMonitors);
|
||||
|
||||
typedef int (*pfnShadowAuthenticate)(rdpShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client,
|
||||
@ -203,9 +203,9 @@ struct _RDP_SHADOW_ENTRY_POINTS
|
||||
UINT32 pointerY; \
|
||||
\
|
||||
const AUDIO_FORMAT* rdpsndFormats; \
|
||||
int nRdpsndFormats; \
|
||||
size_t nRdpsndFormats; \
|
||||
const AUDIO_FORMAT* audinFormats; \
|
||||
int nAudinFormats; \
|
||||
size_t nAudinFormats; \
|
||||
\
|
||||
pfnShadowSynchronizeEvent SynchronizeEvent; \
|
||||
pfnShadowKeyboardEvent KeyboardEvent; \
|
||||
@ -253,7 +253,7 @@ struct _SHADOW_MSG_OUT_POINTER_POSITION_UPDATE
|
||||
UINT32 yPos;
|
||||
};
|
||||
typedef struct _SHADOW_MSG_OUT_POINTER_POSITION_UPDATE
|
||||
SHADOW_MSG_OUT_POINTER_POSITION_UPDATE;
|
||||
SHADOW_MSG_OUT_POINTER_POSITION_UPDATE;
|
||||
|
||||
struct _SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE
|
||||
{
|
||||
@ -268,7 +268,7 @@ struct _SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE
|
||||
BYTE* andMaskData;
|
||||
};
|
||||
typedef struct _SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE
|
||||
SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE;
|
||||
SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE;
|
||||
|
||||
struct _SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES
|
||||
{
|
||||
@ -279,7 +279,7 @@ struct _SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES
|
||||
UINT16 wTimestamp;
|
||||
};
|
||||
typedef struct _SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES
|
||||
SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES;
|
||||
SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES;
|
||||
|
||||
struct _SHADOW_MSG_OUT_AUDIO_OUT_VOLUME
|
||||
{
|
||||
|
@ -112,32 +112,33 @@ char* audio_format_get_tag_string(UINT16 wFormatTag)
|
||||
return "WAVE_FORMAT_UNKNOWN";
|
||||
}
|
||||
|
||||
void audio_format_print(const AUDIO_FORMAT* format)
|
||||
void audio_format_print(wLog* log, DWORD level, const AUDIO_FORMAT* format)
|
||||
{
|
||||
WLog_INFO(TAG, "%s:\t wFormatTag: 0x%04"PRIX16" nChannels: %"PRIu16" nSamplesPerSec: %"PRIu32" "
|
||||
"nAvgBytesPerSec: %"PRIu32" nBlockAlign: %"PRIu16" wBitsPerSample: %"PRIu16" cbSize: %"PRIu16"",
|
||||
audio_format_get_tag_string(format->wFormatTag), format->wFormatTag,
|
||||
format->nChannels, format->nSamplesPerSec, format->nAvgBytesPerSec,
|
||||
format->nBlockAlign, format->wBitsPerSample, format->cbSize);
|
||||
WLog_Print(log, level,
|
||||
"%s:\t wFormatTag: 0x%04"PRIX16" nChannels: %"PRIu16" nSamplesPerSec: %"PRIu32" "
|
||||
"nAvgBytesPerSec: %"PRIu32" nBlockAlign: %"PRIu16" wBitsPerSample: %"PRIu16" cbSize: %"PRIu16"",
|
||||
audio_format_get_tag_string(format->wFormatTag), format->wFormatTag,
|
||||
format->nChannels, format->nSamplesPerSec, format->nAvgBytesPerSec,
|
||||
format->nBlockAlign, format->wBitsPerSample, format->cbSize);
|
||||
}
|
||||
|
||||
void audio_format_prints(const AUDIO_FORMAT* formats, UINT16 count)
|
||||
void audio_formats_print(wLog* log, DWORD level, const AUDIO_FORMAT* formats, UINT16 count)
|
||||
{
|
||||
UINT16 index;
|
||||
const AUDIO_FORMAT* format;
|
||||
|
||||
if (formats)
|
||||
{
|
||||
WLog_INFO(TAG, "AUDIO_FORMATS (%"PRIu16") ={", count);
|
||||
WLog_Print(log, level, "AUDIO_FORMATS (%"PRIu16") ={", count);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
format = &formats[index];
|
||||
WLog_ERR(TAG, "\t");
|
||||
audio_format_print(format);
|
||||
WLog_Print(log, level, "\t");
|
||||
audio_format_print(log, level, format);
|
||||
}
|
||||
|
||||
WLog_ERR(TAG, "}");
|
||||
WLog_Print(log, level, "}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,24 +218,63 @@ BOOL audio_format_copy(const AUDIO_FORMAT* srcFormat, AUDIO_FORMAT* dstFormat)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL audio_format_compatible(const AUDIO_FORMAT* formatA, const AUDIO_FORMAT* formatB)
|
||||
BOOL audio_format_compatible(const AUDIO_FORMAT* with, const AUDIO_FORMAT* what)
|
||||
{
|
||||
if (!formatA || !formatB)
|
||||
if (!with || !what)
|
||||
return FALSE;
|
||||
|
||||
if (formatA->wFormatTag != formatB->wFormatTag)
|
||||
if (with->wFormatTag != WAVE_FORMAT_UNKNOWN)
|
||||
{
|
||||
if (with->wFormatTag != what->wFormatTag)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (with->nChannels != 0)
|
||||
{
|
||||
if (with->nChannels != what->nChannels)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (with->nSamplesPerSec != 0)
|
||||
{
|
||||
if (with->nSamplesPerSec != what->nSamplesPerSec)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (with->wBitsPerSample != 0)
|
||||
{
|
||||
if (with->wBitsPerSample != what->wBitsPerSample)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL audio_format_valid(const AUDIO_FORMAT* format)
|
||||
{
|
||||
if (!format)
|
||||
return FALSE;
|
||||
|
||||
if (formatA->nChannels != formatB->nChannels)
|
||||
if (format->nChannels == 0)
|
||||
return FALSE;
|
||||
|
||||
if (formatA->nSamplesPerSec != formatB->nSamplesPerSec)
|
||||
if (format->nSamplesPerSec == 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void rdpsnd_free_audio_format(AUDIO_FORMAT* format)
|
||||
AUDIO_FORMAT* audio_format_new(void)
|
||||
{
|
||||
return audio_formats_new(1);
|
||||
}
|
||||
|
||||
AUDIO_FORMAT* audio_formats_new(size_t count)
|
||||
{
|
||||
return calloc(count, sizeof(AUDIO_FORMAT));
|
||||
}
|
||||
|
||||
void audio_format_free(AUDIO_FORMAT* format)
|
||||
{
|
||||
if (format)
|
||||
free(format->data);
|
||||
@ -249,7 +289,7 @@ void audio_formats_free(AUDIO_FORMAT* formats, size_t count)
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
AUDIO_FORMAT* format = &formats[index];
|
||||
rdpsnd_free_audio_format(format);
|
||||
audio_format_free(format);
|
||||
}
|
||||
|
||||
free(formats);
|
||||
|
@ -21,19 +21,13 @@
|
||||
#endif
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#include <freerdp/codec/dsp.h>
|
||||
#include "shadow.h"
|
||||
|
||||
#include "shadow_audin.h"
|
||||
|
||||
#define TAG SERVER_TAG("shadow")
|
||||
|
||||
/* Default supported audio formats */
|
||||
static const AUDIO_FORMAT default_supported_audio_formats[] =
|
||||
{
|
||||
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL }
|
||||
};
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
@ -42,17 +36,15 @@ static const AUDIO_FORMAT default_supported_audio_formats[] =
|
||||
static UINT AudinServerOpening(audin_server_context* context)
|
||||
{
|
||||
AUDIO_FORMAT* agreed_format = NULL;
|
||||
int i = 0, j = 0;
|
||||
size_t i = 0, j = 0;
|
||||
|
||||
for (i = 0; i < context->num_client_formats; i++)
|
||||
{
|
||||
for (j = 0; j < context->num_server_formats; j++)
|
||||
{
|
||||
if ((context->client_formats[i].wFormatTag == context->server_formats[j].wFormatTag) &&
|
||||
(context->client_formats[i].nChannels == context->server_formats[j].nChannels) &&
|
||||
(context->client_formats[i].nSamplesPerSec == context->server_formats[j].nSamplesPerSec))
|
||||
if (audio_format_compatible(&context->server_formats[j], &context->client_formats[i]))
|
||||
{
|
||||
agreed_format = (AUDIO_FORMAT*) &context->server_formats[j];
|
||||
agreed_format = &context->server_formats[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -99,36 +91,137 @@ static UINT AudinServerReceiveSamples(audin_server_context* context, const void*
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
int shadow_client_audin_init(rdpShadowClient* client)
|
||||
BOOL shadow_client_audin_init(rdpShadowClient* client)
|
||||
{
|
||||
audin_server_context* audin;
|
||||
audin = client->audin = audin_server_context_new(client->vcm);
|
||||
|
||||
if (!audin)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
audin->data = client;
|
||||
|
||||
if (client->subsystem->audinFormats)
|
||||
{
|
||||
audin->server_formats = client->subsystem->audinFormats;
|
||||
size_t x;
|
||||
audin->server_formats = audio_formats_new(client->subsystem->nAudinFormats);
|
||||
|
||||
if (!audin->server_formats)
|
||||
goto fail;
|
||||
|
||||
for (x = 0; x < client->subsystem->nAudinFormats; x++)
|
||||
{
|
||||
if (!audio_format_copy(&client->subsystem->audinFormats[x], &audin->server_formats[x]))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
audin->num_server_formats = client->subsystem->nAudinFormats;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Default supported audio formats */
|
||||
BYTE adpcm_data_7[] =
|
||||
{
|
||||
0xf4, 0x07, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x40, 0x00, 0xf0, 0x00,
|
||||
0x00, 0x00, 0xcc, 0x01, 0x30, 0xff, 0x88, 0x01, 0x18, 0xff
|
||||
};
|
||||
BYTE adpcm_data_3[] =
|
||||
{
|
||||
0xf4, 0x03, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x40, 0x00, 0xf0, 0x00,
|
||||
0x00, 0x00, 0xcc, 0x01, 0x30, 0xff, 0x88, 0x01, 0x18, 0xff
|
||||
};
|
||||
BYTE adpcm_data_1[] =
|
||||
{
|
||||
0xf4, 0x01, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x40, 0x00, 0xf0, 0x00,
|
||||
0x00, 0x00, 0xcc, 0x01, 0x30, 0xff, 0x88, 0x01, 0x18, 0xff
|
||||
};
|
||||
BYTE adpcm_dvi_data_7[] = { 0xf9, 0x07 };
|
||||
BYTE adpcm_dvi_data_3[] = { 0xf9, 0x03 };
|
||||
BYTE adpcm_dvi_data_1[] = { 0xf9, 0x01 };
|
||||
BYTE gsm610_data[] = { 0x40, 0x01 };
|
||||
const AUDIO_FORMAT default_supported_audio_formats[] =
|
||||
{
|
||||
/* Formats sent by windows 10 server */
|
||||
{ WAVE_FORMAT_AAC_MS, 2, 44100, 24000, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_AAC_MS, 2, 44100, 20000, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_AAC_MS, 2, 44100, 16000, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_AAC_MS, 2, 44100, 12000, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_ADPCM, 2, 44100, 44359, 2048, 4, 32, adpcm_data_7 },
|
||||
{ WAVE_FORMAT_DVI_ADPCM, 2, 44100, 44251, 2048, 4, 2, adpcm_dvi_data_7 },
|
||||
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL },
|
||||
{ WAVE_FORMAT_ADPCM, 2, 22050, 22311, 1024, 4, 32, adpcm_data_3 },
|
||||
{ WAVE_FORMAT_DVI_ADPCM, 2, 22050, 22201, 1024, 4, 2, adpcm_dvi_data_3 },
|
||||
{ WAVE_FORMAT_ADPCM, 1, 44100, 22179, 1024, 4, 32, adpcm_data_7 },
|
||||
{ WAVE_FORMAT_DVI_ADPCM, 1, 44100, 22125, 1024, 4, 2, adpcm_dvi_data_7 },
|
||||
{ WAVE_FORMAT_ADPCM, 2, 11025, 11289, 512, 4, 32, adpcm_data_1 },
|
||||
{ WAVE_FORMAT_DVI_ADPCM, 2, 11025, 11177, 512, 4, 2, adpcm_dvi_data_1 },
|
||||
{ WAVE_FORMAT_ADPCM, 1, 22050, 11155, 512, 4, 32, adpcm_data_3 },
|
||||
{ WAVE_FORMAT_DVI_ADPCM, 1, 22050, 11100, 512, 4, 2, adpcm_dvi_data_3 },
|
||||
{ WAVE_FORMAT_GSM610, 1, 44100, 8957, 65, 0, 2, gsm610_data },
|
||||
{ WAVE_FORMAT_ADPCM, 2, 8000, 8192, 512, 4, 32, adpcm_data_1 },
|
||||
{ WAVE_FORMAT_DVI_ADPCM, 2, 8000, 8110, 512, 4, 2, adpcm_dvi_data_1 },
|
||||
{ WAVE_FORMAT_ADPCM, 1, 11025, 5644, 256, 4, 32, adpcm_data_1 },
|
||||
{ WAVE_FORMAT_DVI_ADPCM, 1, 11025, 5588, 256, 4, 2, adpcm_dvi_data_1 },
|
||||
{ WAVE_FORMAT_GSM610, 1, 22050, 4478, 65, 0, 2, gsm610_data },
|
||||
{ WAVE_FORMAT_ADPCM, 1, 8000, 4096, 256, 4, 32, adpcm_data_1 },
|
||||
{ WAVE_FORMAT_DVI_ADPCM, 1, 8000, 4055, 256, 4, 2, adpcm_dvi_data_1 },
|
||||
{ WAVE_FORMAT_GSM610, 1, 11025, 2239, 65, 0, 2, gsm610_data },
|
||||
{ WAVE_FORMAT_GSM610, 1, 8000, 1625, 65, 0, 2, gsm610_data },
|
||||
/* Formats added for others */
|
||||
|
||||
{ WAVE_FORMAT_MSG723, 2, 44100, 176400, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_MSG723, 2, 22050, 176400, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_MSG723, 1, 44100, 176400, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_MSG723, 1, 22050, 176400, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_PCM, 2, 22050, 176400, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_PCM, 1, 44100, 176400, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_PCM, 1, 22050, 176400, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_MULAW, 2, 44100, 176400, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_MULAW, 2, 22050, 176400, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_MULAW, 1, 44100, 176400, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_MULAW, 1, 22050, 176400, 4, 16, 0, NULL },
|
||||
{ WAVE_FORMAT_ALAW, 2, 44100, 44100, 2, 8, 0, NULL },
|
||||
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL },
|
||||
{ WAVE_FORMAT_ALAW, 1, 44100, 44100, 2, 8, 0, NULL },
|
||||
{ WAVE_FORMAT_ALAW, 1, 22050, 44100, 2, 8, 0, NULL }
|
||||
};
|
||||
const size_t nrDefaultFormatsMax = ARRAYSIZE(default_supported_audio_formats);
|
||||
size_t x;
|
||||
audin->server_formats = audio_formats_new(nrDefaultFormatsMax);
|
||||
|
||||
if (!audin->server_formats)
|
||||
goto fail;
|
||||
|
||||
/* Set default audio formats. */
|
||||
audin->server_formats = default_supported_audio_formats;
|
||||
audin->num_server_formats = sizeof(default_supported_audio_formats) / sizeof(
|
||||
default_supported_audio_formats[0]);
|
||||
for (x = 0; x < nrDefaultFormatsMax; x++)
|
||||
{
|
||||
const AUDIO_FORMAT* format = &default_supported_audio_formats[x];
|
||||
|
||||
if (freerdp_dsp_supports_format(format, FALSE))
|
||||
{
|
||||
AUDIO_FORMAT* dst = &audin->server_formats[audin->num_server_formats++];
|
||||
audio_format_copy(format, dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (audin->num_server_formats < 1)
|
||||
goto fail;
|
||||
|
||||
audin->dst_format = audin->server_formats[0];
|
||||
audin->Opening = AudinServerOpening;
|
||||
audin->OpenResult = AudinServerOpenResult;
|
||||
audin->ReceiveSamples = AudinServerReceiveSamples;
|
||||
return 1;
|
||||
return TRUE;
|
||||
fail:
|
||||
audin_server_context_free(audin);
|
||||
client->audin = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void shadow_client_audin_uninit(rdpShadowClient* client)
|
||||
|
@ -28,7 +28,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int shadow_client_audin_init(rdpShadowClient* client);
|
||||
BOOL shadow_client_audin_init(rdpShadowClient* client);
|
||||
void shadow_client_audin_uninit(rdpShadowClient* client);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -43,14 +43,14 @@ static AUDIO_FORMAT supported_audio_formats[ARRAYSIZE(default_supported_audio_fo
|
||||
|
||||
static void rdpsnd_activated(RdpsndServerContext* context)
|
||||
{
|
||||
AUDIO_FORMAT* agreed_format = NULL;
|
||||
const AUDIO_FORMAT* agreed_format = NULL;
|
||||
UINT16 i = 0, j = 0;
|
||||
|
||||
for (i = 0; i < context->num_client_formats; i++)
|
||||
{
|
||||
for (j = 0; j < context->num_server_formats; j++)
|
||||
{
|
||||
if (audio_format_compatible(&context->client_formats[i], &context->server_formats[j]))
|
||||
if (audio_format_compatible(&context->server_formats[j], &context->client_formats[i]))
|
||||
{
|
||||
agreed_format = &context->server_formats[j];
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user