ardour
srcfilesource.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 Paul Davis
3  Written by: Robin Gareus <robin@gareus.org>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 
19 */
20 
21 #include "pbd/error.h"
22 #include "pbd/failed_constructor.h"
23 
24 #include "ardour/audiofilesource.h"
25 #include "ardour/debug.h"
26 #include "ardour/srcfilesource.h"
27 
28 #include "i18n.h"
29 
30 using namespace ARDOUR;
31 using namespace PBD;
32 
33 const uint32_t SrcFileSource::blocksize = 65536U; /* somewhat arbitrary */
34 
36  : Source(s, DataType::AUDIO, src->name(), Flag (src->flags() & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy)))
37  , AudioFileSource (s, src->path(), Flag (src->flags() & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy)))
38  , _source (src)
39  , _src_state (0)
40  , _source_position(0)
41  , _target_position(0)
42  , _fract_position(0)
43 {
44  assert(_source->n_channels() == 1);
45 
46  int src_type = SRC_SINC_BEST_QUALITY;
47 
48  switch (srcq) {
49  case SrcBest:
50  src_type = SRC_SINC_BEST_QUALITY;
51  break;
52  case SrcGood:
53  src_type = SRC_SINC_MEDIUM_QUALITY;
54  break;
55  case SrcQuick:
56  src_type = SRC_SINC_FASTEST;
57  break;
58  case SrcFast:
59  src_type = SRC_ZERO_ORDER_HOLD;
60  break;
61  case SrcFastest:
62  src_type = SRC_LINEAR;
63  break;
64  }
65 
66 
67  _ratio = s.nominal_frame_rate() / _source->sample_rate();
68  _src_data.src_ratio = _ratio;
69 
70  src_buffer_size = ceil((double)blocksize / _ratio) + 2;
71  _src_buffer = new float[src_buffer_size];
72 
73  int err;
74  if ((_src_state = src_new (src_type, 1, &err)) == 0) {
75  error << string_compose(_("Import: src_new() failed : %1"), src_strerror (err)) << endmsg ;
76  throw failed_constructor ();
77  }
78 }
79 
81 {
82  DEBUG_TRACE (DEBUG::AudioPlayback, "SrcFileSource::~SrcFileSource\n");
83  _src_state = src_delete (_src_state) ;
84  delete [] _src_buffer;
85 }
86 
87 void
89 {
91  if (fs) {
92  fs->close ();
93  }
94 }
95 
98 {
99  int err;
100  const double srccnt = cnt / _ratio;
101 
102  if (_target_position != start) {
103  DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("SRC: reset %1 -> %2\n", _target_position, start));
104  src_reset(_src_state);
105  _fract_position = 0;
106  _source_position = start / _ratio;
108  }
109 
110  const framecnt_t scnt = ceilf(srccnt - _fract_position);
111  _fract_position += (scnt - srccnt);
112 
113 #ifndef NDEBUG
114  if (scnt >= src_buffer_size) {
115  DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("SRC: CRASH AHEAD :) %1 >= %2 (fract=%3, cnt=%4)\n",
116  scnt, src_buffer_size, _fract_position, cnt));
117  }
118 #endif
119  assert(scnt < src_buffer_size);
120 
121  _src_data.input_frames = _source->read (_src_buffer, _source_position, scnt);
122 
123  if ((framecnt_t) _src_data.input_frames < scnt
124  || _source_position + scnt >= _source->length(0)) {
125  _src_data.end_of_input = true;
126  _target_position += _src_data.input_frames * _ratio;
127  DEBUG_TRACE (DEBUG::AudioPlayback, "SRC: END OF INPUT\n");
128  } else {
129  _src_data.end_of_input = false;
130  _target_position += cnt;
131  }
132 
133  _src_data.output_frames = cnt;
134  _src_data.data_in = _src_buffer;
135  _src_data.data_out = dst;
136 
137  if (_src_data.end_of_input) {
138  _src_data.output_frames = std::min ((long)floor(_src_data.input_frames * _ratio), _src_data.output_frames);
139  }
140 
141 
142  if ((err = src_process (_src_state, &_src_data))) {
143  error << string_compose(_("SrcFileSource: %1"), src_strerror (err)) << endmsg ;
144  return 0;
145  }
146 
147  if (_src_data.end_of_input && _src_data.output_frames_gen <= 0) {
148  return 0;
149  }
150 
151  _source_position += _src_data.input_frames_used;
152 
153  framepos_t saved_target = _target_position;
154  framecnt_t generated = _src_data.output_frames_gen;
155 
156  while (generated < cnt) {
157  DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("SRC: recurse for %1 samples\n", cnt - generated));
158  framecnt_t g = read_unlocked(dst + generated, _target_position, cnt - generated);
159  generated += g;
160  if (g == 0) break;
161  }
162  _target_position = saved_target;
163 
164  DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("SRC: in: %1-> want: %2 || got: %3 total: %4\n",
165  _src_data.input_frames, _src_data.output_frames, _src_data.output_frames_gen, generated));
166 
167  return generated;
168 }
framecnt_t nominal_frame_rate() const
Definition: session.h:367
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
static const uint32_t blocksize
Definition: srcfilesource.h:66
LIBPBD_API Transmitter error
framepos_t _target_position
Definition: srcfilesource.h:74
SrcQuality
Definition: types.h:522
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
LIBARDOUR_API uint64_t AudioPlayback
Definition: debug.cc:49
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
Definition: region.cc:63
SrcFileSource(Session &, boost::shared_ptr< AudioFileSource >, SrcQuality srcq=SrcQuality(SrcQuick))
virtual void close()=0
#define _(Text)
Definition: i18n.h:11
int64_t framecnt_t
Definition: types.h:76
float Sample
Definition: types.h:54
framepos_t _source_position
Definition: srcfilesource.h:73
Definition: amp.h:29
#define DEBUG_TRACE(bits, str)
Definition: debug.h:55
int64_t framepos_t
Definition: types.h:66
boost::shared_ptr< AudioFileSource > _source
Definition: srcfilesource.h:67
SRC_STATE * _src_state
Definition: srcfilesource.h:69
const char * name
Writable
Definition: selectable.h:36
Definition: debug.h:30
framecnt_t src_buffer_size
Definition: srcfilesource.h:78
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
framecnt_t read_unlocked(Sample *dst, framepos_t start, framecnt_t cnt) const