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

Commit 73581b8f authored by Sharad Sangle's avatar Sharad Sangle Committed by Linux Build Service Account
Browse files

audio: add support for MSM audio formats

- Add support for EVRC, QCELP, and WMA formats
- Add definition for 5.1 channel recording
- Reference change If3676b88fa287b484ef8616c0a6b67177b61a720

Change-Id: I6b6e5ca98921adeadd2a3d76580fe85fb28eeaf0
(cherry picked from commit 10c4f204bb5ac78b9cf3854b536663ccd3d50333)
(cherry picked from commit 3f99cc5f134b0f00a52218ae1c0273cc11ae7702)
(cherry picked from commit 1d35b52c7c9cf1cfd3a3de372391a7a57f593af9)
parent 8e0f421d
Loading
Loading
Loading
Loading
+93 −11
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 * Not a Contribution.
 *
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
@@ -37,6 +40,13 @@ static const char* const kClassPathName = "android/media/AudioRecord";
struct fields_t {
    // these fields provide access from C++ to the...
    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
};
@@ -154,7 +164,23 @@ 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;
    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;

    return AUDIO_FORMAT_PCM_8_BIT;
}
// ----------------------------------------------------------------------------
static int
android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
@@ -173,15 +199,25 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
    uint32_t nbChannels = popcount(channelMask);

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

    int bytesPerSample = audioFormat == ENCODING_PCM_16BIT ? 2 : 1;
    audio_format_t format = audioFormat == ENCODING_PCM_16BIT ?
            AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_8_BIT;
    int bytesPerSample;
    if(audioFormat == javaAudioRecordFields.PCM8)
        bytesPerSample = 1;
    else if((audioFormat == javaAudioRecordFields.AMRWB) &&
            ((uint32_t)source != AUDIO_SOURCE_VOICE_COMMUNICATION))
        bytesPerSample = 61;
    else
        bytesPerSample = 2;
    audio_format_t format = (audio_format_t)getformatrec(audioFormat);

    if (buffSizeInBytes == 0) {
         ALOGE("Error creating AudioRecord: frameCount is 0.");
@@ -513,9 +549,8 @@ static jint android_media_AudioRecord_get_min_buff_size(JNIEnv *env, jobject th
    size_t frameCount = 0;
    status_t result = AudioRecord::getMinFrameCount(&frameCount,
            sampleRateInHertz,
            (audioFormat == ENCODING_PCM_16BIT ?
                AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_8_BIT),
            audio_channel_in_mask_from_count(nbChannels));
            (audio_format_t)getformatrec(audioFormat),
            nbChannels);

    if (result == BAD_VALUE) {
        return 0;
@@ -523,7 +558,14 @@ static jint android_media_AudioRecord_get_min_buff_size(JNIEnv *env, jobject th
    if (result != NO_ERROR) {
        return -1;
    }
    return frameCount * nbChannels * (audioFormat == ENCODING_PCM_16BIT ? 2 : 1);
    int bytesPerSample;
    if(audioFormat == javaAudioRecordFields.PCM8)
        bytesPerSample = 1;
    else if(audioFormat == javaAudioRecordFields.AMRWB)
        bytesPerSample = 61;
    else
        bytesPerSample = 2;
    return frameCount * nbChannels * bytesPerSample;
}


@@ -555,8 +597,18 @@ static JNINativeMethod gMethods[] = {

// field names found in android/media/AudioRecord.java
#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"
#define JAVA_AUDIOFORMAT_CLASS_NAME "android/media/AudioFormat"
extern bool android_media_getIntConstantFromClass(JNIEnv* pEnv,
                jclass theClass, const char* className, const char* constName, int* constVal);

// ----------------------------------------------------------------------------
int register_android_media_AudioRecord(JNIEnv *env)
@@ -599,6 +651,36 @@ int register_android_media_AudioRecord(JNIEnv *env)
        return -1;
    }

    jclass audioFormatClass = NULL;
    audioFormatClass = env->FindClass(JAVA_AUDIOFORMAT_CLASS_NAME);
    if (audioFormatClass == NULL) {
        ALOGE("Can't find %s", JAVA_AUDIOFORMAT_CLASS_NAME);
        return -1;
    }
    if ( !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                JAVA_CONST_PCM16_NAME, &(javaAudioRecordFields.PCM16))
           || !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                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;
    }
    return AndroidRuntime::registerNativeMethods(env,
            kClassPathName, gMethods, NELEM(gMethods));
}
+141 −12
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 * Not a Contribution.
 *
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
@@ -40,6 +43,24 @@ static const char* const kClassPathName = "android/media/AudioTrack";
struct fields_t {
    // these fields provide access from C++ to the...
    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       EVRCNW;                //...  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
    jfieldID  jniData;      // stores in Java additional resources used by the native AudioTrack
};
@@ -56,8 +77,6 @@ struct audiotrack_callback_cookie {
#define MODE_STATIC 0
#define MODE_STREAM 1
// keep these values in sync with AudioFormat.java
#define ENCODING_PCM_16BIT 2
#define ENCODING_PCM_8BIT  3

// ----------------------------------------------------------------------------
class AudioTrackJniStorage {
@@ -194,6 +213,23 @@ 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;
    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;

    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,
@@ -244,8 +280,13 @@ 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 != ENCODING_PCM_16BIT) && (audioFormat != ENCODING_PCM_8BIT)) {

    if ((audioFormat != javaAudioTrackFields.PCM16)
        && (audioFormat != javaAudioTrackFields.PCM8)
        && (audioFormat != javaAudioTrackFields.AMRNB)
        && (audioFormat != javaAudioTrackFields.AMRWB)
        && (audioFormat != javaAudioTrackFields.EVRC)
        && (audioFormat != javaAudioTrackFields.EVRCB)
        && (audioFormat != javaAudioTrackFields.EVRCWB)) {
        ALOGE("Error creating AudioTrack: unsupported audio format.");
        return AUDIOTRACK_ERROR_SETUP_INVALIDFORMAT;
    }
@@ -253,20 +294,23 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
    // for the moment 8bitPCM in MODE_STATIC is not supported natively in the AudioTrack C++ class
    // so we declare everything as 16bitPCM, the 8->16bit conversion for MODE_STATIC will be handled
    // in android_media_AudioTrack_native_write_byte()
    if ((audioFormat == ENCODING_PCM_8BIT)
    if ((audioFormat == javaAudioTrackFields.PCM8)
        && (memoryMode == MODE_STATIC)) {
        ALOGV("android_media_AudioTrack_native_setup(): requesting MODE_STATIC for 8bit \
            buff size of %dbytes, switching to 16bit, buff size of %dbytes",
            buffSizeInBytes, 2*buffSizeInBytes);
        audioFormat = ENCODING_PCM_16BIT;
        audioFormat = javaAudioTrackFields.PCM16;
        // we will need twice the memory to store the data
        buffSizeInBytes *= 2;
    }

    // compute the frame count
    int bytesPerSample = audioFormat == ENCODING_PCM_16BIT ? 2 : 1;
    audio_format_t format = audioFormat == ENCODING_PCM_16BIT ?
            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);
@@ -519,14 +563,19 @@ jint writeToTrack(const sp<AudioTrack>& track, jint audioFormat, jbyte* data,
            written = 0;
        }
    } else {
        if (audioFormat == ENCODING_PCM_16BIT) {
        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();
            }
            memcpy(track->sharedBuffer()->pointer(), data + offsetInBytes, sizeInBytes);
            written = sizeInBytes;
        } else if (audioFormat == ENCODING_PCM_8BIT) {
        } else if (audioFormat == javaAudioTrackFields.PCM8) {
            // data contains 8bit data we need to expand to 16bit before copying
            // to the shared memory
            // writing to shared memory, check for capacity,
@@ -834,7 +883,7 @@ static jint android_media_AudioTrack_get_min_buff_size(JNIEnv *env, jobject thi
            sampleRateInHertz) != NO_ERROR) {
        return -1;
    }
    return frameCount * nbChannels * (audioFormat == ENCODING_PCM_16BIT ? 2 : 1);
    return frameCount * nbChannels * (audioFormat == javaAudioTrackFields.PCM8 ? 1 : 2);
}

