~ubuntu-branches/ubuntu/utopic/ardour3/utopic

« back to all changes in this revision

Viewing changes to libs/ardour/ardour/diskstream.h

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2013-09-21 19:05:02 UTC
  • Revision ID: package-import@ubuntu.com-20130921190502-8gsftrku6jnzhd7v
Tags: upstream-3.4~dfsg
ImportĀ upstreamĀ versionĀ 3.4~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (C) 2000-2006 Paul Davis
 
3
 
 
4
    This program is free software; you can redistribute it and/or modify
 
5
    it under the terms of the GNU General Public License as published by
 
6
    the Free Software Foundation; either version 2 of the License, or
 
7
    (at your option) any later version.
 
8
 
 
9
    This program is distributed in the hope that it will be useful,
 
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
    GNU General Public License for more details.
 
13
 
 
14
    You should have received a copy of the GNU General Public License
 
15
    along with this program; if not, write to the Free Software
 
16
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
 
 
18
*/
 
19
 
 
20
#ifndef __ardour_diskstream_h__
 
21
#define __ardour_diskstream_h__
 
22
 
 
23
#include <string>
 
24
#include <queue>
 
25
#include <map>
 
26
#include <vector>
 
27
#include <cmath>
 
28
#include <time.h>
 
29
 
 
30
#include <boost/utility.hpp>
 
31
 
 
32
#include "evoral/types.hpp"
 
33
 
 
34
#include "ardour/ardour.h"
 
35
#include "ardour/chan_count.h"
 
36
#include "ardour/session_object.h"
 
37
#include "ardour/types.h"
 
38
#include "ardour/utils.h"
 
39
#include "ardour/public_diskstream.h"
 
40
 
 
41
struct tm;
 
