/* API: Init factory */ static pj_status_t opensl_init(pjmedia_aud_dev_factory *f) { struct opensl_aud_factory *pa = (struct opensl_aud_factory*)f; SLresult result; /* Create engine */ result = slCreateEngine(&pa->engineObject, 0, NULL, 0, NULL, NULL); if (result != SL_RESULT_SUCCESS) { PJ_LOG(3, (THIS_FILE, "Cannot create engine %d ", result)); return opensl_to_pj_error(result); } /* Realize the engine */ result = (*pa->engineObject)->Realize(pa->engineObject, SL_BOOLEAN_FALSE); if (result != SL_RESULT_SUCCESS) { PJ_LOG(3, (THIS_FILE, "Cannot realize engine")); opensl_destroy(f); return opensl_to_pj_error(result); } /* Get the engine interface, which is needed in order to create * other objects. */ result = (*pa->engineObject)->GetInterface(pa->engineObject, SL_IID_ENGINE, &pa->engineEngine); if (result != SL_RESULT_SUCCESS) { PJ_LOG(3, (THIS_FILE, "Cannot get engine interface")); opensl_destroy(f); return opensl_to_pj_error(result); } /* Create output mix */ result = (*pa->engineEngine)->CreateOutputMix(pa->engineEngine, &pa->outputMixObject, 0, NULL, NULL); if (result != SL_RESULT_SUCCESS) { PJ_LOG(3, (THIS_FILE, "Cannot create output mix")); opensl_destroy(f); return opensl_to_pj_error(result); } /* Realize the output mix */ result = (*pa->outputMixObject)->Realize(pa->outputMixObject, SL_BOOLEAN_FALSE); if (result != SL_RESULT_SUCCESS) { PJ_LOG(3, (THIS_FILE, "Cannot realize output mix")); opensl_destroy(f); return opensl_to_pj_error(result); } PJ_LOG(4,(THIS_FILE, "OpenSL sound library initialized")); return PJ_SUCCESS; }
/* API: start stream. */ static pj_status_t strm_start(pjmedia_aud_stream *s) { struct opensl_aud_stream *stream = (struct opensl_aud_stream*)s; int i; SLresult result = SL_RESULT_SUCCESS; PJ_LOG(4, (THIS_FILE, "Starting %s stream..", stream->name.ptr)); stream->quit_flag = 0; if (stream->recordBufQ && stream->recordRecord) { /* Enqueue an empty buffer to be filled by the recorder * (for streaming recording, we need to enqueue at least 2 empty * buffers to start things off) */ for (i = 0; i < NUM_BUFFERS; i++) { result = (*stream->recordBufQ)->Enqueue(stream->recordBufQ, stream->recordBuffer[i], stream->recordBufferSize); /* The most likely other result is SL_RESULT_BUFFER_INSUFFICIENT, * which for this code would indicate a programming error */ pj_assert(result == SL_RESULT_SUCCESS); } result = (*stream->recordRecord)->SetRecordState( stream->recordRecord, SL_RECORDSTATE_RECORDING); if (result != SL_RESULT_SUCCESS) { PJ_LOG(3, (THIS_FILE, "Cannot start recorder")); goto on_error; } } if (stream->playerPlay && stream->playerBufQ) { /* Set the player's state to playing */ result = (*stream->playerPlay)->SetPlayState(stream->playerPlay, SL_PLAYSTATE_PLAYING); if (result != SL_RESULT_SUCCESS) { PJ_LOG(3, (THIS_FILE, "Cannot start player")); goto on_error; } for (i = 0; i < NUM_BUFFERS; i++) { pj_bzero(stream->playerBuffer[i], stream->playerBufferSize/100); result = (*stream->playerBufQ)->Enqueue(stream->playerBufQ, stream->playerBuffer[i], stream->playerBufferSize/100); pj_assert(result == SL_RESULT_SUCCESS); } } PJ_LOG(4, (THIS_FILE, "%s stream started", stream->name.ptr)); return PJ_SUCCESS; on_error: if (result != SL_RESULT_SUCCESS) strm_stop(&stream->base); return opensl_to_pj_error(result); }