summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorKyle Repinski <repinski23@gmail.com>2015-03-24 17:06:19 -0500
committerZiyan <jaraidaniel@gmail.com>2016-01-15 12:29:33 +0100
commit1da4513f2dc7e631c3d7604a1e5d9fce517eaaec (patch)
treeaac3467953eb3f704b5fffeec142dea63c6d0659 /audio
parent2c4955eb175aeec8993996fcd74a63d74f3ea11c (diff)
downloaddevice_samsung_tuna-1da4513f2dc7e631c3d7604a1e5d9fce517eaaec.zip
device_samsung_tuna-1da4513f2dc7e631c3d7604a1e5d9fce517eaaec.tar.gz
device_samsung_tuna-1da4513f2dc7e631c3d7604a1e5d9fce517eaaec.tar.bz2
audio: Initial work towards a variable sampling rate.
Conflicts: audio/policy/audio_policy.default.conf Change-Id: I4d13946e88cacbf5e4ca383d5d0756262442efd2
Diffstat (limited to 'audio')
-rw-r--r--audio/Android.mk6
-rw-r--r--audio/audio_hw.c77
-rw-r--r--audio/audio_policy.conf4
3 files changed, 82 insertions, 5 deletions
diff --git a/audio/Android.mk b/audio/Android.mk
index 4ec8ae5..b678403 100644
--- a/audio/Android.mk
+++ b/audio/Android.mk
@@ -27,7 +27,11 @@ LOCAL_C_INCLUDES += \
LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libaudioutils libdl libsecril-client
LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS += -DFORCE_OUT_SAMPLING_RATE=44100
+ifeq ($(TARGET_TUNA_AUDIO_FORCE_SAMPLE_RATE),)
+LOCAL_CFLAGS += -DUSE_VARIABLE_SAMPLING_RATE
+else
+LOCAL_CFLAGS += -DFORCE_OUT_SAMPLING_RATE=$(TARGET_TUNA_AUDIO_FORCE_SAMPLE_RATE)
+endif
include $(BUILD_SHARED_LIBRARY)
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
index 0715fff..5e36799 100644
--- a/audio/audio_hw.c
+++ b/audio/audio_hw.c
@@ -240,9 +240,11 @@
/* If sample rate converter is required, then use triple-buffering to
* help mask the variance in cycle times. Otherwise use double-buffering.
*/
+/* TODO: Figure out a better check for this
#elif DEFAULT_OUT_SAMPLING_RATE != MM_FULL_POWER_SAMPLING_RATE
#define PLAYBACK_SHORT_PERIOD_COUNT 3
#define OUT_RESAMPLER
+*/
#else
#define PLAYBACK_SHORT_PERIOD_COUNT 2
#endif
@@ -325,7 +327,7 @@ enum tty_modes {
/* deep buffer */
struct pcm_config pcm_config_mm = {
.channels = 2,
- .rate = MM_FULL_POWER_SAMPLING_RATE,
+ .rate = MM_FULL_POWER_SAMPLING_RATE, /* changed based on audio policy setting */
.period_size = DEEP_BUFFER_LONG_PERIOD_SIZE,
.period_count = PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT,
.format = PCM_FORMAT_S16_LE,
@@ -336,7 +338,7 @@ struct pcm_config pcm_config_mm = {
/* low latency */
struct pcm_config pcm_config_tones = {
.channels = 2,
- .rate = MM_FULL_POWER_SAMPLING_RATE,
+ .rate = MM_FULL_POWER_SAMPLING_RATE, /* changed based on audio policy setting */
.period_size = SHORT_PERIOD_SIZE,
.period_count = PLAYBACK_SHORT_PERIOD_COUNT,
.format = PCM_FORMAT_S16_LE,
@@ -716,6 +718,10 @@ struct tuna_stream_out {
bool muted;
struct tuna_audio_device *dev;
+
+#ifdef USE_VARIABLE_SAMPLING_RATE
+ unsigned int sample_rate;
+#endif
};
#define MAX_PREPROCESSORS 3 /* maximum one AGC + one NS + one AEC per input stream */
@@ -1424,7 +1430,14 @@ static int start_output_stream_low_latency(struct tuna_stream_out *out)
if (adev->out_device & ~(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET | AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
/* Something not a dock in use */
out->config[PCM_NORMAL] = pcm_config_tones;
+#ifndef USE_VARIABLE_SAMPLING_RATE
out->config[PCM_NORMAL].rate = MM_FULL_POWER_SAMPLING_RATE;
+#else
+ if (out->sample_rate % 48 == 0)
+ out->config[PCM_NORMAL].rate = MM_FULL_POWER_SAMPLING_RATE;
+ else
+ out->config[PCM_NORMAL].rate = MM_LOW_POWER_SAMPLING_RATE;
+#endif
out->pcm[PCM_NORMAL] = pcm_open(CARD_TUNA_DEFAULT, PORT_TONES,
flags, &out->config[PCM_NORMAL]);
}
@@ -1432,7 +1445,14 @@ static int start_output_stream_low_latency(struct tuna_stream_out *out)
if (adev->out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
/* SPDIF output in use */
out->config[PCM_SPDIF] = pcm_config_tones;
+#ifndef USE_VARIABLE_SAMPLING_RATE
out->config[PCM_SPDIF].rate = MM_FULL_POWER_SAMPLING_RATE;
+#else
+ if (out->sample_rate % 48 == 0)
+ out->config[PCM_SPDIF].rate = MM_FULL_POWER_SAMPLING_RATE;
+ else
+ out->config[PCM_SPDIF].rate = MM_LOW_POWER_SAMPLING_RATE;
+#endif
out->pcm[PCM_SPDIF] = pcm_open(CARD_TUNA_DEFAULT, PORT_SPDIF,
flags, &out->config[PCM_SPDIF]);
}
@@ -1489,7 +1509,14 @@ static int start_output_stream_deep_buffer(struct tuna_stream_out *out)
out->use_long_periods = true;
out->config[PCM_NORMAL] = pcm_config_mm;
+#ifndef USE_VARIABLE_SAMPLING_RATE
out->config[PCM_NORMAL].rate = MM_FULL_POWER_SAMPLING_RATE;
+#else
+ if (out->sample_rate % 48 == 0)
+ out->config[PCM_NORMAL].rate = MM_FULL_POWER_SAMPLING_RATE;
+ else
+ out->config[PCM_NORMAL].rate = MM_LOW_POWER_SAMPLING_RATE;
+#endif
out->pcm[PCM_NORMAL] = pcm_open(CARD_TUNA_DEFAULT, PORT_MM,
PCM_OUT | PCM_MMAP | PCM_NOIRQ, &out->config[PCM_NORMAL]);
if (out->pcm[PCM_NORMAL] && !pcm_is_ready(out->pcm[PCM_NORMAL])) {
@@ -1664,15 +1691,26 @@ static int get_playback_delay(struct tuna_stream_out *out,
/* adjust render time stamp with delay added by current driver buffer.
* Add the duration of current frame as we want the render time of the last
* sample being written. */
+#ifndef USE_VARIABLE_SAMPLING_RATE
buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
MM_FULL_POWER_SAMPLING_RATE);
+#else
+ buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
+ out->sample_rate); // ?
+#endif
return 0;
}
static uint32_t out_get_sample_rate(const struct audio_stream *stream __unused)
{
+#ifdef USE_VARIABLE_SAMPLING_RATE
+ struct tuna_stream_out *out = (struct tuna_stream_out *)stream;
+
+ return out->sample_rate; // TODO: out->config[PCM_*].rate?
+#else
return DEFAULT_OUT_SAMPLING_RATE;
+#endif
}
static uint32_t out_get_sample_rate_hdmi(const struct audio_stream *stream)
@@ -1695,7 +1733,11 @@ static size_t out_get_buffer_size_low_latency(const struct audio_stream *stream)
multiple of 16 frames, as audioflinger expects audio buffers to
be a multiple of 16 frames. Note: we use the default rate here
from pcm_config_tones.rate. */
+#ifndef USE_VARIABLE_SAMPLING_RATE
size_t size = (SHORT_PERIOD_SIZE * DEFAULT_OUT_SAMPLING_RATE) / pcm_config_tones.rate;
+#else
+ size_t size = SHORT_PERIOD_SIZE; //?
+#endif
size = ((size + 15) / 16) * 16;
return size * audio_stream_out_frame_size((const struct audio_stream_out *)stream);
}
@@ -1708,8 +1750,12 @@ static size_t out_get_buffer_size_deep_buffer(const struct audio_stream *stream)
multiple of 16 frames, as audioflinger expects audio buffers to
be a multiple of 16 frames. Note: we use the default rate here
from pcm_config_mm.rate. */
+#ifndef USE_VARIABLE_SAMPLING_RATE
size_t size = (DEEP_BUFFER_SHORT_PERIOD_SIZE * DEFAULT_OUT_SAMPLING_RATE) /
pcm_config_mm.rate;
+#else
+ size_t size = DEEP_BUFFER_SHORT_PERIOD_SIZE; //?
+#endif
size = ((size + 15) / 16) * 16;
return size * audio_stream_out_frame_size((const struct audio_stream_out *)stream);
}
@@ -1922,7 +1968,11 @@ static uint32_t out_get_latency_low_latency(const struct audio_stream_out *strea
struct tuna_stream_out *out = (struct tuna_stream_out *)stream;
/* Note: we use the default rate here from pcm_config_mm.rate */
+#ifndef USE_VARIABLE_SAMPLING_RATE
return (SHORT_PERIOD_SIZE * PLAYBACK_SHORT_PERIOD_COUNT * 1000) / pcm_config_tones.rate;
+#else
+ return (SHORT_PERIOD_SIZE * PLAYBACK_SHORT_PERIOD_COUNT * 1000) / out->sample_rate; // ?
+#endif
}
static uint32_t out_get_latency_deep_buffer(const struct audio_stream_out *stream)
@@ -1930,8 +1980,13 @@ static uint32_t out_get_latency_deep_buffer(const struct audio_stream_out *strea
struct tuna_stream_out *out = (struct tuna_stream_out *)stream;
/* Note: we use the default rate here from pcm_config_mm.rate */
+#ifndef USE_VARIABLE_SAMPLING_RATE
return (DEEP_BUFFER_LONG_PERIOD_SIZE * PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT * 1000) /
pcm_config_mm.rate;
+#else
+ return (DEEP_BUFFER_LONG_PERIOD_SIZE * PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT * 1000) /
+ out->sample_rate; // ?
+#endif
}
static uint32_t out_get_latency_hdmi(const struct audio_stream_out *stream)
@@ -2129,9 +2184,15 @@ static ssize_t out_write_deep_buffer(struct audio_stream_out *stream, const void
kernel_frames = pcm_get_buffer_size(out->pcm[PCM_NORMAL]) - kernel_frames;
if (kernel_frames > out->write_threshold) {
+#ifndef USE_VARIABLE_SAMPLING_RATE
unsigned long time = (unsigned long)
(((int64_t)(kernel_frames - out->write_threshold) * 1000000) /
MM_FULL_POWER_SAMPLING_RATE);
+#else
+ unsigned long time = (unsigned long)
+ (((int64_t)(kernel_frames - out->write_threshold) * 1000000) /
+ out->sample_rate); // ?
+#endif
if (time < MIN_WRITE_SLEEP_US)
time = MIN_WRITE_SLEEP_US;
usleep(time);
@@ -3277,9 +3338,17 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
out = (struct tuna_stream_out *)calloc(1, sizeof(struct tuna_stream_out));
if (!out)
return -ENOMEM;
+ ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
+ __func__, config->sample_rate, config->channel_mask, devices, flags);
out->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+#ifdef USE_VARIABLE_SAMPLING_RATE
+ if (config->sample_rate == 0) {
+ config->sample_rate = MM_LOW_POWER_SAMPLING_RATE;
+ }
+ out->sample_rate = config->sample_rate;
+#endif
if (flags & AUDIO_OUTPUT_FLAG_DIRECT &&
devices == AUDIO_DEVICE_OUT_AUX_DIGITAL) {
@@ -3313,6 +3382,8 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
ret = -ENOSYS;
goto err_open;
}
+ /* NOTE: This gets called with the highest (or last?)
+ * sampling rate listed in the audio policy */
output_type = OUTPUT_DEEP_BUF;
out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
out->stream.common.get_buffer_size = out_get_buffer_size_deep_buffer;
@@ -3326,6 +3397,8 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
ret = -ENOSYS;
goto err_open;
}
+ /* NOTE: This gets called with the highest (or last?)
+ * sampling rate listed in the audio policy */
output_type = OUTPUT_LOW_LATENCY;
out->stream.common.get_buffer_size = out_get_buffer_size_low_latency;
out->stream.common.get_sample_rate = out_get_sample_rate;
diff --git a/audio/audio_policy.conf b/audio/audio_policy.conf
index 3131fa7..a782448 100644
--- a/audio/audio_policy.conf
+++ b/audio/audio_policy.conf
@@ -23,14 +23,14 @@ audio_hw_modules {
primary {
outputs {
primary {
- sampling_rates 44100|48000
+ sampling_rates 44100
channel_masks AUDIO_CHANNEL_OUT_STEREO
formats AUDIO_FORMAT_PCM_16_BIT
devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET
flags AUDIO_OUTPUT_FLAG_PRIMARY
}
deep_buffer {
- sampling_rates 44100|48000
+ sampling_rates 44100
channel_masks AUDIO_CHANNEL_OUT_STEREO
formats AUDIO_FORMAT_PCM_16_BIT
devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE