/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "AAudioMixer"
//#define LOG_NDEBUG 0
#include <utils/Log.h>

#define ATRACE_TAG ATRACE_TAG_AUDIO

#include <cstring>
#include <utils/Trace.h>

#include "AAudioMixer.h"

#ifndef AAUDIO_MIXER_ATRACE_ENABLED
#define AAUDIO_MIXER_ATRACE_ENABLED    1
#endif

using android::WrappingBuffer;
using android::FifoBuffer;
using android::fifo_frames_t;

void AAudioMixer::allocate(int32_t samplesPerFrame, int32_t framesPerBurst) {
    mSamplesPerFrame = samplesPerFrame;
    mFramesPerBurst = framesPerBurst;
    int32_t samplesPerBuffer = samplesPerFrame * framesPerBurst;
    mOutputBuffer = std::make_unique<float[]>(samplesPerBuffer);
    mBufferSizeInBytes = samplesPerBuffer * sizeof(float);
}

void AAudioMixer::clear() {
    memset(mOutputBuffer.get(), 0, mBufferSizeInBytes);
}

int32_t AAudioMixer::mix(int streamIndex, std::shared_ptr<FifoBuffer> fifo, bool allowUnderflow) {
    WrappingBuffer wrappingBuffer;
    float *destination = mOutputBuffer.get();

#if AAUDIO_MIXER_ATRACE_ENABLED
    ATRACE_BEGIN("aaMix");
#endif /* AAUDIO_MIXER_ATRACE_ENABLED */

    // Gather the data from the client. May be in two parts.
    fifo_frames_t fullFrames = fifo->getFullDataAvailable(&wrappingBuffer);
#if AAUDIO_MIXER_ATRACE_ENABLED
    if (ATRACE_ENABLED()) {
        char rdyText[] = "aaMixRdy#";
        char letter = 'A' + (streamIndex % 26);
        rdyText[sizeof(rdyText) - 2] = letter;
        ATRACE_INT(rdyText, fullFrames);
    }
#else /* MIXER_ATRACE_ENABLED */
    (void) trackIndex;
#endif /* AAUDIO_MIXER_ATRACE_ENABLED */

    // If allowUnderflow then always advance by one burst even if we do not have the data.
    // Otherwise the stream timing will drift whenever there is an underflow.
    // This actual underflow can then be detected by the client for XRun counting.
    //
    // Generally, allowUnderflow will be false when stopping a stream and we want to
    // use up whatever data is in the queue.
    fifo_frames_t framesDesired = mFramesPerBurst;
    if (!allowUnderflow && fullFrames < framesDesired) {
        framesDesired = fullFrames; // just use what is available then stop
    }

    // Mix data in one or two parts.
    int partIndex = 0;
    int32_t framesLeft = framesDesired;
    while (framesLeft > 0 && partIndex < WrappingBuffer::SIZE) {
        fifo_frames_t framesToMixFromPart = framesLeft;
        fifo_frames_t framesAvailableFromPart = wrappingBuffer.numFrames[partIndex];
        if (framesAvailableFromPart > 0) {
            if (framesToMixFromPart > framesAvailableFromPart) {
                framesToMixFromPart = framesAvailableFromPart;
            }
            mixPart(destination, (float *)wrappingBuffer.data[partIndex],
                    framesToMixFromPart);

            destination += framesToMixFromPart * mSamplesPerFrame;
            framesLeft -= framesToMixFromPart;
        }
        partIndex++;
    }
    fifo->advanceReadIndex(framesDesired);

#if AAUDIO_MIXER_ATRACE_ENABLED
    ATRACE_END();
#endif /* AAUDIO_MIXER_ATRACE_ENABLED */

    return (framesDesired - framesLeft); // framesRead
}

void AAudioMixer::mixPart(float *destination, float *source, int32_t numFrames) {
    int32_t numSamples = numFrames * mSamplesPerFrame;
    // TODO maybe optimize using SIMD
    for (int sampleIndex = 0; sampleIndex < numSamples; sampleIndex++) {
        *destination++ += *source++;
    }
}

float *AAudioMixer::getOutputBuffer() {
    return mOutputBuffer.get();
}
