Blame libfreerdp/codec/dsp.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit 1fb8d4
 * Digital Sound Processing
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2010-2011 Vic Lee
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <assert.h>
Packit 1fb8d4
#include <stdio.h>
Packit 1fb8d4
#include <stdlib.h>
Packit 1fb8d4
#include <string.h>
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
Packit 1fb8d4
#include <freerdp/types.h>
Packit 1fb8d4
#include <freerdp/log.h>
Packit 1fb8d4
#include <freerdp/codec/dsp.h>
Packit 1fb8d4
Packit 1fb8d4
#if !defined(WITH_DSP_FFMPEG)
Packit 1fb8d4
#if defined(WITH_GSM)
Packit 1fb8d4
#include <gsm/gsm.h>
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_LAME)
Packit 1fb8d4
#include <lame/lame.h>
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_FAAD2)
Packit 1fb8d4
#include <neaacdec.h>
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_FAAC)
Packit 1fb8d4
#include <faac.h>
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_SOXR)
Packit 1fb8d4
#include <soxr.h>
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#else
Packit 1fb8d4
#include "dsp_ffmpeg.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#define TAG FREERDP_TAG("dsp")
Packit 1fb8d4
Packit 1fb8d4
#if !defined(WITH_DSP_FFMPEG)
Packit 1fb8d4
Packit 1fb8d4
union _ADPCM
Packit 1fb8d4
{
Packit 1fb8d4
	struct
Packit 1fb8d4
	{
Packit 1fb8d4
		INT16 last_sample[2];
Packit 1fb8d4
		INT16 last_step[2];
Packit 1fb8d4
	} ima;
Packit 1fb8d4
	struct
Packit 1fb8d4
	{
Packit 1fb8d4
		BYTE predictor[2];
Packit 1fb8d4
		INT32 delta[2];
Packit 1fb8d4
		INT32 sample1[2];
Packit 1fb8d4
		INT32 sample2[2];
Packit 1fb8d4
	} ms;
Packit 1fb8d4
};
Packit 1fb8d4
typedef union _ADPCM ADPCM;
Packit 1fb8d4
Packit 1fb8d4
struct _FREERDP_DSP_CONTEXT
Packit 1fb8d4
{
Packit 1fb8d4
	BOOL encoder;
Packit 1fb8d4
Packit 1fb8d4
	ADPCM adpcm;
Packit 1fb8d4
	AUDIO_FORMAT format;
Packit 1fb8d4
Packit 1fb8d4
	wStream* buffer;
Packit 1fb8d4
	wStream* resample;
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_GSM)
Packit 1fb8d4
	gsm gsm;
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_LAME)
Packit 1fb8d4
	lame_t lame;
Packit 1fb8d4
	hip_t hip;
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_FAAD2)
Packit 1fb8d4
	NeAACDecHandle faad;
Packit 1fb8d4
	BOOL faadSetup;
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_FAAC)
Packit 1fb8d4
	faacEncHandle faac;
Packit 1fb8d4
	unsigned long faacInputSamples;
Packit 1fb8d4
	unsigned long faacMaxOutputBytes;
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_SOXR)
Packit 1fb8d4
	soxr_t sox;
Packit 1fb8d4
#endif
Packit 1fb8d4
};
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Microsoft Multimedia Standards Update
Packit 1fb8d4
 * http://download.microsoft.com/download/9/8/6/9863C72A-A3AA-4DDB-B1BA-CA8D17EFD2D4/RIFFNEW.pdf
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
static BOOL freerdp_dsp_resample(FREERDP_DSP_CONTEXT* context,
Packit 1fb8d4
                                 const BYTE* src, size_t size,
Packit 1fb8d4
                                 const AUDIO_FORMAT* srcFormat,
Packit 1fb8d4
                                 const BYTE** data, size_t* length)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_SOXR)
Packit 1fb8d4
	soxr_error_t error;
Packit 1fb8d4
	size_t idone, odone;
Packit 1fb8d4
#endif
Packit 1fb8d4
	size_t sframes, rframes;
Packit 1fb8d4
	size_t rsize;
Packit 1fb8d4
	size_t j;
Packit 1fb8d4
	size_t sbytes, rbytes;
Packit 1fb8d4
	size_t srcBytesPerFrame, dstBytesPerFrame;
Packit 1fb8d4
	size_t srcChannels, dstChannels;
Packit 1fb8d4
	AUDIO_FORMAT format;
Packit 1fb8d4
Packit 1fb8d4
	if (srcFormat->wFormatTag != WAVE_FORMAT_PCM)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "%s requires %s for sample input, got %s", __FUNCTION__,
Packit 1fb8d4
		         audio_format_get_tag_string(WAVE_FORMAT_PCM),
Packit 1fb8d4
		         audio_format_get_tag_string(srcFormat->wFormatTag));
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	srcChannels = srcFormat->nChannels;
Packit 1fb8d4
	dstChannels = context->format.nChannels;
Packit 1fb8d4
	srcBytesPerFrame = (srcFormat->wBitsPerSample > 8) ? 2 : 1;
Packit 1fb8d4
	dstBytesPerFrame = (context->format.wBitsPerSample > 8) ? 2 : 1;
Packit 1fb8d4
	/* We want to ignore differences of source and destination format. */
Packit 1fb8d4
	format = *srcFormat;
Packit 1fb8d4
	format.wFormatTag = WAVE_FORMAT_UNKNOWN;
Packit 1fb8d4
Packit 1fb8d4
	if (audio_format_compatible(&format, &context->format))
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_SOXR)
Packit 1fb8d4
	sbytes = srcChannels * srcBytesPerFrame;
Packit 1fb8d4
	sframes = size / sbytes;
Packit 1fb8d4
	rbytes = dstBytesPerFrame * dstChannels;
Packit 1fb8d4
	/* Integer rounding correct division */
Packit 1fb8d4
	rframes = (sframes * context->format.nSamplesPerSec + (srcFormat->nSamplesPerSec + 1) / 2) /
Packit 1fb8d4
	          srcFormat->nSamplesPerSec;
Packit 1fb8d4
	rsize = rframes * rbytes;
Packit 1fb8d4
Packit 1fb8d4
	if (!Stream_EnsureCapacity(context->resample, rsize))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	error = soxr_process(context->sox, src, sframes, &idone,
Packit 1fb8d4
	                     Stream_Buffer(context->resample),
Packit 1fb8d4
	                     Stream_Capacity(context->resample) / rbytes, &odone);
Packit 1fb8d4
	Stream_SetLength(context->resample, odone * rbytes);
Packit 1fb8d4
	*data = Stream_Buffer(context->resample);
Packit 1fb8d4
	*length = Stream_Length(context->resample);
Packit 1fb8d4
	return (error == 0) ? TRUE : FALSE;
Packit 1fb8d4
#else
Packit 1fb8d4
	WLog_ERR(TAG, "Missing resample support, recompile -DWITH_SOXR=ON or -DWITH_DSP_FFMPEG=ON");
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
#endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Microsoft IMA ADPCM specification:
Packit 1fb8d4
 *
