Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3207e7e3 authored by Sidipotu Ashok's avatar Sidipotu Ashok Committed by Gerrit Code Review
Browse files

audio: VOIP bringup and support for vocoders

Change-Id: I601d72866baa9846263831664dc6e68cad72625c
parent 12e95d42
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -10637,7 +10637,12 @@ package android.media {
    field public static final int CHANNEL_OUT_QUAD = 204; // 0xcc
    field public static final int CHANNEL_OUT_STEREO = 12; // 0xc
    field public static final int CHANNEL_OUT_SURROUND = 1052; // 0x41c
    field public static final int ENCODING_AMRNB = 100; // 0x64
    field public static final int ENCODING_AMRWB = 101; // 0x65
    field public static final int ENCODING_DEFAULT = 1; // 0x1
    field public static final int ENCODING_EVRC = 102; // 0x66
    field public static final int ENCODING_EVRCB = 103; // 0x67
    field public static final int ENCODING_EVRCWB = 104; // 0x68
    field public static final int ENCODING_INVALID = 0; // 0x0
    field public static final int ENCODING_PCM_16BIT = 2; // 0x2
    field public static final int ENCODING_PCM_8BIT = 3; // 0x3
+60 −8
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008 The Android Open Source Project
 * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -49,6 +50,11 @@ struct fields_t {
    jmethodID postNativeEventInJava; //... event post callback method
    int       PCM16;                 //...  format constants
    int       PCM8;                  //...  format constants
    int       AMRNB;                 //...  format constants
    int       AMRWB;                 //...  format constants
    int       EVRC;                  //...  format constants
    int       EVRCB;                 //...  format constants
    int       EVRCWB;                //...  format constants
    jfieldID  nativeRecorderInJavaObj; // provides access to the C++ AudioRecord object
    jfieldID  nativeCallbackCookie;    // provides access to the AudioRecord callback data
};
@@ -162,6 +168,24 @@ static sp<AudioRecord> setAudioRecord(JNIEnv* env, jobject thiz, const sp<AudioR
    env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, (int)ar.get());
    return old;
}
int getformatrec(int audioformat)
{
    if(audioformat==javaAudioRecordFields.PCM16)
        return AUDIO_FORMAT_PCM_16_BIT;
#ifdef QCOM_HARDWARE
    else if(audioformat==javaAudioRecordFields.AMRNB)
        return AUDIO_FORMAT_AMR_NB;
    else if(audioformat==javaAudioRecordFields.AMRWB)
        return AUDIO_FORMAT_AMR_WB;
    else if(audioformat==javaAudioRecordFields.EVRC)
        return AUDIO_FORMAT_EVRC;
    else if(audioformat==javaAudioRecordFields.EVRCB)
        return AUDIO_FORMAT_EVRCB;
    else if(audioformat==javaAudioRecordFields.EVRCWB)
        return AUDIO_FORMAT_EVRCWB;
#endif
    return AUDIO_FORMAT_PCM_8_BIT;
}

