X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsndfilesource.cc;h=ab090381b4d27caea3a4d676b7e4910d3b109181;hb=44fd104ada0fbd8b76d34150e941d85d6de6f81b;hp=2885240a5193cee69a5c745ccc10d39ed9ff9322;hpb=f9f5ec85fbfd15d0008f70d4185a84eeadfd3891;p=ardour.git diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index 2885240a51..ab090381b4 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -15,9 +15,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ +#include #include #include @@ -26,7 +26,6 @@ #include #include - #include #include #include @@ -36,6 +35,7 @@ using namespace std; using namespace ARDOUR; using namespace PBD; +using Glib::ustring; gain_t* SndFileSource::out_coefficient = 0; gain_t* SndFileSource::in_coefficient = 0; @@ -44,24 +44,21 @@ const AudioFileSource::Flag SndFileSource::default_writable_flags = AudioFileSou AudioFileSource::Removable| AudioFileSource::RemovableIfEmpty| AudioFileSource::CanRename); - SndFileSource::SndFileSource (Session& s, const XMLNode& node) : AudioFileSource (s, node) { init (); - cerr << "SndFileSource @ " << _path << " channel = " << channel << endl; - if (open()) { throw failed_constructor (); } } -SndFileSource::SndFileSource (Session& s, string path, int chn, Flag flags) +SndFileSource::SndFileSource (Session& s, ustring path, int chn, Flag flags) /* files created this way are never writable or removable */ : AudioFileSource (s, path, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))) { - channel = chn; + _channel = chn; init (); @@ -70,7 +67,7 @@ SndFileSource::SndFileSource (Session& s, string path, int chn, Flag flags) } } -SndFileSource::SndFileSource (Session& s, string path, SampleFormat sfmt, HeaderFormat hf, nframes_t rate, Flag flags) +SndFileSource::SndFileSource (Session& s, ustring path, SampleFormat sfmt, HeaderFormat hf, nframes_t rate, Flag flags) : AudioFileSource (s, path, flags, sfmt, hf) { int fmt = 0; @@ -82,7 +79,7 @@ SndFileSource::SndFileSource (Session& s, string path, SampleFormat sfmt, Header */ file_is_new = true; - + switch (hf) { case CAF: fmt = SF_FORMAT_CAF; @@ -124,6 +121,10 @@ SndFileSource::SndFileSource (Session& s, string path, SampleFormat sfmt, Header case FormatInt24: fmt |= SF_FORMAT_PCM_24; break; + + case FormatInt16: + fmt |= SF_FORMAT_PCM_16; + break; } _info.channels = 1; @@ -172,20 +173,17 @@ SndFileSource::SndFileSource (Session& s, string path, SampleFormat sfmt, Header _flags = Flag (_flags & ~Broadcast); delete _broadcast_info; _broadcast_info = 0; - } - - } + } + } } void SndFileSource::init () { - string file; + ustring file; // lets try to keep the object initalizations here at the top xfade_buf = 0; - interleave_buf = 0; - interleave_bufsize = 0; sf = 0; _broadcast_info = 0; @@ -219,13 +217,21 @@ SndFileSource::open () if ((sf = sf_open (_path.c_str(), (writable() ? SFM_RDWR : SFM_READ), &_info)) == 0) { char errbuf[256]; sf_error_str (0, errbuf, sizeof (errbuf) - 1); +#ifndef HAVE_COREAUDIO + /* if we have CoreAudio, we will be falling back to that if libsndfile fails, + so we don't want to see this message. + */ + error << string_compose(_("SndFileSource: cannot open file \"%1\" for %2 (%3)"), _path, (writable() ? "read+write" : "reading"), errbuf) << endmsg; +#endif return -1; } - if (channel >= _info.channels) { - error << string_compose(_("SndFileSource: file only contains %1 channels; %2 is invalid as a channel number"), _info.channels, channel) << endmsg; + if (_channel >= _info.channels) { +#ifndef HAVE_COREAUDIO + error << string_compose(_("SndFileSource: file only contains %1 channels; %2 is invalid as a channel number"), _info.channels, _channel) << endmsg; +#endif sf_close (sf); sf = 0; return -1; @@ -240,7 +246,7 @@ SndFileSource::open () set_timeline_position (get_timecode_info (sf, _broadcast_info, timecode_info_exists)); - if (!timecode_info_exists) { + if (_length != 0 && !timecode_info_exists) { delete _broadcast_info; _broadcast_info = 0; _flags = Flag (_flags & ~Broadcast); @@ -270,10 +276,6 @@ SndFileSource::~SndFileSource () touch_peakfile (); } - if (interleave_buf) { - delete [] interleave_buf; - } - if (_broadcast_info) { delete _broadcast_info; } @@ -316,6 +318,11 @@ SndFileSource::read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const file_cnt = cnt; } + if (file_cnt != cnt) { + nframes_t delta = cnt - file_cnt; + memset (dst+file_cnt, 0, sizeof (Sample) * delta); + } + if (file_cnt) { if (sf_seek (sf, (sf_count_t) start, SEEK_SET|SFM_READ) != (sf_count_t) start) { @@ -332,24 +339,12 @@ SndFileSource::read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const } } - if (file_cnt != cnt) { - nframes_t delta = cnt - file_cnt; - memset (dst+file_cnt, 0, sizeof (Sample) * delta); - } - real_cnt = cnt * _info.channels; - if (interleave_bufsize < real_cnt) { - - if (interleave_buf) { - delete [] interleave_buf; - } - interleave_bufsize = real_cnt; - interleave_buf = new float[interleave_bufsize]; - } + Sample* interleave_buf = get_interleave_buffer (real_cnt); nread = sf_read_float (sf, interleave_buf, real_cnt); - ptr = interleave_buf + channel; + ptr = interleave_buf + _channel; nread /= _info.channels; /* stride through the interleaved data */ @@ -390,7 +385,7 @@ SndFileSource::nondestructive_write_unlocked (Sample *data, nframes_t cnt) nframes_t oldlen; int32_t frame_pos = _length; - + if (write_float (data, frame_pos, cnt) != cnt) { return 0; } @@ -399,28 +394,7 @@ SndFileSource::nondestructive_write_unlocked (Sample *data, nframes_t cnt) update_length (oldlen, cnt); if (_build_peakfiles) { - PeakBuildRecord *pbr = 0; - - if (pending_peak_builds.size()) { - pbr = pending_peak_builds.back(); - } - - if (pbr && pbr->frame + pbr->cnt == oldlen) { - - /* the last PBR extended to the start of the current write, - so just extend it again. - */ - pbr->cnt += cnt; - } else { - pending_peak_builds.push_back (new PeakBuildRecord (oldlen, cnt)); - } - - _peaks_built = false; - } - - - if (_build_peakfiles) { - queue_for_peaks (shared_from_this (), false); + compute_and_write_peaks (data, frame_pos, cnt, false, true); } _write_data_count = cnt; @@ -510,32 +484,12 @@ SndFileSource::destructive_write_unlocked (Sample* data, nframes_t cnt) old_file_pos = file_pos; update_length (file_pos, cnt); - file_pos += cnt; if (_build_peakfiles) { - PeakBuildRecord *pbr = 0; - - if (pending_peak_builds.size()) { - pbr = pending_peak_builds.back(); - } - - if (pbr && pbr->frame + pbr->cnt == old_file_pos) { - - /* the last PBR extended to the start of the current write, - so just extend it again. - */ - - pbr->cnt += cnt; - } else { - pending_peak_builds.push_back (new PeakBuildRecord (old_file_pos, cnt)); - } - - _peaks_built = false; + compute_and_write_peaks (data, file_pos, cnt, false, true); } - if (_build_peakfiles) { - queue_for_peaks (shared_from_this (), true); - } + file_pos += cnt; return cnt; } @@ -630,9 +584,6 @@ SndFileSource::set_header_timeline_position () delete _broadcast_info; _broadcast_info = 0; } - - - } nframes_t @@ -888,7 +839,7 @@ SndFileSource::set_timeline_position (int64_t pos) } int -SndFileSource::get_soundfile_info (string path, SoundFileInfo& info, string& error_msg) +SndFileSource::get_soundfile_info (const ustring& path, SoundFileInfo& info, string& error_msg) { SNDFILE *sf; SF_INFO sf_info; @@ -940,3 +891,10 @@ SndFileSource::get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& e ret |= (uint32_t) binfo->time_reference_low; return ret; } + +bool +SndFileSource::one_of_several_channels () const +{ + return _info.channels > 1; +} +