AudioInputOpenSLES.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. //
  2. // libtgvoip is free and unencumbered public domain software.
  3. // For more information, see http://unlicense.org or the UNLICENSE file
  4. // you should have received with this source code distribution.
  5. //
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <assert.h>
  9. #include "AudioInputOpenSLES.h"
  10. #include "../../logging.h"
  11. #include "OpenSLEngineWrapper.h"
  12. #define CHECK_SL_ERROR(res, msg) if(res!=SL_RESULT_SUCCESS){ LOGE(msg); return; }
  13. #define BUFFER_SIZE 960 // 20 ms
  14. using namespace tgvoip;
  15. using namespace tgvoip::audio;
  16. unsigned int AudioInputOpenSLES::nativeBufferSize;
  17. AudioInputOpenSLES::AudioInputOpenSLES(){
  18. slEngine=OpenSLEngineWrapper::CreateEngine();
  19. LOGI("Native buffer size is %u samples", nativeBufferSize);
  20. if(nativeBufferSize<BUFFER_SIZE && BUFFER_SIZE % nativeBufferSize!=0){
  21. LOGE("20ms is not divisible by native buffer size!!");
  22. }else if(nativeBufferSize>BUFFER_SIZE && nativeBufferSize%BUFFER_SIZE!=0){
  23. LOGE("native buffer size is not multiple of 20ms!!");
  24. nativeBufferSize+=nativeBufferSize%BUFFER_SIZE;
  25. }
  26. if(nativeBufferSize==BUFFER_SIZE)
  27. nativeBufferSize*=2;
  28. LOGI("Adjusted native buffer size is %u", nativeBufferSize);
  29. buffer=(int16_t*)calloc(BUFFER_SIZE, sizeof(int16_t));
  30. nativeBuffer=(int16_t*)calloc((size_t) nativeBufferSize, sizeof(int16_t));
  31. slRecorderObj=NULL;
  32. }
  33. AudioInputOpenSLES::~AudioInputOpenSLES(){
  34. //Stop();
  35. (*slBufferQueue)->Clear(slBufferQueue);
  36. (*slRecorderObj)->Destroy(slRecorderObj);
  37. slRecorderObj=NULL;
  38. slRecorder=NULL;
  39. slBufferQueue=NULL;
  40. slEngine=NULL;
  41. OpenSLEngineWrapper::DestroyEngine();
  42. free(buffer);
  43. buffer=NULL;
  44. free(nativeBuffer);
  45. nativeBuffer=NULL;
  46. }
  47. void AudioInputOpenSLES::BufferCallback(SLAndroidSimpleBufferQueueItf bq, void *context){
  48. ((AudioInputOpenSLES*)context)->HandleSLCallback();
  49. }
  50. void AudioInputOpenSLES::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
  51. assert(slRecorderObj==NULL);
  52. SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE,
  53. SL_IODEVICE_AUDIOINPUT,
  54. SL_DEFAULTDEVICEID_AUDIOINPUT, NULL};
  55. SLDataSource audioSrc = {&loc_dev, NULL};
  56. SLDataLocator_AndroidSimpleBufferQueue loc_bq =
  57. {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 1};
  58. SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, channels, sampleRate*1000,
  59. SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
  60. channels==2 ? (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT) : SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN};
  61. SLDataSink audioSnk = {&loc_bq, &format_pcm};
  62. const SLInterfaceID id[2] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION};
  63. const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
  64. SLresult result = (*slEngine)->CreateAudioRecorder(slEngine, &slRecorderObj, &audioSrc, &audioSnk, 2, id, req);
  65. CHECK_SL_ERROR(result, "Error creating recorder");
  66. SLAndroidConfigurationItf recorderConfig;
  67. result = (*slRecorderObj)->GetInterface(slRecorderObj, SL_IID_ANDROIDCONFIGURATION, &recorderConfig);
  68. SLint32 streamType = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION;
  69. result = (*recorderConfig)->SetConfiguration(recorderConfig, SL_ANDROID_KEY_RECORDING_PRESET, &streamType, sizeof(SLint32));
  70. result=(*slRecorderObj)->Realize(slRecorderObj, SL_BOOLEAN_FALSE);
  71. CHECK_SL_ERROR(result, "Error realizing recorder");
  72. result=(*slRecorderObj)->GetInterface(slRecorderObj, SL_IID_RECORD, &slRecorder);
  73. CHECK_SL_ERROR(result, "Error getting recorder interface");
  74. result=(*slRecorderObj)->GetInterface(slRecorderObj, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &slBufferQueue);
  75. CHECK_SL_ERROR(result, "Error getting buffer queue");
  76. result=(*slBufferQueue)->RegisterCallback(slBufferQueue, AudioInputOpenSLES::BufferCallback, this);
  77. CHECK_SL_ERROR(result, "Error setting buffer queue callback");
  78. (*slBufferQueue)->Enqueue(slBufferQueue, nativeBuffer, nativeBufferSize*sizeof(int16_t));
  79. }
  80. void AudioInputOpenSLES::Start(){
  81. SLresult result=(*slRecorder)->SetRecordState(slRecorder, SL_RECORDSTATE_RECORDING);
  82. CHECK_SL_ERROR(result, "Error starting record");
  83. }
  84. void AudioInputOpenSLES::Stop(){
  85. SLresult result=(*slRecorder)->SetRecordState(slRecorder, SL_RECORDSTATE_STOPPED);
  86. CHECK_SL_ERROR(result, "Error stopping record");
  87. }
  88. void AudioInputOpenSLES::HandleSLCallback(){
  89. //SLmillisecond pMsec = 0;
  90. //(*slRecorder)->GetPosition(slRecorder, &pMsec);
  91. //LOGI("Callback! pos=%lu", pMsec);
  92. //InvokeCallback((unsigned char*)buffer, BUFFER_SIZE*sizeof(int16_t));
  93. //fwrite(nativeBuffer, 1, nativeBufferSize*2, test);
  94. if(nativeBufferSize==BUFFER_SIZE){
  95. //LOGV("nativeBufferSize==BUFFER_SIZE");
  96. InvokeCallback((unsigned char *) nativeBuffer, BUFFER_SIZE*sizeof(int16_t));
  97. }else if(nativeBufferSize<BUFFER_SIZE){
  98. //LOGV("nativeBufferSize<BUFFER_SIZE");
  99. if(positionInBuffer>=BUFFER_SIZE){
  100. InvokeCallback((unsigned char *) buffer, BUFFER_SIZE*sizeof(int16_t));
  101. positionInBuffer=0;
  102. }
  103. memcpy(((unsigned char*)buffer)+positionInBuffer*2, nativeBuffer, (size_t)nativeBufferSize*2);
  104. positionInBuffer+=nativeBufferSize;
  105. }else if(nativeBufferSize>BUFFER_SIZE){
  106. //LOGV("nativeBufferSize>BUFFER_SIZE");
  107. for(unsigned int offset=0;offset<nativeBufferSize;offset+=BUFFER_SIZE){
  108. InvokeCallback(((unsigned char *) nativeBuffer)+offset*2, BUFFER_SIZE*sizeof(int16_t));
  109. }
  110. }
  111. (*slBufferQueue)->Enqueue(slBufferQueue, nativeBuffer, nativeBufferSize*sizeof(int16_t));
  112. }