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