summaryrefslogtreecommitdiffstats
path: root/media/libmedia
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmedia')
-rw-r--r--media/libmedia/AudioTrack.cpp128
1 files changed, 84 insertions, 44 deletions
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index b1be8b1..cd419bd 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -54,6 +54,12 @@ status_t AudioTrack::getMinFrameCount(
audio_stream_type_t streamType,
uint32_t sampleRate)
{
+ // FIXME merge with similar code in createTrack_l(), except we're missing
+ // some information here that is available in createTrack_l():
+ // audio_io_handle_t output
+ // audio_format_t format
+ // audio_channel_mask_t channelMask
+ // audio_output_flags_t flags
int afSampleRate;
if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
return NO_INIT;
@@ -201,11 +207,11 @@ status_t AudioTrack::set(
streamType = AUDIO_STREAM_MUSIC;
}
- int afSampleRate;
- if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
- return NO_INIT;
- }
if (sampleRate == 0) {
+ int afSampleRate;
+ if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
+ return NO_INIT;
+ }
sampleRate = afSampleRate;
}
@@ -223,6 +229,12 @@ status_t AudioTrack::set(
return BAD_VALUE;
}
+ // AudioFlinger does not currently support 8-bit data in shared memory
+ if (format == AUDIO_FORMAT_PCM_8_BIT && sharedBuffer != 0) {
+ ALOGE("8-bit data in shared memory is not supported");
+ return BAD_VALUE;
+ }
+
// force direct flag if format is not linear PCM
if (!audio_is_linear_pcm(format)) {
flags = (audio_output_flags_t)
@@ -744,14 +756,6 @@ status_t AudioTrack::createTrack_l(
return NO_INIT;
}
- int afSampleRate;
- if (AudioSystem::getSamplingRate(output, streamType, &afSampleRate) != NO_ERROR) {
- return NO_INIT;
- }
- int afFrameCount;
- if (AudioSystem::getFrameCount(output, streamType, &afFrameCount) != NO_ERROR) {
- return NO_INIT;
- }
uint32_t afLatency;
if (AudioSystem::getLatency(output, streamType, &afLatency) != NO_ERROR) {
return NO_INIT;
@@ -768,14 +772,57 @@ status_t AudioTrack::createTrack_l(
ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by client");
flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST);
}
- ALOGV("createTrack_l() output %d afFrameCount %d afLatency %d", output, afFrameCount, afLatency);
+ ALOGV("createTrack_l() output %d afLatency %d", output, afLatency);
mNotificationFramesAct = mNotificationFramesReq;
+
if (!audio_is_linear_pcm(format)) {
+
if (sharedBuffer != 0) {
+ // Same comment as below about ignoring frameCount parameter for set()
frameCount = sharedBuffer->size();
+ } else if (frameCount == 0) {
+ int afFrameCount;
+ if (AudioSystem::getFrameCount(output, streamType, &afFrameCount) != NO_ERROR) {
+ return NO_INIT;
+ }
+ frameCount = afFrameCount;
}
- } else {
+
+ } else if (sharedBuffer != 0) {
+
+ // Ensure that buffer alignment matches channelCount
+ int channelCount = popcount(channelMask);
+ // 8-bit data in shared memory is not currently supported by AudioFlinger
+ size_t alignment = /* format == AUDIO_FORMAT_PCM_8_BIT ? 1 : */ 2;
+ if (channelCount > 1) {
+ // More than 2 channels does not require stronger alignment than stereo
+ alignment <<= 1;
+ }
+ if (((uint32_t)sharedBuffer->pointer() & (alignment - 1)) != 0) {
+ ALOGE("Invalid buffer alignment: address %p, channelCount %d",
+ sharedBuffer->pointer(), channelCount);
+ return BAD_VALUE;
+ }
+
+ // When initializing a shared buffer AudioTrack via constructors,
+ // there's no frameCount parameter.
+ // But when initializing a shared buffer AudioTrack via set(),
+ // there _is_ a frameCount parameter. We silently ignore it.
+ frameCount = sharedBuffer->size()/channelCount/sizeof(int16_t);
+
+ } else if (!(flags & AUDIO_OUTPUT_FLAG_FAST)) {
+
+ // FIXME move these calculations and associated checks to server
+ int afSampleRate;
+ if (AudioSystem::getSamplingRate(output, streamType, &afSampleRate) != NO_ERROR) {
+ return NO_INIT;
+ }
+ int afFrameCount;
+ if (AudioSystem::getFrameCount(output, streamType, &afFrameCount) != NO_ERROR) {
+ return NO_INIT;
+ }
+
// Ensure that buffer depth covers at least audio hardware latency
uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
if (minBufCount < 2) minBufCount = 2;
@@ -784,38 +831,27 @@ status_t AudioTrack::createTrack_l(
ALOGV("minFrameCount: %d, afFrameCount=%d, minBufCount=%d, sampleRate=%d, afSampleRate=%d"
", afLatency=%d",
minFrameCount, afFrameCount, minBufCount, sampleRate, afSampleRate, afLatency);
-#define MIN_FRAME_COUNT_FAST 128 // FIXME hard-coded
- if ((flags & AUDIO_OUTPUT_FLAG_FAST) && (minFrameCount > MIN_FRAME_COUNT_FAST)) {
- minFrameCount = MIN_FRAME_COUNT_FAST;
- }
- if (sharedBuffer == 0) {
- if (frameCount == 0) {
- frameCount = minFrameCount;
- }
- if (mNotificationFramesAct == 0) {
- mNotificationFramesAct = frameCount/2;
- }
- // Make sure that application is notified with sufficient margin
- // before underrun
- if (mNotificationFramesAct > (uint32_t)frameCount/2) {
- mNotificationFramesAct = frameCount/2;
- }
- if (frameCount < minFrameCount) {
- // not ALOGW because it happens all the time when playing key clicks over A2DP
- ALOGV("Minimum buffer size corrected from %d to %d",
- frameCount, minFrameCount);
- frameCount = minFrameCount;
- }
- } else {
- // Ensure that buffer alignment matches channelCount
- int channelCount = popcount(channelMask);
- if (((uint32_t)sharedBuffer->pointer() & (channelCount | 1)) != 0) {
- ALOGE("Invalid buffer alignement: address %p, channelCount %d", sharedBuffer->pointer(), channelCount);
- return BAD_VALUE;
- }
- frameCount = sharedBuffer->size()/channelCount/sizeof(int16_t);
+ if (frameCount == 0) {
+ frameCount = minFrameCount;
+ }
+ if (mNotificationFramesAct == 0) {
+ mNotificationFramesAct = frameCount/2;
+ }
+ // Make sure that application is notified with sufficient margin
+ // before underrun
+ if (mNotificationFramesAct > (uint32_t)frameCount/2) {
+ mNotificationFramesAct = frameCount/2;
}
+ if (frameCount < minFrameCount) {
+ // not ALOGW because it happens all the time when playing key clicks over A2DP
+ ALOGV("Minimum buffer size corrected from %d to %d",
+ frameCount, minFrameCount);
+ frameCount = minFrameCount;
+ }
+
+ } else {
+ // For fast tracks, the frame count calculations and checks are done by server
}
IAudioFlinger::track_flags_t trackFlags = IAudioFlinger::TRACK_DEFAULT;
@@ -864,6 +900,9 @@ status_t AudioTrack::createTrack_l(
} else {
ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %u", mCblk->frameCount);
}
+ if (sharedBuffer == 0) {
+ mNotificationFramesAct = mCblk->frameCount/2;
+ }
}
if (sharedBuffer == 0) {
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
@@ -879,6 +918,7 @@ status_t AudioTrack::createTrack_l(
mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
mCblk->waitTimeMs = 0;
mRemainingFrames = mNotificationFramesAct;
+ // FIXME don't believe this lie
mLatency = afLatency + (1000*mCblk->frameCount) / sampleRate;
return NO_ERROR;
}