aflibaudio.cc
来自「一个共享源码的音频库2」· CC 代码 · 共 778 行 · 第 1/2 页
CC
778 行
if (*(d_list.begin())) { (*(d_list.begin()))->getLength(length); num_samples = (int)length; } // IF caller does not want memory returned then free if (free_memory == TRUE) { for (it_data = d_list.begin(); it_data != d_list.end(); it_data++) delete (*it_data); d_list.erase(d_list.begin(), d_list.begin()); d_list.push_back(NULL); } decrementLevel(); return (*(d_list.begin()));}voidaflibAudio::examineChain(){ // This function will examine the chain if necessary and perform any preprocessing // that is necessary if (_level == 1) { // IF chain has not been preprocessed if (FALSE == checkChain(this)) { preprocessChain(this, NULL); } }}boolaflibAudio::checkChain(const aflibAudio * audio) const{ // This will check the chain that is setup to see if it has been preprocessed // since the last change to the chain. This function will handle multiple parents // for a derived object. This function is recursive. map<int, aflibAudio *, less<int> > audio_list = audio->getParents(); map<int, aflibAudio *, less<int> >::iterator it; bool ret_value = TRUE; // Loop thru all parents of this object for (it = audio_list.begin(); it != audio_list.end(); it++) { // Check down the chain of this object ret_value = checkChain((*it).second); // If chain is not setup then we are done if (ret_value == FALSE) break; } // IF nodes are processed AND this node is enabled then check this node if ((ret_value == TRUE) && (audio->getEnable())) { ret_value = audio->getNodeProcessed(); } return (ret_value);}voidaflibAudio::preprocessChain( aflibAudio * audio, aflibAudio * child){ // This function will preprocess a chain by starting at the beginning of the chain // going down the chain and storing the output configuration of the parent to the // input configuration of the child. If child is null then we are at the end of // the chain. This function will handle multiple parents. This function is recursive. map<int, aflibAudio *, less<int> > audio_list = audio->getParents(); map<int, aflibAudio *, less<int> >::iterator it; // Loop thru all parents of this object to get to the top of the chain for (it = audio_list.begin(); it != audio_list.end(); it++) { preprocessChain((*it).second, audio); } // IF there is a child if (child != NULL) { if (child->getEnable() == TRUE) { // set the input of the child to the output of the parent child->setInputConfig(audio->getOutputConfig()); // IF node is enabled if (audio->getEnable() == TRUE) { // see if child needs to have input sample rate converted /* TODO might be better to use input no instead of pointer. * or else consolidate both these functions into one */ audio = child->convertChannels(*audio); audio = child->convertSampleRate(*audio); } } else { child->aflibAudio::setInputConfig(audio->getOutputConfig()); } } // Set this node to have been preprocessed audio->setNodeProcessed(TRUE);}aflibAudio*aflibAudio::convertSampleRate(aflibAudio& parent){// Called after parent sets input_cfg to it's output_cfg aflibConfig config(getInputConfig()); int sample_rate = config.getSamplesPerSecond(); int input_sample_rate = sample_rate; double factor; // IF sample rate conversion is enabled for child if (_enable_sample_rate == TRUE) { // If sample rate is not supported by child if (!isSampleRateSupported(sample_rate)) { // If sample_rate is overridden by user then above should // return overridden rate if it was supported factor = (double)sample_rate/(double)input_sample_rate; /* TODO allow for the fact a child can have more then one parent */ if (_cvt) _cvt->setFactor( factor ); else _cvt = new aflibAudioSampleRateCvt(parent, factor); aflib_debug("aflibAudio: converting by factor %0.2f", factor); // Remove old parent and install new parent replaceParent(parent, *_cvt); // Setup the config data for this new node _cvt->setInputConfig(parent.getOutputConfig()); // Set child sample rate to new sample_rate config.setSamplesPerSecond(sample_rate); // Set this new node to have already been processed _cvt->setNodeProcessed(TRUE); return _cvt; } } return &parent;}aflibAudio*aflibAudio::convertChannels(aflibAudio& parent){ // Called after parent sets input_cfg to it's output_cfg aflibConfig config(getInputConfig()); int channels = config.getChannels(); int input_channels = channels; // IF channels conversion is enabled for child if (_enable_channels == TRUE) { // If sample rate is not supported by child if (!isChannelsSupported(channels)) { // If sample_rate is overridden by user then above should // return overridden rate if it was supported /* TODO allow for the fact a child can have more then one parent */ if (!_mix) _mix = new aflibAudioMixer(parent); _mix->delAllMix(); /* TODO more intellegence about types of mixes to add */ if(input_channels == 2) { /* left to mono - right to mono */ _mix->addMix(1,1,0, 100); _mix->addMix(1,0,0, 100); } else if(input_channels == 1) { /* mono to left - mono to right */ _mix->addMix(1,0,0, 100); _mix->addMix(1,0,1, 100); } else { /* route every input channel to every output channel */ for(int j = 0; j < channels; j++){ for(int i = 0;i < input_channels; i++){ _mix->addMix(1,i,j,100); } } } // Remove old parent and install new parent replaceParent(parent, *_mix); // Setup the config data for this new node _mix->setInputConfig(parent.getOutputConfig()); // Set child sample rate to new sample_rate config.setChannels(channels); // Set this new node to have already been processed _mix->setNodeProcessed(TRUE); return _mix; } } return &parent;}voidaflibAudio::convertData(aflibData& data){ const aflibConfig& config = data.getConfig(); // IF data size conversion is enabled if (_enable_data_size == TRUE) { // If data size is not supported if (!isDataSizeSupported(config.getSampleSize())) { switch (config.getSampleSize()) { case AFLIB_DATA_8S: // Find an acceptable data size to convert to if (isDataSizeSupported(AFLIB_DATA_8U)) data.convertToSize(AFLIB_DATA_8U); else if (isDataSizeSupported(AFLIB_DATA_16S)) data.convertToSize(AFLIB_DATA_16S); else if (isDataSizeSupported(AFLIB_DATA_16U)) data.convertToSize(AFLIB_DATA_16U); else if (isDataSizeSupported(AFLIB_DATA_32S)) data.convertToSize(AFLIB_DATA_32S); else cerr << "No allowed data size to convert to" << endl; break; case AFLIB_DATA_8U: // Find an acceptable data size to convert to if (isDataSizeSupported(AFLIB_DATA_8S)) data.convertToSize(AFLIB_DATA_8S); else if (isDataSizeSupported(AFLIB_DATA_16U)) data.convertToSize(AFLIB_DATA_16U); else if (isDataSizeSupported(AFLIB_DATA_16S)) data.convertToSize(AFLIB_DATA_16S); else if (isDataSizeSupported(AFLIB_DATA_32S)) data.convertToSize(AFLIB_DATA_32S); else cerr << "No allowed data size to convert to" << endl; break; case AFLIB_DATA_16S: // Find an acceptable data size to convert to if (isDataSizeSupported(AFLIB_DATA_16U)) data.convertToSize(AFLIB_DATA_16U); else if (isDataSizeSupported(AFLIB_DATA_8S)) data.convertToSize(AFLIB_DATA_8S); else if (isDataSizeSupported(AFLIB_DATA_8U)) data.convertToSize(AFLIB_DATA_8U); else if (isDataSizeSupported(AFLIB_DATA_32S)) data.convertToSize(AFLIB_DATA_32S); else cerr << "No allowed data size to convert to" << endl; break; case AFLIB_DATA_16U: // Find an acceptable data size to convert to if (isDataSizeSupported(AFLIB_DATA_16S)) data.convertToSize(AFLIB_DATA_16S); else if (isDataSizeSupported(AFLIB_DATA_8U)) data.convertToSize(AFLIB_DATA_8U); else if (isDataSizeSupported(AFLIB_DATA_8S)) data.convertToSize(AFLIB_DATA_8S); else if (isDataSizeSupported(AFLIB_DATA_32S)) data.convertToSize(AFLIB_DATA_32S); else cerr << "No allowed data size to convert to" << endl; break; case AFLIB_DATA_32S: // Find an acceptable data size to convert to if (isDataSizeSupported(AFLIB_DATA_16S)) data.convertToSize(AFLIB_DATA_16S); else if (isDataSizeSupported(AFLIB_DATA_16U)) data.convertToSize(AFLIB_DATA_16U); else if (isDataSizeSupported(AFLIB_DATA_8S)) data.convertToSize(AFLIB_DATA_8S); else if (isDataSizeSupported(AFLIB_DATA_8U)) data.convertToSize(AFLIB_DATA_8U); else cerr << "No allowed data size to convert to" << endl; break; default: break; } } } // IF endian conversion is enabled if (_enable_endian == TRUE) { // If endian is supported if (!isEndianSupported(config.getDataEndian())) { if (config.getDataEndian() == AFLIB_ENDIAN_LITTLE) data.convertToEndian(AFLIB_ENDIAN_BIG); else data.convertToEndian(AFLIB_ENDIAN_LITTLE); } }}boolaflibAudio::isDataSizeSupported(aflib_data_size size){ // This is the base classes implmentation of the virtual function that // determines what data sizes are supported by a derived class. The base // classes implementation will return that all data sizes are supported. If // this is true for your derived class then this function does not need // to be overriden. If it is not then you will need to override this // function. A derived class should return TRUE under some condition. return (TRUE);}boolaflibAudio::isEndianSupported(aflib_data_endian end){ // This is the base classes implmentation of the virtual function that // determines what endian is supported by a derived class. The base // classes implementation will return that all endians are support. If // this is true for your derived class then this function does not need // to be overriden. If it is not then you will need to override this // function. A derived class should return TRUE under some condition. return (TRUE);}boolaflibAudio::isSampleRateSupported(int& rate){ // This is the base classes implmentation of the virtual function that // determines what sample rates are supported by a derived class. The base // classes implementation will return that all rates are supported. If // this is true for your derived class then this function does not need // to be overriden. If it is not then you will need to override this // function. If you return FALSE then you should set rate to the // recommended sample rate that should be used. return (TRUE);}boolaflibAudio::isChannelsSupported(int& channels){ // This is the base classes implmentation of the virtual function that // determines how many channels are supported by a derived class. The base // classes implementation will return true which states all numbers of // channels are supported. If // this is true for your derived class then this function does not need // to be overriden. If it is not then you will need to override this // function. If you return FALSE then you should set channels to the // recommended channels that should be used. return (TRUE);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?