Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88592ecc authored by Glenn Kasten's avatar Glenn Kasten Committed by Android (Google) Code Review
Browse files

Merge "Remove the notion of "active track" from mixer"

parents a2a0a5d7 9c56d4ae
Loading
Loading
Loading
Loading
+19 −13
Original line number Diff line number Diff line
@@ -2102,12 +2102,13 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
        sp<Track> t = activeTracks[i].promote();
        if (t == 0) continue;

        // this const just means the local variable doesn't change
        Track* const track = t.get();
        audio_track_cblk_t* cblk = track->cblk();

        // The first time a track is added we wait
        // for all its buffers to be filled before processing it
        mAudioMixer->setActiveTrack(track->name());
        int name = track->name();
        // make sure that we have enough frames to mix one full buffer.
        // enforce this condition only once to enable draining the buffer in case the client
        // app does not call stop() and relies on underrun to stop:
@@ -2133,7 +2134,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
        if ((cblk->framesReady() >= minFrames) && track->isReady() &&
                !track->isPaused() && !track->isTerminated())
        {
            //ALOGV("track %d u=%08x, s=%08x [OK] on thread %p", track->name(), cblk->user, cblk->server, this);
            //ALOGV("track %d u=%08x, s=%08x [OK] on thread %p", name, cblk->user, cblk->server, this);

            mixedTracks++;

@@ -2146,8 +2147,8 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
                if (chain != 0) {
                    tracksWithEffect++;
                } else {
                    LOGW("prepareTracks_l(): track %08x attached to effect but no chain found on session %d",
                            track->name(), track->sessionId());
                    LOGW("prepareTracks_l(): track %d attached to effect but no chain found on session %d",
                            name, track->sessionId());
                }
            }

@@ -2160,7 +2161,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
                    track->mState = TrackBase::ACTIVE;
                    param = AudioMixer::RAMP_VOLUME;
                }
                mAudioMixer->setParameter(AudioMixer::RESAMPLE, AudioMixer::RESET, NULL);
                mAudioMixer->setParameter(name, AudioMixer::RESAMPLE, AudioMixer::RESET, NULL);
            } else if (cblk->server != 0) {
                // If the track is stopped before the first frame was mixed,
                // do not apply ramp
@@ -2212,26 +2213,31 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
            aux = int16_t(va);

            // XXX: these things DON'T need to be done each time
            mAudioMixer->setBufferProvider(track);
            mAudioMixer->enable();
            mAudioMixer->setBufferProvider(name, track);
            mAudioMixer->enable(name);

            mAudioMixer->setParameter(param, AudioMixer::VOLUME0, (void *)left);
            mAudioMixer->setParameter(param, AudioMixer::VOLUME1, (void *)right);
            mAudioMixer->setParameter(param, AudioMixer::AUXLEVEL, (void *)aux);
            mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, (void *)left);
            mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, (void *)right);
            mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, (void *)aux);
            mAudioMixer->setParameter(
                name,
                AudioMixer::TRACK,
                AudioMixer::FORMAT, (void *)track->format());
            mAudioMixer->setParameter(
                name,
                AudioMixer::TRACK,
                AudioMixer::CHANNEL_MASK, (void *)track->channelMask());
            mAudioMixer->setParameter(
                name,
                AudioMixer::RESAMPLE,
                AudioMixer::SAMPLE_RATE,
                (void *)(cblk->sampleRate));
            mAudioMixer->setParameter(
                name,
                AudioMixer::TRACK,
                AudioMixer::MAIN_BUFFER, (void *)track->mainBuffer());
            mAudioMixer->setParameter(
                name,
                AudioMixer::TRACK,
                AudioMixer::AUX_BUFFER, (void *)track->auxBuffer());

@@ -2239,7 +2245,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
            track->mRetryCount = kMaxTrackRetries;
            mixerStatus = MIXER_TRACKS_READY;
        } else {
            //ALOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", track->name(), cblk->user, cblk->server, this);
            //ALOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", name, cblk->user, cblk->server, this);
            if (track->isStopped()) {
                track->reset();
            }
@@ -2251,7 +2257,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
                // No buffers for this track. Give it a few chances to
                // fill a buffer, then remove it from active list.
                if (--(track->mRetryCount) <= 0) {
                    ALOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", track->name(), this);
                    ALOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", name, this);
                    tracksToRemove->add(track);
                    // indicate to client process that the track was disabled because of underrun
                    android_atomic_or(CBLK_DISABLED_ON, &cblk->flags);
@@ -2259,7 +2265,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
                    mixerStatus = MIXER_TRACKS_ENABLED;
                }
            }
            mAudioMixer->disable();
            mAudioMixer->disable(name);
        }
    }

