1/*
2 * Copyright (C) 2010 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#include <stdlib.h>
18#include <stdio.h>
19#include <string.h>
20#include <unistd.h>
21#include <sys/time.h>
22#include <fcntl.h>
23
24#include <SLES/OpenSLES.h>
25#include <SLES/OpenSLES_Android.h>
26
27
28#define MAX_NUMBER_INTERFACES 1
29
30#define GUID_DISPLAY_LENGTH 35
31#define FX_NAME_LENGTH 64
32
33//-----------------------------------------------------------------
34/* Exits the application if an error is encountered */
35#define ExitOnError(x) ExitOnErrorFunc(x,__LINE__)
36
37void ExitOnErrorFunc( SLresult result , int line)
38{
39    if (SL_RESULT_SUCCESS != result) {
40        fprintf(stderr, "%u error code encountered at line %d, exiting\n", result, line);
41        exit(EXIT_FAILURE);
42    }
43}
44
45//-----------------------------------------------------------------
46void guidToString(const SLInterfaceID guid, char *str) {
47    if ((NULL == guid) || (NULL == str)) {
48        return;
49    }
50    snprintf(str, GUID_DISPLAY_LENGTH, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
51            guid->time_low,
52            guid->time_mid,
53            guid->time_hi_and_version,
54            guid->clock_seq,
55            guid->node[0],
56            guid->node[1],
57            guid->node[2],
58            guid->node[3],
59            guid->node[4],
60            guid->node[5]);
61}
62
63//-----------------------------------------------------------------
64
65/* Query available effects on Android  */
66void TestGenericFxCapabilities(  )
67{
68
69    SLresult    result;
70    SLObjectItf sl;
71
72    /* ------------------------------------------------------ */
73    /* Engine configuration and creation */
74
75    SLEngineOption EngineOption[] = {
76            {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE}
77    };
78
79    SLboolean required[MAX_NUMBER_INTERFACES];
80    SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
81
82    /* Initialize arrays required[] and iidArray[] */
83    for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) {
84        required[i] = SL_BOOLEAN_FALSE;
85        iidArray[i] = SL_IID_NULL;
86    }
87
88    iidArray[0] = SL_IID_ANDROIDEFFECTCAPABILITIES;
89    required[0] = SL_BOOLEAN_TRUE;
90
91
92    result = slCreateEngine( &sl, 1, EngineOption, 1, iidArray, required);
93    ExitOnError(result);
94
95    /* Realizing the SL Engine in synchronous mode. */
96    result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
97    ExitOnError(result);
98
99
100    SLEngineItf EngineItf;
101    SLAndroidEffectCapabilitiesItf EffectLibItf;
102
103    /* Get the SL Engine interface which is implicit */
104    result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
105    ExitOnError(result);
106
107    /* Get the Android Effect Capabilities interface */
108    result = (*sl)->GetInterface(sl, SL_IID_ANDROIDEFFECTCAPABILITIES, (void*)&EffectLibItf);
109    ExitOnError(result);
110
111    /* ------------------------------------------------------ */
112    /* Query the effect library */
113
114    SLuint32 nbEffects = 0;
115    result = (*EffectLibItf)->QueryNumEffects(EffectLibItf, &nbEffects);
116    ExitOnError(result);
117    fprintf(stdout, "Effect library contains %d effects:\n", nbEffects);
118
119    SLchar effectName[FX_NAME_LENGTH+1];
120    SLuint16 effectNameLength = FX_NAME_LENGTH;
121    char typeString[GUID_DISPLAY_LENGTH];
122    char implString[GUID_DISPLAY_LENGTH];
123
124    SLInterfaceID effectType, effectImplementation;
125    for (SLuint32 i = 0 ; i < nbEffects ; i++ ) {
126        fprintf(stdout,"- effect %d: ", i);
127        memset(effectName, 'Z', FX_NAME_LENGTH+1);
128        effectNameLength = FX_NAME_LENGTH;
129        result = (*EffectLibItf)->QueryEffect(EffectLibItf, i,
130                &effectType, &effectImplementation, effectName, &effectNameLength);
131        if ('Z' != effectName[FX_NAME_LENGTH]) {
132            fprintf(stderr, "QueryEffect wrote beyond end of buffer\n");
133            continue;
134        }
135        ExitOnError(result);
136        printf("length=%u ", effectNameLength);
137        if (FX_NAME_LENGTH < effectNameLength) {
138            printf(" (>max) ");
139            effectNameLength = FX_NAME_LENGTH;
140        }
141        guidToString(effectType, typeString);
142        guidToString(effectImplementation, implString);
143        effectName[FX_NAME_LENGTH - 1] = '\0';
144        fprintf(stdout, " type=%s, impl=%s name=%.*s \n", typeString, implString, effectNameLength,
145                effectName);
146    }
147
148    /* Shutdown OpenSL ES */
149     (*sl)->Destroy(sl);
150}
151
152//-----------------------------------------------------------------
153int main(int argc __unused, char* const argv[])
154{
155    fprintf(stdout, "OpenSL ES test %s: exercises SLAndroidEffectCapabilitiesItf.\n", argv[0]);
156
157    TestGenericFxCapabilities();
158
159    return EXIT_SUCCESS;
160}
161