Merge pull request #585 from llyzs/dsp
dsp: rewrite api to reduce memory allocations.
This commit is contained in:
commit
e8144e4bdc
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user