|
|
|
@ -1,6 +1,7 @@ |
|
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2013 The Android Open Source Project |
|
|
|
|
* Copyright (C) 2017 Christopher N. Hesse <raymanfx@gmail.com> |
|
|
|
|
* Copyright (C) 2017 Andreas Schneider <asn@cryptomilk.org> |
|
|
|
|
* |
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
@ -243,6 +244,35 @@ static const struct string_to_enum out_channels_name_to_enum_table[] = { |
|
|
|
|
STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct timespec time_spec_diff(struct timespec time1, struct timespec time0) { |
|
|
|
|
struct timespec ret; |
|
|
|
|
int xsec = 0; |
|
|
|
|
int sign = 1; |
|
|
|
|
|
|
|
|
|
if (time0.tv_nsec > time1.tv_nsec) { |
|
|
|
|
xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1)); |
|
|
|
|
time0.tv_nsec -= (long int) (1E9 * xsec); |
|
|
|
|
time0.tv_sec += xsec; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((time1.tv_nsec - time0.tv_nsec) > 1E9) { |
|
|
|
|
xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9); |
|
|
|
|
time0.tv_nsec += (long int) (1E9 * xsec); |
|
|
|
|
time0.tv_sec -= xsec; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret.tv_sec = time1.tv_sec - time0.tv_sec; |
|
|
|
|
ret.tv_nsec = time1.tv_nsec - time0.tv_nsec; |
|
|
|
|
|
|
|
|
|
if (time1.tv_sec < time0.tv_sec) { |
|
|
|
|
sign = -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret.tv_sec = ret.tv_sec * sign; |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool is_supported_format(audio_format_t format) |
|
|
|
|
{ |
|
|
|
|
if (format == AUDIO_FORMAT_MP3 || |
|
|
|
@ -389,6 +419,11 @@ static int mixer_init(struct audio_device *adev) |
|
|
|
|
mixer_card->card = card; |
|
|
|
|
mixer_card->mixer = mixer; |
|
|
|
|
mixer_card->audio_route = audio_route; |
|
|
|
|
|
|
|
|
|
/* Do not sleep on first enable_snd_device() */ |
|
|
|
|
mixer_card->dsp_poweroff_time.tv_sec = 1; |
|
|
|
|
mixer_card->dsp_poweroff_time.tv_nsec = 0; |
|
|
|
|
|
|
|
|
|
list_add_tail(&adev->mixer_list, &mixer_card->adev_list_node); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -702,6 +737,10 @@ static int enable_snd_device(struct audio_device *adev, |
|
|
|
|
struct mixer_card *mixer_card; |
|
|
|
|
struct listnode *node; |
|
|
|
|
const char *snd_device_name = get_snd_device_name(snd_device); |
|
|
|
|
#ifdef DSP_POWEROFF_DELAY |
|
|
|
|
struct timespec activation_time; |
|
|
|
|
struct timespec elapsed_time; |
|
|
|
|
#endif /* DSP_POWEROFF_DELAY */ |
|
|
|
|
|
|
|
|
|
if (snd_device_name == NULL) |
|
|
|
|
return -EINVAL; |
|
|
|
@ -724,10 +763,26 @@ static int enable_snd_device(struct audio_device *adev, |
|
|
|
|
|
|
|
|
|
list_for_each(node, &uc_info->mixer_list) { |
|
|
|
|
mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]); |
|
|
|
|
|
|
|
|
|
#ifdef DSP_POWEROFF_DELAY |
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &activation_time); |
|
|
|
|
|
|
|
|
|
elapsed_time = time_spec_diff(mixer_card->dsp_poweroff_time, |
|
|
|
|
activation_time); |
|
|
|
|
if (elapsed_time.tv_sec == 0) { |
|
|
|
|
long elapsed_usec = elapsed_time.tv_nsec / 1000; |
|
|
|
|
|
|
|
|
|
if (elapsed_usec < DSP_POWEROFF_DELAY) { |
|
|
|
|
usleep(DSP_POWEROFF_DELAY - elapsed_usec); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
update_mixer = true; |
|
|
|
|
#endif /* DSP_POWEROFF_DELAY */ |
|
|
|
|
audio_route_apply_path(mixer_card->audio_route, snd_device_name); |
|
|
|
|
if (update_mixer) |
|
|
|
|
if (update_mixer) { |
|
|
|
|
audio_route_update_mixer(mixer_card->audio_route); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
@ -761,10 +816,17 @@ int disable_snd_device(struct audio_device *adev, |
|
|
|
|
snd_device, snd_device_name); |
|
|
|
|
list_for_each(node, &uc_info->mixer_list) { |
|
|
|
|
mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]); |
|
|
|
|
#ifdef DSP_POWEROFF_DELAY |
|
|
|
|
update_mixer = true; |
|
|
|
|
#endif /* DSP_POWEROFF_DELAY */ |
|
|
|
|
audio_route_reset_path(mixer_card->audio_route, snd_device_name); |
|
|
|
|
if (update_mixer) |
|
|
|
|
if (update_mixer) { |
|
|
|
|
audio_route_update_mixer(mixer_card->audio_route); |
|
|
|
|
} |
|
|
|
|
#ifdef DSP_POWEROFF_DELAY |
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &(mixer_card->dsp_poweroff_time)); |
|
|
|
|
#endif /* DSP_POWEROFF_DELAY */ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|