Merge "Move the pcm period settings into properties"
diff --git a/audio/device_port_sink.cpp b/audio/device_port_sink.cpp
index a42f692..668f2f0 100644
--- a/audio/device_port_sink.cpp
+++ b/audio/device_port_sink.cpp
@@ -46,13 +46,6 @@
constexpr int kMaxJitterUs = 3000; // Enforced by CTS, should be <= 6ms
struct TinyalsaSink : public DevicePortSink {
- // Mostly magic numbers.
- // In pcm, the hardware works with `period_size` granularity.
- // The `period_count` is the number of `period_size` units in the pcm
- // buffer.
- static constexpr size_t kPcmPeriodCount = 8;
- static constexpr size_t kPcmPeriodSizeMultiplier = 2;
-
TinyalsaSink(unsigned pcmCard, unsigned pcmDevice,
const AudioConfig &cfg,
uint64_t &frames)
@@ -67,8 +60,7 @@
, mPcm(talsa::pcmOpen(pcmCard, pcmDevice,
util::countChannels(cfg.base.channelMask),
cfg.base.sampleRateHz,
- kPcmPeriodCount,
- kPcmPeriodSizeMultiplier * cfg.frameCount / kPcmPeriodCount,
+ cfg.frameCount,
true /* isOut */)) {
if (mPcm) {
LOG_ALWAYS_FATAL_IF(!talsa::pcmPrepare(mPcm.get()));
@@ -85,8 +77,10 @@
static int getLatencyMs(const AudioConfig &cfg) {
constexpr size_t inMs = 1000;
- const size_t numerator = kPcmPeriodSizeMultiplier * cfg.frameCount;
- const size_t denominator = kPcmPeriodCount * cfg.base.sampleRateHz / inMs;
+ const talsa::PcmPeriodSettings periodSettings =
+ talsa::pcmGetPcmPeriodSettings();
+ const size_t numerator = periodSettings.periodSizeMultiplier * cfg.frameCount;
+ const size_t denominator = periodSettings.periodCount * cfg.base.sampleRateHz / inMs;
// integer division with rounding
return (numerator + (denominator >> 1)) / denominator;
diff --git a/audio/device_port_source.cpp b/audio/device_port_source.cpp
index c3d9b84..e4c4528 100644
--- a/audio/device_port_source.cpp
+++ b/audio/device_port_source.cpp
@@ -50,13 +50,6 @@
constexpr int kMaxJitterUs = 3000; // Enforced by CTS, should be <= 6ms
struct TinyalsaSource : public DevicePortSource {
- // Mostly magic numbers.
- // In pcm, the hardware works with `period_size` granularity.
- // The `period_count` is the number of `period_size` units in the pcm
- // buffer.
- static constexpr size_t kPcmPeriodCount = 8;
- static constexpr size_t kPcmPeriodSizeMultiplier = 2;
-
TinyalsaSource(unsigned pcmCard, unsigned pcmDevice,
const AudioConfig &cfg, uint64_t &frames)
: mStartNs(systemTime(SYSTEM_TIME_MONOTONIC))
@@ -69,8 +62,7 @@
, mPcm(talsa::pcmOpen(pcmCard, pcmDevice,
util::countChannels(cfg.base.channelMask),
cfg.base.sampleRateHz,
- kPcmPeriodCount,
- kPcmPeriodSizeMultiplier * cfg.frameCount / kPcmPeriodCount,
+ cfg.frameCount,
false /* isOut */)) {
if (mPcm) {
LOG_ALWAYS_FATAL_IF(!talsa::pcmPrepare(mPcm.get()));
diff --git a/audio/talsa.cpp b/audio/talsa.cpp
index a0fc73c..e538c4e 100644
--- a/audio/talsa.cpp
+++ b/audio/talsa.cpp
@@ -15,6 +15,7 @@
*/
#include <mutex>
+#include <cutils/properties.h>
#include <log/log.h>
#include "talsa.h"
#include "debug.h"
@@ -31,6 +32,9 @@
struct mixer *gMixer0 = nullptr;
int gMixerRefcounter0 = 0;
std::mutex gMixerMutex;
+const PcmPeriodSettings kDefaultPcmPeriodSettings = { 4, 1 };
+PcmPeriodSettings gPcmPeriodSettings;
+std::once_flag gPcmPeriodSettingsFlag;
void mixerSetValueAll(struct mixer_ctl *ctl, int value) {
const unsigned int n = mixer_ctl_get_num_values(ctl);
@@ -95,8 +99,38 @@
return mixerUnrefImpl(mixer, gMixer0, gMixerRefcounter0);
}
+bool initPcmPeriodSettings(PcmPeriodSettings *dst) {
+ char prop_value[PROPERTY_VALUE_MAX];
+
+ if (property_get("ro.hardware.audio.tinyalsa.period_count", prop_value, nullptr) < 0) {
+ return false;
+ }
+ if (sscanf(prop_value, "%u", &dst->periodCount) != 1) {
+ return false;
+ }
+
+ if (property_get("ro.hardware.audio.tinyalsa.period_size_multiplier", prop_value, nullptr) < 0) {
+ return false;
+ }
+ if (sscanf(prop_value, "%u", &dst->periodSizeMultiplier) != 1) {
+ return false;
+ }
+
+ return true;
+}
+
} // namespace
+PcmPeriodSettings pcmGetPcmPeriodSettings() {
+ std::call_once(gPcmPeriodSettingsFlag, [](){
+ if (!initPcmPeriodSettings(&gPcmPeriodSettings)) {
+ gPcmPeriodSettings = kDefaultPcmPeriodSettings;
+ }
+ });
+
+ return gPcmPeriodSettings;
+}
+
void PcmDeleter::operator()(pcm_t *x) const {
LOG_ALWAYS_FATAL_IF(::pcm_close(x) != 0);
};
@@ -105,16 +139,20 @@
const unsigned int card,
const unsigned int nChannels,
const size_t sampleRateHz,
- const size_t periodCount,
- const size_t periodSize,
+ const size_t frameCount,
const bool isOut) {
+ const PcmPeriodSettings periodSettings = pcmGetPcmPeriodSettings();
+
struct pcm_config pcm_config;
memset(&pcm_config, 0, sizeof(pcm_config));
pcm_config.channels = nChannels;
pcm_config.rate = sampleRateHz;
- pcm_config.period_count = periodCount; // Approx interrupts per buffer
- pcm_config.period_size = periodSize; // Approx frames between interrupts
+ // Approx interrupts per buffer
+ pcm_config.period_count = periodSettings.periodCount;
+ // Approx frames between interrupts
+ pcm_config.period_size =
+ periodSettings.periodSizeMultiplier * frameCount / periodSettings.periodCount;
pcm_config.format = PCM_FORMAT_S16_LE;
PcmPtr pcm =
@@ -125,8 +163,8 @@
return pcm;
} else {
ALOGE("%s:%d pcm_open failed for nChannels=%u sampleRateHz=%zu "
- "period_count=%zu period_size=%zu isOut=%d with %s", __func__, __LINE__,
- nChannels, sampleRateHz, periodCount, periodSize, isOut,
+ "period_count=%d period_size=%d isOut=%d with %s", __func__, __LINE__,
+ nChannels, sampleRateHz, pcm_config.period_count, pcm_config.period_size, isOut,
pcm_get_error(pcm.get()));
return FAILURE(nullptr);
}
diff --git a/audio/talsa.h b/audio/talsa.h
index 6024158..1854f1e 100644
--- a/audio/talsa.h
+++ b/audio/talsa.h
@@ -28,12 +28,18 @@
constexpr unsigned int kPcmDevice = 0;
constexpr unsigned int kPcmCard = 0;
+struct PcmPeriodSettings {
+ unsigned periodCount;
+ unsigned periodSizeMultiplier;
+};
+
+PcmPeriodSettings pcmGetPcmPeriodSettings();
+
typedef struct pcm pcm_t;
struct PcmDeleter { void operator()(pcm_t *x) const; };
typedef std::unique_ptr<pcm_t, PcmDeleter> PcmPtr;
PcmPtr pcmOpen(unsigned int dev, unsigned int card, unsigned int nChannels,
- size_t sampleRateHz, size_t periodCount, size_t periodSize,
- bool isOut);
+ size_t sampleRateHz, size_t frameCount, bool isOut);
bool pcmPrepare(pcm_t *pcm);
bool pcmStart(pcm_t *pcm);
bool pcmStop(pcm_t *pcm);
diff --git a/init.ranchu.rc b/init.ranchu.rc
index c4313c1..5c6bc9f 100644
--- a/init.ranchu.rc
+++ b/init.ranchu.rc
@@ -94,6 +94,8 @@
chown root system /sys/power/wake_lock
chown root system /sys/power/wake_unlock
setprop ro.hardware.audio.primary goldfish
+ setprop ro.hardware.audio.tinyalsa.period_count 4
+ setprop ro.hardware.audio.tinyalsa.period_size_multiplier 4
setprop wifi.interface wlan0
setprop wifi.direct.interface p2p-dev-wlan0