/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Test various combinations of data sources and sinks #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <SLES/OpenSLES.h> int main(int argc __unused, char **argv __unused) { SLresult result; SLObjectItf engineObject; // create engine result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); assert(SL_RESULT_SUCCESS == result); SLEngineItf engineEngine; result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); assert(SL_RESULT_SUCCESS == result); result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); assert(SL_RESULT_SUCCESS == result); // configure a typical audio source of 44.1 kHz stereo 16-bit little endian SLDataLocator_BufferQueue loc_bufq; loc_bufq.locatorType = SL_DATALOCATOR_BUFFERQUEUE; loc_bufq.numBuffers = 1; SLDataFormat_PCM format_pcm; format_pcm.formatType = SL_DATAFORMAT_PCM; format_pcm.numChannels = 2; format_pcm.samplesPerSec = SL_SAMPLINGRATE_44_1; format_pcm.bitsPerSample = 16; format_pcm.containerSize = 16; format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; SLDataSource audioSrc; audioSrc.pLocator = &loc_bufq; audioSrc.pFormat = &format_pcm; // configure audio sink SLDataLocator_OutputMix loc_outmix; loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; loc_outmix.outputMix = NULL; SLDataSink audioSnk; audioSnk.pLocator = &loc_outmix; audioSnk.pFormat = NULL; // create audio player using a NULL output mix SLInterfaceID ids[1] = {SL_IID_BUFFERQUEUE}; SLboolean req[1] = {SL_BOOLEAN_TRUE}; SLObjectItf playerObject; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_PARAMETER_INVALID == result); assert(NULL == playerObject); // create audio player using an engine as the output mix loc_outmix.outputMix = engineObject; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_PARAMETER_INVALID == result); assert(NULL == playerObject); // create output mix but don't realize it yet SLObjectItf outputMixObject; result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL); assert(SL_RESULT_SUCCESS == result); // create audio player using the unrealized output mix loc_outmix.outputMix = outputMixObject; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_PRECONDITIONS_VIOLATED == result); assert(NULL == playerObject); // now realize the output mix result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); assert(SL_RESULT_SUCCESS == result); // create audio player using the realized output mix // and a bogus data format for the sink (ignored per spec) audioSnk.pFormat = (void *) 0xDEADBEEF; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_SUCCESS == result); assert(NULL != playerObject); audioSnk.pFormat = NULL; // destroy player (*playerObject)->Destroy(playerObject); // now try to create audio player using various unusual parameters // number of channels format_pcm.numChannels = 0; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_PARAMETER_INVALID == result); assert(NULL == playerObject); format_pcm.numChannels = 3; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_CONTENT_UNSUPPORTED == result); assert(NULL == playerObject); format_pcm.numChannels = 2; // sample rate format_pcm.samplesPerSec = 0; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_PARAMETER_INVALID == result); assert(NULL == playerObject); format_pcm.samplesPerSec = 1000; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_CONTENT_UNSUPPORTED == result); assert(NULL == playerObject); format_pcm.samplesPerSec = SL_SAMPLINGRATE_44_1; // bits per sample format_pcm.bitsPerSample = 17; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_PARAMETER_INVALID == result); assert(NULL == playerObject); format_pcm.bitsPerSample = 24; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_CONTENT_UNSUPPORTED == result); assert(NULL == playerObject); format_pcm.bitsPerSample = 16; // container size format_pcm.containerSize = 8; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_PARAMETER_INVALID == result); assert(NULL == playerObject); format_pcm.containerSize = 32; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_CONTENT_UNSUPPORTED == result); assert(NULL == playerObject); format_pcm.containerSize = 16; // channel mask format_pcm.channelMask = 0; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_SUCCESS == result); assert(NULL != playerObject); (*playerObject)->Destroy(playerObject); format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_PARAMETER_INVALID == result); assert(NULL == playerObject); format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_PARAMETER_INVALID == result); assert(NULL == playerObject); format_pcm.numChannels = 1; format_pcm.channelMask = 0; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_SUCCESS == result); assert(NULL != playerObject); (*playerObject)->Destroy(playerObject); format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_PARAMETER_INVALID == result); assert(NULL == playerObject); format_pcm.numChannels = 2; // endianness format_pcm.endianness = SL_BYTEORDER_BIGENDIAN; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); #ifdef ANDROID // known bug on SDL assert(SL_RESULT_CONTENT_UNSUPPORTED == result); assert(NULL == playerObject); #else if (SL_RESULT_CONTENT_UNSUPPORTED != result) { printf("ERROR: expected SL_RESULT_CONTENT_UNSUPPORTED\n"); if (NULL != playerObject) (*playerObject)->Destroy(playerObject); } #endif format_pcm.endianness = 0; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, &audioSnk, 1, ids, req); assert(SL_RESULT_PARAMETER_INVALID == result); assert(NULL == playerObject); format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; // destroy output mix (*outputMixObject)->Destroy(outputMixObject); // destroy engine (*engineObject)->Destroy(engineObject); return EXIT_SUCCESS; }