summaryrefslogtreecommitdiff
path: root/modules/mpa/decode.c
diff options
context:
space:
mode:
authorChristian Hoene <christian.hoene@symonics.com>2016-04-24 11:43:11 +0200
committerChristian Hoene <christian.hoene@symonics.com>2016-04-24 11:43:11 +0200
commit1081461b418ef49943be1adae8752ad41052ef87 (patch)
tree248fb218393c4c42f0cfe266b922efe3767f5af5 /modules/mpa/decode.c
parent2bf9664d0f4c29569f783cb68367f70c3b9a2280 (diff)
Addressed code review and added start mute because of sync problems
Diffstat (limited to 'modules/mpa/decode.c')
-rw-r--r--modules/mpa/decode.c123
1 files changed, 70 insertions, 53 deletions
diff --git a/modules/mpa/decode.c b/modules/mpa/decode.c
index 65035e4..d62bd60 100644
--- a/modules/mpa/decode.c
+++ b/modules/mpa/decode.c
@@ -11,12 +11,12 @@
#include <string.h>
#include "mpa.h"
-#undef DEBUG
-
struct audec_state {
mpg123_handle *dec;
SpeexResamplerState *resampler;
int channels;
+ int16_t intermediate_buffer[MPA_FRAMESIZE*2];
+ int start;
};
@@ -36,7 +36,7 @@ int mpa_decode_update(struct audec_state **adsp, const struct aucodec *ac,
const char *fmtp)
{
struct audec_state *ads;
- int mpaerr, err=0;
+ int result, err=0;
if (!adsp || !ac || !ac->ch)
return EINVAL;
@@ -49,42 +49,47 @@ int mpa_decode_update(struct audec_state **adsp, const struct aucodec *ac,
if (ads)
mem_deref(ads);
-
+
ads = mem_zalloc(sizeof(*ads), destructor);
if (!ads)
return ENOMEM;
ads->channels = 0;
ads->resampler = NULL;
+ ads->start = 0;
- ads->dec = mpg123_new(NULL,&mpaerr);
+ ads->dec = mpg123_new(NULL,&result);
if (!ads->dec) {
- error("mpa: decoder create: %s\n", mpg123_plain_strerror(mpaerr));
+ error("mpa: decoder create: %s\n",
+ mpg123_plain_strerror(result));
err = ENOMEM;
goto out;
}
#ifdef DEBUG
- mpaerr = mpg123_param(ads->dec, MPG123_VERBOSE, 4, 4.);
+ result = mpg123_param(ads->dec, MPG123_VERBOSE, 4, 4.);
#else
- mpaerr = mpg123_param(ads->dec, MPG123_VERBOSE, 0, 0.);
+ result = mpg123_param(ads->dec, MPG123_VERBOSE, 0, 0.);
#endif
- if(mpaerr != MPG123_OK) {
- error("MPA libmpg123 param error %s", mpg123_plain_strerror(mpaerr));
+ if (result != MPG123_OK) {
+ error("MPA libmpg123 param error %s",
+ mpg123_plain_strerror(result));
err = EINVAL;
goto out;
}
- mpaerr = mpg123_format_all(ads->dec);
- if(mpaerr != MPG123_OK) {
- error("MPA libmpg123 format error %s", mpg123_plain_strerror(mpaerr));
+ result = mpg123_format_all(ads->dec);
+ if (result != MPG123_OK) {
+ error("MPA libmpg123 format error %s",
+ mpg123_plain_strerror(result));
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));
+ result = mpg123_open_feed(ads->dec);
+ if (result != MPG123_OK) {
+ error("MPA libmpg123 open feed error %s",
+ mpg123_plain_strerror(result));
err = EINVAL;
goto out;
}
@@ -103,74 +108,86 @@ int mpa_decode_update(struct audec_state **adsp, const struct aucodec *ac,
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, i;
- long samplerate,res;
+ int result, channels, encoding, i;
+ long samplerate;
size_t n;
- uint32_t header;
- static int16_t ds[2304];
- spx_uint32_t ds_len;
- spx_uint32_t in_len;
+ spx_uint32_t intermediate_len;
+ spx_uint32_t out_len;
- if (!ads || !sampv || !sampc || !buf)
+ if (!ads || !sampv || !sampc || !buf || len<=4)
return EINVAL;
- if(len<=4)
- return EINVAL;
- header = *(uint32_t*)buf;
- if(header != 0) {
- error("MPA header is not zero %08X\n", header);
+ if(*(uint32_t*)buf != 0) {
+ error("MPA header is not zero %08X, not supported yet\n",
+ *(uint32_t*)buf);
return EPROTO;
}
- 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) {
- error("mpa: upsample error: %s %d %d\n", strerror(res), in_len, *sampc/2);
+ if (ads->resampler) {
+ result = mpg123_decode(ads->dec, buf+4, len-4,
+ (unsigned char*)ads->intermediate_buffer,
+ sizeof(ads->intermediate_buffer), &n);
+ /* n counts bytes */
+ intermediate_len = n / 2 / ads->channels;
+ /* intermediate_len counts samples per channel */
+ out_len = *sampc;
+ result=speex_resampler_process_interleaved_int(
+ ads->resampler, ads->intermediate_buffer,
+ &intermediate_len, sampv, &out_len);
+ if (result!=RESAMPLER_ERR_SUCCESS) {
+ error("mpa: upsample error: %s %d %d\n",
+ strerror(result), out_len, *sampc/2);
return EPROTO;
}
#ifdef DEBUG
- debug("mpa decode %d %d %d %d\n",ds_len,*sampc,in_len,n);
+ info("mpa decode %d %d %d %d\n",intermediate_len,*sampc,
+ out_len,n);
#endif
- *sampc = in_len * 2;
+ *sampc = out_len * ads->channels;
}
else {
- mpaerr = mpg123_decode(ads->dec, buf+4, len-4, (unsigned char*)sampv, *sampc*2, &n);
+ result = mpg123_decode(ads->dec, buf+4, len-4,
+ (unsigned char*)sampv, *sampc*2, &n);
#ifdef DEBUG
- debug("mpa decode %d %d\n",*sampc,n);
+ info("mpa decode %d %d\n",*sampc,n);
#endif
*sampc = n / 2;
}
- if(ads->channels==1) {
- for(i=*sampc-1;i>=0;i--)
+
+ if (ads->start<100) { /* mpg123 needs some to sync */
+ ads->start++;
+ *sampc=0;
+ }
+ if (ads->channels==1) {
+ for (i=*sampc-1;i>=0;i--)
sampv[i+i+1]=sampv[i+i]=sampv[i];
*sampc *= 2;
}
- if(mpaerr == MPG123_NEW_FORMAT) {
+ if (result == MPG123_NEW_FORMAT) {
mpg123_getformat(ads->dec, &samplerate, &channels, &encoding);
- info("MPA libmpg123 format change %d %d %04X\n",samplerate,channels,encoding);
+ info("MPA libmpg123 format change %d %d %04X\n",samplerate
+ ,channels,encoding);
ads->channels = channels;
-
- if(samplerate != 48000) {
- ads->resampler = speex_resampler_init(channels, samplerate, 48000, 3, &mpaerr);
- if(mpaerr!=RESAMPLER_ERR_SUCCESS || ads->resampler==NULL) {
- error("mpa: upsampler init failed %d\n",mpaerr);
+ ads->start = 0;
+ if (samplerate != 48000) {
+ ads->resampler = speex_resampler_init(channels,
+ samplerate, 48000, 3, &result);
+ if (result!=RESAMPLER_ERR_SUCCESS
+ || ads->resampler==NULL) {
+ error("mpa: upsampler failed %d\n",result);
return EINVAL;
}
}
else
ads->resampler = NULL;
-
}
- else if(mpaerr == MPG123_NEED_MORE)
+ else if (result == MPG123_NEED_MORE)
return 0;
- else if(mpaerr != MPG123_OK) {
- error("MPA libmpg123 feed error %d %s", mpaerr, mpg123_plain_strerror(mpaerr));
+ else if (result != MPG123_OK) {
+ error("MPA libmpg123 feed error %d %s", result,
+ mpg123_plain_strerror(result));
return EPROTO;
}