1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
#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
|