AudioSource::AudioSource( audio_source_t inputSource, const String16 &opPackageName, uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate, uid_t uid, pid_t pid) : mStarted(false), mSampleRate(sampleRate), mOutSampleRate(outSampleRate > 0 ? outSampleRate : sampleRate), mTrackMaxAmplitude(false), mStartTimeUs(0), mMaxAmplitude(0), mPrevSampleTimeUs(0), mInitialReadTimeUs(0), mNumFramesReceived(0), mNumFramesSkipped(0), mNumFramesLost(0), mNumClientOwnedBuffers(0) { ALOGV("sampleRate: %u, outSampleRate: %u, channelCount: %u", sampleRate, outSampleRate, channelCount); CHECK(channelCount == 1 || channelCount == 2); CHECK(sampleRate > 0); size_t minFrameCount; status_t status = AudioRecord::getMinFrameCount(&minFrameCount, sampleRate, AUDIO_FORMAT_PCM_16_BIT, audio_channel_in_mask_from_count(channelCount)); if (status == OK) { // make sure that the AudioRecord callback never returns more than the maximum // buffer size uint32_t frameCount = kMaxBufferSize / sizeof(int16_t) / channelCount; // make sure that the AudioRecord total buffer size is large enough size_t bufCount = 2; while ((bufCount * frameCount) < minFrameCount) { bufCount++; } mRecord = new AudioRecord( inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT, audio_channel_in_mask_from_count(channelCount), opPackageName, (size_t) (bufCount * frameCount), AudioRecordCallbackFunction, this, frameCount /*notificationFrames*/, AUDIO_SESSION_ALLOCATE, AudioRecord::TRANSFER_DEFAULT, AUDIO_INPUT_FLAG_NONE, uid, pid); mInitCheck = mRecord->initCheck(); if (mInitCheck != OK) { mRecord.clear(); } } else { mInitCheck = status; } }
AudioSource::AudioSource( audio_source_t inputSource, uint32_t sampleRate, uint32_t channelCount) : mStarted(false), mSampleRate(sampleRate), mPrevSampleTimeUs(0), mNumFramesReceived(0), mNumClientOwnedBuffers(0) { #ifdef MTK_AOSP_ENHANCEMENT ALOGI("AudioSource constructor sampleRate: %d, channelCount: %d", sampleRate, channelCount); #else ALOGV("sampleRate: %d, channelCount: %d", sampleRate, channelCount); #endif CHECK(channelCount == 1 || channelCount == 2); size_t minFrameCount; status_t status = AudioRecord::getMinFrameCount(&minFrameCount, sampleRate, AUDIO_FORMAT_PCM_16_BIT, audio_channel_in_mask_from_count(channelCount)); if (status == OK) { // make sure that the AudioRecord callback never returns more than the maximum // buffer size uint32_t frameCount = kMaxBufferSize / sizeof(int16_t) / channelCount; // make sure that the AudioRecord total buffer size is large enough size_t bufCount = 2; while ((bufCount * frameCount) < minFrameCount) { bufCount++; } mRecord = new AudioRecord( inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT, audio_channel_in_mask_from_count(channelCount), (size_t) (bufCount * frameCount), AudioRecordCallbackFunction, this, frameCount /*notificationFrames*/); mInitCheck = mRecord->initCheck(); #ifdef MTK_AOSP_ENHANCEMENT ALOGI("AudioSource constructor, getMinFrameCount return minFrameCount =%d",minFrameCount); ALOGI("AudioSource constructor, buffer requirment: frameCount,=%d,bufCount =%d,mInitCheck=%d",\ frameCount,bufCount,mInitCheck); #endif } else { mInitCheck = status; #ifdef MTK_AOSP_ENHANCEMENT ALOGI("AudioSource constructor, getMinFrameCount fail !!!,mInitCheck=%d",mInitCheck); #endif } }
AudioSource::AudioSource( audio_source_t inputSource, uint32_t sampleRate, String8 Params, uint32_t channelCount) : mRecord(NULL), mStarted(false), mSampleRate(sampleRate), mPrevSampleTimeUs(0), mNumFramesReceived(0), mNumClientOwnedBuffers(0) { ALOGI("sampleRate: %d, channelCount: %d", sampleRate, channelCount); CHECK(channelCount == 1 || channelCount == 2); size_t minFrameCount; status_t status = AudioRecord::getMinFrameCount(&minFrameCount, sampleRate, AUDIO_FORMAT_PCM_16_BIT, audio_channel_in_mask_from_count(channelCount)); if (status == OK) { // make sure that the AudioRecord callback never returns more than the maximum // buffer size int frameCount = kMaxBufferSize / sizeof(int16_t) / channelCount; // make sure that the AudioRecord total buffer size is large enough int bufCount = 2; while ((bufCount * frameCount) < minFrameCount) { bufCount++; } int iframecount = bufCount * frameCount; iframecount >>=1; ALOGD("minFrameCount=%d,iframecount=%d,total framecount=%d,notify framecount=%d", minFrameCount,iframecount,iframecount*3,iframecount>>1); mRecord = new AudioRecord( inputSource, Params, sampleRate, AUDIO_FORMAT_PCM_16_BIT, audio_channel_in_mask_from_count(channelCount), 3*iframecount, AudioRecordCallbackFunction, this, iframecount); mInitCheck = mRecord->initCheck(); ALOGI("AudioSource constructor, getMinFrameCount return minFrameCount =%d",minFrameCount); ALOGI("AudioSource constructor, buffer requirment: frameCount,=%d,bufCount =%d,mInitCheck=%d",\ frameCount,bufCount,mInitCheck); } else {
AudioSource::AudioSource( audio_source_t inputSource, uint32_t sampleRate, uint32_t channelCount) : mRecord(NULL), mStarted(false), mSampleRate(sampleRate), mPrevSampleTimeUs(0), mNumFramesReceived(0), mNumClientOwnedBuffers(0) { ALOGV("sampleRate: %d, channelCount: %d", sampleRate, channelCount); CHECK(channelCount == 1 || channelCount == 2); int minFrameCount; status_t status = AudioRecord::getMinFrameCount(&minFrameCount, sampleRate, AUDIO_FORMAT_PCM_16_BIT, audio_channel_in_mask_from_count(channelCount)); if (status == OK) { // make sure that the AudioRecord callback never returns more than the maximum // buffer size int frameCount = kMaxBufferSize / sizeof(int16_t) / channelCount; // make sure that the AudioRecord total buffer size is large enough int bufCount = 2; while ((bufCount * frameCount) < minFrameCount) { bufCount++; } mRecord = new AudioRecord( inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT, audio_channel_in_mask_from_count(channelCount), bufCount * frameCount, AudioRecordCallbackFunction, this, frameCount); mInitCheck = mRecord->initCheck(); } else { mInitCheck = status; } }
static int adev_open_input_stream(struct audio_hw_device *dev, audio_io_handle_t handle, audio_devices_t devices, struct audio_config *config, struct audio_stream_in **stream_in, audio_input_flags_t flags __unused, const char *address /*__unused*/, audio_source_t source __unused) { ALOGV("in adev_open_input_stream() rate:%" PRIu32 ", chanMask:0x%" PRIX32 ", fmt:%" PRIu8, config->sample_rate, config->channel_mask, config->format); struct stream_in *in = (struct stream_in *)calloc(1, sizeof(struct stream_in)); int ret = 0; if (in == NULL) return -ENOMEM; /* setup function pointers */ in->stream.common.get_sample_rate = in_get_sample_rate; in->stream.common.set_sample_rate = in_set_sample_rate; in->stream.common.get_buffer_size = in_get_buffer_size; in->stream.common.get_channels = in_get_channels; in->stream.common.get_format = in_get_format; in->stream.common.set_format = in_set_format; in->stream.common.standby = in_standby; in->stream.common.dump = in_dump; in->stream.common.set_parameters = in_set_parameters; in->stream.common.get_parameters = in_get_parameters; in->stream.common.add_audio_effect = in_add_audio_effect; in->stream.common.remove_audio_effect = in_remove_audio_effect; in->stream.set_gain = in_set_gain; in->stream.read = in_read; in->stream.get_input_frames_lost = in_get_input_frames_lost; pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL); pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL); in->dev = (struct audio_device *)dev; pthread_mutex_lock(&in->dev->lock); in->profile = &in->dev->in_profile; struct pcm_config proxy_config; memset(&proxy_config, 0, sizeof(proxy_config)); /* Pull out the card/device pair */ parse_card_device_params(false, &(in->profile->card), &(in->profile->device)); profile_read_device_info(in->profile); pthread_mutex_unlock(&in->dev->lock); /* Rate */ if (config->sample_rate == 0) { proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(in->profile); } else if (profile_is_sample_rate_valid(in->profile, config->sample_rate)) { proxy_config.rate = config->sample_rate; } else { ALOGE("%s: The requested sample rate (%d) is not valid", __func__, config->sample_rate); proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(in->profile); ret = -EINVAL; } /* Format */ if (config->format == AUDIO_FORMAT_DEFAULT) { proxy_config.format = profile_get_default_format(in->profile); config->format = audio_format_from_pcm_format(proxy_config.format); } else { enum pcm_format fmt = pcm_format_from_audio_format(config->format); if (profile_is_format_valid(in->profile, fmt)) { proxy_config.format = fmt; } else { ALOGE("%s: The requested format (0x%x) is not valid", __func__, config->format); proxy_config.format = profile_get_default_format(in->profile); config->format = audio_format_from_pcm_format(proxy_config.format); ret = -EINVAL; } } /* Channels */ unsigned proposed_channel_count = 0; if (k_force_channels) { proposed_channel_count = k_force_channels; } else if (config->channel_mask == AUDIO_CHANNEL_NONE) { proposed_channel_count = profile_get_default_channel_count(in->profile); } if (proposed_channel_count != 0) { config->channel_mask = audio_channel_in_mask_from_count(proposed_channel_count); if (config->channel_mask == AUDIO_CHANNEL_INVALID) config->channel_mask = audio_channel_mask_for_index_assignment_from_count(proposed_channel_count); in->hal_channel_count = proposed_channel_count; } else { in->hal_channel_count = audio_channel_count_from_in_mask(config->channel_mask); } /* we can expose any channel mask, and emulate internally based on channel count. */ in->hal_channel_mask = config->channel_mask; proxy_config.channels = profile_get_default_channel_count(in->profile); proxy_prepare(&in->proxy, in->profile, &proxy_config); in->standby = true; in->conversion_buffer = NULL; in->conversion_buffer_size = 0; *stream_in = &in->stream; return ret; }
AudioSource::AudioSource( audio_source_t inputSource, uint32_t sampleRate, uint32_t channelCount) : mRecord(NULL), mStarted(false), mSampleRate(sampleRate), mPrevSampleTimeUs(0), mNumFramesReceived(0), mNumClientOwnedBuffers(0) #ifdef QCOM_ENHANCED_AUDIO ,mFormat(AUDIO_FORMAT_PCM_16_BIT), mMime(MEDIA_MIMETYPE_AUDIO_RAW) #endif { ALOGV("sampleRate: %d, channelCount: %d", sampleRate, channelCount); CHECK(channelCount == 1 || channelCount == 2 || channelCount == 6); int minFrameCount; status_t status = AudioRecord::getMinFrameCount(&minFrameCount, sampleRate, AUDIO_FORMAT_PCM_16_BIT, audio_channel_in_mask_from_count(channelCount)); #ifdef QCOM_ENHANCED_AUDIO if ( NO_ERROR != AudioSystem::getInputBufferSize( sampleRate, mFormat, channelCount, (size_t*)&mMaxBufferSize) ) { mMaxBufferSize = kMaxBufferSize; ALOGV("mMaxBufferSize = %d", mMaxBufferSize); } #endif if (status == OK) { // make sure that the AudioRecord callback never returns more than the maximum // buffer size #ifdef QCOM_ENHANCED_AUDIO int frameCount = mMaxBufferSize / sizeof(int16_t) / channelCount; #else int frameCount = kMaxBufferSize / sizeof(int16_t) / channelCount; #endif // make sure that the AudioRecord total buffer size is large enough int bufCount = 2; while ((bufCount * frameCount) < minFrameCount) { bufCount++; } mRecord = new AudioRecord( inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT, audio_channel_in_mask_from_count(channelCount), #ifdef QCOM_ENHANCED_AUDIO 4 * mMaxBufferSize / sizeof(int16_t), /* Enable ping-pong buffers */ #else bufCount * frameCount, #endif AudioRecordCallbackFunction, this, frameCount); mInitCheck = mRecord->initCheck(); //configure the auto ramp start duration mAutoRampStartUs = kAutoRampStartUs; uint32_t playbackLatencyMs = 0; if (AudioSystem::getOutputLatency(&playbackLatencyMs, AUDIO_STREAM_DEFAULT) == OK) { if (2*playbackLatencyMs*1000LL > kAutoRampStartUs) { mAutoRampStartUs = 2*playbackLatencyMs*1000LL; } } ALOGD("Start autoramp from %lld", mAutoRampStartUs); } else { mInitCheck = status; } }
//----------------------------------------------------------------------------- SLresult android_audioRecorder_realize(CAudioRecorder* ar, SLboolean async) { SL_LOGV("android_audioRecorder_realize(%p) entering", ar); SLresult result = SL_RESULT_SUCCESS; // already checked in created and checkSourceSink assert(ar->mDataSink.mLocator.mLocatorType == SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE); const SLDataFormat_PCM *df_pcm = &ar->mDataSink.mFormat.mPCM; // the following platform-independent fields have been initialized in CreateAudioRecorder() // ar->mNumChannels // ar->mSampleRateMilliHz uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec); checkAndSetPerformanceModePre(ar); audio_input_flags_t policy; switch (ar->mPerformanceMode) { case ANDROID_PERFORMANCE_MODE_NONE: case ANDROID_PERFORMANCE_MODE_POWER_SAVING: policy = AUDIO_INPUT_FLAG_NONE; break; case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS: policy = AUDIO_INPUT_FLAG_FAST; break; case ANDROID_PERFORMANCE_MODE_LATENCY: default: policy = (audio_input_flags_t)(AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW); break; } SL_LOGV("Audio Record format: %dch(0x%x), %dbit, %dKHz", df_pcm->numChannels, df_pcm->channelMask, df_pcm->bitsPerSample, df_pcm->samplesPerSec / 1000000); // note that df_pcm->channelMask has already been validated during object creation. audio_channel_mask_t channelMask = sles_to_audio_input_channel_mask(df_pcm->channelMask); // To maintain backward compatibility with previous releases, ignore // channel masks that are not indexed. if (channelMask == AUDIO_CHANNEL_INVALID || audio_channel_mask_get_representation(channelMask) == AUDIO_CHANNEL_REPRESENTATION_POSITION) { channelMask = audio_channel_in_mask_from_count(df_pcm->numChannels); SL_LOGI("Emulating old channel mask behavior " "(ignoring positional mask %#x, using default mask %#x based on " "channel count of %d)", df_pcm->channelMask, channelMask, df_pcm->numChannels); } SL_LOGV("SLES channel mask %#x converted to Android mask %#x", df_pcm->channelMask, channelMask); // initialize platform-specific CAudioRecorder fields ar->mAudioRecord = new android::AudioRecord( ar->mRecordSource, // source sampleRate, // sample rate in Hertz sles_to_android_sampleFormat(df_pcm), // format channelMask, // channel mask android::String16(), // app ops 0, // frameCount audioRecorder_callback,// callback_t (void*)ar, // user, callback data, here the AudioRecorder 0, // notificationFrames AUDIO_SESSION_ALLOCATE, android::AudioRecord::TRANSFER_CALLBACK, // transfer type policy); // audio_input_flags_t android::status_t status = ar->mAudioRecord->initCheck(); if (android::NO_ERROR != status) { SL_LOGE("android_audioRecorder_realize(%p) error creating AudioRecord object; status %d", ar, status); // FIXME should return a more specific result depending on status result = SL_RESULT_CONTENT_UNSUPPORTED; ar->mAudioRecord.clear(); return result; } // update performance mode according to actual flags granted to AudioRecord checkAndSetPerformanceModePost(ar); // If there is a JavaAudioRoutingProxy associated with this recorder, hook it up... JNIEnv* j_env = NULL; jclass clsAudioRecord = NULL; jmethodID midRoutingProxy_connect = NULL; if (ar->mAndroidConfiguration.mRoutingProxy != NULL && (j_env = android::AndroidRuntime::getJNIEnv()) != NULL && (clsAudioRecord = j_env->FindClass("android/media/AudioRecord")) != NULL && (midRoutingProxy_connect = j_env->GetMethodID(clsAudioRecord, "deferred_connect", "(J)V")) != NULL) { j_env->ExceptionClear(); j_env->CallVoidMethod(ar->mAndroidConfiguration.mRoutingProxy, midRoutingProxy_connect, ar->mAudioRecord.get()); if (j_env->ExceptionCheck()) { SL_LOGE("Java exception releasing recorder routing object."); result = SL_RESULT_INTERNAL_ERROR; ar->mAudioRecord.clear(); return result; } } if (ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY) { audio_session_t sessionId = ar->mAudioRecord->getSessionId(); // initialize AEC effect_descriptor_t *descriptor = &ar->mAcousticEchoCancellation.mAECDescriptor; if (memcmp(SL_IID_ANDROIDACOUSTICECHOCANCELLATION, &descriptor->type, sizeof(effect_uuid_t)) == 0) { if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) || (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { SL_LOGV("Need to initialize AEC for AudioRecorder=%p", ar); android_aec_init(sessionId, &ar->mAcousticEchoCancellation); } } // initialize AGC descriptor = &ar->mAutomaticGainControl.mAGCDescriptor; if (memcmp(SL_IID_ANDROIDAUTOMATICGAINCONTROL, &descriptor->type, sizeof(effect_uuid_t)) == 0) { if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) || (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { SL_LOGV("Need to initialize AGC for AudioRecorder=%p", ar); android_agc_init(sessionId, &ar->mAutomaticGainControl); } } // initialize NS descriptor = &ar->mNoiseSuppression.mNSDescriptor; if (memcmp(SL_IID_ANDROIDNOISESUPPRESSION, &descriptor->type, sizeof(effect_uuid_t)) == 0) { if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) || (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { SL_LOGV("Need to initialize NS for AudioRecorder=%p", ar); android_ns_init(sessionId, &ar->mNoiseSuppression); } } } return result; }