summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour/source.h
blob: e8dadf57bdea7792f40c8eb897ce25da38396cce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
 * Copyright (C) 2006-2014 David Robillard <d@drobilla.net>
 * Copyright (C) 2006-2017 Paul Davis <paul@linuxaudiosystems.com>
 * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
 * Copyright (C) 2016-2019 Robin Gareus <robin@gareus.org>
 * Copyright (C) 2018-2019 Ben Loftis <ben@harrisonconsoles.com>
 *
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef __ardour_source_h__
#define __ardour_source_h__

#include <string>
#include <set>

#include <glibmm/threads.h>

#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/utility.hpp>
#include "pbd/statefuldestructible.h"

#include "ardour/ardour.h"
#include "ardour/session_object.h"
#include "ardour/data_type.h"

namespace ARDOUR {

class Session;

class LIBARDOUR_API Source : public SessionObject,
		public boost::enable_shared_from_this<ARDOUR::Source>
{
public:
	enum Flag {
		Writable = 0x1,
		CanRename = 0x2,
		Broadcast = 0x4,
		Removable = 0x8,
		RemovableIfEmpty = 0x10,
		RemoveAtDestroy = 0x20,
		NoPeakFile = 0x40,
		/* 0x80 was Destructive */
		Empty = 0x100, /* used for MIDI only */
		RF64_RIFF = 0x200,
		Missing = 0x400, /* used for MIDI only */
	};

	typedef Glib::Threads::Mutex::Lock Lock;

	Source (Session&, DataType type, const std::string& name, Flag flags=Flag(0));
	Source (Session&, const XMLNode&);

	virtual ~Source ();

	DataType type() { return _type; }

	time_t timestamp() const { return _timestamp; }
	void stamp (time_t when) { _timestamp = when; }

	virtual bool        empty () const = 0;
	virtual samplecnt_t length (samplepos_t pos) const = 0;
	virtual void        update_length (samplecnt_t cnt) = 0;

	void                 set_take_id (std::string id) { _take_id =id; }
	const std::string&   take_id ()        const { return _take_id; }

	void mark_for_remove();

	virtual void mark_streaming_write_started (const Lock& lock) {}
	virtual void mark_streaming_write_completed (const Lock& lock) = 0;

	virtual void session_saved() {}

	XMLNode& get_state ();
	int set_state (const XMLNode&, int version);

	bool         writable () const;

	virtual bool length_mutable() const    { return false; }

	static PBD::Signal1<void,Source*>             SourceCreated;

	bool has_been_analysed() const;
	virtual bool can_be_analysed() const { return false; }
	virtual void set_been_analysed (bool yn);
	virtual bool check_for_analysis_data_on_disk();

	PBD::Signal0<void> AnalysisChanged;

	AnalysisFeatureList transients;
	std::string get_transients_path() const;
	int load_transients (const std::string&);

	virtual samplepos_t natural_position() const { return _natural_position; }
	virtual void set_natural_position (samplepos_t pos);
	bool have_natural_position() const { return _have_natural_position; }

	void set_allow_remove_if_empty (bool yn);

	Glib::Threads::Mutex& mutex() { return _lock; }
	Flag flags() const { return _flags; }

	virtual void inc_use_count ();
	virtual void dec_use_count ();
	int  use_count() const { return g_atomic_int_get (const_cast<gint*>(&_use_count)); }
	bool used() const { return use_count() > 0; }

	uint32_t level() const { return _level; }

	std::string ancestor_name() { return _ancestor_name.empty() ? name() : _ancestor_name; }
	void set_ancestor_name(const std::string& name) { _ancestor_name = name; }

	void set_captured_for (std::string str) { _captured_for = str; }
	std::string captured_for() const { return _captured_for; }

	static PBD::Signal1<void,boost::shared_ptr<ARDOUR::Source> > SourcePropertyChanged;

  protected:
	DataType            _type;
	Flag                _flags;
	time_t              _timestamp;
	std::string         _take_id;
	samplepos_t          _natural_position;
	samplepos_t          _have_natural_position;
	bool                _analysed;
        mutable Glib::Threads::Mutex _lock;
        mutable Glib::Threads::Mutex _analysis_lock;
	gint                _use_count; /* atomic */
	uint32_t            _level; /* how deeply nested is this source w.r.t a disk file */
	std::string         _ancestor_name;
	std::string        _captured_for;

  private:
	void fix_writable_flags ();
};

}

#endif /* __ardour_source_h__ */