IAudioTrack.cpp revision ad3af3305f024bcbbd55c894a4995e449498e1ba
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 RESERVED, // was MUTE 37 PAUSE, 38 ATTACH_AUX_EFFECT, 39 ALLOCATE_TIMED_BUFFER, 40 QUEUE_TIMED_BUFFER, 41 SET_MEDIA_TIME_TRANSFORM, 42 SET_PARAMETERS 43}; 44 45class BpAudioTrack : public BpInterface<IAudioTrack> 46{ 47public: 48 BpAudioTrack(const sp<IBinder>& impl) 49 : BpInterface<IAudioTrack>(impl) 50 { 51 } 52 53 virtual sp<IMemory> getCblk() const 54 { 55 Parcel data, reply; 56 sp<IMemory> cblk; 57 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 58 status_t status = remote()->transact(GET_CBLK, data, &reply); 59 if (status == NO_ERROR) { 60 cblk = interface_cast<IMemory>(reply.readStrongBinder()); 61 } 62 return cblk; 63 } 64 65 virtual status_t start() 66 { 67 Parcel data, reply; 68 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 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 pause() 93 { 94 Parcel data, reply; 95 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 96 remote()->transact(PAUSE, data, &reply); 97 } 98 99 virtual status_t attachAuxEffect(int effectId) 100 { 101 Parcel data, reply; 102 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 103 data.writeInt32(effectId); 104 status_t status = remote()->transact(ATTACH_AUX_EFFECT, data, &reply); 105 if (status == NO_ERROR) { 106 status = reply.readInt32(); 107 } else { 108 ALOGW("attachAuxEffect() error: %s", strerror(-status)); 109 } 110 return status; 111 } 112 113 virtual status_t allocateTimedBuffer(size_t size, sp<IMemory>* buffer) { 114 Parcel data, reply; 115 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 116 data.writeInt32(size); 117 status_t status = remote()->transact(ALLOCATE_TIMED_BUFFER, 118 data, &reply); 119 if (status == NO_ERROR) { 120 status = reply.readInt32(); 121 if (status == NO_ERROR) { 122 *buffer = interface_cast<IMemory>(reply.readStrongBinder()); 123 } 124 } 125 return status; 126 } 127 128 virtual status_t queueTimedBuffer(const sp<IMemory>& buffer, 129 int64_t pts) { 130 Parcel data, reply; 131 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 132 data.writeStrongBinder(buffer->asBinder()); 133 data.writeInt64(pts); 134 status_t status = remote()->transact(QUEUE_TIMED_BUFFER, 135 data, &reply); 136 if (status == NO_ERROR) { 137 status = reply.readInt32(); 138 } 139 return status; 140 } 141 142 virtual status_t setMediaTimeTransform(const LinearTransform& xform, 143 int target) { 144 Parcel data, reply; 145 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 146 data.writeInt64(xform.a_zero); 147 data.writeInt64(xform.b_zero); 148 data.writeInt32(xform.a_to_b_numer); 149 data.writeInt32(xform.a_to_b_denom); 150 data.writeInt32(target); 151 status_t status = remote()->transact(SET_MEDIA_TIME_TRANSFORM, 152 data, &reply); 153 if (status == NO_ERROR) { 154 status = reply.readInt32(); 155 } 156 return status; 157 } 158 159 virtual status_t setParameters(const String8& keyValuePairs) { 160 Parcel data, reply; 161 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); 162 data.writeString8(keyValuePairs); 163 status_t status = remote()->transact(SET_PARAMETERS, data, &reply); 164 if (status == NO_ERROR) { 165 status = reply.readInt32(); 166 } 167 return status; 168 } 169}; 170 171IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack"); 172 173// ---------------------------------------------------------------------- 174 175status_t BnAudioTrack::onTransact( 176 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 177{ 178 switch (code) { 179 case GET_CBLK: { 180 CHECK_INTERFACE(IAudioTrack, data, reply); 181 reply->writeStrongBinder(getCblk()->asBinder()); 182 return NO_ERROR; 183 } break; 184 case START: { 185 CHECK_INTERFACE(IAudioTrack, data, reply); 186 reply->writeInt32(start()); 187 return NO_ERROR; 188 } break; 189 case STOP: { 190 CHECK_INTERFACE(IAudioTrack, data, reply); 191 stop(); 192 return NO_ERROR; 193 } break; 194 case FLUSH: { 195 CHECK_INTERFACE(IAudioTrack, data, reply); 196 flush(); 197 return NO_ERROR; 198 } break; 199 case PAUSE: { 200 CHECK_INTERFACE(IAudioTrack, data, reply); 201 pause(); 202 return NO_ERROR; 203 } 204 case ATTACH_AUX_EFFECT: { 205 CHECK_INTERFACE(IAudioTrack, data, reply); 206 reply->writeInt32(attachAuxEffect(data.readInt32())); 207 return NO_ERROR; 208 } break; 209 case ALLOCATE_TIMED_BUFFER: { 210 CHECK_INTERFACE(IAudioTrack, data, reply); 211 sp<IMemory> buffer; 212 status_t status = allocateTimedBuffer(data.readInt32(), &buffer); 213 reply->writeInt32(status); 214 if (status == NO_ERROR) { 215 reply->writeStrongBinder(buffer->asBinder()); 216 } 217 return NO_ERROR; 218 } break; 219 case QUEUE_TIMED_BUFFER: { 220 CHECK_INTERFACE(IAudioTrack, data, reply); 221 sp<IMemory> buffer = interface_cast<IMemory>( 222 data.readStrongBinder()); 223 uint64_t pts = data.readInt64(); 224 reply->writeInt32(queueTimedBuffer(buffer, pts)); 225 return NO_ERROR; 226 } break; 227 case SET_MEDIA_TIME_TRANSFORM: { 228 CHECK_INTERFACE(IAudioTrack, data, reply); 229 LinearTransform xform; 230 xform.a_zero = data.readInt64(); 231 xform.b_zero = data.readInt64(); 232 xform.a_to_b_numer = data.readInt32(); 233 xform.a_to_b_denom = data.readInt32(); 234 int target = data.readInt32(); 235 reply->writeInt32(setMediaTimeTransform(xform, target)); 236 return NO_ERROR; 237 } break; 238 case SET_PARAMETERS: { 239 CHECK_INTERFACE(IAudioTrack, data, reply); 240 String8 keyValuePairs(data.readString8()); 241 reply->writeInt32(setParameters(keyValuePairs)); 242 return NO_ERROR; 243 } break; 244 default: 245 return BBinder::onTransact(code, data, reply, flags); 246 } 247} 248 249}; // namespace android 250