Esempio n. 1
0
static BOOL rdpsnd_winmm_open(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency)
{
	MMRESULT mmResult;
	rdpsndWinmmPlugin* winmm = (rdpsndWinmmPlugin*) device;

	if (winmm->hWaveOut)
		return TRUE;

	rdpsnd_winmm_set_format(device, format, latency);
	freerdp_dsp_context_reset_adpcm(winmm->dsp_context);

	mmResult = waveOutOpen(&winmm->hWaveOut, WAVE_MAPPER, &winmm->format,
			(DWORD_PTR) rdpsnd_winmm_callback_function, (DWORD_PTR) winmm, CALLBACK_FUNCTION);

	if (mmResult != MMSYSERR_NOERROR)
	{
		WLog_ERR(TAG,  "waveOutOpen failed: %"PRIu32"", mmResult);
		return FALSE;
	}

	mmResult = waveOutSetVolume(winmm->hWaveOut, winmm->volume);

	if (mmResult != MMSYSERR_NOERROR)
	{
		WLog_ERR(TAG,  "waveOutSetVolume failed: %"PRIu32"", mmResult);
		return FALSE;
	}

	return TRUE;
}
Esempio n. 2
0
static void* audin_alsa_thread_func(void* arg)
{
	int error;
	uint8* buffer;
	int rbytes_per_frame;
	int tbytes_per_frame;
	snd_pcm_t* capture_handle = NULL;
	AudinALSADevice* alsa = (AudinALSADevice*) arg;

	DEBUG_DVC("in");

	rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel;
	tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel;
	alsa->buffer = (uint8*) xzalloc(tbytes_per_frame * alsa->frames_per_packet);
	alsa->buffer_frames = 0;
	buffer = (uint8*) xzalloc(rbytes_per_frame * alsa->frames_per_packet);
	freerdp_dsp_context_reset_adpcm(alsa->dsp_context);
	do
	{
		if ((error = snd_pcm_open(&capture_handle, alsa->device_name, SND_PCM_STREAM_CAPTURE, 0)) < 0)
		{
			DEBUG_WARN("snd_pcm_open (%s)", snd_strerror(error));
			break;
		}
		if (!audin_alsa_set_params(alsa, capture_handle))
		{
			break;
		}

		while (!freerdp_thread_is_stopped(alsa->thread))
		{
			error = snd_pcm_readi(capture_handle, buffer, alsa->frames_per_packet);
			if (error == -EPIPE)
			{
				snd_pcm_recover(capture_handle, error, 0);
				continue;
			}
			else if (error < 0)
			{
				DEBUG_WARN("snd_pcm_readi (%s)", snd_strerror(error));
				break;
			}
			if (!audin_alsa_thread_receive(alsa, buffer, error * rbytes_per_frame))
				break;
		}
	} while (0);

	xfree(buffer);
	xfree(alsa->buffer);
	alsa->buffer = NULL;
	if (capture_handle)
		snd_pcm_close(capture_handle);

	freerdp_thread_quit(alsa->thread);

	DEBUG_DVC("out");

	return NULL;
}
Esempio n. 3
0
static void rdpsnd_server_select_format(rdpsnd_server_context* context, int client_format_index)
{
	int bs;
	int out_buffer_size;
	rdpsndFormat *format;
	rdpsnd_server* rdpsnd = (rdpsnd_server*) context;

	if (client_format_index < 0 || client_format_index >= context->num_client_formats)
	{
		printf("rdpsnd_server_select_format: index %d is not correct.\n", client_format_index);
		return;
	}

	rdpsnd->src_bytes_per_sample = context->src_format.wBitsPerSample / 8;
	rdpsnd->src_bytes_per_frame = rdpsnd->src_bytes_per_sample * context->src_format.nChannels;

	context->selected_client_format = client_format_index;
	format = &context->client_formats[client_format_index];

	if (format->wFormatTag == 0x11)
	{
		bs = (format->nBlockAlign - 4 * format->nChannels) * 4;
		rdpsnd->out_frames = (format->nBlockAlign * 4 * format->nChannels * 2 / bs + 1) * bs / (format->nChannels * 2);
	}
	else if (format->wFormatTag == 0x02)
	{
		bs = (format->nBlockAlign - 7 * format->nChannels) * 2 / format->nChannels + 2;
		rdpsnd->out_frames = bs * 4;
	}
	else
	{
		rdpsnd->out_frames = 0x4000 / rdpsnd->src_bytes_per_frame;
	}

	if (format->nSamplesPerSec != context->src_format.nSamplesPerSec)
	{
		rdpsnd->out_frames = (rdpsnd->out_frames * context->src_format.nSamplesPerSec + format->nSamplesPerSec - 100) / format->nSamplesPerSec;
	}
	rdpsnd->out_pending_frames = 0;

	out_buffer_size = rdpsnd->out_frames * rdpsnd->src_bytes_per_frame;
	
	if (rdpsnd->out_buffer_size < out_buffer_size)
	{
		rdpsnd->out_buffer = (BYTE*) realloc(rdpsnd->out_buffer, out_buffer_size);
		rdpsnd->out_buffer_size = out_buffer_size;
	}

	freerdp_dsp_context_reset_adpcm(rdpsnd->dsp_context);
}
Esempio n. 4
0
static void rdpsnd_pulse_open(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
{
	rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
	pa_stream_state_t state;
	pa_stream_flags_t flags;
	pa_buffer_attr buffer_attr = { 0 };
	char ss[PA_SAMPLE_SPEC_SNPRINT_MAX];

	if (!pulse->context || pulse->stream)
	{
		DEBUG_WARN("pulse stream has been created.");
		return;
	}

	rdpsnd_pulse_set_format_spec(pulse, format);
	pulse->latency = latency;

	if (pa_sample_spec_valid(&pulse->sample_spec) == 0)
	{
		pa_sample_spec_snprint(ss, sizeof(ss), &pulse->sample_spec);
		DEBUG_WARN("Invalid sample spec %s", ss);
		return;
	}

	pa_threaded_mainloop_lock(pulse->mainloop);
	pulse->stream = pa_stream_new(pulse->context, "freerdp",
		&pulse->sample_spec, NULL);
	if (!pulse->stream)
	{
		pa_threaded_mainloop_unlock(pulse->mainloop);
		DEBUG_WARN("pa_stream_new failed (%d)",
			pa_context_errno(pulse->context));
		return;
	}

	/* install essential callbacks */
	pa_stream_set_state_callback(pulse->stream,
		rdpsnd_pulse_stream_state_callback, pulse);
	pa_stream_set_write_callback(pulse->stream,
		rdpsnd_pulse_stream_request_callback, pulse);

	flags = PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE;
	if (pulse->latency > 0)
	{
		buffer_attr.maxlength = pa_usec_to_bytes(pulse->latency * 2 * 1000, &pulse->sample_spec);
		buffer_attr.tlength = pa_usec_to_bytes(pulse->latency * 1000, &pulse->sample_spec);
		buffer_attr.prebuf = (uint32_t) -1;
		buffer_attr.minreq = (uint32_t) -1;
		buffer_attr.fragsize = (uint32_t) -1;
		flags |= PA_STREAM_ADJUST_LATENCY;
	}
	if (pa_stream_connect_playback(pulse->stream,
		pulse->device_name, pulse->latency > 0 ? &buffer_attr : NULL, flags, NULL, NULL) < 0)
	{
		pa_threaded_mainloop_unlock(pulse->mainloop);
		DEBUG_WARN("pa_stream_connect_playback failed (%d)",
			pa_context_errno(pulse->context));
		return;
	}

	for (;;)
	{
		state = pa_stream_get_state(pulse->stream);
		if (state == PA_STREAM_READY)
			break;
		if (!PA_STREAM_IS_GOOD(state))
		{
			DEBUG_WARN("bad stream state (%d)",
				pa_context_errno(pulse->context));
			break;
		}
		pa_threaded_mainloop_wait(pulse->mainloop);
	}
	pa_threaded_mainloop_unlock(pulse->mainloop);
	if (state == PA_STREAM_READY)
	{
		freerdp_dsp_context_reset_adpcm(pulse->dsp_context);
		DEBUG_SVC("connected");
	}
	else
	{
		rdpsnd_pulse_close(device);
	}
}
Esempio n. 5
0
static BOOL rdpsnd_server_select_format(RdpsndServerContext* context, int client_format_index)
{
	int bs;
	int out_buffer_size;
	AUDIO_FORMAT *format;

	if (client_format_index < 0 || client_format_index >= context->num_client_formats)
	{
		fprintf(stderr, "%s: index %d is not correct.\n", __FUNCTION__, client_format_index);
		return FALSE;
	}
	
	context->priv->src_bytes_per_sample = context->src_format.wBitsPerSample / 8;
	context->priv->src_bytes_per_frame = context->priv->src_bytes_per_sample * context->src_format.nChannels;

	context->selected_client_format = client_format_index;
	format = &context->client_formats[client_format_index];
	
	if (format->nSamplesPerSec == 0)
	{
		fprintf(stderr, "%s: invalid Client Sound Format!!\n", __FUNCTION__);
		return FALSE;
	}

	switch(format->wFormatTag)
	{
		case WAVE_FORMAT_DVI_ADPCM:
			bs = (format->nBlockAlign - 4 * format->nChannels) * 4;
			context->priv->out_frames = (format->nBlockAlign * 4 * format->nChannels * 2 / bs + 1) * bs / (format->nChannels * 2);
			break;

		case WAVE_FORMAT_ADPCM:
			bs = (format->nBlockAlign - 7 * format->nChannels) * 2 / format->nChannels + 2;
			context->priv->out_frames = bs * 4;
			break;
		default:
			context->priv->out_frames = 0x4000 / context->priv->src_bytes_per_frame;
			break;
	}

	if (format->nSamplesPerSec != context->src_format.nSamplesPerSec)
	{
		context->priv->out_frames = (context->priv->out_frames * context->src_format.nSamplesPerSec + format->nSamplesPerSec - 100) / format->nSamplesPerSec;
	}
	context->priv->out_pending_frames = 0;

	out_buffer_size = context->priv->out_frames * context->priv->src_bytes_per_frame;
	
	if (context->priv->out_buffer_size < out_buffer_size)
	{
		BYTE *newBuffer;

		newBuffer = (BYTE *)realloc(context->priv->out_buffer, out_buffer_size);
		if (!newBuffer)
			return FALSE;

		context->priv->out_buffer = newBuffer;
		context->priv->out_buffer_size = out_buffer_size;
	}

	freerdp_dsp_context_reset_adpcm(context->priv->dsp_context);
	return TRUE;
}
Esempio n. 6
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_select_format(RdpsndServerContext* context, int client_format_index)
{
	int bs;
	int out_buffer_size;
	AUDIO_FORMAT *format;
	UINT error = CHANNEL_RC_OK;

	if (client_format_index < 0 || client_format_index >= context->num_client_formats)
	{
		WLog_ERR(TAG,  "index %d is not correct.", client_format_index);
		return ERROR_INVALID_DATA;
	}
	
	EnterCriticalSection(&context->priv->lock);

	context->priv->src_bytes_per_sample = context->src_format.wBitsPerSample / 8;
	context->priv->src_bytes_per_frame = context->priv->src_bytes_per_sample * context->src_format.nChannels;

	context->selected_client_format = client_format_index;
	format = &context->client_formats[client_format_index];
	
	if (format->nSamplesPerSec == 0)
	{
		WLog_ERR(TAG,  "invalid Client Sound Format!!");
		error = ERROR_INVALID_DATA;
		goto out;
	}

	if (context->latency <= 0)
		context->latency = 50;
	context->priv->out_frames = context->src_format.nSamplesPerSec * context->latency / 1000;
	if (context->priv->out_frames < 1)
		context->priv->out_frames = 1;
	switch(format->wFormatTag)
	{
		case WAVE_FORMAT_DVI_ADPCM:
			bs = (format->nBlockAlign - 4 * format->nChannels) * 4;
			context->priv->out_frames -= context->priv->out_frames % bs;
			if (context->priv->out_frames < bs)
				context->priv->out_frames = bs;
			break;

		case WAVE_FORMAT_ADPCM:
			bs = (format->nBlockAlign - 7 * format->nChannels) * 2 / format->nChannels + 2;
			context->priv->out_frames -= context->priv->out_frames % bs;
			if (context->priv->out_frames < bs)
				context->priv->out_frames = bs;
			break;
	}
	context->priv->out_pending_frames = 0;

	out_buffer_size = context->priv->out_frames * context->priv->src_bytes_per_frame;
	
	if (context->priv->out_buffer_size < out_buffer_size)
	{
		BYTE *newBuffer;

		newBuffer = (BYTE *)realloc(context->priv->out_buffer, out_buffer_size);
		if (!newBuffer)
		{
			WLog_ERR(TAG, "realloc failed!");
			error = CHANNEL_RC_NO_MEMORY;
			goto out;
		}

		context->priv->out_buffer = newBuffer;
		context->priv->out_buffer_size = out_buffer_size;
	}

	freerdp_dsp_context_reset_adpcm(context->priv->dsp_context);

out:
	LeaveCriticalSection(&context->priv->lock);
	return error;
}