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
27ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas 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);
5678bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar    meta->setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit);
57e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
58e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    return meta;
59e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
60e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
61e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huberstatus_t SineSource::read(
62ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        MediaBuffer **out, const ReadOptions * /* options */) {
63e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    *out = NULL;
64e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
65e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    MediaBuffer *buffer;
66e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    status_t err = mGroup->acquire_buffer(&buffer);
67e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
68e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (err != OK) {
69e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        return err;
70e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
71e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
72e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    size_t frameSize = mNumChannels * sizeof(int16_t);
73e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    size_t numFramesPerBuffer = buffer->size() / frameSize;
74e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
75e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    int16_t *ptr = (int16_t *)buffer->data();
76e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
77e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    const double k = kFrequency / mSampleRate * (2.0 * M_PI);
78e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
79e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    double x = mPhase * k;
80e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    for (size_t i = 0; i < numFramesPerBuffer; ++i) {
81e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        int16_t amplitude = (int16_t)(32767.0 * sin(x));
82e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
83e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        *ptr++ = amplitude;
84e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        if (mNumChannels == 2) {
85e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            *ptr++ = amplitude;
86e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        }
87e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
88e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        x += k;
89e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
90e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
9148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber    buffer->meta_data()->setInt64(
9248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber            kKeyTime, ((int64_t)mPhase * 1000000) / mSampleRate);
93e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
94e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    mPhase += numFramesPerBuffer;
95e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
96e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    buffer->set_range(0, numFramesPerBuffer * frameSize);
97e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
98e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    *out = buffer;
99e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
100e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    return OK;
101e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
102e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
103e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}  // namespace android
104