static int aout_thread_n(JNIEnv *env, SDL_Aout *aout) { SDL_Aout_Opaque *opaque = aout->opaque; SDL_Android_AudioTrack *atrack = opaque->atrack; SDL_AudioCallback audio_cblk = opaque->spec.callback; void *userdata = opaque->spec.userdata; uint8_t *buffer = opaque->buffer; int copy_size = opaque->buffer_size; assert(atrack); assert(buffer); SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); if (!opaque->abort_request && !opaque->pause_on) SDL_Android_AudioTrack_play(env, atrack); while (!opaque->abort_request) { SDL_LockMutex(opaque->wakeup_mutex); if (!opaque->abort_request && opaque->pause_on) { SDL_Android_AudioTrack_pause(env, atrack); while (!opaque->abort_request && opaque->pause_on) { SDL_CondWaitTimeout(opaque->wakeup_cond, opaque->wakeup_mutex, 1000); } if (!opaque->abort_request && !opaque->pause_on) SDL_Android_AudioTrack_play(env, atrack); } if (opaque->need_flush) { opaque->need_flush = 0; SDL_Android_AudioTrack_flush(env, atrack); } if (opaque->need_set_volume) { opaque->need_set_volume = 0; SDL_Android_AudioTrack_set_volume(env, atrack, opaque->left_volume, opaque->right_volume); } SDL_UnlockMutex(opaque->wakeup_mutex); audio_cblk(userdata, buffer, copy_size); if (opaque->need_flush) { SDL_Android_AudioTrack_flush(env, atrack); opaque->need_flush = false; } if (opaque->need_flush) { opaque->need_flush = 0; SDL_Android_AudioTrack_flush(env, atrack); } else { int written = SDL_Android_AudioTrack_write_byte(env, atrack, buffer, copy_size); if (written != copy_size) { ALOGW("AudioTrack: not all data copied %d/%d", (int)written, (int)copy_size); } } // TODO: 1 if callback return -1 or 0 } SDL_Android_AudioTrack_free(env, atrack); return 0; }
int aout_thread_n(JNIEnv *env, SDL_Aout *aout) { SDL_Aout_Opaque *opaque = aout->opaque; SDL_AndroidAudioTrack *atrack = opaque->atrack; SDL_AudioCallback audio_cblk = opaque->spec.callback; void *userdata = opaque->spec.userdata; uint8_t *buffer = opaque->buffer; int copy_size = 256; assert(atrack); assert(buffer); SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); if (!opaque->abort_request && !opaque->pause_on) sdl_audiotrack_play(env, atrack); while (!opaque->abort_request) { SDL_LockMutex(opaque->wakeup_mutex); if (!opaque->abort_request && opaque->pause_on) { sdl_audiotrack_pause(env, atrack); while (!opaque->abort_request && opaque->pause_on) { SDL_CondWaitTimeout(opaque->wakeup_cond, opaque->wakeup_mutex, 1000); } if (!opaque->abort_request && !opaque->pause_on) sdl_audiotrack_play(env, atrack); } if (opaque->need_flush) { opaque->need_flush = 0; sdl_audiotrack_flush(env, atrack); } SDL_UnlockMutex(opaque->wakeup_mutex); audio_cblk(userdata, buffer, copy_size); if (opaque->need_flush) { sdl_audiotrack_flush(env, atrack); opaque->need_flush = false; } if (opaque->need_flush) { opaque->need_flush = 0; sdl_audiotrack_flush(env, atrack); } else { sdl_audiotrack_write_byte(env, atrack, buffer, copy_size); } // TODO: 1 if callback return -1 or 0 } sdl_audiotrack_free(env, atrack); return 0; }
static int aout_thread_n(SDL_Aout *aout) { SDL_Aout_Opaque *opaque = aout->opaque; SLPlayItf slPlayItf = opaque->slPlayItf; SLAndroidSimpleBufferQueueItf slBufferQueueItf = opaque->slBufferQueueItf; SLVolumeItf slVolumeItf = opaque->slVolumeItf; SDL_AudioCallback audio_cblk = opaque->spec.callback; void *userdata = opaque->spec.userdata; uint8_t *next_buffer = NULL; int next_buffer_index = 0; size_t bytes_per_buffer = opaque->bytes_per_buffer; SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); if (!opaque->abort_request && !opaque->pause_on) (*slPlayItf)->SetPlayState(slPlayItf, SL_PLAYSTATE_PLAYING); while (!opaque->abort_request) { SLAndroidSimpleBufferQueueState slState = {0}; SLresult slRet = (*slBufferQueueItf)->GetState(slBufferQueueItf, &slState); if (slRet != SL_RESULT_SUCCESS) { ALOGE("%s: slBufferQueueItf->GetState() failed\n", __func__); SDL_UnlockMutex(opaque->wakeup_mutex); } SDL_LockMutex(opaque->wakeup_mutex); if (!opaque->abort_request && (opaque->pause_on || slState.count >= OPENSLES_BUFFERS)) { while (!opaque->abort_request && (opaque->pause_on || slState.count >= OPENSLES_BUFFERS)) { if (!opaque->pause_on) { (*slPlayItf)->SetPlayState(slPlayItf, SL_PLAYSTATE_PLAYING); } SDL_CondWaitTimeout(opaque->wakeup_cond, opaque->wakeup_mutex, 1000); SLresult slRet = (*slBufferQueueItf)->GetState(slBufferQueueItf, &slState); if (slRet != SL_RESULT_SUCCESS) { ALOGE("%s: slBufferQueueItf->GetState() failed\n", __func__); SDL_UnlockMutex(opaque->wakeup_mutex); } if (opaque->pause_on) (*slPlayItf)->SetPlayState(slPlayItf, SL_PLAYSTATE_PAUSED); } if (!opaque->abort_request && !opaque->pause_on) { (*slPlayItf)->SetPlayState(slPlayItf, SL_PLAYSTATE_PLAYING); } } if (opaque->need_flush) { opaque->need_flush = 0; (*slBufferQueueItf)->Clear(slBufferQueueItf); } #if 0 if (opaque->need_set_volume) { opaque->need_set_volume = 0; // FIXME: set volume here } #endif if (opaque->need_set_volume) { opaque->need_set_volume = 0; SLmillibel level = android_amplification_to_sles((opaque->left_volume + opaque->right_volume) / 2); ALOGI("slVolumeItf->SetVolumeLevel((%f, %f) -> %d)\n", opaque->left_volume, opaque->right_volume, (int)level); slRet = (*slVolumeItf)->SetVolumeLevel(slVolumeItf, level); if (slRet != SL_RESULT_SUCCESS) { ALOGE("slVolumeItf->SetVolumeLevel failed %d\n", (int)slRet); // just ignore error } } SDL_UnlockMutex(opaque->wakeup_mutex); next_buffer = opaque->buffer + next_buffer_index * bytes_per_buffer; next_buffer_index = (next_buffer_index + 1) % OPENSLES_BUFFERS; audio_cblk(userdata, next_buffer, bytes_per_buffer); if (opaque->need_flush) { (*slBufferQueueItf)->Clear(slBufferQueueItf); opaque->need_flush = false; } if (opaque->need_flush) { ALOGE("flush"); opaque->need_flush = 0; (*slBufferQueueItf)->Clear(slBufferQueueItf); } else { slRet = (*slBufferQueueItf)->Enqueue(slBufferQueueItf, next_buffer, bytes_per_buffer); if (slRet == SL_RESULT_SUCCESS) { // do nothing } else if (slRet == SL_RESULT_BUFFER_INSUFFICIENT) { // don't retry, just pass through ALOGE("SL_RESULT_BUFFER_INSUFFICIENT\n"); } else { ALOGE("slBufferQueueItf->Enqueue() = %d\n", (int)slRet); break; } } // TODO: 1 if callback return -1 or 0 } return 0; }