Uploaded start of CoreAudioSource. More sfdb work.
authorTaybin Rutkin <taybin@taybin.com>
Fri, 9 Dec 2005 14:16:02 +0000 (14:16 +0000)
committerTaybin Rutkin <taybin@taybin.com>
Fri, 9 Dec 2005 14:16:02 +0000 (14:16 +0000)
git-svn-id: svn://localhost/trunk/ardour2@184 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/option_editor.cc
gtk2_ardour/option_editor.h
libs/ardour/ardour/coreaudio_source.h [new file with mode: 0644]
libs/ardour/coreaudio_source.cc [new file with mode: 0644]

index 99dcbd05350dca5be80ccce9d3b6d281a1e5c25d..0a137f3c427022eb683c5141776c9e66ca66e094 100644 (file)
@@ -76,7 +76,10 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui)
          editor (ed),
          mixer (mixui),
 
-         path_table (9, 2),
+         /* Paths */
+         path_table (11, 2),
+         sfdb_paths(ListStore::create(sfdb_path_columns)),
+         sfdb_path_view(sfdb_paths),
 
          /* Fades */
 
@@ -422,6 +425,13 @@ OptionEditor::setup_path_options()
        path_table.attach (*label, 0, 1, 1, 2, FILL|EXPAND, FILL);
        path_table.attach (native_format_combo, 1, 3, 1, 2, Gtk::FILL|Gtk::EXPAND, FILL);
 
+       label = manage(new Label(_("Soundfile Search Paths")));
+       label->set_name("OptionsLabel");
+       path_table.attach(*label, 0, 1, 2, 3, FILL|EXPAND, FILL);
+       path_table.attach(sfdb_path_view, 1, 3, 2, 3, Gtk::FILL|Gtk::EXPAND, FILL);
+
+       sfdb_path_view.append_column(_("Paths"), sfdb_path_columns.paths);
+
        vector<string> nfstrings = internationalize (native_format_strings);
 
        set_popdown_strings (native_format_combo, nfstrings);
index 3cce36611dd5afd8625116bbf341be9339216232..77e55dce7a6aea08010258b7945f0f980f4751fe 100644 (file)
@@ -80,6 +80,18 @@ class OptionEditor : public Gtk::Dialog
 
        Gtk::ComboBoxText       native_format_combo;
 
+       Glib::RefPtr<Gtk::ListStore> sfdb_paths;
+       Gtk::TreeView sfdb_path_view;
+
+       struct SoundFilePathColumns : public Gtk::TreeModel::ColumnRecord
+       {
+         public:
+           Gtk::TreeModelColumn<std::string> paths;
+
+               SoundFilePathColumns() { add (paths); }
+       };
+       SoundFilePathColumns sfdb_path_columns;
+
        void setup_path_options();
        void add_session_paths ();
        void remove_session_paths ();
