Re: [PATCH 02/10] android/hal-audio: Add support to register audio endpoints

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Andrzej,

On Wed, Jan 15, 2014 at 11:59 AM, Andrzej Kaczmarek
<andrzej.kaczmarek@xxxxxxxxx> wrote:
> This patch adds support to register audio enpoints via Audio IPC.
> Endpoints are registered based on predefined codecs table and for
> each defined codec one endpoint is registered. By default, only
> SBC will be supported.
> ---
>  android/hal-audio.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 167 insertions(+)
>
> diff --git a/android/hal-audio.c b/android/hal-audio.c
> index 354c3cf..84e7348 100644
> --- a/android/hal-audio.c
> +++ b/android/hal-audio.c
> @@ -31,6 +31,11 @@
>  #include "audio-msg.h"
>  #include "hal-log.h"
>  #include "hal-msg.h"
> +#include "../profiles/audio/a2dp-codecs.h"
> +
> +static const uint8_t a2dp_src_uuid[] = {
> +               0x00, 0x00, 0x11, 0x0a, 0x00, 0x00, 0x10, 0x00,
> +               0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb };
>
>  static int listen_sk = -1;
>  static int audio_sk = -1;
> @@ -40,11 +45,118 @@ static pthread_t ipc_th = 0;
>  static pthread_mutex_t close_mutex = PTHREAD_MUTEX_INITIALIZER;
>  static pthread_mutex_t sk_mutex = PTHREAD_MUTEX_INITIALIZER;
>
> +struct audio_input_config {
> +       uint32_t rate;
> +       uint32_t channels;
> +       audio_format_t format;
> +};
> +
> +static int codec_sbc_get_presets(struct audio_preset *preset, size_t *len);
> +
> +struct audio_codec {
> +       uint8_t type;
> +
> +       int (*get_presets) (struct audio_preset *preset, size_t *len);
> +
> +       int (*init) (struct audio_preset *preset, void **codec_data);
> +       int (*cleanup) (void *codec_data);
> +       int (*get_config) (void *codec_data,
> +                                       struct audio_input_config *config);
> +       ssize_t (*write_data) (void *codec_data, const void *buffer,
> +                               size_t bytes);
> +};
> +
> +static const struct audio_codec audio_codecs[] = {
> +       {
> +               .type = A2DP_CODEC_SBC,
> +
> +               .get_presets = codec_sbc_get_presets,
> +       }
> +};
> +
> +#define NUM_CODECS (sizeof(audio_codecs) / sizeof(audio_codecs[0]))
> +
> +#define MAX_AUDIO_ENDPOINTS NUM_CODECS
> +
> +struct audio_endpoint {
> +       uint8_t id;
> +       const struct audio_codec *codec;
> +       void *codec_data;
> +       int fd;
> +};
> +
> +static struct audio_endpoint audio_endpoints[MAX_AUDIO_ENDPOINTS];
> +
>  struct a2dp_audio_dev {
>         struct audio_hw_device dev;
>         struct audio_stream_out *out;
>  };
>
> +static const a2dp_sbc_t codec_sbc_presets[] = {

Call it sbc_presets

> +       {
> +               .frequency = SBC_SAMPLING_FREQ_44100 | SBC_SAMPLING_FREQ_48000,
> +               .channel_mode = SBC_CHANNEL_MODE_MONO |
> +                               SBC_CHANNEL_MODE_DUAL_CHANNEL |
> +                               SBC_CHANNEL_MODE_STEREO |
> +                               SBC_CHANNEL_MODE_JOINT_STEREO,
> +               .subbands = SBC_SUBBANDS_4 | SBC_SUBBANDS_8,
> +               .allocation_method = SBC_ALLOCATION_SNR |
> +                                       SBC_ALLOCATION_LOUDNESS,
> +               .block_length = SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8 |
> +                               SBC_BLOCK_LENGTH_12 | SBC_BLOCK_LENGTH_16,
> +               .min_bitpool = MIN_BITPOOL,
> +               .max_bitpool = MAX_BITPOOL
> +       },
> +       {
> +               .frequency = SBC_SAMPLING_FREQ_44100,
> +               .channel_mode = SBC_CHANNEL_MODE_STEREO,
> +               .subbands = SBC_SUBBANDS_8,
> +               .allocation_method = SBC_ALLOCATION_LOUDNESS,
> +               .block_length = SBC_BLOCK_LENGTH_16,
> +               .min_bitpool = MIN_BITPOOL,
> +               .max_bitpool = MAX_BITPOOL
> +       },
> +       {
> +               .frequency = SBC_SAMPLING_FREQ_48000,
> +               .channel_mode = SBC_CHANNEL_MODE_STEREO,
> +               .subbands = SBC_SUBBANDS_8,
> +               .allocation_method = SBC_ALLOCATION_LOUDNESS,
> +               .block_length = SBC_BLOCK_LENGTH_16,
> +               .min_bitpool = MIN_BITPOOL,
> +               .max_bitpool = MAX_BITPOOL
> +       },
> +};

