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 "include/core/SkData.h" 9#include "modules/audioplayer/SkAudioPlayer.h" 10 11#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 12 13#ifdef SK_BUILD_FOR_MAC 14#include <AVFoundation/AVFoundation.h> 15#endif 16 17#ifdef SK_BUILD_FOR_IOS 18// ??? 19#endif 20 21class SkAudioPlayer_Mac : public SkAudioPlayer { 22public: 23 SkAudioPlayer_Mac(AVAudioPlayer* player, sk_sp<SkData> data) 24 : fPlayer(player) 25 , fData(std::move(data)) 26 { 27 fPlayer.enableRate = YES; 28 [fPlayer prepareToPlay]; 29 } 30 31 ~SkAudioPlayer_Mac() override { 32 // [fPlayer release]; 33 } 34 35 double onGetDuration() const override { return [fPlayer duration]; } 36 37 double onGetTime() const override { return fPlayer.currentTime; } 38 39 double onSetTime(double t) override { 40 bool wasPlaying = this->isPlaying(); 41 if (wasPlaying) { 42 [fPlayer pause]; 43 } 44 fPlayer.currentTime = t; 45 if (wasPlaying) { 46 [fPlayer play]; 47 } 48 return fPlayer.currentTime; 49 } 50 51 52 State onSetState(State state) override { 53 switch (state) { 54 case State::kPlaying: [fPlayer play]; break; 55 case State::kStopped: [fPlayer stop]; break; 56 case State::kPaused: [fPlayer pause]; break; 57 } 58 return state; 59 } 60 61 float onSetRate(float r) override { fPlayer.rate = r; return r; } 62 63 float onSetVolume(float v) override { fPlayer.volume = v; return v; } 64 65private: 66 AVAudioPlayer* fPlayer; 67 sk_sp<SkData> fData; // we hold this onbehalf of the player's NSData 68}; 69 70std::unique_ptr<SkAudioPlayer> SkAudioPlayer::Make(sk_sp<SkData> src) { 71 // The NSData does not own the actual buffer (src), but our subclass will 72 73 NSData* data = [[NSData alloc] initWithBytesNoCopy:(void*)src->data() length:src->size()]; 74 AVAudioPlayer* player = [[AVAudioPlayer alloc] initWithData:data error:nil]; 75 [data release]; 76 77 if (player) { 78 return std::unique_ptr<SkAudioPlayer>(new SkAudioPlayer_Mac(player, std::move(src))); 79 } 80 return nullptr; 81} 82 83#endif 84