blob: 587077a0ef4d7021fcc9486e0520b1e620872417 [file] [log] [blame]
#include "SineSource.h"
#include <math.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
namespace android {
SineSource::SineSource(int32_t sampleRate, int32_t numChannels)
: mStarted(false),
mSampleRate(sampleRate),
mNumChannels(numChannels),
mPhase(0),
mGroup(NULL) {
CHECK(numChannels == 1 || numChannels == 2);
}
SineSource::~SineSource() {
if (mStarted) {
stop();
}
}
status_t SineSource::start(MetaData * /* params */) {
CHECK(!mStarted);
mGroup = new MediaBufferGroup;
mGroup->add_buffer(new MediaBuffer(kBufferSize));
mPhase = 0;
mStarted = true;
return OK;
}
status_t SineSource::stop() {
CHECK(mStarted);
delete mGroup;
mGroup = NULL;
mStarted = false;
return OK;
}
sp<MetaData> SineSource::getFormat() {
sp<MetaData> meta = new MetaData;
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
meta->setInt32(kKeyChannelCount, mNumChannels);
meta->setInt32(kKeySampleRate, mSampleRate);
meta->setInt32(kKeyMaxInputSize, kBufferSize);
return meta;
}
status_t SineSource::read(
MediaBuffer **out, const ReadOptions * /* options */) {
*out = NULL;
MediaBuffer *buffer;
status_t err = mGroup->acquire_buffer(&buffer);
if (err != OK) {
return err;
}
size_t frameSize = mNumChannels * sizeof(int16_t);
size_t numFramesPerBuffer = buffer->size() / frameSize;
int16_t *ptr = (int16_t *)buffer->data();
const double k = kFrequency / mSampleRate * (2.0 * M_PI);
double x = mPhase * k;
for (size_t i = 0; i < numFramesPerBuffer; ++i) {
int16_t amplitude = (int16_t)(32767.0 * sin(x));
*ptr++ = amplitude;
if (mNumChannels == 2) {
*ptr++ = amplitude;
}
x += k;
}
buffer->meta_data()->setInt64(
kKeyTime, ((int64_t)mPhase * 1000000) / mSampleRate);
mPhase += numFramesPerBuffer;
buffer->set_range(0, numFramesPerBuffer * frameSize);
*out = buffer;
return OK;
}
} // namespace android