diff options
| -rw-r--r-- | audio/a2dp.c | 30 | ||||
| -rw-r--r-- | audio/a2dp.h | 77 | ||||
| -rw-r--r-- | audio/ipc.h | 8 | ||||
| -rw-r--r-- | audio/sink.c | 88 | ||||
| -rw-r--r-- | audio/unix.c | 19 | 
5 files changed, 139 insertions, 83 deletions
| diff --git a/audio/a2dp.c b/audio/a2dp.c index 74699cd5..1c59374f 100644 --- a/audio/a2dp.c +++ b/audio/a2dp.c @@ -355,25 +355,25 @@ static gboolean getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep,  	sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;  	sbc_cap.cap.media_codec_type = A2DP_CODEC_SBC; -	sbc_cap.frequency = ( A2DP_SAMPLING_FREQ_48000 | -				A2DP_SAMPLING_FREQ_44100 | -				A2DP_SAMPLING_FREQ_32000 | -				A2DP_SAMPLING_FREQ_16000 ); +	sbc_cap.frequency = ( SBC_SAMPLING_FREQ_48000 | +				SBC_SAMPLING_FREQ_44100 | +				SBC_SAMPLING_FREQ_32000 | +				SBC_SAMPLING_FREQ_16000 ); -	sbc_cap.channel_mode = ( A2DP_CHANNEL_MODE_JOINT_STEREO | -					A2DP_CHANNEL_MODE_STEREO | -					A2DP_CHANNEL_MODE_DUAL_CHANNEL | -					A2DP_CHANNEL_MODE_MONO ); +	sbc_cap.channel_mode = ( SBC_CHANNEL_MODE_JOINT_STEREO | +					SBC_CHANNEL_MODE_STEREO | +					SBC_CHANNEL_MODE_DUAL_CHANNEL | +					SBC_CHANNEL_MODE_MONO ); -	sbc_cap.block_length = ( A2DP_BLOCK_LENGTH_16 | -					A2DP_BLOCK_LENGTH_12 | -					A2DP_BLOCK_LENGTH_8 | -					A2DP_BLOCK_LENGTH_4 ); +	sbc_cap.block_length = ( SBC_BLOCK_LENGTH_16 | +					SBC_BLOCK_LENGTH_12 | +					SBC_BLOCK_LENGTH_8 | +					SBC_BLOCK_LENGTH_4 ); -	sbc_cap.subbands = ( A2DP_SUBBANDS_8 | A2DP_SUBBANDS_4 ); +	sbc_cap.subbands = ( SBC_SUBBANDS_8 | SBC_SUBBANDS_4 ); -	sbc_cap.allocation_method = ( A2DP_ALLOCATION_LOUDNESS | -					A2DP_ALLOCATION_SNR ); +	sbc_cap.allocation_method = ( SBC_ALLOCATION_LOUDNESS | +					SBC_ALLOCATION_SNR );  	sbc_cap.min_bitpool = MIN_BITPOOL;  	sbc_cap.max_bitpool = MAX_BITPOOL; diff --git a/audio/a2dp.h b/audio/a2dp.h index 8227296f..cfd1c47d 100644 --- a/audio/a2dp.h +++ b/audio/a2dp.h @@ -27,26 +27,37 @@  #define A2DP_CODEC_MPEG24		0x02  #define A2DP_CODEC_ATRAC		0x03 -#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 - -#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 +#define SBC_SAMPLING_FREQ_16000		(1 << 3) +#define SBC_SAMPLING_FREQ_32000		(1 << 2) +#define SBC_SAMPLING_FREQ_44100		(1 << 1) +#define SBC_SAMPLING_FREQ_48000		1 + +#define SBC_CHANNEL_MODE_MONO		(1 << 3) +#define SBC_CHANNEL_MODE_DUAL_CHANNEL	(1 << 2) +#define SBC_CHANNEL_MODE_STEREO		(1 << 1) +#define SBC_CHANNEL_MODE_JOINT_STEREO	1 + +#define SBC_BLOCK_LENGTH_4		(1 << 3) +#define SBC_BLOCK_LENGTH_8		(1 << 2) +#define SBC_BLOCK_LENGTH_12		(1 << 1) +#define SBC_BLOCK_LENGTH_16		1 + +#define SBC_SUBBANDS_4			(1 << 1) +#define SBC_SUBBANDS_8			1 + +#define SBC_ALLOCATION_SNR		(1 << 1) +#define SBC_ALLOCATION_LOUDNESS		1 + +#define MPEG_LAYER_MP1			(1 << 2) +#define MPEG_LAYER_MP2			(1 << 1) +#define MPEG_LAYER_MP3			1 + +#define MPEG_SAMPLING_FREQ_16000	(1 << 5) +#define MPEG_SAMPLING_FREQ_22050	(1 << 4) +#define MPEG_SAMPLING_FREQ_24000	(1 << 3) +#define MPEG_SAMPLING_FREQ_32000	(1 << 2) +#define MPEG_SAMPLING_FREQ_44100	(1 << 1) +#define MPEG_SAMPLING_FREQ_48000	1  #define MAX_BITPOOL 64  #define MIN_BITPOOL 2 @@ -64,6 +75,19 @@ struct sbc_codec_cap {  	uint8_t max_bitpool;  } __attribute__ ((packed)); +struct mpeg_codec_cap { +	struct avdtp_media_codec_capability cap; +	uint8_t channel_mode:4; +	uint8_t crc:1; +	uint8_t layer:3; +	uint8_t frequency:6; +	uint8_t mpf:1; +	uint8_t rfa:1; +	uint8_t bitrate0:7; +	uint8_t vbr:1; +	uint8_t bitrate1; +} __attribute__ ((packed)); +  #elif __BYTE_ORDER == __BIG_ENDIAN  struct sbc_codec_cap { @@ -77,6 +101,19 @@ struct sbc_codec_cap {  	uint8_t max_bitpool;  } __attribute__ ((packed)); +struct mpeg_codec_cap { +	struct avdtp_media_codec_capability cap; +	uint8_t layer:3; +	uint8_t crc:1; +	uint8_t channel_mode:4; +	uint8_t rfa:1; +	uint8_t mpf:1; +	uint8_t frequency:6; +	uint8_t vbr:1; +	uint8_t bitrate0:7; +	uint8_t bitrate1; +} __attribute__ ((packed)); +  #else  #error "Unknown byte order"  #endif diff --git a/audio/ipc.h b/audio/ipc.h index 3e1200fa..64ed65a7 100644 --- a/audio/ipc.h +++ b/audio/ipc.h @@ -162,8 +162,14 @@ typedef struct {  	uint8_t max_bitpool;  } __attribute__ ((packed)) sbc_capabilities_t; -/* To be defined */  typedef struct { +	uint8_t channel_mode; +	uint8_t crc; +	uint8_t layer; +	uint8_t frequency; +	uint8_t mpf; +	uint8_t vbr; +	uint16_t bitrate;  } __attribute__ ((packed)) mpeg_capabilities_t;  struct bt_getcapabilities_rsp { diff --git a/audio/sink.c b/audio/sink.c index 259abf8f..a95c2e45 100644 --- a/audio/sink.c +++ b/audio/sink.c @@ -193,28 +193,28 @@ static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,  static uint8_t default_bitpool(uint8_t freq, uint8_t mode)  {  	switch (freq) { -	case A2DP_SAMPLING_FREQ_16000: -	case A2DP_SAMPLING_FREQ_32000: +	case SBC_SAMPLING_FREQ_16000: +	case SBC_SAMPLING_FREQ_32000:  		return 53; -	case A2DP_SAMPLING_FREQ_44100: +	case SBC_SAMPLING_FREQ_44100:  		switch (mode) { -		case A2DP_CHANNEL_MODE_MONO: -		case A2DP_CHANNEL_MODE_DUAL_CHANNEL: +		case SBC_CHANNEL_MODE_MONO: +		case SBC_CHANNEL_MODE_DUAL_CHANNEL:  			return 31; -		case A2DP_CHANNEL_MODE_STEREO: -		case A2DP_CHANNEL_MODE_JOINT_STEREO: +		case SBC_CHANNEL_MODE_STEREO: +		case SBC_CHANNEL_MODE_JOINT_STEREO:  			return 53;  		default:  			error("Invalid channel mode %u", mode);  			return 53;  		} -	case A2DP_SAMPLING_FREQ_48000: +	case SBC_SAMPLING_FREQ_48000:  		switch (mode) { -		case A2DP_CHANNEL_MODE_MONO: -		case A2DP_CHANNEL_MODE_DUAL_CHANNEL: +		case SBC_CHANNEL_MODE_MONO: +		case SBC_CHANNEL_MODE_DUAL_CHANNEL:  			return 29; -		case A2DP_CHANNEL_MODE_STEREO: -		case A2DP_CHANNEL_MODE_JOINT_STEREO: +		case SBC_CHANNEL_MODE_STEREO: +		case SBC_CHANNEL_MODE_JOINT_STEREO:  			return 51;  		default:  			error("Invalid channel mode %u", mode); @@ -236,58 +236,58 @@ static gboolean select_sbc_params(struct sbc_codec_cap *cap,  	cap->cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;  	cap->cap.media_codec_type = A2DP_CODEC_SBC; -	if (supported->frequency & A2DP_SAMPLING_FREQ_44100) -		cap->frequency = A2DP_SAMPLING_FREQ_44100; -	else if (supported->frequency & A2DP_SAMPLING_FREQ_48000) -		cap->frequency = A2DP_SAMPLING_FREQ_48000; -	else if (supported->frequency & A2DP_SAMPLING_FREQ_32000) -		cap->frequency = A2DP_SAMPLING_FREQ_32000; -	else if (supported->frequency & A2DP_SAMPLING_FREQ_16000) -		cap->frequency = A2DP_SAMPLING_FREQ_16000; +	if (supported->frequency & SBC_SAMPLING_FREQ_44100) +		cap->frequency = SBC_SAMPLING_FREQ_44100; +	else if (supported->frequency & SBC_SAMPLING_FREQ_48000) +		cap->frequency = SBC_SAMPLING_FREQ_48000; +	else if (supported->frequency & SBC_SAMPLING_FREQ_32000) +		cap->frequency = SBC_SAMPLING_FREQ_32000; +	else if (supported->frequency & SBC_SAMPLING_FREQ_16000) +		cap->frequency = SBC_SAMPLING_FREQ_16000;  	else {  		error("No supported frequencies");  		return FALSE;  	} -	if (supported->channel_mode & A2DP_CHANNEL_MODE_JOINT_STEREO) -		cap->channel_mode = A2DP_CHANNEL_MODE_JOINT_STEREO; -	else if (supported->channel_mode & A2DP_CHANNEL_MODE_STEREO) -		cap->channel_mode = A2DP_CHANNEL_MODE_STEREO; -	else if (supported->channel_mode & A2DP_CHANNEL_MODE_DUAL_CHANNEL) -		cap->channel_mode = A2DP_CHANNEL_MODE_DUAL_CHANNEL; -	else if (supported->channel_mode & A2DP_CHANNEL_MODE_MONO) -		cap->channel_mode = A2DP_CHANNEL_MODE_MONO; +	if (supported->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO) +		cap->channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO; +	else if (supported->channel_mode & SBC_CHANNEL_MODE_STEREO) +		cap->channel_mode = SBC_CHANNEL_MODE_STEREO; +	else if (supported->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL) +		cap->channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL; +	else if (supported->channel_mode & SBC_CHANNEL_MODE_MONO) +		cap->channel_mode = SBC_CHANNEL_MODE_MONO;  	else {  		error("No supported channel modes");  		return FALSE;  	} -	if (supported->block_length & A2DP_BLOCK_LENGTH_16) -		cap->block_length = A2DP_BLOCK_LENGTH_16; -	else if (supported->block_length & A2DP_BLOCK_LENGTH_12) -		cap->block_length = A2DP_BLOCK_LENGTH_12; -	else if (supported->block_length & A2DP_BLOCK_LENGTH_8) -		cap->block_length = A2DP_BLOCK_LENGTH_8; -	else if (supported->block_length & A2DP_BLOCK_LENGTH_4) -		cap->block_length = A2DP_BLOCK_LENGTH_4; +	if (supported->block_length & SBC_BLOCK_LENGTH_16) +		cap->block_length = SBC_BLOCK_LENGTH_16; +	else if (supported->block_length & SBC_BLOCK_LENGTH_12) +		cap->block_length = SBC_BLOCK_LENGTH_12; +	else if (supported->block_length & SBC_BLOCK_LENGTH_8) +		cap->block_length = SBC_BLOCK_LENGTH_8; +	else if (supported->block_length & SBC_BLOCK_LENGTH_4) +		cap->block_length = SBC_BLOCK_LENGTH_4;  	else {  		error("No supported block lengths");  		return FALSE;  	} -	if (supported->subbands & A2DP_SUBBANDS_8) -		cap->subbands = A2DP_SUBBANDS_8; -	else if (supported->subbands & A2DP_SUBBANDS_4) -		cap->subbands = A2DP_SUBBANDS_4; +	if (supported->subbands & SBC_SUBBANDS_8) +		cap->subbands = SBC_SUBBANDS_8; +	else if (supported->subbands & SBC_SUBBANDS_4) +		cap->subbands = SBC_SUBBANDS_4;  	else {  		error("No supported subbands");  		return FALSE;  	} -	if (supported->allocation_method & A2DP_ALLOCATION_LOUDNESS) -		cap->allocation_method = A2DP_ALLOCATION_LOUDNESS; -	else if (supported->allocation_method & A2DP_ALLOCATION_SNR) -		cap->allocation_method = A2DP_ALLOCATION_SNR; +	if (supported->allocation_method & SBC_ALLOCATION_LOUDNESS) +		cap->allocation_method = SBC_ALLOCATION_LOUDNESS; +	else if (supported->allocation_method & SBC_ALLOCATION_SNR) +		cap->allocation_method = SBC_ALLOCATION_SNR;  	min_bitpool = MAX(MIN_BITPOOL, supported->min_bitpool);  	max_bitpool = MIN(default_bitpool(cap->frequency, cap->channel_mode), diff --git a/audio/unix.c b/audio/unix.c index d9f7c670..2226579d 100644 --- a/audio/unix.c +++ b/audio/unix.c @@ -341,6 +341,7 @@ static void a2dp_discovery_complete(struct avdtp *session, GSList *seps,  	struct bt_getcapabilities_rsp *rsp = (void *) buf;  	struct a2dp_data *a2dp = &client->d.a2dp;  	struct sbc_codec_cap *sbc_cap = NULL; +	struct mpeg_codec_cap *mpeg_cap = NULL;  	GSList *l;  	if (err) @@ -364,10 +365,11 @@ static void a2dp_discovery_complete(struct avdtp *session, GSList *seps,  		codec_cap = (void *) cap->data; -		if (codec_cap->media_codec_type == A2DP_CODEC_SBC && !sbc_cap) { +		if (codec_cap->media_codec_type == A2DP_CODEC_SBC && !sbc_cap)  			sbc_cap = (void *) codec_cap; -			break; -		} + +		if (codec_cap->media_codec_type == A2DP_CODEC_MPEG12 && !mpeg_cap) +			mpeg_cap = (void *) codec_cap;  	}  	/* endianess prevent direct cast */ @@ -381,6 +383,17 @@ static void a2dp_discovery_complete(struct avdtp *session, GSList *seps,  		rsp->sbc_capabilities.max_bitpool = sbc_cap->max_bitpool;  	} +	if (mpeg_cap) { +		rsp->mpeg_capabilities.channel_mode = mpeg_cap->channel_mode; +		rsp->mpeg_capabilities.crc = mpeg_cap->crc; +		rsp->mpeg_capabilities.layer = mpeg_cap->layer; +		rsp->mpeg_capabilities.frequency = mpeg_cap->frequency; +		rsp->mpeg_capabilities.mpf = mpeg_cap->mpf; +		rsp->mpeg_capabilities.vbr = mpeg_cap->vbr; +		rsp->mpeg_capabilities.bitrate = mpeg_cap->bitrate1 & +				mpeg_cap->bitrate0 << 8; +	} +  	unix_ipc_sendmsg(client, &rsp->rsp_h.msg_h);  	return; | 
