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