Blame libfreerdp/codec/dsp.c

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