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__); }
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; }