// ----------------------------------------------------------------------------
static int
@@ -181,14 +205,23 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,

    // compare the format against the Java constants
    if ((audioFormat != javaAudioRecordFields.PCM16)
#ifdef QCOM_HARDWARE
        && (audioFormat != javaAudioRecordFields.AMRNB)
        && (audioFormat != javaAudioRecordFields.AMRWB)
        && (audioFormat != javaAudioRecordFields.EVRC)
        && (audioFormat != javaAudioRecordFields.EVRCB)
        && (audioFormat != javaAudioRecordFields.EVRCWB)
#endif
        && (audioFormat != javaAudioRecordFields.PCM8)) {
        ALOGE("Error creating AudioRecord: unsupported audio format.");
        return AUDIORECORD_ERROR_SETUP_INVALIDFORMAT;
    }

    int bytesPerSample = audioFormat==javaAudioRecordFields.PCM16 ? 2 : 1;
    audio_format_t format = audioFormat==javaAudioRecordFields.PCM16 ?
            AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_8_BIT;
    int bytesPerSample;
    if(audioFormat == javaAudioRecordFields.PCM8)
        bytesPerSample = 1;
    else
        bytesPerSample = 2;
    audio_format_t format = (audio_format_t)getformatrec(audioFormat);

    if (buffSizeInBytes == 0) {
         ALOGE("Error creating AudioRecord: frameCount is 0.");
@@ -515,8 +548,7 @@ static jint android_media_AudioRecord_get_min_buff_size(JNIEnv *env, jobject th
    int frameCount = 0;
    status_t result = AudioRecord::getMinFrameCount(&frameCount,
            sampleRateInHertz,
            (audioFormat == javaAudioRecordFields.PCM16 ?
                AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_8_BIT),
            (audio_format_t)getformatrec(audioFormat),
            nbChannels);

    if (result == BAD_VALUE) {
@@ -525,7 +557,7 @@ static jint android_media_AudioRecord_get_min_buff_size(JNIEnv *env, jobject th
    if (result != NO_ERROR) {
        return -1;
    }
    return frameCount * nbChannels * (audioFormat == javaAudioRecordFields.PCM16 ? 2 : 1);
    return frameCount * nbChannels * (audioFormat == javaAudioRecordFields.PCM8 ? 1 : 2);
}


@@ -559,6 +591,11 @@ static JNINativeMethod gMethods[] = {
#define JAVA_POSTEVENT_CALLBACK_NAME  "postEventFromNative"
#define JAVA_CONST_PCM16_NAME         "ENCODING_PCM_16BIT"
#define JAVA_CONST_PCM8_NAME          "ENCODING_PCM_8BIT"
#define JAVA_CONST_AMRNB_NAME         "ENCODING_AMRNB"
#define JAVA_CONST_AMRWB_NAME         "ENCODING_AMRWB"
#define JAVA_CONST_EVRC_NAME          "ENCODING_EVRC"
#define JAVA_CONST_EVRCB_NAME         "ENCODING_EVRCB"
#define JAVA_CONST_EVRCWB_NAME        "ENCODING_EVRCWB"
#define JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME  "mNativeRecorderInJavaObj"
#define JAVA_NATIVECALLBACKINFO_FIELD_NAME       "mNativeCallbackCookie"

@@ -622,7 +659,22 @@ int register_android_media_AudioRecord(JNIEnv *env)
                JAVA_CONST_PCM16_NAME, &(javaAudioRecordFields.PCM16))
           || !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                JAVA_CONST_PCM8_NAME, &(javaAudioRecordFields.PCM8)) ) {
                JAVA_CONST_PCM8_NAME, &(javaAudioRecordFields.PCM8))
           || !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                JAVA_CONST_AMRNB_NAME, &(javaAudioRecordFields.AMRNB))
           || !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                JAVA_CONST_AMRWB_NAME, &(javaAudioRecordFields.AMRWB))
           || !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                JAVA_CONST_EVRC_NAME, &(javaAudioRecordFields.EVRC))
           || !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                JAVA_CONST_EVRCB_NAME, &(javaAudioRecordFields.EVRCB))
           || !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                JAVA_CONST_EVRCWB_NAME, &(javaAudioRecordFields.EVRCWB))) {
        // error log performed in getIntConstantFromClass()
        return -1;
    }
