diff options
author | David Robillard <d@drobilla.net> | 2006-08-01 03:23:35 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2006-08-01 03:23:35 +0000 |
commit | 6f4a92f740b2fd75794489ce58f9348f8adf6bf4 (patch) | |
tree | 68ecd4d29bf7d1db00da9dfa9e14ac2e93ca1e42 /libs/ardour/ardour | |
parent | ba0c8bc2ef92a84b99040df46e76d8ac54d3d9da (diff) |
Heavy-duty abstraction work to split type-specific classes into
specializations of (new, for the most part) generic bases. (eg. most everything
from the MIDI branch except for actual MIDI things, so merges have a chance of
succeeding). Also the new edit toolbar, and various other cleanup things I did
along the way.
Should be functionally equivalent (except the toolbar), this is just design work.
She's a big'un....
git-svn-id: svn://localhost/ardour2/trunk@727 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r-- | libs/ardour/ardour/audio_diskstream.h | 276 | ||||
-rw-r--r-- | libs/ardour/ardour/audio_track.h | 113 | ||||
-rw-r--r-- | libs/ardour/ardour/audioengine.h | 5 | ||||
-rw-r--r-- | libs/ardour/ardour/audioplaylist.h | 3 | ||||
-rw-r--r-- | libs/ardour/ardour/audioregion.h | 85 | ||||
-rw-r--r-- | libs/ardour/ardour/buffer.h | 144 | ||||
-rw-r--r-- | libs/ardour/ardour/diskstream.h | 319 | ||||
-rw-r--r-- | libs/ardour/ardour/io.h | 26 | ||||
-rw-r--r-- | libs/ardour/ardour/playlist.h | 20 | ||||
-rw-r--r-- | libs/ardour/ardour/port.h | 73 | ||||
-rw-r--r-- | libs/ardour/ardour/region.h | 104 | ||||
-rw-r--r-- | libs/ardour/ardour/route.h | 5 | ||||
-rw-r--r-- | libs/ardour/ardour/route_group.h | 3 | ||||
-rw-r--r-- | libs/ardour/ardour/route_group_specialized.h | 6 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 69 | ||||
-rw-r--r-- | libs/ardour/ardour/session_diskstream.h | 42 | ||||
-rw-r--r-- | libs/ardour/ardour/track.h | 158 | ||||
-rw-r--r-- | libs/ardour/ardour/types.h | 6 |
18 files changed, 882 insertions, 575 deletions
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index 0a0c908d31..e2dfc5fd0c 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2000 Paul Davis + Copyright (C) 2000-2006 Paul Davis 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 @@ -14,12 +14,10 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: diskstream.h 579 2006-06-12 19:56:37Z essej $ */ -#ifndef __ardour_diskstream_h__ -#define __ardour_diskstream_h__ +#ifndef __ardour_audio_diskstream_h__ +#define __ardour_audio_diskstream_h__ #include <sigc++/signal.h> @@ -42,6 +40,8 @@ #include <ardour/route.h> #include <ardour/port.h> #include <ardour/utils.h> +#include <ardour/diskstream.h> +#include <ardour/audioplaylist.h> struct tm; @@ -54,53 +54,20 @@ class AudioPlaylist; class AudioFileSource; class IO; -class AudioDiskstream : public Stateful, public sigc::trackable +class AudioDiskstream : public Diskstream { public: - enum Flag { - Recordable = 0x1, - Hidden = 0x2, - Destructive = 0x4 - }; - - AudioDiskstream (Session &, const string& name, Flag f = Recordable); + AudioDiskstream (Session &, const string& name, Diskstream::Flag f = Recordable); AudioDiskstream (Session &, const XMLNode&); - string name() const { return _name; } - - ARDOUR::IO* io() const { return _io; } - void set_io (ARDOUR::IO& io); + const PBD::ID& id() const { return _id; } + // FIXME AudioDiskstream& ref() { _refcnt++; return *this; } - void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; } - uint32_t refcnt() const { return _refcnt; } float playback_buffer_load() const; float capture_buffer_load() const; - void set_flag (Flag f) { - _flags |= f; - } - - void unset_flag (Flag f) { - _flags &= ~f; - } - - AlignStyle alignment_style() const { return _alignment_style; } - void set_align_style (AlignStyle); - void set_persistent_align_style (AlignStyle); - - bool hidden() const { return _flags & Hidden; } - bool recordable() const { return _flags & Recordable; } - bool destructive() const { return _flags & Destructive; } - - void set_destructive (bool yn); - - jack_nframes_t roll_delay() const { return _roll_delay; } - void set_roll_delay (jack_nframes_t); - - int set_name (string str, void* src); - string input_source (uint32_t n=0) const { if (n < channels.size()) { return channels[n].source ? channels[n].source->name() : ""; @@ -113,14 +80,7 @@ class AudioDiskstream : public Stateful, public sigc::trackable if (n < channels.size()) return channels[n].source; return 0; } - void set_record_enabled (bool yn, void *src); - bool record_enabled() const { return g_atomic_int_get (&_record_enabled); } - void punch_in (); - void punch_out (); - - bool reversed() const { return _actual_speed < 0.0f; } - double speed() const { return _visible_speed; } - void set_speed (double); + void set_record_enabled (bool yn); float peak_power(uint32_t n=0) { float x = channels[n].peak_power; @@ -131,14 +91,13 @@ class AudioDiskstream : public Stateful, public sigc::trackable return minus_infinity(); } } + + AudioPlaylist* audio_playlist () { return dynamic_cast<AudioPlaylist*>(_playlist); } - int use_playlist (AudioPlaylist *); + int use_playlist (Playlist *); int use_new_playlist (); int use_copy_playlist (); - void start_scrub (jack_nframes_t where); - void end_scrub (); - Sample *playback_buffer (uint32_t n=0) { if (n < channels.size()) return channels[n].current_playback_buffer; @@ -151,51 +110,23 @@ class AudioDiskstream : public Stateful, public sigc::trackable return 0; } - AudioPlaylist *playlist () { return _playlist; } - AudioFileSource *write_source (uint32_t n=0) { if (n < channels.size()) return channels[n].write_source; return 0; } - jack_nframes_t current_capture_start() const { return capture_start_frame; } - jack_nframes_t current_capture_end() const { return capture_start_frame + capture_captured; } - jack_nframes_t get_capture_start_frame (uint32_t n=0); - jack_nframes_t get_captured_frames (uint32_t n=0); - - uint32_t n_channels() { return _n_channels; } - int add_channel (); int remove_channel (); - static void set_disk_io_chunk_frames (uint32_t n) { - disk_io_chunk_frames = n; - } - - static jack_nframes_t disk_io_frames() { return disk_io_chunk_frames; } - sigc::signal<void,void*> record_enable_changed; - sigc::signal<void> speed_changed; - sigc::signal<void,void*> reverse_changed; - sigc::signal<void> PlaylistChanged; - sigc::signal<void> AlignmentStyleChanged; - - static sigc::signal<void> DiskOverrun; - static sigc::signal<void> DiskUnderrun; - static sigc::signal<void,AudioDiskstream*> AudioDiskstreamCreated; // XXX use a ref with sigc2 - static sigc::signal<void,list<AudioFileSource*>*> DeleteSources; - /* stateful */ XMLNode& get_state(void); - int set_state(const XMLNode& node); + int set_state(const XMLNode& node); void monitor_input (bool); - jack_nframes_t capture_offset() const { return _capture_offset; } - void set_capture_offset (); - static void swap_by_ptr (Sample *first, Sample *last) { while (first < last) { Sample tmp = *first; @@ -212,19 +143,7 @@ class AudioDiskstream : public Stateful, public sigc::trackable } } - bool slaved() const { return _slaved; } - void set_slaved(bool yn) { _slaved = yn; } - - int set_loop (Location *loc); - sigc::signal<void,Location *> LoopSet; - - std::list<Region*>& last_capture_regions () { - return _last_capture_regions; - } - - void handle_input_change (IOChange, void *src); - - const PBD::ID& id() const { return _id; } + std::list<Region*>& last_capture_regions () { return _last_capture_regions; } XMLNode* deprecated_io_node; @@ -236,9 +155,8 @@ class AudioDiskstream : public Stateful, public sigc::trackable while they are called. */ - void set_pending_overwrite (bool); + void set_pending_overwrite(bool); int overwrite_existing_buffers (); - void reverse_scrub_buffer (bool to_forward); void set_block_size (jack_nframes_t); int internal_playback_seek (jack_nframes_t distance); int can_internal_playback_seek (jack_nframes_t distance); @@ -246,9 +164,6 @@ class AudioDiskstream : public Stateful, public sigc::trackable void reset_write_sources (bool, bool force = false); void non_realtime_input_change (); - uint32_t read_data_count() const { return _read_data_count; } - uint32_t write_data_count() const { return _write_data_count; } - protected: friend class Auditioner; int seek (jack_nframes_t which_sample, bool complete_refill = false); @@ -256,38 +171,23 @@ class AudioDiskstream : public Stateful, public sigc::trackable protected: friend class AudioTrack; - void prepare (); int process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input); bool commit (jack_nframes_t nframes); - void recover (); /* called if commit will not be called, but process was */ private: /* use unref() to destroy a diskstream */ - ~AudioDiskstream(); - enum TransitionType { - CaptureStart = 0, - CaptureEnd - }; - - struct CaptureTransition { - - TransitionType type; - // the start or end file frame pos - jack_nframes_t capture_val; - }; - struct ChannelInfo { Sample *playback_wrap_buffer; Sample *capture_wrap_buffer; Sample *speed_buffer; - float peak_power; + float peak_power; - AudioFileSource *fades_source; + AudioFileSource *fades_source; AudioFileSource *write_source; Port *source; @@ -309,129 +209,30 @@ class AudioDiskstream : public Stateful, public sigc::trackable jack_nframes_t curr_capture_cnt; }; - typedef vector<ChannelInfo> ChannelList; - - - string _name; - ARDOUR::Session& _session; - ARDOUR::IO* _io; - ChannelList channels; - uint32_t _n_channels; - PBD::ID _id; - - mutable gint _record_enabled; - AudioPlaylist* _playlist; - double _visible_speed; - double _actual_speed; - /* items needed for speed change logic */ - bool _buffer_reallocation_required; - bool _seek_required; - - bool force_refill; - jack_nframes_t capture_start_frame; - jack_nframes_t capture_captured; - bool was_recording; - jack_nframes_t adjust_capture_position; - jack_nframes_t _capture_offset; - jack_nframes_t _roll_delay; - jack_nframes_t first_recordable_frame; - jack_nframes_t last_recordable_frame; - int last_possibly_recording; - AlignStyle _alignment_style; - bool _scrubbing; - bool _slaved; - bool _processed; - Location* loop_location; - jack_nframes_t overwrite_frame; - off_t overwrite_offset; - bool pending_overwrite; - bool overwrite_queued; - IOChange input_change_pending; - jack_nframes_t wrap_buffer_size; - jack_nframes_t speed_buffer_size; - - uint64_t last_phase; - uint64_t phi; - - jack_nframes_t file_frame; - jack_nframes_t playback_sample; - jack_nframes_t playback_distance; - - uint32_t _read_data_count; - uint32_t _write_data_count; - - bool in_set_state; - AlignStyle _persistent_alignment_style; - bool first_input_change; - - Glib::Mutex state_lock; - - jack_nframes_t scrub_start; - jack_nframes_t scrub_buffer_size; - jack_nframes_t scrub_offset; - uint32_t _refcnt; - - sigc::connection ports_created_c; - sigc::connection plmod_connection; - sigc::connection plstate_connection; - sigc::connection plgone_connection; - - /* the two central butler operations */ - - int do_flush (char * workbuf, bool force = false); - int do_refill (Sample *mixdown_buffer, float *gain_buffer, char *workbuf); - - int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf, jack_nframes_t& start, jack_nframes_t cnt, - ChannelInfo& channel_info, int channel, bool reversed); - - uint32_t i_am_the_modifier; + /* The two central butler operations */ + int do_flush (Session::RunContext context, bool force = false); + int do_refill () { return _do_refill(_mixdown_buffer, _gain_buffer, _conversion_buffer); } - /* XXX fix this redundancy ... */ + int do_refill_with_alloc(); - void playlist_changed (Change); - void playlist_modified (); - void playlist_deleted (Playlist*); - void session_controls_changed (Session::ControlType); + int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf, + jack_nframes_t& start, jack_nframes_t cnt, + ChannelInfo& channel_info, int channel, bool reversed); void finish_capture (bool rec_monitors_input); - void clean_up_capture (struct tm&, time_t, bool abort); void transport_stopped (struct tm&, time_t, bool abort); - struct CaptureInfo { - uint32_t start; - uint32_t frames; - }; - - vector<CaptureInfo*> capture_info; - Glib::Mutex capture_info_lock; - - void init (Flag); + void init (Diskstream::Flag); void init_channel (ChannelInfo &chan); void destroy_channel (ChannelInfo &chan); - static jack_nframes_t disk_io_chunk_frames; - int use_new_write_source (uint32_t n=0); - int use_new_fade_source (uint32_t n=0); int find_and_use_playlist (const string&); void allocate_temporary_buffers (); - unsigned char _flags; - - int create_input_port (); - int connect_input_port (); - int seek_unlocked (jack_nframes_t which_sample); - - int ports_created (); - - bool realtime_set_speed (double, bool global_change); - void non_realtime_set_speed (); - - std::list<Region*> _last_capture_regions; - std::vector<AudioFileSource*> capturing_sources; int use_pending_capture_data (XMLNode& node); void get_input_sources (); @@ -439,10 +240,29 @@ class AudioDiskstream : public Stateful, public sigc::trackable void set_align_style_from_io(); void setup_destructive_playlist (); void use_destructive_playlist (); - void engage_record_enable (void* src); - void disengage_record_enable (void* src); + + void engage_record_enable (); + void disengage_record_enable (); + + // Working buffers for do_refill (butler thread) + static void allocate_working_buffers(); + static void free_working_buffers(); + + static size_t _working_buffers_size; + static Sample* _mixdown_buffer; + static gain_t* _gain_buffer; + static char* _conversion_buffer; + + // Uh, /really/ private? (death to friend classes) + int _do_refill (Sample *mixdown_buffer, float *gain_buffer, char *workbuf); + + + std::vector<AudioFileSource*> capturing_sources; + + typedef vector<ChannelInfo> ChannelList; + ChannelList channels; }; } // namespace ARDOUR -#endif /* __ardour_diskstream_h__ */ +#endif /* __ardour_audio_diskstream_h__ */ diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h index 5f65e2591d..15b99297c8 100644 --- a/libs/ardour/ardour/audio_track.h +++ b/libs/ardour/ardour/audio_track.h @@ -21,7 +21,7 @@ #ifndef __ardour_audio_track_h__ #define __ardour_audio_track_h__ -#include <ardour/route.h> +#include <ardour/track.h> namespace ARDOUR { @@ -30,76 +30,38 @@ class AudioDiskstream; class AudioPlaylist; class RouteGroup; -class AudioTrack : public Route +class AudioTrack : public Track { public: AudioTrack (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal); AudioTrack (Session&, const XMLNode&); ~AudioTrack (); - - int set_name (string str, void *src); - - int roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, - jack_nframes_t offset, int declick, bool can_record, bool rec_monitors_input); - int no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, - jack_nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input); - int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, - jack_nframes_t offset, bool can_record, bool rec_monitors_input); - - void toggle_monitor_input (); + int roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, + jack_nframes_t offset, int declick, bool can_record, bool rec_monitors_input); + + int no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, + jack_nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input); + + int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, + jack_nframes_t offset, bool can_record, bool rec_monitors_input); - bool can_record() const { return true; } - void set_record_enable (bool yn, void *src); + AudioDiskstream& audio_diskstream() const; - AudioDiskstream& disk_stream() const { return *diskstream; } - int set_diskstream (AudioDiskstream&, void *); int use_diskstream (string name); int use_diskstream (const PBD::ID& id); - - TrackMode mode() const { return _mode; } - void set_mode (TrackMode m); - sigc::signal<void> ModeChanged; - - jack_nframes_t update_total_latency(); - void set_latency_delay (jack_nframes_t); int export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t end_frame); - sigc::signal<void,void*> diskstream_changed; - - enum FreezeState { - NoFreeze, - Frozen, - UnFrozen - }; - - FreezeState freeze_state() const; - - sigc::signal<void> FreezeChange; - void freeze (InterThreadInfo&); void unfreeze (); void bounce (InterThreadInfo&); void bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo&); - XMLNode& get_state(); - XMLNode& get_template(); int set_state(const XMLNode& node); - PBD::Controllable& rec_enable_control() { - return _rec_enable_control; - } - - bool record_enabled() const; - void set_meter_point (MeterPoint, void* src); - protected: - AudioDiskstream *diskstream; - MeterPoint _saved_meter_point; - TrackMode _mode; - XMLNode& state (bool full); void passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame, @@ -107,59 +69,12 @@ class AudioTrack : public Route bool meter); uint32_t n_process_buffers (); - + private: - struct FreezeRecordInsertInfo { - FreezeRecordInsertInfo(XMLNode& st, boost::shared_ptr<Insert> ins) - : state (st), insert (ins) {} - - XMLNode state; - boost::shared_ptr<Insert> insert; - PBD::ID id; - UndoAction memento; - }; - - struct FreezeRecord { - FreezeRecord() { - playlist = 0; - have_mementos = false; - } - - ~FreezeRecord(); - - AudioPlaylist* playlist; - vector<FreezeRecordInsertInfo*> insert_info; - bool have_mementos; - FreezeState state; - }; - - FreezeRecord _freeze_record; - XMLNode* pending_state; - - void diskstream_record_enable_changed (void *src); - void diskstream_input_channel_changed (void *src); - - void input_change_handler (void *src); - - sigc::connection recenable_connection; - sigc::connection ic_connection; - - int deprecated_use_diskstream_connections (); + int set_diskstream (AudioDiskstream&, void *); + int deprecated_use_diskstream_connections (); void set_state_part_two (); void set_state_part_three (); - - struct RecEnableControllable : public PBD::Controllable { - RecEnableControllable (AudioTrack&); - - void set_value (float); - float get_value (void) const; - - AudioTrack& track; - }; - - RecEnableControllable _rec_enable_control; - - bool _destructive; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index 8db795ae90..81370e379c 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -34,6 +34,7 @@ #include <ardour/ardour.h> #include <jack/jack.h> #include <jack/transport.h> +#include <ardour/types.h> namespace ARDOUR { @@ -104,8 +105,8 @@ class AudioEngine : public sigc::trackable virtual const char *what() const throw() { return "could not connect to engine backend"; } }; - Port *register_audio_input_port (const std::string& portname); - Port *register_audio_output_port (const std::string& portname); + Port *register_input_port (DataType type, const std::string& portname); + Port *register_output_port (DataType type, const std::string& portname); int unregister_port (Port *); int connect (const std::string& source, const std::string& destination); diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h index 1b60cf185d..5a77067f8f 100644 --- a/libs/ardour/ardour/audioplaylist.h +++ b/libs/ardour/ardour/audioplaylist.h @@ -77,9 +77,6 @@ class AudioPlaylist : public ARDOUR::Playlist bool destroy_region (Region*); - void get_equivalent_regions (const AudioRegion&, std::vector<AudioRegion*>&); - void get_region_list_equivalent_regions (const AudioRegion&, std::vector<AudioRegion*>&); - void drop_all_states (); protected: diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index d7bb0c916b..683e946713 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -27,8 +27,9 @@ #include <pbd/undo.h> #include <ardour/ardour.h> -#include <ardour/gain.h> #include <ardour/region.h> +#include <ardour/gain.h> +#include <ardour/logcurve.h> #include <ardour/export.h> class XMLNode; @@ -43,14 +44,14 @@ class AudioSource; struct AudioRegionState : public RegionState { - AudioRegionState (std::string why); - - Curve _fade_in; - Curve _fade_out; - Curve _envelope; - gain_t _scale_amplitude; - uint32_t _fade_in_disabled; - uint32_t _fade_out_disabled; + AudioRegionState (std::string why); + + Curve _fade_in; + Curve _fade_out; + Curve _envelope; + gain_t _scale_amplitude; + uint32_t _fade_in_disabled; + uint32_t _fade_out_disabled; }; class AudioRegion : public Region @@ -75,11 +76,7 @@ class AudioRegion : public Region AudioRegion (SourceList &, const XMLNode&); ~AudioRegion(); - bool region_list_equivalent (const AudioRegion&) const ; - bool source_equivalent (const AudioRegion&) const; - bool equivalent (const AudioRegion&) const; - bool size_equivalent (const AudioRegion&) const; - bool overlap_equivalent (const AudioRegion&) const; + bool source_equivalent (const Region&) const; bool speed_mismatch (float) const; @@ -96,7 +93,7 @@ class AudioRegion : public Region vector<string> master_source_names(); bool envelope_active () const { return _flags & Region::EnvelopeActive; } - bool fade_in_active () const { return _flags & Region::FadeIn; } + bool fade_in_active () const { return _flags & Region::FadeIn; } bool fade_out_active () const { return _flags & Region::FadeOut; } bool captured() const { return !(_flags & (Region::Flag (Region::Import|Region::External))); } @@ -104,20 +101,21 @@ class AudioRegion : public Region Curve& fade_out() { return _fade_out; } Curve& envelope() { return _envelope; } - jack_nframes_t read_peaks (PeakData *buf, jack_nframes_t npeaks, jack_nframes_t offset, jack_nframes_t cnt, uint32_t chan_n=0, double samples_per_unit= 1.0) const; - - virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer, - float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt, - uint32_t chan_n = 0, - jack_nframes_t read_frames = 0, - jack_nframes_t skip_frames = 0) const; + jack_nframes_t read_peaks (PeakData *buf, jack_nframes_t npeaks, + jack_nframes_t offset, jack_nframes_t cnt, + uint32_t chan_n=0, double samples_per_unit= 1.0) const; - jack_nframes_t master_read_at (Sample *buf, Sample *mixdown_buffer, - float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt, uint32_t chan_n=0) const; + virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buf, + float *gain_buf, char * workbuf, jack_nframes_t position, jack_nframes_t cnt, + uint32_t chan_n = 0, + jack_nframes_t read_frames = 0, + jack_nframes_t skip_frames = 0) const; + jack_nframes_t master_read_at (Sample *buf, Sample *mixdown_buf, + float *gain_buf, char * workbuf, + jack_nframes_t position, jack_nframes_t cnt, uint32_t chan_n=0) const; XMLNode& state (bool); - XMLNode& get_state (); int set_state (const XMLNode&); static void set_default_fade (float steepness, jack_nframes_t len); @@ -144,10 +142,6 @@ class AudioRegion : public Region int separate_by_channel (ARDOUR::Session&, vector<AudioRegion*>&) const; - uint32_t read_data_count() const { return _read_data_count; } - - ARDOUR::Playlist* playlist() const { return _playlist; } - UndoAction get_memento() const; /* filter */ @@ -171,20 +165,6 @@ class AudioRegion : public Region friend class Playlist; private: - SourceList sources; - SourceList master_sources; /* used when timefx are applied, so - we can always use the original - source. - */ - mutable Curve _fade_in; - FadeShape _fade_in_shape; - mutable Curve _fade_out; - FadeShape _fade_out_shape; - mutable Curve _envelope; - gain_t _scale_amplitude; - uint32_t _fade_in_disabled; - uint32_t _fade_out_disabled; - void set_default_fades (); void set_default_fade_in (); void set_default_fade_out (); @@ -196,10 +176,6 @@ class AudioRegion : public Region void recompute_gain_at_end (); void recompute_gain_at_start (); - bool copied() const { return _flags & Copied; } - void maybe_uncopy (); - void rename_after_first_edit (); - jack_nframes_t _read_at (const SourceList&, Sample *buf, Sample *mixdown_buffer, float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt, uint32_t chan_n = 0, @@ -216,6 +192,21 @@ class AudioRegion : public Region void envelope_changed (Change); void source_deleted (Source*); + + + SourceList sources; + + /** Used when timefx are applied, so we can always use the original source. */ + SourceList master_sources; + + mutable Curve _fade_in; + FadeShape _fade_in_shape; + mutable Curve _fade_out; + FadeShape _fade_out_shape; + mutable Curve _envelope; + gain_t _scale_amplitude; + uint32_t _fade_in_disabled; + uint32_t _fade_out_disabled; }; } /* namespace ARDOUR */ diff --git a/libs/ardour/ardour/buffer.h b/libs/ardour/ardour/buffer.h new file mode 100644 index 0000000000..6604e5533b --- /dev/null +++ b/libs/ardour/ardour/buffer.h @@ -0,0 +1,144 @@ +/* + Copyright (C) 2006 Paul Davis + Written by Dave Robillard, 2006 + + 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., + 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __ardour_buffer_h__ +#define __ardour_buffer_h__ + +#define _XOPEN_SOURCE 600 +#include <cstdlib> // for posix_memalign +#include <cassert> +#include <ardour/types.h> +#include <jack/jack.h> + +namespace ARDOUR { + + +/* Yes, this is a bit of a mess right now. I'll clean it up when everything + * using it works out.. */ + + +/** A buffer of recordable/playable data. + * + * This is a datatype-agnostic base class for all buffers (there are no + * methods to actually access the data). This provides a way for code that + * doesn't care about the data type to still deal with buffers (which is + * why the base class can't be a template). + * + * To actually read/write buffer contents, use the appropriate derived class. + */ +class Buffer +{ +public: + Buffer(DataType type, size_t capacity) + : _type(type), _capacity(capacity), _size(0) + {} + + virtual ~Buffer() {} + + /** Maximum capacity of buffer. + * Note in some cases the entire buffer may not contain valid data, use size. */ + size_t capacity() const { return _capacity; } + + /** Amount of valid data in buffer. Use this over capacity almost always. */ + size_t size() const { return _size; } + + /** Type of this buffer. + * Based on this you can static cast a Buffer* to the desired type. */ + virtual DataType type() const { return _type; } + + /** Jack type (eg JACK_DEFAULT_AUDIO_TYPE) */ + const char* jack_type() const { return type_to_jack_type(type()); } + + /** String type as saved in session XML files (eg "audio" or "midi") */ + const char* type_string() const { return type_to_string(type()); } + + /* The below static methods need to be separate from the above methods + * because the conversion is needed in places where there's no Buffer. + * These should probably live somewhere else... + */ + + static const char* type_to_jack_type(DataType t) { + switch (t) { + case AUDIO: return JACK_DEFAULT_AUDIO_TYPE; + case MIDI: return JACK_DEFAULT_MIDI_TYPE; + default: return ""; + } + } + + static const char* type_to_string(DataType t) { + switch (t) { + case AUDIO: return "audio"; + case MIDI: return "midi"; + default: return "unknown"; // reeeally shouldn't ever happen + } + } + + /** Used for loading from XML (route default types etc) */ + static DataType type_from_string(const string& str) { + if (str == "audio") + return AUDIO; + else if (str == "midi") + return MIDI; + else + return NIL; + } + +protected: + DataType _type; + size_t _capacity; + size_t _size; +}; + + +/* Inside every class with a type in it's name is a template waiting to get out... */ + + +/** Buffer containing 32-bit floating point (audio) data. */ +class AudioBuffer : public Buffer +{ +public: + AudioBuffer(size_t capacity) + : Buffer(AUDIO, capacity) + , _data(NULL) + { + _size = capacity; // For audio buffers, size = capacity (always) +#ifdef NO_POSIX_MEMALIGN + b = (Sample *) malloc(sizeof(Sample) * capacity); +#else + posix_memalign((void**)_data, 16, sizeof(Sample) * capacity); +#endif + assert(_data); + memset(_data, 0, sizeof(Sample) * capacity); + } + + const Sample* data() const { return _data; } + Sample* data() { return _data; } + +private: + // These are undefined (prevent copies) + AudioBuffer(const AudioBuffer& copy); + AudioBuffer& operator=(const AudioBuffer& copy); + + Sample* const _data; ///< Actual buffer contents +}; + + +} // namespace ARDOUR + +#endif // __ardour_buffer_h__ diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h new file mode 100644 index 0000000000..ebce516d8b --- /dev/null +++ b/libs/ardour/ardour/diskstream.h @@ -0,0 +1,319 @@ +/* + Copyright (C) 2000-2006 Paul Davis + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id: diskstream.h 579 2006-06-12 19:56:37Z essej $ +*/ + +#ifndef __ardour_diskstream_h__ +#define __ardour_diskstream_h__ + +#include <sigc++/signal.h> + +#include <cmath> +#include <string> +#include <queue> +#include <map> +#include <vector> + +#include <time.h> + +#include <pbd/fastlog.h> +#include <pbd/ringbufferNPT.h> +#include <pbd/stateful.h> + +#include <ardour/ardour.h> +#include <ardour/configuration.h> +#include <ardour/session.h> +#include <ardour/route_group.h> +#include <ardour/route.h> +#include <ardour/port.h> +#include <ardour/utils.h> + + +struct tm; + +namespace ARDOUR { + +class AudioEngine; +class Send; +class Session; +class Playlist; +class IO; + +class Diskstream : public Stateful, public sigc::trackable +{ + public: + enum Flag { + Recordable = 0x1, + Hidden = 0x2, + Destructive = 0x4 + }; + + string name () const { return _name; } + virtual int set_name (string str); + + ARDOUR::IO* io() const { return _io; } + void set_io (ARDOUR::IO& io); + + virtual Diskstream& ref() { _refcnt++; return *this; } + void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; } + uint32_t refcnt() const { return _refcnt; } + + virtual float playback_buffer_load() const = 0; + virtual float capture_buffer_load() const = 0; + + void set_flag (Flag f) { _flags |= f; } + void unset_flag (Flag f) { _flags &= ~f; } + + AlignStyle alignment_style() const { return _alignment_style; } + void set_align_style (AlignStyle); + void set_persistent_align_style (AlignStyle a) { _persistent_alignment_style = a; } + + jack_nframes_t roll_delay() const { return _roll_delay; } + void set_roll_delay (jack_nframes_t); + + bool record_enabled() const { return g_atomic_int_get (&_record_enabled); } + virtual void set_record_enabled (bool yn) = 0; + + bool destructive() const { return _flags & Destructive; } + virtual void set_destructive (bool yn); + + const PBD::ID& id() const { return _id; } + bool hidden() const { return _flags & Hidden; } + bool recordable() const { return _flags & Recordable; } + bool reversed() const { return _actual_speed < 0.0f; } + double speed() const { return _visible_speed; } + + virtual void punch_in() {} + virtual void punch_out() {} + + void set_speed (double); + void non_realtime_set_speed (); + + Playlist* playlist () { return _playlist; } + + virtual int use_playlist (Playlist *); + virtual int use_new_playlist () = 0; + virtual int use_copy_playlist () = 0; + + jack_nframes_t current_capture_start() const { return capture_start_frame; } + jack_nframes_t current_capture_end() const { return capture_start_frame + capture_captured; } + jack_nframes_t get_capture_start_frame (uint32_t n=0); + jack_nframes_t get_captured_frames (uint32_t n=0); + + uint32_t n_channels() { return _n_channels; } + + static jack_nframes_t disk_io_frames() { return disk_io_chunk_frames; } + static void set_disk_io_chunk_frames (uint32_t n) { disk_io_chunk_frames = n; } + + /* Stateful */ + virtual XMLNode& get_state(void) = 0; + virtual int set_state(const XMLNode& node) = 0; + + // FIXME: makes sense for all diskstream types? + virtual void monitor_input (bool) {} + + jack_nframes_t capture_offset() const { return _capture_offset; } + virtual void set_capture_offset (); + + bool slaved() const { return _slaved; } + void set_slaved(bool yn) { _slaved = yn; } + + int set_loop (Location *loc); + + std::list<Region*>& last_capture_regions () { return _last_capture_regions; } + + void handle_input_change (IOChange, void *src); + + sigc::signal<void> RecordEnableChanged; + sigc::signal<void> SpeedChanged; + sigc::signal<void> ReverseChanged; + sigc::signal<void> PlaylistChanged; + sigc::signal<void> AlignmentStyleChanged; + sigc::signal<void,Location *> LoopSet; + + static sigc::signal<void> DiskOverrun; + static sigc::signal<void> DiskUnderrun; + static sigc::signal<void,Diskstream*> DiskstreamCreated; // XXX use a ref with sigc2 + static sigc::signal<void,list<Source*>*> DeleteSources; + + protected: + friend class Session; + + Diskstream (Session &, const string& name, Flag f = Recordable); + Diskstream (Session &, const XMLNode&); + + /* the Session is the only point of access for these because they require + * that the Session is "inactive" while they are called. + */ + + virtual void set_pending_overwrite (bool) = 0; + virtual int overwrite_existing_buffers () = 0; + virtual void set_block_size (jack_nframes_t) = 0; + virtual int internal_playback_seek (jack_nframes_t distance) = 0; + virtual int can_internal_playback_seek (jack_nframes_t distance) = 0; + virtual int rename_write_sources () = 0; + virtual void reset_write_sources (bool, bool force = false) = 0; + virtual void non_realtime_input_change () = 0; + + uint32_t read_data_count() const { return _read_data_count; } + uint32_t write_data_count() const { return _write_data_count; } + + protected: + friend class Auditioner; + virtual int seek (jack_nframes_t which_sample, bool complete_refill = false) = 0; + + protected: + friend class Track; + + virtual void prepare (); + virtual int process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input) = 0; + virtual bool commit (jack_nframes_t nframes) = 0; + virtual void recover (); /* called if commit will not be called, but process was */ + + //private: + + /** Use unref() to destroy a diskstream */ + virtual ~Diskstream(); + + enum TransitionType { + CaptureStart = 0, + CaptureEnd + }; + + struct CaptureTransition { + TransitionType type; + jack_nframes_t capture_val; ///< The start or end file frame position + }; + + /* The two central butler operations */ + virtual int do_flush (Session::RunContext context, bool force = false) = 0; + virtual int do_refill () = 0; + + /** For non-butler contexts (allocates temporary working buffers) */ + virtual int do_refill_with_alloc() = 0; + + + /* XXX fix this redundancy ... */ + + virtual void playlist_changed (Change); + virtual void playlist_modified (); + virtual void playlist_deleted (Playlist*); + + virtual void finish_capture (bool rec_monitors_input) = 0; + virtual void transport_stopped (struct tm&, time_t, bool abort) = 0; + + struct CaptureInfo { + uint32_t start; + uint32_t frames; + }; + + virtual void init (Flag); + + virtual int use_new_write_source (uint32_t n=0) = 0; + + virtual int find_and_use_playlist (const string&) = 0; + + virtual void allocate_temporary_buffers () = 0; + + virtual bool realtime_set_speed (double, bool global_change); + + std::list<Region*> _last_capture_regions; + virtual int use_pending_capture_data (XMLNode& node) = 0; + + virtual void get_input_sources () = 0; + virtual void check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record) = 0; + virtual void set_align_style_from_io() {} + virtual void setup_destructive_playlist () = 0; + virtual void use_destructive_playlist () = 0; + + static jack_nframes_t disk_io_chunk_frames; + vector<CaptureInfo*> capture_info; + Glib::Mutex capture_info_lock; + + uint32_t i_am_the_modifier; + + string _name; + ARDOUR::Session& _session; + ARDOUR::IO* _io; + uint32_t _n_channels; + PBD::ID _id; + Playlist* _playlist; + + mutable gint _record_enabled; + double _visible_speed; + double _actual_speed; + /* items needed for speed change logic */ + bool _buffer_reallocation_required; + bool _seek_required; + + bool force_refill; + jack_nframes_t capture_start_frame; + jack_nframes_t capture_captured; + bool was_recording; + jack_nframes_t adjust_capture_position; + jack_nframes_t _capture_offset; + jack_nframes_t _roll_delay; + jack_nframes_t first_recordable_frame; + jack_nframes_t last_recordable_frame; + int last_possibly_recording; + AlignStyle _alignment_style; + bool _scrubbing; + bool _slaved; + bool _processed; + Location* loop_location; + jack_nframes_t overwrite_frame; + off_t overwrite_offset; + bool pending_overwrite; + bool overwrite_queued; + IOChange input_change_pending; + jack_nframes_t wrap_buffer_size; + jack_nframes_t speed_buffer_size; + + uint64_t last_phase; + uint64_t phi; + + jack_nframes_t file_frame; + jack_nframes_t playback_sample; + jack_nframes_t playback_distance; + + uint32_t _read_data_count; + uint32_t _write_data_count; + + bool in_set_state; + AlignStyle _persistent_alignment_style; + bool first_input_change; + + Glib::Mutex state_lock; + + jack_nframes_t scrub_start; + jack_nframes_t scrub_buffer_size; + jack_nframes_t scrub_offset; + + uint32_t _refcnt; + + sigc::connection ports_created_c; + sigc::connection plmod_connection; + sigc::connection plstate_connection; + sigc::connection plgone_connection; + + unsigned char _flags; +}; + +}; /* namespace ARDOUR */ + +#endif /* __ardour_diskstream_h__ */ diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index 0356da8dc8..35b20f655e 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -38,6 +38,7 @@ #include <ardour/utils.h> #include <ardour/state_manager.h> #include <ardour/curve.h> +#include <ardour/types.h> using std::string; using std::vector; @@ -52,6 +53,11 @@ class Port; class Connection; class Panner; +/** A collection of input and output ports with connections. + * + * An IO can contain ports of varying types, making routes/inserts/etc with + * varied combinations of types (eg MIDI and audio) possible. + */ class IO : public Stateful, public ARDOUR::StateManager { @@ -60,7 +66,8 @@ class IO : public Stateful, public ARDOUR::StateManager IO (Session&, string name, int input_min = -1, int input_max = -1, - int output_min = -1, int output_max = -1); + int output_min = -1, int output_max = -1, + DataType default_type = AUDIO); virtual ~IO(); @@ -74,25 +81,29 @@ class IO : public Stateful, public ARDOUR::StateManager void set_output_minimum (int n); void set_output_maximum (int n); + DataType default_type() const { return _default_type; } + const string& name() const { return _name; } virtual int set_name (string str, void *src); virtual void silence (jack_nframes_t, jack_nframes_t offset); + // These should be moved in to a separate object that manipulates an IO + void pan (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset, gain_t gain_coeff); void pan_automated (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset); void collect_input (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset); - void deliver_output (vector<Sample *>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset); - void deliver_output_no_pan (vector<Sample *>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset); + void deliver_output (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset); + void deliver_output_no_pan (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset); void just_meter_input (jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset); virtual uint32_t n_process_buffers () { return 0; } virtual void set_gain (gain_t g, void *src); - void inc_gain (gain_t delta, void *src); - gain_t gain () const { return _desired_gain; } + void inc_gain (gain_t delta, void *src); + gain_t gain () const { return _desired_gain; } virtual gain_t effective_gain () const; Panner& panner() { return *_panner; } @@ -105,8 +116,8 @@ class IO : public Stateful, public ARDOUR::StateManager Connection *input_connection() const { return _input_connection; } Connection *output_connection() const { return _output_connection; } - int add_input_port (string source, void *src); - int add_output_port (string destination, void *src); + int add_input_port (string source, void *src, DataType type = NIL); + int add_output_port (string destination, void *src, DataType type = NIL); int remove_input_port (Port *, void *src); int remove_output_port (Port *, void *src); @@ -273,6 +284,7 @@ public: PBD::ID _id; bool no_panner_reset; XMLNode* deferred_state; + DataType _default_type; virtual void set_deferred_state() {} diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index 9fb1950bfa..9fb5b0eb2b 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -54,7 +54,6 @@ class Playlist : public Stateful, public StateManager { Playlist (const Playlist&, string name, bool hidden = false); Playlist (const Playlist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false); - virtual jack_nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, char * workbuf, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0) = 0; virtual void clear (bool with_delete = false, bool with_save = true); virtual void dump () const; virtual UndoAction get_memento() const = 0; @@ -81,6 +80,8 @@ class Playlist : public Stateful, public StateManager { void add_region (const Region&, jack_nframes_t position, float times = 1, bool with_save = true); void remove_region (Region *); + void get_equivalent_regions (const Region&, std::vector<Region*>&); + void get_region_list_equivalent_regions (const Region&, std::vector<Region*>&); void replace_region (Region& old, Region& newr, jack_nframes_t pos); void split_region (Region&, jack_nframes_t position); void partition (jack_nframes_t start, jack_nframes_t end, bool just_top_level); @@ -108,16 +109,15 @@ class Playlist : public Stateful, public StateManager { int set_state (const XMLNode&); XMLNode& get_template (); - sigc::signal<void,Region *> RegionAdded; - sigc::signal<void,Region *> RegionRemoved; - + sigc::signal<void,Region *> RegionAdded; + sigc::signal<void,Region *> RegionRemoved; sigc::signal<void,Playlist*,bool> InUse; - sigc::signal<void> Modified; - sigc::signal<void> NameChanged; - sigc::signal<void> LengthChanged; - sigc::signal<void> LayeringChanged; - sigc::signal<void,Playlist *> GoingAway; - sigc::signal<void> StatePushed; + sigc::signal<void> Modified; + sigc::signal<void> NameChanged; + sigc::signal<void> LengthChanged; + sigc::signal<void> LayeringChanged; + sigc::signal<void,Playlist *> GoingAway; + sigc::signal<void> StatePushed; static sigc::signal<void,Playlist*> PlaylistCreated; diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h index 93ed2777e4..86c99cb7e3 100644 --- a/libs/ardour/ardour/port.h +++ b/libs/ardour/ardour/port.h @@ -33,24 +33,24 @@ class AudioEngine; class Port : public sigc::trackable { public: virtual ~Port() { - free (port); + free (_port); } Sample *get_buffer (jack_nframes_t nframes) { if (_flags & JackPortIsOutput) { return _buffer; } else { - return (Sample *) jack_port_get_buffer (port, nframes); + return (Sample *) jack_port_get_buffer (_port, nframes); } } void reset_buffer () { if (_flags & JackPortIsOutput) { - _buffer = (Sample *) jack_port_get_buffer (port, 0); + _buffer = (Sample *) jack_port_get_buffer (_port, 0); } else { _buffer = 0; /* catch illegal attempts to use it */ } - silent = false; + _silent = false; } std::string name() { @@ -58,7 +58,7 @@ class Port : public sigc::trackable { } std::string short_name() { - return jack_port_short_name (port); + return jack_port_short_name (_port); } int set_name (std::string str); @@ -68,7 +68,7 @@ class Port : public sigc::trackable { } bool is_mine (jack_client_t *client) { - return jack_port_is_mine (client, port); + return jack_port_is_mine (client, _port); } const char* type() const { @@ -76,21 +76,21 @@ class Port : public sigc::trackable { } int connected () const { - return jack_port_connected (port); + return jack_port_connected (_port); } bool connected_to (const std::string& portname) const { - return jack_port_connected_to (port, portname.c_str()); + return jack_port_connected_to (_port, portname.c_str()); } const char ** get_connections () const { - return jack_port_get_connections (port); + return jack_port_get_connections (_port); } void reset_overs () { _short_overs = 0; _long_overs = 0; - overlen = 0; + _overlen = 0; } void reset_peak_meter () { @@ -103,18 +103,18 @@ class Port : public sigc::trackable { } void enable_metering() { - metering++; + _metering++; } void disable_metering () { - if (metering) { metering--; } + if (_metering) { _metering--; } } - float peak_db() const { return _peak_db; } + float peak_db() const { return _peak_db; } jack_default_audio_sample_t peak() const { return _peak; } uint32_t short_overs () const { return _short_overs; } - uint32_t long_overs () const { return _long_overs; } + uint32_t long_overs () const { return _long_overs; } static void set_short_over_length (jack_nframes_t); static void set_long_over_length (jack_nframes_t); @@ -128,7 +128,7 @@ class Port : public sigc::trackable { } bool monitoring_input () const { - return jack_port_monitoring_input (port); + return jack_port_monitoring_input (_port); } bool can_monitor () const { @@ -136,30 +136,29 @@ class Port : public sigc::trackable { } void ensure_monitor_input (bool yn) { - jack_port_request_monitor (port, yn); + jack_port_request_monitor (_port, yn); } void request_monitor_input (bool yn) { - jack_port_request_monitor (port, yn); + jack_port_request_monitor (_port, yn); } jack_nframes_t latency () const { - return jack_port_get_latency (port); + return jack_port_get_latency (_port); } void set_latency (jack_nframes_t nframes) { - jack_port_set_latency (port, nframes); + jack_port_set_latency (_port, nframes); } sigc::signal<void,bool> MonitorInputChanged; sigc::signal<void,bool> ClockSyncChanged; - bool is_silent() const { return silent; } + bool is_silent() const { return _silent; } + /** Assumes that the port is an audio output port */ void silence (jack_nframes_t nframes, jack_nframes_t offset) { - /* assumes that the port is an output port */ - - if (!silent) { + if (!_silent) { memset (_buffer + offset, 0, sizeof (Sample) * nframes); if (offset == 0) { /* XXX this isn't really true, but i am not sure @@ -167,13 +166,13 @@ class Port : public sigc::trackable { want to set it true when the entire port buffer has been overrwritten. */ - silent = true; + _silent = true; } } } void mark_silence (bool yn) { - silent = yn; + _silent = yn; } private: @@ -184,7 +183,7 @@ class Port : public sigc::trackable { /* engine isn't supposed to below here */ - Sample *_buffer; + Sample *_buffer; /* cache these 3 from JACK so that we can access them for reconnecting. @@ -194,18 +193,18 @@ class Port : public sigc::trackable { std::string _type; std::string _name; - bool last_monitor : 1; - bool silent : 1; - jack_port_t *port; - jack_nframes_t overlen; - jack_default_audio_sample_t _peak; - float _peak_db; - uint32_t _short_overs; - uint32_t _long_overs; - unsigned short metering; + bool _last_monitor : 1; + bool _silent : 1; + jack_port_t *_port; + jack_nframes_t _overlen; + jack_default_audio_sample_t _peak; + float _peak_db; + uint32_t _short_overs; + uint32_t _long_overs; + unsigned short _metering; - static jack_nframes_t long_over_length; - static jack_nframes_t short_over_length; + static jack_nframes_t _long_over_length; + static jack_nframes_t _short_over_length; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index baf93a8f77..3773a3b893 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -24,7 +24,6 @@ #include <pbd/undo.h> #include <ardour/ardour.h> -#include <ardour/logcurve.h> #include <ardour/state_manager.h> class XMLNode; @@ -36,22 +35,22 @@ class Source; enum RegionEditState { EditChangesNothing = 0, - EditChangesName = 1, - EditChangesID = 2 + EditChangesName = 1, + EditChangesID = 2 }; -struct RegionState : public StateManager::State { - - RegionState (std::string why) : StateManager::State (why) {} - - jack_nframes_t _start; - jack_nframes_t _length; - jack_nframes_t _position; - uint32_t _flags; - jack_nframes_t _sync_position; - layer_t _layer; - string _name; - mutable RegionEditState _first_edit; +struct RegionState : public StateManager::State +{ + RegionState (std::string why) : StateManager::State (why) {} + + jack_nframes_t _start; + jack_nframes_t _length; + jack_nframes_t _position; + uint32_t _flags; + jack_nframes_t _sync_position; + layer_t _layer; + string _name; + mutable RegionEditState _first_edit; }; class Region : public Stateful, public StateManager @@ -95,7 +94,7 @@ class Region : public Stateful, public StateManager Region (const Region&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags); Region (const Region&); Region (const XMLNode&); - ~Region(); + virtual ~Region(); const PBD::ID& id() const { return _id; } @@ -105,9 +104,10 @@ class Region : public Stateful, public StateManager void set_name (string str); jack_nframes_t position () const { return _position; } - jack_nframes_t start () const { return _start; } - jack_nframes_t length() const { return _length; } - layer_t layer () const { return _layer; } + jack_nframes_t start () const { return _start; } + jack_nframes_t length() const { return _length; } + layer_t layer () const { return _layer; } + jack_nframes_t sync_offset(int& dir) const; jack_nframes_t sync_position() const; @@ -118,14 +118,13 @@ class Region : public Stateful, public StateManager jack_nframes_t first_frame() const { return _position; } jack_nframes_t last_frame() const { return _position + _length - 1; } - bool hidden() const { return _flags & Hidden; } - bool muted() const { return _flags & Muted; } - bool opaque () const { return _flags & Opaque; } - bool envelope_active () const { return _flags & EnvelopeActive; } - bool locked() const { return _flags & Locked; } - bool automatic() const { return _flags & Automatic; } + bool hidden() const { return _flags & Hidden; } + bool muted() const { return _flags & Muted; } + bool opaque () const { return _flags & Opaque; } + bool locked() const { return _flags & Locked; } + bool automatic() const { return _flags & Automatic; } bool whole_file() const { return _flags & WholeFile ; } - Flag flags() const { return _flags; } + Flag flags() const { return _flags; } virtual bool should_save_state () const { return !(_flags & DoNotSaveState); }; @@ -139,12 +138,14 @@ class Region : public Stateful, public StateManager OverlapType coverage (jack_nframes_t start, jack_nframes_t end) const { return ARDOUR::coverage (_position, _position + _length - 1, start, end); } - - virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer, - float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt, - uint32_t chan_n = 0, - jack_nframes_t read_frames = 0, - jack_nframes_t skip_frames = 0) const = 0; + + bool equivalent (const Region&) const; + bool size_equivalent (const Region&) const; + bool overlap_equivalent (const Region&) const; + bool region_list_equivalent (const Region&) const; + virtual bool source_equivalent (const Region&) const = 0; + + virtual bool speed_mismatch (float) const = 0; /* EDITING OPERATIONS */ @@ -173,7 +174,6 @@ class Region : public Stateful, public StateManager void set_hidden (bool yn); void set_muted (bool yn); void set_opaque (bool yn); - void set_envelope_active (bool yn); void set_locked (bool yn); virtual uint32_t read_data_count() const { return _read_data_count; } @@ -189,9 +189,9 @@ class Region : public Stateful, public StateManager /* serialization */ + XMLNode& get_state (); virtual XMLNode& state (bool); - XMLNode& get_state (); - int set_state (const XMLNode&); + virtual int set_state (const XMLNode&); sigc::signal<void,Region*> GoingAway; @@ -211,23 +211,6 @@ class Region : public Stateful, public StateManager void set_last_layer_op (uint64_t when); protected: - - jack_nframes_t _start; - jack_nframes_t _length; - jack_nframes_t _position; - Flag _flags; - jack_nframes_t _sync_position; - layer_t _layer; - string _name; - mutable RegionEditState _first_edit; - int _frozen; - Glib::Mutex lock; - PBD::ID _id; - ARDOUR::Playlist* _playlist; - mutable uint32_t _read_data_count; // modified in read() - Change pending_changed; - uint64_t _last_layer_op; // timestamp - XMLNode& get_short_state (); /* used only by Session */ /* state management */ @@ -251,6 +234,23 @@ class Region : public Stateful, public StateManager virtual bool verify_length (jack_nframes_t) = 0; virtual void recompute_at_start () = 0; virtual void recompute_at_end () = 0; + + + jack_nframes_t _start; + jack_nframes_t _length; + jack_nframes_t _position; + Flag _flags; + jack_nframes_t _sync_position; + layer_t _layer; + string _name; + mutable RegionEditState _first_edit; + int _frozen; + Glib::Mutex lock; + PBD::ID _id; + ARDOUR::Playlist* _playlist; + mutable uint32_t _read_data_count; // modified in read() + Change pending_changed; + uint64_t _last_layer_op; // timestamp }; } /* namespace ARDOUR */ diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index b8a11301ca..ea4a2374d4 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -40,6 +40,7 @@ #include <ardour/io.h> #include <ardour/session.h> #include <ardour/redirect.h> +#include <ardour/types.h> namespace ARDOUR { @@ -68,7 +69,9 @@ class Route : public IO }; - Route (Session&, std::string name, int input_min, int input_max, int output_min, int output_max, Flag flags = Flag(0)); + Route (Session&, std::string name, int input_min, int input_max, int output_min, int output_max, + Flag flags = Flag(0), DataType default_type = AUDIO); + Route (Session&, const XMLNode&); virtual ~Route(); diff --git a/libs/ardour/ardour/route_group.h b/libs/ardour/ardour/route_group.h index 11253eda5b..e9fad1aa2b 100644 --- a/libs/ardour/ardour/route_group.h +++ b/libs/ardour/ardour/route_group.h @@ -35,6 +35,7 @@ using std::list; namespace ARDOUR { class Route; +class Track; class AudioTrack; class Session; @@ -90,7 +91,7 @@ class RouteGroup : public Stateful, public sigc::trackable { /* to use these, #include <ardour/route_group_specialized.h> */ - template<class T> void apply (void (AudioTrack::*func)(T, void *), T val, void *src); + template<class T> void apply (void (Track::*func)(T, void *), T val, void *src); /* fills at_set with all members of the group that are AudioTracks */ diff --git a/libs/ardour/ardour/route_group_specialized.h b/libs/ardour/ardour/route_group_specialized.h index 0424002dcd..250d3744df 100644 --- a/libs/ardour/ardour/route_group_specialized.h +++ b/libs/ardour/ardour/route_group_specialized.h @@ -7,11 +7,11 @@ namespace ARDOUR { template<class T> void -RouteGroup::apply (void (AudioTrack::*func)(T, void *), T val, void *src) +RouteGroup::apply (void (Track::*func)(T, void *), T val, void *src) { for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) { - AudioTrack *at; - if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) { + Track *at; + if ((at = dynamic_cast<Track*>(*i)) != 0) { (at->*func)(val, this); } } diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index dbcd830a04..8d10d9f598 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -66,6 +66,7 @@ namespace ARDOUR { class Port; class AudioEngine; class Slave; +class Diskstream; class AudioDiskstream; class Route; class AuxInput; @@ -157,17 +158,17 @@ class Session : public sigc::trackable, public Stateful Clear }; - Type type; - Action action; - jack_nframes_t action_frame; - jack_nframes_t target_frame; - float speed; + Type type; + Action action; + jack_nframes_t action_frame; + jack_nframes_t target_frame; + float speed; union { - void* ptr; - bool yes_or_no; - Session::SlaveSource slave; - Route* route; + void* ptr; + bool yes_or_no; + Session::SlaveSource slave; + Route* route; }; list<AudioRange> audio_range; @@ -269,30 +270,18 @@ class Session : public sigc::trackable, public Stateful vector<Sample*>& get_silent_buffers (uint32_t howmany); vector<Sample*>& get_send_buffers () { return _send_buffers; } - AudioDiskstream *diskstream_by_id (const PBD::ID& id); - AudioDiskstream *diskstream_by_name (string name); + Diskstream* diskstream_by_id (const PBD::ID& id); + Diskstream* diskstream_by_name (string name); bool have_captured() const { return _have_captured; } void refill_all_diskstream_buffers (); uint32_t diskstream_buffer_size() const { return dstream_buffer_size; } - /* XXX fix required here when we get new diskstream types *, but - not sure of the direction to take this in until then. - */ - - uint32_t get_next_diskstream_id() const { return n_audio_diskstreams(); } - uint32_t n_audio_diskstreams() const; + uint32_t get_next_diskstream_id() const { return n_diskstreams(); } + uint32_t n_diskstreams() const; - typedef list<AudioDiskstream *> AudioDiskstreamList; - - Session::AudioDiskstreamList audio_disk_streams() const { - Glib::RWLock::ReaderLock lm (diskstream_lock); - return audio_diskstreams; /* XXX yes, force a copy */ - } - - void foreach_audio_diskstream (void (AudioDiskstream::*func)(void)); - template<class T> void foreach_audio_diskstream (T *obj, void (T::*func)(AudioDiskstream&)); + typedef list<Diskstream *> DiskstreamList; typedef std::list<boost::shared_ptr<Route> > RouteList; @@ -356,7 +345,7 @@ class Session : public sigc::trackable, public Stateful sigc::signal<void> HaltOnXrun; sigc::signal<void,boost::shared_ptr<Route> > RouteAdded; - sigc::signal<void,AudioDiskstream*> AudioDiskstreamAdded; + sigc::signal<void,Diskstream*> DiskstreamAdded; // FIXME: make a shared_ptr void request_roll (); void request_bounded_roll (jack_nframes_t start, jack_nframes_t end); @@ -368,15 +357,14 @@ class Session : public sigc::trackable, public Stateful void goto_start () { request_locate (start_location->start(), false); } void use_rf_shuttle_speed (); void request_transport_speed (float speed); - void request_overwrite_buffer (AudioDiskstream*); - void request_diskstream_speed (AudioDiskstream&, float speed); + void request_overwrite_buffer (Diskstream*); + void request_diskstream_speed (Diskstream&, float speed); void request_input_change_handling (); bool locate_pending() const { return static_cast<bool>(post_transport_work&PostTransportLocate); } bool transport_locked () const; int wipe (); - int wipe_diskstream (AudioDiskstream *); int remove_region_from_region_list (Region&); @@ -553,9 +541,6 @@ class Session : public sigc::trackable, public Stateful void resort_routes (); void resort_routes_using (boost::shared_ptr<RouteList>); - void resort_routes_proxy (void* src) { - resort_routes (); - } AudioEngine &engine() { return _engine; }; @@ -636,7 +621,7 @@ class Session : public sigc::trackable, public Stateful string path_from_region_name (string name, string identifier); AudioRegion* find_whole_file_parent (AudioRegion&); - void find_equivalent_playlist_regions (AudioRegion&, std::vector<AudioRegion*>& result); + void find_equivalent_playlist_regions (Region&, std::vector<Region*>& result); AudioRegion *XMLRegionFactory (const XMLNode&, bool full); @@ -713,8 +698,6 @@ class Session : public sigc::trackable, public Stateful sigc::signal<void,Playlist*> PlaylistAdded; sigc::signal<void,Playlist*> PlaylistRemoved; - Playlist *get_playlist (string name); - uint32_t n_playlists() const; template<class T> void foreach_playlist (T *obj, void (T::*func)(Playlist *)); @@ -739,7 +722,7 @@ class Session : public sigc::trackable, public Stateful boost::shared_ptr<Auditioner> the_auditioner() { return auditioner; } void audition_playlist (); - void audition_region (AudioRegion&); + void audition_region (Region&); void cancel_audition (); bool is_auditioning () const; @@ -980,7 +963,7 @@ class Session : public sigc::trackable, public Stateful void set_frame_rate (jack_nframes_t nframes); protected: - friend class AudioDiskstream; + friend class Diskstream; void stop_butler (); void wait_till_butler_finished(); @@ -1442,12 +1425,12 @@ class Session : public sigc::trackable, public Stateful bool waiting_to_start; void set_auto_loop (bool yn); - void overwrite_some_buffers (AudioDiskstream*); + void overwrite_some_buffers (Diskstream*); void flush_all_redirects (); void locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false); void start_locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false); void force_locate (jack_nframes_t frame, bool with_roll = false); - void set_diskstream_speed (AudioDiskstream*, float speed); + void set_diskstream_speed (Diskstream*, float speed); void set_transport_speed (float speed, bool abort = false); void stop_transport (bool abort = false); void start_transport (); @@ -1478,10 +1461,10 @@ class Session : public sigc::trackable, public Stateful /* disk-streams */ - AudioDiskstreamList audio_diskstreams; + DiskstreamList diskstreams; mutable Glib::RWLock diskstream_lock; uint32_t dstream_buffer_size; - void add_diskstream (AudioDiskstream*); + void add_diskstream (Diskstream*); int load_diskstreams (const XMLNode&); /* routes stuff */ @@ -1549,7 +1532,7 @@ class Session : public sigc::trackable, public Stateful Playlist *XMLPlaylistFactory (const XMLNode&); void playlist_length_changed (Playlist *); - void diskstream_playlist_changed (AudioDiskstream *); + void diskstream_playlist_changed (Diskstream *); /* NAMED SELECTIONS */ diff --git a/libs/ardour/ardour/session_diskstream.h b/libs/ardour/ardour/session_diskstream.h deleted file mode 100644 index 33fc5419ba..0000000000 --- a/libs/ardour/ardour/session_diskstream.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ - -#ifndef __ardour_session_diskstream_h__ -#define __ardour_session_diskstream_h__ - -#include <ardour/session.h> -#include <ardour/audio_diskstream.h> - -namespace ARDOUR { - -template<class T> void -Session::foreach_audio_diskstream (T *obj, void (T::*func)(AudioDiskstream&)) -{ - Glib::RWLock::ReaderLock lm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); i++) { - if (!(*i)->hidden()) { - (obj->*func) (**i); - } - } -} - -} /* namespace */ - -#endif /* __ardour_session_diskstream_h__ */ diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h new file mode 100644 index 0000000000..707ead1573 --- /dev/null +++ b/libs/ardour/ardour/track.h @@ -0,0 +1,158 @@ +/* + Copyright (C) 2006 Paul Davis + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __ardour_track_h__ +#define __ardour_track_h__ + +#include <ardour/route.h> + +namespace ARDOUR { + +class Session; +class Diskstream; +class Playlist; +class RouteGroup; + +class Track : public Route +{ + public: + Track (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal, DataType default_type = AUDIO); + + virtual ~Track (); + + int set_name (string str, void *src); + + virtual int roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, + jack_nframes_t offset, int declick, bool can_record, bool rec_monitors_input) = 0; + + virtual int no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, + jack_nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input) = 0; + + virtual int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, + jack_nframes_t offset, bool can_record, bool rec_monitors_input) = 0; + + void toggle_monitor_input (); + + bool can_record() const { return true; } + + Diskstream& diskstream() const { return *_diskstream; } + + virtual int use_diskstream (string name) = 0; + virtual int use_diskstream (const PBD::ID& id) = 0; + + TrackMode mode() const { return _mode; } + void set_mode (TrackMode m); + + jack_nframes_t update_total_latency(); + void set_latency_delay (jack_nframes_t); + + enum FreezeState { + NoFreeze, + Frozen, + UnFrozen + }; + + FreezeState freeze_state() const; + + virtual void freeze (InterThreadInfo&) = 0; + virtual void unfreeze () = 0; + + virtual void bounce (InterThreadInfo&) = 0; + virtual void bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo&) = 0; + + XMLNode& get_state(); + XMLNode& get_template(); + virtual int set_state(const XMLNode& node) = 0; + + PBD::Controllable& rec_enable_control() { return _rec_enable_control; } + + bool record_enabled() const; + void set_record_enable (bool yn, void *src); + + void set_meter_point (MeterPoint, void* src); + + sigc::signal<void> ModeChanged; + sigc::signal<void> DiskstreamChanged; + sigc::signal<void> FreezeChange; + + protected: + Track (Session& sess, const XMLNode& node, DataType default_type = AUDIO); + + virtual XMLNode& state (bool full) = 0; + + virtual void passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame, + jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter) = 0; + + virtual uint32_t n_process_buffers () = 0; + + Diskstream *_diskstream; + MeterPoint _saved_meter_point; + TrackMode _mode; + + //private: (FIXME) + struct FreezeRecordInsertInfo { + FreezeRecordInsertInfo(XMLNode& st, boost::shared_ptr<Insert> ins) + : state (st), insert (ins) {} + + XMLNode state; + boost::shared_ptr<Insert> insert; + PBD::ID id; + UndoAction memento; + }; + + struct FreezeRecord { + FreezeRecord() + : playlist(0) + , have_mementos(false) + {} + + ~FreezeRecord(); + + Playlist* playlist; + vector<FreezeRecordInsertInfo*> insert_info; + bool have_mementos; + FreezeState state; + }; + + struct RecEnableControllable : public PBD::Controllable { + RecEnableControllable (Track&); + + void set_value (float); + float get_value (void) const; + + Track& track; + }; + + //virtual void diskstream_record_enable_changed (void *src) = 0; + //virtual void diskstream_input_channel_changed (void *src) = 0; + + //virtual void input_change_handler (void *src) = 0; + + virtual void set_state_part_two () = 0; + + FreezeRecord _freeze_record; + XMLNode* pending_state; + sigc::connection recenable_connection; + sigc::connection ic_connection; + RecEnableControllable _rec_enable_control; + bool _destructive; +}; + +}; /* namespace ARDOUR*/ + +#endif /* __ardour_track_h__ */ diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index fa1d121d02..e073b413bb 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -243,6 +243,12 @@ namespace ARDOUR { PeakDatum min; PeakDatum max; }; + + enum DataType { + NIL = 0, + AUDIO, + MIDI + }; } std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf); |