1e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber#include "SineSource.h"
2e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
3e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber#include <math.h>
4e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
5e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber#include <media/stagefright/MediaBufferGroup.h>
6f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h>
8e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber#include <media/stagefright/MetaData.h>
9e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
10e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Hubernamespace android {
11e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
12e5adbeee3401915ff8e1a983396ce3554436b11cAndreas HuberSineSource::SineSource(int32_t sampleRate, int32_t numChannels)
13e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    : mStarted(false),
14e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber      mSampleRate(sampleRate),
15e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber      mNumChannels(numChannels),
16e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber      mPhase(0),
17e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber      mGroup(NULL) {
18e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK(numChannels == 1 || numChannels == 2);
19e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
20e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
21e5adbeee3401915ff8e1a983396ce3554436b11cAndreas HuberSineSource::~SineSource() {
22e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (mStarted) {
23e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        stop();
24e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
25e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
26e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
27e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huberstatus_t SineSource::start(MetaData *params) {
28e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK(!mStarted);
29e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
30e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    mGroup = new MediaBufferGroup;
31e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    mGroup->add_buffer(new MediaBuffer(kBufferSize));
32e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
33e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    mPhase = 0;
34e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    mStarted = true;
35e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
36e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    return OK;
37e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
38e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
39e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huberstatus_t SineSource::stop() {
40e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK(mStarted);
41e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
42e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    delete mGroup;
43e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    mGroup = NULL;
44e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
45e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    mStarted = false;
46e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
47e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    return OK;
48e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
49e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
50e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Hubersp<MetaData> SineSource::getFormat() {
51e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    sp<MetaData> meta = new MetaData;
5218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
53e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    meta->setInt32(kKeyChannelCount, mNumChannels);
54e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    meta->setInt32(kKeySampleRate, mSampleRate);
55c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    meta->setInt32(kKeyMaxInputSize, kBufferSize);
56e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
57e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    return meta;
58e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
59e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
60e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huberstatus_t SineSource::read(
61e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        MediaBuffer **out, const ReadOptions *options) {
62e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    *out = NULL;
63e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
64e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    MediaBuffer *buffer;
65e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    status_t err = mGroup->acquire_buffer(&buffer);
66e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
67e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (err != OK) {
68e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        return err;
69e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
70e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
71e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    size_t frameSize = mNumChannels * sizeof(int16_t);
72e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    size_t numFramesPerBuffer = buffer->size() / frameSize;
73e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
74e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    int16_t *ptr = (int16_t *)buffer->data();
75e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
76e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    const double k = kFrequency / mSampleRate * (2.0 * M_PI);
77e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
78e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    double x = mPhase * k;
79e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    for (size_t i = 0; i < numFramesPerBuffer; ++i) {
80e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        int16_t amplitude = (int16_t)(32767.0 * sin(x));
81e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
82e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        *ptr++ = amplitude;
83e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        if (mNumChannels == 2) {
84e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            *ptr++ = amplitude;
85e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        }
86e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
87e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        x += k;
88e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
89e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
9048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber    buffer->meta_data()->setInt64(
9148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber            kKeyTime, ((int64_t)mPhase * 1000000) / mSampleRate);
92e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
93e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    mPhase += numFramesPerBuffer;
94e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
95e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    buffer->set_range(0, numFramesPerBuffer * frameSize);
96e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
97e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    *out = buffer;
98e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
99e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    return OK;
100e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
101e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
102e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}  // namespace android
103