/*
 * Copyright (C) 2014 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_NDEBUG 0
#define LOG_TAG "audioloop"
#include <utils/Log.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <utils/String16.h>

#include <binder/ProcessState.h>
#include <media/mediarecorder.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/AMRWriter.h>
#include <media/stagefright/AudioSource.h>
#include <media/stagefright/MediaCodecSource.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/SimpleDecodingSource.h>
#include "AudioPlayer.h"
#include "SineSource.h"

using namespace android;

static void usage(const char* name)
{
    fprintf(stderr, "Usage: %s [-d du.ration] [-m] [-w] [-N name] [<output-file>]\n", name);
    fprintf(stderr, "Encodes either a sine wave or microphone input to AMR format\n");
    fprintf(stderr, "    -d    duration in seconds, default 5 seconds\n");
    fprintf(stderr, "    -m    use microphone for input, default sine source\n");
    fprintf(stderr, "    -w    use AMR wideband (default narrowband)\n");
    fprintf(stderr, "    -N    name of the encoder; must be set with -M\n");
    fprintf(stderr, "    -M    media type of the encoder; must be set with -N\n");
    fprintf(stderr, "    <output-file> output file for AMR encoding,"
            " if unspecified, decode to speaker.\n");
}

int main(int argc, char* argv[])
{
    static const int channels = 1; // not permitted to be stereo now
    unsigned duration = 5;
    bool useMic = false;
    bool outputWBAMR = false;
    bool playToSpeaker = true;
    const char* fileOut = NULL;
    AString name;
    AString mediaType;
    int ch;
    while ((ch = getopt(argc, argv, "d:mwN:M:")) != -1) {
        switch (ch) {
        case 'd':
            duration = atoi(optarg);
            break;
        case 'm':
            useMic = true;
            break;
        case 'w':
            outputWBAMR = true;
            break;
        case 'N':
            name.setTo(optarg);
            break;
        case 'M':
            mediaType.setTo(optarg);
            break;
        default:
            usage(argv[0]);
            return -1;
        }
    }
    argc -= optind;
    argv += optind;
    if (argc == 1) {
        fileOut = argv[0];
    }
    if ((name.empty() && !mediaType.empty()) || (!name.empty() && mediaType.empty())) {
        fprintf(stderr, "-N and -M must be set together\n");
        usage(argv[0]);
        return -1;
    }
    if (!name.empty() && fileOut != NULL) {
        fprintf(stderr, "-N and -M cannot be used with <output file>\n");
        usage(argv[0]);
        return -1;
    }
    int32_t sampleRate = !name.empty() ? 44100 : outputWBAMR ? 16000 : 8000;
    int32_t bitRate = sampleRate;

    android::ProcessState::self()->startThreadPool();
    sp<MediaSource> source;

    if (useMic) {
        // talk into the appropriate microphone for the duration
        audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
        attr.source = AUDIO_SOURCE_MIC;

        source = new AudioSource(
                &attr,
                String16(),
                sampleRate,
                channels);
    } else {
        // use a sine source at 500 hz.
        source = new SineSource(sampleRate, channels);
    }

    sp<AMessage> meta = new AMessage;
    if (name.empty()) {
        meta->setString(
                "mime",
                outputWBAMR ? MEDIA_MIMETYPE_AUDIO_AMR_WB
                        : MEDIA_MIMETYPE_AUDIO_AMR_NB);
    } else {
        meta->setString("mime", mediaType);
        meta->setString("testing-name", name);
    }

    meta->setInt32("channel-count", channels);
    meta->setInt32("sample-rate", sampleRate);
    meta->setInt32("bitrate", bitRate);
    int32_t maxInputSize;
    if (source->getFormat()->findInt32(kKeyMaxInputSize, &maxInputSize)) {
        meta->setInt32("max-input-size", maxInputSize);
    }

    sp<ALooper> looper = new ALooper;
    looper->setName("audioloop");
    looper->start();

    sp<MediaSource> encoder = MediaCodecSource::Create(looper, meta, source);

    if (fileOut != NULL) {
        // target file specified, write encoded AMR output
        int fd = open(fileOut, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
        if (fd < 0) {
            return 1;
        }
        sp<AMRWriter> writer = new AMRWriter(fd);
        close(fd);
        writer->addSource(encoder);
        writer->start();
        sleep(duration);
        writer->stop();
    } else {
        // otherwise decode to speaker
        sp<MediaSource> decoder = SimpleDecodingSource::Create(encoder);

        if (playToSpeaker) {
            AudioPlayer player(NULL);
            player.setSource(decoder);
            player.start();
            sleep(duration);

ALOGI("Line: %d", __LINE__);
            decoder.clear(); // must clear |decoder| otherwise delete player will hang.
ALOGI("Line: %d", __LINE__);
        } else {
            CHECK_EQ(decoder->start(), (status_t)OK);
            MediaBufferBase* buffer;
            while (decoder->read(&buffer) == OK) {
                // do something with buffer (save it eventually?)
                // need to stop after some count though...
                putchar('.');
                fflush(stdout);
                buffer->release();
                buffer = NULL;
            }
            CHECK_EQ(decoder->stop(), (status_t)OK);
        }
ALOGI("Line: %d", __LINE__);
    }

    return 0;
}