diff --git a/libs/ardour/ardour/coreaudio_source.h b/libs/ardour/ardour/coreaudio_source.h
new file mode 100644 (file)
index 0000000..f620764
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+    Copyright (C) 2000 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.
+
+    $Id$
+*/
+
+#ifndef __coreaudio_source_h__ 
+#define __coreaudio_source_h__
+
+#include <AudioToolbox/AudioFile.h>
+
+#include <ardour/source.h>
+
+namespace ARDOUR {
+
+class CoreAudioSource : public Source {
+  public:
+       CoreAudioSource (const string& path_plus_channel, bool build_peak = true);
+       CoreAudioSource (const XMLNode&);
+       ~CoreAudioSource ();
+
+       jack_nframes_t length() const { return _info.frames; }
+       jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const;
+       void           mark_for_remove() {} // we never remove external sndfiles 
+       string         peak_path(string audio_path);
+       string         old_peak_path(string audio_path);
+       string         path() const { return _path; }
+
+       static void set_peak_dir (string dir) { peak_dir = dir; }
+
+  private:
+       static string peak_dir;
+
+       AudioFileID sf;
+       uint16_t channel;
+       mutable float *tmpbuf;
+       mutable jack_nframes_t tmpbufsize;
+       mutable PBD::Lock _tmpbuf_lock;
+       string  _path;
+
+       void init (const string &str, bool build_peak);
+       jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const;
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __coreaudio_source_h__ */
+
diff --git a/libs/ardour/coreaudio_source.cc b/libs/ardour/coreaudio_source.cc
new file mode 100644 (file)
index 0000000..91c69da
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+    Copyright (C) 2000 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.
+
+    $Id$
+*/
+
+#include <string>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include <pbd/mountpoint.h>
+#include <ardour/coreaudio_source.h>
+
+#include "i18n.h"
+
+using namespace ARDOUR;
+
+string CoreAudioSource::peak_dir = "";
+
+CoreAudioSource::CoreAudioSource (const XMLNode& node)
+       : Source (node)
+{
+       if (set_state (node)) {
+               throw failed_constructor();
+       }
+
+       init (_name, true);
+       SourceCreated (this); /* EMIT SIGNAL */
+}
+
+CoreAudioSource::CoreAudioSource (const string& idstr, bool build_peak)
+       : Source(build_peak)
+{
+       init (idstr, build_peak);
+
+       if (build_peak) {
+                SourceCreated (this); /* EMIT SIGNAL */
+       }
+}
+
+void 
+CoreAudioSource::init (const string& idstr, bool build_peak)
+{
+       string::size_type pos;
+       string file;
+
+       tmpbuf = 0;
+       tmpbufsize = 0;
+       sf = 0;
+
+       _name = idstr;
+
+       if ((pos = idstr.find_last_of (':')) == string::npos) {
+               channel = 0;
+               file = idstr;
+       } else {
+               channel = atoi (idstr.substr (pos+1).c_str());
+               file = idstr.substr (0, pos);
+       }
+
+       /* note that we temporarily truncated _id at the colon */
+       FSRef* ref;
+       OSStatus err = FSPathMakeRef (file.c_str(), ref, 0);
+       if (err) {
+               throw failed_constructor();
+       }
+       err = AudioFileOpen (ref, fsCurPerm, 0, sf);
+       if (err) {
+               throw failed_constructor();
+       }
+       
+       if (channel >= _info.channels) {
+               error << string_compose(_("CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel number"), _info.channels, channel) << endmsg;
+               sf_close (sf);
+               sf = 0;
+               throw failed_constructor();
+       }
+
+       _length = _info.frames;
+       _path = file;
+
+       if (build_peak) {
+               if (initialize_peakfile (false, file)) {
+                       sf_close (sf);
+                       sf = 0;
+                       throw failed_constructor ();
+               }
+       }
+}
+
+CoreAudioSource::~CoreAudioSource ()
+
+{
+        GoingAway (this); /* EMIT SIGNAL */
+
+       if (sf) {
+               sf_close (sf);
+       }
+
+       if (tmpbuf) {
+               delete [] tmpbuf;
+       }
+}
+
+jack_nframes_t
+CoreAudioSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const
+{
+       return read (dst, start, cnt);
+}
+
+jack_nframes_t
+CoreAudioSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const
+{
+       int32_t nread;
+       float *ptr;
+       uint32_t real_cnt;
+
+       if (sf_seek (sf, (off_t) start, SEEK_SET) < 0) {
+               char errbuf[256];
+               sf_error_str (0, errbuf, sizeof (errbuf) - 1);
+               error << string_compose(_("CoreAudioSource: could not seek to frame %1 within %2 (%3)"), start, _name.substr (1), errbuf) << endmsg;
+               return 0;
+       }
+
+       if (_info.channels == 1) {
+               jack_nframes_t ret = sf_read_float (sf, dst, cnt);
+               _read_data_count = cnt * sizeof(float);
+               return ret;
+       }
+
+       real_cnt = cnt * _info.channels;
+
+       {
+               LockMonitor lm (_tmpbuf_lock, __LINE__, __FILE__);
+               
+               if (tmpbufsize < real_cnt) {
+                       
+                       if (tmpbuf) {
+                               delete [] tmpbuf;
+                       }
+                       tmpbufsize = real_cnt;
+                       tmpbuf = new float[tmpbufsize];
+               }
+               
+               nread = sf_read_float (sf, tmpbuf, real_cnt);
+               ptr = tmpbuf + channel;
+               nread /= _info.channels;
+               
+               /* stride through the interleaved data */
+               
+               for (int32_t n = 0; n < nread; ++n) {
+                       dst[n] = *ptr;
+                       ptr += _info.channels;
+               }
+       }
+
+       _read_data_count = cnt * sizeof(float);
+               
+       return nread;
+}
+
+string
+CoreAudioSource::peak_path (string audio_path)
+{
+       /* XXX hardly bombproof! fix me */
+
+       struct stat stat_file;
+       struct stat stat_mount;
+
+       string mp = mountpoint (audio_path);
+
+       stat (audio_path.c_str(), &stat_file);
+       stat (mp.c_str(), &stat_mount);
+
+       char buf[32];
+       snprintf (buf, sizeof (buf), "%ld-%ld-%d.peak", stat_mount.st_ino, stat_file.st_ino, channel);
+
+       string res = peak_dir;
+       res += buf;
+
+       return res;
+}
+
+string
+CoreAudioSource::old_peak_path (string audio_path)
+{
+       return peak_path (audio_path);
+}