summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/actions.cc13
-rw-r--r--gtk2_ardour/icons/bigknob.pngbin94045 -> 78788 bytes
-rw-r--r--gtk2_ardour/icons/littleknob.pngbin31010 -> 32350 bytes
-rw-r--r--gtk2_ardour/keyeditor.cc4
-rw-r--r--gtk2_ardour/utils.cc84
-rw-r--r--gtk2_ardour/utils.h2
-rw-r--r--libs/ardour/ardour/sndfilesource.h2
-rw-r--r--libs/gtkmm2ext/actions.cc17
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/motionfeedback.h2
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/utils.h4
-rw-r--r--libs/gtkmm2ext/mfimg.cc16
-rw-r--r--libs/gtkmm2ext/motionfeedback.cc74
-rw-r--r--libs/gtkmm2ext/utils.cc83
-rw-r--r--libs/gtkmm2ext/wscript10
-rw-r--r--libs/pbd/file_manager.cc85
-rw-r--r--libs/pbd/pbd/file_manager.h45
-rw-r--r--libs/pbd/pbd/sndfile_manager.h56
-rw-r--r--libs/pbd/sndfile_manager.cc92
-rw-r--r--libs/pbd/wscript1
19 files changed, 366 insertions, 224 deletions
diff --git a/gtk2_ardour/actions.cc b/gtk2_ardour/actions.cc
index 6d29737b86..49ac38d405 100644
--- a/gtk2_ardour/actions.cc
+++ b/gtk2_ardour/actions.cc
@@ -186,16 +186,3 @@ ActionManager::map_some_state (const char* group, const char* action, sigc::slot
}
}
-string
-ActionManager::get_key_representation (const string& accel_path, AccelKey& key)
-{
- bool known = lookup_entry (accel_path, key);
-
- if (known) {
- uint32_t k = possibly_translate_legal_accelerator_to_real_key (key.get_key());
- key = AccelKey (k, Gdk::ModifierType (key.get_mod()));
- return ui_manager->get_accel_group()->name (key.get_key(), Gdk::ModifierType (key.get_mod()));
- }
-
- return unbound_string;
-}
diff --git a/gtk2_ardour/icons/bigknob.png b/gtk2_ardour/icons/bigknob.png
index b4fa02aad4..1511d23127 100644
--- a/gtk2_ardour/icons/bigknob.png
+++ b/gtk2_ardour/icons/bigknob.png
Binary files differ
diff --git a/gtk2_ardour/icons/littleknob.png b/gtk2_ardour/icons/littleknob.png
index a48f222204..76544e1399 100644
--- a/gtk2_ardour/icons/littleknob.png
+++ b/gtk2_ardour/icons/littleknob.png
Binary files differ
diff --git a/gtk2_ardour/keyeditor.cc b/gtk2_ardour/keyeditor.cc
index 96a9857412..2a72adb5dd 100644
--- a/gtk2_ardour/keyeditor.cc
+++ b/gtk2_ardour/keyeditor.cc
@@ -8,6 +8,8 @@
#include <gtkmm/accelmap.h>
#include <gtkmm/uimanager.h>
+#include "gtkmm2ext/utils.h"
+
#include "pbd/strsplit.h"
#include "pbd/replace_all.h"
@@ -173,7 +175,7 @@ KeyEditor::on_key_release_event (GdkEventKey* ev)
}
cerr << "real lkeyval: " << ev->keyval << endl;
- possibly_translate_keyval_to_make_legal_accelerator (ev->keyval);
+ Gtkmm2ext::possibly_translate_keyval_to_make_legal_accelerator (ev->keyval);
cerr << "using keyval = " << ev->keyval << endl;
diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc
index e96137ee2c..ac43d06e59 100644
--- a/gtk2_ardour/utils.cc
+++ b/gtk2_ardour/utils.cc
@@ -684,7 +684,7 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
uint32_t fakekey = ev->keyval;
- if (possibly_translate_keyval_to_make_legal_accelerator (fakekey)) {
+ if (Gtkmm2ext::possibly_translate_keyval_to_make_legal_accelerator (fakekey)) {
if (allow_activating && gtk_accel_groups_activate(G_OBJECT(win), fakekey, GdkModifierType(ev->state))) {
return true;
}
@@ -916,88 +916,6 @@ reset_dpi ()
DPIReset();//Emit Signal
}
-bool
-possibly_translate_keyval_to_make_legal_accelerator (uint32_t& keyval)
-{
- int fakekey = GDK_VoidSymbol;
-
- switch (keyval) {
- case GDK_Tab:
- case GDK_ISO_Left_Tab:
- fakekey = GDK_nabla;
- break;
-
- case GDK_Up:
- fakekey = GDK_uparrow;
- break;
-
- case GDK_Down:
- fakekey = GDK_downarrow;
- break;
-
- case GDK_Right:
- fakekey = GDK_rightarrow;
- break;
-
- case GDK_Left:
- fakekey = GDK_leftarrow;
- break;
-
- case GDK_Return:
- fakekey = GDK_3270_Enter;
- break;
-
- case GDK_KP_Enter:
- fakekey = GDK_F35;
- break;
-
- default:
- break;
- }
-
- if (fakekey != GDK_VoidSymbol) {
- keyval = fakekey;
- return true;
- }
-
- return false;
-}
-
-uint32_t
-possibly_translate_legal_accelerator_to_real_key (uint32_t keyval)
-{
- switch (keyval) {
- case GDK_nabla:
- return GDK_Tab;
- break;
-
- case GDK_uparrow:
- return GDK_Up;
- break;
-
- case GDK_downarrow:
- return GDK_Down;
- break;
-
- case GDK_rightarrow:
- return GDK_Right;
- break;
-
- case GDK_leftarrow:
- return GDK_Left;
- break;
-
- case GDK_3270_Enter:
- return GDK_Return;
-
- case GDK_F35:
- return GDK_KP_Enter;
- break;
- }
-
- return keyval;
-}
-
inline guint8
diff --git a/gtk2_ardour/utils.h b/gtk2_ardour/utils.h
index bfde7807d5..cac21b4ffa 100644
--- a/gtk2_ardour/utils.h
+++ b/gtk2_ardour/utils.h
@@ -75,8 +75,6 @@ void set_color (Gdk::Color&, int);
bool relay_key_press (GdkEventKey* ev, Gtk::Window* win);
bool forward_key_press (GdkEventKey* ev);
bool key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev);
-bool possibly_translate_keyval_to_make_legal_accelerator (uint32_t& keyval);
-uint32_t possibly_translate_legal_accelerator_to_real_key (uint32_t keyval);
Glib::RefPtr<Gdk::Pixbuf> get_xpm (std::string);
Glib::ustring get_icon_path (const char*);
diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h
index 58cfbf5b4f..9a01892ccf 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 "pbd/file_manager.h"
+#include "pbd/sndfile_manager.h"
namespace ARDOUR {
diff --git a/libs/gtkmm2ext/actions.cc b/libs/gtkmm2ext/actions.cc
index 1145987764..bff718e9b7 100644
--- a/libs/gtkmm2ext/actions.cc
+++ b/libs/gtkmm2ext/actions.cc
@@ -21,6 +21,7 @@
#include <vector>
#include <string>
#include <list>
+#include <stdint.h>
#include <gtk/gtkaccelmap.h>
#include <gtk/gtkuimanager.h>
@@ -32,6 +33,7 @@
#include "pbd/error.h"
#include "gtkmm2ext/actions.h"
+#include "gtkmm2ext/utils.h"
#include "i18n.h"
@@ -40,6 +42,7 @@ using namespace Gtk;
using namespace Glib;
using namespace sigc;
using namespace PBD;
+using namespace Gtkmm2ext;
RefPtr<UIManager> ActionManager::ui_manager;
string ActionManager::unbound_string = "--";
@@ -294,3 +297,17 @@ ActionManager::uncheck_toggleaction (const char * name)
delete [] group_name;
}
+
+string
+ActionManager::get_key_representation (const string& accel_path, AccelKey& key)
+{
+ bool known = lookup_entry (accel_path, key);
+
+ if (known) {
+ uint32_t k = possibly_translate_legal_accelerator_to_real_key (key.get_key());
+ key = AccelKey (k, Gdk::ModifierType (key.get_mod()));
+ return ui_manager->get_accel_group()->name (key.get_key(), Gdk::ModifierType (key.get_mod()));
+ }
+
+ return unbound_string;
+}
diff --git a/libs/gtkmm2ext/gtkmm2ext/motionfeedback.h b/libs/gtkmm2ext/gtkmm2ext/motionfeedback.h
index b93357cdc1..a567c7d408 100644
--- a/libs/gtkmm2ext/gtkmm2ext/motionfeedback.h
+++ b/libs/gtkmm2ext/gtkmm2ext/motionfeedback.h
@@ -65,6 +65,8 @@ class MotionFeedback : public Gtk::VBox
void set_controllable (boost::shared_ptr<PBD::Controllable> c) { binding_proxy.set_controllable (c); }
void set_lamp_color (const Gdk::Color&);
+ void render_file (const std::string& path, int width, int height);
+
protected:
gfloat _range;
gfloat _lower;
diff --git a/libs/gtkmm2ext/gtkmm2ext/utils.h b/libs/gtkmm2ext/gtkmm2ext/utils.h
index d6d5a9498c..f4ddacd409 100644
--- a/libs/gtkmm2ext/gtkmm2ext/utils.h
+++ b/libs/gtkmm2ext/gtkmm2ext/utils.h
@@ -22,6 +22,7 @@
#include <vector>
#include <string>
+#include <stdint.h>
#include <gtkmm/treeview.h>
#include <gdkmm/window.h> /* for WMDecoration */
@@ -71,6 +72,9 @@ namespace Gtkmm2ext {
void set_treeview_header_as_default_label(Gtk::TreeViewColumn *c);
Glib::RefPtr<Gdk::Drawable> get_bogus_drawable();
void detach_menu (Gtk::Menu&);
+
+ bool possibly_translate_keyval_to_make_legal_accelerator (uint32_t& keyval);
+ uint32_t possibly_translate_legal_accelerator_to_real_key (uint32_t keyval);
};
#endif /* __gtkmm2ext_utils_h__ */
diff --git a/libs/gtkmm2ext/mfimg.cc b/libs/gtkmm2ext/mfimg.cc
new file mode 100644
index 0000000000..12a79fc6c5
--- /dev/null
+++ b/libs/gtkmm2ext/mfimg.cc
@@ -0,0 +1,16 @@
+#include <cstdlib>
+#include <gtkmm.h>
+#include "gtkmm2ext/motionfeedback.h"
+
+using namespace std;
+using namespace Gtkmm2ext;
+
+int
+main (int argc, char* argv[])
+{
+ Gtk::Main app (&argc, &argv);
+ int size = atoi (argv[1]);
+ Glib::RefPtr<Gdk::Pixbuf> pb;
+ MotionFeedback mf (pb, MotionFeedback::Rotary, 0, 0, false, size, size);
+ mf.render_file (argv[2], size, size);
+}
diff --git a/libs/gtkmm2ext/motionfeedback.cc b/libs/gtkmm2ext/motionfeedback.cc
index 81f856c2a4..683d1befa4 100644
--- a/libs/gtkmm2ext/motionfeedback.cc
+++ b/libs/gtkmm2ext/motionfeedback.cc
@@ -37,7 +37,9 @@ MotionFeedback::MotionFeedback (Glib::RefPtr<Gdk::Pixbuf> pix,
Type t,
const char *widget_name,
Adjustment *adj,
- bool with_numeric_display, int subw, int subh)
+ bool with_numeric_display,
+ int subw,
+ int subh)
: type (t)
, value_packer (0)
, value (0)
@@ -351,7 +353,7 @@ MotionFeedback::core_draw (cairo_t* cr, int phase, double radius, double x, doub
g_return_if_fail (cr != NULL);
- cairo_set_source_rgba (cr, 0.75, 0.75, 0.75, (double) 0);
+ cairo_set_source_rgba (cr, 0.75, 0.75, 0.75, (double) 1.0);
cairo_rectangle (cr, (double) 0, (double) 0, subwidth, subheight);
cairo_fill (cr);
@@ -536,7 +538,6 @@ MotionFeedback::core_draw (cairo_t* cr, int phase, double radius, double x, doub
bool
MotionFeedback::pixwin_expose_event (GdkEventExpose* ev)
{
- // GtkWidget* widget = GTK_WIDGET(pixwin.gobj());
GdkWindow *window = pixwin.get_window()->gobj();
GtkAdjustment* adj = adjustment->gobj();
@@ -570,22 +571,23 @@ MotionFeedback::pixwin_expose_event (GdkEventExpose* ev)
phase = (phase + 63) % 64;
}
-#if 1
- cairo_t* cr = gdk_cairo_create (GDK_DRAWABLE (window));
-
- gdk_cairo_rectangle (cr, &ev->area);
- cairo_clip (cr);
-
- core_draw (cr, phase, subheight/2, subwidth/2, subheight/2);
- cairo_destroy (cr);
-
-#else
-
- gdk_draw_pixbuf (GDK_DRAWABLE(window), widget->style->fg_gc[0],
- pixbuf->gobj(),
- phase * subwidth, type * subheight,
- 0, 0, subwidth, subheight, GDK_RGB_DITHER_NORMAL, 0, 0);
-#endif
+ if (pixbuf) {
+ std::cerr << "Render from pixbuf\n";
+ GtkWidget* widget = GTK_WIDGET(pixwin.gobj());
+ gdk_draw_pixbuf (GDK_DRAWABLE(window), widget->style->fg_gc[0],
+ pixbuf->gobj(),
+ phase * subwidth, type * subheight,
+ 0, 0, subwidth, subheight, GDK_RGB_DITHER_NORMAL, 0, 0);
+ } else {
+ std::cerr << "Render with cairo\n";
+ cairo_t* cr = gdk_cairo_create (GDK_DRAWABLE (window));
+
+ gdk_cairo_rectangle (cr, &ev->area);
+ cairo_clip (cr);
+
+ core_draw (cr, phase, subheight/2, subwidth/2, subheight/2);
+ cairo_destroy (cr);
+ }
return true;
}
@@ -644,3 +646,37 @@ MotionFeedback::set_lamp_color (const Gdk::Color& c)
prolooks_hsv_set_value (lamp_hsv, 0.67);
lamp_dark = (prolooks_hsv_to_gdk_color (lamp_hsv, &col3), col3);
}
+
+void
+MotionFeedback::render_file (const std::string& path, int w, int h)
+{
+ GdkPixmap* pixmap = gdk_pixmap_new (0, w, h, 24);
+ GdkPixbuf* pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 1, 8, w * 65, h);
+ GError* err = 0;
+ GdkRectangle r;
+
+ r.x = 0;
+ r.y = 0;
+ r.width = w;
+ r.height = h;
+
+ set_lamp_color (Gdk::Color ("#b9feff"));
+
+ for (int i = 0; i < 65; ++i) {
+ cairo_t* cr = gdk_cairo_create (GDK_DRAWABLE (pixmap));
+ gdk_cairo_rectangle (cr, &r);
+ cairo_clip (cr);
+ core_draw (cr, i, h/2, w/2, h/2);
+ gdk_pixbuf_get_from_drawable (pixbuf, pixmap, gdk_colormap_get_system(), 0, 0, w*i, 0, w, h);
+ cairo_destroy (cr);
+ }
+
+ if (gdk_pixbuf_save (pixbuf, path.c_str(), "png", &err, 0)) {
+ if (err) {
+ std::cerr << "could not save image set to " << path << ": " << err->message << std::endl;
+ }
+ }
+
+ g_object_unref (G_OBJECT (pixbuf));
+ g_object_unref (G_OBJECT (pixmap));
+}
diff --git a/libs/gtkmm2ext/utils.cc b/libs/gtkmm2ext/utils.cc
index d558ce8099..4e45cdb8b7 100644
--- a/libs/gtkmm2ext/utils.cc
+++ b/libs/gtkmm2ext/utils.cc
@@ -156,3 +156,86 @@ Gtkmm2ext::detach_menu (Gtk::Menu& menu)
}
}
}
+
+bool
+Gtkmm2ext::possibly_translate_keyval_to_make_legal_accelerator (uint32_t& keyval)
+{
+ int fakekey = GDK_VoidSymbol;
+
+ switch (keyval) {
+ case GDK_Tab:
+ case GDK_ISO_Left_Tab:
+ fakekey = GDK_nabla;
+ break;
+
+ case GDK_Up:
+ fakekey = GDK_uparrow;
+ break;
+
+ case GDK_Down:
+ fakekey = GDK_downarrow;
+ break;
+
+ case GDK_Right:
+ fakekey = GDK_rightarrow;
+ break;
+
+ case GDK_Left:
+ fakekey = GDK_leftarrow;
+ break;
+
+ case GDK_Return:
+ fakekey = GDK_3270_Enter;
+ break;
+
+ case GDK_KP_Enter:
+ fakekey = GDK_F35;
+ break;
+
+ default:
+ break;
+ }
+
+ if (fakekey != GDK_VoidSymbol) {
+ keyval = fakekey;
+ return true;
+ }
+
+ return false;
+}
+
+uint32_t
+Gtkmm2ext::possibly_translate_legal_accelerator_to_real_key (uint32_t keyval)
+{
+ switch (keyval) {
+ case GDK_nabla:
+ return GDK_Tab;
+ break;
+
+ case GDK_uparrow:
+ return GDK_Up;
+ break;
+
+ case GDK_downarrow:
+ return GDK_Down;
+ break;
+
+ case GDK_rightarrow:
+ return GDK_Right;
+ break;
+
+ case GDK_leftarrow:
+ return GDK_Left;
+ break;
+
+ case GDK_3270_Enter:
+ return GDK_Return;
+
+ case GDK_F35:
+ return GDK_KP_Enter;
+ break;
+ }
+
+ return keyval;
+}
+
diff --git a/libs/gtkmm2ext/wscript b/libs/gtkmm2ext/wscript
index dc8dbff76f..30e4400056 100644
--- a/libs/gtkmm2ext/wscript
+++ b/libs/gtkmm2ext/wscript
@@ -91,6 +91,16 @@ def build(bld):
else:
obj.source += ['gtkapplication_x11.c']
+ mfimg = bld.new_task_gen(features = 'cc cxx cprogram')
+ mfimg.source = 'mfimg.cc'
+ mfimg.export_incdirs = ['.']
+ mfimg.includes = ['.']
+ mfimg.name = 'mfimg'
+ mfimg.target = 'mfimg'
+ mfimg.uselib = 'GTKMM GTK GTKOSX OSX GDK'
+ mfimg.uselib_local = 'libpbd libgtkmm2ext'
+ mfimg.ldflags = [ '-lpthread', '-lrt', '-lsndfile' ]
+
def shutdown():
autowaf.shutdown()
diff --git a/libs/pbd/file_manager.cc b/libs/pbd/file_manager.cc
index 25d171b959..1ababb79bb 100644
--- a/libs/pbd/file_manager.cc
+++ b/libs/pbd/file_manager.cc
@@ -24,6 +24,7 @@
#include <fcntl.h>
#include <cassert>
#include <iostream>
+#include <cstdio>
#include "pbd/compose.h"
#include "pbd/file_manager.h"
#include "pbd/debug.h"
@@ -33,32 +34,6 @@ using namespace PBD;
FileManager* FileDescriptor::_manager;
-namespace PBD {
-
-/** Class to limit the number of files held open */
-class FileManager
-{
-public:
- FileManager ();
-
- void add (FileDescriptor *);
- void remove (FileDescriptor *);
-
- void release (FileDescriptor *);
- bool allocate (FileDescriptor *);
-
-private:
-
- void close (FileDescriptor *);
-
- std::list<FileDescriptor*> _files; ///< files we know about
- Glib::Mutex _mutex; ///< mutex for _files, _open and FileDescriptor contents
- int _open; ///< number of open files
- int _max_open; ///< maximum number of open files
-};
-
-}
-
FileManager::FileManager ()
: _open (0)
{
@@ -207,64 +182,6 @@ FileDescriptor::release ()
manager()->release (this);
}
-/** @param n Filename.
- * @param w true to open writeable, otherwise false.
- * @param i SF_INFO for the file.
- */
-
-SndFileDescriptor::SndFileDescriptor (string const & n, bool w, SF_INFO* i)
- : FileDescriptor (n, w)
- , _sndfile (0)
- , _info (i)
-{
- manager()->add (this);
-}
-
-SndFileDescriptor::~SndFileDescriptor ()
-{
- manager()->remove (this);
-}
-
-/** @return SNDFILE*, or 0 on error */
-SNDFILE*
-SndFileDescriptor::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 _sndfile;
-}
-
-void
-SndFileDescriptor::close ()
-{
- /* we must have a lock on the FileManager's mutex */
-
- sf_close (_sndfile);
- _sndfile = 0;
-}
-
-bool
-SndFileDescriptor::is_open () const
-{
- /* we must have a lock on the FileManager's mutex */
-
- return _sndfile != 0;
-}
-
-bool
-SndFileDescriptor::open ()
-{
- /* we must have a lock on the FileManager's mutex */
-
- _sndfile = sf_open (_name.c_str(), _writeable ? SFM_RDWR : SFM_READ, _info);
- return (_sndfile == 0);
-}
/** @param n Filename.
diff --git a/libs/pbd/pbd/file_manager.h b/libs/pbd/pbd/file_manager.h
index 3f708eb44e..2d3650c2c5 100644
--- a/libs/pbd/pbd/file_manager.h
+++ b/libs/pbd/pbd/file_manager.h
@@ -23,7 +23,7 @@
#include <sys/types.h>
#include <string>
#include <map>
-#include <sndfile.h>
+#include <list>
#include <glibmm/thread.h>
#include "pbd/signals.h"
@@ -81,26 +81,6 @@ 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
@@ -144,6 +124,29 @@ private:
std::string _mode;
};
+
+/** Class to limit the number of files held open */
+class FileManager
+{
+public:
+ FileManager ();
+
+ void add (FileDescriptor *);
+ void remove (FileDescriptor *);
+
+ void release (FileDescriptor *);
+ bool allocate (FileDescriptor *);
+
+private:
+
+ void close (FileDescriptor *);
+
+ std::list<FileDescriptor*> _files; ///< files we know about
+ Glib::Mutex _mutex; ///< mutex for _files, _open and FileDescriptor contents
+ int _open; ///< number of open files
+ int _max_open; ///< maximum number of open files
+};
+
}
#endif
diff --git a/libs/pbd/pbd/sndfile_manager.h b/libs/pbd/pbd/sndfile_manager.h
new file mode 100644
index 0000000000..a73f8cfd44
--- /dev/null
+++ b/libs/pbd/pbd/sndfile_manager.h
@@ -0,0 +1,56 @@
+/*
+ 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 __pbd_sndfile_manager_h__
+#define __pbd_sndfile_manager_h__
+
+#include <sys/types.h>
+#include <string>
+#include <map>
+#include <sndfile.h>
+#include <glibmm/thread.h>
+#include "pbd/signals.h"
+#include "pbd/file_manager.h"
+
+namespace PBD {
+
+/** 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
+};
+
+}
+
+#endif /* __pbd_sndfile_manager_h__ */
diff --git a/libs/pbd/sndfile_manager.cc b/libs/pbd/sndfile_manager.cc
new file mode 100644
index 0000000000..5637de26ee
--- /dev/null
+++ b/libs/pbd/sndfile_manager.cc
@@ -0,0 +1,92 @@
+/*
+ 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.
+
+*/
+
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <cassert>
+#include <iostream>
+#include "pbd/compose.h"
+#include "pbd/sndfile_manager.h"
+#include "pbd/debug.h"
+
+using namespace std;
+using namespace PBD;
+
+/** @param n Filename.
+ * @param w true to open writeable, otherwise false.
+ * @param i SF_INFO for the file.
+ */
+
+SndFileDescriptor::SndFileDescriptor (string const & n, bool w, SF_INFO* i)
+ : FileDescriptor (n, w)
+ , _sndfile (0)
+ , _info (i)
+{
+ manager()->add (this);
+}
+
+SndFileDescriptor::~SndFileDescriptor ()
+{
+ manager()->remove (this);
+}
+
+/** @return SNDFILE*, or 0 on error */
+SNDFILE*
+SndFileDescriptor::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 _sndfile;
+}
+
+void
+SndFileDescriptor::close ()
+{
+ /* we must have a lock on the FileManager's mutex */
+
+ sf_close (_sndfile);
+ _sndfile = 0;
+}
+
+bool
+SndFileDescriptor::is_open () const
+{
+ /* we must have a lock on the FileManager's mutex */
+
+ return _sndfile != 0;
+}
+
+bool
+SndFileDescriptor::open ()
+{
+ /* we must have a lock on the FileManager's mutex */
+
+ _sndfile = sf_open (_name.c_str(), _writeable ? SFM_RDWR : SFM_READ, _info);
+ return (_sndfile == 0);
+}
+
diff --git a/libs/pbd/wscript b/libs/pbd/wscript
index 73d6c3023c..7052ad98ca 100644
--- a/libs/pbd/wscript
+++ b/libs/pbd/wscript
@@ -83,6 +83,7 @@ def build(bld):
search_path.cc
shortpath.cc
signals.cc
+ sndfile_manager.cc
stacktrace.cc
stateful_diff_command.cc
stateful.cc