summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2007-08-29 23:44:03 +0000
committerMarcel Holtmann <marcel@holtmann.org>2007-08-29 23:44:03 +0000
commitf803f3511095e17811c50ebc85971ddd40c55618 (patch)
tree63b0ddccf21db4e57abc58f0df32e63a3c361ed5 /audio
parent69e07f5a7b3934fac5bcf4c554e14e0d0b3cec47 (diff)
Fix the ALSA plugin parameter mess
Diffstat (limited to 'audio')
-rw-r--r--audio/ipc.h40
-rw-r--r--audio/pcm_bluetooth.c62
-rw-r--r--audio/unix.c203
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;
}