Home | History | Annotate | Download | only in sandbox
      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 // Test various buffer queue configurations
     18 
     19 #include <assert.h>
     20 #include <math.h>
     21 #include <stdio.h>
     22 #include <stdlib.h>
     23 #include <unistd.h>
     24 
     25 #include <SLES/OpenSLES.h>
     26 
     27 typedef struct {
     28     SLuint8 numChannels;
     29     SLuint32 milliHz;
     30     SLuint8 bitsPerSample;
     31 } PCM;
     32 
     33 PCM formats[] = {
     34     {1, SL_SAMPLINGRATE_8,      8},
     35     {2, SL_SAMPLINGRATE_8,      8},
     36     {1, SL_SAMPLINGRATE_8,      16},
     37     {2, SL_SAMPLINGRATE_8,      16},
     38     {1, SL_SAMPLINGRATE_11_025, 8},
     39     {2, SL_SAMPLINGRATE_11_025, 8},
     40     {1, SL_SAMPLINGRATE_11_025, 16},
     41     {2, SL_SAMPLINGRATE_11_025, 16},
     42     {1, SL_SAMPLINGRATE_12,     8},
     43     {2, SL_SAMPLINGRATE_12,     8},
     44     {1, SL_SAMPLINGRATE_12,     16},
     45     {2, SL_SAMPLINGRATE_12,     16},
     46     {1, SL_SAMPLINGRATE_16,     8},
     47     {2, SL_SAMPLINGRATE_16,     8},
     48     {1, SL_SAMPLINGRATE_16,     16},
     49     {2, SL_SAMPLINGRATE_16,     16},
     50     {1, SL_SAMPLINGRATE_22_05,  8},
     51     {2, SL_SAMPLINGRATE_22_05,  8},
     52     {1, SL_SAMPLINGRATE_22_05,  16},
     53     {2, SL_SAMPLINGRATE_22_05,  16},
     54     {1, SL_SAMPLINGRATE_24,     8},
     55     {2, SL_SAMPLINGRATE_24,     8},
     56     {1, SL_SAMPLINGRATE_24,     16},
     57     {2, SL_SAMPLINGRATE_24,     16},
     58     {1, SL_SAMPLINGRATE_32,     8},
     59     {2, SL_SAMPLINGRATE_32,     8},
     60     {1, SL_SAMPLINGRATE_32,     16},
     61     {2, SL_SAMPLINGRATE_32,     16},
     62     {1, SL_SAMPLINGRATE_44_1,   8},
     63     {2, SL_SAMPLINGRATE_44_1,   8},
     64     {1, SL_SAMPLINGRATE_44_1,   16},
     65     {2, SL_SAMPLINGRATE_44_1,   16},
     66     {1, SL_SAMPLINGRATE_48,     8},
     67     {2, SL_SAMPLINGRATE_48,     8},
     68     {1, SL_SAMPLINGRATE_48,     16},
     69     {2, SL_SAMPLINGRATE_48,     16},
     70     {0, 0,                      0}
     71 };
     72 
     73 int main(int argc __unused, char **argv __unused)
     74 {
     75     SLresult result;
     76     SLObjectItf engineObject;
     77 
     78     // create engine
     79     result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
     80     assert(SL_RESULT_SUCCESS == result);
     81     SLEngineItf engineEngine;
     82     result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
     83     assert(SL_RESULT_SUCCESS == result);
     84     result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
     85     assert(SL_RESULT_SUCCESS == result);
     86 
     87     // create output mix
     88     SLObjectItf outputMixObject;
     89     result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
     90     assert(SL_RESULT_SUCCESS == result);
     91     result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
     92     assert(SL_RESULT_SUCCESS == result);
     93 
     94     // loop over all formats
     95     PCM *format;
     96     float hzLeft = 440.0;   // A440 (Concert A)
     97     float hzRight = 440.0;
     98     for (format = formats; format->numChannels; ++format) {
     99 
    100         printf("Channels: %d, sample rate: %u, bits: %u\n", format->numChannels,
    101                 format->milliHz / 1000, format->bitsPerSample);
    102 
    103         // configure audio source
    104         SLDataLocator_BufferQueue loc_bufq;
    105         loc_bufq.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
    106         loc_bufq.numBuffers = 1;
    107         SLDataFormat_PCM format_pcm;
    108         format_pcm.formatType = SL_DATAFORMAT_PCM;
    109         format_pcm.numChannels = format->numChannels;
    110         format_pcm.samplesPerSec = format->milliHz;
    111         format_pcm.bitsPerSample = format->bitsPerSample;
    112         format_pcm.containerSize = format->bitsPerSample;
    113         format_pcm.channelMask = 0;
    114         format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
    115         SLDataSource audioSrc;
    116         audioSrc.pLocator = &loc_bufq;
    117         audioSrc.pFormat = &format_pcm;
    118 
    119         // configure audio sink
    120         SLDataLocator_OutputMix loc_outmix;
    121         loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
    122         loc_outmix.outputMix = outputMixObject;
    123         SLDataSink audioSnk;
    124         audioSnk.pLocator = &loc_outmix;
    125         audioSnk.pFormat = NULL;
    126 
    127         // create audio player
    128         SLuint32 numInterfaces = 1;
    129         SLInterfaceID ids[1];
    130         SLboolean req[1];
    131         ids[0] = SL_IID_BUFFERQUEUE;
    132         req[0] = SL_BOOLEAN_TRUE;
    133         SLObjectItf playerObject;
    134         result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
    135                 &audioSnk, numInterfaces, ids, req);
    136         if (SL_RESULT_SUCCESS != result) {
    137             printf("failed %u\n", result);
    138             continue;
    139         }
    140 
    141         // realize the player
    142         result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE);
    143         assert(SL_RESULT_SUCCESS == result);
    144 
    145         // generate a sine wave buffer, ascending in half-steps for each format
    146 #define N (44100*4)
    147         static unsigned char buffer[N];
    148         unsigned i;
    149         for (i = 0; i < N; ) {
    150             float seconds = (((i * 8) / (format->bitsPerSample * format->numChannels)) * 1000.0) /
    151                     format->milliHz;
    152             short sampleLeft = sin(seconds * M_PI_2 * hzLeft) * 32767.0;
    153             short sampleRight = sin(seconds * M_PI_2 * hzRight) * 32767.0;
    154             if (2 == format->numChannels) {
    155                 if (8 == format->bitsPerSample) {
    156                     buffer[i++] = (sampleLeft + 32768) >> 8;
    157                     buffer[i++] = (sampleRight + 32768) >> 8;
    158                 } else {
    159                     assert(16 == format->bitsPerSample);
    160                     buffer[i++] = sampleLeft & 0xFF;
    161                     buffer[i++] = sampleLeft >> 8;
    162                     buffer[i++] = sampleRight & 0xFF;
    163                     buffer[i++] = sampleRight >> 8;
    164                 }
    165             } else {
    166                 assert(1 == format->numChannels);
    167                 // cast to int and divide by 2 are needed to prevent overflow
    168                 short sampleMono = ((int) sampleLeft + (int) sampleRight) / 2;
    169                 if (8 == format->bitsPerSample) {
    170                     buffer[i++] = (sampleMono + 32768) >> 8;
    171                 } else {
    172                     assert(16 == format->bitsPerSample);
    173                     buffer[i++] = sampleMono & 0xFF;
    174                     buffer[i++] = sampleMono >> 8;
    175                 }
    176             }
    177             if (seconds >= 1.0f)
    178                 break;
    179         }
    180 
    181         // get the buffer queue interface and enqueue a buffer
    182         SLBufferQueueItf playerBufferQueue;
    183         result = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE,
    184                 &playerBufferQueue);
    185         assert(SL_RESULT_SUCCESS == result);
    186         result = (*playerBufferQueue)->Enqueue(playerBufferQueue, buffer, i);
    187         assert(SL_RESULT_SUCCESS == result);
    188 
    189         // get the play interface
    190         SLPlayItf playerPlay;
    191         result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay);
    192         assert(SL_RESULT_SUCCESS == result);
    193 
    194         // set the player's state to playing
    195         result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
    196         assert(SL_RESULT_SUCCESS == result);
    197 
    198         // wait for the buffer to be played
    199         for (;;) {
    200             SLBufferQueueState state;
    201             result = (*playerBufferQueue)->GetState(playerBufferQueue, &state);
    202             assert(SL_RESULT_SUCCESS == result);
    203             if (state.count == 0)
    204                 break;
    205             usleep(20000);
    206         }
    207 
    208         // destroy audio player
    209         (*playerObject)->Destroy(playerObject);
    210 
    211         //usleep(1000000);
    212         hzLeft *= 1.05946309; // twelfth root of 2
    213         hzRight /= 1.05946309;
    214     }
    215 
    216     // destroy output mix
    217     (*outputMixObject)->Destroy(outputMixObject);
    218 
    219     // destroy engine
    220     (*engineObject)->Destroy(engineObject);
    221 
    222     return EXIT_SUCCESS;
    223 }
    224