21 #include "libardour-config.h"
31 #ifdef PLATFORM_WINDOWS
32 #include <glibmm/convert.h>
34 #include <glibmm/fileutils.h>
35 #include <glibmm/miscutils.h>
39 #include "ardour/utils.h"
49 gain_t* SndFileSource::out_coefficient = 0;
50 gain_t* SndFileSource::in_coefficient = 0;
55 Source::RemovableIfEmpty |
63 , _capture_start (false)
64 , _capture_end (false)
70 assert (Glib::file_test (
_path, Glib::FILE_TEST_EXISTS));
87 , _capture_start (false)
88 , _capture_end (false)
96 assert (Glib::file_test (
_path, Glib::FILE_TEST_EXISTS));
112 , _broadcast_info (0)
113 , _capture_start (false)
114 , _capture_end (false)
122 assert (!Glib::file_test (
_path, Glib::FILE_TEST_EXISTS));
134 fmt = SF_FORMAT_AIFF;
162 fmt |= SF_FORMAT_FLOAT;
166 fmt |= SF_FORMAT_PCM_24;
170 fmt |= SF_FORMAT_PCM_16;
175 _info.samplerate = rate;
198 , _broadcast_info (0)
199 , _capture_start (false)
200 , _capture_end (false)
208 assert (Glib::file_test (
_path, Glib::FILE_TEST_EXISTS));
251 #ifdef PLATFORM_WINDOWS
252 path_to_open = Glib::locale_from_utf8(
_path);
254 path_to_open =
_path;
261 sf_error_str (0, errbuf,
sizeof (errbuf) - 1);
262 #ifndef HAVE_COREAUDIO
267 cerr <<
"failed to open " << path_to_open <<
" with name " <<
_name << endl;
270 path_to_open, (
writable() ?
"read+write" :
"reading"), errbuf) <<
endmsg;
276 #ifndef HAVE_COREAUDIO
304 if (
_length != 0 && !bwf_info_exists) {
314 if (bwf_info_exists) {
319 sf_command (
_sndfile, SFC_SET_UPDATE_HEADER_AUTO, 0, SF_FALSE);
331 error <<
string_compose (
_(
"cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"),
354 return _info.samplerate;
369 memset (dst, 0,
sizeof (
Sample) * cnt);
373 if (const_cast<SndFileSource*>(
this)->
open()) {
384 }
else if (start + cnt >
_length) {
397 assert (file_cnt >= 0);
399 if (file_cnt != cnt) {
401 memset (dst+file_cnt, 0,
sizeof (
Sample) * delta);
406 if (sf_seek (
_sndfile, (sf_count_t) start, SEEK_SET|SFM_READ) != (sf_count_t) start) {
408 sf_error_str (0, errbuf,
sizeof (errbuf) - 1);
413 if (
_info.channels == 1) {
415 if (ret != file_cnt) {
417 sf_error_str (0, errbuf,
sizeof (errbuf) - 1);
418 error <<
string_compose(
_(
"SndFileSource: @ %1 could not read %2 within %3 (%4) (len = %5, ret was %6)"), start, file_cnt,
_name.
val().substr (1), errbuf,
_length, ret) << endl;
424 real_cnt = cnt *
_info.channels;
428 nread = sf_read_float (
_sndfile, interleave_buf, real_cnt);
430 nread /=
_info.channels;
436 ptr +=
_info.channels;
464 if (
_info.channels != 1) {
510 if (
crossfade (data, subcnt, 1) != subcnt) {
515 Sample * tmpdata = data + subcnt;
518 subcnt = cnt - subcnt;
519 if (
crossfade (tmpdata, subcnt, 0) != subcnt) {
601 int const r = sf_command (
_sndfile, SFC_UPDATE_HEADER_NOW, 0, 0) != SF_TRUE;
661 error <<
string_compose (
_(
"cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"),
673 if (
_sndfile == 0 || sf_seek (
_sndfile, frame_pos, SEEK_SET|SFM_WRITE) < 0) {
675 sf_error_str (0, errbuf,
sizeof (errbuf) - 1);
680 if (sf_writef_float (
_sndfile, data, cnt) != (ssize_t) cnt) {
756 fade_data = data + nofade;
765 }
else if (fade_position + xfade >
_length) {
769 file_cnt =
_length - fade_position;
781 if (retval >= 0 && errno == EAGAIN) {
792 if (file_cnt != xfade) {
797 if (nofade && !fade_in) {
814 for (n = 0; n < xfade; ++n) {
823 for (n = 0; n < xfade; ++n) {
830 std::vector<gain_t> in(xfade);
831 std::vector<gain_t> out(xfade);
854 if (fade_in && nofade) {
927 if ((sf = sf_open (const_cast<char*>(path.c_str()), SFM_READ, &sf_info)) == 0) {
929 error_msg = sf_error_str (0, errbuf,
sizeof (errbuf) - 1);
935 info.
length = sf_info.frames;
940 if (major.length() + minor.length() < 16) {
946 info.
timecode = binfo.load_from_file (sf) ? binfo.get_time_reference() : 0;
956 return _info.channels > 1;
962 int const type =
_info.format & SF_FORMAT_TYPEMASK;
963 int const sub =
_info.format & SF_FORMAT_SUBMASK;
965 return (sub != SF_FORMAT_FLOAT && sub != SF_FORMAT_DOUBLE && type != SF_FORMAT_OGG);
bool set_destructive(bool yn)
static int get_soundfile_info(const std::string &path, SoundFileInfo &_info, std::string &error_msg)
ARDOUR::Session & _session
LIBPBD_API Transmitter fatal
framecnt_t write_unlocked(Sample *dst, framecnt_t cnt)
void set_from_session(Session const &session, int64_t time_ref)
LIBARDOUR_API void compute_equal_power_fades(ARDOUR::framecnt_t nframes, float *in, float *out)
static bool _build_peakfiles
void clear_capture_marks()
std::string sndfile_minor_format(int)
std::string sndfile_major_format(int)
static gain_t * out_coefficient
static framecnt_t header_position_offset
static framecnt_t xfade_frames
void set_originator_ref_from_session(Session const &)
static void setup_standard_crossfades(Session const &, framecnt_t sample_rate)
SndFileSource(Session &, const std::string &path, int chn, Flag flags)
LIBPBD_API Transmitter error
LIBPBD_API Transmitter warning
framepos_t _timeline_position
std::ostream & endmsg(std::ostream &ostr)
SessionConfiguration config
framecnt_t write_float(Sample *data, framepos_t pos, framecnt_t cnt)
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
bool clamped_at_unity() const
framepos_t last_capture_start_frame() const
void set_timeline_position(framepos_t)
void update_length(framecnt_t cnt)
virtual void set_timeline_position(framepos_t pos)
static gain_t * in_coefficient
framecnt_t crossfade(Sample *data, framecnt_t cnt, int dir)
static PBD::Signal0< void > HeaderPositionOffsetChanged
bool one_of_several_channels() const
framecnt_t destructive_write_unlocked(Sample *dst, framecnt_t cnt)
LIBARDOUR_API PBD::PropertyDescriptor< boost::shared_ptr< AutomationList > > fade_in
framepos_t capture_start_frame
framecnt_t nondestructive_write_unlocked(Sample *dst, framecnt_t cnt)
void set_path(const std::string &p)
int setup_broadcast_info(framepos_t when, struct tm &, time_t)
PBD::Property< std::string > _name
LIBPBD_API Transmitter info
static Sample * get_interleave_buffer(framecnt_t size)
void handle_header_position_change()
void set_header_timeline_position()
void mark_capture_start(framepos_t)
framepos_t natural_position() const
int update_header(framepos_t when, struct tm &, time_t)
virtual void set_path(const std::string &)
float sample_rate() const
BroadcastInfo * _broadcast_info
int compute_and_write_peaks(Sample *buf, framecnt_t first_frame, framecnt_t cnt, bool force, bool intermediate_peaks_ready_signal)
PBD::ScopedConnection header_position_connection
std::string string_compose(const std::string &fmt, const T1 &o1)
framecnt_t read_unlocked(Sample *dst, framepos_t start, framecnt_t cnt) const