• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright 2008, 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_NDEBUG 0
19 #define LOG_TAG "AudioRecord"
20 
21 #include <stdint.h>
22 #include <sys/types.h>
23 
24 #include <sched.h>
25 #include <sys/resource.h>
26 
27 #include <private/media/AudioTrackShared.h>
28 
29 #include <media/AudioSystem.h>
30 #include <media/AudioRecord.h>
31 #include <media/mediarecorder.h>
32 
33 #include <binder/IServiceManager.h>
34 #include <utils/Log.h>
35 #include <binder/MemoryDealer.h>
36 #include <binder/Parcel.h>
37 #include <binder/IPCThreadState.h>
38 #include <utils/Timers.h>
39 #include <cutils/atomic.h>
40 
41 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
42 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
43 
44 namespace android {
45 
46 // ---------------------------------------------------------------------------
47 
AudioRecord()48 AudioRecord::AudioRecord()
49     : mStatus(NO_INIT), mInput(0)
50 {
51 }
52 
AudioRecord(int inputSource,uint32_t sampleRate,int format,uint32_t channels,int frameCount,uint32_t flags,callback_t cbf,void * user,int notificationFrames)53 AudioRecord::AudioRecord(
54         int inputSource,
55         uint32_t sampleRate,
56         int format,
57         uint32_t channels,
58         int frameCount,
59         uint32_t flags,
60         callback_t cbf,
61         void* user,
62         int notificationFrames)
63     : mStatus(NO_INIT), mInput(0)
64 {
65     mStatus = set(inputSource, sampleRate, format, channels,
66             frameCount, flags, cbf, user, notificationFrames);
67 }
68 
~AudioRecord()69 AudioRecord::~AudioRecord()
70 {
71     if (mStatus == NO_ERROR) {
72         // Make sure that callback function exits in the case where
73         // it is looping on buffer empty condition in obtainBuffer().
74         // Otherwise the callback thread will never exit.
75         stop();
76         if (mClientRecordThread != 0) {
77             mClientRecordThread->requestExitAndWait();
78             mClientRecordThread.clear();
79         }
80         mAudioRecord.clear();
81         IPCThreadState::self()->flushCommands();
82         AudioSystem::releaseInput(mInput);
83     }
84 }
85 
set(int inputSource,uint32_t sampleRate,int format,uint32_t channels,int frameCount,uint32_t flags,callback_t cbf,void * user,int notificationFrames,bool threadCanCallJava)86 status_t AudioRecord::set(
87         int inputSource,
88         uint32_t sampleRate,
89         int format,
90         uint32_t channels,
91         int frameCount,
92         uint32_t flags,
93         callback_t cbf,
94         void* user,
95         int notificationFrames,
96         bool threadCanCallJava)
97 {
98 
99     LOGV("set(): sampleRate %d, channels %d, frameCount %d",sampleRate, channels, frameCount);
100     if (mAudioRecord != 0) {
101         return INVALID_OPERATION;
102     }
103 
104     if (inputSource == AUDIO_SOURCE_DEFAULT) {
105         inputSource = AUDIO_SOURCE_MIC;
106     }
107 
108     if (sampleRate == 0) {
109         sampleRate = DEFAULT_SAMPLE_RATE;
110     }
111     // these below should probably come from the audioFlinger too...
112     if (format == 0) {
113         format = AudioSystem::PCM_16_BIT;
114     }
115     // validate parameters
116     if (!AudioSystem::isValidFormat(format)) {
117         LOGE("Invalid format");
118         return BAD_VALUE;
119     }
120 
121     if (!AudioSystem::isInputChannel(channels)) {
122         return BAD_VALUE;
123     }
124     int channelCount = AudioSystem::popCount(channels);
125 
126     mInput = AudioSystem::getInput(inputSource,
127                                     sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags);
128     if (mInput == 0) {
129         LOGE("Could not get audio output for stream type %d", inputSource);
130         return BAD_VALUE;
131     }
132 
133     // validate framecount
134     size_t inputBuffSizeInBytes = -1;
135     if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &inputBuffSizeInBytes)
136             != NO_ERROR) {
137         LOGE("AudioSystem could not query the input buffer size.");
138         return NO_INIT;
139     }
140 
141     if (inputBuffSizeInBytes == 0) {
142         LOGE("Recording parameters are not supported: sampleRate %d, channelCount %d, format %d",
143             sampleRate, channelCount, format);
144         return BAD_VALUE;
145     }
146 
147     int frameSizeInBytes = channelCount * (format == AudioSystem::PCM_16_BIT ? 2 : 1);
148     if (AudioSystem::isLinearPCM(format)) {
149         frameSizeInBytes = channelCount * (format == AudioSystem::PCM_16_BIT ? sizeof(int16_t) : sizeof(int8_t));
150     } else {
151         frameSizeInBytes = sizeof(int8_t);
152     }
153 
154 
155     // We use 2* size of input buffer for ping pong use of record buffer.
156     int minFrameCount = 2 * inputBuffSizeInBytes / frameSizeInBytes;
157     LOGV("AudioRecord::set() minFrameCount = %d", minFrameCount);
158 
159     if (frameCount == 0) {
160         frameCount = minFrameCount;
161     } else if (frameCount < minFrameCount) {
162         return BAD_VALUE;
163     }
164 
165     if (notificationFrames == 0) {
166         notificationFrames = frameCount/2;
167     }
168 
169     // create the IAudioRecord
170     status_t status = openRecord(sampleRate, format, channelCount,
171                                  frameCount, flags);
172 
173     if (status != NO_ERROR) {
174         return status;
175     }
176 
177     if (cbf != 0) {
178         mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava);
179         if (mClientRecordThread == 0) {
180             return NO_INIT;
181         }
182     }
183 
184     mStatus = NO_ERROR;
185 
186     mFormat = format;
187     // Update buffer size in case it has been limited by AudioFlinger during track creation
188     mFrameCount = mCblk->frameCount;
189     mChannelCount = (uint8_t)channelCount;
190     mActive = 0;
191     mCbf = cbf;
192     mNotificationFrames = notificationFrames;
193     mRemainingFrames = notificationFrames;
194     mUserData = user;
195     // TODO: add audio hardware input latency here
196     mLatency = (1000*mFrameCount) / sampleRate;
197     mMarkerPosition = 0;
198     mMarkerReached = false;
199     mNewPosition = 0;
200     mUpdatePeriod = 0;
201     mInputSource = (uint8_t)inputSource;
202     mFlags = flags;
203 
204     return NO_ERROR;
205 }
206 
initCheck() const207 status_t AudioRecord::initCheck() const
208 {
209     return mStatus;
210 }
211 
212 // -------------------------------------------------------------------------
213 
latency() const214 uint32_t AudioRecord::latency() const
215 {
216     return mLatency;
217 }
218 
format() const219 int AudioRecord::format() const
220 {
221     return mFormat;
222 }
223 
channelCount() const224 int AudioRecord::channelCount() const
225 {
226     return mChannelCount;
227 }
228 
frameCount() const229 uint32_t AudioRecord::frameCount() const
230 {
231     return mFrameCount;
232 }
233 
frameSize() const234 int AudioRecord::frameSize() const
235 {
236     if (AudioSystem::isLinearPCM(mFormat)) {
237         return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t));
238     } else {
239         return sizeof(uint8_t);
240     }
241 }
242 
inputSource() const243 int AudioRecord::inputSource() const
244 {
245     return (int)mInputSource;
246 }
247 
248 // -------------------------------------------------------------------------
249 
start()250 status_t AudioRecord::start()
251 {
252     status_t ret = NO_ERROR;
253     sp<ClientRecordThread> t = mClientRecordThread;
254 
255     LOGV("start");
256 
257     if (t != 0) {
258         if (t->exitPending()) {
259             if (t->requestExitAndWait() == WOULD_BLOCK) {
260                 LOGE("AudioRecord::start called from thread");
261                 return WOULD_BLOCK;
262             }
263         }
264         t->mLock.lock();
265      }
266 
267     if (android_atomic_or(1, &mActive) == 0) {
268         ret = AudioSystem::startInput(mInput);
269         if (ret == NO_ERROR) {
270             ret = mAudioRecord->start();
271             if (ret == DEAD_OBJECT) {
272                 LOGV("start() dead IAudioRecord: creating a new one");
273                 ret = openRecord(mCblk->sampleRate, mFormat, mChannelCount,
274                         mFrameCount, mFlags);
275             }
276             if (ret == NO_ERROR) {
277                 mNewPosition = mCblk->user + mUpdatePeriod;
278                 mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
279                 mCblk->waitTimeMs = 0;
280                 if (t != 0) {
281                    t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT);
282                 } else {
283                     setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
284                 }
285             } else {
286                 LOGV("start() failed");
287                 AudioSystem::stopInput(mInput);
288                 android_atomic_and(~1, &mActive);
289             }
290         }
291     }
292 
293     if (t != 0) {
294         t->mLock.unlock();
295     }
296 
297     return ret;
298 }
299 
stop()300 status_t AudioRecord::stop()
301 {
302     sp<ClientRecordThread> t = mClientRecordThread;
303 
304     LOGV("stop");
305 
306     if (t != 0) {
307         t->mLock.lock();
308      }
309 
310     if (android_atomic_and(~1, &mActive) == 1) {
311         mCblk->cv.signal();
312         mAudioRecord->stop();
313         // the record head position will reset to 0, so if a marker is set, we need
314         // to activate it again
315         mMarkerReached = false;
316         if (t != 0) {
317             t->requestExit();
318         } else {
319             setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
320         }
321         AudioSystem::stopInput(mInput);
322     }
323 
324     if (t != 0) {
325         t->mLock.unlock();
326     }
327 
328     return NO_ERROR;
329 }
330 
stopped() const331 bool AudioRecord::stopped() const
332 {
333     return !mActive;
334 }
335 
getSampleRate()336 uint32_t AudioRecord::getSampleRate()
337 {
338     return mCblk->sampleRate;
339 }
340 
setMarkerPosition(uint32_t marker)341 status_t AudioRecord::setMarkerPosition(uint32_t marker)
342 {
343     if (mCbf == 0) return INVALID_OPERATION;
344 
345     mMarkerPosition = marker;
346     mMarkerReached = false;
347 
348     return NO_ERROR;
349 }
350 
getMarkerPosition(uint32_t * marker)351 status_t AudioRecord::getMarkerPosition(uint32_t *marker)
352 {
353     if (marker == 0) return BAD_VALUE;
354 
355     *marker = mMarkerPosition;
356 
357     return NO_ERROR;
358 }
359 
setPositionUpdatePeriod(uint32_t updatePeriod)360 status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
361 {
362     if (mCbf == 0) return INVALID_OPERATION;
363 
364     uint32_t curPosition;
365     getPosition(&curPosition);
366     mNewPosition = curPosition + updatePeriod;
367     mUpdatePeriod = updatePeriod;
368 
369     return NO_ERROR;
370 }
371 
getPositionUpdatePeriod(uint32_t * updatePeriod)372 status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod)
373 {
374     if (updatePeriod == 0) return BAD_VALUE;
375 
376     *updatePeriod = mUpdatePeriod;
377 
378     return NO_ERROR;
379 }
380 
getPosition(uint32_t * position)381 status_t AudioRecord::getPosition(uint32_t *position)
382 {
383     if (position == 0) return BAD_VALUE;
384 
385     *position = mCblk->user;
386 
387     return NO_ERROR;
388 }
389 
390 
391 // -------------------------------------------------------------------------
392 
openRecord(uint32_t sampleRate,int format,int channelCount,int frameCount,uint32_t flags)393 status_t AudioRecord::openRecord(
394         uint32_t sampleRate,
395         int format,
396         int channelCount,
397         int frameCount,
398         uint32_t flags)
399 {
400     status_t status;
401     const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
402     if (audioFlinger == 0) {
403         return NO_INIT;
404     }
405 
406     sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), mInput,
407                                                        sampleRate, format,
408                                                        channelCount,
409                                                        frameCount,
410                                                        ((uint16_t)flags) << 16,
411                                                        &status);
412     if (record == 0) {
413         LOGE("AudioFlinger could not create record track, status: %d", status);
414         return status;
415     }
416     sp<IMemory> cblk = record->getCblk();
417     if (cblk == 0) {
418         LOGE("Could not get control block");
419         return NO_INIT;
420     }
421     mAudioRecord.clear();
422     mAudioRecord = record;
423     mCblkMemory.clear();
424     mCblkMemory = cblk;
425     mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
426     mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
427     mCblk->out = 0;
428 
429     return NO_ERROR;
430 }
431 
obtainBuffer(Buffer * audioBuffer,int32_t waitCount)432 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
433 {
434     int active;
435     status_t result;
436     audio_track_cblk_t* cblk = mCblk;
437     uint32_t framesReq = audioBuffer->frameCount;
438     uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS;
439 
440     audioBuffer->frameCount  = 0;
441     audioBuffer->size        = 0;
442 
443     uint32_t framesReady = cblk->framesReady();
444 
445     if (framesReady == 0) {
446         cblk->lock.lock();
447         goto start_loop_here;
448         while (framesReady == 0) {
449             active = mActive;
450             if (UNLIKELY(!active)) {
451                 cblk->lock.unlock();
452                 return NO_MORE_BUFFERS;
453             }
454             if (UNLIKELY(!waitCount)) {
455                 cblk->lock.unlock();
456                 return WOULD_BLOCK;
457             }
458             result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
459             if (__builtin_expect(result!=NO_ERROR, false)) {
460                 cblk->waitTimeMs += waitTimeMs;
461                 if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
462                     LOGW(   "obtainBuffer timed out (is the CPU pegged?) "
463                             "user=%08x, server=%08x", cblk->user, cblk->server);
464                     cblk->lock.unlock();
465                     result = mAudioRecord->start();
466                     if (result == DEAD_OBJECT) {
467                         LOGW("obtainBuffer() dead IAudioRecord: creating a new one");
468                         result = openRecord(cblk->sampleRate, mFormat, mChannelCount,
469                                             mFrameCount, mFlags);
470                         if (result == NO_ERROR) {
471                             cblk = mCblk;
472                             cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
473                         }
474                     }
475                     cblk->lock.lock();
476                     cblk->waitTimeMs = 0;
477                 }
478                 if (--waitCount == 0) {
479                     cblk->lock.unlock();
480                     return TIMED_OUT;
481                 }
482             }
483             // read the server count again
484         start_loop_here:
485             framesReady = cblk->framesReady();
486         }
487         cblk->lock.unlock();
488     }
489 
490     cblk->waitTimeMs = 0;
491 
492     if (framesReq > framesReady) {
493         framesReq = framesReady;
494     }
495 
496     uint32_t u = cblk->user;
497     uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
498 
499     if (u + framesReq > bufferEnd) {
500         framesReq = bufferEnd - u;
501     }
502 
503     audioBuffer->flags       = 0;
504     audioBuffer->channelCount= mChannelCount;
505     audioBuffer->format      = mFormat;
506     audioBuffer->frameCount  = framesReq;
507     audioBuffer->size        = framesReq*cblk->frameSize;
508     audioBuffer->raw         = (int8_t*)cblk->buffer(u);
509     active = mActive;
510     return active ? status_t(NO_ERROR) : status_t(STOPPED);
511 }
512 
releaseBuffer(Buffer * audioBuffer)513 void AudioRecord::releaseBuffer(Buffer* audioBuffer)
514 {
515     audio_track_cblk_t* cblk = mCblk;
516     cblk->stepUser(audioBuffer->frameCount);
517 }
518 
519 // -------------------------------------------------------------------------
520 
read(void * buffer,size_t userSize)521 ssize_t AudioRecord::read(void* buffer, size_t userSize)
522 {
523     ssize_t read = 0;
524     Buffer audioBuffer;
525     int8_t *dst = static_cast<int8_t*>(buffer);
526 
527     if (ssize_t(userSize) < 0) {
528         // sanity-check. user is most-likely passing an error code.
529         LOGE("AudioRecord::read(buffer=%p, size=%u (%d)",
530                 buffer, userSize, userSize);
531         return BAD_VALUE;
532     }
533 
534     LOGV("read size: %d", userSize);
535 
536     do {
537 
538         audioBuffer.frameCount = userSize/frameSize();
539 
540         // Calling obtainBuffer() with a negative wait count causes
541         // an (almost) infinite wait time.
542         status_t err = obtainBuffer(&audioBuffer, -1);
543         if (err < 0) {
544             // out of buffers, return #bytes written
545             if (err == status_t(NO_MORE_BUFFERS))
546                 break;
547             return ssize_t(err);
548         }
549 
550         size_t bytesRead = audioBuffer.size;
551         memcpy(dst, audioBuffer.i8, bytesRead);
552 
553         dst += bytesRead;
554         userSize -= bytesRead;
555         read += bytesRead;
556 
557         releaseBuffer(&audioBuffer);
558     } while (userSize);
559 
560     return read;
561 }
562 
563 // -------------------------------------------------------------------------
564 
processAudioBuffer(const sp<ClientRecordThread> & thread)565 bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread)
566 {
567     Buffer audioBuffer;
568     uint32_t frames = mRemainingFrames;
569     size_t readSize;
570 
571     // Manage marker callback
572     if (!mMarkerReached && (mMarkerPosition > 0)) {
573         if (mCblk->user >= mMarkerPosition) {
574             mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition);
575             mMarkerReached = true;
576         }
577     }
578 
579     // Manage new position callback
580     if (mUpdatePeriod > 0) {
581         while (mCblk->user >= mNewPosition) {
582             mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition);
583             mNewPosition += mUpdatePeriod;
584         }
585     }
586 
587     do {
588         audioBuffer.frameCount = frames;
589         // Calling obtainBuffer() with a wait count of 1
590         // limits wait time to WAIT_PERIOD_MS. This prevents from being
591         // stuck here not being able to handle timed events (position, markers).
592         status_t err = obtainBuffer(&audioBuffer, 1);
593         if (err < NO_ERROR) {
594             if (err != TIMED_OUT) {
595                 LOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up.");
596                 return false;
597             }
598             break;
599         }
600         if (err == status_t(STOPPED)) return false;
601 
602         size_t reqSize = audioBuffer.size;
603         mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
604         readSize = audioBuffer.size;
605 
606         // Sanity check on returned size
607         if (ssize_t(readSize) <= 0) {
608             // The callback is done filling buffers
609             // Keep this thread going to handle timed events and
610             // still try to get more data in intervals of WAIT_PERIOD_MS
611             // but don't just loop and block the CPU, so wait
612             usleep(WAIT_PERIOD_MS*1000);
613             break;
614         }
615         if (readSize > reqSize) readSize = reqSize;
616 
617         audioBuffer.size = readSize;
618         audioBuffer.frameCount = readSize/frameSize();
619         frames -= audioBuffer.frameCount;
620 
621         releaseBuffer(&audioBuffer);
622 
623     } while (frames);
624 
625 
626     // Manage overrun callback
627     if (mActive && (mCblk->framesAvailable_l() == 0)) {
628         LOGV("Overrun user: %x, server: %x, flowControlFlag %d", mCblk->user, mCblk->server, mCblk->flowControlFlag);
629         if (mCblk->flowControlFlag == 0) {
630             mCbf(EVENT_OVERRUN, mUserData, 0);
631             mCblk->flowControlFlag = 1;
632         }
633     }
634 
635     if (frames == 0) {
636         mRemainingFrames = mNotificationFrames;
637     } else {
638         mRemainingFrames = frames;
639     }
640     return true;
641 }
642 
643 // =========================================================================
644 
ClientRecordThread(AudioRecord & receiver,bool bCanCallJava)645 AudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava)
646     : Thread(bCanCallJava), mReceiver(receiver)
647 {
648 }
649 
threadLoop()650 bool AudioRecord::ClientRecordThread::threadLoop()
651 {
652     return mReceiver.processAudioBuffer(this);
653 }
654 
655 // -------------------------------------------------------------------------
656 
657 }; // namespace android
658 
659