#include <freerdp/addin.h>
#include <freerdp/codec/dsp.h>
#include <freerdp/utils/thread.h>
+#include <freerdp/channels/rdpsnd.h>
#include "audin_main.h"
snd_strerror(error));
return FALSE;
}
+
snd_pcm_hw_params_any(capture_handle, hw_params);
- snd_pcm_hw_params_set_access(capture_handle, hw_params,
- SND_PCM_ACCESS_RW_INTERLEAVED);
- snd_pcm_hw_params_set_format(capture_handle, hw_params,
- alsa->format);
- snd_pcm_hw_params_set_rate_near(capture_handle, hw_params,
- &alsa->actual_rate, NULL);
- snd_pcm_hw_params_set_channels_near(capture_handle, hw_params,
- &alsa->actual_channels);
+ snd_pcm_hw_params_set_access(capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
+ snd_pcm_hw_params_set_format(capture_handle, hw_params, alsa->format);
+ snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &alsa->actual_rate, NULL);
+ snd_pcm_hw_params_set_channels_near(capture_handle, hw_params, &alsa->actual_channels);
snd_pcm_hw_params(capture_handle, hw_params);
snd_pcm_hw_params_free(hw_params);
snd_pcm_prepare(capture_handle);
alsa->actual_rate, alsa->actual_channels,
alsa->target_rate, alsa->target_channels);
}
+
return TRUE;
}
break;
cframes = alsa->frames_per_packet - alsa->buffer_frames;
+
if (cframes > frames)
cframes = frames;
- memcpy(alsa->buffer + alsa->buffer_frames * tbytes_per_frame,
- src, cframes * tbytes_per_frame);
+
+ CopyMemory(alsa->buffer + alsa->buffer_frames * tbytes_per_frame, src, cframes * tbytes_per_frame);
+
alsa->buffer_frames += cframes;
+
if (alsa->buffer_frames >= alsa->frames_per_packet)
{
- if (alsa->wformat == 0x11)
+ if (alsa->wformat == WAVE_FORMAT_DVI_ADPCM)
{
alsa->dsp_context->encode_ima_adpcm(alsa->dsp_context,
alsa->buffer, alsa->buffer_frames * tbytes_per_frame,
alsa->target_channels, alsa->block_size);
+
encoded_data = alsa->dsp_context->adpcm_buffer;
encoded_size = alsa->dsp_context->adpcm_size;
+
DEBUG_DVC("encoded %d to %d",
alsa->buffer_frames * tbytes_per_frame, encoded_size);
}
frames = 0;
}
else
+ {
ret = alsa->receive(encoded_data, encoded_size, alsa->user_data);
+ }
+
alsa->buffer_frames = 0;
+
if (!ret)
break;
}
+
src += cframes * tbytes_per_frame;
frames -= cframes;
}
} while (0);
free(buffer);
+
free(alsa->buffer);
alsa->buffer = NULL;
+
if (capture_handle)
snd_pcm_close(capture_handle);
{
switch (format->wFormatTag)
{
- case 1: /* PCM */
+ case WAVE_FORMAT_PCM:
if (format->cbSize == 0 &&
(format->nSamplesPerSec <= 48000) &&
(format->wBitsPerSample == 8 || format->wBitsPerSample == 16) &&
}
break;
- case 0x11: /* IMA ADPCM */
+ case WAVE_FORMAT_DVI_ADPCM:
if ((format->nSamplesPerSec <= 48000) &&
(format->wBitsPerSample == 4) &&
(format->nChannels == 1 || format->nChannels == 2))
}
break;
}
+
return FALSE;
}
alsa->actual_rate = format->nSamplesPerSec;
alsa->target_channels = format->nChannels;
alsa->actual_channels = format->nChannels;
+
switch (format->wFormatTag)
{
- case 1: /* PCM */
+ case WAVE_FORMAT_PCM:
switch (format->wBitsPerSample)
{
case 8:
}
break;
- case 0x11: /* IMA ADPCM */
+ case WAVE_FORMAT_DVI_ADPCM:
alsa->format = SND_PCM_FORMAT_S16_LE;
alsa->bytes_per_channel = 2;
bs = (format->nBlockAlign - 4 * format->nChannels) * 4;
alsa->frames_per_packet);
break;
}
+
alsa->wformat = format->wFormatTag;
alsa->block_size = format->nBlockAlign;
}
for (channels_list = g_channels_list; channels_list; channels_list = channels_list->next)
{
channels = channels_list->channels;
+
if (channels->instance == instance)
{
ReleaseMutex(g_mutex_list);
channels = ((rdpInitHandle*) pInitHandle)->channels;
- if (pOpenHandle == 0)
+ if (!pOpenHandle)
{
DEBUG_CHANNELS("error bad channel handle");
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
}
- if (pChannelOpenEventProc == 0)
+ if (!pChannelOpenEventProc)
{
DEBUG_CHANNELS("error bad proc");
return CHANNEL_RC_BAD_PROC;
lchannel_data = freerdp_channels_find_channel_data_by_name(channels, pChannelName, &index);
- if (lchannel_data == 0)
+ if (!lchannel_data)
{
DEBUG_CHANNELS("error channel name");
return CHANNEL_RC_UNKNOWN_CHANNEL_NAME;
return CHANNEL_RC_NOT_CONNECTED;
}
- if (pData == 0)
+ if (!pData)
{
DEBUG_CHANNELS("error bad pData");
return CHANNEL_RC_NULL_DATA;
}
- if (dataLength == 0)
+ if (!dataLength)
{
DEBUG_CHANNELS("error bad dataLength");
return CHANNEL_RC_ZERO_LENGTH;
channels = freerdp_channels_find_by_open_handle(openHandle, &index);
- if ((channels == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT))
+ if ((!channels) || (index < 0) || (index >= CHANNEL_MAX_COUNT))
{
DEBUG_CHANNELS("error bad channels handle");
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
return CHANNEL_RC_NOT_CONNECTED;
}
- if (event == NULL)
+ if (!event)
{
DEBUG_CHANNELS("error bad event");
return CHANNEL_RC_NULL_DATA;
}
channels->event = event;
+
/* set the event */
SetEvent(channels->signal);
channels = freerdp_channels_find_by_instance(instance);
- if (channels == 0)
+ if (!channels)
{
DEBUG_CHANNELS("could not find channel manager");
return 1;
}
- lrdp_channel = freerdp_channels_find_channel_by_id(channels, instance->settings,
- channel_id, &index);
- if (lrdp_channel == 0)
+ lrdp_channel = freerdp_channels_find_channel_by_id(channels, instance->settings, channel_id, &index);
+
+ if (!lrdp_channel)
{
DEBUG_CHANNELS("could not find channel id");
return 1;
lchannel_data = freerdp_channels_find_channel_data_by_name(channels, lrdp_channel->Name, &index);
- if (lchannel_data == 0)
+ if (!lchannel_data)
{
DEBUG_CHANNELS("could not find channel name");
return 1;
lrdp_channel = freerdp_channels_find_channel_by_name(channels, instance->settings,
lchannel_data->name, &item->Index);
- if (lrdp_channel != NULL)
+ if (lrdp_channel)
instance->SendChannelData(instance, lrdp_channel->ChannelId, item->Data, item->DataLength);
- if (lchannel_data->open_event_proc != 0)
+ if (lchannel_data->open_event_proc)
{
lchannel_data->open_event_proc(lchannel_data->open_handle,
CHANNEL_EVENT_WRITE_COMPLETE, item->UserData, sizeof(void*), sizeof(void*), 0);
#include <freerdp/addin.h>
#include <freerdp/constants.h>
#include <freerdp/utils/stream.h>
-#include <freerdp/utils/list.h>
#include <freerdp/utils/svc_plugin.h>
#include "rdpsnd_main.h"
+#define TIME_DELAY_MS 250
+
struct rdpsnd_plugin
{
rdpSvcPlugin plugin;
wMessagePipe* MsgPipe;
+ HANDLE thread;
BYTE cBlockNo;
rdpsndFormat* supported_formats;
rdpsndDevicePlugin* device;
};
-/* process the linked list of data that has queued to be sent */
-static void rdpsnd_process_interval(rdpSvcPlugin* plugin)
+static void* rdpsnd_schedule_thread(void* arg)
{
STREAM* data;
wMessage message;
+ UINT16 wTimeDiff;
UINT16 wTimeStamp;
UINT16 wCurrentTime;
- rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin;
+ rdpsndPlugin* rdpsnd = (rdpsndPlugin*) arg;
- while (MessageQueue_Peek(rdpsnd->MsgPipe->Out, &message, FALSE))
+ while (1)
{
+ if (!MessageQueue_Wait(rdpsnd->MsgPipe->Out))
+ break;
+
+ if (!MessageQueue_Peek(rdpsnd->MsgPipe->Out, &message, TRUE))
+ break;
+
if (message.id == WMQ_QUIT)
break;
wTimeStamp = (UINT16) (size_t) message.lParam;
wCurrentTime = (UINT16) GetTickCount();
- if (wCurrentTime <= wTimeStamp)
- break;
+ //printf("wTimeStamp: %d wCurrentTime: %d\n", wTimeStamp, wCurrentTime);
- if (MessageQueue_Peek(rdpsnd->MsgPipe->Out, &message, TRUE))
+ if (wCurrentTime <= wTimeStamp)
{
- data = (STREAM*) message.wParam;
- svc_plugin_send(plugin, data);
-
- DEBUG_SVC("processed output data");
+ wTimeDiff = wTimeStamp - wCurrentTime;
+ //printf("Sleeping %d ms\n", wTimeDiff);
+ Sleep(wTimeDiff);
}
+
+ data = (STREAM*) message.wParam;
+ svc_plugin_send((rdpSvcPlugin*) rdpsnd, data);
+ DEBUG_SVC("processed output data");
}
+#if 0
if (rdpsnd->is_open && (rdpsnd->close_timestamp > 0))
{
if (GetTickCount() > rdpsnd->close_timestamp)
DEBUG_SVC("processed close");
}
}
+#endif
- if ((MessageQueue_Size(rdpsnd->MsgPipe->Out) == 0) && !rdpsnd->is_open)
- rdpsnd->plugin.interval_ms = 0;
+ return NULL;
}
static void rdpsnd_free_supported_formats(rdpsndPlugin* rdpsnd)
static void rdpsnd_process_message_wave(rdpsndPlugin* rdpsnd, STREAM* data_in)
{
STREAM* data;
- UINT32 delay_ms;
UINT16 wTimeStamp;
rdpsnd->expectingWave = 0;
IFCALL(rdpsnd->device->Play, rdpsnd->device, stream_get_head(data_in), stream_get_size(data_in));
}
- delay_ms = 250;
- wTimeStamp = rdpsnd->wTimeStamp + delay_ms;
-
- DEBUG_SVC("data_size %d delay_ms %u process_ms %u",
- stream_get_size(data_in), delay_ms, process_ms);
+ wTimeStamp = rdpsnd->wTimeStamp + TIME_DELAY_MS;
data = stream_new(8);
stream_write_BYTE(data, SNDC_WAVECONFIRM);
stream_write_BYTE(data, rdpsnd->cBlockNo); /* cConfirmedBlockNo */
stream_write_BYTE(data, 0); /* bPad */
- wTimeStamp = rdpsnd->wave_timestamp + delay_ms;
+ wTimeStamp = rdpsnd->wave_timestamp + TIME_DELAY_MS;
MessageQueue_Post(rdpsnd->MsgPipe->Out, NULL, 0, (void*) data, (void*) (size_t) wTimeStamp);
-
- rdpsnd->plugin.interval_ms = 10;
}
static void rdpsnd_process_message_close(rdpsndPlugin* rdpsnd)
}
rdpsnd->close_timestamp = GetTickCount() + 2000;
- rdpsnd->plugin.interval_ms = 10;
}
static void rdpsnd_process_message_setvolume(rdpsndPlugin* rdpsnd, STREAM* data_in)
static void rdpsnd_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
{
- rdpsndPlugin* rdpsnd = (rdpsndPlugin*)plugin;
+ rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin;
BYTE msgType;
UINT16 BodySize;
DEBUG_SVC("connecting");
- plugin->interval_callback = rdpsnd_process_interval;
-
rdpsnd->latency = -1;
rdpsnd->MsgPipe = MessagePipe_New();
+ rdpsnd->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpsnd_schedule_thread, (void*) plugin, 0, NULL);
args = (ADDIN_ARGV*) plugin->channel_entry_points.pExtendedData;
rdpSvcPlugin plugin;
/* put your private data here */
-
};
-static void sample_process_interval(rdpSvcPlugin* plugin)
-{
- printf("sample_process_interval:\n");
-}
-
static void sample_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
{
int bytes;
printf("sample_process_receive:\n");
- if (sample == NULL)
+ if (!sample)
{
printf("sample_process_receive: sample is nil\n");
return;
}
- /* process data in(from server) here */
+ /* process data in (from server) here */
/* here we just send the same data back */
bytes = stream_get_size(data_in);
printf("sample_process_receive: got bytes %d\n", bytes);
+
if (bytes > 0)
{
data_out = stream_new(bytes);
printf("sample_process_connect:\n");
- if (sample == NULL)
- {
+ if (!sample)
return;
- }
-
- /* if you want a call from channel thread once is a while do this */
- plugin->interval_ms = 1000;
- plugin->interval_callback = sample_process_interval;
-
}
static void sample_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event)
{
printf("sample_process_event:\n");
- /* events comming from main freerdp window to plugin */
+ /* events coming from main freerdp window to plugin */
/* send them back with svc_plugin_send_event */
freerdp_event_free(event);
static void sample_process_terminate(rdpSvcPlugin* plugin)
{
- samplePlugin* sample = (samplePlugin*)plugin;
+ samplePlugin* sample = (samplePlugin*) plugin;
printf("sample_process_terminate:\n");
- if (sample == NULL)
- {
+ if (!sample)
return;
- }
/* put your cleanup here */
CHANNEL_ENTRY_POINTS_EX channel_entry_points;
CHANNEL_DEF channel_def;
- int interval_ms;
-
void (*connect_callback)(rdpSvcPlugin* plugin);
void (*receive_callback)(rdpSvcPlugin* plugin, STREAM* data_in);
void (*event_callback)(rdpSvcPlugin* plugin, RDP_EVENT* event);
- void (*interval_callback)(rdpSvcPlugin* plugin);
void (*terminate_callback)(rdpSvcPlugin* plugin);
HANDLE thread;
}
}
- if (channel == NULL)
+ if (!channel)
{
printf("freerdp_channel_send: unknown channel_id %d\n", channel_id);
return FALSE;
flags = CHANNEL_FLAG_FIRST;
left = size;
+
while (left > 0)
{
s = rdp_send_stream_init(rdp);
chunk_size = left;
flags |= CHANNEL_FLAG_LAST;
}
+
if ((channel->options & CHANNEL_OPTION_SHOW_PROTOCOL))
{
flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
UINT32 flags;
int chunk_length;
- if(stream_get_left(s) < 8)
+ if (stream_get_left(s) < 8)
return FALSE;
+
stream_read_UINT32(s, length);
stream_read_UINT32(s, flags);
chunk_length = stream_get_left(s);
IFCALL(instance->ReceiveChannelData, instance,
channel_id, stream_get_tail(s), chunk_length, flags, length);
+
return TRUE;
}
length += rdp_security_stream_out(rdp, s, length);
stream_set_pos(s, length);
+
if (transport_write(rdp->transport, s) < 0)
return FALSE;
while (1)
{
- if (plugin->interval_ms > 0)
- {
- Sleep(plugin->interval_ms);
- }
- else
- {
- if (!MessageQueue_Wait(plugin->MsgPipe->In))
- break;
- }
+ if (!MessageQueue_Wait(plugin->MsgPipe->In))
+ break;
if (MessageQueue_Peek(plugin->MsgPipe->In, &message, TRUE))
{
IFCALL(plugin->event_callback, plugin, event);
}
}
-
- if (plugin->interval_ms > 0)
- IFCALL(plugin->interval_callback, plugin);
}
DEBUG_SVC("out");