Skip to content

Commit 540c35f

Browse files
gkastenAndroid (Google) Code Review
authored andcommitted
Merge "Track volume cleanup"
2 parents 96c804a + 0632bad commit 540c35f

File tree

3 files changed

+35
-15
lines changed

3 files changed

+35
-15
lines changed

include/private/media/AudioTrackShared.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,13 @@ struct audio_track_cblk_t
7171
uint32_t loopStart;
7272
uint32_t loopEnd;
7373
int loopCount;
74-
volatile union {
75-
uint16_t volume[2];
76-
uint32_t volumeLR;
77-
};
74+
75+
// Channel volumes are fixed point U4.12, so 0x1000 means 1.0.
76+
// Left channel is in [0:15], right channel is in [16:31].
77+
// Always read and write the combined pair atomically.
78+
// For AudioTrack only, not used by AudioRecord.
79+
uint32_t volumeLR;
80+
7881
uint32_t sampleRate;
7982
// NOTE: audio_track_cblk_t::frameSize is not equal to AudioTrack::frameSize() for
8083
// 8 bit PCM data: in this case, mCblk->frameSize is based on a sample size of

media/libmedia/AudioTrack.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,6 @@ status_t AudioTrack::setVolume(float left, float right)
480480
mVolume[LEFT] = left;
481481
mVolume[RIGHT] = right;
482482

483-
// write must be atomic
484483
mCblk->volumeLR = (uint32_t(uint16_t(right * 0x1000)) << 16) | uint16_t(left * 0x1000);
485484

486485
return NO_ERROR;

services/audioflinger/AudioFlinger.cpp

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ static const char kHardwareLockedString[] = "Hardware lock is taken\n";
7272

7373
//static const nsecs_t kStandbyTimeInNsecs = seconds(3);
7474
static const float MAX_GAIN = 4096.0f;
75-
static const float MAX_GAIN_INT = 0x1000;
75+
static const uint32_t MAX_GAIN_INT = 0x1000;
7676

7777
// retry counts for buffer fill timeout
7878
// 50 * ~20msecs = 1 second
@@ -2190,14 +2190,29 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
21902190
// read original volumes with volume control
21912191
float typeVolume = mStreamTypes[track->type()].volume;
21922192
float v = masterVolume * typeVolume;
2193-
vl = (uint32_t)(v * cblk->volume[0]) << 12;
2194-
vr = (uint32_t)(v * cblk->volume[1]) << 12;
2193+
uint32_t vlr = cblk->volumeLR;
2194+
vl = vlr & 0xFFFF;
2195+
vr = vlr >> 16;
2196+
// track volumes come from shared memory, so can't be trusted and must be clamped
2197+
if (vl > MAX_GAIN_INT) {
2198+
ALOGV("Track left volume out of range: %04X", vl);
2199+
vl = MAX_GAIN_INT;
2200+
}
2201+
if (vr > MAX_GAIN_INT) {
2202+
ALOGV("Track right volume out of range: %04X", vr);
2203+
vr = MAX_GAIN_INT;
2204+
}
2205+
// now apply the master volume and stream type volume
2206+
vl = (uint32_t)(v * vl) << 12;
2207+
vr = (uint32_t)(v * vr) << 12;
2208+
// assuming master volume and stream type volume each go up to 1.0,
2209+
// vl and vr are now in 8.24 format
21952210

21962211
uint16_t sendLevel = cblk->getSendLevel_U4_12();
21972212
// send level comes from shared memory and so may be corrupt
2198-
if (sendLevel >= 0x1000) {
2213+
if (sendLevel >= MAX_GAIN_INT) {
21992214
ALOGV("Track send level out of range: %04X", sendLevel);
2200-
sendLevel = 0x1000;
2215+
sendLevel = MAX_GAIN_INT;
22012216
}
22022217
va = (uint32_t)(v * sendLevel);
22032218
}
@@ -2217,6 +2232,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
22172232

22182233
// Convert volumes from 8.24 to 4.12 format
22192234
int16_t left, right, aux;
2235+
// This additional clamping is needed in case chain->setVolume_l() overshot
22202236
uint32_t v_clamped = (vl + (1 << 11)) >> 12;
22212237
if (v_clamped > MAX_GAIN_INT) v_clamped = MAX_GAIN_INT;
22222238
left = int16_t(v_clamped);
@@ -2699,10 +2715,11 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
26992715
} else {
27002716
float typeVolume = mStreamTypes[track->type()].volume;
27012717
float v = mMasterVolume * typeVolume;
2702-
float v_clamped = v * cblk->volume[0];
2718+
uint32_t vlr = cblk->volumeLR;
2719+
float v_clamped = v * (vlr & 0xFFFF);
27032720
if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
27042721
left = v_clamped/MAX_GAIN;
2705-
v_clamped = v * cblk->volume[1];
2722+
v_clamped = v * (vlr >> 16);
27062723
if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
27072724
right = v_clamped/MAX_GAIN;
27082725
}
@@ -3436,6 +3453,7 @@ void AudioFlinger::PlaybackThread::Track::destroy()
34363453

34373454
void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
34383455
{
3456+
uint32_t vlr = mCblk->volumeLR;
34393457
snprintf(buffer, size, " %05d %05d %03u %03u 0x%08x %05u %04u %1d %1d %1d %05u %05u %05u 0x%08x 0x%08x 0x%08x 0x%08x\n",
34403458
mName - AudioMixer::TRACK0,
34413459
(mClient == NULL) ? getpid() : mClient->pid(),
@@ -3448,8 +3466,8 @@ void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
34483466
mMute,
34493467
mFillingUpStatus,
34503468
mCblk->sampleRate,
3451-
mCblk->volume[0],
3452-
mCblk->volume[1],
3469+
vlr & 0xFFFF,
3470+
vlr >> 16,
34533471
mCblk->server,
34543472
mCblk->user,
34553473
(int)mMainBuffer,
@@ -3794,7 +3812,7 @@ AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
37943812
if (mCblk != NULL) {
37953813
mCblk->flags |= CBLK_DIRECTION_OUT;
37963814
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
3797-
mCblk->volume[0] = mCblk->volume[1] = 0x1000;
3815+
mCblk->volumeLR = (MAX_GAIN_INT << 16) | MAX_GAIN_INT;
37983816
mOutBuffer.frameCount = 0;
37993817
playbackThread->mTracks.add(this);
38003818
ALOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, " \

0 commit comments

Comments
 (0)