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