blob: def3612ec4c93cf52258260eeb6c7c4aace1df67 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef AUDIORECORD_H_
18#define AUDIORECORD_H_
19
20#include <stdint.h>
21#include <sys/types.h>
22
23#include <media/IAudioFlinger.h>
24#include <media/IAudioRecord.h>
25#include <media/AudioTrack.h>
26
27#include <utils/RefBase.h>
28#include <utils/Errors.h>
Mathias Agopian07952722009-05-19 19:08:10 -070029#include <binder/IInterface.h>
30#include <binder/IMemory.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031#include <utils/threads.h>
32
Dima Zavin24fc2fb2011-04-19 22:30:36 -070033#include <hardware/audio.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034
35namespace android {
36
37// ----------------------------------------------------------------------------
38
39class AudioRecord
40{
41public:
42
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043 static const int DEFAULT_SAMPLE_RATE = 8000;
44
45 /* Events used by AudioRecord callback function (callback_t).
Eric Laurenta553c252009-07-17 12:17:14 -070046 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047 * to keep in sync with frameworks/base/media/java/android/media/AudioRecord.java
48 */
49 enum event_type {
50 EVENT_MORE_DATA = 0, // Request to reqd more data from PCM buffer.
51 EVENT_OVERRUN = 1, // PCM buffer overrun occured.
52 EVENT_MARKER = 2, // Record head is at the specified marker position
53 // (See setMarkerPosition()).
Eric Laurenta553c252009-07-17 12:17:14 -070054 EVENT_NEW_POS = 3, // Record head is at a new position
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055 // (See setPositionUpdatePeriod()).
56 };
57
58 /* Create Buffer on the stack and pass it to obtainBuffer()
59 * and releaseBuffer().
60 */
61
62 class Buffer
63 {
64 public:
65 enum {
66 MUTE = 0x00000001
67 };
68 uint32_t flags;
69 int channelCount;
70 int format;
71 size_t frameCount;
72 size_t size;
73 union {
74 void* raw;
75 short* i16;
76 int8_t* i8;
77 };
78 };
79
80 /* These are static methods to control the system-wide AudioFlinger
81 * only privileged processes can have access to them
82 */
83
84// static status_t setMasterMute(bool mute);
85
86 /* As a convenience, if a callback is supplied, a handler thread
87 * is automatically created with the appropriate priority. This thread
88 * invokes the callback when a new buffer becomes ready or an overrun condition occurs.
89 * Parameters:
90 *
91 * event: type of event notified (see enum AudioRecord::event_type).
92 * user: Pointer to context for use by the callback receiver.
93 * info: Pointer to optional parameter according to event type:
94 * - EVENT_MORE_DATA: pointer to AudioRecord::Buffer struct. The callback must not read
95 * more bytes than indicated by 'size' field and update 'size' if less bytes are
96 * read.
97 * - EVENT_OVERRUN: unused.
98 * - EVENT_MARKER: pointer to an uin32_t containing the marker position in frames.
99 * - EVENT_NEW_POS: pointer to an uin32_t containing the new position in frames.
100 */
101
102 typedef void (*callback_t)(int event, void* user, void *info);
103
Chia-chi Yeh97d61f72010-06-22 08:01:13 +0800104 /* Returns the minimum frame count required for the successful creation of
105 * an AudioRecord object.
106 * Returned status (from utils/Errors.h) can be:
107 * - NO_ERROR: successful operation
108 * - NO_INIT: audio server or audio hardware not initialized
109 * - BAD_VALUE: unsupported configuration
110 */
111
112 static status_t getMinFrameCount(int* frameCount,
113 uint32_t sampleRate,
114 int format,
115 int channelCount);
116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 /* Constructs an uninitialized AudioRecord. No connection with
118 * AudioFlinger takes place.
119 */
120 AudioRecord();
121
122 /* Creates an AudioRecord track and registers it with AudioFlinger.
123 * Once created, the track needs to be started before it can be used.
124 * Unspecified values are set to the audio hardware's current
125 * values.
126 *
127 * Parameters:
128 *
Eric Laurenta553c252009-07-17 12:17:14 -0700129 * inputSource: Select the audio input to record to (e.g. AUDIO_SOURCE_DEFAULT).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 * sampleRate: Track sampling rate in Hz.
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700131 * format: Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 * 16 bits per sample).
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700133 * channels: Channel mask: see audio_channels_t.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 * frameCount: Total size of track PCM buffer in frames. This defines the
135 * latency of the track.
136 * flags: A bitmask of acoustic values from enum record_flags. It enables
137 * AGC, NS, and IIR.
138 * cbf: Callback function. If not null, this function is called periodically
139 * to provide new PCM data.
140 * notificationFrames: The callback function is called each time notificationFrames PCM
141 * frames are ready in record track output buffer.
142 * user Context for use by the callback receiver.
143 */
144
145 enum record_flags {
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700146 RECORD_AGC_ENABLE = AUDIO_IN_ACOUSTICS_AGC_ENABLE,
147 RECORD_NS_ENABLE = AUDIO_IN_ACOUSTICS_NS_ENABLE,
148 RECORD_IIR_ENABLE = AUDIO_IN_ACOUSTICS_TX_IIR_ENABLE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 };
150
Eric Laurent4bc035a2009-05-22 09:18:15 -0700151 AudioRecord(int inputSource,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 uint32_t sampleRate = 0,
153 int format = 0,
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700154 uint32_t channels = AUDIO_CHANNEL_IN_MONO,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 int frameCount = 0,
156 uint32_t flags = 0,
157 callback_t cbf = 0,
158 void* user = 0,
Eric Laurent65b65452010-06-01 23:49:17 -0700159 int notificationFrames = 0,
160 int sessionId = 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161
162
163 /* Terminates the AudioRecord and unregisters it from AudioFlinger.
164 * Also destroys all resources assotiated with the AudioRecord.
165 */
166 ~AudioRecord();
167
168
169 /* Initialize an uninitialized AudioRecord.
170 * Returned status (from utils/Errors.h) can be:
171 * - NO_ERROR: successful intialization
172 * - INVALID_OPERATION: AudioRecord is already intitialized or record device is already in use
Eric Laurenta553c252009-07-17 12:17:14 -0700173 * - BAD_VALUE: invalid parameter (channels, format, sampleRate...)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 * - NO_INIT: audio server or audio hardware not initialized
175 * - PERMISSION_DENIED: recording is not allowed for the requesting process
176 * */
Eric Laurent4bc035a2009-05-22 09:18:15 -0700177 status_t set(int inputSource = 0,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 uint32_t sampleRate = 0,
179 int format = 0,
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700180 uint32_t channels = AUDIO_CHANNEL_IN_MONO,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 int frameCount = 0,
182 uint32_t flags = 0,
183 callback_t cbf = 0,
184 void* user = 0,
185 int notificationFrames = 0,
Eric Laurent65b65452010-06-01 23:49:17 -0700186 bool threadCanCallJava = false,
187 int sessionId = 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188
189
190 /* Result of constructing the AudioRecord. This must be checked
191 * before using any AudioRecord API (except for set()), using
192 * an uninitialized AudioRecord produces undefined results.
193 * See set() method above for possible return codes.
194 */
195 status_t initCheck() const;
196
197 /* Returns this track's latency in milliseconds.
198 * This includes the latency due to AudioRecord buffer size
199 * and audio hardware driver.
200 */
201 uint32_t latency() const;
202
203 /* getters, see constructor */
204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 int format() const;
206 int channelCount() const;
Eric Laurenta553c252009-07-17 12:17:14 -0700207 int channels() const;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 uint32_t frameCount() const;
209 int frameSize() const;
Eric Laurent4bc035a2009-05-22 09:18:15 -0700210 int inputSource() const;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211
212
213 /* After it's created the track is not active. Call start() to
214 * make it active. If set, the callback will start being called.
215 */
216 status_t start();
217
218 /* Stop a track. If set, the callback will cease being called and
219 * obtainBuffer returns STOPPED. Note that obtainBuffer() still works
220 * and will fill up buffers until the pool is exhausted.
221 */
222 status_t stop();
223 bool stopped() const;
224
Eric Laurent88e209d2009-07-07 07:10:45 -0700225 /* get sample rate for this record track
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 */
227 uint32_t getSampleRate();
228
229 /* Sets marker position. When record reaches the number of frames specified,
230 * a callback with event type EVENT_MARKER is called. Calling setMarkerPosition
Eric Laurenta553c252009-07-17 12:17:14 -0700231 * with marker == 0 cancels marker notification callback.
232 * If the AudioRecord has been opened with no callback function associated,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 * the operation will fail.
234 *
235 * Parameters:
236 *
237 * marker: marker position expressed in frames.
238 *
239 * Returned status (from utils/Errors.h) can be:
240 * - NO_ERROR: successful operation
241 * - INVALID_OPERATION: the AudioRecord has no callback installed.
242 */
243 status_t setMarkerPosition(uint32_t marker);
244 status_t getMarkerPosition(uint32_t *marker);
245
246
Eric Laurenta553c252009-07-17 12:17:14 -0700247 /* Sets position update period. Every time the number of frames specified has been recorded,
248 * a callback with event type EVENT_NEW_POS is called.
249 * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification
250 * callback.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 * If the AudioRecord has been opened with no callback function associated,
252 * the operation will fail.
253 *
254 * Parameters:
255 *
256 * updatePeriod: position update notification period expressed in frames.
257 *
258 * Returned status (from utils/Errors.h) can be:
259 * - NO_ERROR: successful operation
260 * - INVALID_OPERATION: the AudioRecord has no callback installed.
261 */
262 status_t setPositionUpdatePeriod(uint32_t updatePeriod);
263 status_t getPositionUpdatePeriod(uint32_t *updatePeriod);
264
265
Eric Laurenta553c252009-07-17 12:17:14 -0700266 /* Gets record head position. The position is the total number of frames
267 * recorded since record start.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 *
269 * Parameters:
270 *
271 * position: Address where to return record head position within AudioRecord buffer.
272 *
273 * Returned status (from utils/Errors.h) can be:
274 * - NO_ERROR: successful operation
275 * - BAD_VALUE: position is NULL
276 */
277 status_t getPosition(uint32_t *position);
278
Eric Laurenta553c252009-07-17 12:17:14 -0700279 /* returns a handle on the audio input used by this AudioRecord.
280 *
281 * Parameters:
282 * none.
283 *
284 * Returned value:
285 * handle on audio hardware input
286 */
Eric Laurent49f02be2009-11-19 09:00:56 -0800287 audio_io_handle_t getInput();
Eric Laurenta553c252009-07-17 12:17:14 -0700288
Eric Laurent65b65452010-06-01 23:49:17 -0700289 /* returns the audio session ID associated to this AudioRecord.
290 *
291 * Parameters:
292 * none.
293 *
294 * Returned value:
295 * AudioRecord session ID.
296 */
297 int getSessionId();
298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 /* obtains a buffer of "frameCount" frames. The buffer must be
300 * filled entirely. If the track is stopped, obtainBuffer() returns
301 * STOPPED instead of NO_ERROR as long as there are buffers availlable,
302 * at which point NO_MORE_BUFFERS is returned.
303 * Buffers will be returned until the pool (buffercount())
304 * is exhausted, at which point obtainBuffer() will either block
305 * or return WOULD_BLOCK depending on the value of the "blocking"
306 * parameter.
307 */
308
309 enum {
310 NO_MORE_BUFFERS = 0x80000001,
311 STOPPED = 1
312 };
313
314 status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount);
315 void releaseBuffer(Buffer* audioBuffer);
316
317
318 /* As a convenience we provide a read() interface to the audio buffer.
319 * This is implemented on top of lockBuffer/unlockBuffer.
320 */
321 ssize_t read(void* buffer, size_t size);
322
Eric Laurent47d0a922010-02-26 02:47:27 -0800323 /* Return the amount of input frames lost in the audio driver since the last call of this function.
324 * Audio driver is expected to reset the value to 0 and restart counting upon returning the current value by this function call.
325 * Such loss typically occurs when the user space process is blocked longer than the capacity of audio driver buffers.
326 * Unit: the number of input audio frames
327 */
328 unsigned int getInputFramesLost();
329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330private:
331 /* copying audio tracks is not allowed */
332 AudioRecord(const AudioRecord& other);
333 AudioRecord& operator = (const AudioRecord& other);
334
335 /* a small internal class to handle the callback */
336 class ClientRecordThread : public Thread
337 {
338 public:
339 ClientRecordThread(AudioRecord& receiver, bool bCanCallJava = false);
340 private:
341 friend class AudioRecord;
342 virtual bool threadLoop();
343 virtual status_t readyToRun() { return NO_ERROR; }
344 virtual void onFirstRef() {}
345 AudioRecord& mReceiver;
346 Mutex mLock;
347 };
348
349 bool processAudioBuffer(const sp<ClientRecordThread>& thread);
Eric Laurent421ddc02011-03-07 14:52:59 -0800350 status_t openRecord_l(uint32_t sampleRate,
Eric Laurentbda74692009-11-04 08:27:26 -0800351 int format,
352 int channelCount,
353 int frameCount,
Eric Laurent49f02be2009-11-19 09:00:56 -0800354 uint32_t flags,
355 audio_io_handle_t input);
Eric Laurent421ddc02011-03-07 14:52:59 -0800356 audio_io_handle_t getInput_l();
357 status_t restoreRecord_l(audio_track_cblk_t*& cblk);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 sp<IAudioRecord> mAudioRecord;
360 sp<IMemory> mCblkMemory;
361 sp<ClientRecordThread> mClientRecordThread;
Eric Laurentf3d6dd02010-11-18 08:40:16 -0800362 Mutex mLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364 uint32_t mFrameCount;
365
366 audio_track_cblk_t* mCblk;
367 uint8_t mFormat;
368 uint8_t mChannelCount;
Eric Laurent4bc035a2009-05-22 09:18:15 -0700369 uint8_t mInputSource;
370 uint8_t mReserved;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 status_t mStatus;
372 uint32_t mLatency;
373
374 volatile int32_t mActive;
375
376 callback_t mCbf;
377 void* mUserData;
378 uint32_t mNotificationFrames;
379 uint32_t mRemainingFrames;
380 uint32_t mMarkerPosition;
Jean-Michel Trivi78c13142009-03-24 19:48:58 -0700381 bool mMarkerReached;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 uint32_t mNewPosition;
383 uint32_t mUpdatePeriod;
Eric Laurentbda74692009-11-04 08:27:26 -0800384 uint32_t mFlags;
Eric Laurent49f02be2009-11-19 09:00:56 -0800385 uint32_t mChannels;
Eric Laurent47d0a922010-02-26 02:47:27 -0800386 audio_io_handle_t mInput;
Eric Laurent65b65452010-06-01 23:49:17 -0700387 int mSessionId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388};
389
390}; // namespace android
391
392#endif /*AUDIORECORD_H_*/