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