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

Commit ec2f4b0a authored by Eric Laurent's avatar Eric Laurent Committed by Android Git Automerger
Browse files

am 47615317: Merge "AudioSystem: added JNI for routing extensions" into lmp-preview-dev

* commit '476153173b5a1b6b1fb5fc41af8b87d7e1ec36b3':
  AudioSystem: added JNI for routing extensions
parents 0d0aa78a a89eb2d8
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
@@ -23,6 +23,11 @@
#define ENCODING_PCM_16BIT 2
#define ENCODING_PCM_8BIT  3
#define ENCODING_PCM_FLOAT 4
#define ENCODING_INVALID 0
#define ENCODING_DEFAULT 1

#define CHANNEL_INVALID 0
#define CHANNEL_OUT_DEFAULT 1

static inline audio_format_t audioFormatToNative(int audioFormat)
{
@@ -33,9 +38,58 @@ static inline audio_format_t audioFormatToNative(int audioFormat)
        return AUDIO_FORMAT_PCM_8_BIT;
    case ENCODING_PCM_FLOAT:
        return AUDIO_FORMAT_PCM_FLOAT;
    case ENCODING_DEFAULT:
        return AUDIO_FORMAT_DEFAULT;
    default:
        return AUDIO_FORMAT_INVALID;
    }
}

static inline int audioFormatFromNative(audio_format_t nativeFormat)
{
    switch (nativeFormat) {
    case AUDIO_FORMAT_PCM_16_BIT:
        return ENCODING_PCM_16BIT;
    case AUDIO_FORMAT_PCM_8_BIT:
        return ENCODING_PCM_8BIT;
    case AUDIO_FORMAT_PCM_FLOAT:
        return ENCODING_PCM_FLOAT;
    case AUDIO_FORMAT_DEFAULT:
        return ENCODING_DEFAULT;
    default:
        return ENCODING_INVALID;
    }
}

static inline audio_channel_mask_t outChannelMaskToNative(int channelMask)
{
    switch (channelMask) {
    case CHANNEL_OUT_DEFAULT:
    case CHANNEL_INVALID:
        return AUDIO_CHANNEL_NONE;
    default:
        return (audio_channel_mask_t)(channelMask>>2);
    }
}

static inline int outChannelMaskFromNative(audio_channel_mask_t nativeMask)
{
    switch (nativeMask) {
    case AUDIO_CHANNEL_NONE:
        return CHANNEL_OUT_DEFAULT;
    default:
        return (int)nativeMask<<2;
    }
}

static inline audio_channel_mask_t inChannelMaskToNative(int channelMask)
{
    return (audio_channel_mask_t)channelMask;
}

static inline int inChannelMaskFromNative(audio_channel_mask_t nativeMask)
{
    return (int)nativeMask;
}

#endif // ANDROID_MEDIA_AUDIOFORMAT_H
+953 −1

File changed.

Preview size limit exceeded, changes collapsed.