+111 −7
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008 The Android Open Source Project
 * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -49,6 +50,19 @@ struct fields_t {
    jmethodID postNativeEventInJava; //... event post callback method
    int       PCM16;                 //...  format constants
    int       PCM8;                  //...  format constants
    int       AMRNB;                 //...  format constants
    int       AMRWB;                 //...  format constants
    int       EVRC;                  //...  format constants
    int       EVRCB;                 //...  format constants
    int       EVRCWB;                //...  format constants
    int       STREAM_VOICE_CALL;     //...  stream type constants
    int       STREAM_SYSTEM;         //...  stream type constants
    int       STREAM_RING;           //...  stream type constants
    int       STREAM_MUSIC;          //...  stream type constants
    int       STREAM_ALARM;          //...  stream type constants
    int       STREAM_NOTIFICATION;   //...  stream type constants
    int       STREAM_BLUETOOTH_SCO;  //...  stream type constants
    int       STREAM_DTMF;           //...  stream type constants
    int       MODE_STREAM;           //...  memory mode
    int       MODE_STATIC;           //...  memory mode
    jfieldID  nativeTrackInJavaObj;  // stores in Java the native AudioTrack object
@@ -199,6 +213,25 @@ static sp<AudioTrack> setAudioTrack(JNIEnv* env, jobject thiz, const sp<AudioTra
}

// ----------------------------------------------------------------------------
int getformat(int audioformat)
{
    if(audioformat==javaAudioTrackFields.PCM16)
        return AUDIO_FORMAT_PCM_16_BIT;
#ifdef QCOM_HARDWARE
    else if(audioformat==javaAudioTrackFields.AMRNB)
        return AUDIO_FORMAT_AMR_NB;
    else if(audioformat==javaAudioTrackFields.AMRWB)
        return AUDIO_FORMAT_AMR_WB;
    else if(audioformat==javaAudioTrackFields.EVRC)
        return AUDIO_FORMAT_EVRC;
    else if(audioformat==javaAudioTrackFields.EVRCB)
        return AUDIO_FORMAT_EVRCB;
    else if(audioformat==javaAudioTrackFields.EVRCWB)
        return AUDIO_FORMAT_EVRCWB;
#endif
    return AUDIO_FORMAT_PCM_8_BIT;
}

static int
android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
        jint streamType, jint sampleRateInHertz, jint javaChannelMask,
@@ -249,7 +282,15 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th

    // check the format.
    // This function was called from Java, so we compare the format against the Java constants
    if ((audioFormat != javaAudioTrackFields.PCM16) && (audioFormat != javaAudioTrackFields.PCM8)) {
    if ((audioFormat != javaAudioTrackFields.PCM16)
#ifdef QCOM_HARDWARE
        && (audioFormat != javaAudioTrackFields.AMRNB)
        && (audioFormat != javaAudioTrackFields.AMRWB)
        && (audioFormat != javaAudioTrackFields.EVRC)
        && (audioFormat != javaAudioTrackFields.EVRCB)
        && (audioFormat != javaAudioTrackFields.EVRCWB)
#endif
        && (audioFormat != javaAudioTrackFields.PCM8)) {
        ALOGE("Error creating AudioTrack: unsupported audio format.");
        return AUDIOTRACK_ERROR_SETUP_INVALIDFORMAT;
    }
@@ -268,9 +309,12 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
    }

    // compute the frame count
    int bytesPerSample = audioFormat == javaAudioTrackFields.PCM16 ? 2 : 1;
    audio_format_t format = audioFormat == javaAudioTrackFields.PCM16 ?
            AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_8_BIT;
    int bytesPerSample;
    if(audioFormat == javaAudioTrackFields.PCM8)
        bytesPerSample = 1;
    else
        bytesPerSample = 2;
    audio_format_t format = (audio_format_t)getformat(audioFormat);
    int frameCount = buffSizeInBytes / (nbChannels * bytesPerSample);

    jclass clazz = env->GetObjectClass(thiz);
@@ -516,7 +560,12 @@ jint writeToTrack(const sp<AudioTrack>& track, jint audioFormat, jbyte* data,
    if (track->sharedBuffer() == 0) {
        written = track->write(data + offsetInBytes, sizeInBytes);
    } else {
        if (audioFormat == javaAudioTrackFields.PCM16) {
        if ((audioFormat == javaAudioTrackFields.PCM16)
        || (audioFormat == javaAudioTrackFields.AMRNB)
        || (audioFormat == javaAudioTrackFields.AMRWB)
        || (audioFormat == javaAudioTrackFields.EVRC)
        || (audioFormat == javaAudioTrackFields.EVRCB)
        || (audioFormat == javaAudioTrackFields.EVRCWB)) {
            // writing to shared memory, check for capacity
            if ((size_t)sizeInBytes > track->sharedBuffer()->size()) {
                sizeInBytes = track->sharedBuffer()->size();
@@ -791,7 +840,7 @@ static jint android_media_AudioTrack_get_min_buff_size(JNIEnv *env, jobject thi
            sampleRateInHertz) != NO_ERROR) {
        return -1;
    }
    return frameCount * nbChannels * (audioFormat == javaAudioTrackFields.PCM16 ? 2 : 1);
    return frameCount * nbChannels * (audioFormat == javaAudioTrackFields.PCM8 ? 1 : 2);
}

// ----------------------------------------------------------------------------
@@ -866,6 +915,11 @@ static JNINativeMethod gMethods[] = {
#define JAVA_POSTEVENT_CALLBACK_NAME                    "postEventFromNative"
#define JAVA_CONST_PCM16_NAME                           "ENCODING_PCM_16BIT"
#define JAVA_CONST_PCM8_NAME                            "ENCODING_PCM_8BIT"
#define JAVA_CONST_AMRNB_NAME                           "ENCODING_AMRNB"
#define JAVA_CONST_AMRWB_NAME                           "ENCODING_AMRWB"
#define JAVA_CONST_EVRC_NAME                            "ENCODING_EVRC"
#define JAVA_CONST_EVRCB_NAME                           "ENCODING_EVRCB"
#define JAVA_CONST_EVRCWB_NAME                          "ENCODING_EVRCWB"
#define JAVA_CONST_BUFFER_COUNT_NAME                    "BUFFER_COUNT"
#define JAVA_CONST_STREAM_VOICE_CALL_NAME               "STREAM_VOICE_CALL"
#define JAVA_CONST_STREAM_SYSTEM_NAME                   "STREAM_SYSTEM"
@@ -963,7 +1017,57 @@ int register_android_media_AudioTrack(JNIEnv *env)
                JAVA_CONST_PCM16_NAME, &(javaAudioTrackFields.PCM16))
           || !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                JAVA_CONST_PCM8_NAME, &(javaAudioTrackFields.PCM8)) ) {
                JAVA_CONST_PCM8_NAME, &(javaAudioTrackFields.PCM8))
           || !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                JAVA_CONST_AMRNB_NAME, &(javaAudioTrackFields.AMRNB))
           || !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                JAVA_CONST_AMRWB_NAME, &(javaAudioTrackFields.AMRWB))
           || !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                JAVA_CONST_EVRC_NAME, &(javaAudioTrackFields.EVRC))
           || !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                JAVA_CONST_EVRCB_NAME, &(javaAudioTrackFields.EVRCB))
           || !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                JAVA_CONST_EVRCWB_NAME, &(javaAudioTrackFields.EVRCWB))
) {
        // error log performed in android_media_getIntConstantFromClass()
        return -1;
    }
    // Get the stream types from the AudioManager class
    jclass audioManagerClass = NULL;
    audioManagerClass = env->FindClass(JAVA_AUDIOMANAGER_CLASS_NAME);
    if (audioManagerClass == NULL) {
       ALOGE("Can't find %s", JAVA_AUDIOMANAGER_CLASS_NAME);
       return -1;
    }
    if ( !android_media_getIntConstantFromClass(env, audioManagerClass,
               JAVA_AUDIOMANAGER_CLASS_NAME,
               JAVA_CONST_STREAM_VOICE_CALL_NAME, &(javaAudioTrackFields.STREAM_VOICE_CALL))
          || !android_media_getIntConstantFromClass(env, audioManagerClass,
               JAVA_AUDIOMANAGER_CLASS_NAME,
               JAVA_CONST_STREAM_MUSIC_NAME, &(javaAudioTrackFields.STREAM_MUSIC))
          || !android_media_getIntConstantFromClass(env, audioManagerClass,
               JAVA_AUDIOMANAGER_CLASS_NAME,
               JAVA_CONST_STREAM_SYSTEM_NAME, &(javaAudioTrackFields.STREAM_SYSTEM))
          || !android_media_getIntConstantFromClass(env, audioManagerClass,
               JAVA_AUDIOMANAGER_CLASS_NAME,
               JAVA_CONST_STREAM_RING_NAME, &(javaAudioTrackFields.STREAM_RING))
          || !android_media_getIntConstantFromClass(env, audioManagerClass,
               JAVA_AUDIOMANAGER_CLASS_NAME,
               JAVA_CONST_STREAM_ALARM_NAME, &(javaAudioTrackFields.STREAM_ALARM))
          || !android_media_getIntConstantFromClass(env, audioManagerClass,
               JAVA_AUDIOMANAGER_CLASS_NAME,
               JAVA_CONST_STREAM_NOTIFICATION_NAME, &(javaAudioTrackFields.STREAM_NOTIFICATION))
          || !android_media_getIntConstantFromClass(env, audioManagerClass,
               JAVA_AUDIOMANAGER_CLASS_NAME,
               JAVA_CONST_STREAM_BLUETOOTH_SCO_NAME, &(javaAudioTrackFields.STREAM_BLUETOOTH_SCO))
          || !android_media_getIntConstantFromClass(env, audioManagerClass,
               JAVA_AUDIOMANAGER_CLASS_NAME,
               JAVA_CONST_STREAM_DTMF_NAME, &(javaAudioTrackFields.STREAM_DTMF))) {
        // error log performed in android_media_getIntConstantFromClass()
        return -1;
    }