Perhaps we should add the recomended values from A2DP spec, iirc there
are at least 3 preset recommended there, high, medium, low quality.

> +static int codec_sbc_get_presets(struct audio_preset *preset, size_t *len)
> +{

Call this one sbc_get_presets

> +       int i;
> +       int count;
> +       size_t new_len = 0;
> +       uint8_t *ptr = (uint8_t *) preset;
> +       size_t preset_size = sizeof(*preset) + sizeof(a2dp_sbc_t);
> +
> +       DBG("");
> +
> +       count = sizeof(codec_sbc_presets) / sizeof(codec_sbc_presets[0]);
> +
> +       for (i = 0; i < count; i++) {
> +               preset = (struct audio_preset *) ptr;
> +
> +               if (new_len + preset_size > *len)
> +                       break;
> +
> +               preset->len = sizeof(a2dp_sbc_t);
> +               memcpy(preset->data, &codec_sbc_presets[i], preset->len);
> +
> +               new_len += preset_size;
> +               ptr += preset_size;
> +       }
> +
> +       *len = new_len;
> +
> +       return i;
> +}
> +
>  static void audio_ipc_cleanup(void)
>  {
>         if (audio_sk >= 0) {
> @@ -200,6 +312,54 @@ failed:
>         return AUDIO_STATUS_FAILED;
>  }
>
> +static int ipc_open_cmd(const struct audio_codec *codec)
> +{
> +       uint8_t buf[BLUEZ_AUDIO_MTU];
> +       struct audio_cmd_open *cmd = (struct audio_cmd_open *) buf;
> +       struct audio_rsp_open rsp;
> +       size_t cmd_len = sizeof(buf) - sizeof(*cmd);
> +       size_t rsp_len = sizeof(rsp);
> +       int result;
> +
> +       DBG("");
> +
> +       memcpy(cmd->uuid, a2dp_src_uuid, sizeof(a2dp_src_uuid));
> +
> +       cmd->codec = codec->type;
> +       cmd->presets = codec->get_presets(cmd->preset, &cmd_len);
> +
> +       cmd_len += sizeof(*cmd);
> +
> +       result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_OPEN, cmd_len, cmd,
> +                               &rsp_len, &rsp, NULL);
> +
> +       if (result != AUDIO_STATUS_SUCCESS)
> +               return 0;
> +
> +       return rsp.id;
> +}
> +
> +static int register_endpoints(void)
> +{
> +       struct audio_endpoint *ep = &audio_endpoints[0];
> +       size_t i;
> +
> +       for (i = 0; i < NUM_CODECS; i++) {
> +               const struct audio_codec *codec = &audio_codecs[i];
> +
> +               ep->id = ipc_open_cmd(codec);
> +
> +               if (!ep->id)
> +                       return AUDIO_STATUS_FAILED;
> +
> +               ep->codec = codec;
> +               ep->codec_data = NULL;
> +               ep->fd = -1;
> +       }

This seems to be overwriting ep if there is more than one codec
available, I guess you need to move ep within the loop as well then
you assign the correspondent codec index to the endpoint index.

-- 
Luiz Augusto von Dentz
--
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




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux