Hi Luiz, > This adds sbc_init_a2dp that can be used to convert A2DP configuration to > the internal representation since they are not binary compatible. > --- > sbc/sbc.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > sbc/sbc.h | 1 + > 2 files changed, 139 insertions(+) > > diff --git a/sbc/sbc.c b/sbc/sbc.c > index c589217..4483074 100644 > --- a/sbc/sbc.c > +++ b/sbc/sbc.c > @@ -57,6 +57,55 @@ > #define MSBC_SYNCWORD 0xAD > #define MSBC_BLOCKS 15 > > +#define A2DP_SAMPLING_FREQ_16000 (1 << 3) > +#define A2DP_SAMPLING_FREQ_32000 (1 << 2) > +#define A2DP_SAMPLING_FREQ_44100 (1 << 1) > +#define A2DP_SAMPLING_FREQ_48000 1 Use (1 << 0) here and let the compiler optimize it. > + > +#define A2DP_CHANNEL_MODE_MONO (1 << 3) > +#define A2DP_CHANNEL_MODE_DUAL_CHANNEL (1 << 2) > +#define A2DP_CHANNEL_MODE_STEREO (1 << 1) > +#define A2DP_CHANNEL_MODE_JOINT_STEREO 1 > + > +#define A2DP_BLOCK_LENGTH_4 (1 << 3) > +#define A2DP_BLOCK_LENGTH_8 (1 << 2) > +#define A2DP_BLOCK_LENGTH_12 (1 << 1) > +#define A2DP_BLOCK_LENGTH_16 1 > + > +#define A2DP_SUBBANDS_4 (1 << 1) > +#define A2DP_SUBBANDS_8 1 > + > +#define A2DP_ALLOCATION_SNR (1 << 1) > +#define A2DP_ALLOCATION_LOUDNESS 1 > + > +#if __BYTE_ORDER == __LITTLE_ENDIAN > + > +typedef struct { > + uint8_t channel_mode:4; > + uint8_t frequency:4; > + uint8_t allocation_method:2; > + uint8_t subbands:2; > + uint8_t block_length:4; > + uint8_t min_bitpool; > + uint8_t max_bitpool; > +} __attribute__ ((packed)) a2dp_sbc_t; If these are internal anyway, then typedef is not needed. Just use a plain packed struct. > + > +#elif __BYTE_ORDER == __BIG_ENDIAN > + > +typedef struct { > + uint8_t frequency:4; > + uint8_t channel_mode:4; > + uint8_t block_length:4; > + uint8_t subbands:2; > + uint8_t allocation_method:2; > + uint8_t min_bitpool; > + uint8_t max_bitpool; > +} __attribute__ ((packed)) a2dp_sbc_t; > + > +#else > +#error "Unknown byte order" > +#endif > + > /* This structure contains an unpacked SBC frame. > Yes, there is probably quite some unused space herein */ > struct sbc_frame { > @@ -1046,6 +1095,95 @@ SBC_EXPORT int sbc_init_msbc(sbc_t *sbc, unsigned long flags) > return 0; > } > > +SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags, void *data) > +{ const void *data. I think we should also add a size_t len to it. Using the general “data” is a bit too generic. What is it actually called in the A2DP PDU anyway? > + a2dp_sbc_t *a2dp = data; > + int err; > + > + err = sbc_init(sbc, flags); > + if (err < 0) > + return err; > + > + switch (a2dp->frequency) { > + case A2DP_SAMPLING_FREQ_16000: Spaces? > + sbc->frequency = SBC_FREQ_16000; > + break; > + case A2DP_SAMPLING_FREQ_32000: > + sbc->frequency = SBC_FREQ_32000; > + break; > + case A2DP_SAMPLING_FREQ_44100: > + sbc->frequency = SBC_FREQ_44100; > + break; > + case A2DP_SAMPLING_FREQ_48000: > + sbc->frequency = SBC_FREQ_48000; > + break; > + default: > + goto failed; > + } > + > + switch (a2dp->channel_mode) { > + case A2DP_CHANNEL_MODE_MONO: > + sbc->mode = SBC_MODE_MONO; > + break; > + case A2DP_CHANNEL_MODE_DUAL_CHANNEL: > + sbc->mode = SBC_MODE_DUAL_CHANNEL; > + break; > + case A2DP_CHANNEL_MODE_STEREO: > + sbc->mode = SBC_MODE_STEREO; > + break; > + case A2DP_CHANNEL_MODE_JOINT_STEREO: > + sbc->mode = SBC_MODE_JOINT_STEREO; > + break; > + default: > + goto failed; > + } > + > + switch (a2dp->allocation_method) { > + case A2DP_ALLOCATION_SNR: > + sbc->allocation = SBC_AM_SNR; > + break; > + case A2DP_ALLOCATION_LOUDNESS: > + sbc->allocation = SBC_AM_LOUDNESS; > + break; > + default: > + goto failed; > + } > + > + switch (a2dp->subbands) { > + case A2DP_SUBBANDS_4: > + sbc->subbands = SBC_SB_4; > + break; > + case A2DP_SUBBANDS_8: Spaces? > + sbc->subbands = SBC_SB_8; > + break; > + default: > + goto failed; > + } > + > + switch (a2dp->block_length) { > + case A2DP_BLOCK_LENGTH_4: > + sbc->blocks = SBC_BLK_4; > + break; > + case A2DP_BLOCK_LENGTH_8: > + sbc->blocks = SBC_BLK_8; > + break; > + case A2DP_BLOCK_LENGTH_12: > + sbc->blocks = SBC_BLK_12; > + break; > + case A2DP_BLOCK_LENGTH_16: > + sbc->blocks = SBC_BLK_16; > + break; > + default: > + goto failed; > + } > + > + return 0; > + > +failed: > + sbc_finish(sbc); > + return -EINVAL; > +} > + > SBC_EXPORT ssize_t sbc_parse(sbc_t *sbc, const void *input, size_t input_len) > { > return sbc_decode(sbc, input, input_len, NULL, 0, NULL); > diff --git a/sbc/sbc.h b/sbc/sbc.h > index 5f8a1fc..1d1c5a1 100644 > --- a/sbc/sbc.h > +++ b/sbc/sbc.h > @@ -84,6 +84,7 @@ typedef struct sbc_struct sbc_t; > int sbc_init(sbc_t *sbc, unsigned long flags); > int sbc_reinit(sbc_t *sbc, unsigned long flags); > int sbc_init_msbc(sbc_t *sbc, unsigned long flags); > +int sbc_init_a2dp(sbc_t *sbc, unsigned long flags, void *data); > > ssize_t sbc_parse(sbc_t *sbc, const void *input, size_t input_len); Regards Marcel -- To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html