IAudioTrack.cpp revision e53b9ead781c36e96d6b6f012ddffc93a3d80f0d
1/* 2** 3** Copyright 2007, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#define LOG_TAG "IAudioTrack" 19//#define LOG_NDEBUG 0 20#include <utils/Log.h> 21 22#include <stdint.h> 23#include <sys/types.h> 24 25#include <binder/Parcel.h> 26 27#include <media/IAudioTrack.h> 28 29namespace android { 30 31enum { 32 GET_CBLK = IBinder::FIRST_CALL_TRANSACTION, 33 START, 34 STOP, 35 FLUSH, 36 MUTE, 37 PAUSE, 38 ATTACH_AUX_EFFECT, 39 ALLOCATE_TIMED_BUFFER, 40 QUEUE_TIMED_BUFFER, 41 SET_MEDIA_TIME_TRANSFORM, 42}; 43 44class BpAudioTrack : public BpInterface<IAudioTrack> 45{ 46public: 47 BpAudioTrack(const sp<IBinder>& impl) 48 : BpInterface<IAudioTrack>(impl) 49 { 50 } 51 52 virtual sp<IMemory> getCblk() const 53 { 54 Parcel data, reply; 55 sp<IMemory> cblk; 56 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 57 status_t status = remote()->transact(GET_CBLK, data, &reply); 58 if (status == NO_ERROR) { 59 cblk = interface_cast<IMemory>(reply.readStrongBinder()); 60 } 61 return cblk; 62 } 63 64 virtual status_t start(pid_t tid) 65 { 66 Parcel data, reply; 67 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 68 data.writeInt32(tid); 69 status_t status = remote()->transact(START, data, &reply); 70 if (status == NO_ERROR) { 71 status = reply.readInt32(); 72 } else { 73 ALOGW("start() error: %s", strerror(-status)); 74 } 75 return status; 76 } 77 78 virtual void stop() 79 { 80 Parcel data, reply; 81 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 82 remote()->transact(STOP, data, &reply); 83 } 84 85 virtual void flush() 86 { 87 Parcel data, reply; 88 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 89 remote()->transact(FLUSH, data, &reply); 90 } 91 92 virtual void mute(bool e) 93 { 94 Parcel data, reply; 95 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 96 data.writeInt32(e); 97 remote()->transact(MUTE, data, &reply); 98 } 99 100 virtual void pause() 101 { 102 Parcel data, reply; 103 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 104 remote()->transact(PAUSE, data, &reply); 105 } 106 107 virtual status_t attachAuxEffect(int effectId) 108 { 109 Parcel data, reply; 110 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 111 data.writeInt32(effectId); 112 status_t status = remote()->transact(ATTACH_AUX_EFFECT, data, &reply); 113 if (status == NO_ERROR) { 114 status = reply.readInt32(); 115 } else { 116 ALOGW("attachAuxEffect() error: %s", strerror(-status)); 117 } 118 return status; 119 } 120 121 virtual status_t allocateTimedBuffer(size_t size, sp<IMemory>* buffer) { 122 Parcel data, reply; 123 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 124 data.writeInt32(size); 125 status_t status = remote()->transact(ALLOCATE_TIMED_BUFFER, 126 data, &reply); 127 if (status == NO_ERROR) { 128 status = reply.readInt32(); 129 if (status == NO_ERROR) { 130 *buffer = interface_cast<IMemory>(reply.readStrongBinder()); 131 } 132 } 133 return status; 134 } 135 136 virtual status_t queueTimedBuffer(const sp<IMemory>& buffer, 137 int64_t pts) { 138 Parcel data, reply; 139 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 140 data.writeStrongBinder(buffer->asBinder()); 141 data.writeInt64(pts); 142 status_t status = remote()->transact(QUEUE_TIMED_BUFFER, 143 data, &reply); 144 if (status == NO_ERROR) { 145 status = reply.readInt32(); 146 } 147 return status; 148 } 149 150 virtual status_t setMediaTimeTransform(const LinearTransform& xform, 151 int target) { 152 Parcel data, reply; 153 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 154 data.writeInt64(xform.a_zero); 155 data.writeInt64(xform.b_zero); 156 data.writeInt32(xform.a_to_b_numer); 157 data.writeInt32(xform.a_to_b_denom); 158 data.writeInt32(target); 159 status_t status = remote()->transact(SET_MEDIA_TIME_TRANSFORM, 160 data, &reply); 161 if (status == NO_ERROR) { 162 status = reply.readInt32(); 163 } 164 return status; 165 } 166}; 167 168IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack"); 169 170// ---------------------------------------------------------------------- 171 172status_t BnAudioTrack::onTransact( 173 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 174{ 175 switch (code) { 176 case GET_CBLK: { 177 CHECK_INTERFACE(IAudioTrack, data, reply); 178 reply->writeStrongBinder(getCblk()->asBinder()); 179 return NO_ERROR; 180 } break; 181 case START: { 182 CHECK_INTERFACE(IAudioTrack, data, reply); 183 reply->writeInt32(start(data.readInt32())); 184 return NO_ERROR; 185 } break; 186 case STOP: { 187 CHECK_INTERFACE(IAudioTrack, data, reply); 188 stop(); 189 return NO_ERROR; 190 } break; 191 case FLUSH: { 192 CHECK_INTERFACE(IAudioTrack, data, reply); 193 flush(); 194 return NO_ERROR; 195 } break; 196 case MUTE: { 197 CHECK_INTERFACE(IAudioTrack, data, reply); 198 mute( data.readInt32() ); 199 return NO_ERROR; 200 } break; 201 case PAUSE: { 202 CHECK_INTERFACE(IAudioTrack, data, reply); 203 pause(); 204 return NO_ERROR; 205 } 206 case ATTACH_AUX_EFFECT: { 207 CHECK_INTERFACE(IAudioTrack, data, reply); 208 reply->writeInt32(attachAuxEffect(data.readInt32())); 209 return NO_ERROR; 210 } break; 211 case ALLOCATE_TIMED_BUFFER: { 212 CHECK_INTERFACE(IAudioTrack, data, reply); 213 sp<IMemory> buffer; 214 status_t status = allocateTimedBuffer(data.readInt32(), &buffer); 215 reply->writeInt32(status); 216 if (status == NO_ERROR) { 217 reply->writeStrongBinder(buffer->asBinder()); 218 } 219 return NO_ERROR; 220 } break; 221 case QUEUE_TIMED_BUFFER: { 222 CHECK_INTERFACE(IAudioTrack, data, reply); 223 sp<IMemory> buffer = interface_cast<IMemory>( 224 data.readStrongBinder()); 225 uint64_t pts = data.readInt64(); 226 reply->writeInt32(queueTimedBuffer(buffer, pts)); 227 return NO_ERROR; 228 } break; 229 case SET_MEDIA_TIME_TRANSFORM: { 230 CHECK_INTERFACE(IAudioTrack, data, reply); 231 LinearTransform xform; 232 xform.a_zero = data.readInt64(); 233 xform.b_zero = data.readInt64(); 234 xform.a_to_b_numer = data.readInt32(); 235 xform.a_to_b_denom = data.readInt32(); 236 int target = data.readInt32(); 237 reply->writeInt32(setMediaTimeTransform(xform, target)); 238 return NO_ERROR; 239 } break; 240 default: 241 return BBinder::onTransact(code, data, reply, flags); 242 } 243} 244 245}; // namespace android 246