multithread.c revision 7126c25d7c037e5086216cf540ecf40779c3585a
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// Multiple threads create and destroy objects 18 19#include "SLES/OpenSLES.h" 20#include <assert.h> 21#include <pthread.h> 22//#include <string.h> 23#include <stdio.h> 24#include <stdlib.h> 25#include <unistd.h> 26 27typedef struct { 28 SLuint32 mObjectID; 29 SLchar *mURI; 30 SLEngineItf mEngineEngine; 31 SLObjectItf mMixObject; 32 SLuint32 mCounter; 33} ThreadArgument; 34 35volatile int timeToExit = 0; 36#define MAX_THREAD 10 37pthread_t threads[MAX_THREAD]; 38ThreadArgument thread_args[MAX_THREAD]; 39 40pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 41 42void *thread_start(void *param) 43{ 44 //pthread_mutex_lock(&mutex); 45 //pthread_mutex_unlock(&mutex); 46 ThreadArgument *ta = (ThreadArgument *) param; 47 48 while (!timeToExit) { 49 SLresult result; 50 51 ++ta->mCounter; 52 switch (ta->mObjectID) { 53 case SL_OBJECTID_OUTPUTMIX: 54 { 55 SLObjectItf myMixObject; 56 result = (*ta->mEngineEngine)->CreateOutputMix(ta->mEngineEngine, &myMixObject, 0, NULL, 57 NULL); 58 assert(SL_RESULT_SUCCESS == result); 59 result = (*myMixObject)->Realize(myMixObject, SL_BOOLEAN_FALSE); 60 assert(SL_RESULT_SUCCESS == result); 61 (*myMixObject)->Destroy(myMixObject); 62 } 63 break; 64 65 case SL_OBJECTID_AUDIOPLAYER: 66 { 67 SLDataLocator_URI locURI = {SL_DATALOCATOR_URI, ta->mURI}; 68 SLDataFormat_MIME dfMIME = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED}; 69 SLDataSource audioSrc = {&locURI, &dfMIME}; 70 SLDataLocator_OutputMix locOutputMix = {SL_DATALOCATOR_OUTPUTMIX, ta->mMixObject}; 71 SLDataSink audioSnk = {&locOutputMix, NULL}; 72 SLObjectItf myPlayerObject; 73 result = (*ta->mEngineEngine)->CreateAudioPlayer(ta->mEngineEngine, &myPlayerObject, 74 &audioSrc, &audioSnk, 0, NULL, NULL); 75 assert(SL_RESULT_SUCCESS == result); 76 result = (*myPlayerObject)->Realize(myPlayerObject, SL_BOOLEAN_FALSE); 77 assert(SL_RESULT_SUCCESS == result); 78 SLPlayItf playerPlay; 79 result = (*myPlayerObject)->GetInterface(myPlayerObject, SL_IID_PLAY, &playerPlay); 80 assert(SL_RESULT_SUCCESS == result); 81 result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);//PAUSED); 82 assert(SL_RESULT_SUCCESS == result); 83 usleep(1000000 + (rand() & 0xFFFFF));//Android crash on 10000 and PAUSED 84 (*myPlayerObject)->Destroy(myPlayerObject); 85 } 86 break; 87 88 default: 89 break; 90 91 } 92 //usleep(100000); 93 } 94 95 return NULL; 96} 97 98 99const char * const uris[4] = {"wav/frog.wav", "wav/bach.wav", "wav/8days.wav", "wav/help16.wav"}; 100 101// Main program 102 103int main(int argc, char **argv) 104{ 105 SLresult result; 106 107 // create engine 108 SLObjectItf engineObject; 109 result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 110 assert(SL_RESULT_SUCCESS == result); 111 result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 112 assert(SL_RESULT_SUCCESS == result); 113 SLEngineItf engineEngine; 114 result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 115 assert(SL_RESULT_SUCCESS == result); 116 117 // create output mix 118 SLObjectItf mixObject; 119 result = (*engineEngine)->CreateOutputMix(engineEngine, &mixObject, 0, NULL, NULL); 120 assert(SL_RESULT_SUCCESS == result); 121 result = (*mixObject)->Realize(mixObject, SL_BOOLEAN_FALSE); 122 assert(SL_RESULT_SUCCESS == result); 123 124 // create threads 125 int i; 126 int ok; 127 for (i = 0; i < MAX_THREAD; ++i) { 128 ThreadArgument *ta = &thread_args[i]; 129 int r = rand(); 130 switch (r & 1) { 131#if 0 132 case 0: 133 ta->mObjectID = SL_OBJECTID_OUTPUTMIX; 134 ta->mURI = NULL; 135 ta->mEngineEngine = engineEngine; 136 ta->mMixObject = NULL; 137 ta->mCounter = 0; 138 break; 139 case 1: 140#endif 141 default: 142 ta->mObjectID = SL_OBJECTID_AUDIOPLAYER; 143 ta->mURI = (SLchar *) uris[(r >> 1) & 3]; 144 ta->mEngineEngine = engineEngine; 145 ta->mMixObject = mixObject; 146 ta->mCounter = 0; 147 break; 148 } 149 //pthread_mutex_lock(&mutex); 150 //pthread_mutex_unlock(&mutex); 151 ok = pthread_create(&threads[i], (const pthread_attr_t *) NULL, thread_start, 152 &thread_args[i]); 153 assert(0 == ok); 154 } 155 156 // let it run for a while 157 int j; 158 for (j = 0; j < 10; ++j) { 159 sleep(1); 160 for (i = 0; i < MAX_THREAD; ++i) { 161 ThreadArgument *ta = &thread_args[i]; 162 printf("[%d]=%lu ", j, ta->mCounter); 163 } 164 printf("\n"); 165 } 166 167 // signal threads that they should exit 168 timeToExit = 1; 169 170 for (j = 0; j < 3; ++j) { 171 sleep(1); 172 for (i = 0; i < MAX_THREAD; ++i) { 173 ThreadArgument *ta = &thread_args[i]; 174 printf("[%d]=%lu ", j, ta->mCounter); 175 } 176 printf("\n"); 177 } 178 179 // now wait for the threads to actually exit 180 for (i = 0; i < MAX_THREAD; ++i) { 181 ok = pthread_join(threads[i], NULL); 182 assert(0 == ok); 183 } 184 185 // tear down objects 186 (*mixObject)->Destroy(mixObject); 187 (*engineObject)->Destroy(engineObject); 188 189 return EXIT_SUCCESS; 190} 191