+125 −5
Original line number Diff line number Diff line
@@ -3007,7 +3007,7 @@ public class AudioManager {
     * @hide
     */
    public int listAudioPorts(ArrayList<AudioPort> ports) {
        return ERROR_INVALID_OPERATION;
        return updateAudioPortCache(ports, null);
    }

    /**
@@ -3016,7 +3016,17 @@ public class AudioManager {
     * @hide
     */
    public int listAudioDevicePorts(ArrayList<AudioPort> devices) {
        return ERROR_INVALID_OPERATION;
        ArrayList<AudioPort> ports = new ArrayList<AudioPort>();
        int status = updateAudioPortCache(ports, null);
        if (status == SUCCESS) {
            devices.clear();
            for (int i = 0; i < ports.size(); i++) {
                if (ports.get(i) instanceof AudioDevicePort) {
                    devices.add(ports.get(i));
                }
            }
        }
        return status;
    }

    /**
@@ -3045,7 +3055,7 @@ public class AudioManager {
    public int createAudioPatch(AudioPatch[] patch,
                                 AudioPortConfig[] sources,
                                 AudioPortConfig[] sinks) {
        return ERROR_INVALID_OPERATION;
        return AudioSystem.createAudioPatch(patch, sources, sinks);
    }

    /**
@@ -3060,7 +3070,7 @@ public class AudioManager {
     * @hide
     */
    public int releaseAudioPatch(AudioPatch patch) {
        return  ERROR_INVALID_OPERATION;
        return AudioSystem.releaseAudioPatch(patch);
    }

    /**
@@ -3069,7 +3079,7 @@ public class AudioManager {
     * @hide
     */
    public int listAudioPatches(ArrayList<AudioPatch> patches) {
        return ERROR_INVALID_OPERATION;
        return updateAudioPortCache(null, patches);
    }

    /**
@@ -3118,4 +3128,114 @@ public class AudioManager {
     */
    public void unregisterAudioPortUpdateListener(OnAudioPortUpdateListener l) {
    }

    //
    // AudioPort implementation
    //

    static final int AUDIOPORT_GENERATION_INIT = 0;
    Integer mAudioPortGeneration = new Integer(AUDIOPORT_GENERATION_INIT);
    ArrayList<AudioPort> mAudioPortsCached = new ArrayList<AudioPort>();
    ArrayList<AudioPatch> mAudioPatchesCached = new ArrayList<AudioPatch>();

    int resetAudioPortGeneration() {
        int generation;
        synchronized (mAudioPortGeneration) {
            generation = mAudioPortGeneration;
            mAudioPortGeneration = AUDIOPORT_GENERATION_INIT;
        }
        return generation;
    }

    int updateAudioPortCache(ArrayList<AudioPort> ports, ArrayList<AudioPatch> patches) {
        synchronized (mAudioPortGeneration) {

            if (mAudioPortGeneration == AUDIOPORT_GENERATION_INIT) {
                int[] patchGeneration = new int[1];
                int[] portGeneration = new int[1];
                int status;
                ArrayList<AudioPort> newPorts = new ArrayList<AudioPort>();
                ArrayList<AudioPatch> newPatches = new ArrayList<AudioPatch>();

                do {
                    newPorts.clear();
                    status = AudioSystem.listAudioPorts(newPorts, portGeneration);
                    Log.i(TAG, "updateAudioPortCache AudioSystem.listAudioPorts() status: "+
                                    status+" num ports: "+ newPorts.size() +" portGeneration: "+portGeneration[0]);
                    if (status != SUCCESS) {
                        return status;
                    }
                    newPatches.clear();
                    status = AudioSystem.listAudioPatches(newPatches, patchGeneration);
                    Log.i(TAG, "updateAudioPortCache AudioSystem.listAudioPatches() status: "+
                            status+" num patches: "+ newPatches.size() +" patchGeneration: "+patchGeneration[0]);
                    if (status != SUCCESS) {
                        return status;
                    }
                } while (patchGeneration[0] != portGeneration[0]);

                for (int i = 0; i < newPatches.size(); i++) {
                    for (int j = 0; j < newPatches.get(i).sources().length; j++) {
                        AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sources()[j], newPorts);
                        if (portCfg == null) {
                            return ERROR;
                        }
                        newPatches.get(i).sources()[j] = portCfg;
                    }
                    for (int j = 0; j < newPatches.get(i).sinks().length; j++) {
                        AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sinks()[j], newPorts);
                        if (portCfg == null) {
                            return ERROR;
                        }
                        newPatches.get(i).sinks()[j] = portCfg;
                    }
                }

                mAudioPortsCached = newPorts;
                mAudioPatchesCached = newPatches;
                mAudioPortGeneration = portGeneration[0];
            }
            if (ports != null) {
                ports.clear();
                ports.addAll(mAudioPortsCached);
            }
            if (patches != null) {
                patches.clear();
                patches.addAll(mAudioPatchesCached);
            }
        }
        return SUCCESS;
    }

    AudioPortConfig updatePortConfig(AudioPortConfig portCfg, ArrayList<AudioPort> ports) {
        AudioPort port = portCfg.port();
        int k;
        for (k = 0; k < ports.size(); k++) {
            // compare handles because the port returned by JNI is not of the correct
            // subclass
            if (ports.get(k).handle().equals(port.handle())) {
                Log.i(TAG, "updatePortConfig match found for port handle: "+
                            port.handle().id()+" port: "+ k);
                port = ports.get(k);
                break;
            }
        }
        if (k == ports.size()) {
            // this hould never happen
            Log.e(TAG, "updatePortConfig port not found for handle: "+port.handle().id());
            return null;
        }
        AudioGainConfig gainCfg = portCfg.gain();
        if (gainCfg != null) {
            AudioGain gain = port.gain(gainCfg.index());
            gainCfg = gain.buildConfig(gainCfg.mode(),
                                       gainCfg.channelMask(),
                                       gainCfg.values(),
                                       gainCfg.rampDurationMs());
        }
        return port.buildConfig(portCfg.samplingRate(),
                                                 portCfg.channelMask(),
                                                 portCfg.format(),
                                                 gainCfg);
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.media;

import java.util.ArrayList;

/* IF YOU CHANGE ANY OF THE CONSTANTS IN THIS FILE, DO NOT FORGET
 * TO UPDATE THE CORRESPONDING NATIVE GLUE AND AudioManager.java.
@@ -459,4 +460,11 @@ public class AudioSystem

    public static native int setLowRamDevice(boolean isLowRamDevice);
    public static native int checkAudioFlinger();

    public static native int listAudioPorts(ArrayList<AudioPort> ports, int[] generation);
    public static native int createAudioPatch(AudioPatch[] patch,
                                            AudioPortConfig[] sources, AudioPortConfig[] sinks);
    public static native int releaseAudioPatch(AudioPatch patch);
    public static native int listAudioPatches(ArrayList<AudioPatch> patches, int[] generation);
}