10a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten/* 20a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten * Copyright (C) 2010 The Android Open Source Project 30a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten * 40a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 50a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten * you may not use this file except in compliance with the License. 60a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten * You may obtain a copy of the License at 70a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten * 80a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 90a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten * 100a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten * Unless required by applicable law or agreed to in writing, software 110a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 120a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten * See the License for the specific language governing permissions and 140a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten * limitations under the License. 150a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten */ 160a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 170a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten// single-threaded, single-player monkey test 180a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 19c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES.h> 200a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten#include <assert.h> 210a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten#include <stdio.h> 220a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten#include <stdlib.h> 230a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten#include <string.h> 240a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten#include <unistd.h> 250a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 260a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kastentypedef enum { 270a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten STATE_UNCHANGED, 280a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten STATE_INITIAL, 290a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten STATE_NONEXISTENT, 300a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten STATE_CREATED, 310a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten STATE_REALIZED, 320a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten STATE_PAUSED, 330a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten STATE_PLAYING, 340a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten STATE_STOPPED, 350a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten STATE_ERROR, 360a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten// STATE_IDLE, // after Stop, then sleep for 3 seconds 370a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten STATE_TERMINAL 380a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} State_t; 390a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 400a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kastentypedef struct { 410a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLObjectItf mObject; 420a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLPlayItf mPlay; 430a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLSeekItf mSeek; 440a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} Player_t, *Player_pt; 450a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 460a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kastentypedef State_t (*Action_pt)(Player_pt player); 470a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 480a058cc3d720cdf3f0f8222472a862258482f34fGlenn KastenSLObjectItf engineObject; 490a058cc3d720cdf3f0f8222472a862258482f34fGlenn KastenSLEngineItf engineEngine; 500a058cc3d720cdf3f0f8222472a862258482f34fGlenn KastenSLObjectItf outputMixObject; 510a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kastenint countTransitions = 0; 520a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kastenint maxTransitions = 10; 530a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 540a058cc3d720cdf3f0f8222472a862258482f34fGlenn KastenState_t actionPause(Player_pt p) 550a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten{ 560a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(NULL != p->mPlay); 570a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLresult result = (*p->mPlay)->SetPlayState(p->mPlay, SL_PLAYSTATE_PAUSED); 580a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_RESULT_SUCCESS == result); 590a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return STATE_PAUSED; 600a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} 610a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 620a058cc3d720cdf3f0f8222472a862258482f34fGlenn KastenState_t actionPlay(Player_pt p) 630a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten{ 640a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(NULL != p->mPlay); 650a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLresult result = (*p->mPlay)->SetPlayState(p->mPlay, SL_PLAYSTATE_PLAYING); 660a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_RESULT_SUCCESS == result); 670a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return STATE_PLAYING; 680a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} 690a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 700a058cc3d720cdf3f0f8222472a862258482f34fGlenn KastenState_t actionStop(Player_pt p) 710a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten{ 720a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(NULL != p->mPlay); 730a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLresult result = (*p->mPlay)->SetPlayState(p->mPlay, SL_PLAYSTATE_STOPPED); 740a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_RESULT_SUCCESS == result); 750a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return STATE_STOPPED; 760a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} 770a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 780a058cc3d720cdf3f0f8222472a862258482f34fGlenn KastenState_t actionRewind(Player_pt p) 790a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten{ 800a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(NULL != p->mSeek); 810a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLresult result = (*p->mSeek)->SetPosition(p->mSeek, (SLmillisecond) 0, SL_SEEKMODE_FAST); 820a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_RESULT_SUCCESS == result); 830a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return STATE_UNCHANGED; 840a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} 850a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 860a058cc3d720cdf3f0f8222472a862258482f34fGlenn KastenState_t actionDestroy(Player_pt p) 870a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten{ 880a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(NULL != p->mObject); 890a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten (*p->mObject)->Destroy(p->mObject); 900a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten p->mObject = NULL; 910a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten p->mPlay = NULL; 920a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten p->mSeek = NULL; 930a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return STATE_NONEXISTENT; 940a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} 950a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 960a058cc3d720cdf3f0f8222472a862258482f34fGlenn KastenState_t actionCreate(Player_pt p) 970a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten{ 980a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten // configure audio source 990a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLDataLocator_URI loc_uri; 1000a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten loc_uri.locatorType = SL_DATALOCATOR_URI; 1010a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten loc_uri.URI = (SLchar *) "wav/frog.wav"; 1020a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLDataFormat_MIME format_mime; 1030a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten format_mime.formatType = SL_DATAFORMAT_MIME; 1040a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten format_mime.mimeType = NULL; 1050a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten format_mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED; 1060a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLDataSource audioSrc; 1070a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten audioSrc.pLocator = &loc_uri; 1080a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten audioSrc.pFormat = &format_mime; 1090a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten // configure audio sink 1100a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLDataLocator_OutputMix loc_outmix; 1110a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 1120a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten loc_outmix.outputMix = outputMixObject; 1130a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLDataSink audioSnk; 1140a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten audioSnk.pLocator = &loc_outmix; 1150a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten audioSnk.pFormat = NULL; 1160a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten // create audio player 1170a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLInterfaceID ids[1] = {SL_IID_SEEK}; 1180a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLboolean req[1] = {SL_BOOLEAN_TRUE}; 1190a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLresult result = (*engineEngine)->CreateAudioPlayer(engineEngine, &p->mObject, &audioSrc, 1200a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten &audioSnk, 1, ids, req); 1210a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten if (SL_RESULT_SUCCESS != result) 1220a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return STATE_ERROR; 1230a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return STATE_CREATED; 1240a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} 1250a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 1260a058cc3d720cdf3f0f8222472a862258482f34fGlenn KastenState_t actionRealize(Player_pt p) 1270a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten{ 1280a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(NULL != p->mObject); 1290a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten // realize the player 1300a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLresult result = (*p->mObject)->Realize(p->mObject, SL_BOOLEAN_FALSE); 1310a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_RESULT_SUCCESS == result); 1320a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten // get interfaces 1330a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten result = (*p->mObject)->GetInterface(p->mObject, SL_IID_PLAY, &p->mPlay); 1340a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_RESULT_SUCCESS == result); 1350a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten result = (*p->mObject)->GetInterface(p->mObject, SL_IID_SEEK, &p->mSeek); 1360a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_RESULT_SUCCESS == result); 1370a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return STATE_REALIZED; 1380a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} 1390a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 140086a6f51a7b12880ed114962136972f89ed70da2Glenn KastenState_t actionSleep(Player_pt p __unused) 1410a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten{ 1420a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten unsigned us = 1000 + (rand() & 0xFFFFF); 1430a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten usleep(us); 1440a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return STATE_UNCHANGED; 1450a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} 1460a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 1470a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten#if 0 1480a058cc3d720cdf3f0f8222472a862258482f34fGlenn KastenState_t actionSleep3(Player_pt p) 1490a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten{ 1500a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten sleep(3); 1510a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return STATE_IDLE; 1520a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} 1530a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten#endif 1540a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 1550a058cc3d720cdf3f0f8222472a862258482f34fGlenn KastenState_t actionTerminateIfDone(Player_pt p) 1560a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten{ 1570a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten if (countTransitions >= maxTransitions) { 1580a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(NULL == p->mObject); 1590a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten // clean up output mix and engine 1600a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(NULL != outputMixObject); 1610a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten (*outputMixObject)->Destroy(outputMixObject); 1620a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten outputMixObject = NULL; 1630a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(NULL != engineObject); 1640a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten (*engineObject)->Destroy(engineObject); 1650a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten engineObject = NULL; 1660a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return STATE_TERMINAL; 1670a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten } else 1680a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return STATE_UNCHANGED; 1690a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} 1700a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 171086a6f51a7b12880ed114962136972f89ed70da2Glenn KastenState_t actionInitialize(Player_pt p __unused) 1720a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten{ 1730a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten // create engine 1740a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLresult result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 1750a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_RESULT_SUCCESS == result); 1760a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 1770a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_RESULT_SUCCESS == result); 1780a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 1790a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_RESULT_SUCCESS == result); 1800a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 1810a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten // create output mix 1820a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL); 1830a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_RESULT_SUCCESS == result); 1840a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); 1850a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_RESULT_SUCCESS == result); 1860a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 1870a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return STATE_NONEXISTENT; 1880a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} 1890a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 1900a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kastentypedef struct { 1910a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten State_t mEntryState; 1920a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten Action_pt mAction; 1930a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten unsigned mProbability; 1940a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten const char *mActionName; 1950a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten unsigned mCount; 1960a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} Transition_t; 1970a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 1980a058cc3d720cdf3f0f8222472a862258482f34fGlenn KastenTransition_t transitionTable[] = { 1990a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten#define _(entryState, action, probability) {entryState, action, probability, #action, 0}, 2000a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_INITIAL, actionInitialize, 1) 2010a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_CREATED, actionDestroy, 1) 2020a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_CREATED, actionRealize, 1) 2030a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_CREATED, actionSleep, 1) 2040a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_NONEXISTENT, actionCreate, 1) 2050a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_NONEXISTENT, actionSleep, 1) 2060a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_PAUSED, actionDestroy, 1) 2070a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_PAUSED, actionPause, 1) 2080a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_PAUSED, actionPlay, 1) 2090a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_PAUSED, actionRewind, 1) 2100a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_PAUSED, actionSleep, 1) 2110a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_PAUSED, actionStop, 1) 2120a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_PLAYING, actionDestroy, 1) 2130a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_PLAYING, actionPause, 1) 2140a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_PLAYING, actionPlay, 1) 2150a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_PLAYING, actionRewind, 1) 2160a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_PLAYING, actionSleep, 1) 2170a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_PLAYING, actionStop, 1) 2180a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_REALIZED, actionDestroy, 1) 2190a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_REALIZED, actionPause, 1) 2200a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_REALIZED, actionPlay, 1) 2210a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_REALIZED, actionSleep, 1) 2220a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_REALIZED, actionStop, 1) 2230a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_STOPPED, actionDestroy, 1) 2240a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_STOPPED, actionPause, 1) 2250a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_STOPPED, actionPlay, 1) 2260a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_STOPPED, actionRewind, 1) 2270a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_STOPPED, actionSleep, 1) 2280a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_STOPPED, actionStop, 1) 2290a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten// _(STATE_STOPPED, actionSleep3, 1) 2300a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten// _(STATE_IDLE, actionDestroy, 1) 2310a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten _(STATE_NONEXISTENT, actionTerminateIfDone, 1) 2320a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten}; 2330a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten 2340a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kastenint main(int argc, char **argv) 2350a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten{ 2360a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten int i; 2370a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten for (i = 1; i < argc; ++i) { 2380a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten char *arg = argv[i]; 2390a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten if (arg[0] != '-') 2400a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten break; 2410a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten if (!strncmp(arg, "-m", 2)) { 2420a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten maxTransitions = atoi(&arg[2]); 2430a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten } else { 2440a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten fprintf(stderr, "Unknown option %s\n", arg); 2450a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten } 2460a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten } 2470a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten unsigned possibleTransitions = sizeof(transitionTable) / sizeof(transitionTable[0]); 2480a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten Player_t player; 2490a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten player.mObject = NULL; 2500a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten player.mPlay = NULL; 2510a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten player.mSeek = NULL; 2520a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten State_t currentState = STATE_INITIAL; 2530a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten while (STATE_TERMINAL != currentState) { 2540a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten unsigned matchingTransitions = 0; 2550a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten unsigned totalProbability = 0; 2560a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten for (i = 0; i < (int) possibleTransitions; ++i) { 2570a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten if (currentState != transitionTable[i].mEntryState) 2580a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten continue; 2590a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten ++matchingTransitions; 2600a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten totalProbability += transitionTable[i].mProbability; 2610a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten } 2620a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten if (matchingTransitions == 0) { 2630a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten fprintf(stderr, "No matching transitions in state %d\n", currentState); 2640a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_BOOLEAN_FALSE); 2650a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten break; 2660a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten } 2670a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten if (totalProbability == 0) { 2680a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten fprintf(stderr, "Found at least one matching transition in state %d, " 2690a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten "but with probability 0\n", currentState); 2700a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_BOOLEAN_FALSE); 2710a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten break; 2720a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten } 2730a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten unsigned choice = (rand() & 0x7FFFFFFF) % totalProbability; 2740a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten totalProbability = 0; 2750a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten for (i = 0; i < (int) possibleTransitions; ++i) { 2760a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten if (currentState != transitionTable[i].mEntryState) 2770a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten continue; 2780a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten totalProbability += transitionTable[i].mProbability; 2790a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten if (totalProbability <= choice) 2800a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten continue; 2810a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten ++transitionTable[i].mCount; 2820a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten ++countTransitions; 2830a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten printf("[%d] Selecting transition %s in state %d for the %u time\n", countTransitions, 2840a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten transitionTable[i].mActionName, currentState, transitionTable[i].mCount); 2850a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten State_t nextState = (*transitionTable[i].mAction)(&player); 2860a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten if (STATE_UNCHANGED != nextState) 2870a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten currentState = nextState; 2880a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten goto found; 2890a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten } 2900a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten fprintf(stderr, "This shouldn't happen\n"); 2910a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten assert(SL_BOOLEAN_FALSE); 2920a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kastenfound: 2930a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten ; 2940a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten } 2950a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten for (i = 0; i < (int) possibleTransitions; ++i) { 2960a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten printf("state %d action %s count %u\n", 2970a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten transitionTable[i].mEntryState, 2980a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten transitionTable[i].mActionName, 2990a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten transitionTable[i].mCount); 3000a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten } 3010a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return EXIT_SUCCESS; 3020a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten} 303