1d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten/*
2d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten * Copyright (C) 2010 The Android Open Source Project
3d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten *
4d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
5d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten * you may not use this file except in compliance with the License.
6d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten * You may obtain a copy of the License at
7d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten *
8d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
9d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten *
10d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten * Unless required by applicable law or agreed to in writing, software
11d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
12d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten * See the License for the specific language governing permissions and
14d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten * limitations under the License.
15d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten */
16d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
17d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten// Test dynamic interface management
18d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
19d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten#include <assert.h>
20d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten#include <math.h>
21d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten#include <stdio.h>
22d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten#include <stdlib.h>
23d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
24a6c5e52ded343b557152156c33d33a10d29bf6f1Glenn Kasten#include <SLES/OpenSLES.h>
25d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten#ifdef ANDROID
26a6c5e52ded343b557152156c33d33a10d29bf6f1Glenn Kasten#include <SLES/OpenSLES_Android.h>
27d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten#endif
28d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
29d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kastenint main(int argc, char **argv)
30d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten{
31d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    if (argc != 1) {
32d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten        fprintf(stderr, "usage: %s\n", argv[0]);
33d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten        return EXIT_FAILURE;
34d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    }
35d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
36d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    SLresult result;
37d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    SLObjectItf engineObject;
38d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
39d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // create engine
40d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
41d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
42d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    SLEngineItf engineEngine;
43d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
44d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
45d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
46d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
47d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
48d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // create output mix
49d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    SLObjectItf outputMixObject;
50d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
51d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
52d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
53d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // get the dynamic interface management interface for output mix, before realize
54d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    SLDynamicInterfaceManagementItf outputMixDIM;
55d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_DYNAMICINTERFACEMANAGEMENT,
56d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten            &outputMixDIM);
57d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_PRECONDITIONS_VIOLATED == result);
58d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(NULL == outputMixDIM);
59d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
60d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // realize output mix
61d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
62d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
63d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
64d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // get the dynamic interface management interface for output mix, after realize
65d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_DYNAMICINTERFACEMANAGEMENT,
66d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten            &outputMixDIM);
67d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
68d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(NULL != outputMixDIM);
69d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
70d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // register callback
71d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixDIM)->RegisterCallback(outputMixDIM, NULL, NULL);
72d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
73d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
74d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // get environmental reverb interface, before add or resume
75d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    SLEnvironmentalReverbItf outputMixEnvironmentalReverb;
76d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
77d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten            &outputMixEnvironmentalReverb);
78d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_FEATURE_UNSUPPORTED == result);
79d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(NULL == outputMixEnvironmentalReverb);
80d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
81d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // resume environmental reverb interface
82d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixDIM)->ResumeInterface(outputMixDIM, SL_IID_ENVIRONMENTALREVERB,
83d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten            SL_BOOLEAN_FALSE);
84d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_PRECONDITIONS_VIOLATED == result);
85d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
86d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // get environmental reverb interface, after resume but before add
87d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
88d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten            &outputMixEnvironmentalReverb);
89d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_FEATURE_UNSUPPORTED == result);
90d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(NULL == outputMixEnvironmentalReverb);
91d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
92d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // add environmental reverb interface
93d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixDIM)->AddInterface(outputMixDIM, SL_IID_ENVIRONMENTALREVERB,
94d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten            SL_BOOLEAN_FALSE);
95d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
96d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
97d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // get environmental reverb interface, after add
98d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
99d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten            &outputMixEnvironmentalReverb);
100d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
101d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(NULL != outputMixEnvironmentalReverb);
102d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
103d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // add environmental reverb interface again
104d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixDIM)->AddInterface(outputMixDIM, SL_IID_ENVIRONMENTALREVERB,
105d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten            SL_BOOLEAN_FALSE);
106d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_PRECONDITIONS_VIOLATED == result);
107d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
108d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // resume environmental reverb interface
109d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixDIM)->ResumeInterface(outputMixDIM, SL_IID_ENVIRONMENTALREVERB,
110d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten            SL_BOOLEAN_FALSE);
111d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_PRECONDITIONS_VIOLATED == result);
112d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
113d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // remove environmental reverb interface (FIXME not yet implemented)
114d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixDIM)->RemoveInterface(outputMixDIM, SL_IID_ENVIRONMENTALREVERB);
115d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert((SL_RESULT_SUCCESS == result) || (SL_RESULT_FEATURE_UNSUPPORTED == result));
116d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
117d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // FIXME once remove is implemented we can try this
118d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    if (SL_RESULT_SUCCESS == result) {
119d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten        result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
120d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten                &outputMixEnvironmentalReverb);
121d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten        assert(SL_RESULT_PRECONDITIONS_VIOLATED == result);
122d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten        assert(NULL == outputMixEnvironmentalReverb);
123d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten        result = (*outputMixDIM)->RemoveInterface(outputMixDIM, SL_IID_ENVIRONMENTALREVERB);
124d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten        assert(SL_RESULT_PRECONDITIONS_VIOLATED == result);
125d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten        result = (*outputMixDIM)->AddInterface(outputMixDIM, SL_IID_ENVIRONMENTALREVERB,
126d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten                SL_BOOLEAN_FALSE);
127d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
128d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten        result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
129d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten                &outputMixEnvironmentalReverb);
130d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
131d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten        assert(NULL != outputMixEnvironmentalReverb);
132d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    }
133d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
134d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // get non-sensical play interface, before add
135d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    SLPlayItf outputMixPlay;
136d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_PLAY, &outputMixPlay);
137d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_FEATURE_UNSUPPORTED == result);
138d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(NULL == outputMixPlay);
139d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
140d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // add play interface
141d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixDIM)->AddInterface(outputMixDIM, SL_IID_PLAY, SL_BOOLEAN_FALSE);
142d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_FEATURE_UNSUPPORTED == result);
143d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
144d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // get play interface should still fail
145d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_PLAY, &outputMixPlay);
146d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(SL_RESULT_FEATURE_UNSUPPORTED == result);
147d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    assert(NULL == outputMixPlay);
148d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
149d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // destroy output mix
150d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    (*outputMixObject)->Destroy(outputMixObject);
151d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
152d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    // destroy engine
153d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    (*engineObject)->Destroy(engineObject);
154d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten
155d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    return EXIT_SUCCESS;
156d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten}
157