summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbc/sbc.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/sbc/sbc.c b/sbc/sbc.c
index ffdf05d..5ba5eb3 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -40,6 +40,7 @@
#include <errno.h>
#include <string.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <sys/types.h>
#include <limits.h>
@@ -52,6 +53,9 @@
#define SBC_SYNCWORD 0x9C
+#define MSBC_SYNCWORD 0xAD
+#define MSBC_BLOCKS 15
+
/* This structure contains an unpacked SBC frame.
Yes, there is probably quite some unused space herein */
struct sbc_frame {
@@ -903,18 +907,22 @@ static ssize_t sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len
}
}
-static void sbc_encoder_init(struct sbc_encoder_state *state,
- const struct sbc_frame *frame)
+static void sbc_encoder_init(bool msbc, struct sbc_encoder_state *state,
+ const struct sbc_frame *frame)
{
memset(&state->X, 0, sizeof(state->X));
state->position = (SBC_X_BUFFER_SIZE - frame->subbands * 9) & ~7;
- state->increment = 4;
+ if (msbc)
+ state->increment = 1;
+ else
+ state->increment = 4;
sbc_init_primitives(state);
}
struct sbc_priv {
int init;
+ bool msbc;
struct SBC_ALIGNED sbc_frame frame;
struct SBC_ALIGNED sbc_decoder_state dec_state;
struct SBC_ALIGNED sbc_encoder_state enc_state;
@@ -922,6 +930,7 @@ struct sbc_priv {
static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
{
+ sbc->flags = flags;
sbc->frequency = SBC_FREQ_44100;
sbc->mode = SBC_MODE_STEREO;
sbc->subbands = SBC_SB_8;
@@ -1057,12 +1066,15 @@ SBC_EXPORT ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
priv->frame.subband_mode = sbc->subbands;
priv->frame.subbands = sbc->subbands ? 8 : 4;
priv->frame.block_mode = sbc->blocks;
- priv->frame.blocks = 4 + (sbc->blocks * 4);
+ if (priv->msbc)
+ priv->frame.blocks = MSBC_BLOCKS;
+ else
+ priv->frame.blocks = 4 + (sbc->blocks * 4);
priv->frame.bitpool = sbc->bitpool;
priv->frame.codesize = sbc_get_codesize(sbc);
priv->frame.length = sbc_get_frame_length(sbc);
- sbc_encoder_init(&priv->enc_state, &priv->frame);
+ sbc_encoder_init(priv->msbc, &priv->enc_state, &priv->frame);
priv->init = 1;
} else if (priv->frame.bitpool != sbc->bitpool) {
priv->frame.length = sbc_get_frame_length(sbc);
@@ -1141,7 +1153,10 @@ SBC_EXPORT size_t sbc_get_frame_length(sbc_t *sbc)
return priv->frame.length;
subbands = sbc->subbands ? 8 : 4;
- blocks = 4 + (sbc->blocks * 4);
+ if (priv->msbc)
+ blocks = MSBC_BLOCKS;
+ else
+ blocks = 4 + (sbc->blocks * 4);
channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
joint = sbc->mode == SBC_MODE_JOINT_STEREO ? 1 : 0;
bitpool = sbc->bitpool;
@@ -1165,7 +1180,10 @@ SBC_EXPORT unsigned sbc_get_frame_duration(sbc_t *sbc)
priv = sbc->priv;
if (!priv->init) {
subbands = sbc->subbands ? 8 : 4;
- blocks = 4 + (sbc->blocks * 4);
+ if (priv->msbc)
+ blocks = MSBC_BLOCKS;
+ else
+ blocks = 4 + (sbc->blocks * 4);
} else {
subbands = priv->frame.subbands;
blocks = priv->frame.blocks;
@@ -1202,7 +1220,10 @@ SBC_EXPORT size_t sbc_get_codesize(sbc_t *sbc)
priv = sbc->priv;
if (!priv->init) {
subbands = sbc->subbands ? 8 : 4;
- blocks = 4 + (sbc->blocks * 4);
+ if (priv->msbc)
+ blocks = MSBC_BLOCKS;
+ else
+ blocks = 4 + (sbc->blocks * 4);
channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
} else {
subbands = priv->frame.subbands;