Beispiel #1
0
void AudioPlayer::rotateBufferThread(int offsetFrame)
{
    char* tmpBuffer = nullptr;
    AudioDecoder* decoder = AudioDecoderManager::createDecoder(_audioCache->_fileFullPath.c_str());
    do
    {
        BREAK_IF(decoder == nullptr || !decoder->open(_audioCache->_fileFullPath.c_str()));

        uint32_t framesRead = 0;
        const uint32_t framesToRead = _audioCache->_queBufferFrames;
        const uint32_t bufferSize = framesToRead * decoder->getBytesPerFrame();
        tmpBuffer = (char*)malloc(bufferSize);
        memset(tmpBuffer, 0, bufferSize);

        if (offsetFrame != 0) {
            decoder->seek(offsetFrame);
        }

        ALint sourceState;
        ALint bufferProcessed = 0;
        bool needToExitThread = false;

        while (!_isDestroyed) {
            alGetSourcei(_alSource, AL_SOURCE_STATE, &sourceState);
            if (sourceState == AL_PLAYING) {
                alGetSourcei(_alSource, AL_BUFFERS_PROCESSED, &bufferProcessed);
                while (bufferProcessed > 0) {
                    bufferProcessed--;
                    if (_timeDirty) {
                        _timeDirty = false;
                        offsetFrame = _currTime * decoder->getSampleRate();
                        decoder->seek(offsetFrame);
                    }
                    else {
                        _currTime += QUEUEBUFFER_TIME_STEP;
                        if (_currTime > _audioCache->_duration) {
                            if (_loop) {
                                _currTime = 0.0f;
                            } else {
                                _currTime = _audioCache->_duration;
                            }
                        }
                    }

                    framesRead = decoder->readFixedFrames(framesToRead, tmpBuffer);

                    if (framesRead == 0) {
                        if (_loop) {
                            decoder->seek(0);
                            framesRead = decoder->readFixedFrames(framesToRead, tmpBuffer);
                        } else {
                            needToExitThread = true;
                            break;
                        }
                    }

                    ALuint bid;
                    alSourceUnqueueBuffers(_alSource, 1, &bid);
                    alBufferData(bid, _audioCache->_format, tmpBuffer, framesRead * decoder->getBytesPerFrame(), decoder->getSampleRate());
                    alSourceQueueBuffers(_alSource, 1, &bid);
                }
            }

            std::unique_lock<std::mutex> lk(_sleepMutex);
            if (_isDestroyed || needToExitThread) {
                break;
            }

            _sleepCondition.wait_for(lk,std::chrono::milliseconds(75));
        }

    } while(false);

    ALOGV("Exit rotate buffer thread ...");
    if (decoder != nullptr)
    {
        decoder->close();
    }
    AudioDecoderManager::destroyDecoder(decoder);
    free(tmpBuffer);
    _isRotateThreadExited = true;
    ALOGV("%s exited.\n", __FUNCTION__);
}
Beispiel #2
0
bool sbsms_convert(const char *filenameIn, const char *filenameOut, bool bAnalyze, bool bSynthesize, progress_cb progressCB, void *data, float rate0, float rate1, float pitch0, float pitch1, float volume)
{  
  bool status = true;
  int srOut = 44100;
  long blockSize;
  int channels;
  SampleCountType samplesIn;
  int srIn;
  SampleCountType samplesToOutput;
  SampleCountType samplesToInput;
  bool bRead = false;
  bool bWrite = false;
  audio *abuf = NULL;
  float *fbuf = NULL;
  SBSMSInterface *iface = NULL;
  SBSMSInterface *ifacePre = NULL;
  SBSMS *sbsms = NULL;
  PcmWriter *writer = NULL;
  AudioDecoder *decoder = NULL;
  AudioDecoder *decoderPre = NULL;

  SBSMSQuality quality(&SBSMSQualityStandard);
  Slide rateSlide(SlideLinearInputRate,rate0,rate1);
  Slide pitchSlide(SlideLinearOutputRate,pitch0,pitch1);

  if(bAnalyze) {
    float preProgress = 0.0f;
    decoder = import(filenameIn);
    if(!decoder) {
      printf("File: %s cannot be opened\n",filenameIn);
      exit(-1);
    }
    srIn = decoder->getSampleRate();
    channels = decoder->getChannels();
    samplesIn = decoder->getFrames();
    samplesToInput = (SampleCountType) (samplesIn*(float)srOut/(float)srIn);
    float pitch = (srOut == srIn?1.0f:(float)srOut / (float)srIn);
    iface = new SBSMSInterfaceDecoder(&rateSlide,&pitchSlide,false,
                                      channels,samplesToInput,0,&quality,decoder,pitch);
    sbsms = new SBSMS(channels,&quality,bSynthesize);

    samplesToOutput = iface->getSamplesToOutput();
 
    if(bSynthesize) {
      blockSize = quality.getFrameSize();
      fbuf = (float*)calloc(blockSize*channels,sizeof(float));
      abuf = (audio*)calloc(blockSize,sizeof(audio));    
      writer = new PcmWriter(filenameOut,samplesToOutput,srOut,channels);
      if(writer->isError()) {
        printf("File: %s cannot be opened\n",filenameOut);
        status = false;
        goto cleanup;
      }

      SampleCountType pos = 0;
      long ret = -1;
      
      while(pos<samplesToOutput && ret) {
        long lastPercent=0;      
        ret = sbsms->read(iface,abuf,blockSize);
        if(pos+ret > samplesToOutput) {
          ret = (long)(samplesToOutput - pos);
        }
        audio_convert_from(fbuf,0,abuf,0,ret,channels);
        for(int k=0;k<ret*channels;k++) {
          fbuf[k] *= volume;
        }
      
        if(ret) writer->write(fbuf, ret);
        pos += ret;
        
        float progress = (float)pos / (float)samplesToOutput;
        progressCB(progress,"Progress",data);
      }
      writer->close();
    }
  }
  
 cleanup:
  if(decoderPre) delete decoderPre;
  if(decoder) delete decoder;
  if(fbuf) free(fbuf);
  if(abuf) free(abuf);
  if(sbsms) delete sbsms;
  if(iface) delete iface;
  if(ifacePre) delete ifacePre;
  if(writer) delete writer;

  return status;
}