dsp: rewrite api to reduce memory allocations.

This commit is contained in:
Vic Lee 2012-05-09 16:15:23 +08:00
parent 2faec09ee2
commit c9ad01ea55
7 changed files with 163 additions and 105 deletions

View File

@ -41,7 +41,8 @@ typedef struct _AudinALSADevice
int bytes_per_channel;
int wformat;
int block_size;
ADPCM adpcm;
FREERDP_DSP_CONTEXT* dsp_context;
freerdp_thread* thread;
@ -96,7 +97,6 @@ static boolean audin_alsa_thread_receive(AudinALSADevice* alsa, uint8* src, int
uint8* encoded_data;
int rbytes_per_frame;
int tbytes_per_frame;
uint8* resampled_data;
rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel;
tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel;
@ -104,18 +104,18 @@ static boolean audin_alsa_thread_receive(AudinALSADevice* alsa, uint8* src, int
if ((alsa->target_rate == alsa->actual_rate) &&
(alsa->target_channels == alsa->actual_channels))
{
resampled_data = NULL;
frames = size / rbytes_per_frame;
}
else
{
resampled_data = dsp_resample(src, alsa->bytes_per_channel,
alsa->dsp_context->resample(alsa->dsp_context, src, alsa->bytes_per_channel,
alsa->actual_channels, alsa->actual_rate, size / rbytes_per_frame,
alsa->target_channels, alsa->target_rate, &frames);
alsa->target_channels, alsa->target_rate);
frames = alsa->dsp_context->resampled_frames;
DEBUG_DVC("resampled %d frames at %d to %d frames at %d",
size / rbytes_per_frame, alsa->actual_rate, frames, alsa->target_rate);
size = frames * tbytes_per_frame;
src = resampled_data;
src = alsa->dsp_context->resampled_buffer;
}
while (frames > 0)
@ -133,9 +133,11 @@ static boolean audin_alsa_thread_receive(AudinALSADevice* alsa, uint8* src, int
{
if (alsa->wformat == 0x11)
{
encoded_data = dsp_encode_ima_adpcm(&alsa->adpcm,
alsa->dsp_context->encode_ima_adpcm(alsa->dsp_context,
alsa->buffer, alsa->buffer_frames * tbytes_per_frame,
alsa->target_channels, alsa->block_size, &encoded_size);
alsa->target_channels, alsa->block_size);
encoded_data = alsa->dsp_context->adpcm_buffer;
encoded_size = alsa->dsp_context->adpcm_size;
DEBUG_DVC("encoded %d to %d",
alsa->buffer_frames * tbytes_per_frame, encoded_size);
}
@ -153,8 +155,6 @@ static boolean audin_alsa_thread_receive(AudinALSADevice* alsa, uint8* src, int
else
ret = alsa->receive(encoded_data, encoded_size, alsa->user_data);
alsa->buffer_frames = 0;
if (encoded_data != alsa->buffer)
xfree(encoded_data);
if (!ret)
break;
}
@ -162,9 +162,6 @@ static boolean audin_alsa_thread_receive(AudinALSADevice* alsa, uint8* src, int
frames -= cframes;
}
if (resampled_data)
xfree(resampled_data);
return ret;
}
@ -184,7 +181,7 @@ static void* audin_alsa_thread_func(void* arg)
alsa->buffer = (uint8*) xzalloc(tbytes_per_frame * alsa->frames_per_packet);
alsa->buffer_frames = 0;
buffer = (uint8*) xzalloc(rbytes_per_frame * alsa->frames_per_packet);
memset(&alsa->adpcm, 0, sizeof(ADPCM));
freerdp_dsp_context_reset_adpcm(alsa->dsp_context);
do
{
if ((error = snd_pcm_open(&capture_handle, alsa->device_name, SND_PCM_STREAM_CAPTURE, 0)) < 0)
@ -233,6 +230,7 @@ static void audin_alsa_free(IAudinDevice* device)
AudinALSADevice* alsa = (AudinALSADevice*) device;
freerdp_thread_free(alsa->thread);
freerdp_dsp_context_free(alsa->dsp_context);
xfree(alsa);
}
@ -365,6 +363,8 @@ int FreeRDPAudinDeviceEntry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
alsa->bytes_per_channel = 2;
alsa->thread = freerdp_thread_new();
alsa->dsp_context = freerdp_dsp_context_new();
pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, (IAudinDevice*) alsa);
return 0;

View File

@ -39,7 +39,8 @@ typedef struct _AudinPulseDevice
pa_stream* stream;
int format;
int block_size;
ADPCM adpcm;
FREERDP_DSP_CONTEXT* dsp_context;
int bytes_per_frame;
uint8* buffer;
@ -145,6 +146,7 @@ static void audin_pulse_free(IAudinDevice* device)
pa_threaded_mainloop_free(pulse->mainloop);
pulse->mainloop = NULL;
}
freerdp_dsp_context_free(pulse->dsp_context);
xfree(pulse);
}
@ -297,9 +299,11 @@ static void audin_pulse_stream_request_callback(pa_stream* stream, size_t length
{
if (pulse->format == 0x11)
{
encoded_data = dsp_encode_ima_adpcm(&pulse->adpcm,
pulse->dsp_context->encode_ima_adpcm(pulse->dsp_context,
pulse->buffer, pulse->buffer_frames * pulse->bytes_per_frame,
pulse->sample_spec.channels, pulse->block_size, &encoded_size);
pulse->sample_spec.channels, pulse->block_size);
encoded_data = pulse->dsp_context->adpcm_buffer;
encoded_size = pulse->dsp_context->adpcm_size;
DEBUG_DVC("encoded %d to %d",
pulse->buffer_frames * pulse->bytes_per_frame, encoded_size);
}
@ -311,8 +315,6 @@ static void audin_pulse_stream_request_callback(pa_stream* stream, size_t length
ret = pulse->receive(encoded_data, encoded_size, pulse->user_data);
pulse->buffer_frames = 0;
if (encoded_data != pulse->buffer)
xfree(encoded_data);
if (!ret)
break;
}
@ -412,7 +414,7 @@ static void audin_pulse_open(IAudinDevice* device, AudinReceive receive, void* u
pa_threaded_mainloop_unlock(pulse->mainloop);
if (state == PA_STREAM_READY)
{
memset(&pulse->adpcm, 0, sizeof(ADPCM));
freerdp_dsp_context_reset_adpcm(pulse->dsp_context);
pulse->buffer = xzalloc(pulse->bytes_per_frame * pulse->frames_per_packet);
pulse->buffer_frames = 0;
DEBUG_DVC("connected");
@ -443,6 +445,8 @@ int FreeRDPAudinDeviceEntry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
strncpy(pulse->device_name, (char*)data->data[2], sizeof(pulse->device_name));
}
pulse->dsp_context = freerdp_dsp_context_new();
pulse->mainloop = pa_threaded_mainloop_new();
if (!pulse->mainloop)
{

View File

@ -40,6 +40,8 @@ typedef struct _TSMFALSAAudioDevice
uint32 source_channels;
uint32 actual_channels;
uint32 bytes_per_sample;
FREERDP_DSP_CONTEXT* dsp_context;
} TSMFALSAAudioDevice;
static boolean tsmf_alsa_open_device(TSMFALSAAudioDevice* alsa)
@ -151,7 +153,6 @@ static boolean tsmf_alsa_play(ITSMFAudioDevice* audio, uint8* data, uint32 data_
uint8* pindex;
int rbytes_per_frame;
int sbytes_per_frame;
uint8* resampled_data;
TSMFALSAAudioDevice* alsa = (TSMFALSAAudioDevice*) audio;
DEBUG_DVC("data_size %d", data_size);
@ -164,18 +165,18 @@ static boolean tsmf_alsa_play(ITSMFAudioDevice* audio, uint8* data, uint32 data_
if ((alsa->source_rate == alsa->actual_rate) &&
(alsa->source_channels == alsa->actual_channels))
{
resampled_data = NULL;
src = data;
}
else
{
resampled_data = dsp_resample(data, alsa->bytes_per_sample,
alsa->dsp_context->resample(alsa->dsp_context, data, alsa->bytes_per_sample,
alsa->source_channels, alsa->source_rate, data_size / sbytes_per_frame,
alsa->actual_channels, alsa->actual_rate, &frames);
alsa->actual_channels, alsa->actual_rate);
frames = alsa->dsp_context->resampled_frames;
DEBUG_DVC("resampled %d frames at %d to %d frames at %d",
data_size / sbytes_per_frame, alsa->source_rate, frames, alsa->actual_rate);
data_size = frames * rbytes_per_frame;
src = resampled_data;
src = alsa->dsp_context->resampled_buffer;
}
pindex = src;
@ -203,9 +204,6 @@ static boolean tsmf_alsa_play(ITSMFAudioDevice* audio, uint8* data, uint32 data_
break;
pindex += error * rbytes_per_frame;
}
if (resampled_data)
xfree(resampled_data);
}
xfree(data);
@ -242,6 +240,7 @@ static void tsmf_alsa_free(ITSMFAudioDevice* audio)
snd_pcm_drain(alsa->out_handle);
snd_pcm_close(alsa->out_handle);
}
freerdp_dsp_context_free(alsa->dsp_context);
xfree(alsa);
}
@ -258,6 +257,8 @@ ITSMFAudioDevice* TSMFAudioDeviceEntry(void)
alsa->iface.Flush = tsmf_alsa_flush;
alsa->iface.Free = tsmf_alsa_free;
alsa->dsp_context = freerdp_dsp_context_new();
return (ITSMFAudioDevice*) alsa;
}

View File

@ -45,7 +45,8 @@ struct rdpsnd_alsa_plugin
int wformat;
int block_size;
int latency;
ADPCM adpcm;
FREERDP_DSP_CONTEXT* dsp_context;
};
static void rdpsnd_alsa_set_params(rdpsndAlsaPlugin* alsa)
@ -169,7 +170,7 @@ static void rdpsnd_alsa_open(rdpsndDevicePlugin* device, rdpsndFormat* format, i
}
else
{
memset(&alsa->adpcm, 0, sizeof(ADPCM));
freerdp_dsp_context_reset_adpcm(alsa->dsp_context);
rdpsnd_alsa_set_format(device, format, latency);
}
}
@ -193,6 +194,7 @@ static void rdpsnd_alsa_free(rdpsndDevicePlugin* device)
rdpsnd_alsa_close(device);
xfree(alsa->device_name);
freerdp_dsp_context_free(alsa->dsp_context);
xfree(alsa);
}
@ -229,10 +231,7 @@ static void rdpsnd_alsa_set_volume(rdpsndDevicePlugin* device, uint32 value)
static void rdpsnd_alsa_play(rdpsndDevicePlugin* device, uint8* data, int size)
{
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*)device;
uint8* decoded_data;
int decoded_size;
uint8* src;
uint8* resampled_data;
int len;
int error;
int frames;
@ -246,14 +245,13 @@ static void rdpsnd_alsa_play(rdpsndDevicePlugin* device, uint8* data, int size)
if (alsa->wformat == 0x11)
{
decoded_data = dsp_decode_ima_adpcm(&alsa->adpcm,
data, size, alsa->source_channels, alsa->block_size, &decoded_size);
size = decoded_size;
src = decoded_data;
alsa->dsp_context->decode_ima_adpcm(alsa->dsp_context,
data, size, alsa->source_channels, alsa->block_size);
size = alsa->dsp_context->adpcm_size;
src = alsa->dsp_context->adpcm_buffer;
}
else
{
decoded_data = NULL;
src = data;
}
@ -268,17 +266,17 @@ static void rdpsnd_alsa_play(rdpsndDevicePlugin* device, uint8* data, int size)
if ((alsa->source_rate == alsa->actual_rate) &&
(alsa->source_channels == alsa->actual_channels))
{
resampled_data = NULL;
}
else
{
resampled_data = dsp_resample(src, alsa->bytes_per_channel,
alsa->dsp_context->resample(alsa->dsp_context, src, alsa->bytes_per_channel,
alsa->source_channels, alsa->source_rate, size / sbytes_per_frame,
alsa->actual_channels, alsa->actual_rate, &frames);
alsa->actual_channels, alsa->actual_rate);
frames = alsa->dsp_context->resampled_frames;
DEBUG_SVC("resampled %d frames at %d to %d frames at %d",
size / sbytes_per_frame, alsa->source_rate, frames, alsa->actual_rate);
size = frames * rbytes_per_frame;
src = resampled_data;
src = alsa->dsp_context->resampled_buffer;
}
pindex = src;
@ -303,11 +301,6 @@ static void rdpsnd_alsa_play(rdpsndDevicePlugin* device, uint8* data, int size)
}
pindex += error * rbytes_per_frame;
}
if (resampled_data)
xfree(resampled_data);
if (decoded_data)
xfree(decoded_data);
}
static void rdpsnd_alsa_start(rdpsndDevicePlugin* device)
@ -353,6 +346,8 @@ int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
alsa->actual_channels = 2;
alsa->bytes_per_channel = 2;
alsa->dsp_context = freerdp_dsp_context_new();
pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*)alsa);
return 0;

