#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-#define PERIOD_SIZE_US (5 * 1000)
+#define PERIOD_DURATION_US (5 * 1000)
#define DEFAULT_PERIOD_SIZE 1024
if (profile == NULL) {
return DEFAULT_PERIOD_SIZE;
} else {
- unsigned period_us = property_get_int32("ro.audio.usb.period_us", PERIOD_SIZE_US);
+ unsigned period_us = property_get_int32("ro.audio.usb.period_us", PERIOD_DURATION_US);
unsigned num_sample_frames = ((uint64_t)sample_rate * period_us) / 1000000;
if (num_sample_frames < profile->min_period_size) {
return profile_is_valid(profile) ? profile->channel_counts[0] : DEFAULT_CHANNEL_COUNT;
}
+unsigned profile_get_closest_channel_count(alsa_device_profile* profile, unsigned count)
+{
+ if (profile_is_valid(profile)) {
+ if (count < profile->min_channel_count) {
+ return profile->min_channel_count;
+ } else if (count > profile->max_channel_count) {
+ return profile->max_channel_count;
+ } else {
+ return count;
+ }
+ } else {
+ return 0;
+ }
+}
+
bool profile_is_channel_count_valid(alsa_device_profile* profile, unsigned count)
{
if (profile_is_initialized(profile)) {
#endif
config->channels = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
+ // For output devices, let's make sure we choose at least stereo
+ // (assuming the device supports it).
+ if (profile->direction == PCM_OUT &&
+ config->channels < 2 && pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS) >= 2) {
+ config->channels = 2;
+ }
config->rate = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
+ // Prefer 48K or 44.1K
+ if (config->rate < 48000 &&
+ pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE) >= 48000) {
+ config->rate = 48000;
+ } else if (config->rate < 44100 &&
+ pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE) >= 44100) {
+ config->rate = 44100;
+ }
config->period_size = profile_calc_min_period_size(profile, config->rate);
config->period_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS);
config->format = get_pcm_format_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
profile->is_valid = true;
+ pcm_params_free(alsa_hw_params);
return true;
}
return strdup(buffer);
}
+
+void profile_dump(const alsa_device_profile* profile, int fd)
+{
+ if (profile == NULL) {
+ dprintf(fd, " %s\n", "No USB Profile");
+ return; /* bail early */
+ }
+
+ if (!profile->is_valid) {
+ dprintf(fd, " Profile is INVALID");
+ }
+
+ /* card/device/direction */
+ dprintf(fd, " card:%d, device:%d - %s\n",
+ profile->card, profile->device, profile->direction == PCM_OUT ? "OUT" : "IN");
+
+ /* formats */
+ dprintf(fd, " Formats: ");
+ for (int fmtIndex = 0;
+ profile->formats[fmtIndex] != PCM_FORMAT_INVALID && fmtIndex < MAX_PROFILE_FORMATS;
+ fmtIndex++) {
+ dprintf(fd, "%d ", profile->formats[fmtIndex]);
+ }
+ dprintf(fd, "\n");
+
+ /* sample rates */
+ dprintf(fd, " Rates: ");
+ for (int rateIndex = 0;
+ profile->sample_rates[rateIndex] != 0 && rateIndex < MAX_PROFILE_SAMPLE_RATES;
+ rateIndex++) {
+ dprintf(fd, "%u ", profile->sample_rates[rateIndex]);
+ }
+ dprintf(fd, "\n");
+
+ // channel counts
+ dprintf(fd, " Channel Counts: ");
+ for (int cntIndex = 0;
+ profile->channel_counts[cntIndex] != 0 && cntIndex < MAX_PROFILE_CHANNEL_COUNTS;
+ cntIndex++) {
+ dprintf(fd, "%u ", profile->channel_counts[cntIndex]);
+ }
+ dprintf(fd, "\n");
+
+ dprintf(fd, " min/max period size [%u : %u]\n",
+ profile->min_period_size,profile-> max_period_size);
+ dprintf(fd, " min/max channel count [%u : %u]\n",
+ profile->min_channel_count, profile->max_channel_count);
+
+ // struct pcm_config default_config;
+ dprintf(fd, " Default Config:\n");
+ dprintf(fd, " channels: %d\n", profile->default_config.channels);
+ dprintf(fd, " rate: %d\n", profile->default_config.rate);
+ dprintf(fd, " period_size: %d\n", profile->default_config.period_size);
+ dprintf(fd, " period_count: %d\n", profile->default_config.period_count);
+ dprintf(fd, " format: %d\n", profile->default_config.format);
+}