// ----------------------------------------------------------------------------
@@ -909,8 +958,26 @@ static JNINativeMethod gMethods[] = {

// field names found in android/media/AudioTrack.java
#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"
#define JAVA_CONST_STREAM_RING_NAME                     "STREAM_RING"
#define JAVA_CONST_STREAM_MUSIC_NAME                    "STREAM_MUSIC"
#define JAVA_CONST_STREAM_ALARM_NAME                    "STREAM_ALARM"
#define JAVA_CONST_STREAM_NOTIFICATION_NAME             "STREAM_NOTIFICATION"
#define JAVA_CONST_STREAM_BLUETOOTH_SCO_NAME            "STREAM_BLUETOOTH_SCO"
#define JAVA_CONST_STREAM_DTMF_NAME                     "STREAM_DTMF"
#define JAVA_NATIVETRACKINJAVAOBJ_FIELD_NAME            "mNativeTrackInJavaObj"
#define JAVA_JNIDATA_FIELD_NAME                         "mJniData"
#define JAVA_AUDIOFORMAT_CLASS_NAME             "android/media/AudioFormat"
#define JAVA_AUDIOMANAGER_CLASS_NAME            "android/media/AudioManager"

// ----------------------------------------------------------------------------
// preconditions:
@@ -969,6 +1036,68 @@ int register_android_media_AudioTrack(JNIEnv *env)
        return -1;
    }

    jclass audioFormatClass = NULL;
    audioFormatClass = env->FindClass(JAVA_AUDIOFORMAT_CLASS_NAME);
    if (audioFormatClass == NULL) {
        ALOGE("Can't find %s", JAVA_AUDIOFORMAT_CLASS_NAME);
        return -1;
    }
    if ( !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                JAVA_CONST_PCM16_NAME, &(javaAudioTrackFields.PCM16))
           || !android_media_getIntConstantFromClass(env, audioFormatClass,
                JAVA_AUDIOFORMAT_CLASS_NAME,
                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))
) {
        return -1;
    }
    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))) {
        return -1;
    }
    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
}

