getting ready for auto resample in opposing versions of SLIN codec

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@232 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2005-12-29 00:26:17 +00:00
parent 99e7acce6b
commit 82d141df73
3 changed files with 139 additions and 6 deletions

View File

@ -70,6 +70,10 @@ SWITCH_DECLARE(switch_status) switch_socket_create_pollfd(switch_pollfd_t *poll,
SWITCH_DECLARE(int) switch_socket_waitfor(switch_pollfd_t *poll, int ms);
SWITCH_DECLARE(void) switch_swap_linear(int16_t *buf, int len);
SWITCH_DECLARE(char *) switch_cut_path(char *in);
SWITCH_DECLARE(int) float_to_short(float *f, short *s, int len);
SWITCH_DECLARE(int) char_to_float(char *c, float *f, int len);
SWITCH_DECLARE(int) float_to_char(float *f, char *c, int len);
SWITCH_DECLARE(int) short_to_float(short *s, float *f, int len);
#if !defined(switch_strdupa) && defined(__GNUC__)
# define switch_strdupa(s) \

View File

@ -34,9 +34,49 @@
static const char modname[] = "mod_rawaudio";
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
struct raw_context {
void *enc_resampler;
int enc_from;
int enc_to;
double enc_factor;
void *dec_resampler;
int dec_from;
int dec_to;
double dec_factor;
};
static int resample(void *handle, double factor, float *src, int srclen, float *dst, int dstlen, int last)
{
int o=0, srcused=0, srcpos=0, out=0;
for(;;) {
int srcBlock = MIN(srclen-srcpos, srclen);
int lastFlag = (last && (srcBlock == srclen-srcpos));
printf("resampling %d/%d (%d)\n", srcpos, srclen, MIN(dstlen-out, dstlen));
o = resample_process(handle, factor, &src[srcpos], srcBlock, lastFlag, &srcused, &dst[out], dstlen-out);
srcpos += srcused;
if (o >= 0)
out += o;
if (o < 0 || (o == 0 && srcpos == srclen))
break;
}
return out;
}
static switch_status switch_raw_init(switch_codec *codec, switch_codec_flag flags, const struct switch_codec_settings *codec_settings)
{
int encoding, decoding;
struct raw_context *context = NULL;
encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
@ -44,6 +84,10 @@ static switch_status switch_raw_init(switch_codec *codec, switch_codec_flag flag
if (!(encoding || decoding)) {
return SWITCH_STATUS_FALSE;
} else {
if (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context)))) {
return SWITCH_STATUS_MEMERR;
}
codec->private = context;
return SWITCH_STATUS_SUCCESS;
}
}
@ -56,11 +100,27 @@ static switch_status switch_raw_encode(switch_codec *codec,
size_t *encoded_data_len,
unsigned int *flag)
{
struct raw_context *context = codec->private;
/* NOOP indicates that the audio in is already the same as the audio out, so no conversion was necessary.
TBD look at other_codec to determine the original format of the data and determine if we need to resample
in the event the audio is the same format but different implementations.
TBD Support varying number of channels
*/
printf("encode %d %d->%d\n", decoded_data_len, other_codec->implementation->bytes_per_frame, codec->implementation->bytes_per_frame);
if (codec->implementation->samples_per_second != other_codec->implementation->samples_per_second) {
if (!context->enc_from) {
printf("Activate Resample %d->%d\n", codec->implementation->samples_per_second, other_codec->implementation->samples_per_second);
context->enc_from = codec->implementation->samples_per_second;
context->enc_to = other_codec->implementation->samples_per_second;
context->enc_factor = ((double)other_codec->implementation->samples_per_second / (double)codec->implementation->samples_per_second);
context->enc_resampler = resample_open(1, context->enc_factor, context->enc_factor);
}
if (context->enc_from) {
}
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_NOOP;
}
@ -73,6 +133,7 @@ static switch_status switch_raw_decode(switch_codec *codec,
size_t *decoded_data_len,
unsigned int *flag)
{
struct raw_context *context = codec->private;
printf("decode %d %d->%d\n", encoded_data_len, other_codec->implementation->bytes_per_frame, codec->implementation->bytes_per_frame);

View File

@ -30,6 +30,74 @@
*
*/
#include <switch_utils.h>
#define NORMFACT (float)0x8000
#define MAXSAMPLE (float)0x7FFF
#define MAXSAMPLEC (char)0x7F
SWITCH_DECLARE(int) float_to_short(float *f, short *s, int len)
{
int i;
float ft;
for(i=0;i<len;i++) {
ft = f[i] * NORMFACT;
if(ft >= 0) {
s[i] = (short)(ft+0.5);
} else {
s[i] = (short)(ft-0.5);
}
if (s[i] > (short)MAXSAMPLE) s[i] = (short)MAXSAMPLE;
if (s[i] < (short)-MAXSAMPLE) s[i] = (short)-MAXSAMPLE;
}
return len;
}
SWITCH_DECLARE(int) char_to_float(char *c, float *f, int len)
{
int i;
if (len % 2) {
return(-1);
}
for(i=1;i<len;i+=2) {
f[(int)(i/2)] = (float)(((c[i])*0x100) + c[i-1]);
f[(int)(i/2)] /= NORMFACT;
if (f[(int)(i/2)] > MAXSAMPLE) f[(int)(i/2)] = MAXSAMPLE;
if (f[(int)(i/2)] < -MAXSAMPLE) f[(int)(i/2)] = -MAXSAMPLE;
}
return len/2;
}
SWITCH_DECLARE(int) float_to_char(float *f, char *c, int len)
{
int i;
float ft;
long l;
for(i=0;i<len;i++) {
ft = f[i] * NORMFACT;
if (ft >= 0) {
l = (long)(ft+0.5);
} else {
l = (long)(ft-0.5);
}
c[i*2] = (unsigned char)((l)&0xff);
c[i*2+1] = (unsigned char)(((l)>>8)&0xff);
}
return len*2;
}
SWITCH_DECLARE(int) short_to_float(short *s, float *f, int len)
{
int i;
int min, max;
min = max = 0;
for(i=0;i<len;i++) {
f[i] = (float)(s[i]) / NORMFACT;
}
return len;
}
SWITCH_DECLARE(char *) switch_cut_path(char *in)
{