Home | History | Annotate | Download | only in mimeUri
      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 #include <stdlib.h>
     18 #include <stdio.h>
     19 #include <string.h>
     20 #include <unistd.h>
     21 #include <sys/time.h>
     22 
     23 #include <SLES/OpenSLES.h>
     24 
     25 
     26 #define MAX_NUMBER_INTERFACES 2
     27 
     28 #define TEST_MUTE 0
     29 #define TEST_SOLO 1
     30 
     31 static int testMode;
     32 //-----------------------------------------------------------------
     33 /* Exits the application if an error is encountered */
     34 #define ExitOnError(x) ExitOnErrorFunc(x,__LINE__)
     35 
     36 void ExitOnErrorFunc( SLresult result , int line)
     37 {
     38     if (SL_RESULT_SUCCESS != result) {
     39         fprintf(stdout, "%u error code encountered at line %d, exiting\n", result, line);
     40         exit(EXIT_FAILURE);
     41     }
     42 }
     43 
     44 
     45 //-----------------------------------------------------------------
     46 
     47 /* Play an audio URIs, play, pause, stop  */
     48 void TestPlayUri( SLObjectItf sl, const char* path)
     49 {
     50     SLresult  result;
     51     SLEngineItf EngineItf;
     52 
     53     /* Objects this application uses: one player and an ouput mix */
     54     SLObjectItf  player, outputMix;
     55 
     56     /* Source of audio data to play */
     57     SLDataSource      audioSource;
     58     SLDataLocator_URI uri;
     59     SLDataFormat_MIME mime;
     60 
     61     /* Data sinks for the audio player */
     62     SLDataSink               audioSink;
     63     SLDataLocator_OutputMix  locator_outputmix;
     64 
     65     /* Play, Volume and PrefetchStatus interfaces for the audio player */
     66     SLPlayItf           playItf;
     67     SLMuteSoloItf       muteSoloItf;
     68     SLPrefetchStatusItf prefetchItf;
     69 
     70     SLboolean required[MAX_NUMBER_INTERFACES];
     71     SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
     72 
     73     /* Get the SL Engine Interface which is implicit */
     74     result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
     75     ExitOnError(result);
     76 
     77     /* Initialize arrays required[] and iidArray[] */
     78     for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) {
     79         required[i] = SL_BOOLEAN_FALSE;
     80         iidArray[i] = SL_IID_NULL;
     81     }
     82 
     83     /* ------------------------------------------------------ */
     84     /* Configuration of the output mix  */
     85 
     86     /* Create Output Mix object to be used by the player */
     87      result = (*EngineItf)->CreateOutputMix(EngineItf, &outputMix, 0, iidArray, required);
     88      ExitOnError(result);
     89 
     90     /* Realize the Output Mix object in synchronous mode */
     91     result = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE);
     92     ExitOnError(result);
     93 
     94     /* Setup the data sink structure */
     95     locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
     96     locator_outputmix.outputMix   = outputMix;
     97     audioSink.pLocator            = (void*)&locator_outputmix;
     98     audioSink.pFormat             = NULL;
     99 
    100     /* ------------------------------------------------------ */
    101     /* Configuration of the player  */
    102 
    103     /* Set arrays required[] and iidArray[] for SLMuteSoloItf and SLPrefetchStatusItf interfaces */
    104     /*  (SLPlayItf is implicit) */
    105     required[0] = SL_BOOLEAN_TRUE;
    106     iidArray[0] = SL_IID_MUTESOLO;
    107     required[1] = SL_BOOLEAN_TRUE;
    108     iidArray[1] = SL_IID_PREFETCHSTATUS;
    109 
    110     /* Setup the data source structure for the URI */
    111     uri.locatorType = SL_DATALOCATOR_URI;
    112     uri.URI         =  (SLchar*) path;
    113     mime.formatType = SL_DATAFORMAT_MIME;
    114     /*     this is how ignored mime information is specified, according to OpenSL ES spec
    115      *     in 9.1.6 SLDataFormat_MIME and 8.23 SLMetadataTraversalItf GetChildInfo */
    116     mime.mimeType      = (SLchar*)NULL;
    117     mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
    118 
    119     audioSource.pFormat  = (void*)&mime;
    120     audioSource.pLocator = (void*)&uri;
    121 
    122     /* Create the audio player */
    123     result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink,
    124             MAX_NUMBER_INTERFACES, iidArray, required);
    125     ExitOnError(result);
    126 
    127     /* Realize the player in synchronous mode. */
    128     result = (*player)->Realize(player, SL_BOOLEAN_FALSE); ExitOnError(result);
    129     fprintf(stdout, "URI example: after Realize\n");
    130 
    131     /* Get the SLPlayItf, SLPrefetchStatusItf and SLMuteSoloItf interfaces for the player */
    132     result = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);
    133     ExitOnError(result);
    134 
    135     result = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf);
    136     ExitOnError(result);
    137 
    138     result = (*player)->GetInterface(player, SL_IID_MUTESOLO, (void*)&muteSoloItf);
    139     ExitOnError(result);
    140 
    141 
    142     fprintf(stdout, "Player configured\n");
    143 
    144     /* ------------------------------------------------------ */
    145     /* Playback and test */
    146 
    147     /* Start the data prefetching by setting the player to the paused state */
    148     result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED );
    149     ExitOnError(result);
    150 
    151     /* Wait until there's data to play */
    152     SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
    153     while (prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) {
    154         usleep(100 * 1000);
    155         (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus);
    156     }
    157 
    158 
    159     /* Testing play states */
    160     /* let it play for 2s */
    161     fprintf(stdout, "----- Playing\n");
    162     result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING );
    163     ExitOnError(result);
    164     usleep(2 * 1000 * 1000);
    165 
    166     /* pause for 1s*/
    167     fprintf(stdout, "----- Pausing (1s)\n");
    168     result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED );
    169     ExitOnError(result);
    170     usleep(2 * 1000 * 1000);
    171 
    172     /* resume */
    173     fprintf(stdout, "----- Playing (2s, should have resumed where it paused)\n");
    174     result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING );
    175     ExitOnError(result);
    176     usleep(2 * 1000 * 1000);
    177 
    178     /* stop */
    179     fprintf(stdout, "----- Stopping\n");
    180     result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
    181     ExitOnError(result);
    182 
    183     /* play for 2s */
    184     fprintf(stdout, "----- Playing (2s, should have started from the beginning\n");
    185     result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING );
    186     ExitOnError(result);
    187     usleep(2 * 1000 * 1000);
    188 
    189     /* stop */
    190     fprintf(stdout, "----- Stopping\n");
    191     result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
    192     ExitOnError(result);
    193 
    194 destroyKillKill:
    195 
    196     /* Destroy the players */
    197     (*player)->Destroy(player);
    198 
    199     /* Destroy Output Mix object */
    200     (*outputMix)->Destroy(outputMix);
    201 }
    202 
    203 //-----------------------------------------------------------------
    204 int main(int argc, char* const argv[])
    205 {
    206     SLresult    result;
    207     SLObjectItf sl;
    208 
    209     fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLVolumeItf, SLMuteSoloItf\n",
    210             argv[0]);
    211     fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n");
    212     fprintf(stdout, "Plays a sound and alternates the muting of the channels (for 5s).\n");
    213     fprintf(stdout, " and then alternates the solo\'ing of the channels (for 5s).\n");
    214     fprintf(stdout, "Stops after 10s\n");
    215 
    216     if (argc == 1) {
    217         fprintf(stdout, "Usage: \t%s url\n", argv[0]);
    218         fprintf(stdout, "Example: \"%s /sdcard/my.mp3\"\n", argv[0]);
    219         exit(EXIT_FAILURE);
    220     }
    221 
    222     SLEngineOption EngineOption[] = {
    223             {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE}
    224     };
    225 
    226     result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
    227     ExitOnError(result);
    228 
    229     /* Realizing the SL Engine in synchronous mode. */
    230     result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
    231     ExitOnError(result);
    232 
    233     if (argc > 1) {
    234         TestPlayUri(sl, argv[1]);
    235     }
    236 
    237     /* Shutdown OpenSL ES */
    238     (*sl)->Destroy(sl);
    239 
    240     return EXIT_SUCCESS;
    241 }
    242