summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2010-05-16 20:54:50 +0000
committerCarl Hetherington <carl@carlh.net>2010-05-16 20:54:50 +0000
commitf1114dedeecf4279a4c19a85be0c11e9fde5610b (patch)
tree090a85771cda9f207a924e38c8f14290adbda033 /libs
parent50615cd17c06a5f4c8a196182407ceee7d182635 (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.h4
-rw-r--r--libs/ardour/ardour/debug.h1
-rw-r--r--libs/ardour/ardour/sndfilesource.h4
-rw-r--r--libs/ardour/debug.cc1
-rw-r--r--libs/ardour/smf_source.cc1
-rw-r--r--libs/ardour/wscript1
-rw-r--r--libs/evoral/src/SMF.cpp27
-rw-r--r--libs/evoral/src/libsmf/smf.h4
-rw-r--r--libs/evoral/src/libsmf/smf_load.c17
-rw-r--r--libs/evoral/src/libsmf/smf_save.c29
-rw-r--r--libs/evoral/wscript2
-rw-r--r--libs/pbd/debug.cc1
-rw-r--r--libs/pbd/file_manager.cc (renamed from libs/ardour/file_manager.cc)99
-rw-r--r--libs/pbd/pbd/debug.h1
-rw-r--r--libs/pbd/pbd/file_manager.h (renamed from libs/ardour/ardour/file_manager.h)35
-rw-r--r--libs/pbd/wscript1
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