• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 <binder/IMemory.h>
21 #include <cutils/sched_policy.h>
22 #include <media/AudioSystem.h>
23 #include <media/IAudioRecord.h>
24 #include <system/audio.h>
25 #include <utils/RefBase.h>
26 #include <utils/Errors.h>
27 #include <utils/threads.h>
28 
29 namespace android {
30 
31 class audio_track_cblk_t;
32 class AudioRecordClientProxy;
33 
34 // ----------------------------------------------------------------------------
35 
36 class AudioRecord : virtual public RefBase
37 {
38 public:
39 
40     static const int DEFAULT_SAMPLE_RATE = 8000;
41 
42     /* Events used by AudioRecord callback function (callback_t).
43      * Keep in sync with frameworks/base/media/java/android/media/AudioRecord.java NATIVE_EVENT_*.
44      */
45     enum event_type {
46         EVENT_MORE_DATA = 0,        // Request to read more data from PCM buffer.
47         EVENT_OVERRUN = 1,          // PCM buffer overrun occurred.
48         EVENT_MARKER = 2,           // Record head is at the specified marker position
49                                     // (See setMarkerPosition()).
50         EVENT_NEW_POS = 3,          // Record head is at a new position
51                                     // (See setPositionUpdatePeriod()).
52     };
53 
54     /* Client should declare Buffer on the stack and pass address to obtainBuffer()
55      * and releaseBuffer().  See also callback_t for EVENT_MORE_DATA.
56      */
57 
58     class Buffer
59     {
60     public:
61         size_t      frameCount;     // number of sample frames corresponding to size;
62                                     // on input it is the number of frames available,
63                                     // on output is the number of frames actually drained
64 
65         size_t      size;           // total size in bytes == frameCount * frameSize
66         union {
67             void*       raw;
68             short*      i16;        // signed 16-bit
69             int8_t*     i8;         // unsigned 8-bit, offset by 0x80
70         };
71     };
72 
73     /* As a convenience, if a callback is supplied, a handler thread
74      * is automatically created with the appropriate priority. This thread
75      * invokes the callback when a new buffer becomes ready or various conditions occur.
76      * Parameters:
77      *
78      * event:   type of event notified (see enum AudioRecord::event_type).
79      * user:    Pointer to context for use by the callback receiver.
80      * info:    Pointer to optional parameter according to event type:
81      *          - EVENT_MORE_DATA: pointer to AudioRecord::Buffer struct. The callback must not read
82      *            more bytes than indicated by 'size' field and update 'size' if fewer bytes are
83      *            consumed.
84      *          - EVENT_OVERRUN: unused.
85      *          - EVENT_MARKER: pointer to const uint32_t containing the marker position in frames.
86      *          - EVENT_NEW_POS: pointer to const uint32_t containing the new position in frames.
87      */
88 
89     typedef void (*callback_t)(int event, void* user, void *info);
90 
91     /* Returns the minimum frame count required for the successful creation of
92      * an AudioRecord object.
93      * Returned status (from utils/Errors.h) can be:
94      *  - NO_ERROR: successful operation
95      *  - NO_INIT: audio server or audio hardware not initialized
96      *  - BAD_VALUE: unsupported configuration
97      */
98 
99      static status_t getMinFrameCount(size_t* frameCount,
100                                       uint32_t sampleRate,
101                                       audio_format_t format,
102                                       audio_channel_mask_t channelMask);
103 
104     /* Constructs an uninitialized AudioRecord. No connection with
105      * AudioFlinger takes place.
106      */
107                         AudioRecord();
108 
109     /* Creates an AudioRecord object and registers it with AudioFlinger.
110      * Once created, the track needs to be started before it can be used.
111      * Unspecified values are set to the audio hardware's current
112      * values.
113      *
114      * Parameters:
115      *
116      * inputSource:        Select the audio input to record to (e.g. AUDIO_SOURCE_DEFAULT).
117      * sampleRate:         Track sampling rate in Hz.
118      * format:             Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed
119      *                     16 bits per sample).
120      * channelMask:        Channel mask.
121      * frameCount:         Minimum size of track PCM buffer in frames. This defines the
122      *                     application's contribution to the
123      *                     latency of the track.  The actual size selected by the AudioRecord could
124      *                     be larger if the requested size is not compatible with current audio HAL
125      *                     latency.  Zero means to use a default value.
126      * cbf:                Callback function. If not null, this function is called periodically
127      *                     to consume new PCM data.
128      * user:               Context for use by the callback receiver.
129      * notificationFrames: The callback function is called each time notificationFrames PCM
130      *                     frames are ready in record track output buffer.
131      * sessionId:          Not yet supported.
132      */
133 
134                         AudioRecord(audio_source_t inputSource,
135                                     uint32_t sampleRate = 0,
136                                     audio_format_t format = AUDIO_FORMAT_DEFAULT,
137                                     audio_channel_mask_t channelMask = AUDIO_CHANNEL_IN_MONO,
138                                     int frameCount      = 0,
139                                     callback_t cbf = NULL,
140                                     void* user = NULL,
141                                     int notificationFrames = 0,
142                                     int sessionId = 0);
143 
144 
145     /* Terminates the AudioRecord and unregisters it from AudioFlinger.
146      * Also destroys all resources associated with the AudioRecord.
147      */
148                         ~AudioRecord();
149 
150 
151     /* Initialize an uninitialized AudioRecord.
152      * Returned status (from utils/Errors.h) can be:
153      *  - NO_ERROR: successful intialization
154      *  - INVALID_OPERATION: AudioRecord is already intitialized or record device is already in use
155      *  - BAD_VALUE: invalid parameter (channels, format, sampleRate...)
156      *  - NO_INIT: audio server or audio hardware not initialized
157      *  - PERMISSION_DENIED: recording is not allowed for the requesting process
158      */
159             status_t    set(audio_source_t inputSource = AUDIO_SOURCE_DEFAULT,
160                             uint32_t sampleRate = 0,
161                             audio_format_t format = AUDIO_FORMAT_DEFAULT,
162                             audio_channel_mask_t channelMask = AUDIO_CHANNEL_IN_MONO,
163                             int frameCount      = 0,
164                             callback_t cbf = NULL,
165                             void* user = NULL,
166                             int notificationFrames = 0,
167                             bool threadCanCallJava = false,
168                             int sessionId = 0);
169 
170 
171     /* Result of constructing the AudioRecord. This must be checked
172      * before using any AudioRecord API (except for set()), because using
173      * an uninitialized AudioRecord produces undefined results.
174      * See set() method above for possible return codes.
175      */
176             status_t    initCheck() const;
177 
178     /* Returns this track's estimated latency in milliseconds.
179      * This includes the latency due to AudioRecord buffer size,
180      * and audio hardware driver.
181      */
182             uint32_t     latency() const;
183 
184    /* getters, see constructor and set() */
185 
186             audio_format_t format() const;
187             uint32_t    channelCount() const;
188             size_t      frameCount() const;
frameSize()189             size_t      frameSize() const { return mFrameSize; }
190             audio_source_t inputSource() const;
191 
192 
193     /* After it's created the track is not active. Call start() to
194      * make it active. If set, the callback will start being called.
195      * If event is not AudioSystem::SYNC_EVENT_NONE, the capture start will be delayed until
196      * the specified event occurs on the specified trigger session.
197      */
198             status_t    start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
199                               int triggerSession = 0);
200 
201     /* Stop a track. If set, the callback will cease being called and
202      * obtainBuffer returns STOPPED. Note that obtainBuffer() still works
203      * and will drain buffers until the pool is exhausted.
204      */
205             void        stop();
206             bool        stopped() const;
207 
208     /* Get sample rate for this record track in Hz.
209      */
210             uint32_t    getSampleRate() const;
211 
212     /* Sets marker position. When record reaches the number of frames specified,
213      * a callback with event type EVENT_MARKER is called. Calling setMarkerPosition
214      * with marker == 0 cancels marker notification callback.
215      * If the AudioRecord has been opened with no callback function associated,
216      * the operation will fail.
217      *
218      * Parameters:
219      *
220      * marker:   marker position expressed in frames.
221      *
222      * Returned status (from utils/Errors.h) can be:
223      *  - NO_ERROR: successful operation
224      *  - INVALID_OPERATION: the AudioRecord has no callback installed.
225      */
226             status_t    setMarkerPosition(uint32_t marker);
227             status_t    getMarkerPosition(uint32_t *marker) const;
228 
229 
230     /* Sets position update period. Every time the number of frames specified has been recorded,
231      * a callback with event type EVENT_NEW_POS is called.
232      * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification
233      * callback.
234      * If the AudioRecord has been opened with no callback function associated,
235      * the operation will fail.
236      *
237      * Parameters:
238      *
239      * updatePeriod:  position update notification period expressed in frames.
240      *
241      * Returned status (from utils/Errors.h) can be:
242      *  - NO_ERROR: successful operation
243      *  - INVALID_OPERATION: the AudioRecord has no callback installed.
244      */
245             status_t    setPositionUpdatePeriod(uint32_t updatePeriod);
246             status_t    getPositionUpdatePeriod(uint32_t *updatePeriod) const;
247 
248 
249     /* Gets record head position. The position is the total number of frames
250      * recorded since record start.
251      *
252      * Parameters:
253      *
254      *  position:  Address where to return record head position within AudioRecord buffer.
255      *
256      * Returned status (from utils/Errors.h) can be:
257      *  - NO_ERROR: successful operation
258      *  - BAD_VALUE:  position is NULL
259      */
260             status_t    getPosition(uint32_t *position) const;
261 
262     /* Returns a handle on the audio input used by this AudioRecord.
263      *
264      * Parameters:
265      *  none.
266      *
267      * Returned value:
268      *  handle on audio hardware input
269      */
270             audio_io_handle_t    getInput() const;
271 
272     /* Returns the audio session ID associated with this AudioRecord.
273      *
274      * Parameters:
275      *  none.
276      *
277      * Returned value:
278      *  AudioRecord session ID.
279      */
280             int    getSessionId() const;
281 
282     /* Obtains a buffer of "frameCount" frames. The buffer must be
283      * drained entirely, and then released with releaseBuffer().
284      * If the track is stopped, obtainBuffer() returns
285      * STOPPED instead of NO_ERROR as long as there are buffers available,
286      * at which point NO_MORE_BUFFERS is returned.
287      * Buffers will be returned until the pool
288      * is exhausted, at which point obtainBuffer() will either block
289      * or return WOULD_BLOCK depending on the value of the "blocking"
290      * parameter.
291      *
292      * Interpretation of waitCount:
293      *  +n  limits wait time to n * WAIT_PERIOD_MS,
294      *  -1  causes an (almost) infinite wait time,
295      *   0  non-blocking.
296      */
297 
298         enum {
299             NO_MORE_BUFFERS = 0x80000001,   // same name in AudioFlinger.h, ok to be different value
300             STOPPED = 1
301         };
302 
303             status_t    obtainBuffer(Buffer* audioBuffer, int32_t waitCount);
304 
305     /* Release an emptied buffer of "frameCount" frames for AudioFlinger to re-fill. */
306             void        releaseBuffer(Buffer* audioBuffer);
307 
308 
309     /* As a convenience we provide a read() interface to the audio buffer.
310      * This is implemented on top of obtainBuffer/releaseBuffer.
311      */
312             ssize_t     read(void* buffer, size_t size);
313 
314     /* Return the number of input frames lost in the audio driver since the last call of this
315      * function.  Audio driver is expected to reset the value to 0 and restart counting upon
316      * returning the current value by this function call.  Such loss typically occurs when the
317      * user space process is blocked longer than the capacity of audio driver buffers.
318      * Units: the number of input audio frames.
319      */
320             unsigned int  getInputFramesLost() const;
321 
322 private:
323     /* copying audio record objects is not allowed */
324                         AudioRecord(const AudioRecord& other);
325             AudioRecord& operator = (const AudioRecord& other);
326 
327     /* a small internal class to handle the callback */
328     class AudioRecordThread : public Thread
329     {
330     public:
331         AudioRecordThread(AudioRecord& receiver, bool bCanCallJava = false);
332 
333         // Do not call Thread::requestExitAndWait() without first calling requestExit().
334         // Thread::requestExitAndWait() is not virtual, and the implementation doesn't do enough.
335         virtual void        requestExit();
336 
337                 void        pause();    // suspend thread from execution at next loop boundary
338                 void        resume();   // allow thread to execute, if not requested to exit
339 
340     private:
341         friend class AudioRecord;
342         virtual bool        threadLoop();
343         AudioRecord& mReceiver;
344         virtual ~AudioRecordThread();
345         Mutex               mMyLock;    // Thread::mLock is private
346         Condition           mMyCond;    // Thread::mThreadExitedCondition is private
347         bool                mPaused;    // whether thread is currently paused
348     };
349 
350             // body of AudioRecordThread::threadLoop()
351             bool processAudioBuffer(const sp<AudioRecordThread>& thread);
352 
353             status_t openRecord_l(uint32_t sampleRate,
354                                 audio_format_t format,
355                                 size_t frameCount,
356                                 audio_io_handle_t input);
357             audio_io_handle_t getInput_l();
358             status_t restoreRecord_l(audio_track_cblk_t*& cblk);
359 
360     sp<AudioRecordThread>   mAudioRecordThread;
361     mutable Mutex           mLock;
362 
363     bool                    mActive;            // protected by mLock
364 
365     // for client callback handler
366     callback_t              mCbf;               // callback handler for events, or NULL
367     void*                   mUserData;
368 
369     // for notification APIs
370     uint32_t                mNotificationFrames;
371     uint32_t                mRemainingFrames;
372     uint32_t                mMarkerPosition;    // in frames
373     bool                    mMarkerReached;
374     uint32_t                mNewPosition;       // in frames
375     uint32_t                mUpdatePeriod;      // in ms
376 
377     // constant after constructor or set()
378     uint32_t                mSampleRate;
379     size_t                  mFrameCount;
380     audio_format_t          mFormat;
381     uint8_t                 mChannelCount;
382     size_t                  mFrameSize;         // app-level frame size == AudioFlinger frame size
383     audio_source_t          mInputSource;
384     status_t                mStatus;
385     uint32_t                mLatency;
386     audio_channel_mask_t    mChannelMask;
387     audio_io_handle_t       mInput;                     // returned by AudioSystem::getInput()
388     int                     mSessionId;
389 
390     // may be changed if IAudioRecord object is re-created
391     sp<IAudioRecord>        mAudioRecord;
392     sp<IMemory>             mCblkMemory;
393     audio_track_cblk_t*     mCblk;
394     void*                   mBuffers;           // starting address of buffers in shared memory
395 
396     int                     mPreviousPriority;          // before start()
397     SchedPolicy             mPreviousSchedulingGroup;
398     AudioRecordClientProxy* mProxy;
399 };
400 
401 }; // namespace android
402 
403 #endif /*AUDIORECORD_H_*/
404