1#include "SineSource.h" 2 3#include <math.h> 4 5#include <media/stagefright/MediaBufferGroup.h> 6#include <media/stagefright/foundation/ADebug.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 meta->setInt32(kKeyMaxInputSize, kBufferSize); 56 57 return meta; 58} 59 60status_t SineSource::read( 61 MediaBuffer **out, const ReadOptions * /* options */) { 62 *out = NULL; 63 64 MediaBuffer *buffer; 65 status_t err = mGroup->acquire_buffer(&buffer); 66 67 if (err != OK) { 68 return err; 69 } 70 71 size_t frameSize = mNumChannels * sizeof(int16_t); 72 size_t numFramesPerBuffer = buffer->size() / frameSize; 73 74 int16_t *ptr = (int16_t *)buffer->data(); 75 76 const double k = kFrequency / mSampleRate * (2.0 * M_PI); 77 78 double x = mPhase * k; 79 for (size_t i = 0; i < numFramesPerBuffer; ++i) { 80 int16_t amplitude = (int16_t)(32767.0 * sin(x)); 81 82 *ptr++ = amplitude; 83 if (mNumChannels == 2) { 84 *ptr++ = amplitude; 85 } 86 87 x += k; 88 } 89 90 buffer->meta_data()->setInt64( 91 kKeyTime, ((int64_t)mPhase * 1000000) / mSampleRate); 92 93 mPhase += numFramesPerBuffer; 94 95 buffer->set_range(0, numFramesPerBuffer * frameSize); 96 97 *out = buffer; 98 99 return OK; 100} 101 102} // namespace android 103