42
 
 
43
namespace ARDOUR {
 
44
 
 
45
class IO;
 
46
class Playlist;
 
47
class Processor;
 
48
class Source;
 
49
class Session;
 
50
class Track;
 
51
class Location;
 
52
class BufferSet;
 
53
 
 
54
/** Parent class for classes which can stream data to and from disk.
 
55
 *  These are used by Tracks to get playback and put recorded data.
 
56
 */
 
57
class Diskstream : public SessionObject, public PublicDiskstream
 
58
{
 
59
  public:
 
60
        enum Flag {
 
61
                Recordable  = 0x1,
 
62
                Hidden      = 0x2,
 
63
                Destructive = 0x4,
 
64
                NonLayered   = 0x8
 
65
        };
 
66
 
 
67
        Diskstream (Session &, const std::string& name, Flag f = Recordable);
 
68
        Diskstream (Session &, const XMLNode&);
 
69
        virtual ~Diskstream();
 
70
 
 
71
        virtual bool set_name (const std::string& str);
 
72
 
 
73
        boost::shared_ptr<ARDOUR::IO> io() const { return _io; }
 
74
        void set_track (ARDOUR::Track *);
 
75
 
 
76
        /** @return A number between 0 and 1, where 0 indicates that the playback buffer
 
77
         *  is dry (ie the disk subsystem could not keep up) and 1 indicates that the
 
78
         *  buffer is full.
 
79
         */
 
80
        virtual float playback_buffer_load() const = 0;
 
81
        virtual float capture_buffer_load() const = 0;
 
82
 
 
83
        void set_flag (Flag f)   { _flags = Flag (_flags | f); }
 
84
        void unset_flag (Flag f) { _flags = Flag (_flags & ~f); }
 
85
 
 
86
        AlignStyle  alignment_style() const { return _alignment_style; }
 
87
        AlignChoice alignment_choice() const { return _alignment_choice; }
 
88
        void       set_align_style (AlignStyle, bool force=false);
 
89
        void       set_align_choice (AlignChoice a, bool force=false);
 
90
 
 
91
        framecnt_t roll_delay() const { return _roll_delay; }
 
92
        void       set_roll_delay (framecnt_t);
 
93
 
 
94
        bool         record_enabled() const { return g_atomic_int_get (&_record_enabled); }
 
95
        virtual void set_record_enabled (bool yn) = 0;
 
96
 
 
97
        bool destructive() const { return _flags & Destructive; }
 
98
        virtual int set_destructive (bool /*yn*/) { return -1; }
 
99
        virtual int set_non_layered (bool /*yn*/) { return -1; }
 
100
        virtual bool can_become_destructive (bool& /*requires_bounce*/) const { return false; }
 
101
 
 
102
        bool           hidden()      const { return _flags & Hidden; }
 
103
        bool           recordable()  const { return _flags & Recordable; }
 
104
        bool           non_layered()  const { return _flags & NonLayered; }
 
105
        bool           reversed()    const { return _actual_speed < 0.0f; }
 
106
        double         speed()       const { return _visible_speed; }
 
107
 
 
108
        virtual void punch_in()  {}
 
109
        virtual void punch_out() {}
 
110
 
 
111
        void non_realtime_set_speed ();
 
112
        virtual void non_realtime_locate (framepos_t /*location*/) {};
 
113
        virtual void playlist_modified ();
 
114
 
 
115
        boost::shared_ptr<Playlist> playlist () { return _playlist; }
 
116
 
 
117
        virtual int use_playlist (boost::shared_ptr<Playlist>);
 
118
        virtual int use_new_playlist () = 0;
 
119
        virtual int use_copy_playlist () = 0;
 
120
 
 
121
        /** @return Start position of currently-running capture (in session frames) */
 
122
        framepos_t current_capture_start() const { return capture_start_frame; }
 
123
        framepos_t current_capture_end()   const { return capture_start_frame + capture_captured; }
 
124
        framepos_t get_capture_start_frame (uint32_t n = 0) const;
 
125
        framecnt_t get_captured_frames (uint32_t n = 0) const;
 
126
 
 
127
        ChanCount n_channels() { return _n_channels; }
 
128
 
 
129
        static framecnt_t disk_io_frames() { return disk_io_chunk_frames; }
 
130
        static void set_disk_io_chunk_frames (framecnt_t n) { disk_io_chunk_frames = n; }
 
131
 
 
132
        /* Stateful */
 
133
        virtual XMLNode& get_state(void);
 
134
        virtual int      set_state(const XMLNode&, int version);
 
135
 
 
136
        virtual void request_jack_monitors_input (bool) {}
 
137
        virtual void ensure_jack_monitors_input (bool) {}
 
138
 
 
139
        framecnt_t   capture_offset() const { return _capture_offset; }
 
140
        virtual void set_capture_offset ();
 
141
 
 
142
        bool slaved() const      { return _slaved; }
 
143
        void set_slaved(bool yn) { _slaved = yn; }
 
144
 
 
145
        int set_loop (Location *loc);
 
146
 
 
147
        std::list<boost::shared_ptr<Source> >& last_capture_sources () { return _last_capture_sources; }
 
148
 
 
149
        void handle_input_change (IOChange, void *src);
 
150
 
 
151
        void move_processor_automation (boost::weak_ptr<Processor>,
 
152
                        std::list<Evoral::RangeMove<framepos_t> > const &);
 
153
 
 
154
        /** For non-butler contexts (allocates temporary working buffers) */
 
155
        virtual int do_refill_with_alloc() = 0;
 
156
        virtual void set_block_size (pframes_t) = 0;
 
157
 
 
158
        bool pending_overwrite () const {
 
159
                return _pending_overwrite;
 
160
        }
 
161
 
 
162
        PBD::Signal0<void>            RecordEnableChanged;
 
163
        PBD::Signal0<void>            SpeedChanged;
 
164
        PBD::Signal0<void>            ReverseChanged;
 
165
        /* Emitted when this diskstream is set to use a different playlist */
 
166
        PBD::Signal0<void>            PlaylistChanged;
 
167
        PBD::Signal0<void>            AlignmentStyleChanged;
 
168
        PBD::Signal1<void,Location *> LoopSet;
 
169
 
 
170
        static PBD::Signal0<void>     DiskOverrun;
 
171
        static PBD::Signal0<void>     DiskUnderrun;
 
172
 
 
173
  protected:
 
174
        friend class Session;
 
175
        friend class Butler;
 
176
 
 
177
        /* the Session is the only point of access for these because they require
 
178
         * that the Session is "inactive" while they are called.
 
179
         */
 
180
 
 
181
        virtual void set_pending_overwrite (bool) = 0;
 
182
        virtual int  overwrite_existing_buffers () = 0;
 
183
        virtual int  internal_playback_seek (framecnt_t distance) = 0;
 
184
        virtual int  can_internal_playback_seek (framecnt_t distance) = 0;
 
185
        virtual void reset_write_sources (bool, bool force = false) = 0;
 
186
        virtual void non_realtime_input_change () = 0;
 
187
 
 
188
  protected:
 
189
        friend class Auditioner;
 
190
        virtual int  seek (framepos_t which_sample, bool complete_refill = false) = 0;
 
191
 
 
192
  protected:
 
193
        friend class Track;
 
194
 
 
195
    virtual int  process (BufferSet&, framepos_t transport_frame, pframes_t nframes, framecnt_t &, bool need_disk_signal) = 0;
 
196
    virtual frameoffset_t calculate_playback_distance (pframes_t nframes) = 0;
 
197
        virtual bool commit  (framecnt_t) = 0;
 
198
 
 
199
        //private:
 
200
 
 
201
        enum TransitionType {
 
202
                CaptureStart = 0,
 
203
                CaptureEnd
 
204
        };
 
205
 
 
206
        struct CaptureTransition {
 
207
                TransitionType   type;
 
208
                framepos_t       capture_val; ///< The start or end file frame position
 
209
        };
 
210
 
 
211
        /* The two central butler operations */
 
212
        virtual int do_flush (RunContext context, bool force = false) = 0;
 
213
        virtual int do_refill () = 0;
 
214
 
 
215
        /* XXX fix this redundancy ... */
 
216
 
 
217
        virtual void playlist_changed (const PBD::PropertyChange&);
 
218
        virtual void playlist_deleted (boost::weak_ptr<Playlist>);
 
219
        virtual void playlist_ranges_moved (std::list< Evoral::RangeMove<framepos_t> > const &, bool);
 
220
 
 
221
        virtual void transport_stopped_wallclock (struct tm&, time_t, bool abort) = 0;
 
222
        virtual void transport_looped (framepos_t transport_frame) = 0;
 
223
 
 
224
        struct CaptureInfo {
 
225
                framepos_t start;
 
226
                framecnt_t frames;
 
227
        };
 
228
 
 
229
        virtual int use_new_write_source (uint32_t n=0) = 0;
 
230
 
 
231
        virtual int find_and_use_playlist (const std::string&) = 0;
 
232
 
 
233
        virtual void allocate_temporary_buffers () = 0;
 
234
 
 
235
        virtual bool realtime_set_speed (double, bool global_change);
 
236
 
 
237
        std::list<boost::shared_ptr<Source> > _last_capture_sources;
 
238
 
 
239
        virtual int use_pending_capture_data (XMLNode& node) = 0;
 
240
 
 
241
        virtual void check_record_status (framepos_t transport_frame, bool can_record);
 
242
        virtual void prepare_record_status (framepos_t /*capture_start_frame*/) {}
 
243
        virtual void set_align_style_from_io() {}
 
244
        virtual void setup_destructive_playlist () {}
 
245
        virtual void use_destructive_playlist () {}
 
246
        virtual void prepare_to_stop (framepos_t pos);
 
247
 
 
248
        void engage_record_enable ();
 
249
        void disengage_record_enable ();
 
250
 
 
251
        virtual bool prep_record_enable () = 0;
 
252
        virtual bool prep_record_disable () = 0;
 
253
 
 
254
        void calculate_record_range (
 
255
                Evoral::OverlapType ot, framepos_t transport_frame, framecnt_t nframes,
 
256
                framecnt_t& rec_nframes, framecnt_t& rec_offset
 
257
                );
 
258
 
 
259
        static framecnt_t disk_io_chunk_frames;
 
260
        std::vector<CaptureInfo*> capture_info;
 
261
        mutable Glib::Threads::Mutex capture_info_lock;
 
262
 
 
263
        uint32_t i_am_the_modifier;
 
264
 
 
265
        boost::shared_ptr<ARDOUR::IO>  _io;
 
266
        Track*       _track;
 
267
        ChanCount    _n_channels;
 
268
 
 
269
        boost::shared_ptr<Playlist> _playlist;
 
270
 
 
271
        mutable gint _record_enabled;
 
272
        double       _visible_speed;
 
273
        double       _actual_speed;
 
274
        /* items needed for speed change logic */
 
275
        bool         _buffer_reallocation_required;
 
276
        bool         _seek_required;
 
277
 
 
278
        /** Start of currently running capture in session frames */
 
279
        framepos_t    capture_start_frame;
 
280
        framecnt_t    capture_captured;
 
281
        bool          was_recording;
 
282
        framecnt_t    adjust_capture_position;
 
283
        framecnt_t   _capture_offset;
 
284
        /** The number of frames by which this diskstream's output should be delayed
 
285
            with respect to the transport frame.  This is used for latency compensation.
 
286
        */
 
287
        framecnt_t   _roll_delay;
 
288
        framepos_t    first_recordable_frame;
 
289
        framepos_t    last_recordable_frame;
 
290
        int           last_possibly_recording;
 
291
        AlignStyle   _alignment_style;
 
292
        AlignChoice  _alignment_choice;
 
293
        bool         _slaved;
 
294
        Location*     loop_location;
 
295
        framepos_t    overwrite_frame;
 
296
        off_t         overwrite_offset;
 
297
        bool          _pending_overwrite;
 
298
        bool          overwrite_queued;
 
299
        IOChange      input_change_pending;
 
300
        framecnt_t    wrap_buffer_size;
 
301
        framecnt_t    speed_buffer_size;
 
302
 
 
303
        double        _speed;
 
304
        double        _target_speed;
 
305
 
 
306
        /** The next frame position that we should be reading from in our playlist */
 
307
        framepos_t     file_frame;
 
308
        framepos_t     playback_sample;
 
309
 
 
310
        bool          in_set_state;
 
311
 
 
312
        Glib::Threads::Mutex state_lock;
 
313
 
 
314
        PBD::ScopedConnectionList playlist_connections;
 
315
 
 
316
        PBD::ScopedConnection ic_connection;
 
317
 
 
318
        Flag _flags;
 
319
        XMLNode* deprecated_io_node;
 
320
 
 
321
        void route_going_away ();
 
322
};
 
323
 
 
324
}; /* namespace ARDOUR */
 
325
 
 
326
#endif /* __ardour_diskstream_h__ */