Skip to content

Commit f607dbb

Browse files
jbeta51Skia Commit-Bot
authored andcommitted
implement SkAudioPLayer for Android
move SkAudioPlayer for Android to proper module refine playback features for the Android AudioPlayer Change-Id: I1906c3b3ef91fa4173f66c2c068dc40a3cf824ca Reviewed-on: https://skia-review.googlesource.com/c/skia/+/319037 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Jorge Betancourt <jmbetancourt@google.com>
1 parent 1c50643 commit f607dbb

File tree

4 files changed

+126
-1
lines changed

4 files changed

+126
-1
lines changed

BUILD.gn

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2353,7 +2353,6 @@ if (skia_enable_tools) {
23532353
":skia",
23542354
"modules/skottie",
23552355
"modules/sksg:samples",
2356-
"//third_party/oboe",
23572356
]
23582357
}
23592358
}

modules/audioplayer/BUILD.gn

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ component("audioplayer") {
1919
"sfml-system",
2020
"sfml-audio",
2121
]
22+
} else if (is_android) {
23+
sources += [ "SkAudioPlayer_oboe.cpp" ]
24+
deps += [ "../../third_party/oboe" ]
25+
libs = [ "OpenSLES" ]
2226
} else {
2327
sources += [ "SkAudioPlayer_none.cpp" ]
2428
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright 2020 Google Inc.
3+
*
4+
* Use of this source code is governed by a BSD-style license that can be
5+
* found in the LICENSE file.
6+
*/
7+
8+
#include "modules/audioplayer/SkAudioPlayer.h"
9+
10+
#include "include/core/SkData.h"
11+
#include "oboe/Oboe.h"
12+
#include "stream/MemInputStream.h"
13+
#include "wav/WavStreamReader.h"
14+
15+
namespace {
16+
17+
class OboeAudioPlayer final : public SkAudioPlayer, oboe::AudioStreamCallback {
18+
public:
19+
explicit OboeAudioPlayer(sk_sp<SkData> data)
20+
: fData(std::move(data))
21+
, fMemInputStream(const_cast<unsigned char *>
22+
(static_cast<const unsigned char *>(fData->data())), static_cast<int32_t>(fData->size()))
23+
{
24+
// wrap data in MemInputStream to parse WAV header
25+
fReader = std::make_unique<parselib::WavStreamReader>(&fMemInputStream);
26+
fReader->parse();
27+
// set member variables and builder properties using reader
28+
fNumSampleFrames = fReader->getNumSampleFrames();
29+
30+
oboe::AudioStreamBuilder builder;
31+
builder.setPerformanceMode(oboe::PerformanceMode::LowLatency);
32+
builder.setSharingMode(oboe::SharingMode::Exclusive);
33+
builder.setSampleRate(fReader->getSampleRate());
34+
builder.setChannelCount(fReader->getNumChannels());
35+
builder.setCallback(this);
36+
builder.setFormat(oboe::AudioFormat::Float);
37+
38+
// open the stream (must manually close it when done)
39+
fStream = nullptr;
40+
builder.openStream(fStream);
41+
}
42+
43+
private:
44+
oboe::DataCallbackResult
45+
onAudioReady(oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames) override {
46+
// we assume float samples here
47+
float *outBuffer = static_cast<float *>(audioData);
48+
int framesRead = fReader->getDataFloat(outBuffer, numFrames);
49+
fReadFrameIndex += framesRead;
50+
int remainingFrames = numFrames - framesRead;
51+
if (remainingFrames > 0) {
52+
if (fIsLooping) {
53+
// handle wrap around
54+
fReader->positionToAudio();
55+
fReader->getDataFloat(&outBuffer[framesRead * fReader->getNumChannels()],
56+
remainingFrames);
57+
fReadFrameIndex += remainingFrames;
58+
} else {
59+
// render silence for rest
60+
renderSilence(&outBuffer[framesRead * fReader->getNumChannels()], remainingFrames);
61+
return oboe::DataCallbackResult::Stop;
62+
}
63+
}
64+
return oboe::DataCallbackResult::Continue;
65+
}
66+
67+
void renderSilence(float *start, int numFrames) {
68+
for (int i = 0; i < numFrames * fReader->getNumChannels(); ++i) {
69+
start[i] = 0;
70+
}
71+
}
72+
double onGetDuration() const override {
73+
return fNumSampleFrames * fStream->getChannelCount() / fStream->getSampleRate();
74+
}
75+
76+
double onGetTime() const override {
77+
return (fReadFrameIndex * fStream->getChannelCount()) / fStream->getSampleRate();
78+
}
79+
80+
double onSetTime(double t) override {
81+
fReadFrameIndex = (t * fStream->getSampleRate()) / fStream->getChannelCount();
82+
return onGetTime();
83+
}
84+
85+
State onSetState(State state) override {
86+
switch (state) {
87+
case State::kPlaying: fStream->start(); break;
88+
case State::kStopped: fStream->close(); break;
89+
case State::kPaused : fStream->pause(); break;
90+
}
91+
92+
return state;
93+
}
94+
95+
96+
// TODO: implement rate function (change sample rate of AudioStream)
97+
float onSetRate(float r) override {
98+
return r;
99+
}
100+
101+
// TODO: implement volume function (multiply each sample by desired amplitude)
102+
float onSetVolume(float v) override {
103+
return v;
104+
}
105+
106+
const sk_sp<SkData> fData;
107+
std::shared_ptr<oboe::AudioStream> fStream;
108+
std::unique_ptr<parselib::WavStreamReader> fReader;
109+
parselib::MemInputStream fMemInputStream;
110+
int32_t fReadFrameIndex {0};
111+
int fNumSampleFrames;
112+
bool fIsLooping {false};
113+
};
114+
115+
} // namespace
116+
117+
std::unique_ptr<SkAudioPlayer> SkAudioPlayer::Make(sk_sp<SkData> src) {
118+
return std::unique_ptr<SkAudioPlayer>(new OboeAudioPlayer(std::move(src)));
119+
}

third_party/oboe/BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ third_party("oboe") {
99
public_include_dirs = [
1010
"../externals/oboe/include",
1111
"../externals/oboe/samples/parselib/src/main/cpp",
12+
"../externals/oboe/src/flowgraph",
1213
]
1314
include_dirs = [ "../externals/oboe/src" ]
1415

@@ -43,10 +44,12 @@ third_party("oboe") {
4344
"../externals/oboe/src/fifo/FifoController.cpp",
4445
"../externals/oboe/src/fifo/FifoControllerBase.cpp",
4546
"../externals/oboe/src/fifo/FifoControllerIndirect.cpp",
47+
"../externals/oboe/src/flowgraph/ChannelCountConverter.cpp",
4648
"../externals/oboe/src/flowgraph/ClipToRange.cpp",
4749
"../externals/oboe/src/flowgraph/FlowGraphNode.cpp",
4850
"../externals/oboe/src/flowgraph/ManyToMultiConverter.cpp",
4951
"../externals/oboe/src/flowgraph/MonoToMultiConverter.cpp",
52+
"../externals/oboe/src/flowgraph/MultiToMonoConverter.cpp",
5053
"../externals/oboe/src/flowgraph/RampLinear.cpp",
5154
"../externals/oboe/src/flowgraph/SampleRateConverter.cpp",
5255
"../externals/oboe/src/flowgraph/SinkFloat.cpp",

0 commit comments

Comments
 (0)