+29 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 * Not a Contribution.
 *
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
@@ -36,6 +39,16 @@ public class AudioFormat {
    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;
    /** @hide */
    public static final int ENCODING_AMRNB = 100;   // accessed by native code
    /** @hide */
    public static final int ENCODING_AMRWB = 101;   // accessed by native code
    /** @hide */
    public static final int ENCODING_EVRC = 102;    // accessed by native code
    /** @hide */
    public static final int ENCODING_EVRCB = 103;   // accessed by native code
    /** @hide */
    public static final int ENCODING_EVRCWB = 104;  // accessed by native code

    /** Invalid audio channel configuration */
    /** @deprecated use CHANNEL_INVALID instead  */
@@ -118,7 +131,23 @@ public class AudioFormat {
    public static final int CHANNEL_IN_Z_AXIS = 0x2000;
    public static final int CHANNEL_IN_VOICE_UPLINK = 0x4000;
    public static final int CHANNEL_IN_VOICE_DNLINK = 0x8000;
    /** @hide */
    public static final int CHANNEL_IN_FRONT_LEFT = 0x10000;
    /** @hide */
    public static final int CHANNEL_IN_FRONT_RIGHT = 0x20000;
    /** @hide */
    public static final int CHANNEL_IN_FRONT_CENTER = 0x40000;
    /** @hide */
    public static final int CHANNEL_IN_LOW_FREQUENCY = 0x80000;
    /** @hide */
    public static final int CHANNEL_IN_BACK_LEFT = 0x100000;
    /** @hide */
    public static final int CHANNEL_IN_BACK_RIGHT = 0x200000;
    public static final int CHANNEL_IN_MONO = CHANNEL_IN_FRONT;
    public static final int CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT);
    /** @hide */
    public static final int CHANNEL_IN_5POINT1 = (CHANNEL_IN_FRONT_LEFT |
            CHANNEL_IN_FRONT_RIGHT | CHANNEL_IN_FRONT_CENTER | CHANNEL_IN_LOW_FREQUENCY |
            CHANNEL_IN_BACK_LEFT | CHANNEL_IN_BACK_RIGHT);

}
+30 −3
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 * Not a Contribution.
 *
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
@@ -284,6 +287,10 @@ public class AudioRecord
            mChannelCount = 2;
            mChannelMask = channelConfig;
            break;
        case AudioFormat.CHANNEL_IN_5POINT1:
            mChannelCount = 6;
            mChannelMask = AudioFormat.CHANNEL_IN_5POINT1;
            break;
        default:
            throw new IllegalArgumentException("Unsupported channel configuration.");
        }
