diff options
author | Carl Hetherington <carl@carlh.net> | 2010-05-16 20:54:50 +0000 |
---|---|---|
committer | Carl Hetherington <carl@carlh.net> | 2010-05-16 20:54:50 +0000 |
commit | f1114dedeecf4279a4c19a85be0c11e9fde5610b (patch) | |
tree | 090a85771cda9f207a924e38c8f14290adbda033 /libs | |
parent | 50615cd17c06a5f4c8a196182407ceee7d182635 (diff) |
Move FileManager code into libpbd. Use it for SMF read/write.
git-svn-id: svn://localhost/ardour2/branches/3.0@7108 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/audiosource.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/debug.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/sndfilesource.h | 4 | ||||
-rw-r--r-- | libs/ardour/debug.cc | 1 | ||||
-rw-r--r-- | libs/ardour/smf_source.cc | 1 | ||||
-rw-r--r-- | libs/ardour/wscript | 1 | ||||
-rw-r--r-- | libs/evoral/src/SMF.cpp | 27 | ||||
-rw-r--r-- | libs/evoral/src/libsmf/smf.h | 4 | ||||
-rw-r--r-- | libs/evoral/src/libsmf/smf_load.c | 17 | ||||
-rw-r--r-- | libs/evoral/src/libsmf/smf_save.c | 29 | ||||
-rw-r--r-- | libs/evoral/wscript | 2 | ||||
-rw-r--r-- | libs/pbd/debug.cc | 1 | ||||
-rw-r--r-- | libs/pbd/file_manager.cc (renamed from libs/ardour/file_manager.cc) | 99 | ||||
-rw-r--r-- | libs/pbd/pbd/debug.h | 1 | ||||
-rw-r--r-- | libs/pbd/pbd/file_manager.h (renamed from libs/ardour/ardour/file_manager.h) | 35 | ||||
-rw-r--r-- | libs/pbd/wscript | 1 |
16 files changed, 153 insertions, 75 deletions
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h index 9879c75a8d..fa9e3439c1 100644 --- a/libs/ardour/ardour/audiosource.h +++ b/libs/ardour/ardour/audiosource.h @@ -32,7 +32,7 @@ #include "ardour/source.h" #include "ardour/ardour.h" #include "ardour/readable.h" -#include "ardour/file_manager.h" +#include "pbd/file_manager.h" #include "pbd/stateful.h" #include "pbd/xml++.h" @@ -141,7 +141,7 @@ class AudioSource : virtual public Source, framecnt_t frames_per_peak); private: - FdFileDescriptor* _peakfile_descriptor; + PBD::FdFileDescriptor* _peakfile_descriptor; int _peakfile_fd; framecnt_t peak_leftover_cnt; framecnt_t peak_leftover_size; diff --git a/libs/ardour/ardour/debug.h b/libs/ardour/ardour/debug.h index 33d973389a..57b66a8793 100644 --- a/libs/ardour/ardour/debug.h +++ b/libs/ardour/ardour/debug.h @@ -46,7 +46,6 @@ namespace PBD { extern uint64_t MidiClock; extern uint64_t Monitor; extern uint64_t Solo; - extern uint64_t FileManager; } } diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h index 2338e35bb0..58cfbf5b4f 100644 --- a/libs/ardour/ardour/sndfilesource.h +++ b/libs/ardour/ardour/sndfilesource.h @@ -24,7 +24,7 @@ #include "ardour/audiofilesource.h" #include "ardour/broadcast_info.h" -#include "ardour/file_manager.h" +#include "pbd/file_manager.h" namespace ARDOUR { @@ -73,7 +73,7 @@ class SndFileSource : public AudioFileSource { framecnt_t write_float (Sample* data, framepos_t pos, framecnt_t cnt); private: - SndFileDescriptor* _descriptor; + PBD::SndFileDescriptor* _descriptor; SF_INFO _info; BroadcastInfo *_broadcast_info; diff --git a/libs/ardour/debug.cc b/libs/ardour/debug.cc index 35a30a00c4..268ec5d033 100644 --- a/libs/ardour/debug.cc +++ b/libs/ardour/debug.cc @@ -43,5 +43,4 @@ uint64_t PBD::DEBUG::MackieControl = PBD::new_debug_bit ("mackiecontrol"); uint64_t PBD::DEBUG::MidiClock = PBD::new_debug_bit ("midiclock"); uint64_t PBD::DEBUG::Monitor = PBD::new_debug_bit ("monitor"); uint64_t PBD::DEBUG::Solo = PBD::new_debug_bit ("solo"); -uint64_t PBD::DEBUG::FileManager = PBD::new_debug_bit ("filemanager"); diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index f48fc301f7..e4727761b5 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -32,7 +32,6 @@ #include <glibmm/miscutils.h> -#include "evoral/SMFReader.hpp" #include "evoral/Control.hpp" #include "ardour/audioengine.h" diff --git a/libs/ardour/wscript b/libs/ardour/wscript index 65d733e9b6..d12ab3cc94 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -92,7 +92,6 @@ libardour_sources = [ 'export_profile_manager.cc', 'export_status.cc', 'export_timespan.cc', - 'file_manager.cc', 'file_source.cc', 'filename_extensions.cc', 'filesystem_paths.cc', diff --git a/libs/evoral/src/SMF.cpp b/libs/evoral/src/SMF.cpp index 73e3651f45..007055def8 100644 --- a/libs/evoral/src/SMF.cpp +++ b/libs/evoral/src/SMF.cpp @@ -26,6 +26,7 @@ #include "evoral/Event.hpp" #include "evoral/SMF.hpp" #include "evoral/midi_util.h" +#include "pbd/file_manager.h" using namespace std; @@ -82,7 +83,14 @@ SMF::open(const std::string& path, int track) THROW_FILE_ERROR } _file_path = path; - _smf = smf_load(_file_path.c_str()); + + PBD::StdioFileDescriptor d (_file_path, "r"); + FILE* f = d.allocate (); + if (f == 0) { + return -1; + } + + _smf = smf_load (f); if (_smf == NULL) { return -1; } @@ -149,7 +157,13 @@ void SMF::close() THROW_FILE_ERROR { if (_smf) { - if (smf_save(_smf, _file_path.c_str()) != 0) { + PBD::StdioFileDescriptor d (_file_path, "w+"); + FILE* f = d.allocate (); + if (f == 0) { + throw FileError (); + } + + if (smf_save(_smf, f) != 0) { throw FileError(); } smf_delete(_smf); @@ -259,8 +273,15 @@ SMF::begin_write() void SMF::end_write() THROW_FILE_ERROR { - if (smf_save(_smf, _file_path.c_str()) != 0) + PBD::StdioFileDescriptor d (_file_path, "w+"); + FILE* f = d.allocate (); + if (f == 0) { + throw FileError (); + } + + if (smf_save(_smf, f) != 0) { throw FileError(); + } } double diff --git a/libs/evoral/src/libsmf/smf.h b/libs/evoral/src/libsmf/smf.h index 212105c5d0..5e3e2d1859 100644 --- a/libs/evoral/src/libsmf/smf.h +++ b/libs/evoral/src/libsmf/smf.h @@ -387,11 +387,11 @@ char *smf_event_decode(const smf_event_t *event) WARN_UNUSED_RESULT; char *smf_event_extract_text(const smf_event_t *event) WARN_UNUSED_RESULT; /* Routines for loading SMF files. */ -smf_t *smf_load(const char *file_name) WARN_UNUSED_RESULT; +smf_t *smf_load(FILE *) WARN_UNUSED_RESULT; smf_t *smf_load_from_memory(const void *buffer, const size_t buffer_length) WARN_UNUSED_RESULT; /* Routine for writing SMF files. */ -int smf_save(smf_t *smf, const char *file_name) WARN_UNUSED_RESULT; +int smf_save(smf_t *smf, FILE *file) WARN_UNUSED_RESULT; /* Routines for manipulating smf_tempo_t. */ smf_tempo_t *smf_get_tempo_by_pulses(const smf_t *smf, size_t pulses) WARN_UNUSED_RESULT; diff --git a/libs/evoral/src/libsmf/smf_load.c b/libs/evoral/src/libsmf/smf_load.c index 71ad02498e..cebca73b82 100644 --- a/libs/evoral/src/libsmf/smf_load.c +++ b/libs/evoral/src/libsmf/smf_load.c @@ -794,12 +794,11 @@ parse_mtrk_chunk(smf_track_t *track) } /** - * Allocate buffer of proper size and read file contents into it. Close file afterwards. + * Allocate buffer of proper size and read file contents into it. */ static int -load_file_into_buffer(void **file_buffer, size_t *file_buffer_length, const char *file_name) +load_file_into_buffer(void **file_buffer, size_t *file_buffer_length, FILE* stream) { - FILE *stream = fopen(file_name, "r"); long offset; if (stream == NULL) { @@ -841,12 +840,6 @@ load_file_into_buffer(void **file_buffer, size_t *file_buffer_length, const char return (-6); } - if (fclose(stream)) { - g_critical("fclose(3) failed: %s", strerror(errno)); - - return (-7); - } - return (0); } @@ -903,17 +896,17 @@ smf_load_from_memory(const void *buffer, const size_t buffer_length) /** * Loads SMF file. * - * \param file_name Path to the file. + * \param file Open file. * \return SMF or NULL, if loading failed. */ smf_t * -smf_load(const char *file_name) +smf_load(FILE *file) { size_t file_buffer_length; void *file_buffer; smf_t *smf; - if (load_file_into_buffer(&file_buffer, &file_buffer_length, file_name)) + if (load_file_into_buffer(&file_buffer, &file_buffer_length, file)) return (NULL); smf = smf_load_from_memory(file_buffer, file_buffer_length); diff --git a/libs/evoral/src/libsmf/smf_save.c b/libs/evoral/src/libsmf/smf_save.c index 1a7a726675..b03bf90044 100644 --- a/libs/evoral/src/libsmf/smf_save.c +++ b/libs/evoral/src/libsmf/smf_save.c @@ -391,29 +391,14 @@ write_track(smf_track_t *track) * Takes smf->file_buffer and saves it to the file. */ static int -write_file(smf_t *smf, const char *file_name) +write_file(smf_t *smf, FILE* stream) { - FILE *stream; - - stream = fopen(file_name, "w+"); - if (stream == NULL) { - g_critical("Cannot open input file: %s", strerror(errno)); - - return (-1); - } - if (fwrite(smf->file_buffer, 1, smf->file_buffer_length, stream) != smf->file_buffer_length) { g_critical("fwrite(3) failed: %s", strerror(errno)); return (-2); } - if (fclose(stream)) { - g_critical("fclose(3) failed: %s", strerror(errno)); - - return (-3); - } - return (0); } @@ -593,11 +578,11 @@ assert_smf_is_identical(const smf_t *a, const smf_t *b) } static void -assert_smf_saved_correctly(const smf_t *smf, const char *file_name) +assert_smf_saved_correctly(const smf_t *smf, FILE* file) { smf_t *saved; - saved = smf_load(file_name); + saved = smf_load (file); assert(saved != NULL); assert_smf_is_identical(smf, saved); @@ -610,11 +595,11 @@ assert_smf_saved_correctly(const smf_t *smf, const char *file_name) /** * Writes the contents of SMF to the file given. * \param smf SMF. - * \param file_name Path to the file. + * \param file File descriptor. * \return 0, if saving was successfull. */ int -smf_save(smf_t *smf, const char *file_name) +smf_save(smf_t *smf, FILE* file) { int i, error; smf_track_t *track; @@ -641,7 +626,7 @@ smf_save(smf_t *smf, const char *file_name) } } - error = write_file(smf, file_name); + error = write_file(smf, file); free_buffer(smf); @@ -649,7 +634,7 @@ smf_save(smf_t *smf, const char *file_name) return (error); #ifndef NDEBUG - assert_smf_saved_correctly(smf, file_name); + assert_smf_saved_correctly(smf, file); #endif return (0); diff --git a/libs/evoral/wscript b/libs/evoral/wscript index b03e182d51..4293fd88d1 100644 --- a/libs/evoral/wscript +++ b/libs/evoral/wscript @@ -91,7 +91,7 @@ def build(bld): obj.name = 'libevoral' obj.target = 'evoral' obj.uselib = 'GLIBMM GTHREAD SMF' - obj.uselib_local = 'libsmf' + obj.uselib_local = 'libsmf libpbd' obj.vnum = EVORAL_LIB_VERSION obj.install_path = os.path.join(bld.env['LIBDIR'], 'ardour3') diff --git a/libs/pbd/debug.cc b/libs/pbd/debug.cc index 318f85a099..4f97ccff86 100644 --- a/libs/pbd/debug.cc +++ b/libs/pbd/debug.cc @@ -32,6 +32,7 @@ static std::map<const char*,uint64_t> _debug_bit_map; uint64_t PBD::DEBUG::Stateful = PBD::new_debug_bit ("stateful"); uint64_t PBD::DEBUG::Properties = PBD::new_debug_bit ("properties"); +uint64_t PBD::DEBUG::FileManager = PBD::new_debug_bit ("filemanager"); uint64_t PBD::debug_bits = 0x0; diff --git a/libs/ardour/file_manager.cc b/libs/pbd/file_manager.cc index bc27459230..25d171b959 100644 --- a/libs/ardour/file_manager.cc +++ b/libs/pbd/file_manager.cc @@ -25,16 +25,15 @@ #include <cassert> #include <iostream> #include "pbd/compose.h" -#include "ardour/file_manager.h" -#include "ardour/debug.h" +#include "pbd/file_manager.h" +#include "pbd/debug.h" using namespace std; using namespace PBD; -using namespace ARDOUR; FileManager* FileDescriptor::_manager; -namespace ARDOUR { +namespace PBD { /** Class to limit the number of files held open */ class FileManager @@ -103,9 +102,9 @@ FileManager::allocate (FileDescriptor* d) list<FileDescriptor*>::iterator oldest = _files.end (); for (list<FileDescriptor*>::iterator i = _files.begin(); i != _files.end(); ++i) { - if ((*i)->is_open() && (*i)->refcount == 0) { - if ((*i)->last_used < lowest_last_used) { - lowest_last_used = (*i)->last_used; + if ((*i)->is_open() && (*i)->_refcount == 0) { + if ((*i)->_last_used < lowest_last_used) { + lowest_last_used = (*i)->_last_used; oldest = i; } } @@ -121,25 +120,26 @@ FileManager::allocate (FileDescriptor* d) DEBUG::FileManager, string_compose ( "closed file for %1 to release file handle; now have %2 of %3 open\n", - (*oldest)->name, _open, _max_open + (*oldest)->_name, _open, _max_open ) ); } if (d->open ()) { + DEBUG_TRACE (DEBUG::FileManager, string_compose ("open of %1 failed.\n", d->_name)); return true; } _open++; - DEBUG_TRACE (DEBUG::FileManager, string_compose ("opened file for %1; now have %2 of %3 open.\n", d->name, _open, _max_open)); + DEBUG_TRACE (DEBUG::FileManager, string_compose ("opened file for %1; now have %2 of %3 open.\n", d->_name, _open, _max_open)); } struct timespec t; clock_gettime (CLOCK_MONOTONIC, &t); - d->last_used = t.tv_sec + (double) t.tv_nsec / 10e9; + d->_last_used = t.tv_sec + (double) t.tv_nsec / 10e9; - d->refcount++; + d->_refcount++; return false; } @@ -150,8 +150,8 @@ FileManager::release (FileDescriptor* d) { Glib::Mutex::Lock lm (_mutex); - d->refcount--; - assert (d->refcount >= 0); + d->_refcount--; + assert (d->_refcount >= 0); } /** Remove a file from our lists. It will be closed if it is currently open. */ @@ -164,7 +164,7 @@ FileManager::remove (FileDescriptor* d) close (d); DEBUG_TRACE ( DEBUG::FileManager, - string_compose ("closed file for %1; file is being removed; now have %2 of %3 open\n", d->name, _open, _max_open) + string_compose ("closed file for %1; file is being removed; now have %2 of %3 open\n", d->_name, _open, _max_open) ); } @@ -182,10 +182,10 @@ FileManager::close (FileDescriptor* d) } FileDescriptor::FileDescriptor (string const & n, bool w) - : refcount (0) - , last_used (0) - , name (n) - , writeable (w) + : _refcount (0) + , _last_used (0) + , _name (n) + , _writeable (w) { } @@ -262,7 +262,7 @@ SndFileDescriptor::open () { /* we must have a lock on the FileManager's mutex */ - _sndfile = sf_open (name.c_str(), writeable ? SFM_RDWR : SFM_READ, _info); + _sndfile = sf_open (_name.c_str(), _writeable ? SFM_RDWR : SFM_READ, _info); return (_sndfile == 0); } @@ -298,7 +298,7 @@ FdFileDescriptor::open () { /* we must have a lock on the FileManager's mutex */ - _fd = ::open (name.c_str(), writeable ? (O_RDWR | O_CREAT) : O_RDONLY, _mode); + _fd = ::open (_name.c_str(), _writeable ? (O_RDWR | O_CREAT) : O_RDONLY, _mode); return (_fd == -1); } @@ -325,3 +325,62 @@ FdFileDescriptor::allocate () */ return _fd; } + + +/** @param n Filename. + * @param w true to open writeable, otherwise false. + */ + +StdioFileDescriptor::StdioFileDescriptor (string const & n, std::string const & m) + : FileDescriptor (n, false) + , _file (0) + , _mode (m) +{ + manager()->add (this); +} + +StdioFileDescriptor::~StdioFileDescriptor () +{ + manager()->remove (this); +} + +bool +StdioFileDescriptor::is_open () const +{ + /* we must have a lock on the FileManager's mutex */ + + return _file != 0; +} + +bool +StdioFileDescriptor::open () +{ + /* we must have a lock on the FileManager's mutex */ + + _file = fopen (_name.c_str(), _mode.c_str()); + return (_file == 0); +} + +void +StdioFileDescriptor::close () +{ + /* we must have a lock on the FileManager's mutex */ + + fclose (_file); + _file = 0; +} + +/** @return FILE*, or 0 on error */ +FILE* +StdioFileDescriptor::allocate () +{ + bool const f = manager()->allocate (this); + if (f) { + return 0; + } + + /* this is ok thread-wise because allocate () has incremented + the Descriptor's refcount, so the file will not be closed + */ + return _file; +} diff --git a/libs/pbd/pbd/debug.h b/libs/pbd/pbd/debug.h index a45a867bd2..d3ce495a1b 100644 --- a/libs/pbd/pbd/debug.h +++ b/libs/pbd/pbd/debug.h @@ -39,6 +39,7 @@ namespace PBD { extern uint64_t Stateful; extern uint64_t Properties; + extern uint64_t FileManager; } } diff --git a/libs/ardour/ardour/file_manager.h b/libs/pbd/pbd/file_manager.h index 86eb9676fa..3f708eb44e 100644 --- a/libs/ardour/ardour/file_manager.h +++ b/libs/pbd/pbd/file_manager.h @@ -17,8 +17,8 @@ */ -#ifndef __file_manager_h__ -#define __file_manager_h__ +#ifndef __pbd_file_manager_h__ +#define __pbd_file_manager_h__ #include <sys/types.h> #include <string> @@ -27,7 +27,7 @@ #include <glibmm/thread.h> #include "pbd/signals.h" -namespace ARDOUR { +namespace PBD { class FileManager; @@ -69,10 +69,10 @@ protected: virtual void close () = 0; virtual bool is_open () const = 0; - int refcount; ///< number of active users of this file - double last_used; ///< monotonic time that this file was last allocated - std::string name; ///< filename - bool writeable; ///< true if it should be opened writeable, otherwise false + int _refcount; ///< number of active users of this file + double _last_used; ///< monotonic time that this file was last allocated + std::string _name; ///< filename + bool _writeable; ///< true if it should be opened writeable, otherwise false FileManager* manager (); @@ -123,6 +123,27 @@ private: mode_t _mode; ///< mode to use when creating files }; +/** FileDescriptor for a file opened using stdio */ +class StdioFileDescriptor : public FileDescriptor +{ +public: + StdioFileDescriptor (std::string const &, std::string const &); + ~StdioFileDescriptor (); + + FILE* allocate (); + +private: + + friend class FileManager; + + bool open (); + void close (); + bool is_open () const; + + FILE* _file; + std::string _mode; +}; + } #endif diff --git a/libs/pbd/wscript b/libs/pbd/wscript index 81174d1262..73d6c3023c 100644 --- a/libs/pbd/wscript +++ b/libs/pbd/wscript @@ -67,6 +67,7 @@ def build(bld): error.cc filesystem.cc filesystem_paths.cc + file_manager.cc file_utils.cc fpu.cc id.cc |