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 // This test program tortures the seek APIs by positioning "randomly" in a file.
18 // It needs as input a permuted .wav and .map produced by the permute tool.
19
20 #include <SLES/OpenSLES.h>
21 #include <assert.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25
26 #define ASSERT_EQ(x, y) assert((x) == (y))
27
main(int argc,char ** argv)28 int main(int argc, char **argv)
29 {
30 if (argc != 3) {
31 fprintf(stderr, "usage: %s file.wav file.map\n", argv[0]);
32 fprintf(stderr, " where file.wav and file.map are created by the permute tool\n");
33 return EXIT_FAILURE;
34 }
35
36 SLresult result;
37
38 // create engine
39 SLObjectItf engineObject;
40 result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
41 ASSERT_EQ(SL_RESULT_SUCCESS, result);
42 result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
43 ASSERT_EQ(SL_RESULT_SUCCESS, result);
44 SLEngineItf engineEngine;
45 result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
46 ASSERT_EQ(SL_RESULT_SUCCESS, result);
47
48 // create output mix
49 SLObjectItf outputmixObject;
50 result = (*engineEngine)->CreateOutputMix(engineEngine, &outputmixObject, 0, NULL, NULL);
51 ASSERT_EQ(SL_RESULT_SUCCESS, result);
52 result = (*outputmixObject)->Realize(outputmixObject, SL_BOOLEAN_FALSE);
53 ASSERT_EQ(SL_RESULT_SUCCESS, result);
54
55 // create an audio player with URI source and output mix sink
56 SLDataSource audiosrc;
57 SLDataSink audiosnk;
58 SLDataLocator_OutputMix locator_outputmix;
59 SLDataLocator_URI locator_uri;
60 SLDataFormat_MIME mime;
61 locator_uri.locatorType = SL_DATALOCATOR_URI;
62 locator_uri.URI = (SLchar *) argv[1];
63 locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
64 locator_outputmix.outputMix = outputmixObject;
65 mime.formatType = SL_DATAFORMAT_MIME;
66 mime.mimeType = (SLchar *) NULL;
67 mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
68 audiosrc.pLocator = &locator_uri;
69 audiosrc.pFormat = &mime;
70 audiosnk.pLocator = &locator_outputmix;
71 audiosnk.pFormat = NULL;
72 SLObjectItf playerObject;
73 SLInterfaceID ids[1] = {SL_IID_SEEK};
74 SLboolean flags[1] = {SL_BOOLEAN_TRUE};
75 result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audiosrc, &audiosnk,
76 1, ids, flags);
77 ASSERT_EQ(SL_RESULT_SUCCESS, result);
78 result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE);
79 ASSERT_EQ(SL_RESULT_SUCCESS, result);
80 SLPlayItf playerPlay;
81 result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay);
82 ASSERT_EQ(SL_RESULT_SUCCESS, result);
83 SLSeekItf playerSeek;
84 result = (*playerObject)->GetInterface(playerObject, SL_IID_SEEK, &playerSeek);
85 ASSERT_EQ(SL_RESULT_SUCCESS, result);
86 SLmillisecond duration;
87 result = (*playerPlay)->GetDuration(playerPlay, &duration);
88 ASSERT_EQ(SL_RESULT_SUCCESS, result);
89 result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PAUSED);
90 ASSERT_EQ(SL_RESULT_SUCCESS, result);
91 result = (*playerPlay)->GetDuration(playerPlay, &duration);
92 ASSERT_EQ(SL_RESULT_SUCCESS, result);
93 result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
94 ASSERT_EQ(SL_RESULT_SUCCESS, result);
95
96 #if 1
97 // play back a file in permuted order using the seek map
98 FILE *fp_map = fopen(argv[2], "r");
99 if (fp_map != NULL) {
100 unsigned position, duration;
101 while (fscanf(fp_map, "%u %u", &position, &duration) == 2) {
102 printf("%u %u\n", position, duration);
103 result = (*playerSeek)->SetPosition(playerSeek, (SLmillisecond) position,
104 SL_SEEKMODE_ACCURATE);
105 ASSERT_EQ(SL_RESULT_SUCCESS, result);
106 if (duration > 0)
107 usleep(duration * 1000);
108 }
109 }
110 #else
111 set_conio_terminal_mode();
112
113 // loop repeatedly, inflicting seek pain each cycle
114 for (;;) {
115 if (kbhit()) {
116 switch (getch()) {
117 case 'q':
118 goto out;
119 }
120 }
121 SLmillisecond delay = 100 + (rand() & 8191);
122 printf("sleep %u\n", (unsigned) delay);
123 usleep(delay * 1000);
124 SLmillisecond newPos = duration * ((rand() & 65535) / 65536.0);
125 printf("seek %u\n", (unsigned) newPos);
126 result = (*playerSeek)->SetPosition(playerSeek, newPos, SL_SEEKMODE_ACCURATE);
127 ASSERT_EQ(SL_RESULT_SUCCESS, result);
128 SLmillisecond nowPos;
129 result = (*playerPlay)->GetPosition(playerPlay, &nowPos);
130 ASSERT_EQ(SL_RESULT_SUCCESS, result);
131 printf("now %u\n", (unsigned) newPos);
132 }
133 out:
134 #endif
135
136 return EXIT_SUCCESS;
137 }
138