📄 aflibfile.cc
字号:
/* * Copyright: (C) 1999-2001 Bruce W. Forsberg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Bruce Forsberg forsberg@tns.net * */// Base class for audio file reading and writing#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "aflibFile.h"#include "aflibFileItem.h"#include "aflibDebug.h"#include <stdio.h> //For findModuleFormat#include <stdlib.h>#include <dlfcn.h>#include <unistd.h> // for setenv and unsetenv#include <iostream>using std::cerr;using std::endl;#include <dirent.h>#include <sys/types.h>#ifdef NO_MODULES#include <aflibDevFile.h>#include <aflibLameFile.h>#include <aflibWavFile.h>#include <aflibAuFile.h>#endif#define MODULE_FORMAT "Format:"#define MODULE_DSCR "Description:"#define MODULE_EXT "Extension:"#define MODULE_MAGIC "Magic:"#define MODULE_NAME "Name:"#define MODULE_VALUE1 "Value1:"#define MODULE_VALUE2 "Value2:"#define MODULE_VALUE3 "Value3:"list<aflibFileItem *> aflibFile::_support_list;bool aflibFile::_list_created = FALSE;aflibFile::aflibFile(const char * module_format){ // This is a constructor that will load the proper shared object based on // the format string that is passed in. Once the shared object is loaded it will // then call the wrapper function to allocate an object for the derived // aflibFile class. This object that is allocate is the actual object that // that will be used to call the member functions. But it will be called // thru this object. This object is the one that the user will see. After // the file object is obtained then it will be used to call the derived // objects constructor. _lib1 = NULL; _file_object = NULL;#ifndef NO_MODULES const char * error_msg; string module_name_full; list<aflibFileItem *>::iterator it; string module_name; /* TODO should probably just include the fullpath and name in * aflibAudioItem. This will allow for future support of various * directories to contain modules */ if (getenv("AFLIB_MODULE_FILE_DIR")) { module_name_full = getenv("AFLIB_MODULE_FILE_DIR"); } else { module_name_full = MODULE_INSTALL_DIR; } module_name_full.append("/lib"); /* TODO make _support_list a map and key on module_format */ // Set the format for this object and find modules name and values for (it = _support_list.begin(); it != _support_list.end(); it++) { if (strcmp((*it)->getFormat().c_str(), module_format) == 0) { _format = module_format; _value1 = (*it)->getValue1(); _value2 = (*it)->getValue2(); _value3 = (*it)->getValue3(); module_name = (*it)->getName(); break; } } if(module_name.length() == 0) return; module_name_full.append(module_name); module_name_full.append(".so"); _lib1 = dlopen(module_name_full.c_str(), RTLD_LAZY ); // IF we can't load module then we are done if(_lib1 == NULL) { error_msg = dlerror(); aflib_warning("%s", error_msg); return; } aflibFile * (*func_ptr)() ; func_ptr = (aflibFile *(*)()) dlsym(_lib1, "getAFileObject"); if (func_ptr == NULL) { error_msg = dlerror(); aflib_warning("%s", error_msg); return; } // call getAFileObject in derived class and get a pointer to allocated object _file_object = func_ptr(); // Pass the value parameters to the file object so derived objects can use it if (_file_object) { _file_object->setValue1(_value1); _file_object->setValue2(_value2); _file_object->setValue3(_value3); }#endif}aflibFile::aflibFile(){ _lib1 = NULL; _file_object = NULL;}/*! \brief Destructor. */aflibFile::~aflibFile(){ // IF a file object was created then delete it now delete _file_object; _file_object = NULL; // IF a library is currently open then close it. We have to close the library // after the delete above so the destructor can be called. if (_lib1) { dlclose(_lib1); }}/*! \brief Main static function to open a file or device for reading based on aflibFileType. This is a static function of this class. Users call this function as the main API to open an audio file or device for reading. Since this is a static member function it is not associated with any aflibFile object and thus no data members can be accessed. The user passes in the file type to be opened. This can be one of the defined types or AFLIB_AUTO_TYPE. This will search the list of supported formats for a match and use that format. If AFLIB_AUTO_TYPE is specified then it will open the file and use a format that matches that file type based on information supplied by each module. Also passed is the file name which should contain the file and directory in which the file can be found. Passed back to the user will be a cfg structure filled that was allocated by the caller. This will tell information about the data. Also will be a status to indicate if any errors occurred. */aflibFile *aflibFile::open( aflibFileType type_enum, const string& file, aflibConfig* cfg, aflibStatus* status){ aflibFile * file_return = NULL; aflibStatus ret_status = AFLIB_ERROR_OPEN; const char * module_name = NULL; // Parse the module file if not done yet parseModuleFile(); // IF user wants auto recognition /* TODO move auto type to a module */ if (type_enum == AFLIB_AUTO_TYPE) { if((module_name = findModuleFile(file)) != NULL) // Allocate the real file pointer to return to user file_return = allocateModuleFile(type_enum, module_name); else ret_status = AFLIB_CANT_AUTO_TYPE; } else { // Allocate the real file pointer to return to user file_return = allocateModuleFile(type_enum, module_name); } if (file_return) { // For module support this calls base class function, for no module // support this calls derived class ret_status = file_return->afopen(file.c_str(), cfg); } else { // Unable to allocate a module so error ret_status = AFLIB_ERROR_INITIALIZATION_FAILURE; } if (status != NULL) { *status = ret_status; } return (file_return);}/*! \brief Main static function to open a file or device for reading based on format string. This is a static function of this class. Users call this function as the main API to open an audio file or device for reading. Since this is a static member function it is not associated with any aflibFile object and thus no data members can be accessed. The user passes in the file type to be opened. This must be one of the file types supplied by the function aflibFile::returnSupportedFormats. Also passed is the file name which should contain the file and directory in which the file can be found. Passed back to the user will be a cfg structure filled that was allocated by the caller. This will tell information about the data. Also will be a status to indicate if any errors occurred. */aflibFile *aflibFile::open( const string& format, const string& file, aflibConfig* cfg, aflibStatus* status){ aflibFile * file_return = NULL; aflibStatus ret_status = AFLIB_ERROR_OPEN; const char * module_name = NULL; // Parse the module file if not done yet parseModuleFile(); // IF user wants auto recognition /* TODO move auto type to a module */ if (format == "AUTO") { if((module_name = findModuleFile(file)) != NULL) // Allocate the real file pointer to return to user file_return = allocateModuleFile(AFLIB_AUTO_TYPE, module_name); else ret_status = AFLIB_CANT_AUTO_TYPE; } else { // Allocate the real file pointer to return to user file_return = allocateModuleFile(AFLIB_AUTO_TYPE, format.c_str()); } if (file_return) { // For module support this calls base class function, for no module // support this calls derived class ret_status = file_return->afopen(file.c_str(), cfg); } else { // Unable to allocate a module so error ret_status = AFLIB_ERROR_INITIALIZATION_FAILURE; } if (status != NULL) { *status = ret_status; } return (file_return);}/*! \brief Main static function for writing to a device or file by type. This is a static function of this class. Users call this function as the main API to open an audio file or device for writing. Since this is a static member function it is not associated with any aflibFile object and thus no data members can be accessed. The user passes in the file type to create. The user also specifies the file name. The specific type of audio data is specified in the cfg parameter. The status of this operation will be returned to the user as status. */aflibFile *aflibFile::create( aflibFileType type_enum, const string& file, const aflibConfig& cfg, aflibStatus* status){ aflibFile * file_return = NULL; aflibStatus ret_status = AFLIB_ERROR_OPEN; // Parse the module file if not done yet parseModuleFile(); // Allocate the real file pointer to return to user file_return = allocateModuleFile(type_enum, NULL); if (file_return) { // For module support this calls base class function, for no module // support this calls derived class ret_status = file_return->afcreate(file.c_str(), cfg); } else { // Unable to allocate a module so error ret_status = AFLIB_ERROR_INITIALIZATION_FAILURE; } // If user wants status returned then return it if (status != NULL) { *status = ret_status; } return (file_return);}/*! \brief Main static function for writing to a device or file by format. This is a static function of this class. Users call this function as the main API to open an audio file or device for writing. Since this is a static member function it is not associated with any aflibFile object and thus no data members can be accessed. The user passes in the file format to create. The user also specifies the file name. The specific type of audio data is specified in the cfg parameter. The status of this operation will be returned to the user as status. */aflibFile *aflibFile::create( const string& format, const string& file, const aflibConfig& cfg, aflibStatus* status){ aflibFile * file_return = NULL; aflibStatus ret_status = AFLIB_ERROR_OPEN; // Parse the module file if not done yet parseModuleFile(); file_return = allocateModuleFile(AFLIB_AUTO_TYPE, format.c_str()); if (file_return) { // For module support this calls base class function, for no module // support this calls derived class ret_status = file_return->afcreate(file.c_str(), cfg); } else { // Unable to allocate a module so error ret_status = AFLIB_ERROR_INITIALIZATION_FAILURE; } // If user wants status returned then return it if (status != NULL) { *status = ret_status; } return (file_return);}/*! \brief Return the current file or device format. */const string&aflibFile::getFormat() const{ return (_format);}/*! \brief Set a file format unique value number 1. */ voidaflibFile::setValue1(const string& value){ _value1 = value;}/*! \brief Set a file format unique value number 2. */ voidaflibFile::setValue2(const string& value){ _value2 = value;}/*! \brief Set a file format unique value number 3. */ voidaflibFile::setValue3(const string& value){ _value3 = value;}/*! \brief Main API for opening a file or device in read mode. This function is only used for module support. For no modules support the derived classes afopen function will be called instead. For module support this function will make a call to the derived classes function. */aflibStatusaflibFile::afopen( const char * file, aflibConfig* cfg){ aflibStatus status = AFLIB_SUCCESS; // IF we are using modules#ifndef NO_MODULES if(initialized()==true) { status = _file_object->afopen(file, cfg); // Get the config parameter from the file object and store in this object if (cfg) { *cfg = _file_object->getOutputConfig(); } } else { status = AFLIB_ERROR_INITIALIZATION_FAILURE; }#endif return (status);}/*! \brief Main API for opening a file or device in write mode. This function is only used for module support. For no module support the derived classes afcreate function will be called instead. For module support
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -