summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorChristian Hoene <christian.hoene@symonics.com>2016-04-22 18:03:30 +0200
committerChristian Hoene <christian.hoene@symonics.com>2016-04-22 18:03:30 +0200
commit030d72b07d6ee500a840ae29dc1f5f9a2a56b430 (patch)
tree59e0540431604402749e71e5876427cef0d1413a /modules
parent54a4418e1b6a4b485ac54a49ab3c7dbc8a9cb5a8 (diff)
Added resampler to decode
Diffstat (limited to 'modules')
-rw-r--r--modules/mpa/decode.c69
-rw-r--r--modules/mpa/encode.c24
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),