+7 −1
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008 The Android Open Source Project
 * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -35,7 +36,12 @@ public class AudioFormat {
    /** Audio data format: PCM 16 bit per sample. Guaranteed to be supported by devices. */
    public static final int ENCODING_PCM_16BIT = 2;
    /** Audio data format: PCM 8 bit per sample. Not guaranteed to be supported by devices. */
    public static final int ENCODING_PCM_8BIT = 3;
    public static final int ENCODING_PCM_8BIT = 3;  // accessed by native code
    public static final int ENCODING_AMRNB = 100;   // accessed by native code
    public static final int ENCODING_AMRWB = 101;   // accessed by native code
    public static final int ENCODING_EVRC = 102;    // accessed by native code
    public static final int ENCODING_EVRCB = 103;   // accessed by native code
    public static final int ENCODING_EVRCWB = 104;  // accessed by native code

    /** Invalid audio channel configuration */
    /** @deprecated use CHANNEL_INVALID instead  */
+16 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import java.nio.ByteBuffer;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemProperties;
import android.util.Log;

/**
@@ -310,6 +311,15 @@ public class AudioRecord
        case AudioFormat.ENCODING_PCM_8BIT:
            mAudioFormat = audioFormat;
            break;
        case AudioFormat.ENCODING_AMRNB:
        case AudioFormat.ENCODING_AMRWB:
        case AudioFormat.ENCODING_EVRC:
        case AudioFormat.ENCODING_EVRCB:
        case AudioFormat.ENCODING_EVRCWB:
            if (SystemProperties.QCOM_HARDWARE) {
                mAudioFormat = audioFormat;
                break;
            }
        default:
            mAudioFormat = AudioFormat.ENCODING_INVALID;
        throw (new IllegalArgumentException("Unsupported sample encoding." 
@@ -476,7 +486,12 @@ public class AudioRecord
        }
        
        // PCM_8BIT is not supported at the moment
        if (audioFormat != AudioFormat.ENCODING_PCM_16BIT) {
        if (audioFormat != AudioFormat.ENCODING_PCM_16BIT
            && audioFormat != AudioFormat.ENCODING_AMRNB
            && audioFormat != AudioFormat.ENCODING_AMRWB
            && audioFormat != AudioFormat.ENCODING_EVRC
            && audioFormat != AudioFormat.ENCODING_EVRCB
            && audioFormat != AudioFormat.ENCODING_EVRCWB) {
            loge("getMinBufferSize(): Invalid audio format.");
            return AudioRecord.ERROR_BAD_VALUE;
        }
Loading