Beispiel #1
0
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;
    }
}
Beispiel #2
0
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
    }
}
Beispiel #3
0
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;
}