summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTaybin Rutkin <taybin@taybin.com>2005-12-09 14:16:02 +0000
committerTaybin Rutkin <taybin@taybin.com>2005-12-09 14:16:02 +0000
commit991a00f80a5012d36dfedc5227474b2b4612fbe4 (patch)
treebde03ec4a83bec38a31bac307c261d603538ebf7
parentcdd680f0b72a2081e05ad981d0467526310150c8 (diff)
Uploaded start of CoreAudioSource. More sfdb work.
git-svn-id: svn://localhost/trunk/ardour2@184 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/option_editor.cc12
-rw-r--r--gtk2_ardour/option_editor.h12
-rw-r--r--libs/ardour/ardour/coreaudio_source.h62
-rw-r--r--libs/ardour/coreaudio_source.cc203
4 files changed, 288 insertions, 1 deletions
diff --git a/gtk2_ardour/option_editor.cc b/gtk2_ardour/option_editor.cc
index 99dcbd0535..0a137f3c42 100644
--- a/gtk2_ardour/option_editor.cc
+++ b/gtk2_ardour/option_editor.cc
@@ -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);
diff --git a/gtk2_ardour/option_editor.h b/gtk2_ardour/option_editor.h
index 3cce36611d..77e55dce7a 100644
--- a/gtk2_ardour/option_editor.h
+++ b/gtk2_ardour/option_editor.h
@@ -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
index 0000000000..f62076497f
--- /dev/null
+++ b/libs/ardour/ardour/coreaudio_source.h
@@ -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
index 0000000000..91c69dab2f
--- /dev/null
+++ b/libs/ardour/coreaudio_source.cc
@@ -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);
+}