Packit 1fb8d4
 * http://wiki.multimedia.cx/index.php?title=Microsoft_IMA_ADPCM
Packit 1fb8d4
 * http://wiki.multimedia.cx/index.php?title=IMA_ADPCM
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
static const INT16 ima_step_index_table[] =
Packit 1fb8d4
{
Packit 1fb8d4
	-1, -1, -1, -1, 2, 4, 6, 8,
Packit 1fb8d4
	    -1, -1, -1, -1, 2, 4, 6, 8
Packit 1fb8d4
    };
Packit 1fb8d4
Packit 1fb8d4
static const INT16 ima_step_size_table[] =
Packit 1fb8d4
{
Packit 1fb8d4
	7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
Packit 1fb8d4
	19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
Packit 1fb8d4
	50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
Packit 1fb8d4
	130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
Packit 1fb8d4
	337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
Packit 1fb8d4
	876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
Packit 1fb8d4
	2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
Packit 1fb8d4
	5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
Packit 1fb8d4
	15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Packit 1fb8d4
};
Packit 1fb8d4
Packit 1fb8d4
static UINT16 dsp_decode_ima_adpcm_sample(ADPCM* adpcm,
Packit 1fb8d4
        unsigned int channel, BYTE sample)
Packit 1fb8d4
{
Packit 1fb8d4
	INT32 ss;
Packit 1fb8d4
	INT32 d;
Packit 1fb8d4
	ss = ima_step_size_table[adpcm->ima.last_step[channel]];
Packit 1fb8d4
	d = (ss >> 3);
Packit 1fb8d4
Packit 1fb8d4
	if (sample & 1)
Packit 1fb8d4
		d += (ss >> 2);
Packit 1fb8d4
Packit 1fb8d4
	if (sample & 2)
Packit 1fb8d4
		d += (ss >> 1);
Packit 1fb8d4
Packit 1fb8d4
	if (sample & 4)
Packit 1fb8d4
		d += ss;
Packit 1fb8d4
Packit 1fb8d4
	if (sample & 8)
Packit 1fb8d4
		d = -d;
Packit 1fb8d4
Packit 1fb8d4
	d += adpcm->ima.last_sample[channel];
Packit 1fb8d4
Packit 1fb8d4
	if (d < -32768)
Packit 1fb8d4
		d = -32768;
Packit 1fb8d4
	else if (d > 32767)
Packit 1fb8d4
		d = 32767;
Packit 1fb8d4
Packit 1fb8d4
	adpcm->ima.last_sample[channel] = (INT16) d;
Packit 1fb8d4
	adpcm->ima.last_step[channel] += ima_step_index_table[sample];
Packit 1fb8d4
Packit 1fb8d4
	if (adpcm->ima.last_step[channel] < 0)
Packit 1fb8d4
		adpcm->ima.last_step[channel] = 0;
Packit 1fb8d4
	else if (adpcm->ima.last_step[channel] > 88)
Packit 1fb8d4
		adpcm->ima.last_step[channel] = 88;
Packit 1fb8d4
Packit 1fb8d4
	return (UINT16) d;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* context,
Packit 1fb8d4
        const BYTE* src, size_t size, wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
	BYTE* dst;
Packit 1fb8d4
	BYTE sample;
Packit 1fb8d4
	UINT16 decoded;
Packit 1fb8d4
	UINT32 out_size = size * 4;
Packit 1fb8d4
	UINT32 channel;
Packit 1fb8d4
	const UINT32 block_size = context->format.nBlockAlign;
Packit 1fb8d4
	const UINT32 channels = context->format.nChannels;
Packit 1fb8d4
	int i;
Packit 1fb8d4
Packit 1fb8d4
	if (!Stream_EnsureCapacity(out, out_size))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	dst = Stream_Pointer(out);
Packit 1fb8d4
Packit 1fb8d4
	while (size > 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (size % block_size == 0)
Packit 1fb8d4
		{
Packit 1fb8d4
			context->adpcm.ima.last_sample[0] = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
Packit 1fb8d4
			context->adpcm.ima.last_step[0] = (INT16)(*(src + 2));
Packit 1fb8d4
			src += 4;
Packit 1fb8d4
			size -= 4;
Packit 1fb8d4
			out_size -= 16;
Packit 1fb8d4
Packit 1fb8d4
			if (channels > 1)
Packit 1fb8d4
			{
Packit 1fb8d4
				context->adpcm.ima.last_sample[1] = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
Packit 1fb8d4
				context->adpcm.ima.last_step[1] = (INT16)(*(src + 2));
Packit 1fb8d4
				src += 4;
Packit 1fb8d4
				size -= 4;
Packit 1fb8d4
				out_size -= 16;
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		if (channels > 1)
Packit 1fb8d4
		{
Packit 1fb8d4
			for (i = 0; i < 8; i++)
Packit 1fb8d4
			{
Packit 1fb8d4
				channel = (i < 4 ? 0 : 1);
Packit 1fb8d4
				sample = ((*src) & 0x0f);
Packit 1fb8d4
				decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, channel, sample);
Packit 1fb8d4
				dst[((i & 3) << 3) + (channel << 1)] = (decoded & 0xFF);
Packit 1fb8d4
				dst[((i & 3) << 3) + (channel << 1) + 1] = (decoded >> 8);
Packit 1fb8d4
				sample = ((*src) >> 4);
Packit 1fb8d4
				decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, channel, sample);
Packit 1fb8d4
				dst[((i & 3) << 3) + (channel << 1) + 4] = (decoded & 0xFF);
Packit 1fb8d4
				dst[((i & 3) << 3) + (channel << 1) + 5] = (decoded >> 8);
Packit 1fb8d4
				src++;
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			dst += 32;
Packit 1fb8d4
			size -= 8;
Packit 1fb8d4
		}
Packit 1fb8d4
		else
Packit 1fb8d4
		{
Packit 1fb8d4
			sample = ((*src) & 0x0f);
Packit 1fb8d4
			decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, 0, sample);
Packit 1fb8d4
			*dst++ = (decoded & 0xFF);
Packit 1fb8d4
			*dst++ = (decoded >> 8);
Packit 1fb8d4
			sample = ((*src) >> 4);
Packit 1fb8d4
			decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, 0, sample);
Packit 1fb8d4
			*dst++ = (decoded & 0xFF);
Packit 1fb8d4
			*dst++ = (decoded >> 8);
Packit 1fb8d4
			src++;
Packit 1fb8d4
			size--;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	Stream_SetPointer(out, dst);
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_GSM)
Packit 1fb8d4
static BOOL freerdp_dsp_decode_gsm610(FREERDP_DSP_CONTEXT* context,
Packit 1fb8d4
                                      const BYTE* src, size_t size, wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
	size_t offset = 0;
Packit 1fb8d4
Packit 1fb8d4
	while (offset < size)
Packit 1fb8d4
	{
Packit 1fb8d4
		int rc;
Packit 1fb8d4
		gsm_signal gsmBlockBuffer[160] = { 0 };
Packit 1fb8d4
		rc = gsm_decode(context->gsm, (gsm_byte*) &src[offset], gsmBlockBuffer);
Packit 1fb8d4
Packit 1fb8d4
		if (rc < 0)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
Packit 1fb8d4
		if ((offset % 65) == 0)
Packit 1fb8d4
			offset += 33;
Packit 1fb8d4
		else
Packit 1fb8d4
			offset += 32;
Packit 1fb8d4
Packit 1fb8d4
		if (!Stream_EnsureRemainingCapacity(out, sizeof(gsmBlockBuffer)))
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
Packit 1fb8d4
		Stream_Write(out, (void*) gsmBlockBuffer, sizeof(gsmBlockBuffer));
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL freerdp_dsp_encode_gsm610(FREERDP_DSP_CONTEXT* context,
Packit 1fb8d4
                                      const BYTE* src, size_t size, wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
	size_t offset = 0;
Packit 1fb8d4
Packit 1fb8d4
	while (offset < size)
Packit 1fb8d4
	{
Packit 1fb8d4
		gsm_signal* signal = (gsm_signal*)&src[offset];
Packit 1fb8d4
Packit 1fb8d4
		if (!Stream_EnsureRemainingCapacity(out, sizeof(gsm_frame)))
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
Packit 1fb8d4
		gsm_encode(context->gsm, signal, Stream_Pointer(out));
Packit 1fb8d4
Packit 1fb8d4
		if ((offset % 65) == 0)
Packit 1fb8d4
			Stream_Seek(out, 33);
Packit 1fb8d4
		else
Packit 1fb8d4
			Stream_Seek(out, 32);
Packit 1fb8d4
Packit 1fb8d4
		offset += 160;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_LAME)
Packit 1fb8d4
static BOOL freerdp_dsp_decode_mp3(FREERDP_DSP_CONTEXT* context,
Packit 1fb8d4
                                   const BYTE* src, size_t size, wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
	int rc, x;
Packit 1fb8d4
	short* pcm_l;
Packit 1fb8d4
	short* pcm_r;
Packit 1fb8d4
	size_t buffer_size;
Packit 1fb8d4
Packit 1fb8d4
	if (!context || !src || !out)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	buffer_size = 2 * context->format.nChannels * context->format.nSamplesPerSec;
Packit 1fb8d4
Packit 1fb8d4
	if (!Stream_EnsureCapacity(context->buffer, 2 * buffer_size))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	pcm_l = (short*)Stream_Buffer(context->buffer);
Packit 1fb8d4
	pcm_r = (short*)Stream_Buffer(context->buffer) + buffer_size;
Packit 1fb8d4
	rc = hip_decode(context->hip, (unsigned char*)/* API is not modifying content */src,
Packit 1fb8d4
	                size, pcm_l, pcm_r);
Packit 1fb8d4
Packit 1fb8d4
	if (rc <= 0)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (!Stream_EnsureRemainingCapacity(out, rc * context->format.nChannels * 2))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	for (x = 0; x < rc; x++)
Packit 1fb8d4
	{
Packit 1fb8d4
		Stream_Write_UINT16(out, pcm_l[x]);
Packit 1fb8d4
		Stream_Write_UINT16(out, pcm_r[x]);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL freerdp_dsp_encode_mp3(FREERDP_DSP_CONTEXT* context,
Packit 1fb8d4
                                   const BYTE* src, size_t size, wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
	size_t samples_per_channel;
Packit 1fb8d4
	int rc;
Packit 1fb8d4
Packit 1fb8d4
	if (!context || !src || !out)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	samples_per_channel = size / context->format.nChannels / context->format.wBitsPerSample / 8;
Packit 1fb8d4
Packit 1fb8d4
	/* Ensure worst case buffer size for mp3 stream taken from LAME header */
Packit 1fb8d4
	if (!Stream_EnsureRemainingCapacity(out, 1.25 * samples_per_channel + 7200))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	samples_per_channel = size / 2 /* size of a sample */ / context->format.nChannels;
Packit 1fb8d4
	rc = lame_encode_buffer_interleaved(context->lame, (short*)src, samples_per_channel,
Packit 1fb8d4
	                                    Stream_Pointer(out), Stream_GetRemainingCapacity(out));
Packit 1fb8d4
Packit 1fb8d4
	if (rc < 0)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	Stream_Seek(out, rc);
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_FAAC)
Packit 1fb8d4
static BOOL freerdp_dsp_encode_faac(FREERDP_DSP_CONTEXT* context,
Packit 1fb8d4
                                    const BYTE* src, size_t size, wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
	int16_t* inSamples = (int16_t*)src;
Packit 1fb8d4
	int32_t* outSamples;
Packit 1fb8d4
	unsigned int bpp;
Packit 1fb8d4
	unsigned int nrSamples, x;
Packit 1fb8d4
	int rc;
Packit 1fb8d4
Packit 1fb8d4
	if (!context || !src || !out)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	bpp = context->format.wBitsPerSample / 8 * context->format.nChannels;
Packit 1fb8d4
	nrSamples = size / bpp;
Packit 1fb8d4
Packit 1fb8d4
	if (!Stream_EnsureCapacity(context->buffer,
Packit 1fb8d4
	                           nrSamples * sizeof(int32_t) * context->format.nChannels))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (!Stream_EnsureRemainingCapacity(out, context->faacMaxOutputBytes))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	outSamples = (int32_t*)Stream_Buffer(context->buffer);
Packit 1fb8d4
Packit 1fb8d4
	for (x = 0; x < nrSamples * context->format.nChannels; x++)
Packit 1fb8d4
		outSamples[x] = inSamples[x];
Packit 1fb8d4
Packit 1fb8d4
	rc = faacEncEncode(context->faac, outSamples, nrSamples * context->format.nChannels,
Packit 1fb8d4
	                   Stream_Pointer(out), Stream_GetRemainingCapacity(out));
Packit 1fb8d4
Packit 1fb8d4
	if (rc < 0)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	else if (rc > 0)
Packit 1fb8d4
		Stream_Seek(out, rc);
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_FAAD2)
Packit 1fb8d4
static BOOL freerdp_dsp_decode_faad(FREERDP_DSP_CONTEXT* context,
Packit 1fb8d4
                                    const BYTE* src, size_t size, wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
	NeAACDecFrameInfo info;
Packit 1fb8d4
	void* output;
Packit 1fb8d4
	size_t offset = 0;
Packit 1fb8d4
Packit 1fb8d4
	if (!context || !src || !out)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (!context->faadSetup)
Packit 1fb8d4
	{
Packit 1fb8d4
		unsigned long samplerate;
Packit 1fb8d4
		unsigned char channels;
Packit 1fb8d4
		char err = NeAACDecInit(context->faad, /* API is not modifying content */(unsigned char*)src,
Packit 1fb8d4
		                        size, &samplerate, &channels);
Packit 1fb8d4
Packit 1fb8d4
		if (err != 0)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
Packit 1fb8d4
		if (channels != context->format.nChannels)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
Packit 1fb8d4
		if (samplerate != context->format.nSamplesPerSec)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
Packit 1fb8d4
		context->faadSetup = TRUE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	while (offset < size)
Packit 1fb8d4
	{
Packit 1fb8d4
		size_t outSize;
Packit 1fb8d4
		void* sample_buffer;
Packit 1fb8d4
		outSize = context->format.nSamplesPerSec * context->format.nChannels *
Packit 1fb8d4
		          context->format.wBitsPerSample / 8;
Packit 1fb8d4
Packit 1fb8d4
		if (!Stream_EnsureRemainingCapacity(out, outSize))
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
Packit 1fb8d4
		sample_buffer = Stream_Pointer(out);
Packit 1fb8d4
		output = NeAACDecDecode2(context->faad, &info, (unsigned char*)&src[offset], size - offset,
Packit 1fb8d4
		                         &sample_buffer, Stream_GetRemainingCapacity(out));
Packit 1fb8d4
Packit 1fb8d4
		if (info.error != 0)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
Packit 1fb8d4
		offset += info.bytesconsumed;
Packit 1fb8d4
Packit 1fb8d4
		if (info.samples == 0)
Packit 1fb8d4
			continue;
Packit 1fb8d4
Packit 1fb8d4
		Stream_Seek(out, info.samples * context->format.wBitsPerSample / 8);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * 0     1     2     3
Packit 1fb8d4
 * 2 0   6 4   10 8  14 12   <left>
Packit 1fb8d4
 *
Packit 1fb8d4
 * 4     5     6     7
Packit 1fb8d4
 * 3 1   7 5   11 9  15 13   <right>
Packit 1fb8d4
 */
Packit 1fb8d4
static const struct
Packit 1fb8d4
{
Packit 1fb8d4
	BYTE byte_num;
Packit 1fb8d4
	BYTE byte_shift;
Packit 1fb8d4
} ima_stereo_encode_map[] =
Packit 1fb8d4
{
Packit 1fb8d4
	{ 0, 0 },
Packit 1fb8d4
	{ 4, 0 },
Packit 1fb8d4
	{ 0, 4 },
Packit 1fb8d4
	{ 4, 4 },
Packit 1fb8d4
	{ 1, 0 },
Packit 1fb8d4
	{ 5, 0 },
Packit 1fb8d4
	{ 1, 4 },
Packit 1fb8d4
	{ 5, 4 },
Packit 1fb8d4
	{ 2, 0 },
Packit 1fb8d4
	{ 6, 0 },
Packit 1fb8d4
	{ 2, 4 },
Packit 1fb8d4
	{ 6, 4 },
Packit 1fb8d4
	{ 3, 0 },
Packit 1fb8d4
	{ 7, 0 },
Packit 1fb8d4
	{ 3, 4 },
Packit 1fb8d4
	{ 7, 4 }
Packit 1fb8d4
};
Packit 1fb8d4
Packit 1fb8d4
static BYTE dsp_encode_ima_adpcm_sample(ADPCM* adpcm, int channel, INT16 sample)
Packit 1fb8d4
{
Packit 1fb8d4
	INT32 e;
Packit 1fb8d4
	INT32 d;
Packit 1fb8d4
	INT32 ss;
Packit 1fb8d4
	BYTE enc;
Packit 1fb8d4
	INT32 diff;
Packit 1fb8d4
	ss = ima_step_size_table[adpcm->ima.last_step[channel]];
Packit 1fb8d4
	d = e = sample - adpcm->ima.last_sample[channel];
Packit 1fb8d4
	diff = ss >> 3;
Packit 1fb8d4
	enc = 0;
Packit 1fb8d4
Packit 1fb8d4
	if (e < 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		enc = 8;
Packit 1fb8d4
		e = -e;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (e >= ss)
Packit 1fb8d4
	{
Packit 1fb8d4
		enc |= 4;
Packit 1fb8d4
		e -= ss;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	ss >>= 1;
Packit 1fb8d4
Packit 1fb8d4
	if (e >= ss)
Packit 1fb8d4
	{
Packit 1fb8d4
		enc |= 2;
Packit 1fb8d4
		e -= ss;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	ss >>= 1;
Packit 1fb8d4
Packit 1fb8d4
	if (e >= ss)
Packit 1fb8d4
	{
Packit 1fb8d4
		enc |= 1;
Packit 1fb8d4
		e -= ss;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (d < 0)
Packit 1fb8d4
		diff = d + e - diff;
Packit 1fb8d4
	else
Packit 1fb8d4
		diff = d - e + diff;
Packit 1fb8d4
Packit 1fb8d4
	diff += adpcm->ima.last_sample[channel];
Packit 1fb8d4
Packit 1fb8d4
	if (diff < -32768)
Packit 1fb8d4
		diff = -32768;
Packit 1fb8d4
	else if (diff > 32767)
Packit 1fb8d4
		diff = 32767;
Packit 1fb8d4
Packit 1fb8d4
	adpcm->ima.last_sample[channel] = (INT16) diff;
Packit 1fb8d4
	adpcm->ima.last_step[channel] += ima_step_index_table[enc];
Packit 1fb8d4
Packit 1fb8d4
	if (adpcm->ima.last_step[channel] < 0)
Packit 1fb8d4
		adpcm->ima.last_step[channel] = 0;
Packit 1fb8d4
	else if (adpcm->ima.last_step[channel] > 88)
Packit 1fb8d4
		adpcm->ima.last_step[channel] = 88;
Packit 1fb8d4
Packit 1fb8d4
	return enc;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT* context,
Packit 1fb8d4
        const BYTE* src, size_t size, wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
	int i;
Packit 1fb8d4
	BYTE* dst;
Packit 1fb8d4
	BYTE* start;
Packit 1fb8d4
	INT16 sample;
Packit 1fb8d4
	BYTE encoded;
Packit 1fb8d4
	UINT32 out_size;
Packit 1fb8d4
	size_t align;
Packit 1fb8d4
	out_size = size / 2;
Packit 1fb8d4
Packit 1fb8d4
	if (!Stream_EnsureRemainingCapacity(out, size))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	start = dst = Stream_Pointer(out);
Packit 1fb8d4
	align = (context->format.nChannels > 1) ? 32 : 4;
Packit 1fb8d4
Packit 1fb8d4
	while (size > align)
Packit 1fb8d4
	{
Packit 1fb8d4
		if ((dst - start) % context->format.nBlockAlign == 0)
Packit 1fb8d4
		{
Packit 1fb8d4
			*dst++ = context->adpcm.ima.last_sample[0] & 0xFF;
Packit 1fb8d4
			*dst++ = (context->adpcm.ima.last_sample[0] >> 8) & 0xFF;
Packit 1fb8d4
			*dst++ = (BYTE) context->adpcm.ima.last_step[0];
Packit 1fb8d4
			*dst++ = 0;
Packit 1fb8d4
Packit 1fb8d4
			if (context->format.nChannels > 1)
Packit 1fb8d4
			{
Packit 1fb8d4
				*dst++ = context->adpcm.ima.last_sample[1] & 0xFF;
Packit 1fb8d4
				*dst++ = (context->adpcm.ima.last_sample[1] >> 8) & 0xFF;
Packit 1fb8d4
				*dst++ = (BYTE) context->adpcm.ima.last_step[1];
Packit 1fb8d4
				*dst++ = 0;
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		if (context->format.nChannels > 1)
Packit 1fb8d4
		{
Packit 1fb8d4
			ZeroMemory(dst, 8);
Packit 1fb8d4
Packit 1fb8d4
			for (i = 0; i < 16; i++)
Packit 1fb8d4
			{
Packit 1fb8d4
				sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
Packit 1fb8d4
				src += 2;
Packit 1fb8d4
				encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, i % 2, sample);
Packit 1fb8d4
				dst[ima_stereo_encode_map[i].byte_num] |= encoded << ima_stereo_encode_map[i].byte_shift;
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			dst += 8;
Packit 1fb8d4
			size -= 32;
Packit 1fb8d4
		}
Packit 1fb8d4
		else
Packit 1fb8d4
		{
Packit 1fb8d4
			sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
Packit 1fb8d4
			src += 2;
Packit 1fb8d4
			encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample);
Packit 1fb8d4
			sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
Packit 1fb8d4
			src += 2;
Packit 1fb8d4
			encoded |= dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample) << 4;
Packit 1fb8d4
			*dst++ = encoded;
Packit 1fb8d4
			size -= 4;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	Stream_SetPointer(out, dst);
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Microsoft ADPCM Specification:
Packit 1fb8d4
 *
Packit 1fb8d4
 * http://wiki.multimedia.cx/index.php?title=Microsoft_ADPCM
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
static const INT32 ms_adpcm_adaptation_table[] =
Packit 1fb8d4
{
Packit 1fb8d4
	230, 230, 230, 230, 307, 409, 512, 614,
Packit 1fb8d4
	768, 614, 512, 409, 307, 230, 230, 230
Packit 1fb8d4
};
Packit 1fb8d4
Packit 1fb8d4
static const INT32 ms_adpcm_coeffs1[7] =
Packit 1fb8d4
{
Packit 1fb8d4
	256, 512, 0, 192, 240, 460, 392
Packit 1fb8d4
};
Packit 1fb8d4
Packit 1fb8d4
static const INT32 ms_adpcm_coeffs2[7] =
Packit 1fb8d4
{
Packit 1fb8d4
	0, -256, 0, 64, 0, -208, -232
Packit 1fb8d4
};
Packit 1fb8d4
Packit 1fb8d4
static INLINE INT16 freerdp_dsp_decode_ms_adpcm_sample(ADPCM* adpcm, BYTE sample, int channel)
Packit 1fb8d4
{
Packit 1fb8d4
	INT8 nibble;
Packit 1fb8d4
	INT32 presample;
Packit 1fb8d4
	nibble = (sample & 0x08 ? (INT8) sample - 16 : sample);
Packit 1fb8d4
	presample = ((adpcm->ms.sample1[channel] * ms_adpcm_coeffs1[adpcm->ms.predictor[channel]]) +
Packit 1fb8d4
	             (adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) / 256;
Packit 1fb8d4
	presample += nibble * adpcm->ms.delta[channel];
Packit 1fb8d4
Packit 1fb8d4
	if (presample > 32767)
Packit 1fb8d4
		presample = 32767;
Packit 1fb8d4
	else if (presample < -32768)
Packit 1fb8d4
		presample = -32768;
Packit 1fb8d4
Packit 1fb8d4
	adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
Packit 1fb8d4
	adpcm->ms.sample1[channel] = presample;
Packit 1fb8d4
	adpcm->ms.delta[channel] = adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[sample] / 256;
Packit 1fb8d4
Packit 1fb8d4
	if (adpcm->ms.delta[channel] < 16)
Packit 1fb8d4
		adpcm->ms.delta[channel] = 16;
Packit 1fb8d4
Packit 1fb8d4
	return (INT16) presample;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* context,
Packit 1fb8d4
                                        const BYTE* src, size_t size, wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
	BYTE* dst;
Packit 1fb8d4
	BYTE sample;
Packit 1fb8d4
	const UINT32 out_size = size * 4;
Packit 1fb8d4
	const UINT32 channels = context->format.nChannels;
Packit 1fb8d4
	const UINT32 block_size = context->format.nBlockAlign;
Packit 1fb8d4
Packit 1fb8d4
	if (!Stream_EnsureCapacity(out, out_size))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	dst = Stream_Pointer(out);
Packit 1fb8d4
Packit 1fb8d4
	while (size > 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (size % block_size == 0)
Packit 1fb8d4
		{
Packit 1fb8d4
			if (channels > 1)
Packit 1fb8d4
			{
Packit 1fb8d4
				context->adpcm.ms.predictor[0] = *src++;
Packit 1fb8d4
				context->adpcm.ms.predictor[1] = *src++;
Packit 1fb8d4
				context->adpcm.ms.delta[0] = *((INT16*) src);
Packit 1fb8d4
				src += 2;
Packit 1fb8d4
				context->adpcm.ms.delta[1] = *((INT16*) src);
Packit 1fb8d4
				src += 2;
Packit 1fb8d4
				context->adpcm.ms.sample1[0] = *((INT16*) src);
Packit 1fb8d4
				src += 2;
Packit 1fb8d4
				context->adpcm.ms.sample1[1] = *((INT16*) src);
Packit 1fb8d4
				src += 2;
Packit 1fb8d4
				context->adpcm.ms.sample2[0] = *((INT16*) src);
Packit 1fb8d4
				src += 2;
Packit 1fb8d4
				context->adpcm.ms.sample2[1] = *((INT16*) src);
Packit 1fb8d4
				src += 2;
Packit 1fb8d4
				size -= 14;
Packit 1fb8d4
				*((INT16*) dst) = context->adpcm.ms.sample2[0];
Packit 1fb8d4
				dst += 2;
Packit 1fb8d4
				*((INT16*) dst) = context->adpcm.ms.sample2[1];
Packit 1fb8d4
				dst += 2;
Packit 1fb8d4
				*((INT16*) dst) = context->adpcm.ms.sample1[0];
Packit 1fb8d4
				dst += 2;
Packit 1fb8d4
				*((INT16*) dst) = context->adpcm.ms.sample1[1];
Packit 1fb8d4
				dst += 2;
Packit 1fb8d4
			}
Packit 1fb8d4
			else
Packit 1fb8d4
			{
Packit 1fb8d4
				context->adpcm.ms.predictor[0] = *src++;
Packit 1fb8d4
				context->adpcm.ms.delta[0] = *((INT16*) src);
Packit 1fb8d4
				src += 2;
Packit 1fb8d4
				context->adpcm.ms.sample1[0] = *((INT16*) src);
Packit 1fb8d4
				src += 2;
Packit 1fb8d4
				context->adpcm.ms.sample2[0] = *((INT16*) src);
Packit 1fb8d4
				src += 2;
Packit 1fb8d4
				size -= 7;
Packit 1fb8d4
				*((INT16*) dst) = context->adpcm.ms.sample2[0];
Packit 1fb8d4
				dst += 2;
Packit 1fb8d4
				*((INT16*) dst) = context->adpcm.ms.sample1[0];
Packit 1fb8d4
				dst += 2;
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		if (channels > 1)
Packit 1fb8d4
		{
Packit 1fb8d4
			sample = *src++;
Packit 1fb8d4
			size--;
Packit 1fb8d4
			*((INT16*) dst) = freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0);
Packit 1fb8d4
			dst += 2;
Packit 1fb8d4
			*((INT16*) dst) = freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1);
Packit 1fb8d4
			dst += 2;
Packit 1fb8d4
			sample = *src++;
Packit 1fb8d4
			size--;
Packit 1fb8d4
			*((INT16*) dst) = freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0);
Packit 1fb8d4
			dst += 2;
Packit 1fb8d4
			*((INT16*) dst) = freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1);
Packit 1fb8d4
			dst += 2;
Packit 1fb8d4
		}
Packit 1fb8d4
		else
Packit 1fb8d4
		{
Packit 1fb8d4
			sample = *src++;
Packit 1fb8d4
			size--;
Packit 1fb8d4
			*((INT16*) dst) = freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0);
Packit 1fb8d4
			dst += 2;
Packit 1fb8d4
			*((INT16*) dst) = freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 0);
Packit 1fb8d4
			dst += 2;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	Stream_SetPointer(out, dst);
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BYTE freerdp_dsp_encode_ms_adpcm_sample(ADPCM* adpcm, INT32 sample, int channel)
Packit 1fb8d4
{
Packit 1fb8d4
	INT32 presample;
Packit 1fb8d4
	INT32 errordelta;
Packit 1fb8d4
	presample = ((adpcm->ms.sample1[channel] * ms_adpcm_coeffs1[adpcm->ms.predictor[channel]]) +
Packit 1fb8d4
	             (adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) / 256;
Packit 1fb8d4
	errordelta = (sample - presample) / adpcm->ms.delta[channel];
Packit 1fb8d4
Packit 1fb8d4
	if ((sample - presample) % adpcm->ms.delta[channel] > adpcm->ms.delta[channel] / 2)
Packit 1fb8d4
		errordelta++;
Packit 1fb8d4
Packit 1fb8d4
	if (errordelta > 7)
Packit 1fb8d4
		errordelta = 7;
Packit 1fb8d4
	else if (errordelta < -8)
Packit 1fb8d4
		errordelta = -8;
Packit 1fb8d4
Packit 1fb8d4
	presample += adpcm->ms.delta[channel] * errordelta;
Packit 1fb8d4
Packit 1fb8d4
	if (presample > 32767)
Packit 1fb8d4
		presample = 32767;
Packit 1fb8d4
	else if (presample < -32768)
Packit 1fb8d4
		presample = -32768;
Packit 1fb8d4
Packit 1fb8d4
	adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
Packit 1fb8d4
	adpcm->ms.sample1[channel] = presample;
Packit 1fb8d4
	adpcm->ms.delta[channel] = adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[(((
Packit 1fb8d4
	                               BYTE) errordelta) & 0x0F)] / 256;
Packit 1fb8d4
Packit 1fb8d4
	if (adpcm->ms.delta[channel] < 16)
Packit 1fb8d4
		adpcm->ms.delta[channel] = 16;
Packit 1fb8d4
Packit 1fb8d4
	return ((BYTE) errordelta) & 0x0F;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL freerdp_dsp_encode_ms_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
Packit 1fb8d4
                                        wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
	BYTE* dst;
Packit 1fb8d4
	BYTE* start;
Packit 1fb8d4
	INT32 sample;
Packit 1fb8d4
	UINT32 out_size;
Packit 1fb8d4
	const size_t step = 8 + ((context->format.nChannels > 1) ? 4 : 0);
Packit 1fb8d4
	out_size = size / 2;
Packit 1fb8d4
Packit 1fb8d4
	if (!Stream_EnsureRemainingCapacity(out, size))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	start = dst = Stream_Pointer(out);
Packit 1fb8d4
Packit 1fb8d4
	if (context->adpcm.ms.delta[0] < 16)
Packit 1fb8d4
		context->adpcm.ms.delta[0] = 16;
Packit 1fb8d4
Packit 1fb8d4
	if (context->adpcm.ms.delta[1] < 16)
Packit 1fb8d4
		context->adpcm.ms.delta[1] = 16;
Packit 1fb8d4
Packit 1fb8d4
	while (size >= step)
Packit 1fb8d4
	{
Packit 1fb8d4
		if ((dst - start) % context->format.nBlockAlign == 0)
Packit 1fb8d4
		{
Packit 1fb8d4
			if (context->format.nChannels > 1)
Packit 1fb8d4
			{
Packit 1fb8d4
				*dst++ = context->adpcm.ms.predictor[0];
Packit 1fb8d4
				*dst++ = context->adpcm.ms.predictor[1];
Packit 1fb8d4
				*dst++ = (BYTE)(context->adpcm.ms.delta[0] & 0xFF);
Packit 1fb8d4
				*dst++ = (BYTE)((context->adpcm.ms.delta[0] >> 8) & 0xFF);
Packit 1fb8d4
				*dst++ = (BYTE)(context->adpcm.ms.delta[1] & 0xFF);
Packit 1fb8d4
				*dst++ = (BYTE)((context->adpcm.ms.delta[1] >> 8) & 0xFF);
Packit 1fb8d4
				context->adpcm.ms.sample1[0] = *((INT16*)(src + 4));
Packit 1fb8d4
				context->adpcm.ms.sample1[1] = *((INT16*)(src + 6));
Packit 1fb8d4
				context->adpcm.ms.sample2[0] = *((INT16*)(src + 0));
Packit 1fb8d4
				context->adpcm.ms.sample2[1] = *((INT16*)(src + 2));
Packit 1fb8d4
				*((INT16*)(dst + 0)) = (INT16) context->adpcm.ms.sample1[0];
Packit 1fb8d4
				*((INT16*)(dst + 2)) = (INT16) context->adpcm.ms.sample1[1];
Packit 1fb8d4
				*((INT16*)(dst + 4)) = (INT16) context->adpcm.ms.sample2[0];
Packit 1fb8d4
				*((INT16*)(dst + 6)) = (INT16) context->adpcm.ms.sample2[1];
Packit 1fb8d4
				dst += 8;
Packit 1fb8d4
				src += 8;
Packit 1fb8d4
				size -= 8;
Packit 1fb8d4
			}
Packit 1fb8d4
			else
Packit 1fb8d4
			{
Packit 1fb8d4
				*dst++ = context->adpcm.ms.predictor[0];
Packit 1fb8d4
				*dst++ = (BYTE)(context->adpcm.ms.delta[0] & 0xFF);
Packit 1fb8d4
				*dst++ = (BYTE)((context->adpcm.ms.delta[0] >> 8) & 0xFF);
Packit 1fb8d4
				context->adpcm.ms.sample1[0] = *((INT16*)(src + 2));
Packit 1fb8d4
				context->adpcm.ms.sample2[0] = *((INT16*)(src + 0));
Packit 1fb8d4
				*((INT16*)(dst + 0)) = (INT16) context->adpcm.ms.sample1[0];
Packit 1fb8d4
				*((INT16*)(dst + 2)) = (INT16) context->adpcm.ms.sample2[0];
Packit 1fb8d4
				dst += 4;
Packit 1fb8d4
				src += 4;
Packit 1fb8d4
				size -= 4;
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		sample = *((INT16*) src);
Packit 1fb8d4
		src += 2;
Packit 1fb8d4
		*dst = freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample, 0) << 4;
Packit 1fb8d4
		sample = *((INT16*) src);
Packit 1fb8d4
		src += 2;
Packit 1fb8d4
		*dst += freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample,
Packit 1fb8d4
		        context->format.nChannels > 1 ? 1 : 0);
Packit 1fb8d4
		dst++;
Packit 1fb8d4
		size -= 4;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	Stream_SetPointer(out, dst);
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
FREERDP_DSP_CONTEXT* freerdp_dsp_context_new(BOOL encoder)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_DSP_FFMPEG)
Packit 1fb8d4
	return freerdp_dsp_ffmpeg_context_new(encoder);
Packit 1fb8d4
#else
Packit 1fb8d4
	FREERDP_DSP_CONTEXT* context = calloc(1, sizeof(FREERDP_DSP_CONTEXT));
Packit 1fb8d4
Packit 1fb8d4
	if (!context)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	context->buffer = Stream_New(NULL, 4096);
Packit 1fb8d4
Packit 1fb8d4
	if (!context->buffer)
Packit 1fb8d4
		goto fail;
Packit 1fb8d4
Packit 1fb8d4
	context->resample = Stream_New(NULL, 4096);
Packit 1fb8d4
Packit 1fb8d4
	if (!context->resample)
Packit 1fb8d4
		goto fail;
Packit 1fb8d4
Packit 1fb8d4
	context->encoder = encoder;
Packit 1fb8d4
#if defined(WITH_GSM)
Packit 1fb8d4
	context->gsm = gsm_create();
Packit 1fb8d4
Packit 1fb8d4
	if (!context->gsm)
Packit 1fb8d4
		goto fail;
Packit 1fb8d4
Packit 1fb8d4
	{
Packit 1fb8d4
		int rc;
Packit 1fb8d4
		int val = 1;
Packit 1fb8d4
		rc = gsm_option(context->gsm, GSM_OPT_WAV49, &val;;
Packit 1fb8d4
Packit 1fb8d4
		if (rc < 0)
Packit 1fb8d4
			goto fail;
Packit 1fb8d4
	}
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_LAME)
Packit 1fb8d4
Packit 1fb8d4
	if (encoder)
Packit 1fb8d4
	{
Packit 1fb8d4
		context->lame = lame_init();
Packit 1fb8d4
Packit 1fb8d4
		if (!context->lame)
Packit 1fb8d4
			goto fail;
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		context->hip = hip_decode_init();
Packit 1fb8d4
Packit 1fb8d4
		if (!context->hip)
Packit 1fb8d4
			goto fail;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_FAAD2)
Packit 1fb8d4
Packit 1fb8d4
	if (!encoder)
Packit 1fb8d4
	{
Packit 1fb8d4
		context->faad = NeAACDecOpen();
Packit 1fb8d4
Packit 1fb8d4
		if (!context->faad)
Packit 1fb8d4
			goto fail;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
	return context;
Packit 1fb8d4
fail:
Packit 1fb8d4
	freerdp_dsp_context_free(context);
Packit 1fb8d4
	return NULL;
Packit 1fb8d4
#endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void freerdp_dsp_context_free(FREERDP_DSP_CONTEXT* context)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_DSP_FFMPEG)
Packit 1fb8d4
	freerdp_dsp_ffmpeg_context_free(context);
Packit 1fb8d4
#else
Packit 1fb8d4
Packit 1fb8d4
	if (context)
Packit 1fb8d4
	{
Packit 1fb8d4
		Stream_Free(context->buffer, TRUE);
Packit 1fb8d4
		Stream_Free(context->resample, TRUE);
Packit 1fb8d4
#if defined(WITH_GSM)
Packit 1fb8d4
		gsm_destroy(context->gsm);
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_LAME)
Packit 1fb8d4
Packit 1fb8d4
		if (context->encoder)
Packit 1fb8d4
			lame_close(context->lame);
Packit 1fb8d4
		else
Packit 1fb8d4
			hip_decode_exit(context->hip);
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_FAAD2)
Packit 1fb8d4
Packit 1fb8d4
		if (!context->encoder)
Packit 1fb8d4
			NeAACDecClose(context->faad);
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined (WITH_FAAC)
Packit 1fb8d4
Packit 1fb8d4
		if (context->faac)
Packit 1fb8d4
			faacEncClose(context->faac);
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_SOXR)
Packit 1fb8d4
		soxr_delete(context->sox);
Packit 1fb8d4
#endif
Packit 1fb8d4
		free(context);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL freerdp_dsp_encode(FREERDP_DSP_CONTEXT* context, const AUDIO_FORMAT* srcFormat,
Packit 1fb8d4
                        const BYTE* data, size_t length, wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_DSP_FFMPEG)
Packit 1fb8d4
	return freerdp_dsp_ffmpeg_encode(context, srcFormat, data, length, out);
Packit 1fb8d4
#else
Packit 1fb8d4
Packit 1fb8d4
	if (!context || !context->encoder || !srcFormat || !data || !out)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (!freerdp_dsp_resample(context, data, length, srcFormat, &data, &length))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	switch (context->format.wFormatTag)
Packit 1fb8d4
	{
Packit 1fb8d4
		case WAVE_FORMAT_PCM:
Packit 1fb8d4
			if (!Stream_EnsureRemainingCapacity(out, length))
Packit 1fb8d4
				return FALSE;
Packit 1fb8d4
Packit 1fb8d4
			Stream_Write(out, data, length);
Packit 1fb8d4
			return TRUE;
Packit 1fb8d4
Packit 1fb8d4
		case WAVE_FORMAT_ADPCM:
Packit 1fb8d4
			return freerdp_dsp_encode_ms_adpcm(context, data, length, out);
Packit 1fb8d4
Packit 1fb8d4
		case WAVE_FORMAT_DVI_ADPCM:
Packit 1fb8d4
			return freerdp_dsp_encode_ima_adpcm(context, data, length, out);
Packit 1fb8d4
#if defined(WITH_GSM)
Packit 1fb8d4
Packit 1fb8d4
		case WAVE_FORMAT_GSM610:
Packit 1fb8d4
			return freerdp_dsp_encode_gsm610(context, data, length, out);
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_LAME)
Packit 1fb8d4
Packit 1fb8d4
		case WAVE_FORMAT_MPEGLAYER3:
Packit 1fb8d4
			return freerdp_dsp_encode_mp3(context, data, length, out);
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_FAAC)
Packit 1fb8d4
Packit 1fb8d4
		case WAVE_FORMAT_AAC_MS:
Packit 1fb8d4
			return freerdp_dsp_encode_faac(context, data, length, out);
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
		default:
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
#endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL freerdp_dsp_decode(FREERDP_DSP_CONTEXT* context, const AUDIO_FORMAT* srcFormat,
Packit 1fb8d4
                        const BYTE* data, size_t length, wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_DSP_FFMPEG)
Packit 1fb8d4
	return freerdp_dsp_ffmpeg_decode(context, srcFormat, data, length, out);
Packit 1fb8d4
#else
Packit 1fb8d4
Packit 1fb8d4
	if (!context || context->encoder || !srcFormat || !data || !out)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	switch (context->format.wFormatTag)
Packit 1fb8d4
	{
Packit 1fb8d4
		case WAVE_FORMAT_PCM:
Packit 1fb8d4
			if (!Stream_EnsureRemainingCapacity(out, length))
Packit 1fb8d4
				return FALSE;
Packit 1fb8d4
Packit 1fb8d4
			Stream_Write(out, data, length);
Packit 1fb8d4
			return TRUE;
Packit 1fb8d4
Packit 1fb8d4
		case WAVE_FORMAT_ADPCM:
Packit 1fb8d4
			return freerdp_dsp_decode_ms_adpcm(context, data, length, out);
Packit 1fb8d4
Packit 1fb8d4
		case WAVE_FORMAT_DVI_ADPCM:
Packit 1fb8d4
			return freerdp_dsp_decode_ima_adpcm(context, data, length, out);
Packit 1fb8d4
#if defined(WITH_GSM)
Packit 1fb8d4
Packit 1fb8d4
		case WAVE_FORMAT_GSM610:
Packit 1fb8d4
			return freerdp_dsp_decode_gsm610(context, data, length, out);
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_LAME)
Packit 1fb8d4
Packit 1fb8d4
		case WAVE_FORMAT_MPEGLAYER3:
Packit 1fb8d4
			return freerdp_dsp_decode_mp3(context, data, length, out);
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_FAAD2)
Packit 1fb8d4
Packit 1fb8d4
		case WAVE_FORMAT_AAC_MS:
Packit 1fb8d4
			return freerdp_dsp_decode_faad(context, data, length, out);
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
		default:
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
#endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL freerdp_dsp_supports_format(const AUDIO_FORMAT* format, BOOL encode)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_DSP_FFMPEG)
Packit 1fb8d4
	return freerdp_dsp_ffmpeg_supports_format(format, encode);
Packit 1fb8d4
#else
Packit 1fb8d4
Packit 1fb8d4
	switch (format->wFormatTag)
Packit 1fb8d4
	{
Packit 1fb8d4
		case WAVE_FORMAT_PCM:
Packit 1fb8d4
			return TRUE;
Packit 1fb8d4
#if defined(WITH_DSP_EXPERIMENTAL)
Packit 1fb8d4
Packit 1fb8d4
		case WAVE_FORMAT_ADPCM:
Packit 1fb8d4
		case WAVE_FORMAT_DVI_ADPCM:
Packit 1fb8d4
			return TRUE;
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_GSM)
Packit 1fb8d4
Packit 1fb8d4
		case WAVE_FORMAT_GSM610:
Packit 1fb8d4
#if defined(WITH_DSP_EXPERIMENTAL)
Packit 1fb8d4
			return TRUE;
Packit 1fb8d4
#else
Packit 1fb8d4
			return !encode;
Packit 1fb8d4
#endif
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_LAME)
Packit 1fb8d4
Packit 1fb8d4
		case WAVE_FORMAT_MPEGLAYER3:
Packit 1fb8d4
#if defined(WITH_DSP_EXPERIMENTAL)
Packit 1fb8d4
			return TRUE;
Packit 1fb8d4
#else
Packit 1fb8d4
			return !encode;
Packit 1fb8d4
#endif
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
		case WAVE_FORMAT_AAC_MS:
Packit 1fb8d4
#if defined(WITH_FAAD2)
Packit 1fb8d4
			if (!encode)
Packit 1fb8d4
				return TRUE;
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_FAAC) && defined(WITH_DSP_EXPERIMENTAL)
Packit 1fb8d4
Packit 1fb8d4
			if (encode)
Packit 1fb8d4
				return TRUE;
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
		default:
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
#endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL freerdp_dsp_context_reset(FREERDP_DSP_CONTEXT* context, const AUDIO_FORMAT* targetFormat)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_DSP_FFMPEG)
Packit 1fb8d4
	return freerdp_dsp_ffmpeg_context_reset(context, targetFormat);
Packit 1fb8d4
#else
Packit 1fb8d4
Packit 1fb8d4
	if (!context || !targetFormat)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	context->format = *targetFormat;
Packit 1fb8d4
#if defined(WITH_FAAD2)
Packit 1fb8d4
	context->faadSetup = FALSE;
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_FAAC)
Packit 1fb8d4
Packit 1fb8d4
	if (context->encoder)
Packit 1fb8d4
	{
Packit 1fb8d4
		faacEncConfigurationPtr cfg;
Packit 1fb8d4
Packit 1fb8d4
		if (context->faac)
Packit 1fb8d4
			faacEncClose(context->faac);
Packit 1fb8d4
Packit 1fb8d4
		context->faac = faacEncOpen(targetFormat->nSamplesPerSec, targetFormat->nChannels,
Packit 1fb8d4
		                            &context->faacInputSamples, &context->faacMaxOutputBytes);
Packit 1fb8d4
Packit 1fb8d4
		if (!context->faac)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
Packit 1fb8d4
		cfg = faacEncGetCurrentConfiguration(context->faac);
Packit 1fb8d4
		cfg->bitRate = 10000;
Packit 1fb8d4
		faacEncSetConfiguration(context->faac, cfg);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(WITH_SOXR)
Packit 1fb8d4
	{
Packit 1fb8d4
		soxr_io_spec_t iospec = soxr_io_spec(SOXR_INT16, SOXR_INT16);
Packit 1fb8d4
		soxr_error_t error;
Packit 1fb8d4
		soxr_delete(context->sox);
Packit 1fb8d4
		context->sox = soxr_create(context->format.nSamplesPerSec, targetFormat->nSamplesPerSec,
Packit 1fb8d4
		                           targetFormat->nChannels, &error, &iospec, NULL, NULL);
Packit 1fb8d4
Packit 1fb8d4
		if (!context->sox || (error != 0))
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
#endif
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
#endif
Packit 1fb8d4
}