1711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten/*
2711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * Copyright (C) 2010 The Android Open Source Project
3711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten *
4711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
5711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * you may not use this file except in compliance with the License.
6711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * You may obtain a copy of the License at
7711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten *
8711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
9711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten *
10711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * Unless required by applicable law or agreed to in writing, software
11711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
12711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * See the License for the specific language governing permissions and
14711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * limitations under the License.
15711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten */
16711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
17711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten// Test dynamic interface management
18711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
19711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#include <assert.h>
20711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#include <math.h>
21711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#include <stdio.h>
22711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#include <stdlib.h>
23711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
24c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES.h>
25711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#ifdef ANDROID
26c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES_Android.h>
27711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#endif
28711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
29711332800108ad6e0e594796e5f8db0da3eff402Glenn Kastenint main(int argc, char **argv)
30711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten{
31711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    if (argc != 1) {
32711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten        fprintf(stderr, "usage: %s\n", argv[0]);
33711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten        return EXIT_FAILURE;
34711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    }
35711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
36711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    SLresult result;
37711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    SLObjectItf engineObject;
38711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
39711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // create engine
40711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
41711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
42711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    SLEngineItf engineEngine;
43711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
44711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
45711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
46711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
47711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
48711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // create output mix
49711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    SLObjectItf outputMixObject;
50711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
51711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
52711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
53711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // get the dynamic interface management interface for output mix, before realize
54711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    SLDynamicInterfaceManagementItf outputMixDIM;
55711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_DYNAMICINTERFACEMANAGEMENT,
56711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten            &outputMixDIM);
57711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_PRECONDITIONS_VIOLATED == result);
58711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(NULL == outputMixDIM);
59711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
60711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // realize output mix
61711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
62711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
63711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
64711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // get the dynamic interface management interface for output mix, after realize
65711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_DYNAMICINTERFACEMANAGEMENT,
66711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten            &outputMixDIM);
67711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
68711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(NULL != outputMixDIM);
69711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
70711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // register callback
71711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixDIM)->RegisterCallback(outputMixDIM, NULL, NULL);
72711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
73711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
74711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // get environmental reverb interface, before add or resume
75711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    SLEnvironmentalReverbItf outputMixEnvironmentalReverb;
76711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
77711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten            &outputMixEnvironmentalReverb);
78711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_FEATURE_UNSUPPORTED == result);
79711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(NULL == outputMixEnvironmentalReverb);
80711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
81711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // resume environmental reverb interface
82711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixDIM)->ResumeInterface(outputMixDIM, SL_IID_ENVIRONMENTALREVERB,
83711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten            SL_BOOLEAN_FALSE);
84711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_PRECONDITIONS_VIOLATED == result);
85711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
86711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // get environmental reverb interface, after resume but before add
87711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
88711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten            &outputMixEnvironmentalReverb);
89711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_FEATURE_UNSUPPORTED == result);
90711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(NULL == outputMixEnvironmentalReverb);
91711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
92711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // add environmental reverb interface
93711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixDIM)->AddInterface(outputMixDIM, SL_IID_ENVIRONMENTALREVERB,
94711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten            SL_BOOLEAN_FALSE);
95711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
96711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
97711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // get environmental reverb interface, after add
98711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
99711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten            &outputMixEnvironmentalReverb);
100711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
101711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(NULL != outputMixEnvironmentalReverb);
102711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
103711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // add environmental reverb interface again
104711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixDIM)->AddInterface(outputMixDIM, SL_IID_ENVIRONMENTALREVERB,
105711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten            SL_BOOLEAN_FALSE);
106711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_PRECONDITIONS_VIOLATED == result);
107711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
108711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // resume environmental reverb interface
109711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixDIM)->ResumeInterface(outputMixDIM, SL_IID_ENVIRONMENTALREVERB,
110711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten            SL_BOOLEAN_FALSE);
111711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_PRECONDITIONS_VIOLATED == result);
112711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
113711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // remove environmental reverb interface (FIXME not yet implemented)
114711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixDIM)->RemoveInterface(outputMixDIM, SL_IID_ENVIRONMENTALREVERB);
115711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert((SL_RESULT_SUCCESS == result) || (SL_RESULT_FEATURE_UNSUPPORTED == result));
116711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
117711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // FIXME once remove is implemented we can try this
118711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    if (SL_RESULT_SUCCESS == result) {
119711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten        result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
120711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten                &outputMixEnvironmentalReverb);
121711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten        assert(SL_RESULT_PRECONDITIONS_VIOLATED == result);
122711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten        assert(NULL == outputMixEnvironmentalReverb);
123711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten        result = (*outputMixDIM)->RemoveInterface(outputMixDIM, SL_IID_ENVIRONMENTALREVERB);
124711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten        assert(SL_RESULT_PRECONDITIONS_VIOLATED == result);
125711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten        result = (*outputMixDIM)->AddInterface(outputMixDIM, SL_IID_ENVIRONMENTALREVERB,
126711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten                SL_BOOLEAN_FALSE);
127711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
128711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten        result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
129711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten                &outputMixEnvironmentalReverb);
130711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
131711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten        assert(NULL != outputMixEnvironmentalReverb);
132711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    }
133711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
134711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // get non-sensical play interface, before add
135711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    SLPlayItf outputMixPlay;
136711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_PLAY, &outputMixPlay);
137711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_FEATURE_UNSUPPORTED == result);
138711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(NULL == outputMixPlay);
139711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
140711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // add play interface
141711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixDIM)->AddInterface(outputMixDIM, SL_IID_PLAY, SL_BOOLEAN_FALSE);
142711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_FEATURE_UNSUPPORTED == result);
143711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
144711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // get play interface should still fail
145711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_PLAY, &outputMixPlay);
146711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(SL_RESULT_FEATURE_UNSUPPORTED == result);
147711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    assert(NULL == outputMixPlay);
148711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
149711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // destroy output mix
150711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    (*outputMixObject)->Destroy(outputMixObject);
151711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
152711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    // destroy engine
153711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    (*engineObject)->Destroy(engineObject);
154711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten
155711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten    return EXIT_SUCCESS;
156711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten}
157