xref: /aosp_15_r20/external/skia/tools/viewer/AudioSlide.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2020 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkData.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "modules/audioplayer/SkAudioPlayer.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkUtils.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "tools/Resources.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "tools/viewer/ClickHandlerSlide.h"
14*c8dee2aaSAndroid Build Coastguard Worker 
15*c8dee2aaSAndroid Build Coastguard Worker class AudioSlide : public ClickHandlerSlide {
16*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<SkAudioPlayer> fPlayer;
17*c8dee2aaSAndroid Build Coastguard Worker     SkRect                         fBar;
18*c8dee2aaSAndroid Build Coastguard Worker 
19*c8dee2aaSAndroid Build Coastguard Worker public:
AudioSlide()20*c8dee2aaSAndroid Build Coastguard Worker     AudioSlide() { fName = "Audio"; }
21*c8dee2aaSAndroid Build Coastguard Worker 
load(SkScalar w,SkScalar h)22*c8dee2aaSAndroid Build Coastguard Worker     void load(SkScalar w, SkScalar h) override {
23*c8dee2aaSAndroid Build Coastguard Worker         auto data = SkData::MakeFromFileName("/Users/reed/skia/mp3/scott-joplin-peacherine-rag.mp3");
24*c8dee2aaSAndroid Build Coastguard Worker         if (data) {
25*c8dee2aaSAndroid Build Coastguard Worker             fPlayer = SkAudioPlayer::Make(data);
26*c8dee2aaSAndroid Build Coastguard Worker 
27*c8dee2aaSAndroid Build Coastguard Worker             SkDebugf("make: dur:%g time%g state:%d",
28*c8dee2aaSAndroid Build Coastguard Worker                      fPlayer->duration(),
29*c8dee2aaSAndroid Build Coastguard Worker                      fPlayer->time(),
30*c8dee2aaSAndroid Build Coastguard Worker                      (int)fPlayer->state());
31*c8dee2aaSAndroid Build Coastguard Worker         }
32*c8dee2aaSAndroid Build Coastguard Worker 
33*c8dee2aaSAndroid Build Coastguard Worker         fBar = { 10, 10, 510, 30 };
34*c8dee2aaSAndroid Build Coastguard Worker     }
35*c8dee2aaSAndroid Build Coastguard Worker 
draw(SkCanvas * canvas)36*c8dee2aaSAndroid Build Coastguard Worker     void draw(SkCanvas* canvas) override {
37*c8dee2aaSAndroid Build Coastguard Worker         if (!fPlayer) {
38*c8dee2aaSAndroid Build Coastguard Worker             return;
39*c8dee2aaSAndroid Build Coastguard Worker         }
40*c8dee2aaSAndroid Build Coastguard Worker 
41*c8dee2aaSAndroid Build Coastguard Worker         SkPaint p;
42*c8dee2aaSAndroid Build Coastguard Worker         p.setColor(0xFFCCCCCC);
43*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawRect(fBar, p);
44*c8dee2aaSAndroid Build Coastguard Worker 
45*c8dee2aaSAndroid Build Coastguard Worker         p.setColor(fPlayer->isPlaying() ? SK_ColorBLUE : 0xFF8888FF);
46*c8dee2aaSAndroid Build Coastguard Worker         SkRect r = fBar;
47*c8dee2aaSAndroid Build Coastguard Worker         r.fRight = r.fLeft + (float)fPlayer->normalizedTime() * r.width();
48*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawRect(r, p);
49*c8dee2aaSAndroid Build Coastguard Worker     }
50*c8dee2aaSAndroid Build Coastguard Worker 
onChar(SkUnichar c)51*c8dee2aaSAndroid Build Coastguard Worker     bool onChar(SkUnichar c) override {
52*c8dee2aaSAndroid Build Coastguard Worker         if (c == ' ') {
53*c8dee2aaSAndroid Build Coastguard Worker             switch (fPlayer->state()) {
54*c8dee2aaSAndroid Build Coastguard Worker                 case SkAudioPlayer::State::kPlaying: fPlayer->pause(); break;
55*c8dee2aaSAndroid Build Coastguard Worker                 case SkAudioPlayer::State::kPaused:  fPlayer->play(); break;
56*c8dee2aaSAndroid Build Coastguard Worker                 case SkAudioPlayer::State::kStopped: fPlayer->play(); break;
57*c8dee2aaSAndroid Build Coastguard Worker             }
58*c8dee2aaSAndroid Build Coastguard Worker             return true;
59*c8dee2aaSAndroid Build Coastguard Worker         }
60*c8dee2aaSAndroid Build Coastguard Worker         return this->ClickHandlerSlide::onChar(c);
61*c8dee2aaSAndroid Build Coastguard Worker     }
62*c8dee2aaSAndroid Build Coastguard Worker 
onFindClickHandler(SkScalar x,SkScalar y,skui::ModifierKey)63*c8dee2aaSAndroid Build Coastguard Worker     Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override {
64*c8dee2aaSAndroid Build Coastguard Worker         if (fPlayer && fBar.contains(x, y)) {
65*c8dee2aaSAndroid Build Coastguard Worker             bool wasPlaying = fPlayer->isPlaying();
66*c8dee2aaSAndroid Build Coastguard Worker             if (wasPlaying) {
67*c8dee2aaSAndroid Build Coastguard Worker                 fPlayer->pause();
68*c8dee2aaSAndroid Build Coastguard Worker             }
69*c8dee2aaSAndroid Build Coastguard Worker             return new Click([this, wasPlaying](Click* click) {
70*c8dee2aaSAndroid Build Coastguard Worker                 if (fBar.contains(click->fCurr.fX, click->fCurr.fY)) {
71*c8dee2aaSAndroid Build Coastguard Worker                     fPlayer->setNormalizedTime((click->fCurr.fX - fBar.fLeft) / fBar.width());
72*c8dee2aaSAndroid Build Coastguard Worker                 }
73*c8dee2aaSAndroid Build Coastguard Worker 
74*c8dee2aaSAndroid Build Coastguard Worker                 if (click->fState == skui::InputState::kUp) {
75*c8dee2aaSAndroid Build Coastguard Worker                     if (wasPlaying) {
76*c8dee2aaSAndroid Build Coastguard Worker                         fPlayer->play();
77*c8dee2aaSAndroid Build Coastguard Worker                     }
78*c8dee2aaSAndroid Build Coastguard Worker                 }
79*c8dee2aaSAndroid Build Coastguard Worker                 return true;
80*c8dee2aaSAndroid Build Coastguard Worker             });
81*c8dee2aaSAndroid Build Coastguard Worker         }
82*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
83*c8dee2aaSAndroid Build Coastguard Worker     }
84*c8dee2aaSAndroid Build Coastguard Worker 
onClick(ClickHandlerSlide::Click *)85*c8dee2aaSAndroid Build Coastguard Worker     bool onClick(ClickHandlerSlide::Click*) override { return false; }
86*c8dee2aaSAndroid Build Coastguard Worker 
animate(double)87*c8dee2aaSAndroid Build Coastguard Worker     bool animate(double /*nanos*/) override {
88*c8dee2aaSAndroid Build Coastguard Worker         return true;
89*c8dee2aaSAndroid Build Coastguard Worker     }
90*c8dee2aaSAndroid Build Coastguard Worker 
91*c8dee2aaSAndroid Build Coastguard Worker };
92*c8dee2aaSAndroid Build Coastguard Worker 
93*c8dee2aaSAndroid Build Coastguard Worker DEF_SLIDE( return new AudioSlide; )
94