diff options
Diffstat (limited to 'audio')
| -rw-r--r-- | audio/pcm_bluetooth.c | 68 | 
1 files changed, 37 insertions, 31 deletions
diff --git a/audio/pcm_bluetooth.c b/audio/pcm_bluetooth.c index a313eab8..491e621a 100644 --- a/audio/pcm_bluetooth.c +++ b/audio/pcm_bluetooth.c @@ -86,6 +86,7 @@ static int bluetooth_close(snd_pcm_ioplug_t *io)  	DBG("bluetooth_close %p", io); +	free(data->buffer);  	free(data);  	return 0; @@ -115,7 +116,7 @@ static int bluetooth_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params  	struct bluetooth_data *data = io->private_data;  	struct ipc_data_cfg cfg = data->cfg;  	uint32_t period_count = io->buffer_size / io->period_size; -	int opt_name; +	int opt_name, err;  	DBG("fd = %d, period_count = %d", cfg.fd, period_count); @@ -133,11 +134,10 @@ static int bluetooth_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params  			sizeof(period_count)) == 0)  		return 0; -	SNDERR("%s (%d)", strerror(errno), errno); -	SNDERR("Unable to set number of SCO buffers: please upgrade your " -			"kernel!"); +	err = errno; +	SNDERR("%s (%d)", strerror(err), err); -	return -EINVAL; +	return -err;  }  static snd_pcm_sframes_t bluetooth_read(snd_pcm_ioplug_t *io, @@ -203,7 +203,7 @@ static snd_pcm_sframes_t bluetooth_write(snd_pcm_ioplug_t *io,  	struct ipc_data_cfg cfg = data->cfg;  	snd_pcm_sframes_t ret = 0;  	snd_pcm_uframes_t frames_to_read; -	unsigned char *buff; +	uint8_t *buff;  	int rsend;  	DBG("areas->step=%u, areas->first=%u, offset=%lu, size=%lu," @@ -215,8 +215,10 @@ static snd_pcm_sframes_t bluetooth_write(snd_pcm_ioplug_t *io,  	else  		frames_to_read = (cfg.pkt_len - data->count) / cfg.sample_size; +	DBG("count = %d, frames_to_read = %lu", data->count, frames_to_read); +  	/* Ready for more data */ -	buff = (unsigned char *) areas->addr + (areas->first + areas->step * offset) / 8; +	buff = (uint8_t *) areas->addr + (areas->first + areas->step * offset) / 8;  	memcpy(data->buffer + data->count, buff, areas->step / 8 * frames_to_read);  	if ((data->count + areas->step / 8 * frames_to_read) != cfg.pkt_len) { @@ -226,13 +228,15 @@ static snd_pcm_sframes_t bluetooth_write(snd_pcm_ioplug_t *io,  		goto done;  	} -	rsend = send(cfg.fd, data->buffer, cfg.pkt_len, io->nonblock ? MSG_DONTWAIT : 0); +	rsend = send(cfg.fd, data->buffer, cfg.pkt_len, +			io->nonblock ? MSG_DONTWAIT : 0);  	if (rsend > 0) {  		/* Reset count pointer */  		data->count = 0;  		/* Increment hardware transmition pointer */ -		data->hw_ptr = (data->hw_ptr + cfg.pkt_len / cfg.sample_size) % io->buffer_size; +		data->hw_ptr = (data->hw_ptr + frames_to_read / cfg.sample_size) +				% io->buffer_size;  		ret = frames_to_read;  	} else if (rsend < 0) @@ -269,6 +273,8 @@ static snd_pcm_ioplug_callback_t bluetooth_capture_callback = {  static int bluetooth_hw_constraint(snd_pcm_ioplug_t *io)  { +	struct bluetooth_data *data = io->private_data; +	struct ipc_data_cfg cfg = data->cfg;  	snd_pcm_access_t access_list[] = {  		SND_PCM_ACCESS_RW_INTERLEAVED,  		/* Mmap access is really useless fo this driver, but we @@ -281,29 +287,36 @@ static int bluetooth_hw_constraint(snd_pcm_ioplug_t *io)  	};  	int err; +	/* access type */  	err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_ACCESS,  					ARRAY_NELEMS(access_list), access_list);  	if (err < 0)  		return err; +	/* supported formats */  	err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_FORMAT,  					ARRAY_NELEMS(format_list), format_list);  	if (err < 0)  		return err; -	err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_CHANNELS, 1, 1); +	/* supported channels */ +	err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_CHANNELS, +					cfg.channels, cfg.channels);  	if (err < 0)  		return err; -	err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_RATE, 8000, 8000); +	err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_RATE, +					cfg.rate, cfg.rate);  	if (err < 0)  		return err; -	err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 48, 48); +	err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, +					cfg.pkt_len, cfg.pkt_len);  	if (err < 0)  		return err; -	err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 2, 200); +	err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, +					2, 200);  	if (err < 0)  		return err; @@ -362,8 +375,7 @@ static int bluetooth_cfg(struct bluetooth_data *data)  	DBG("Sending PKT_TYPE_CFG_REQ..."); -	pkt = malloc(len); -	if (!pkt) +	if ((pkt = malloc(len)) == 0)  		return -ENOMEM;  	memset(pkt, 0, len); @@ -371,8 +383,7 @@ static int bluetooth_cfg(struct bluetooth_data *data)  	pkt->role = PKT_ROLE_NONE;  	pkt->error = PKT_ERROR_NONE; -	ret = send(data->sock, pkt, len, 0); -	if (ret < 0) { +	if ((ret = send(data->sock, pkt, len, 0)) < 0) {  		ret = -errno;  		goto done;  	} else if (ret == 0) { @@ -385,8 +396,7 @@ static int bluetooth_cfg(struct bluetooth_data *data)  	DBG("Waiting for response...");  	memset(pkt, 0, len); -	ret = recv(data->sock, pkt, len, 0); -	if (ret < 0) { +	if ((ret = recv(data->sock, pkt, len, 0)) < 0) {  		ret = -errno;  		goto done;  	} else if (ret == 0) { @@ -433,15 +443,19 @@ static int bluetooth_cfg(struct bluetooth_data *data)  		goto done;  	} -	ret = bluetooth_recvmsg_fd(data); -	if (ret < 0) +	if ((ret = bluetooth_recvmsg_fd(data)) < 0)  		goto done; +	if ((data->buffer = malloc(data->cfg.pkt_len)) == 0) +		return -ENOMEM; +  	/* It is possible there is some outstanding  	data in the pipe - we have to empty it */  	while(recv(data->cfg.fd, data->buffer, data->cfg.pkt_len,  		MSG_DONTWAIT) > 0); +	memset(data->buffer, 0, data->cfg.pkt_len); +  done:  	free(pkt);  	return ret; @@ -463,8 +477,7 @@ static int bluetooth_init(struct bluetooth_data *data)  	id = abs(getpid() * rand()); -	sk = socket(PF_LOCAL, SOCK_STREAM, 0); -	if (sk < 0) { +	if ((sk = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) {  		err = -errno;  		SNDERR("Can't open socket");  		return -errno; @@ -480,16 +493,9 @@ static int bluetooth_init(struct bluetooth_data *data)  	data->sock = sk; -	err = bluetooth_cfg(data); -	if (err < 0) +	if ((err = bluetooth_cfg(data)) < 0)  		return err; -	data->buffer = malloc(data->cfg.pkt_len); -	if (!data->buffer) -		return -ENOMEM; - -	memset(data->buffer, 0, data->cfg.pkt_len); -  	return 0;  }  | 
