提交 82d141df authored 作者: Anthony Minessale's avatar Anthony Minessale

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
上级 99e7acce
......@@ -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) \
......
......@@ -34,16 +34,60 @@
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);
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,12 +100,28 @@ 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);
......
......@@ -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)
{
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论