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