@@ -296,6 +303,11 @@ public class AudioRecord
            break;
        case AudioFormat.ENCODING_PCM_16BIT:
        case AudioFormat.ENCODING_PCM_8BIT:
        case AudioFormat.ENCODING_AMRNB:
        case AudioFormat.ENCODING_AMRWB:
        case AudioFormat.ENCODING_EVRC:
        case AudioFormat.ENCODING_EVRCB:
        case AudioFormat.ENCODING_EVRCWB:
            mAudioFormat = audioFormat;
            break;
        default:
@@ -314,8 +326,15 @@ public class AudioRecord
    private void audioBuffSizeCheck(int audioBufferSize) {
        // NB: this section is only valid with PCM data.
        // To update when supporting compressed formats
        int frameSizeInBytes = mChannelCount
            * (mAudioFormat == AudioFormat.ENCODING_PCM_8BIT ? 1 : 2);
        int bytesPerSample;
        if(mAudioFormat == AudioFormat.ENCODING_PCM_8BIT)
            bytesPerSample = 1;
        else if((mAudioFormat == AudioFormat.ENCODING_AMRWB) &&
                (mRecordSource != MediaRecorder.AudioSource.VOICE_COMMUNICATION))
            bytesPerSample = 61;
        else
            bytesPerSample = 2;
        int frameSizeInBytes = mChannelCount * bytesPerSample;
        if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) {
            throw new IllegalArgumentException("Invalid audio buffer size.");
        }
@@ -460,6 +479,9 @@ public class AudioRecord
        case (AudioFormat.CHANNEL_IN_FRONT | AudioFormat.CHANNEL_IN_BACK):
            channelCount = 2;
            break;
        case AudioFormat.CHANNEL_IN_5POINT1:
            channelCount = 6;
            break;
        case AudioFormat.CHANNEL_INVALID:
        default:
            loge("getMinBufferSize(): Invalid channel configuration.");
@@ -467,7 +489,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 ERROR_BAD_VALUE;
        }
+11 −1
Original line number Diff line number Diff line
@@ -415,6 +415,11 @@ public class AudioTrack
            break;
        case AudioFormat.ENCODING_PCM_16BIT:
        case AudioFormat.ENCODING_PCM_8BIT:
        case AudioFormat.ENCODING_AMRNB:
        case AudioFormat.ENCODING_AMRWB:
        case AudioFormat.ENCODING_EVRC:
        case AudioFormat.ENCODING_EVRCB:
        case AudioFormat.ENCODING_EVRCWB:
            mAudioFormat = audioFormat;
            break;
        default:
@@ -702,7 +707,12 @@ public class AudioTrack
        }

        if ((audioFormat != AudioFormat.ENCODING_PCM_16BIT)
            && (audioFormat != AudioFormat.ENCODING_PCM_8BIT)) {
            && (audioFormat != AudioFormat.ENCODING_PCM_8BIT)
            && (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 ERROR_BAD_VALUE;
        }
Loading