From f803f3511095e17811c50ebc85971ddd40c55618 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 29 Aug 2007 23:44:03 +0000 Subject: Fix the ALSA plugin parameter mess --- audio/ipc.h | 40 +++++----- audio/pcm_bluetooth.c | 62 ++++++++------- audio/unix.c | 203 ++++++++++++++++++++++++-------------------------- 3 files changed, 150 insertions(+), 155 deletions(-) diff --git a/audio/ipc.h b/audio/ipc.h index 2043b761..1c26e304 100644 --- a/audio/ipc.h +++ b/audio/ipc.h @@ -60,36 +60,38 @@ struct ipc_packet { } __attribute__ ((packed)); /* File descriptor options */ -#define CFG_FD_OPT_READ 0 -#define CFG_FD_OPT_WRITE 1 -#define CFG_FD_OPT_READWRITE 2 +#define CFG_FD_OPT_READ 0 +#define CFG_FD_OPT_WRITE 1 +#define CFG_FD_OPT_READWRITE 2 /* Audio channel mode */ -#define CFG_CHANNEL_MODE_MONO (1 << 3) -#define CFG_CHANNEL_MODE_DUAL_CHANNEL (1 << 2) -#define CFG_CHANNEL_MODE_STEREO (1 << 1) -#define CFG_CHANNEL_MODE_JOINT_STEREO 1 +#define CFG_MODE_AUTO 0 +#define CFG_MODE_MONO 1 +#define CFG_MODE_DUAL_CHANNEL 2 +#define CFG_MODE_STEREO 3 +#define CFG_MODE_JOINT_STEREO 4 + +/* Allocation method */ +#define CFG_ALLOCATION_AUTO 0 +#define CFG_ALLOCATION_LOUDNESS 1 +#define CFG_ALLOCATION_SNR 2 /* Codec options */ -#define CFG_CODEC_NONE 0 -#define CFG_CODEC_SBC 1 +#define CFG_CODEC_NONE 0 +#define CFG_CODEC_SCO 1 +#define CFG_CODEC_SBC 2 struct ipc_data_cfg { - uint8_t fd_opt; /* Stream file descriptor options: read, + uint8_t fd_opt; /* Stream file descriptor options: read, write or readwrite */ - uint8_t channels; /* Number of audio channel */ - uint8_t channel_mode; /* Audio channel mode*/ uint16_t pkt_len; /* Stream packet length */ - uint8_t sample_size; /* Sample size in bytes */ + uint8_t sample_size; /* Sample size in bytes */ + uint8_t mode; /* Audio channel mode */ uint16_t rate; /* Stream sample rate */ - uint8_t codec; /* Stream codec */ - uint8_t data[0]; /* Codec payload */ + uint8_t codec; /* Stream codec */ + uint8_t data[0]; /* Codec payload */ } __attribute__ ((packed)); -/* SBC codec options */ -#define CODEC_SBC_ALLOCATION_SNR (1 << 1) -#define CODEC_SBC_ALLOCATION_LOUDNESS 1 - struct ipc_codec_sbc { uint8_t allocation; uint8_t subbands; diff --git a/audio/pcm_bluetooth.c b/audio/pcm_bluetooth.c index 92a94fc0..f712bb0f 100644 --- a/audio/pcm_bluetooth.c +++ b/audio/pcm_bluetooth.c @@ -718,7 +718,7 @@ static int bluetooth_hsp_hw_constraint(snd_pcm_ioplug_t *io) unsigned int format_list[] = { SND_PCM_FORMAT_S16_LE }; - int err; + int err, channels; /* access type */ err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_ACCESS, @@ -733,14 +733,15 @@ static int bluetooth_hsp_hw_constraint(snd_pcm_ioplug_t *io) return err; /* supported channels */ + channels = cfg.mode == CFG_MODE_MONO ? 1 : 2; err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_CHANNELS, - cfg.channels, cfg.channels); + channels, channels); if (err < 0) return err; /* supported rate */ err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_RATE, - cfg.rate, cfg.rate); + cfg.rate, cfg.rate); if (err < 0) return err; @@ -751,7 +752,7 @@ static int bluetooth_hsp_hw_constraint(snd_pcm_ioplug_t *io) return err; err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, - 2, 200); + 2, 200); if (err < 0) return err; @@ -773,7 +774,7 @@ static int bluetooth_a2dp_hw_constraint(snd_pcm_ioplug_t *io) unsigned int format_list[] = { SND_PCM_FORMAT_S16_LE }; - int err; + int err, channels; /* access type */ err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_ACCESS, @@ -788,14 +789,15 @@ static int bluetooth_a2dp_hw_constraint(snd_pcm_ioplug_t *io) return err; /* supported channels */ + channels = cfg.mode = CFG_MODE_MONO ? 1 : 2; err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_CHANNELS, - cfg.channels, cfg.channels); + channels, channels); if (err < 0) return err; /* supported rate */ err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_RATE, - cfg.rate, cfg.rate); + cfg.rate, cfg.rate); if (err < 0) return err; @@ -806,7 +808,7 @@ static int bluetooth_a2dp_hw_constraint(snd_pcm_ioplug_t *io) return err; err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, - 2, 50); + 2, 50); if (err < 0) return err; @@ -874,9 +876,8 @@ static int bluetooth_a2dp_init(struct bluetooth_data *data, /* FIXME: init using flags? */ sbc_init(&a2dp->sbc, 0); a2dp->sbc.rate = cfg->rate; - a2dp->sbc.channels = cfg->channels; - if (cfg->channel_mode == CFG_CHANNEL_MODE_MONO || - cfg->channel_mode == CFG_CHANNEL_MODE_JOINT_STEREO) + a2dp->sbc.channels = cfg->mode == CFG_MODE_MONO ? 1 : 2; + if (cfg->mode == CFG_MODE_MONO || cfg->mode == CFG_MODE_JOINT_STEREO) a2dp->sbc.joint = 1; a2dp->sbc.allocation = sbc->allocation; a2dp->sbc.subbands = sbc->subbands; @@ -898,10 +899,8 @@ static int bluetooth_cfg_init(struct ipc_packet *pkt, snd_config_t *conf) struct ipc_data_cfg *cfg = (void *) pkt->data; struct ipc_codec_sbc *sbc = (void *) cfg->data; snd_config_iterator_t i, next; - const char *addr, *pref, *mode, *allocation, *rate, *subbands, - *blocks, *bitpool; - - cfg->channels = 2; + const char *addr, *pref; + const char *mode, *allocation, *rate, *subbands, *blocks, *bitpool; snd_config_for_each(i, next, conf) { snd_config_t *n = snd_config_iterator_entry(i); @@ -934,9 +933,7 @@ static int bluetooth_cfg_init(struct ipc_packet *pkt, snd_config_t *conf) else if (strcmp(pref, "voice") == 0 || strcmp(pref, "hfp") == 0) { pkt->role = PKT_ROLE_VOICE; - cfg->channels = 1; - } - else if (strcmp(pref, "hifi") == 0 || + } else if (strcmp(pref, "hifi") == 0 || strcmp(pref, "a2dp") == 0) pkt->role = PKT_ROLE_HIFI; continue; @@ -958,17 +955,16 @@ static int bluetooth_cfg_init(struct ipc_packet *pkt, snd_config_t *conf) return -EINVAL; } - if (strcmp(pref, "mono") == 0) { - cfg->channels = 1; - cfg->channel_mode = CFG_CHANNEL_MODE_MONO; - } + if (strcmp(pref, "auto") == 0) + cfg->mode = CFG_MODE_AUTO; + else if (strcmp(pref, "mono") == 0) + cfg->mode = CFG_MODE_MONO; else if (strcmp(pref, "dual") == 0) - cfg->channel_mode = CFG_CHANNEL_MODE_DUAL_CHANNEL; + cfg->mode = CFG_MODE_DUAL_CHANNEL; else if (strcmp(pref, "stereo") == 0) - cfg->channel_mode = CFG_CHANNEL_MODE_STEREO; + cfg->mode = CFG_MODE_STEREO; else if (strcmp(pref, "joint") == 0) - cfg->channel_mode = CFG_CHANNEL_MODE_JOINT_STEREO; - + cfg->mode = CFG_MODE_JOINT_STEREO; continue; } @@ -978,10 +974,12 @@ static int bluetooth_cfg_init(struct ipc_packet *pkt, snd_config_t *conf) return -EINVAL; } - if (strcmp(pref, "snr") == 0) - sbc->allocation = CODEC_SBC_ALLOCATION_SNR; + if (strcmp(pref, "auto") == 0) + sbc->allocation = CFG_ALLOCATION_AUTO; else if (strcmp(pref, "loudness") == 0) - sbc->allocation = CODEC_SBC_ALLOCATION_LOUDNESS; + sbc->allocation = CFG_ALLOCATION_LOUDNESS; + else if (strcmp(pref, "snr") == 0) + sbc->allocation = CFG_ALLOCATION_SNR; continue; } @@ -1093,9 +1091,9 @@ done: DBG("Device configuration:"); - DBG("\n\tfd=%d\n\tfd_opt=%u\n\tchannels=%u\n\tpkt_len=%u\n\tsample_size=%u\n\trate=%u", - data->stream_fd, data->cfg.fd_opt, data->cfg.channels, - data->cfg.pkt_len, data->cfg.sample_size, data->cfg.rate); + DBG("\n\tfd=%d\n\tfd_opt=%u\n\tpkt_len=%u\n\tsample_size=%u\n\trate=%u", + data->stream_fd, data->cfg.fd_opt, data->cfg.pkt_len, + data->cfg.sample_size, data->cfg.rate); if (data->cfg.codec == CFG_CODEC_SBC) { ret = bluetooth_a2dp_init(data, sbc); diff --git a/audio/unix.c b/audio/unix.c index 7fa2db05..3b9d6d46 100644 --- a/audio/unix.c +++ b/audio/unix.c @@ -209,9 +209,9 @@ static int unix_send_cfg(int sock, struct ipc_data_cfg *cfg, int fd) return len; } - debug("fd=%d, fd_opt=%u, channels=%u, pkt_len=%u," - "sample_size=%u, rate=%u", fd, cfg->fd_opt, cfg->channels, - cfg->pkt_len, cfg->sample_size, cfg->rate); + debug("fd=%d, fd_opt=%u, pkt_len=%u, sample_size=%u, rate=%u", + fd, cfg->fd_opt, cfg->pkt_len, + cfg->sample_size, cfg->rate); if (cfg->codec == CFG_CODEC_SBC) codec_len = sizeof(struct ipc_codec_sbc); @@ -258,9 +258,8 @@ static void headset_setup_complete(struct device *dev, void *user_data) memset(&cfg, 0, sizeof(cfg)); cfg.fd_opt = CFG_FD_OPT_READWRITE; - cfg.codec = CFG_CODEC_NONE; - cfg.channels = 1; - cfg.channel_mode = CFG_CHANNEL_MODE_MONO; + cfg.codec = CFG_CODEC_SCO; + cfg.mode = CFG_MODE_MONO; cfg.pkt_len = 48; cfg.sample_size = 2; cfg.rate = 8000; @@ -327,24 +326,22 @@ static void a2dp_setup_complete(struct avdtp *session, struct device *dev, cfg->fd_opt = CFG_FD_OPT_WRITE; sbc_cap = (void *) codec_cap; - cfg->channels = sbc_cap->channel_mode == A2DP_CHANNEL_MODE_MONO ? - 1 : 2; - cfg->channel_mode = sbc_cap->channel_mode; + cfg->mode = sbc_cap->channel_mode; cfg->sample_size = 2; switch (sbc_cap->frequency) { - case A2DP_SAMPLING_FREQ_16000: - cfg->rate = 16000; - break; - case A2DP_SAMPLING_FREQ_32000: - cfg->rate = 32000; - break; - case A2DP_SAMPLING_FREQ_44100: - cfg->rate = 44100; - break; - case A2DP_SAMPLING_FREQ_48000: - cfg->rate = 48000; - break; + case A2DP_SAMPLING_FREQ_16000: + cfg->rate = 16000; + break; + case A2DP_SAMPLING_FREQ_32000: + cfg->rate = 32000; + break; + case A2DP_SAMPLING_FREQ_44100: + cfg->rate = 44100; + break; + case A2DP_SAMPLING_FREQ_48000: + cfg->rate = 48000; + break; } cfg->codec = CFG_CODEC_SBC; @@ -353,18 +350,18 @@ static void a2dp_setup_complete(struct avdtp *session, struct device *dev, sbc->subbands = sbc_cap->subbands == A2DP_SUBBANDS_4 ? 4 : 8; switch (sbc_cap->block_length) { - case A2DP_BLOCK_LENGTH_4: - sbc->blocks = 4; - break; - case A2DP_BLOCK_LENGTH_8: - sbc->blocks = 8; - break; - case A2DP_BLOCK_LENGTH_12: - sbc->blocks = 12; - break; - case A2DP_BLOCK_LENGTH_16: - sbc->blocks = 16; - break; + case A2DP_BLOCK_LENGTH_4: + sbc->blocks = 4; + break; + case A2DP_BLOCK_LENGTH_8: + sbc->blocks = 8; + break; + case A2DP_BLOCK_LENGTH_12: + sbc->blocks = 12; + break; + case A2DP_BLOCK_LENGTH_16: + sbc->blocks = 16; + break; } sbc->bitpool = sbc_cap->max_bitpool; @@ -454,92 +451,90 @@ static int cfg_to_caps(struct ipc_data_cfg *cfg, struct sbc_codec_cap *sbc_cap) sbc_cap->cap.media_type = AVDTP_MEDIA_TYPE_AUDIO; sbc_cap->cap.media_codec_type = A2DP_CODEC_SBC; - if (cfg->rate > 0) { - switch (cfg->rate) { - case 48000: - sbc_cap->frequency = A2DP_SAMPLING_FREQ_48000; - break; - case 44100: - sbc_cap->frequency = A2DP_SAMPLING_FREQ_44100; - break; - case 32000: - sbc_cap->frequency = A2DP_SAMPLING_FREQ_32000; - break; - case 16000: - sbc_cap->frequency = A2DP_SAMPLING_FREQ_16000; - break; - default: - return -EINVAL; - } - } else + switch (cfg->rate) { + case 48000: + sbc_cap->frequency = A2DP_SAMPLING_FREQ_48000; + break; + case 44100: + sbc_cap->frequency = A2DP_SAMPLING_FREQ_44100; + break; + case 32000: + sbc_cap->frequency = A2DP_SAMPLING_FREQ_32000; + break; + case 16000: + sbc_cap->frequency = A2DP_SAMPLING_FREQ_16000; + break; + default: sbc_cap->frequency = A2DP_SAMPLING_FREQ_44100; + break; + } - if (cfg->channel_mode > 0) { - switch (cfg->channel_mode) { - case A2DP_CHANNEL_MODE_JOINT_STEREO: - case A2DP_CHANNEL_MODE_STEREO: - case A2DP_CHANNEL_MODE_DUAL_CHANNEL: - case A2DP_CHANNEL_MODE_MONO: - sbc_cap->channel_mode = cfg->channel_mode; - break; - default: - return -EINVAL; - } - } else + switch (cfg->mode) { + case CFG_MODE_MONO: + sbc_cap->channel_mode = A2DP_CHANNEL_MODE_MONO; + break; + case CFG_MODE_DUAL_CHANNEL: + sbc_cap->channel_mode = A2DP_CHANNEL_MODE_DUAL_CHANNEL; + break; + case CFG_MODE_STEREO: + sbc_cap->channel_mode = A2DP_CHANNEL_MODE_STEREO; + break; + case CFG_MODE_JOINT_STEREO: + sbc_cap->channel_mode = A2DP_CHANNEL_MODE_JOINT_STEREO; + break; + default: sbc_cap->channel_mode = A2DP_CHANNEL_MODE_JOINT_STEREO; + break; + } - if (sbc->allocation > 0) { - switch (sbc->allocation) { - case A2DP_ALLOCATION_LOUDNESS: - case A2DP_ALLOCATION_SNR: - sbc_cap->allocation_method = sbc->allocation; - break; - default: - return -EINVAL; - } - } else + switch (sbc->allocation) { + case CFG_ALLOCATION_LOUDNESS: + sbc_cap->allocation_method = A2DP_ALLOCATION_LOUDNESS; + break; + case CFG_ALLOCATION_SNR: + sbc_cap->allocation_method = A2DP_ALLOCATION_LOUDNESS; + break; + default: sbc_cap->allocation_method = A2DP_ALLOCATION_LOUDNESS; + break; + } - if (sbc->subbands > 0) { - switch (sbc->subbands) { - case 8: - sbc_cap->subbands = A2DP_SUBBANDS_8; - break; - case 4: - sbc_cap->subbands = A2DP_SUBBANDS_4; - break; - default: - return -EINVAL; - } - } else + switch (sbc->subbands) { + case 8: sbc_cap->subbands = A2DP_SUBBANDS_8; + break; + case 4: + sbc_cap->subbands = A2DP_SUBBANDS_4; + break; + default: + sbc_cap->subbands = A2DP_SUBBANDS_8; + break; + } - if (sbc->blocks > 0) { - switch (sbc->blocks) { - case 16: - sbc_cap->block_length = A2DP_BLOCK_LENGTH_16; - break; - case 12: - sbc_cap->block_length = A2DP_BLOCK_LENGTH_12; - break; - case 8: - sbc_cap->block_length = A2DP_BLOCK_LENGTH_8; - break; - case 4: - sbc_cap->block_length = A2DP_BLOCK_LENGTH_4; - break; - default: - return -EINVAL; - } - } else + switch (sbc->blocks) { + case 16: sbc_cap->block_length = A2DP_BLOCK_LENGTH_16; + break; + case 12: + sbc_cap->block_length = A2DP_BLOCK_LENGTH_12; + break; + case 8: + sbc_cap->block_length = A2DP_BLOCK_LENGTH_8; + break; + case 4: + sbc_cap->block_length = A2DP_BLOCK_LENGTH_4; + break; + default: + sbc_cap->block_length = A2DP_BLOCK_LENGTH_16; + break; + } if (sbc->bitpool > 250) return -EINVAL; else if (sbc->bitpool > 0) sbc_cap->min_bitpool = sbc_cap->max_bitpool = sbc->bitpool; else - sbc_cap->min_bitpool = 53; + sbc_cap->min_bitpool = sbc_cap->max_bitpool = 53; return 0; } -- cgit