diff options
author | Taybin Rutkin <taybin@taybin.com> | 2005-12-09 14:16:02 +0000 |
---|---|---|
committer | Taybin Rutkin <taybin@taybin.com> | 2005-12-09 14:16:02 +0000 |
commit | 991a00f80a5012d36dfedc5227474b2b4612fbe4 (patch) | |
tree | bde03ec4a83bec38a31bac307c261d603538ebf7 | |
parent | cdd680f0b72a2081e05ad981d0467526310150c8 (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.cc | 12 | ||||
-rw-r--r-- | gtk2_ardour/option_editor.h | 12 | ||||
-rw-r--r-- | libs/ardour/ardour/coreaudio_source.h | 62 | ||||
-rw-r--r-- | libs/ardour/coreaudio_source.cc | 203 |
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); +} |