diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/mpa/decode.c | 69 | ||||
-rw-r--r-- | modules/mpa/encode.c | 24 |
2 files changed, 76 insertions, 17 deletions
diff --git a/modules/mpa/decode.c b/modules/mpa/decode.c index 11ab8b4..7d57563 100644 --- a/modules/mpa/decode.c +++ b/modules/mpa/decode.c @@ -7,11 +7,14 @@ #include <re.h> #include <baresip.h> #include <mpg123.h> +#include <speex/speex_resampler.h> +#include <string.h> #include "mpa.h" struct audec_state { mpg123_handle *dec; + SpeexResamplerState *resampler; }; @@ -21,6 +24,8 @@ static void destructor(void *arg) mpg123_close(ads->dec); mpg123_delete(ads->dec); + + warning("mpa: decoder destroyed\n"); } @@ -35,14 +40,15 @@ int mpa_decode_update(struct audec_state **adsp, const struct aucodec *ac, ads = *adsp; - if (ads) - return 0; + warning("mpa: decoder created %s\n",fmtp); + if (ads) + mem_deref(ads); + ads = mem_zalloc(sizeof(*ads), destructor); if (!ads) return ENOMEM; - mpg123_delete(ads->dec); ads->dec = mpg123_new(NULL,&mpaerr); if (!ads->dec) { warning("mpa: decoder create: %s\n", mpg123_plain_strerror(mpaerr)); @@ -53,20 +59,23 @@ int mpa_decode_update(struct audec_state **adsp, const struct aucodec *ac, mpaerr = mpg123_param(ads->dec, MPG123_VERBOSE, 4, 4.); if(mpaerr != MPG123_OK) { error("MPA libmpg123 param error %s", mpg123_plain_strerror(mpaerr)); - return EINVAL; + err = EINVAL; + goto out; } - mpaerr = mpg123_format(ads->dec, 48000 /*ac->srate*/, 2 /*ac->ch*/, MPG123_ENC_SIGNED_16); + mpaerr = mpg123_format_all(ads->dec); if(mpaerr != MPG123_OK) { error("MPA libmpg123 format error %s", mpg123_plain_strerror(mpaerr)); - return EINVAL; + err = EINVAL; + goto out; } mpaerr = mpg123_open_feed(ads->dec); if(mpaerr != MPG123_OK) { error("MPA libmpg123 open feed error %s", mpg123_plain_strerror(mpaerr)); - return EINVAL; + err = EINVAL; + goto out; } @@ -84,9 +93,12 @@ int mpa_decode_frm(struct audec_state *ads, int16_t *sampv, size_t *sampc, const uint8_t *buf, size_t len) { int mpaerr, channels, encoding; - long samplerate; + long samplerate,res; size_t n; uint32_t header; + static int16_t ds[2304]; + spx_uint32_t ds_len; + spx_uint32_t in_len; if (!ads || !sampv || !sampc || !buf) return EINVAL; @@ -100,10 +112,48 @@ int mpa_decode_frm(struct audec_state *ads, int16_t *sampv, size_t *sampc, } - mpaerr = mpg123_decode(ads->dec, buf+4, len-4, (unsigned char*)sampv, *sampc*2, &n); + + + + if(ads->resampler) { + in_len = *sampc; + ds_len = 2304*2; + mpaerr = mpg123_decode(ads->dec, buf+4, len-4, (unsigned char*)ds, sizeof(ds), &n); /* n counts bytes */ + ds_len = n / 4; /* ds_len counts samples per channel */ + res=speex_resampler_process_interleaved_int(ads->resampler, ds, &ds_len, sampv, &in_len); + if (res!=RESAMPLER_ERR_SUCCESS) { + warning("mpa: upsample error: %s %d %d\n", strerror(res), in_len, *sampc/2); + return EPROTO; + } + warning("mpa decode %d %d %d %d\n",ds_len,*sampc,in_len,n); + *sampc = in_len * 2; + } + else { + mpaerr = mpg123_decode(ads->dec, buf+4, len-4, (unsigned char*)sampv, *sampc*2, &n); + warning("mpa decode %d %d\n",*sampc,n); + *sampc = n / 2; + } + if(mpaerr == MPG123_NEW_FORMAT) { mpg123_getformat(ads->dec, &samplerate, &channels, &encoding); info("MPA libmpg123 format change %d %d %04X\n",samplerate,channels,encoding); + + if(channels == 1) { + warning("mpa: resampler channel 1\n"); + ads->resampler = NULL; + return EINVAL; + } + + if(samplerate != 48000) { + ads->resampler = speex_resampler_init(2, samplerate, 48000, 3, &mpaerr); + if(mpaerr!=RESAMPLER_ERR_SUCCESS || ads->resampler==NULL) { + warning("mpa: upsampler init failed %d\n",mpaerr); + return EINVAL; + } + } + else + ads->resampler = NULL; + } else if(mpaerr == MPG123_NEED_MORE) return 0; @@ -113,7 +163,6 @@ int mpa_decode_frm(struct audec_state *ads, int16_t *sampv, size_t *sampc, } // warning("mpa decode %d %d %d\n",*sampc,len,n); - *sampc = n / 2; return 0; } diff --git a/modules/mpa/encode.c b/modules/mpa/encode.c index 1195844..de75845 100644 --- a/modules/mpa/encode.c +++ b/modules/mpa/encode.c @@ -25,6 +25,9 @@ static void destructor(void *arg) if (aes->enc) twolame_close(&aes->enc); + + warning("mpa: encoder destroyed\n"); + } int mpa_encode_update(struct auenc_state **aesp, const struct aucodec *ac, @@ -42,7 +45,11 @@ int mpa_encode_update(struct auenc_state **aesp, const struct aucodec *ac, aes = *aesp; - if (!aes) { + if (aes) { + mem_deref(aes); +// twolame_close(&aes->enc); + } + aes = mem_zalloc(sizeof(*aes), destructor); aes->enc = twolame_init(); if (!aes->enc) { @@ -52,7 +59,8 @@ int mpa_encode_update(struct auenc_state **aesp, const struct aucodec *ac, } aes->channels = auc->ch; *aesp = aes; - } + + warning("mpa: encoder created %s\n",fmtp); prm.samplerate = 32000; prm.bitrate = 128000; @@ -76,14 +84,15 @@ int mpa_encode_update(struct auenc_state **aesp, const struct aucodec *ac, return EINVAL; } - twolame_print_config(aes->enc); - mpares = twolame_init_params(aes->enc); if(mpares!=0) { warning("mpa: encoder init params failed\n"); return EINVAL; } + twolame_print_config(aes->enc); + + if(prm.samplerate != 48000) { aes->resampler = speex_resampler_init(2, 48000, prm.samplerate, 3, &mpares); if(mpares!=RESAMPLER_ERR_SUCCESS) { @@ -110,14 +119,15 @@ int mpa_encode_frm(struct auenc_state *aes, uint8_t *buf, size_t *len, if(aes->resampler) { in_len = sampc/2; + ds_len = 1920; n=speex_resampler_process_interleaved_int(aes->resampler, sampv, &in_len, ds, &ds_len); if (n!=RESAMPLER_ERR_SUCCESS || in_len != sampc/2) { - warning("mpa: downsample error: %s\n", strerror(n)); + warning("mpa: downsample error: %s %d %d\n", strerror(n), in_len, sampc/2); return EPROTO; } - n = twolame_encode_buffer_interleaved(aes->enc, ds, ds_len/2, + n = twolame_encode_buffer_interleaved(aes->enc, ds, ds_len, buf+4, (*len)-4); - warning("mpa encode %d %d %d %d %d\n",ds_len,sampc,aes->channels,*len,n); +// warning("mpa encode %d %d %d %d %d\n",ds_len,sampc,aes->channels,*len,n); } else n = twolame_encode_buffer_interleaved(aes->enc, sampv, (int)(sampc/2), |