+63 −61
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ namespace android {
// ----------------------------------------------------------------------------

AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate)
    :   mActiveTrack(0), mTrackNames(0), mSampleRate(sampleRate)
    :   mTrackNames(0), mSampleRate(sampleRate)
{
    // AudioMixer is not yet capable of multi-channel beyond stereo
    assert(2 == MAX_NUM_CHANNELS);
@@ -140,120 +140,120 @@ void AudioMixer::deleteTrackName(int name)
    mTrackNames &= ~(1<<name);
}

void AudioMixer::enable()
void AudioMixer::enable(int name)
{
    if (mState.tracks[ mActiveTrack ].enabled != 1) {
        mState.tracks[ mActiveTrack ].enabled = 1;
        ALOGV("enable(%d)", mActiveTrack);
        invalidateState(1<<mActiveTrack);
    name -= TRACK0;
    assert(uint32_t(name) < MAX_NUM_TRACKS);
    track_t& track = mState.tracks[name];

    if (track.enabled != 1) {
        track.enabled = 1;
        ALOGV("enable(%d)", name);
        invalidateState(1 << name);
    }
}

void AudioMixer::disable()
void AudioMixer::disable(int name)
{
    if (mState.tracks[ mActiveTrack ].enabled != 0) {
        mState.tracks[ mActiveTrack ].enabled = 0;
        ALOGV("disable(%d)", mActiveTrack);
        invalidateState(1<<mActiveTrack);
    name -= TRACK0;
    assert(uint32_t(name) < MAX_NUM_TRACKS);
    track_t& track = mState.tracks[name];

    if (track.enabled != 0) {
        track.enabled = 0;
        ALOGV("disable(%d)", name);
        invalidateState(1 << name);
    }
}

void AudioMixer::setActiveTrack(int track)
void AudioMixer::setParameter(int name, int target, int param, void *value)
{
    // this also catches track < TRACK0
    track -= TRACK0;
    assert(uint32_t(track) < MAX_NUM_TRACKS);
    mActiveTrack = track;
}
    name -= TRACK0;
    assert(uint32_t(name) < MAX_NUM_TRACKS);
    track_t& track = mState.tracks[name];

void AudioMixer::setParameter(int target, int name, void *value)
{
    int valueInt = (int)value;
    int32_t *valueBuf = (int32_t *)value;

    switch (target) {

    case TRACK:
        switch (name) {
        switch (param) {
        case CHANNEL_MASK: {
            uint32_t mask = (uint32_t)value;
            if (mState.tracks[ mActiveTrack ].channelMask != mask) {
            if (track.channelMask != mask) {
                uint8_t channelCount = popcount(mask);
                assert((channelCount <= MAX_NUM_CHANNELS) && (channelCount));
                mState.tracks[ mActiveTrack ].channelMask = mask;
                mState.tracks[ mActiveTrack ].channelCount = channelCount;
                track.channelMask = mask;
                track.channelCount = channelCount;
                ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
                invalidateState(1<<mActiveTrack);
                invalidateState(1 << name);
            }
            } break;
        case MAIN_BUFFER:
            if (mState.tracks[ mActiveTrack ].mainBuffer != valueBuf) {
                mState.tracks[ mActiveTrack ].mainBuffer = valueBuf;
            if (track.mainBuffer != valueBuf) {
                track.mainBuffer = valueBuf;
                ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
                invalidateState(1<<mActiveTrack);
                invalidateState(1 << name);
            }
            break;
        case AUX_BUFFER:
            if (mState.tracks[ mActiveTrack ].auxBuffer != valueBuf) {
                mState.tracks[ mActiveTrack ].auxBuffer = valueBuf;
            if (track.auxBuffer != valueBuf) {
                track.auxBuffer = valueBuf;
                ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
                invalidateState(1<<mActiveTrack);
                invalidateState(1 << name);
            }
            break;
        default:
            // bad name
            // bad param
            assert(false);
        }
        break;

    case RESAMPLE:
        switch (name) {
        case SAMPLE_RATE: {
        switch (param) {
        case SAMPLE_RATE:
            assert(valueInt > 0);
            track_t& track = mState.tracks[ mActiveTrack ];
            if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
                ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
                        uint32_t(valueInt));
                invalidateState(1<<mActiveTrack);
                invalidateState(1 << name);
            }
            } break;
        case RESET: {
            track_t& track = mState.tracks[ mActiveTrack ];
            break;
        case RESET:
            track.resetResampler();
            invalidateState(1<<mActiveTrack);
            } break;
            invalidateState(1 << name);
            break;
        default:
            // bad name
            // bad param
            assert(false);
        }
        break;

    case RAMP_VOLUME:
    case VOLUME:
        switch (name) {
        switch (param) {
        case VOLUME0:
        case VOLUME1: {
            track_t& track = mState.tracks[ mActiveTrack ];
            if (track.volume[name-VOLUME0] != valueInt) {
        case VOLUME1:
            if (track.volume[param-VOLUME0] != valueInt) {
                ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
                track.prevVolume[name-VOLUME0] = track.volume[name-VOLUME0] << 16;
                track.volume[name-VOLUME0] = valueInt;
                track.prevVolume[param-VOLUME0] = track.volume[param-VOLUME0] << 16;
                track.volume[param-VOLUME0] = valueInt;
                if (target == VOLUME) {
                    track.prevVolume[name-VOLUME0] = valueInt << 16;
                    track.volumeInc[name-VOLUME0] = 0;
                    track.prevVolume[param-VOLUME0] = valueInt << 16;
                    track.volumeInc[param-VOLUME0] = 0;
                } else {
                    int32_t d = (valueInt<<16) - track.prevVolume[name-VOLUME0];
                    int32_t d = (valueInt<<16) - track.prevVolume[param-VOLUME0];
                    int32_t volInc = d / int32_t(mState.frameCount);
                    track.volumeInc[name-VOLUME0] = volInc;
                    track.volumeInc[param-VOLUME0] = volInc;
                    if (volInc == 0) {
                        track.prevVolume[name-VOLUME0] = valueInt << 16;
                        track.prevVolume[param-VOLUME0] = valueInt << 16;
                    }
                }
                invalidateState(1<<mActiveTrack);
                invalidateState(1 << name);
            }
            } break;
        case AUXLEVEL: {
            track_t& track = mState.tracks[ mActiveTrack ];
            break;
        case AUXLEVEL:
            if (track.auxLevel != valueInt) {
                ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
                track.prevAuxLevel = track.auxLevel << 16;
@@ -269,11 +269,11 @@ void AudioMixer::setParameter(int target, int name, void *value)
                        track.prevAuxLevel = valueInt << 16;
                    }
                }
                invalidateState(1<<mActiveTrack);
                invalidateState(1 << name);
            }
            } break;
            break;
        default:
            // bad name
            // bad param
            assert(false);
        }
        break;
@@ -348,9 +348,11 @@ size_t AudioMixer::getUnreleasedFrames(int name)
    return 0;
}

void AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
void AudioMixer::setBufferProvider(int name, AudioBufferProvider* buffer)
{
    mState.tracks[ mActiveTrack ].bufferProvider = buffer;
    name -= TRACK0;
    assert(uint32_t(name) < MAX_NUM_TRACKS);
    mState.tracks[name].bufferProvider = buffer;
}


+7 −7
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ public:

    enum { // names

        // track units (MAX_NUM_TRACKS units)
        // track names (MAX_NUM_TRACKS units)
        TRACK0          = 0x1000,

        // 0x2000 is unused
@@ -69,16 +69,16 @@ public:
    };


    // For all APIs with "name": TRACK0 <= name < TRACK0 + MAX_NUM_TRACKS
    int         getTrackName();
    void        deleteTrackName(int name);

    void        enable();
    void        disable();
    void        enable(int name);
    void        disable(int name);

    void        setActiveTrack(int track);
    void        setParameter(int target, int name, void *value);
    void        setParameter(int name, int target, int param, void *value);

    void        setBufferProvider(AudioBufferProvider* bufferProvider);
    void        setBufferProvider(int name, AudioBufferProvider* bufferProvider);
    void        process();

    uint32_t    trackNames() const { return mTrackNames; }
@@ -171,7 +171,7 @@ private:
        track_t         tracks[MAX_NUM_TRACKS]; __attribute__((aligned(32)));
    };

    int             mActiveTrack;
    // bitmask of allocated track names, where bit 0 corresponds to TRACK0 etc.
    uint32_t        mTrackNames;
    const uint32_t  mSampleRate;