View File

@ -41,7 +41,8 @@ struct rdpsnd_pulse_plugin
int format;
int block_size;
int latency;
ADPCM adpcm;
FREERDP_DSP_CONTEXT* dsp_context;
};
static void rdpsnd_pulse_context_state_callback(pa_context* context, void* userdata)
@ -297,7 +298,7 @@ static void rdpsnd_pulse_open(rdpsndDevicePlugin* device, rdpsndFormat* format,
pa_threaded_mainloop_unlock(pulse->mainloop);
if (state == PA_STREAM_READY)
{
memset(&pulse->adpcm, 0, sizeof(ADPCM));
freerdp_dsp_context_reset_adpcm(pulse->dsp_context);
DEBUG_SVC("connected");
}
else
@ -329,6 +330,7 @@ static void rdpsnd_pulse_free(rdpsndDevicePlugin* device)
pulse->mainloop = NULL;
}
xfree(pulse->device_name);
freerdp_dsp_context_free(pulse->dsp_context);
xfree(pulse);
}
@ -398,23 +400,20 @@ static void rdpsnd_pulse_play(rdpsndDevicePlugin* device, uint8* data, int size)
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
int len;
int ret;
uint8* decoded_data;
uint8* src;
int decoded_size;
if (!pulse->stream)
return;
if (pulse->format == 0x11)
{
decoded_data = dsp_decode_ima_adpcm(&pulse->adpcm,
data, size, pulse->sample_spec.channels, pulse->block_size, &decoded_size);
size = decoded_size;
src = decoded_data;
pulse->dsp_context->decode_ima_adpcm(pulse->dsp_context,
data, size, pulse->sample_spec.channels, pulse->block_size);
size = pulse->dsp_context->adpcm_size;
src = pulse->dsp_context->adpcm_buffer;
}
else
{
decoded_data = NULL;
src = data;
}
@ -440,9 +439,6 @@ static void rdpsnd_pulse_play(rdpsndDevicePlugin* device, uint8* data, int size)
size -= len;
}
pa_threaded_mainloop_unlock(pulse->mainloop);
if (decoded_data)
xfree(decoded_data);
}
static void rdpsnd_pulse_start(rdpsndDevicePlugin* device)
@ -480,6 +476,8 @@ int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
pulse->device_name = NULL;
}
pulse->dsp_context = freerdp_dsp_context_new();
pulse->mainloop = pa_threaded_mainloop_new();
if (!pulse->mainloop)
{

View File

@ -29,14 +29,34 @@ struct _ADPCM
};
typedef struct _ADPCM ADPCM;
FREERDP_API uint8* dsp_resample(uint8* src, int bytes_per_sample,
uint32 schan, uint32 srate, int sframes,
uint32 rchan, uint32 rrate, int * prframes);
typedef struct _FREERDP_DSP_CONTEXT FREERDP_DSP_CONTEXT;
struct _FREERDP_DSP_CONTEXT
{
uint8* resampled_buffer;
uint32 resampled_size;
uint32 resampled_frames;
uint32 resampled_maxlength;
FREERDP_API uint8* dsp_decode_ima_adpcm(ADPCM* adpcm,
uint8* src, int size, int channels, int block_size, int* out_size);
FREERDP_API uint8* dsp_encode_ima_adpcm(ADPCM* adpcm,
uint8* src, int size, int channels, int block_size, int* out_size);
uint8* adpcm_buffer;
uint32 adpcm_size;
uint32 adpcm_maxlength;
ADPCM adpcm;
void (*resample)(FREERDP_DSP_CONTEXT* context,
const uint8* src, int bytes_per_sample,
uint32 schan, uint32 srate, int sframes,
uint32 rchan, uint32 rrate);
void (*decode_ima_adpcm)(FREERDP_DSP_CONTEXT* context,
const uint8* src, int size, int channels, int block_size);
void (*encode_ima_adpcm)(FREERDP_DSP_CONTEXT* context,
const uint8* src, int size, int channels, int block_size);
};
FREERDP_API FREERDP_DSP_CONTEXT* freerdp_dsp_context_new(void);
FREERDP_API void freerdp_dsp_context_free(FREERDP_DSP_CONTEXT* context);
#define freerdp_dsp_context_reset_adpcm(_c) memset(&_c->adpcm, 0, sizeof(ADPCM))
#endif /* __DSP_UTILS_H */

