Home | History | Annotate | Download | only in libaudiojni
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "SL-Utils"
     19 
     20 #include "sl-utils.h"
     21 #include <utils/Mutex.h>
     22 
     23 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
     24 
     25 // These will wind up in <SLES/OpenSLES_Android.h>
     26 #define SL_ANDROID_SPEAKER_QUAD (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT \
     27  | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT)
     28 
     29 #define SL_ANDROID_SPEAKER_5DOT1 (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT \
     30  | SL_SPEAKER_FRONT_CENTER  | SL_SPEAKER_LOW_FREQUENCY| SL_SPEAKER_BACK_LEFT \
     31  | SL_SPEAKER_BACK_RIGHT)
     32 
     33 #define SL_ANDROID_SPEAKER_7DOT1 (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT \
     34  |SL_SPEAKER_SIDE_RIGHT)
     35 
     36 namespace android {
     37 
     38 static Mutex gLock;
     39 static SLObjectItf gEngineObject;
     40 static unsigned gRefCount;
     41 
     42 static const char *gErrorStrings[] = {
     43     "SL_RESULT_SUCCESS",                // 0
     44     "SL_RESULT_PRECONDITIONS_VIOLATE",  // 1
     45     "SL_RESULT_PARAMETER_INVALID",      // 2
     46     "SL_RESULT_MEMORY_FAILURE",         // 3
     47     "SL_RESULT_RESOURCE_ERROR",         // 4
     48     "SL_RESULT_RESOURCE_LOST",          // 5
     49     "SL_RESULT_IO_ERROR",               // 6
     50     "SL_RESULT_BUFFER_INSUFFICIENT",    // 7
     51     "SL_RESULT_CONTENT_CORRUPTED",      // 8
     52     "SL_RESULT_CONTENT_UNSUPPORTED",    // 9
     53     "SL_RESULT_CONTENT_NOT_FOUND",      // 10
     54     "SL_RESULT_PERMISSION_DENIED",      // 11
     55     "SL_RESULT_FEATURE_UNSUPPORTED",    // 12
     56     "SL_RESULT_INTERNAL_ERROR",         // 13
     57     "SL_RESULT_UNKNOWN_ERROR",          // 14
     58     "SL_RESULT_OPERATION_ABORTED",      // 15
     59     "SL_RESULT_CONTROL_LOST",           // 16
     60 };
     61 
     62 const char *getSLErrStr(int code) {
     63     if ((size_t)code >= ARRAY_SIZE(gErrorStrings)) {
     64         return "SL_RESULT_UNKNOWN";
     65     }
     66     return gErrorStrings[code];
     67 }
     68 
     69 SLuint32 channelCountToMask(unsigned channelCount) {
     70     switch (channelCount) {
     71     case 1:
     72         return SL_SPEAKER_FRONT_LEFT; // we prefer left over center
     73     case 2:
     74         return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
     75     case 3:
     76         return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER;
     77     case 4:
     78         return SL_ANDROID_SPEAKER_QUAD;
     79     case 5:
     80         return SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER;
     81     case 6:
     82         return SL_ANDROID_SPEAKER_5DOT1;
     83     case 7:
     84         return SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_BACK_CENTER;
     85     case 8:
     86         return SL_ANDROID_SPEAKER_7DOT1;
     87     default:
     88         return 0;
     89     }
     90 }
     91 
     92 static SLObjectItf createEngine() {
     93     static SLEngineOption EngineOption[] = {
     94         {
     95             (SLuint32) SL_ENGINEOPTION_THREADSAFE,
     96             (SLuint32) SL_BOOLEAN_TRUE
     97         },
     98     };
     99     // create engine in thread-safe mode
    100     SLObjectItf engine;
    101     SLresult result = slCreateEngine(&engine,
    102             1 /* numOptions */, EngineOption /* pEngineOptions */,
    103             0 /* numInterfaces */, NULL /* pInterfaceIds */, NULL /* pInterfaceRequired */);
    104     if (result != SL_RESULT_SUCCESS) {
    105         ALOGE("slCreateEngine() failed: %s", getSLErrStr(result));
    106         return NULL;
    107     }
    108     // realize the engine
    109     result = (*engine)->Realize(engine, SL_BOOLEAN_FALSE /* async */);
    110     if (result != SL_RESULT_SUCCESS) {
    111         ALOGE("Realize() failed: %s", getSLErrStr(result));
    112         (*engine)->Destroy(engine);
    113         return NULL;
    114     }
    115     return engine;
    116 }
    117 
    118 SLObjectItf OpenSLEngine(bool global) {
    119 
    120     if (!global) {
    121         return createEngine();
    122     }
    123     Mutex::Autolock l(gLock);
    124     if (gRefCount == 0) {
    125         gEngineObject = createEngine();
    126     }
    127     gRefCount++;
    128     return gEngineObject;
    129 }
    130 
    131 void CloseSLEngine(SLObjectItf engine) {
    132     Mutex::Autolock l(gLock);
    133     if (engine == gEngineObject) {
    134         if (gRefCount == 0) {
    135             ALOGE("CloseSLEngine(%p): refcount already 0", engine);
    136             return;
    137         }
    138         if (--gRefCount != 0) {
    139             return;
    140         }
    141         gEngineObject = NULL;
    142     }
    143     (*engine)->Destroy(engine);
    144 }
    145 
    146 } // namespace android
    147 
    148