136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/*
236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Copyright (C) 2010 The Android Open Source Project
336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *
436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * you may not use this file except in compliance with the License.
636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * You may obtain a copy of the License at
736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *
836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *      http://www.apache.org/licenses/LICENSE-2.0
936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *
1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Unless required by applicable law or agreed to in writing, software
1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * See the License for the specific language governing permissions and
1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * limitations under the License.
1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines */
1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This test program tortures the seek APIs by positioning "randomly" in a file.
18dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// It needs as input a permuted .wav and .map produced by the permute tool.
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <SLES/OpenSLES.h>
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <assert.h>
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <stdio.h>
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <stdlib.h>
2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <unistd.h>
2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define ASSERT_EQ(x, y) assert((x) == (y))
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesint main(int argc, char **argv)
2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines{
3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (argc != 3) {
3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        fprintf(stderr, "usage: %s file.wav file.map\n", argv[0]);
3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        fprintf(stderr, "  where file.wav and file.map are created by the permute tool\n");
3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return EXIT_FAILURE;
3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SLresult result;
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // create engine
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SLObjectItf engineObject;
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ASSERT_EQ(SL_RESULT_SUCCESS, result);
4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ASSERT_EQ(SL_RESULT_SUCCESS, result);
44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SLEngineItf engineEngine;
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ASSERT_EQ(SL_RESULT_SUCCESS, result);
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // create output mix
49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SLObjectItf outputmixObject;
5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputmixObject, 0, NULL, NULL);
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ASSERT_EQ(SL_RESULT_SUCCESS, result);
5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    result = (*outputmixObject)->Realize(outputmixObject, SL_BOOLEAN_FALSE);
5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ASSERT_EQ(SL_RESULT_SUCCESS, result);
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // create an audio player with URI source and output mix sink
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SLDataSource audiosrc;
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SLDataSink audiosnk;
5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SLDataLocator_OutputMix locator_outputmix;
59cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    SLDataLocator_URI locator_uri;
6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SLDataFormat_MIME mime;
6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    locator_uri.locatorType = SL_DATALOCATOR_URI;
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    locator_uri.URI = (SLchar *) argv[1];
63cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
64cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    locator_outputmix.outputMix = outputmixObject;
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    mime.formatType = SL_DATAFORMAT_MIME;
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    mime.mimeType = (SLchar *) NULL;
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    audiosrc.pLocator = &locator_uri;
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    audiosrc.pFormat = &mime;
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    audiosnk.pLocator = &locator_outputmix;
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    audiosnk.pFormat = NULL;
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SLObjectItf playerObject;
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SLInterfaceID ids[1] = {SL_IID_SEEK};
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SLboolean flags[1] = {SL_BOOLEAN_TRUE};
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audiosrc, &audiosnk,
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            1, ids, flags);
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ASSERT_EQ(SL_RESULT_SUCCESS, result);
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE);
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ASSERT_EQ(SL_RESULT_SUCCESS, result);
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SLPlayItf playerPlay;
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay);
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ASSERT_EQ(SL_RESULT_SUCCESS, result);
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SLSeekItf playerSeek;
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    result = (*playerObject)->GetInterface(playerObject, SL_IID_SEEK, &playerSeek);
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ASSERT_EQ(SL_RESULT_SUCCESS, result);
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SLmillisecond duration;
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    result = (*playerPlay)->GetDuration(playerPlay, &duration);
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ASSERT_EQ(SL_RESULT_SUCCESS, result);
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PAUSED);
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ASSERT_EQ(SL_RESULT_SUCCESS, result);
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    result = (*playerPlay)->GetDuration(playerPlay, &duration);
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ASSERT_EQ(SL_RESULT_SUCCESS, result);
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
94cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    ASSERT_EQ(SL_RESULT_SUCCESS, result);
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#if 1
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // play back a file in permuted order using the seek map
9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    FILE *fp_map = fopen(argv[2], "r");
9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (fp_map != NULL) {
10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        unsigned position, duration;
10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        while (fscanf(fp_map, "%u %u", &position, &duration) == 2) {
10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            printf("%u %u\n", position, duration);
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            result = (*playerSeek)->SetPosition(playerSeek, (SLmillisecond) position,
10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    SL_SEEKMODE_ACCURATE);
10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ASSERT_EQ(SL_RESULT_SUCCESS, result);
10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            if (duration > 0)
10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                usleep(duration * 1000);
10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#else
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    set_conio_terminal_mode();
11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // loop repeatedly, inflicting seek pain each cycle
11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (;;) {
11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (kbhit()) {
116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            switch (getch()) {
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            case 'q':
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                goto out;
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            }
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        SLmillisecond delay = 100 + (rand() & 8191);
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        printf("sleep %u\n", (unsigned) delay);
12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        usleep(delay * 1000);
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        SLmillisecond newPos = duration * ((rand() & 65535) / 65536.0);
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        printf("seek %u\n", (unsigned) newPos);
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        result = (*playerSeek)->SetPosition(playerSeek, newPos, SL_SEEKMODE_ACCURATE);
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        ASSERT_EQ(SL_RESULT_SUCCESS, result);
12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        SLmillisecond nowPos;
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        result = (*playerPlay)->GetPosition(playerPlay, &nowPos);
13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        ASSERT_EQ(SL_RESULT_SUCCESS, result);
13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        printf("now %u\n", (unsigned) newPos);
13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesout:
13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif
13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EXIT_SUCCESS;
13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines