@@ -72,7 +72,7 @@ static const char kHardwareLockedString[] = "Hardware lock is taken\n";
7272
7373// static const nsecs_t kStandbyTimeInNsecs = seconds(3);
7474static 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
34373454void 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