Advertisement
malinika

Android Open SL realization

Jun 20th, 2015
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.82 KB | None | 0 0
  1. void cb(SLAndroidSimpleBufferQueueItf bq, void * context) {
  2.     OSLBufferPlayer * player = (OSLBufferPlayer *)context;
  3.     if(!playerStarted)
  4.     {
  5.         return;
  6.     }
  7.     int bufferSize = player->getContext()->getBufferSize();
  8.     short * bufferToPlay = secondBuffer ?
  9.                                 player->currentPitch==0 ?
  10.                                     player->buffer2 :
  11.                                     player->bufferPitch2
  12.                                 :
  13.                                 player->currentPitch==0 ?
  14.                                     player->buffer1 :
  15.                                     player->bufferPitch1
  16.                                 ;
  17.  
  18.     (*player->bufferQueue)->Enqueue(player->bufferQueue, bufferToPlay , player->currentBufferSize);
  19.  
  20.     // Define pitch koefficient
  21.     // It's experimental value
  22.     int pitch = player->currentPitch;
  23.     float koefPitch = 0.05629;
  24.     if (pitch > 4) {
  25.         koefPitch = 0.05029;
  26.     }
  27.     if (pitch < 0) {
  28.         koefPitch = 0.05729;
  29.     }
  30.  
  31.     short * buffer = secondBuffer ? player->buffer1 : player->buffer2;
  32.     short * bufferPitch = secondBuffer ? player->bufferPitch1 : player->bufferPitch2;
  33.     float sizeToRead = pitch==0 ? (player->getContext()->getBufferSize()) : (player->getContext()->getBufferSize()/(1-koefPitch * pitch));
  34.     for(int i = 0;i<sizeToRead;i++) {
  35.         buffer[i] = 0;
  36.     }
  37.     for(int i = 0;i<MAX_SOUND_COUNT;i++) {
  38.         if(player->sound[i]!=0 && player->sound[i]->isPlaying()) {
  39.             short * buff = player->sound[i]->getBufferWithOffset(sizeToRead/2);
  40.             for(int j = 0;j<sizeToRead;j++) {
  41.                 float mult = player->sound[i]->getMultiplier();
  42.                 short res = buff[j]*mult;
  43.                 buffer[j] = mixSamples(buffer[j], res);
  44.             }
  45.         }
  46.     }
  47.  
  48.     // Define how many frames must be deleted/added to sample
  49.     float framesToAdjustCount = (float) sizeToRead * koefPitch * abs(pitch);
  50.  
  51.     // Calculate new frames count
  52.     float origFrameCount = sizeToRead;
  53.     float newFramesCount = origFrameCount;
  54.     newFramesCount += (pitch > 0) ? -framesToAdjustCount : framesToAdjustCount;
  55.  
  56.     // Update frames
  57.     if (pitch == 0) {
  58.         // Use original frames for null pitch
  59.  
  60.     } else {
  61.         // Define which frame must be added/deleted
  62.         // float type is used for more accuracy
  63.         // int is not recommended, it gives wrong behaviour, too much roundation
  64.         float frameToAdjustNumber = (float) sizeToRead / (float)framesToAdjustCount;
  65.  
  66.         int k = 0;
  67.         int currentIteration = 0;
  68.         bool adjustableStep = false;
  69.  
  70.         for (int i = 0; i < origFrameCount; i++) {
  71.             if (k < newFramesCount) {
  72.  
  73.                 adjustableStep = false;
  74.  
  75.                 // Check if current frame is 'adjustable' frame
  76.                 // Checking is required since frameToAdjustNumber is float value, not integer.
  77.                 // Float value gives more accuracy
  78.                 float tmp1 = (float) i / frameToAdjustNumber;
  79.                 if (roundf(tmp1) - tmp1 >= 0 && currentIteration != roundf(tmp1)) {
  80.                     currentIteration = roundf(tmp1);
  81.                     adjustableStep = true;
  82.                 }
  83.  
  84.                 if (pitch > 0) {
  85.                     // remove one frame
  86.                     if (adjustableStep) {
  87.                         continue;
  88.                     }
  89.                     bufferPitch[k] = buffer[i];
  90.                 } else {
  91.                     // add new frame
  92.                     bufferPitch[k] = buffer[i];
  93.                     if (adjustableStep) {
  94.                         if (i < origFrameCount - 2) {
  95.                             k += 1;
  96.                             bufferPitch[k] = ((int)buffer[i] + (int)buffer[i+2])/2;
  97.                         }
  98.                     }
  99.                 }
  100.                 k += 1;
  101.             }
  102.         }
  103.     }
  104.  
  105.     if(player->recording) {
  106.          short * bufferToWrite = secondBuffer ?
  107.                                 player->currentPitch==0 ?
  108.                                     player->buffer1 :
  109.                                     player->bufferPitch1
  110.                                 :
  111.                                 player->currentPitch==0 ?
  112.                                     player->buffer2 :
  113.                                     player->bufferPitch2
  114.                                 ;
  115.                                      for(int i = 0;i<player->getContext()->getBufferSize();i++) {
  116.                                         player->bufferRecord[i] = bufferToWrite[i];
  117.                                 }
  118.         write(player->recordFileFD, player->bufferRecord, player->getContext()->getBufferSize());
  119.     }
  120.     secondBuffer = !secondBuffer;
  121. }
  122.  
  123. void OSLBufferPlayer::setCurrentPitch(int pitch) {
  124.     currentPitch = pitch;
  125. }
  126.  
  127. void OSLBufferPlayer::init(){
  128.     SLresult result;
  129.  
  130.     SLDataLocator_AndroidSimpleBufferQueue locatorBufferQueue;
  131.     locatorBufferQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
  132.     locatorBufferQueue.numBuffers = 16;
  133.  
  134.     SLDataFormat_PCM formatPCM;
  135.     formatPCM.formatType = SL_DATAFORMAT_PCM;
  136.     formatPCM.numChannels = 2;
  137.     int sampleRate = context->getSampleRate()==48000 ? SL_SAMPLINGRATE_48 : SL_SAMPLINGRATE_44_1;
  138.     formatPCM.samplesPerSec = sampleRate;
  139.     formatPCM.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16 ;
  140.     formatPCM.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
  141.     formatPCM.channelMask = SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT ;
  142.     formatPCM.endianness = SL_BYTEORDER_LITTLEENDIAN;
  143.  
  144.     audioSrc.pLocator = &locatorBufferQueue;
  145.     audioSrc.pFormat = &formatPCM;
  146.  
  147.     locatorOutMix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
  148.     locatorOutMix.outputMix =  context->getOutputMixObject();
  149.  
  150.     audioSnk.pLocator = &locatorOutMix;
  151.     audioSnk.pFormat = NULL;
  152.  
  153.      // create audio player
  154.     const SLInterfaceID ids[2] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE,SL_IID_VOLUME};
  155.  
  156.     const SLboolean req[2] = {SL_BOOLEAN_TRUE,SL_BOOLEAN_TRUE};
  157.  
  158.     result = (*context->getEngine())->CreateAudioPlayer(context->getEngine(),
  159.             &playerObj, &audioSrc, &audioSnk,2, ids, req);
  160.  
  161.     assert(SL_RESULT_SUCCESS == result);
  162.  
  163.     result = (*playerObj)->Realize(playerObj, SL_BOOLEAN_FALSE );
  164.     assert(SL_RESULT_SUCCESS == result);
  165.     if (result != SL_RESULT_SUCCESS ) {
  166.         playerObj = NULL;
  167.     }
  168.  
  169.  
  170.     result = (*playerObj)->GetInterface(playerObj, SL_IID_PLAY, &player);
  171.     assert(SL_RESULT_SUCCESS == result);
  172.  
  173.     result = (*playerObj)->GetInterface(playerObj, SL_IID_VOLUME, &fdPlayerVolume);
  174.     assert(SL_RESULT_SUCCESS == result);
  175.  
  176.  
  177.     result = (*playerObj)->GetInterface(playerObj,       SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bufferQueue);
  178.     assert(SL_RESULT_SUCCESS == result);
  179.  
  180.     result = (*bufferQueue)->RegisterCallback(bufferQueue, cb, (void *) this);
  181.  
  182.     result = (*player)->SetCallbackEventsMask(player, SL_PLAYEVENT_HEADATEND);
  183.  
  184.     //Initialize buffers
  185.     //allocate current buffer size with minumum pitch available (-5)
  186.     currentPitch =0;
  187.     float koefPitch = 0.05029f;
  188.     currentBufferSize = getContext()->getBufferSize();
  189.  
  190.     // Calculate new frames count
  191.     int origFrameCount = currentBufferSize;
  192.     int newFramesCount = origFrameCount;
  193.     newFramesCount = 2+getContext()->getBufferSize()/(1-koefPitch * 10); //max frames count
  194.  
  195.     buffer2 = (short*)malloc(newFramesCount*sizeof(short));
  196.     buffer1 = (short*)malloc(newFramesCount*sizeof(short));
  197.  
  198.     bufferPitch2 = (short*)malloc(newFramesCount*sizeof(short));
  199.     bufferPitch1 = (short*)malloc(newFramesCount*sizeof(short));
  200.  
  201.     bufferRecord = (short*)malloc(newFramesCount*sizeof(short));
  202.     for(int i = 0;i<newFramesCount;i++) {
  203.         buffer2[i] = 0;
  204.         buffer1[i] = 0;
  205.         bufferRecord[i] = 0;
  206.     }
  207.  
  208.     for(int i = 0;i<newFramesCount;i++) {
  209.         bufferPitch2[i] = 0;
  210.         bufferPitch1[i] = 0;
  211.     }
  212.  
  213.     recording = false;
  214.     currentEffect = OSLContext::NONE;
  215. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement