am 484a1e81: Merge "Fix problem with dropouts with multiple USB audio streams." into lmp-dev
* commit '484a1e8130b248843025a556c45f1c002e5d92d8': Fix problem with dropouts with multiple USB audio streams.
This commit is contained in:
commit
4b0bdc3326
5 changed files with 60 additions and 23 deletions
|
@ -124,6 +124,8 @@ __BEGIN_DECLS
|
|||
#define AUDIO_PARAMETER_STREAM_INPUT_SOURCE "input_source" /* audio_source_t */
|
||||
#define AUDIO_PARAMETER_STREAM_SAMPLING_RATE "sampling_rate" /* uint32_t */
|
||||
|
||||
#define AUDIO_PARAMETER_DEVICE_DISCONNECT "disconnect" /* audio_devices_t */
|
||||
|
||||
/* Query supported formats. The response is a '|' separated list of strings from
|
||||
* audio_format_t enum e.g: "sup_formats=AUDIO_FORMAT_PCM_16_BIT" */
|
||||
#define AUDIO_PARAMETER_STREAM_SUP_FORMATS "sup_formats"
|
||||
|
|
|
@ -92,6 +92,14 @@ bool profile_is_valid(alsa_device_profile* profile) {
|
|||
return profile->is_valid;
|
||||
}
|
||||
|
||||
bool profile_is_cached_for(alsa_device_profile* profile, int card, int device) {
|
||||
return card == profile->card && device == profile->device;
|
||||
}
|
||||
|
||||
void profile_decache(alsa_device_profile* profile) {
|
||||
profile->card = profile->device = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the supplied value rounded up to the next even multiple of 16
|
||||
*/
|
||||
|
|
|
@ -61,6 +61,8 @@ typedef struct {
|
|||
void profile_init(alsa_device_profile* profile, int direction);
|
||||
bool profile_is_initialized(alsa_device_profile* profile);
|
||||
bool profile_is_valid(alsa_device_profile* profile);
|
||||
bool profile_is_cached_for(alsa_device_profile* profile, int card, int device);
|
||||
void profile_decache(alsa_device_profile* profile);
|
||||
|
||||
bool profile_read_device_info(alsa_device_profile* profile);
|
||||
|
||||
|
|
|
@ -27,20 +27,6 @@
|
|||
#define DEFAULT_PERIOD_SIZE 1024
|
||||
#define DEFAULT_PERIOD_COUNT 2
|
||||
|
||||
//void proxy_init(alsa_device_proxy * proxy)
|
||||
//{
|
||||
// proxy->profile = NULL;
|
||||
//
|
||||
// proxy->alsa_config.format = DEFAULT_SAMPLE_FORMAT;
|
||||
// proxy->alsa_config.rate = DEFAULT_SAMPLE_RATE;
|
||||
// proxy->alsa_config.channels = DEFAULT_CHANNEL_COUNT;
|
||||
//
|
||||
// proxy->alsa_config.period_size = DEFAULT_PERIOD_SIZE;
|
||||
// proxy->alsa_config.period_count = DEFAULT_PERIOD_COUNT;
|
||||
//
|
||||
// proxy->pcm = NULL;
|
||||
//}
|
||||
|
||||
void proxy_prepare(alsa_device_proxy * proxy, alsa_device_profile* profile,
|
||||
struct pcm_config * config)
|
||||
{
|
||||
|
@ -79,7 +65,6 @@ void proxy_prepare(alsa_device_proxy * proxy, alsa_device_profile* profile,
|
|||
int proxy_open(alsa_device_proxy * proxy)
|
||||
{
|
||||
alsa_device_profile* profile = proxy->profile;
|
||||
|
||||
ALOGV("proxy_open(card:%d device:%d %s)", profile->card, profile->device,
|
||||
profile->direction == PCM_OUT ? "PCM_OUT" : "PCM_IN");
|
||||
|
||||
|
@ -103,8 +88,12 @@ int proxy_open(alsa_device_proxy * proxy)
|
|||
|
||||
void proxy_close(alsa_device_proxy * proxy)
|
||||
{
|
||||
pcm_close(proxy->pcm);
|
||||
proxy->pcm = NULL;
|
||||
ALOGV("proxy_close() [pcm:%p]", proxy->pcm);
|
||||
|
||||
if (proxy->pcm != NULL) {
|
||||
pcm_close(proxy->pcm);
|
||||
proxy->pcm = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -253,7 +253,6 @@ static size_t out_get_buffer_size(const struct audio_stream *stream)
|
|||
const struct stream_out* out = (const struct stream_out*)stream;
|
||||
size_t buffer_size =
|
||||
proxy_get_period_size(&out->proxy) * audio_stream_out_frame_size(&(out->stream));
|
||||
ALOGV("out_get_buffer_size() = %zu", buffer_size);
|
||||
return buffer_size;
|
||||
}
|
||||
|
||||
|
@ -327,7 +326,7 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
|
|||
if (param_val >= 0)
|
||||
device = atoi(value);
|
||||
|
||||
if (card >= 0 && device >= 0) {
|
||||
if (card >= 0 && device >= 0 && !profile_is_cached_for(out->profile, card, device)) {
|
||||
/* cannot read pcm device info if playback is active */
|
||||
if (!out->standby)
|
||||
ret_value = -ENOSYS;
|
||||
|
@ -343,6 +342,7 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&out->lock);
|
||||
pthread_mutex_unlock(&out->dev->lock);
|
||||
str_parms_destroy(parms);
|
||||
|
@ -401,7 +401,6 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, si
|
|||
}
|
||||
pthread_mutex_unlock(&out->dev->lock);
|
||||
|
||||
|
||||
alsa_device_proxy* proxy = &out->proxy;
|
||||
const void * write_buff = buffer;
|
||||
int num_write_buff_bytes = bytes;
|
||||
|
@ -516,6 +515,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
|
|||
|
||||
// build this to hand to the alsa_device_proxy
|
||||
struct pcm_config proxy_config;
|
||||
memset(&proxy_config, 0, sizeof(proxy_config));
|
||||
|
||||
int ret = 0;
|
||||
|
||||
|
@ -704,7 +704,7 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
|
|||
pthread_mutex_lock(&in->dev->lock);
|
||||
pthread_mutex_lock(&in->lock);
|
||||
|
||||
/* Card/Device */
|
||||
/* Device Connection Message ("card=1,device=0") */
|
||||
param_val = str_parms_get_str(parms, "card", value, sizeof(value));
|
||||
if (param_val >= 0)
|
||||
card = atoi(value);
|
||||
|
@ -713,7 +713,7 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
|
|||
if (param_val >= 0)
|
||||
device = atoi(value);
|
||||
|
||||
if (card >= 0 && device >= 0) {
|
||||
if (card >= 0 && device >= 0 && !profile_is_cached_for(in->profile, card, device)) {
|
||||
/* cannot read pcm device info if playback is active */
|
||||
if (!in->standby)
|
||||
ret_value = -ENOSYS;
|
||||
|
@ -728,7 +728,7 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
|
|||
in->profile->device = saved_device;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&in->lock);
|
||||
pthread_mutex_unlock(&in->dev->lock);
|
||||
|
@ -923,6 +923,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
|
|||
in->profile = &in->dev->in_profile;
|
||||
|
||||
struct pcm_config proxy_config;
|
||||
memset(&proxy_config, 0, sizeof(proxy_config));
|
||||
|
||||
/* Rate */
|
||||
if (config->sample_rate == 0) {
|
||||
|
@ -995,6 +996,41 @@ static void adev_close_input_stream(struct audio_hw_device *dev, struct audio_st
|
|||
*/
|
||||
static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
|
||||
{
|
||||
ALOGV("audio_hw:usb adev_set_parameters(%s)", kvpairs);
|
||||
|
||||
struct audio_device * adev = (struct audio_device *)dev;
|
||||
|
||||
char value[32];
|
||||
int param_val;
|
||||
|
||||
struct str_parms * parms = str_parms_create_str(kvpairs);
|
||||
|
||||
/* Check for the "disconnect" message */
|
||||
param_val = str_parms_get_str(parms, "disconnect", value, sizeof(value));
|
||||
if (param_val >= 0) {
|
||||
audio_devices_t device = (audio_devices_t)atoi(value);
|
||||
|
||||
param_val = str_parms_get_str(parms, "card", value, sizeof(value));
|
||||
int alsa_card = param_val >= 0 ? atoi(value) : -1;
|
||||
|
||||
param_val = str_parms_get_str(parms, "device", value, sizeof(value));
|
||||
int alsa_device = param_val >= 0 ? atoi(value) : -1;
|
||||
|
||||
if (alsa_card >= 0 && alsa_device >= 0) {
|
||||
/* "decache" the profile */
|
||||
pthread_mutex_lock(&adev->lock);
|
||||
if (device == AUDIO_DEVICE_OUT_USB_DEVICE &&
|
||||
profile_is_cached_for(&adev->out_profile, alsa_card, alsa_device)) {
|
||||
profile_decache(&adev->out_profile);
|
||||
}
|
||||
if (device == AUDIO_DEVICE_IN_USB_DEVICE &&
|
||||
profile_is_cached_for(&adev->in_profile, alsa_card, alsa_device)) {
|
||||
profile_decache(&adev->in_profile);
|
||||
}
|
||||
pthread_mutex_unlock(&adev->lock);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue