android_audio.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #ifdef IRON_A2
  2. #include <iron_audio.h>
  3. #include <SLES/OpenSLES.h>
  4. #include <SLES/OpenSLES_Android.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. static iron_a2_buffer_t a2_buffer;
  8. static SLObjectItf engineObject;
  9. static SLEngineItf engineEngine;
  10. static SLObjectItf outputMixObject;
  11. static SLObjectItf bqPlayerObject;
  12. static SLPlayItf bqPlayerPlay = NULL;
  13. static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
  14. #define AUDIO_BUFFER_SIZE 1 * 1024
  15. static int16_t tempBuffer[AUDIO_BUFFER_SIZE];
  16. static void copySample(void *buffer) {
  17. float left_value = *(float *)&a2_buffer.channels[0][a2_buffer.read_location];
  18. float right_value = *(float *)&a2_buffer.channels[1][a2_buffer.read_location];
  19. a2_buffer.read_location += 1;
  20. if (a2_buffer.read_location >= a2_buffer.data_size) {
  21. a2_buffer.read_location = 0;
  22. }
  23. ((int16_t *)buffer)[0] = (int16_t)(left_value * 32767);
  24. ((int16_t *)buffer)[1] = (int16_t)(right_value * 32767);
  25. }
  26. static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf caller, void *context) {
  27. if (iron_a2_internal_callback(&a2_buffer, AUDIO_BUFFER_SIZE / 2)) {
  28. for (int i = 0; i < AUDIO_BUFFER_SIZE; i += 2) {
  29. copySample(&tempBuffer[i]);
  30. }
  31. }
  32. else {
  33. memset(tempBuffer, 0, sizeof(tempBuffer));
  34. }
  35. SLresult result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, tempBuffer, AUDIO_BUFFER_SIZE * 2);
  36. }
  37. static bool initialized = false;
  38. void iron_a2_init() {
  39. if (initialized) {
  40. return;
  41. }
  42. iron_a2_internal_init();
  43. initialized = true;
  44. a2_buffer.read_location = 0;
  45. a2_buffer.write_location = 0;
  46. a2_buffer.data_size = 128 * 1024;
  47. a2_buffer.channel_count = 2;
  48. a2_buffer.channels[0] = (float *)malloc(a2_buffer.data_size * sizeof(float));
  49. a2_buffer.channels[1] = (float *)malloc(a2_buffer.data_size * sizeof(float));
  50. SLresult result;
  51. result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
  52. result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
  53. result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
  54. const SLInterfaceID ids[] = {SL_IID_VOLUME};
  55. const SLboolean req[] = {SL_BOOLEAN_FALSE};
  56. result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req);
  57. result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
  58. SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
  59. SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 2,
  60. SL_SAMPLINGRATE_44_1, SL_PCMSAMPLEFORMAT_FIXED_16,
  61. SL_PCMSAMPLEFORMAT_FIXED_16, SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
  62. SL_BYTEORDER_LITTLEENDIAN};
  63. SLDataSource audioSrc = {&loc_bufq, &format_pcm};
  64. SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
  65. SLDataSink audioSnk = {&loc_outmix, NULL};
  66. const SLInterfaceID ids1[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
  67. const SLboolean req1[] = {SL_BOOLEAN_TRUE};
  68. result = (*engineEngine)->CreateAudioPlayer(engineEngine, &(bqPlayerObject), &audioSrc, &audioSnk, 1, ids1, req1);
  69. result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
  70. result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &(bqPlayerPlay));
  71. result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &(bqPlayerBufferQueue));
  72. result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
  73. result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
  74. memset(tempBuffer, 0, sizeof(tempBuffer));
  75. result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, tempBuffer, AUDIO_BUFFER_SIZE * 2);
  76. }
  77. void pauseAudio() {
  78. if (bqPlayerPlay == NULL) {
  79. return;
  80. }
  81. SLresult result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PAUSED);
  82. }
  83. void resumeAudio() {
  84. if (bqPlayerPlay == NULL) {
  85. return;
  86. }
  87. SLresult result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
  88. }
  89. void iron_a2_update() {}
  90. void iron_a2_shutdown() {
  91. if (bqPlayerObject != NULL) {
  92. (*bqPlayerObject)->Destroy(bqPlayerObject);
  93. bqPlayerObject = NULL;
  94. bqPlayerPlay = NULL;
  95. bqPlayerBufferQueue = NULL;
  96. }
  97. if (outputMixObject != NULL) {
  98. (*outputMixObject)->Destroy(outputMixObject);
  99. outputMixObject = NULL;
  100. }
  101. if (engineObject != NULL) {
  102. (*engineObject)->Destroy(engineObject);
  103. engineObject = NULL;
  104. engineEngine = NULL;
  105. }
  106. }
  107. uint32_t iron_a2_samples_per_second(void) {
  108. return 44100;
  109. }
  110. #endif