View File

@ -24,9 +24,10 @@
#include <freerdp/utils/memory.h>
#include <freerdp/utils/dsp.h>
uint8* dsp_resample(uint8* src, int bytes_per_sample,
static void freerdp_dsp_resample(FREERDP_DSP_CONTEXT* context,
const uint8* src, int bytes_per_sample,
uint32 schan, uint32 srate, int sframes,
uint32 rchan, uint32 rrate, int * prframes)
uint32 rchan, uint32 rrate)
{
uint8* dst;
uint8* p;
@ -39,9 +40,13 @@ uint8* dsp_resample(uint8* src, int bytes_per_sample,
sbytes = bytes_per_sample * schan;
rbytes = bytes_per_sample * rchan;
rframes = sframes * rrate / srate;
*prframes = rframes;
rsize = rbytes * rframes;
dst = (uint8*) xzalloc(rsize);
if (rsize > context->resampled_maxlength)
{
context->resampled_maxlength = rsize + 1024;
context->resampled_buffer = xrealloc(context->resampled_buffer, context->resampled_maxlength);
}
dst = context->resampled_buffer;
p = dst;
for (i = 0; i < rframes; i++)
@ -59,7 +64,8 @@ uint8* dsp_resample(uint8* src, int bytes_per_sample,
}
}
return dst;
context->resampled_frames = rframes;
context->resampled_size = rsize;
}
/**
@ -122,35 +128,39 @@ static uint16 dsp_decode_ima_adpcm_sample(ADPCM* adpcm,
return (uint16) d;
}
uint8* dsp_decode_ima_adpcm(ADPCM* adpcm,
uint8* src, int size, int channels, int block_size, int* out_size)
static void freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* context,
const uint8* src, int size, int channels, int block_size)
{
uint8* out;
uint8* dst;
uint8 sample;
uint16 decoded;
uint32 out_size;
int channel;
int i;
*out_size = size * 4;
out = (uint8 *) xzalloc(*out_size);
dst = out;
out_size = size * 4;
if (out_size > context->adpcm_maxlength)
{
context->adpcm_maxlength = out_size + 1024;
context->adpcm_buffer = xrealloc(context->adpcm_buffer, context->adpcm_maxlength);
}
dst = context->adpcm_buffer;
while (size > 0)
{
if (size % block_size == 0)
{
adpcm->last_sample[0] = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8));
adpcm->last_step[0] = (sint16) (*(src + 2));
context->adpcm.last_sample[0] = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8));
context->adpcm.last_step[0] = (sint16) (*(src + 2));
src += 4;
size -= 4;
*out_size -= 16;
out_size -= 16;
if (channels > 1)
{
adpcm->last_sample[1] = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8));
adpcm->last_step[1] = (sint16) (*(src + 2));
context->adpcm.last_sample[1] = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8));
context->adpcm.last_step[1] = (sint16) (*(src + 2));
src += 4;
size -= 4;
*out_size -= 16;
out_size -= 16;
}
}
@ -160,11 +170,11 @@ uint8* dsp_decode_ima_adpcm(ADPCM* adpcm,
{
channel = (i < 4 ? 0 : 1);
sample = ((*src) & 0x0f);
decoded = dsp_decode_ima_adpcm_sample(adpcm, channel, sample);
decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, channel, sample);
dst[((i & 3) << 3) + (channel << 1)] = (decoded & 0xff);
dst[((i & 3) << 3) + (channel << 1) + 1] = (decoded >> 8);
sample = ((*src) >> 4);
decoded = dsp_decode_ima_adpcm_sample(adpcm, channel, sample);
decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, channel, sample);
dst[((i & 3) << 3) + (channel << 1) + 4] = (decoded & 0xff);
dst[((i & 3) << 3) + (channel << 1) + 5] = (decoded >> 8);
src++;
@ -175,18 +185,19 @@ uint8* dsp_decode_ima_adpcm(ADPCM* adpcm,
else
{
sample = ((*src) & 0x0f);
decoded = dsp_decode_ima_adpcm_sample(adpcm, 0, sample);
decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, 0, sample);
*dst++ = (decoded & 0xff);
*dst++ = (decoded >> 8);
sample = ((*src) >> 4);
decoded = dsp_decode_ima_adpcm_sample(adpcm, 0, sample);
decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, 0, sample);
*dst++ = (decoded & 0xff);
*dst++ = (decoded >> 8);
src++;
size--;
}
}
return out;
context->adpcm_size = out_size;
}
/**
@ -277,30 +288,35 @@ static uint8 dsp_encode_ima_adpcm_sample(ADPCM* adpcm,
return enc;
}
uint8* dsp_encode_ima_adpcm(ADPCM* adpcm,
uint8* src, int size, int channels, int block_size, int* out_size)
static void freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT* context,
const uint8* src, int size, int channels, int block_size)
{
uint8* out;
uint8* dst;
sint16 sample;
uint8 encoded;
uint32 out_size;
int i;
out = (uint8*) xzalloc(size / 2);
dst = out;
out_size = size / 2;
if (out_size > context->adpcm_maxlength)
{
context->adpcm_maxlength = out_size + 1024;
context->adpcm_buffer = xrealloc(context->adpcm_buffer, context->adpcm_maxlength);
}
dst = context->adpcm_buffer;
while (size > 0)
{
if ((dst - out) % block_size == 0)
if ((dst - context->adpcm_buffer) % block_size == 0)
{
*dst++ = adpcm->last_sample[0] & 0xff;
*dst++ = (adpcm->last_sample[0] >> 8) & 0xff;
*dst++ = (uint8) adpcm->last_step[0];
*dst++ = context->adpcm.last_sample[0] & 0xff;
*dst++ = (context->adpcm.last_sample[0] >> 8) & 0xff;
*dst++ = (uint8) context->adpcm.last_step[0];
*dst++ = 0;
if (channels > 1)
{
*dst++ = adpcm->last_sample[1] & 0xff;
*dst++ = (adpcm->last_sample[1] >> 8) & 0xff;
*dst++ = (uint8) adpcm->last_step[1];
*dst++ = context->adpcm.last_sample[1] & 0xff;
*dst++ = (context->adpcm.last_sample[1] >> 8) & 0xff;
*dst++ = (uint8) context->adpcm.last_step[1];
*dst++ = 0;
}
}
@ -312,7 +328,7 @@ uint8* dsp_encode_ima_adpcm(ADPCM* adpcm,
{
sample = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8));
src += 2;
encoded = dsp_encode_ima_adpcm_sample(adpcm, i % 2, sample);
encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, i % 2, sample);
dst[ima_stereo_encode_map[i].byte_num] |= encoded << ima_stereo_encode_map[i].byte_shift;
}
dst += 8;
@ -322,15 +338,39 @@ uint8* dsp_encode_ima_adpcm(ADPCM* adpcm,
{
sample = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8));
src += 2;
encoded = dsp_encode_ima_adpcm_sample(adpcm, 0, sample);
encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample);
sample = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8));
src += 2;
encoded |= dsp_encode_ima_adpcm_sample(adpcm, 0, sample) << 4;
encoded |= dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample) << 4;
*dst++ = encoded;
size -= 4;
}
}
*out_size = dst - out;
return out;
context->adpcm_size = dst - context->adpcm_buffer;
}
FREERDP_DSP_CONTEXT* freerdp_dsp_context_new(void)
{
FREERDP_DSP_CONTEXT* context;
context = xnew(FREERDP_DSP_CONTEXT);
context->resample = freerdp_dsp_resample;
context->decode_ima_adpcm = freerdp_dsp_decode_ima_adpcm;
context->encode_ima_adpcm = freerdp_dsp_encode_ima_adpcm;
return context;
}
void freerdp_dsp_context_free(FREERDP_DSP_CONTEXT* context)
{
if (context)
{
if (context->resampled_buffer)
xfree(context->resampled_buffer);
if (context->adpcm_buffer)
xfree(context->adpcm_buffer);
xfree(context);
}
}