diff options
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r-- | libs/ardour/ardour/audiosource.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/debug.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/file_manager.h | 128 | ||||
-rw-r--r-- | libs/ardour/ardour/sndfilesource.h | 5 |
4 files changed, 136 insertions, 2 deletions
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h index c4a6e4e475..9879c75a8d 100644 --- a/libs/ardour/ardour/audiosource.h +++ b/libs/ardour/ardour/audiosource.h @@ -32,6 +32,7 @@ #include "ardour/source.h" #include "ardour/ardour.h" #include "ardour/readable.h" +#include "ardour/file_manager.h" #include "pbd/stateful.h" #include "pbd/xml++.h" @@ -140,7 +141,8 @@ class AudioSource : virtual public Source, framecnt_t frames_per_peak); private: - int peakfile; + FdFileDescriptor* _peakfile_descriptor; + int _peakfile_fd; framecnt_t peak_leftover_cnt; framecnt_t peak_leftover_size; Sample* peak_leftovers; diff --git a/libs/ardour/ardour/debug.h b/libs/ardour/ardour/debug.h index 57b66a8793..33d973389a 100644 --- a/libs/ardour/ardour/debug.h +++ b/libs/ardour/ardour/debug.h @@ -46,6 +46,7 @@ namespace PBD { extern uint64_t MidiClock; extern uint64_t Monitor; extern uint64_t Solo; + extern uint64_t FileManager; } } diff --git a/libs/ardour/ardour/file_manager.h b/libs/ardour/ardour/file_manager.h new file mode 100644 index 0000000000..86eb9676fa --- /dev/null +++ b/libs/ardour/ardour/file_manager.h @@ -0,0 +1,128 @@ +/* + Copyright (C) 2010 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __file_manager_h__ +#define __file_manager_h__ + +#include <sys/types.h> +#include <string> +#include <map> +#include <sndfile.h> +#include <glibmm/thread.h> +#include "pbd/signals.h" + +namespace ARDOUR { + +class FileManager; + +/** Parent class for FileDescriptors. + * + * When a subclass is instantiated, the file it describes is added to a + * list. The FileDescriptor can be `allocated', meaning that its + * file will be opened on the filesystem, and can then be `released'. + * FileDescriptors are reference counted as they are allocated and + * released. When a descriptor's refcount is 0, the file on the + * filesystem is eligible to be closed if necessary to free up file + * handles for other files. + * + * The upshot of all this is that Ardour can manage the number of + * open files to stay within limits imposed by the operating system. + */ + +class FileDescriptor +{ +public: + FileDescriptor (std::string const &, bool); + virtual ~FileDescriptor () {} + + void release (); + + /** Emitted when the file is closed */ + PBD::Signal0<void> Closed; + +protected: + + friend class FileManager; + + /* These methods and variables must be called / accessed + with a lock held on the FileManager's mutex + */ + + /** @return false on success, true on failure */ + virtual bool open () = 0; + 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 + + FileManager* manager (); + +private: + + static FileManager* _manager; +}; + +/** FileDescriptor for a file to be opened using libsndfile */ +class SndFileDescriptor : public FileDescriptor +{ +public: + SndFileDescriptor (std::string const &, bool, SF_INFO *); + ~SndFileDescriptor (); + + SNDFILE* allocate (); + +private: + + friend class FileManager; + + bool open (); + void close (); + bool is_open () const; + + SNDFILE* _sndfile; ///< SNDFILE* pointer, or 0 if the file is closed + SF_INFO* _info; ///< libsndfile's info for this file +}; + +/** FileDescriptor for a file to be opened using POSIX open */ +class FdFileDescriptor : public FileDescriptor +{ +public: + FdFileDescriptor (std::string const &, bool, mode_t); + ~FdFileDescriptor (); + + int allocate (); + +private: + + friend class FileManager; + + bool open (); + void close (); + bool is_open () const; + + int _fd; ///< file descriptor, or -1 if the file is closed + mode_t _mode; ///< mode to use when creating files +}; + +} + +#endif diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h index 96f39de2c8..2338e35bb0 100644 --- a/libs/ardour/ardour/sndfilesource.h +++ b/libs/ardour/ardour/sndfilesource.h @@ -24,6 +24,7 @@ #include "ardour/audiofilesource.h" #include "ardour/broadcast_info.h" +#include "ardour/file_manager.h" namespace ARDOUR { @@ -72,13 +73,14 @@ class SndFileSource : public AudioFileSource { framecnt_t write_float (Sample* data, framepos_t pos, framecnt_t cnt); private: - SNDFILE *sf; + SndFileDescriptor* _descriptor; SF_INFO _info; BroadcastInfo *_broadcast_info; void init_sndfile (); int open(); int setup_broadcast_info (framepos_t when, struct tm&, time_t); + void file_closed (); /* destructive */ @@ -100,6 +102,7 @@ class SndFileSource : public AudioFileSource { framecnt_t nondestructive_write_unlocked (Sample *dst, framecnt_t cnt); void handle_header_position_change (); PBD::ScopedConnection header_position_connection; + PBD::ScopedConnection file_manager_connection; }; } // namespace ARDOUR |