1b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten/* 2b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten * Copyright (C) 2010 The Android Open Source Project 3b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten * 4b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 5b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten * you may not use this file except in compliance with the License. 6b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten * You may obtain a copy of the License at 7b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten * 8b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 9b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten * 10b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten * Unless required by applicable law or agreed to in writing, software 11b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 12b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten * See the License for the specific language governing permissions and 14b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten * limitations under the License. 15b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten */ 16b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten 17095ce2204cc75a50d9f1df60d1c8f357209a7c3dGlenn Kasten// This test program tortures the seek APIs by positioning "randomly" in a file. 18095ce2204cc75a50d9f1df60d1c8f357209a7c3dGlenn Kasten// It needs as input a permuted .wav and .map produced by the permute tool. 19b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten 20c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES.h> 21b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten#include <assert.h> 22b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten#include <stdio.h> 23b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten#include <stdlib.h> 24b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten#include <unistd.h> 25b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten 26b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten#define ASSERT_EQ(x, y) assert((x) == (y)) 27b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten 28b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kastenint main(int argc, char **argv) 29b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten{ 30b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten if (argc != 3) { 31b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten fprintf(stderr, "usage: %s file.wav file.map\n", argv[0]); 32095ce2204cc75a50d9f1df60d1c8f357209a7c3dGlenn Kasten fprintf(stderr, " where file.wav and file.map are created by the permute tool\n"); 33b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten return EXIT_FAILURE; 34b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten } 35b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten 36b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLresult result; 37b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten 38b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten // create engine 39b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLObjectItf engineObject; 40b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 41b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 42b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 43b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 44b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLEngineItf engineEngine; 45b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 46b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 47b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten 48b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten // create output mix 49b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLObjectItf outputmixObject; 50b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten result = (*engineEngine)->CreateOutputMix(engineEngine, &outputmixObject, 0, NULL, NULL); 51b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 52b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten result = (*outputmixObject)->Realize(outputmixObject, SL_BOOLEAN_FALSE); 53b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 54b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten 55b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten // create an audio player with URI source and output mix sink 56b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLDataSource audiosrc; 57b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLDataSink audiosnk; 58b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLDataLocator_OutputMix locator_outputmix; 59b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLDataLocator_URI locator_uri; 60c0b196d740ef7a60728a014be0eaadb0dbc1d7aeGlenn Kasten SLDataFormat_MIME mime; 61b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten locator_uri.locatorType = SL_DATALOCATOR_URI; 62e629abc58c2acadc7487ea71c1e063f8f8989199Glenn Kasten locator_uri.URI = (SLchar *) argv[1]; 63b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 64b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten locator_outputmix.outputMix = outputmixObject; 65c0b196d740ef7a60728a014be0eaadb0dbc1d7aeGlenn Kasten mime.formatType = SL_DATAFORMAT_MIME; 66c0b196d740ef7a60728a014be0eaadb0dbc1d7aeGlenn Kasten mime.mimeType = (SLchar *) NULL; 67c0b196d740ef7a60728a014be0eaadb0dbc1d7aeGlenn Kasten mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED; 68b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten audiosrc.pLocator = &locator_uri; 69c0b196d740ef7a60728a014be0eaadb0dbc1d7aeGlenn Kasten audiosrc.pFormat = &mime; 70b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten audiosnk.pLocator = &locator_outputmix; 71b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten audiosnk.pFormat = NULL; 72b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLObjectItf playerObject; 73b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLInterfaceID ids[1] = {SL_IID_SEEK}; 74b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLboolean flags[1] = {SL_BOOLEAN_TRUE}; 75a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audiosrc, &audiosnk, 76a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi 1, ids, flags); 77b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 78b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE); 79b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 80b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLPlayItf playerPlay; 81b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay); 82b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 83b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLSeekItf playerSeek; 84b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten result = (*playerObject)->GetInterface(playerObject, SL_IID_SEEK, &playerSeek); 85b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 86b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLmillisecond duration; 87b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten result = (*playerPlay)->GetDuration(playerPlay, &duration); 88b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 89b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PAUSED); 90b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 91b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten result = (*playerPlay)->GetDuration(playerPlay, &duration); 92b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 93b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING); 94b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 95b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten 96b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten#if 1 97b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten // play back a file in permuted order using the seek map 98b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten FILE *fp_map = fopen(argv[2], "r"); 99b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten if (fp_map != NULL) { 100b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten unsigned position, duration; 101b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten while (fscanf(fp_map, "%u %u", &position, &duration) == 2) { 102b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten printf("%u %u\n", position, duration); 103a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi result = (*playerSeek)->SetPosition(playerSeek, (SLmillisecond) position, 104a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi SL_SEEKMODE_ACCURATE); 105b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 106b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten if (duration > 0) 107b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten usleep(duration * 1000); 108b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten } 109b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten } 110b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten#else 111b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten set_conio_terminal_mode(); 112b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten 113b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten // loop repeatedly, inflicting seek pain each cycle 114b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten for (;;) { 115b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten if (kbhit()) { 116b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten switch (getch()) { 117b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten case 'q': 118b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten goto out; 119b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten } 120b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten } 121b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLmillisecond delay = 100 + (rand() & 8191); 122b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten printf("sleep %u\n", (unsigned) delay); 123b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten usleep(delay * 1000); 124b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLmillisecond newPos = duration * ((rand() & 65535) / 65536.0); 125b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten printf("seek %u\n", (unsigned) newPos); 126b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten result = (*playerSeek)->SetPosition(playerSeek, newPos, SL_SEEKMODE_ACCURATE); 127b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 128b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten SLmillisecond nowPos; 129b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten result = (*playerPlay)->GetPosition(playerPlay, &nowPos); 130b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 131b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten printf("now %u\n", (unsigned) newPos); 132b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten } 133b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kastenout: 134b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten#endif 135b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten 136b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten return EXIT_SUCCESS; 137b9fa556e62aa6e0c8a59f224136e509df813cfc7Glenn Kasten} 138