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 Service 5a9772
union _ADPCM {
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 Service 5a9772
static INT16 read_int16(const BYTE* src)
Packit Service 5a9772
{
Packit Service 5a9772
	return (INT16)(src[0] | (src[1] << 8));
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static void write_int16(BYTE* dst, INT32 val)
Packit Service 5a9772
{
Packit Service 5a9772
	dst[1] = (val >> 8) & 0xFF;
Packit Service 5a9772
	dst[0] = val & 0xFF;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static BOOL freerdp_dsp_channel_mix(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
Packit Service 5a9772
                                    const AUDIO_FORMAT* srcFormat, const BYTE** data,
Packit Service 5a9772
                                    size_t* length)
Packit Service 5a9772
{
Packit Service 5a9772
	UINT32 bpp;
Packit Service 5a9772
	size_t samples;
Packit Service 5a9772
	size_t x, y;
Packit Service 5a9772
Packit Service 5a9772
	if (!context || !data || !length)
Packit Service 5a9772
		return FALSE;
Packit Service 5a9772
Packit Service 5a9772
	if (srcFormat->wFormatTag != WAVE_FORMAT_PCM)
Packit Service 5a9772
		return FALSE;
Packit Service 5a9772
Packit Service 5a9772
	bpp = srcFormat->wBitsPerSample > 8 ? 2 : 1;
Packit Service 5a9772
	samples = size / bpp;
Packit Service 5a9772
Packit Service 5a9772
	if (context->format.nChannels == srcFormat->nChannels)
Packit Service 5a9772
	{
Packit Service 5a9772
		*data = src;
Packit Service 5a9772
		*length = size;
Packit Service 5a9772
		return TRUE;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	Stream_SetPosition(context->buffer, 0);
Packit Service 5a9772
Packit Service 5a9772
	/* Destination has more channels than source */
Packit Service 5a9772
	if (context->format.nChannels > srcFormat->nChannels)
Packit Service 5a9772
	{
Packit Service 5a9772
		switch (srcFormat->nChannels)
Packit Service 5a9772
		{
Packit Service 5a9772
			case 1:
Packit Service 5a9772
				if (!Stream_EnsureCapacity(context->buffer, size * 2))
Packit Service 5a9772
					return FALSE;
Packit Service 5a9772
Packit Service 5a9772
				for (x = 0; x < samples; x++)
Packit Service 5a9772
				{
Packit Service 5a9772
					for (y = 0; y < bpp; y++)
Packit Service 5a9772
						Stream_Write_UINT8(context->buffer, src[x * bpp + y]);
Packit Service 5a9772
Packit Service 5a9772
					for (y = 0; y < bpp; y++)
Packit Service 5a9772
						Stream_Write_UINT8(context->buffer, src[x * bpp + y]);
Packit Service 5a9772
				}
Packit Service 5a9772
Packit Service 5a9772
				Stream_SealLength(context->buffer);
Packit Service 5a9772
				*data = Stream_Buffer(context->buffer);
Packit Service 5a9772
				*length = Stream_Length(context->buffer);
Packit Service 5a9772
				return TRUE;
Packit Service 5a9772
Packit Service 5a9772
			case 2:  /* We only support stereo, so we can not handle this case. */
Packit Service 5a9772
			default: /* Unsupported number of channels */
Packit Service 5a9772
				return FALSE;
Packit Service 5a9772
		}
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	/* Destination has less channels than source */
Packit Service 5a9772
	switch (srcFormat->nChannels)
Packit Service 5a9772
	{
Packit Service 5a9772
		case 2:
Packit Service 5a9772
			if (!Stream_EnsureCapacity(context->buffer, size / 2))
Packit Service 5a9772
				return FALSE;
Packit Service 5a9772
Packit Service 5a9772
			/* Simply drop second channel.
Packit Service 5a9772
			 * TODO: Calculate average */
Packit Service 5a9772
			for (x = 0; x < samples; x++)
Packit Service 5a9772
			{
Packit Service 5a9772
				for (y = 0; y < bpp; y++)
Packit Service 5a9772
					Stream_Write_UINT8(context->buffer, src[2 * x * bpp + y]);
Packit Service 5a9772
			}
Packit Service 5a9772
Packit Service 5a9772
			Stream_SealLength(context->buffer);
Packit Service 5a9772
			*data = Stream_Buffer(context->buffer);
Packit Service 5a9772
			*length = Stream_Length(context->buffer);
Packit Service 5a9772
			return TRUE;
Packit Service 5a9772
Packit Service 5a9772
		case 1:  /* Invalid, do we want to use a 0 channel sound? */
Packit Service 5a9772
		default: /* Unsupported number of channels */
Packit Service 5a9772
			return FALSE;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return FALSE;
Packit Service 5a9772
}
Packit Service 5a9772
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 Service 5a9772
static BOOL freerdp_dsp_resample(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
Packit Service 5a9772
                                 const AUDIO_FORMAT* srcFormat, 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
	size_t sframes, rframes;
Packit 1fb8d4
	size_t rsize;
Packit 1fb8d4
	size_t j;
Packit 1fb8d4
	size_t sbytes, rbytes;
Packit Service 5a9772
#endif
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 Service 5a9772
	error = soxr_process(context->sox, src, sframes, &idone, 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 Service 5a9772
	WINPR_UNUSED(src);
Packit Service 5a9772
	WINPR_UNUSED(size);
Packit Service 5a9772
	WINPR_UNUSED(data);
Packit Service 5a9772
	WINPR_UNUSED(length);
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 Service 5a9772
static const INT16 ima_step_index_table[] = {
Packit Service 5a9772
	-1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8
Packit Service 5a9772
};
Packit 1fb8d4
Packit Service 5a9772
static const INT16 ima_step_size_table[] = {
Packit Service 5a9772
	7,     8,     9,     10,    11,    12,    13,    14,    16,    17,    19,   21,    23,
Packit Service 5a9772
	25,    28,    31,    34,    37,    41,    45,    50,    55,    60,    66,   73,    80,
Packit Service 5a9772
	88,    97,    107,   118,   130,   143,   157,   173,   190,   209,   230,  253,   279,
Packit Service 5a9772
	307,   337,   371,   408,   449,   494,   544,   598,   658,   724,   796,  876,   963,
Packit Service 5a9772
	1060,  1166,  1282,  1411,  1552,  1707,  1878,  2066,  2272,  2499,  2749, 3024,  3327,
Packit Service 5a9772
	3660,  4026,  4428,  4871,  5358,  5894,  6484,  7132,  7845,  8630,  9493, 10442, 11487,
Packit Service 5a9772
	12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Packit 1fb8d4
};
Packit 1fb8d4
Packit Service 5a9772
static UINT16 dsp_decode_ima_adpcm_sample(ADPCM* adpcm, 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 Service 5a9772
	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 Service 5a9772
	return (UINT16)d;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
Packit Service 5a9772
                                         wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
	BYTE* dst;
Packit 1fb8d4
	BYTE sample;
Packit 1fb8d4
	UINT16 decoded;
Packit Service 5a9772
	size_t 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 Service 5a9772
	size_t 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 Service 5a9772
			context->adpcm.ima.last_sample[0] =
Packit Service 5a9772
			    (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 Service 5a9772
				context->adpcm.ima.last_sample[1] =
Packit Service 5a9772
				    (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 Service 5a9772
static BOOL freerdp_dsp_decode_gsm610(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
Packit Service 5a9772
                                      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 Service 5a9772
		rc = gsm_decode(context->gsm, (gsm_byte*)/* API does not modify */ &src[offset],
Packit Service 5a9772
		                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 Service 5a9772
		Stream_Write(out, (void*)gsmBlockBuffer, sizeof(gsmBlockBuffer));
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static BOOL freerdp_dsp_encode_gsm610(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
Packit Service 5a9772
                                      wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
	size_t offset = 0;
Packit 1fb8d4
Packit 1fb8d4
	while (offset < size)
Packit 1fb8d4
	{
Packit Service 5a9772
		const gsm_signal* signal = (const gsm_signal*)&src[offset];
Packit 1fb8d4
Packit 1fb8d4
		if (!Stream_EnsureRemainingCapacity(out, sizeof(gsm_frame)))
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
Packit Service 5a9772
		gsm_encode(context->gsm, (gsm_signal*)/* API does not modify */ signal,
Packit Service 5a9772
		           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 Service 5a9772
static BOOL freerdp_dsp_decode_mp3(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
Packit Service 5a9772
                                   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 Service 5a9772
	rc = hip_decode(context->hip, (unsigned char*)/* API is not modifying content */ src, size,
Packit Service 5a9772
	                pcm_l, pcm_r);
Packit 1fb8d4
Packit 1fb8d4
	if (rc <= 0)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit Service 5a9772
	if (!Stream_EnsureRemainingCapacity(out, (size_t)rc * context->format.nChannels * 2))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	for (x = 0; x < rc; x++)
Packit 1fb8d4
	{
Packit Service 5a9772
		Stream_Write_UINT16(out, (UINT16)pcm_l[x]);
Packit Service 5a9772
		Stream_Write_UINT16(out, (UINT16)pcm_r[x]);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static BOOL freerdp_dsp_encode_mp3(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
Packit Service 5a9772
                                   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 Service 5a9772
	if (!Stream_EnsureRemainingCapacity(out, 5 / 4 * 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 Service 5a9772
	Stream_Seek(out, (size_t)rc);
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_FAAC)
Packit Service 5a9772
static BOOL freerdp_dsp_encode_faac(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
Packit Service 5a9772
                                    wStream* out)
Packit 1fb8d4
{
Packit Service 5a9772
	const int16_t* inSamples = (const int16_t*)src;
Packit 1fb8d4
	int32_t* outSamples;
Packit 1fb8d4
	unsigned int bpp;
Packit Service 5a9772
	size_t 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 Service 5a9772
		Stream_Seek(out, (size_t)rc);
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_FAAD2)
Packit Service 5a9772
static BOOL freerdp_dsp_decode_faad(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
Packit Service 5a9772
                                    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 Service 5a9772
		long err =
Packit Service 5a9772
		    NeAACDecInit(context->faad, /* API is not modifying content */ (unsigned char*)src,
Packit Service 5a9772
		                 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 Service 5a9772
} ima_stereo_encode_map[] = { { 0, 0 }, { 4, 0 }, { 0, 4 }, { 4, 4 }, { 1, 0 }, { 5, 0 },
Packit Service 5a9772
	                          { 1, 4 }, { 5, 4 }, { 2, 0 }, { 6, 0 }, { 2, 4 }, { 6, 4 },
Packit Service 5a9772
	                          { 3, 0 }, { 7, 0 }, { 3, 4 }, { 7, 4 } };
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 Service 5a9772
	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 Service 5a9772
static BOOL freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
Packit Service 5a9772
                                         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 Service 5a9772
	size_t 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 Service 5a9772
			*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 Service 5a9772
				*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 Service 5a9772
				dst[ima_stereo_encode_map[i].byte_num] |= encoded
Packit Service 5a9772
				                                          << 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 Service 5a9772
static const INT32 ms_adpcm_adaptation_table[] = { 230, 230, 230, 230, 307, 409, 512, 614,
Packit Service 5a9772
	                                               768, 614, 512, 409, 307, 230, 230, 230 };
Packit 1fb8d4
Packit Service 5a9772
static const INT32 ms_adpcm_coeffs1[7] = { 256, 512, 0, 192, 240, 460, 392 };
Packit 1fb8d4
Packit Service 5a9772
static const INT32 ms_adpcm_coeffs2[7] = { 0, -256, 0, 64, 0, -208, -232 };
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 Service 5a9772
	nibble = (sample & 0x08 ? (INT8)sample - 16 : (INT8)sample);
Packit 1fb8d4
	presample = ((adpcm->ms.sample1[channel] * ms_adpcm_coeffs1[adpcm->ms.predictor[channel]]) +
Packit Service 5a9772
	             (adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) /
Packit Service 5a9772
	            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 Service 5a9772
	return (INT16)presample;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
Packit Service 5a9772
                                        wStream* out)
Packit 1fb8d4
{
Packit 1fb8d4
	BYTE* dst;
Packit 1fb8d4
	BYTE sample;
Packit Service 5a9772
	const size_t 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 Service 5a9772
				context->adpcm.ms.delta[0] = read_int16(src);
Packit 1fb8d4
				src += 2;
Packit Service 5a9772
				context->adpcm.ms.delta[1] = read_int16(src);
Packit 1fb8d4
				src += 2;
Packit Service 5a9772
				context->adpcm.ms.sample1[0] = read_int16(src);
Packit 1fb8d4
				src += 2;
Packit Service 5a9772
				context->adpcm.ms.sample1[1] = read_int16(src);
Packit 1fb8d4
				src += 2;
Packit Service 5a9772
				context->adpcm.ms.sample2[0] = read_int16(src);
Packit 1fb8d4
				src += 2;
Packit Service 5a9772
				context->adpcm.ms.sample2[1] = read_int16(src);
Packit 1fb8d4
				src += 2;
Packit 1fb8d4
				size -= 14;
Packit Service 5a9772
				write_int16(dst, context->adpcm.ms.sample2[0]);
Packit 1fb8d4
				dst += 2;
Packit Service 5a9772
				write_int16(dst, context->adpcm.ms.sample2[1]);
Packit 1fb8d4
				dst += 2;
Packit Service 5a9772
				write_int16(dst, context->adpcm.ms.sample1[0]);
Packit 1fb8d4
				dst += 2;
Packit Service 5a9772
				write_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 Service 5a9772
				context->adpcm.ms.delta[0] = read_int16(src);
Packit 1fb8d4
				src += 2;
Packit Service 5a9772
				context->adpcm.ms.sample1[0] = read_int16(src);
Packit 1fb8d4
				src += 2;
Packit Service 5a9772
				context->adpcm.ms.sample2[0] = read_int16(src);
Packit 1fb8d4
				src += 2;
Packit 1fb8d4
				size -= 7;
Packit Service 5a9772
				write_int16(dst, context->adpcm.ms.sample2[0]);
Packit 1fb8d4
				dst += 2;
Packit Service 5a9772
				write_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 Service 5a9772
			write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
Packit 1fb8d4
			dst += 2;
Packit Service 5a9772
			write_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 Service 5a9772
			write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
Packit 1fb8d4
			dst += 2;
Packit Service 5a9772
			write_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 Service 5a9772
			write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
Packit 1fb8d4
			dst += 2;
Packit Service 5a9772
			write_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 Service 5a9772
	             (adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) /
Packit Service 5a9772
	            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 Service 5a9772
	adpcm->ms.delta[channel] =
Packit Service 5a9772
	    adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[(((BYTE)errordelta) & 0x0F)] / 256;
Packit 1fb8d4
Packit 1fb8d4
	if (adpcm->ms.delta[channel] < 16)
Packit 1fb8d4
		adpcm->ms.delta[channel] = 16;
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
	size_t 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 Service 5a9772
				context->adpcm.ms.sample1[0] = read_int16(src + 4);
Packit Service 5a9772
				context->adpcm.ms.sample1[1] = read_int16(src + 6);
Packit Service 5a9772
				context->adpcm.ms.sample2[0] = read_int16(src + 0);
Packit Service 5a9772
				context->adpcm.ms.sample2[1] = read_int16(src + 2);
Packit Service 5a9772
				write_int16(dst + 0, context->adpcm.ms.sample1[0]);
Packit Service 5a9772
				write_int16(dst + 2, context->adpcm.ms.sample1[1]);
Packit Service 5a9772
				write_int16(dst + 4, context->adpcm.ms.sample2[0]);
Packit Service 5a9772
				write_int16(dst + 6, 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 Service 5a9772
				context->adpcm.ms.sample1[0] = read_int16(src + 2);
Packit Service 5a9772
				context->adpcm.ms.sample2[0] = read_int16(src + 0);
Packit Service 5a9772
				write_int16(dst + 0, context->adpcm.ms.sample1[0]);
Packit Service 5a9772
				write_int16(dst + 2, context->adpcm.ms.sample2[0]);
Packit 1fb8d4
				dst += 4;
Packit 1fb8d4
				src += 4;
Packit 1fb8d4
				size -= 4;
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
Packit Service 5a9772
		sample = read_int16(src);
Packit 1fb8d4
		src += 2;
Packit Service 5a9772
		*dst = (freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample, 0) << 4) & 0xFF;
Packit Service 5a9772
		sample = read_int16(src);
Packit 1fb8d4
		src += 2;
Packit 1fb8d4
		*dst += freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample,
Packit Service 5a9772
		                                           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 Service 5a9772
#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 Service 5a9772
	const BYTE* resampleData;
Packit Service 5a9772
	size_t resampleLength;
Packit Service 5a9772
	AUDIO_FORMAT format;
Packit 1fb8d4
Packit 1fb8d4
	if (!context || !context->encoder || !srcFormat || !data || !out)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit Service 5a9772
	format = *srcFormat;
Packit Service 5a9772
Packit Service 5a9772
	if (!freerdp_dsp_channel_mix(context, data, length, srcFormat, &resampleData, &resampleLength))
Packit Service 5a9772
		return FALSE;
Packit Service 5a9772
Packit Service 5a9772
	format.nChannels = context->format.nChannels;
Packit Service 5a9772
Packit Service 5a9772
	if (!freerdp_dsp_resample(context, resampleData, resampleLength, &format, &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 Service 5a9772
#if !defined(WITH_DSP_EXPERIMENTAL)
Packit Service 5a9772
	WINPR_UNUSED(encode);
Packit Service 5a9772
#endif
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
}