1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker #include <media/TrackPlayerBase.h>
18*ec779b8eSAndroid Build Coastguard Worker
19*ec779b8eSAndroid Build Coastguard Worker namespace android {
20*ec779b8eSAndroid Build Coastguard Worker using aidl_utils::binderStatusFromStatusT;
21*ec779b8eSAndroid Build Coastguard Worker using media::VolumeShaper;
22*ec779b8eSAndroid Build Coastguard Worker
23*ec779b8eSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
TrackPlayerBase()24*ec779b8eSAndroid Build Coastguard Worker TrackPlayerBase::TrackPlayerBase() : PlayerBase(),
25*ec779b8eSAndroid Build Coastguard Worker mPlayerVolumeL(1.0f), mPlayerVolumeR(1.0f)
26*ec779b8eSAndroid Build Coastguard Worker {
27*ec779b8eSAndroid Build Coastguard Worker ALOGD("TrackPlayerBase::TrackPlayerBase()");
28*ec779b8eSAndroid Build Coastguard Worker }
29*ec779b8eSAndroid Build Coastguard Worker
30*ec779b8eSAndroid Build Coastguard Worker
~TrackPlayerBase()31*ec779b8eSAndroid Build Coastguard Worker TrackPlayerBase::~TrackPlayerBase() {
32*ec779b8eSAndroid Build Coastguard Worker ALOGD("TrackPlayerBase::~TrackPlayerBase()");
33*ec779b8eSAndroid Build Coastguard Worker doDestroy();
34*ec779b8eSAndroid Build Coastguard Worker }
35*ec779b8eSAndroid Build Coastguard Worker
init(const sp<AudioTrack> & pat,const sp<AudioTrack::IAudioTrackCallback> & callback,player_type_t playerType,audio_usage_t usage,audio_session_t sessionId)36*ec779b8eSAndroid Build Coastguard Worker void TrackPlayerBase::init(const sp<AudioTrack>& pat,
37*ec779b8eSAndroid Build Coastguard Worker const sp<AudioTrack::IAudioTrackCallback>& callback,
38*ec779b8eSAndroid Build Coastguard Worker player_type_t playerType, audio_usage_t usage,
39*ec779b8eSAndroid Build Coastguard Worker audio_session_t sessionId) {
40*ec779b8eSAndroid Build Coastguard Worker PlayerBase::init(playerType, usage, sessionId);
41*ec779b8eSAndroid Build Coastguard Worker mAudioTrack.store(pat);
42*ec779b8eSAndroid Build Coastguard Worker if (pat != 0) {
43*ec779b8eSAndroid Build Coastguard Worker mCallbackHandle = callback;
44*ec779b8eSAndroid Build Coastguard Worker mSelfAudioDeviceCallback = new SelfAudioDeviceCallback(*this);
45*ec779b8eSAndroid Build Coastguard Worker pat->addAudioDeviceCallback(mSelfAudioDeviceCallback);
46*ec779b8eSAndroid Build Coastguard Worker pat->setPlayerIId(mPIId); // set in PlayerBase::init().
47*ec779b8eSAndroid Build Coastguard Worker }
48*ec779b8eSAndroid Build Coastguard Worker }
49*ec779b8eSAndroid Build Coastguard Worker
destroy()50*ec779b8eSAndroid Build Coastguard Worker void TrackPlayerBase::destroy() {
51*ec779b8eSAndroid Build Coastguard Worker doDestroy();
52*ec779b8eSAndroid Build Coastguard Worker baseDestroy();
53*ec779b8eSAndroid Build Coastguard Worker }
54*ec779b8eSAndroid Build Coastguard Worker
SelfAudioDeviceCallback(PlayerBase & self)55*ec779b8eSAndroid Build Coastguard Worker TrackPlayerBase::SelfAudioDeviceCallback::SelfAudioDeviceCallback(PlayerBase& self) :
56*ec779b8eSAndroid Build Coastguard Worker AudioSystem::AudioDeviceCallback(), mSelf(self) {
57*ec779b8eSAndroid Build Coastguard Worker }
58*ec779b8eSAndroid Build Coastguard Worker
~SelfAudioDeviceCallback()59*ec779b8eSAndroid Build Coastguard Worker TrackPlayerBase::SelfAudioDeviceCallback::~SelfAudioDeviceCallback() {
60*ec779b8eSAndroid Build Coastguard Worker }
61*ec779b8eSAndroid Build Coastguard Worker
onAudioDeviceUpdate(audio_io_handle_t __unused,const DeviceIdVector & deviceIds)62*ec779b8eSAndroid Build Coastguard Worker void TrackPlayerBase::SelfAudioDeviceCallback::onAudioDeviceUpdate(audio_io_handle_t __unused,
63*ec779b8eSAndroid Build Coastguard Worker const DeviceIdVector& deviceIds) {
64*ec779b8eSAndroid Build Coastguard Worker mSelf.baseUpdateDeviceIds(deviceIds);
65*ec779b8eSAndroid Build Coastguard Worker }
66*ec779b8eSAndroid Build Coastguard Worker
doDestroy()67*ec779b8eSAndroid Build Coastguard Worker void TrackPlayerBase::doDestroy() {
68*ec779b8eSAndroid Build Coastguard Worker sp<AudioTrack> audioTrack = getAudioTrack();
69*ec779b8eSAndroid Build Coastguard Worker
70*ec779b8eSAndroid Build Coastguard Worker // Note that there may still be another reference in post-unlock phase of SetPlayState
71*ec779b8eSAndroid Build Coastguard Worker clearAudioTrack();
72*ec779b8eSAndroid Build Coastguard Worker
73*ec779b8eSAndroid Build Coastguard Worker if (audioTrack != 0) {
74*ec779b8eSAndroid Build Coastguard Worker audioTrack->stop();
75*ec779b8eSAndroid Build Coastguard Worker audioTrack->removeAudioDeviceCallback(mSelfAudioDeviceCallback);
76*ec779b8eSAndroid Build Coastguard Worker mSelfAudioDeviceCallback.clear();
77*ec779b8eSAndroid Build Coastguard Worker }
78*ec779b8eSAndroid Build Coastguard Worker }
79*ec779b8eSAndroid Build Coastguard Worker
setPlayerVolume(float vl,float vr)80*ec779b8eSAndroid Build Coastguard Worker void TrackPlayerBase::setPlayerVolume(float vl, float vr) {
81*ec779b8eSAndroid Build Coastguard Worker {
82*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mSettingsLock);
83*ec779b8eSAndroid Build Coastguard Worker mPlayerVolumeL = vl;
84*ec779b8eSAndroid Build Coastguard Worker mPlayerVolumeR = vr;
85*ec779b8eSAndroid Build Coastguard Worker }
86*ec779b8eSAndroid Build Coastguard Worker doSetVolume();
87*ec779b8eSAndroid Build Coastguard Worker }
88*ec779b8eSAndroid Build Coastguard Worker
89*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
90*ec779b8eSAndroid Build Coastguard Worker // Implementation of IPlayer
playerStart()91*ec779b8eSAndroid Build Coastguard Worker status_t TrackPlayerBase::playerStart() {
92*ec779b8eSAndroid Build Coastguard Worker status_t status = NO_INIT;
93*ec779b8eSAndroid Build Coastguard Worker if (sp<AudioTrack> audioTrack = getAudioTrack(); audioTrack != 0) {
94*ec779b8eSAndroid Build Coastguard Worker status = audioTrack->start();
95*ec779b8eSAndroid Build Coastguard Worker }
96*ec779b8eSAndroid Build Coastguard Worker return status;
97*ec779b8eSAndroid Build Coastguard Worker }
98*ec779b8eSAndroid Build Coastguard Worker
playerPause()99*ec779b8eSAndroid Build Coastguard Worker status_t TrackPlayerBase::playerPause() {
100*ec779b8eSAndroid Build Coastguard Worker status_t status = NO_INIT;
101*ec779b8eSAndroid Build Coastguard Worker if (sp<AudioTrack> audioTrack = getAudioTrack(); audioTrack != 0) {
102*ec779b8eSAndroid Build Coastguard Worker audioTrack->pause();
103*ec779b8eSAndroid Build Coastguard Worker status = NO_ERROR;
104*ec779b8eSAndroid Build Coastguard Worker }
105*ec779b8eSAndroid Build Coastguard Worker return status;
106*ec779b8eSAndroid Build Coastguard Worker }
107*ec779b8eSAndroid Build Coastguard Worker
108*ec779b8eSAndroid Build Coastguard Worker
playerStop()109*ec779b8eSAndroid Build Coastguard Worker status_t TrackPlayerBase::playerStop() {
110*ec779b8eSAndroid Build Coastguard Worker status_t status = NO_INIT;
111*ec779b8eSAndroid Build Coastguard Worker if (sp<AudioTrack> audioTrack = getAudioTrack(); audioTrack != 0) {
112*ec779b8eSAndroid Build Coastguard Worker audioTrack->stop();
113*ec779b8eSAndroid Build Coastguard Worker status = NO_ERROR;
114*ec779b8eSAndroid Build Coastguard Worker }
115*ec779b8eSAndroid Build Coastguard Worker return status;
116*ec779b8eSAndroid Build Coastguard Worker }
117*ec779b8eSAndroid Build Coastguard Worker
playerSetVolume()118*ec779b8eSAndroid Build Coastguard Worker status_t TrackPlayerBase::playerSetVolume() {
119*ec779b8eSAndroid Build Coastguard Worker return doSetVolume();
120*ec779b8eSAndroid Build Coastguard Worker }
121*ec779b8eSAndroid Build Coastguard Worker
doSetVolume()122*ec779b8eSAndroid Build Coastguard Worker status_t TrackPlayerBase::doSetVolume() {
123*ec779b8eSAndroid Build Coastguard Worker status_t status = NO_INIT;
124*ec779b8eSAndroid Build Coastguard Worker if (sp<AudioTrack> audioTrack = getAudioTrack(); audioTrack != 0) {
125*ec779b8eSAndroid Build Coastguard Worker float tl = mPlayerVolumeL * mPanMultiplierL * mVolumeMultiplierL;
126*ec779b8eSAndroid Build Coastguard Worker float tr = mPlayerVolumeR * mPanMultiplierR * mVolumeMultiplierR;
127*ec779b8eSAndroid Build Coastguard Worker audioTrack->setVolume(tl, tr);
128*ec779b8eSAndroid Build Coastguard Worker status = NO_ERROR;
129*ec779b8eSAndroid Build Coastguard Worker }
130*ec779b8eSAndroid Build Coastguard Worker return status;
131*ec779b8eSAndroid Build Coastguard Worker }
132*ec779b8eSAndroid Build Coastguard Worker
133*ec779b8eSAndroid Build Coastguard Worker
applyVolumeShaper(const media::VolumeShaperConfiguration & configuration,const media::VolumeShaperOperation & operation)134*ec779b8eSAndroid Build Coastguard Worker binder::Status TrackPlayerBase::applyVolumeShaper(
135*ec779b8eSAndroid Build Coastguard Worker const media::VolumeShaperConfiguration& configuration,
136*ec779b8eSAndroid Build Coastguard Worker const media::VolumeShaperOperation& operation) {
137*ec779b8eSAndroid Build Coastguard Worker
138*ec779b8eSAndroid Build Coastguard Worker sp<VolumeShaper::Configuration> spConfiguration = new VolumeShaper::Configuration();
139*ec779b8eSAndroid Build Coastguard Worker sp<VolumeShaper::Operation> spOperation = new VolumeShaper::Operation();
140*ec779b8eSAndroid Build Coastguard Worker
141*ec779b8eSAndroid Build Coastguard Worker status_t s = spConfiguration->readFromParcelable(configuration)
142*ec779b8eSAndroid Build Coastguard Worker ?: spOperation->readFromParcelable(operation);
143*ec779b8eSAndroid Build Coastguard Worker if (s != OK) {
144*ec779b8eSAndroid Build Coastguard Worker return binderStatusFromStatusT(s);
145*ec779b8eSAndroid Build Coastguard Worker }
146*ec779b8eSAndroid Build Coastguard Worker if (sp<AudioTrack> audioTrack = getAudioTrack(); audioTrack != 0) {
147*ec779b8eSAndroid Build Coastguard Worker ALOGD("TrackPlayerBase::applyVolumeShaper() from IPlayer");
148*ec779b8eSAndroid Build Coastguard Worker VolumeShaper::Status status = audioTrack->applyVolumeShaper(spConfiguration, spOperation);
149*ec779b8eSAndroid Build Coastguard Worker if (status < 0) { // a non-negative value is the volume shaper id.
150*ec779b8eSAndroid Build Coastguard Worker ALOGE("TrackPlayerBase::applyVolumeShaper() failed with status %d", status);
151*ec779b8eSAndroid Build Coastguard Worker }
152*ec779b8eSAndroid Build Coastguard Worker return binderStatusFromStatusT(status);
153*ec779b8eSAndroid Build Coastguard Worker } else {
154*ec779b8eSAndroid Build Coastguard Worker ALOGD("TrackPlayerBase::applyVolumeShaper()"
155*ec779b8eSAndroid Build Coastguard Worker " no AudioTrack for volume control from IPlayer");
156*ec779b8eSAndroid Build Coastguard Worker return binder::Status::ok();
157*ec779b8eSAndroid Build Coastguard Worker }
158*ec779b8eSAndroid Build Coastguard Worker }
159*ec779b8eSAndroid Build Coastguard Worker
160*ec779b8eSAndroid Build Coastguard Worker } // namespace android
161