summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2006-07-30 03:25:38 +0000
committerDavid Robillard <d@drobilla.net>2006-07-30 03:25:38 +0000
commit9d5d82b4df5b3510177fd31557ac765f46778fe8 (patch)
treeb0b786f4f8fcee4e76c7c3ab1a66f603c08de070 /libs/ardour
parent8277d134b9733aee344782891c99f07114384d9e (diff)
Abstraction cleanups/polish, towards merging with trunk
git-svn-id: svn://localhost/ardour2/branches/midi@720 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/audio_diskstream.h93
-rw-r--r--libs/ardour/ardour/diskstream.h62
-rw-r--r--libs/ardour/ardour/midi_diskstream.h22
-rw-r--r--libs/ardour/ardour/playlist.h17
-rw-r--r--libs/ardour/ardour/region.h2
-rw-r--r--libs/ardour/ardour/session.h2
-rw-r--r--libs/ardour/audio_diskstream.cc197
-rw-r--r--libs/ardour/diskstream.cc112
-rw-r--r--libs/ardour/midi_diskstream.cc4
-rw-r--r--libs/ardour/session.cc4
-rw-r--r--libs/ardour/session_butler.cc18
-rw-r--r--libs/ardour/session_state.cc3
12 files changed, 224 insertions, 312 deletions
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index c4a942a5d7..ec15cf1caf 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,8 +14,6 @@
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_audio_diskstream_h__
@@ -62,18 +60,12 @@ class AudioDiskstream : public Diskstream
AudioDiskstream (Session &, const string& name, Diskstream::Flag f = Recordable);
AudioDiskstream (Session &, const XMLNode&);
- void set_io (ARDOUR::IO& io);
-
+ // 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_align_style (AlignStyle);
- //void set_persistent_align_style (AlignStyle);
-
string input_source (uint32_t n=0) const {
if (n < channels.size()) {
return channels[n].source ? channels[n].source->name() : "";
@@ -87,7 +79,6 @@ class AudioDiskstream : public Diskstream
}
void set_record_enabled (bool yn, void *src);
- //void set_speed (double);
float peak_power(uint32_t n=0) {
float x = channels[n].peak_power;
@@ -98,16 +89,13 @@ class AudioDiskstream : public Diskstream
return minus_infinity();
}
}
+
+ AudioPlaylist* audio_playlist () { return dynamic_cast<AudioPlaylist*>(_playlist); }
int use_playlist (Playlist *);
int use_new_playlist ();
int use_copy_playlist ();
- void start_scrub (jack_nframes_t where) {} // FIXME?
- void end_scrub () {} // FIXME?
-
- Playlist *playlist () { return _playlist; }
-
Sample *playback_buffer (uint32_t n=0) {
if (n < channels.size())
return channels[n].current_playback_buffer;
@@ -137,7 +125,6 @@ class AudioDiskstream : public Diskstream
void monitor_input (bool);
- // FIXME: these don't belong here
static void swap_by_ptr (Sample *first, Sample *last) {
while (first < last) {
Sample tmp = *first;
@@ -154,11 +141,6 @@ class AudioDiskstream : public Diskstream
}
}
- //void handle_input_change (IOChange, void *src);
-
- //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;
int set_loop (Location *loc);
@@ -168,8 +150,6 @@ class AudioDiskstream : public Diskstream
return _last_capture_regions;
}
- void handle_input_change (IOChange, void *src);
-
const PBD::ID& id() const { return _id; }
XMLNode* deprecated_io_node;
@@ -184,7 +164,6 @@ class AudioDiskstream : public Diskstream
void set_pending_overwrite(bool);
int overwrite_existing_buffers ();
- void reverse_scrub_buffer (bool to_forward) {} // FIXME?
void set_block_size (jack_nframes_t);
int internal_playback_seek (jack_nframes_t distance);
int can_internal_playback_seek (jack_nframes_t distance);
@@ -237,60 +216,30 @@ class AudioDiskstream : public Diskstream
jack_nframes_t curr_capture_cnt;
};
- typedef vector<ChannelInfo> ChannelList;
-
- /* the two central butler operations */
-
- int do_flush (char * workbuf, bool force = false);
- int do_refill (Sample *mixdown_buffer, float *gain_buffer, char *workbuf);
+ /* 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); }
- virtual int non_realtime_do_refill() { return do_refill(0, 0, 0); }
+ int do_refill_with_alloc();
- 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);
-
- /* XXX fix this redundancy ... */
-
- //void playlist_changed (Change);
- //void playlist_modified ();
- void playlist_deleted (Playlist*);
- void session_controls_changed (Session::ControlType) {} // FIXME?
+ 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) {} // FIXME?
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 (Diskstream::Flag);
void init_channel (ChannelInfo &chan);
void destroy_channel (ChannelInfo &chan);
int use_new_write_source (uint32_t n=0);
- int use_new_fade_source (uint32_t n=0) { return 0; } // FIXME?
int find_and_use_playlist (const string&);
void allocate_temporary_buffers ();
- int create_input_port () { return 0; } // FIXME?
- int connect_input_port () { return 0; } // FIXME?
- int seek_unlocked (jack_nframes_t which_sample) { return 0; } // FIXME?
-
- int ports_created () { return 0; } // FIXME?
-
- //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 ();
@@ -299,10 +248,26 @@ class AudioDiskstream : public Diskstream
void setup_destructive_playlist ();
void use_destructive_playlist ();
- ChannelList channels;
- AudioPlaylist* _playlist;
void engage_record_enable (void* src);
void disengage_record_enable (void* src);
+
+ // 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
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index b595879264..ff25127ec9 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/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
@@ -52,7 +52,6 @@ class AudioEngine;
class Send;
class Session;
class Playlist;
-//class FileSource;
class IO;
/* FIXME: There are (obviously) far too many virtual functions in this ATM.
@@ -71,10 +70,10 @@ class Diskstream : public Stateful, public sigc::trackable
virtual int set_name (string str, void* src);
ARDOUR::IO* io() const { return _io; }
- virtual void set_io (ARDOUR::IO& io) = 0;
+ void set_io (ARDOUR::IO& io);
virtual Diskstream& ref() { _refcnt++; return *this; }
- void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; }
+ void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; }
uint32_t refcnt() const { return _refcnt; }
virtual float playback_buffer_load() const = 0;
@@ -105,17 +104,15 @@ class Diskstream : public Stateful, public sigc::trackable
virtual void punch_in() {}
virtual void punch_out() {}
- virtual void set_speed (double);
- virtual void non_realtime_set_speed () = 0;
+ void set_speed (double);
+ void non_realtime_set_speed ();
- virtual Playlist *playlist () = 0;
+ Playlist* playlist () { return _playlist; }
+
+ virtual int use_playlist (Playlist *);
virtual int use_new_playlist () = 0;
- virtual int use_playlist (Playlist *) = 0;
virtual int use_copy_playlist () = 0;
- virtual void start_scrub (jack_nframes_t where) = 0;
- virtual void end_scrub () = 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);
@@ -123,7 +120,7 @@ class Diskstream : public Stateful, public sigc::trackable
uint32_t n_channels() { return _n_channels; }
- static jack_nframes_t disk_io_frames() { return disk_io_chunk_frames; }
+ 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 */
@@ -144,7 +141,7 @@ class Diskstream : public Stateful, public sigc::trackable
std::list<Region*>& last_capture_regions () { return _last_capture_regions; }
- virtual void handle_input_change (IOChange, void *src);
+ void handle_input_change (IOChange, void *src);
sigc::signal<void,void*> RecordEnableChanged;
sigc::signal<void> SpeedChanged;
@@ -170,7 +167,6 @@ class Diskstream : public Stateful, public sigc::trackable
virtual void set_pending_overwrite (bool) = 0;
virtual int overwrite_existing_buffers () = 0;
- virtual void reverse_scrub_buffer (bool to_forward) = 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;
@@ -209,25 +205,21 @@ class Diskstream : public Stateful, public sigc::trackable
jack_nframes_t capture_val;
};
- /* the two central butler operations */
-
- virtual int do_flush (char * workbuf, bool force = false) = 0;
- //int do_refill (Sample *mixdown_buffer, float *gain_buffer, char *workbuf);
+ /* The two central butler operations */
+ virtual int do_flush (Session::RunContext context, bool force = false) = 0;
+ virtual int do_refill () = 0;
- virtual int non_realtime_do_refill() = 0;
+ /** For non-butler contexts (allocates temporary working buffers) */
+ virtual int do_refill_with_alloc() = 0;
- //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);
/* XXX fix this redundancy ... */
virtual void playlist_changed (Change);
virtual void playlist_modified ();
- virtual void playlist_deleted (Playlist*) = 0;
- virtual void session_controls_changed (Session::ControlType) = 0;
+ virtual void playlist_deleted (Playlist*);
virtual void finish_capture (bool rec_monitors_input) = 0;
- virtual void clean_up_capture (struct tm&, time_t, bool abort) = 0;
virtual void transport_stopped (struct tm&, time_t, bool abort) = 0;
struct CaptureInfo {
@@ -237,37 +229,23 @@ class Diskstream : public Stateful, public sigc::trackable
virtual void init (Flag);
- //void init_channel (ChannelInfo &chan);
- //void destroy_channel (ChannelInfo &chan);
-
virtual int use_new_write_source (uint32_t n=0) = 0;
- virtual int use_new_fade_source (uint32_t n=0) = 0;
virtual int find_and_use_playlist (const string&) = 0;
- //void allocate_temporary_buffers ();
-
- virtual int create_input_port () = 0;
- virtual int connect_input_port () = 0;
- virtual int seek_unlocked (jack_nframes_t which_sample) = 0;
-
- virtual int ports_created () = 0;
+ virtual void allocate_temporary_buffers () = 0;
virtual bool realtime_set_speed (double, bool global_change);
- //void non_realtime_set_speed ();
std::list<Region*> _last_capture_regions;
- //std::vector<FileSource*> capturing_sources;
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;
- //void set_align_style_from_io();
+ virtual void set_align_style_from_io() {}
virtual void setup_destructive_playlist () = 0;
- //void use_destructive_playlist ();
+ virtual void use_destructive_playlist () = 0;
- // Wouldn't hurt for this thing to do on a diet:
-
static jack_nframes_t disk_io_chunk_frames;
vector<CaptureInfo*> capture_info;
Glib::Mutex capture_info_lock;
@@ -279,6 +257,7 @@ class Diskstream : public Stateful, public sigc::trackable
ARDOUR::IO* _io;
uint32_t _n_channels;
PBD::ID _id;
+ Playlist* _playlist;
mutable gint _record_enabled;
double _visible_speed;
@@ -338,7 +317,6 @@ class Diskstream : public Stateful, public sigc::trackable
sigc::connection plgone_connection;
unsigned char _flags;
-
};
}; /* namespace ARDOUR */
diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h
index b6121d1176..5998363d69 100644
--- a/libs/ardour/ardour/midi_diskstream.h
+++ b/libs/ardour/ardour/midi_diskstream.h
@@ -80,9 +80,6 @@ class MidiDiskstream : public Diskstream
int use_new_playlist ();
int use_copy_playlist ();
- void start_scrub (jack_nframes_t where) {} // FIXME?
- void end_scrub () {} // FIXME?
-
Playlist *playlist () { return _playlist; }
static sigc::signal<void,list<SMFSource*>*> DeleteSources;
@@ -106,7 +103,6 @@ class MidiDiskstream : public Diskstream
void set_pending_overwrite(bool);
int overwrite_existing_buffers ();
- void reverse_scrub_buffer (bool to_forward) {} // FIXME?
void set_block_size (jack_nframes_t);
int internal_playback_seek (jack_nframes_t distance);
int can_internal_playback_seek (jack_nframes_t distance);
@@ -134,12 +130,11 @@ class MidiDiskstream : public Diskstream
MidiPlaylist* _playlist;
- /* the two central butler operations */
-
- int do_flush (char * workbuf, bool force = false);
- int do_refill (RawMidi *mixdown_buffer, float *gain_buffer, char *workbuf);
+ /*Tthe two central butler operations */
+ int do_flush (Session::RunContext context, bool force = false) { return 0; }
+ int do_refill () { return 0; }
- virtual int non_realtime_do_refill() { return do_refill(0, 0, 0); }
+ int do_refill_with_alloc() { return 0; }
int read (RawMidi* buf, RawMidi* mixdown_buffer, char * workbuf, jack_nframes_t& start, jack_nframes_t cnt, bool reversed);
@@ -148,10 +143,8 @@ class MidiDiskstream : public Diskstream
//void playlist_changed (Change);
//void playlist_modified ();
void playlist_deleted (Playlist*);
- void session_controls_changed (Session::ControlType) {} // FIXME?
void finish_capture (bool rec_monitors_input);
- void clean_up_capture (struct tm&, time_t, bool abort) {} // FIXME?
void transport_stopped (struct tm&, time_t, bool abort);
struct CaptureInfo {
@@ -162,18 +155,11 @@ class MidiDiskstream : public Diskstream
void init (Diskstream::Flag);
int use_new_write_source (uint32_t n=0);
- int use_new_fade_source (uint32_t n=0) { return 0; } // FIXME?
int find_and_use_playlist (const string&);
void allocate_temporary_buffers ();
- int create_input_port () { return 0; } // FIXME?
- int connect_input_port () { return 0; } // FIXME?
- int seek_unlocked (jack_nframes_t which_sample) { return 0; } // FIXME?
-
- int ports_created () { return 0; } // FIXME?
-
//bool realtime_set_speed (double, bool global_change);
void non_realtime_set_speed ();
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index ca760a5ad5..add253982f 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -110,16 +110,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/region.h b/libs/ardour/ardour/region.h
index 68ac55df67..a138f66042 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -145,6 +145,8 @@ class Region : public Stateful, public StateManager
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;
/*virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt,
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 7bd24b96cc..dd8ec4806a 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -938,7 +938,7 @@ class Session : public sigc::trackable, public Stateful
/* buffers for gain and pan */
gain_t* gain_automation_buffer () const { return _gain_automation_buffer; }
- pan_t** pan_automation_buffer() const { return _pan_automation_buffer; }
+ pan_t** pan_automation_buffer () const { return _pan_automation_buffer; }
/* buffers for conversion */
enum RunContext {
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index a3345cf15a..5f6ce05016 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2000-2003 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,8 +14,6 @@
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.cc 567 2006-06-07 14:54:12Z trutkin $
*/
#include <fstream>
@@ -23,6 +21,7 @@
#include <unistd.h>
#include <cmath>
#include <cerrno>
+#include <cassert>
#include <string>
#include <climits>
#include <fcntl.h>
@@ -57,10 +56,14 @@ using namespace PBD;
sigc::signal<void,list<AudioFileSource*>*> AudioDiskstream::DeleteSources;
+size_t AudioDiskstream::_working_buffers_size = 0;
+Sample* AudioDiskstream::_mixdown_buffer = 0;
+gain_t* AudioDiskstream::_gain_buffer = 0;
+char* AudioDiskstream::_conversion_buffer = 0;
+
AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Diskstream::Flag flag)
: Diskstream(sess, name, flag)
, deprecated_io_node(NULL)
- , _playlist(NULL)
{
/* prevent any write sources from being created */
@@ -77,7 +80,6 @@ AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Diskstream:
AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node)
: Diskstream(sess, node)
, deprecated_io_node(NULL)
- , _playlist(NULL)
{
in_set_state = true;
init (Recordable);
@@ -178,25 +180,33 @@ AudioDiskstream::~AudioDiskstream ()
{
Glib::Mutex::Lock lm (state_lock);
- if (_playlist)
- _playlist->unref ();
-
- for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+ for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan)
destroy_channel((*chan));
- }
channels.clear();
}
void
-AudioDiskstream::handle_input_change (IOChange change, void *src)
+AudioDiskstream::allocate_working_buffers()
{
- Glib::Mutex::Lock lm (state_lock);
+ assert(disk_io_frames() > 0);
- if (!(input_change_pending & change)) {
- input_change_pending = IOChange (input_change_pending|change);
- _session.request_input_change_handling ();
- }
+ _working_buffers_size = disk_io_frames();
+ _mixdown_buffer = new Sample[_working_buffers_size];
+ _gain_buffer = new gain_t[_working_buffers_size];
+ _conversion_buffer = new char[_working_buffers_size * 4];
+}
+
+void
+AudioDiskstream::free_working_buffers()
+{
+ delete _mixdown_buffer;
+ delete _gain_buffer;
+ delete _conversion_buffer;
+ _working_buffers_size = 0;
+ _mixdown_buffer = 0;
+ _gain_buffer = 0;
+ _conversion_buffer = 0;
}
void
@@ -312,40 +322,7 @@ AudioDiskstream::use_playlist (Playlist* playlist)
{
assert(dynamic_cast<AudioPlaylist*>(playlist));
- {
- Glib::Mutex::Lock lm (state_lock);
-
- if (playlist == _playlist) {
- return 0;
- }
-
- plstate_connection.disconnect();
- plmod_connection.disconnect ();
- plgone_connection.disconnect ();
-
- if (_playlist) {
- _playlist->unref();
- }
-
- _playlist = dynamic_cast<AudioPlaylist*>(playlist);
- _playlist->ref();
-
- if (!in_set_state && recordable()) {
- reset_write_sources (false);
- }
-
- plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &AudioDiskstream::playlist_changed));
- plmod_connection = _playlist->Modified.connect (mem_fun (*this, &AudioDiskstream::playlist_modified));
- plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &AudioDiskstream::playlist_deleted));
- }
-
- if (!overwrite_queued) {
- _session.request_overwrite_buffer (this);
- overwrite_queued = true;
- }
-
- PlaylistChanged (); /* EMIT SIGNAL */
- _session.set_dirty ();
+ Diskstream::use_playlist(playlist);
return 0;
}
@@ -377,6 +354,8 @@ AudioDiskstream::use_new_playlist ()
int
AudioDiskstream::use_copy_playlist ()
{
+ assert(audio_playlist());
+
if (destructive()) {
return 0;
}
@@ -391,7 +370,7 @@ AudioDiskstream::use_copy_playlist ()
newname = Playlist::bump_name (_playlist->name(), _session);
- if ((playlist = new AudioPlaylist (*_playlist, newname)) != 0) {
+ if ((playlist = new AudioPlaylist (*audio_playlist(), newname)) != 0) {
playlist->set_orig_diskstream_id (id());
return use_playlist (playlist);
} else {
@@ -399,19 +378,6 @@ AudioDiskstream::use_copy_playlist ()
}
}
-
-void
-AudioDiskstream::playlist_deleted (Playlist* pl)
-{
- /* this catches an ordering issue with session destruction. playlists
- are destroyed before diskstreams. we have to invalidate any handles
- we have to the playlist.
- */
-
- _playlist = 0;
-}
-
-
void
AudioDiskstream::setup_destructive_playlist ()
{
@@ -461,36 +427,6 @@ AudioDiskstream::use_destructive_playlist ()
}
void
-AudioDiskstream::set_io (IO& io)
-{
- _io = &io;
- set_align_style_from_io ();
-}
-
-void
-AudioDiskstream::non_realtime_set_speed ()
-{
- if (_buffer_reallocation_required)
- {
- Glib::Mutex::Lock lm (state_lock);
- allocate_temporary_buffers ();
-
- _buffer_reallocation_required = false;
- }
-
- if (_seek_required) {
- if (speed() != 1.0f || speed() != -1.0f) {
- seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()), true);
- }
- else {
- seek (_session.transport_frame(), true);
- }
-
- _seek_required = false;
- }
-}
-
-void
AudioDiskstream::check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record)
{
int possibly_recording;
@@ -1054,9 +990,9 @@ AudioDiskstream::seek (jack_nframes_t frame, bool complete_refill)
file_frame = frame;
if (complete_refill) {
- while ((ret = non_realtime_do_refill ()) > 0);
+ while ((ret = do_refill_with_alloc ()) > 0) ;
} else {
- ret = non_realtime_do_refill ();
+ ret = do_refill_with_alloc ();
}
return ret;
@@ -1148,7 +1084,7 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
this_read = min(cnt,this_read);
- if (_playlist->read (buf+offset, mixdown_buffer, gain_buffer, workbuf, start, this_read, channel) != this_read) {
+ if (audio_playlist()->read (buf+offset, mixdown_buffer, gain_buffer, workbuf, start, this_read, channel) != this_read) {
error << string_compose(_("AudioDiskstream %1: cannot read %2 from playlist at frame %3"), _id, this_read,
start) << endmsg;
return -1;
@@ -1182,14 +1118,27 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
}
int
-AudioDiskstream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * workbuf)
+AudioDiskstream::do_refill_with_alloc()
+{
+ Sample* mix_buf = new Sample[disk_io_chunk_frames];
+ float* gain_buf = new float[disk_io_chunk_frames];
+ char* work_buf = new char[disk_io_chunk_frames * 4];
+
+ int ret = _do_refill(mix_buf, gain_buf, work_buf);
+
+ delete [] mix_buf;
+ delete [] gain_buf;
+ delete [] work_buf;
+
+ return ret;
+}
+
+int
+AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer, char * workbuf)
{
int32_t ret = 0;
jack_nframes_t to_read;
RingBufferNPT<Sample>::rw_vector vector;
- bool free_mixdown;
- bool free_gain;
- bool free_workbuf;
bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
jack_nframes_t total_space;
jack_nframes_t zero_fill;
@@ -1197,6 +1146,10 @@ AudioDiskstream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * w
ChannelList::iterator i;
jack_nframes_t ts;
+ assert(mixdown_buffer);
+ assert(gain_buffer);
+ assert(workbuf);
+
channels.front().playback_buf->get_write_vector (&vector);
if ((total_space = vector.len[0] + vector.len[1]) == 0) {
@@ -1303,33 +1256,6 @@ AudioDiskstream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * w
zero_fill = 0;
}
}
-
- /* Please note: the code to allocate buffers isn't run
- during normal butler thread operation. Its there
- for other times when we need to call do_refill()
- from somewhere other than the butler thread.
- */
-
- if (mixdown_buffer == 0) {
- mixdown_buffer = new Sample[disk_io_chunk_frames];
- free_mixdown = true;
- } else {
- free_mixdown = false;
- }
-
- if (gain_buffer == 0) {
- gain_buffer = new float[disk_io_chunk_frames];
- free_gain = true;
- } else {
- free_gain = false;
- }
-
- if (workbuf == 0) {
- workbuf = new char[disk_io_chunk_frames * 4];
- free_workbuf = true;
- } else {
- free_workbuf = false;
- }
jack_nframes_t file_frame_tmp = 0;
@@ -1398,22 +1324,15 @@ AudioDiskstream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * w
file_frame = file_frame_tmp;
out:
- if (free_mixdown) {
- delete [] mixdown_buffer;
- }
- if (free_gain) {
- delete [] gain_buffer;
- }
- if (free_workbuf) {
- delete [] workbuf;
- }
return ret;
}
int
-AudioDiskstream::do_flush (char * workbuf, bool force_flush)
+AudioDiskstream::do_flush (Session::RunContext context, bool force_flush)
{
+ char* workbuf = _session.conversion_buffer(context);
+
uint32_t to_write;
int32_t ret = 0;
RingBufferNPT<Sample>::rw_vector vector;
@@ -1570,7 +1489,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
*/
while (more_work && !err) {
- switch (do_flush ( _session.conversion_buffer(Session::TransportContext), true)) {
+ switch (do_flush (Session::TransportContext, true)) {
case 0:
more_work = false;
break;
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index 4e2bec9850..9fc2ded0ce 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2000-2003 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
@@ -55,7 +55,7 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
-jack_nframes_t Diskstream::disk_io_chunk_frames;
+jack_nframes_t Diskstream::disk_io_chunk_frames = 0;
sigc::signal<void,Diskstream*> Diskstream::DiskstreamCreated;
//sigc::signal<void,list<AudioFileSource*>*> Diskstream::DeleteSources;
@@ -65,13 +65,14 @@ sigc::signal<void> Diskstream::DiskUnderrun;
Diskstream::Diskstream (Session &sess, const string &name, Flag flag)
: _name (name)
, _session (sess)
+ , _playlist(NULL)
{
init (flag);
}
Diskstream::Diskstream (Session& sess, const XMLNode& node)
: _session (sess)
-
+ , _playlist(NULL)
{
init (Recordable);
}
@@ -113,37 +114,28 @@ Diskstream::init (Flag f)
_read_data_count = 0;
_write_data_count = 0;
- /* there are no channels at this point, so these
- two calls just get speed_buffer_size and wrap_buffer
- size setup without duplicating their code.
- */
-
- //set_block_size (_session.get_block_size());
- //allocate_temporary_buffers ();
-
pending_overwrite = false;
overwrite_frame = 0;
overwrite_queued = false;
input_change_pending = NoChange;
- //add_channel ();
- _n_channels = 0;//1;
+ _n_channels = 0;
}
Diskstream::~Diskstream ()
{
- // Taken by child.. assure lock?
+ // Taken by derived class destrctors.. assure lock?
//Glib::Mutex::Lock lm (state_lock);
- //if (_playlist) {
- // _playlist->unref ();
- //}
+ if (_playlist)
+ _playlist->unref ();
+}
- //for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
- // destroy_channel((*chan));
- //}
-
- //channels.clear();
+void
+Diskstream::set_io (IO& io)
+{
+ _io = &io;
+ set_align_style_from_io ();
}
void
@@ -157,6 +149,29 @@ Diskstream::handle_input_change (IOChange change, void *src)
}
}
+void
+Diskstream::non_realtime_set_speed ()
+{
+ if (_buffer_reallocation_required)
+ {
+ Glib::Mutex::Lock lm (state_lock);
+ allocate_temporary_buffers ();
+
+ _buffer_reallocation_required = false;
+ }
+
+ if (_seek_required) {
+ if (speed() != 1.0f || speed() != -1.0f) {
+ seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()), true);
+ }
+ else {
+ seek (_session.transport_frame(), true);
+ }
+
+ _seek_required = false;
+ }
+}
+
bool
Diskstream::realtime_set_speed (double sp, bool global)
{
@@ -223,7 +238,6 @@ Diskstream::set_align_style (AlignStyle a)
return;
}
-
if (a != _alignment_style) {
_alignment_style = a;
AlignmentStyleChanged ();
@@ -287,6 +301,47 @@ Diskstream::set_speed (double sp)
playlist_modified();
}
+int
+Diskstream::use_playlist (Playlist* playlist)
+{
+ {
+ Glib::Mutex::Lock lm (state_lock);
+
+ if (playlist == _playlist) {
+ return 0;
+ }
+
+ plstate_connection.disconnect();
+ plmod_connection.disconnect ();
+ plgone_connection.disconnect ();
+
+ if (_playlist) {
+ _playlist->unref();
+ }
+
+ _playlist = playlist;
+ _playlist->ref();
+
+ if (!in_set_state && recordable()) {
+ reset_write_sources (false);
+ }
+
+ plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &Diskstream::playlist_changed));
+ plmod_connection = _playlist->Modified.connect (mem_fun (*this, &Diskstream::playlist_modified));
+ plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &Diskstream::playlist_deleted));
+ }
+
+ if (!overwrite_queued) {
+ _session.request_overwrite_buffer (this);
+ overwrite_queued = true;
+ }
+
+ PlaylistChanged (); /* EMIT SIGNAL */
+ _session.set_dirty ();
+
+ return 0;
+}
+
void
Diskstream::playlist_changed (Change ignored)
{
@@ -302,6 +357,17 @@ Diskstream::playlist_modified ()
}
}
+void
+Diskstream::playlist_deleted (Playlist* pl)
+{
+ /* this catches an ordering issue with session destruction. playlists
+ are destroyed before diskstreams. we have to invalidate any handles
+ we have to the playlist.
+ */
+
+ _playlist = 0;
+}
+
int
Diskstream::set_name (string str, void *src)
{
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index a5853136ea..4602fc8f67 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -388,7 +388,7 @@ MidiDiskstream::read (RawMidi* buf, RawMidi* mixdown_buffer, char * workbuf, jac
{
return 0;
}
-
+/*
int
MidiDiskstream::do_refill (RawMidi* mixdown_buffer, float* gain_buffer, char * workbuf)
{
@@ -400,7 +400,7 @@ MidiDiskstream::do_flush (char * workbuf, bool force_flush)
{
return 0;
}
-
+*/
void
MidiDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
{
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index fec674b671..011d1d6237 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -403,6 +403,8 @@ Session::~Session ()
for (map<RunContext,char*>::iterator i = _conversion_buffers.begin(); i != _conversion_buffers.end(); ++i) {
delete [] (i->second);
}
+
+ AudioDiskstream::free_working_buffers();
#undef TRACK_DESTRUCTION
#ifdef TRACK_DESTRUCTION
@@ -2105,7 +2107,7 @@ void
Session::add_diskstream (Diskstream* dstream)
{
/* need to do this in case we're rolling at the time, to prevent false underruns */
- dstream->non_realtime_do_refill();
+ dstream->do_refill_with_alloc();
{
Glib::RWLock::WriterLock lm (diskstream_lock);
diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc
index f0a2af0a83..6509a783bb 100644
--- a/libs/ardour/session_butler.cc
+++ b/libs/ardour/session_butler.cc
@@ -170,11 +170,6 @@ Session::butler_thread_work ()
bool disk_work_outstanding = false;
DiskstreamList::iterator i;
- butler_mixdown_buffer = new Sample[AudioDiskstream::disk_io_frames()];
- butler_gain_buffer = new gain_t[AudioDiskstream::disk_io_frames()];
- // this buffer is used for temp conversion purposes in filesources
- char * conv_buffer = conversion_buffer(ButlerContext);
-
while (true) {
pfd[0].fd = butler_request_pipe[0];
pfd[0].events = POLLIN|POLLERR|POLLHUP;
@@ -256,16 +251,15 @@ Session::butler_thread_work ()
Glib::RWLock::ReaderLock dsm (diskstream_lock);
for (i = diskstreams.begin(); !transport_work_requested() && butler_should_run && i != diskstreams.end(); ++i) {
- // cerr << "rah fondr " << (*i)->io()->name () << endl;
- AudioDiskstream* ads = dynamic_cast<AudioDiskstream*>(*i);
- if (!ads) continue; // FIXME
- switch (ads->do_refill (butler_mixdown_buffer, butler_gain_buffer, conv_buffer)) {
+ Diskstream* const ds = *i;
+
+ switch (ds->do_refill ()) {
case 0:
- bytes += ads->read_data_count();
+ bytes += ds->read_data_count();
break;
case 1:
- bytes += ads->read_data_count();
+ bytes += ds->read_data_count();
disk_work_outstanding = true;
break;
@@ -302,7 +296,7 @@ Session::butler_thread_work ()
for (i = diskstreams.begin(); !transport_work_requested() && butler_should_run && i != diskstreams.end(); ++i) {
// cerr << "write behind for " << (*i)->name () << endl;
- switch ((*i)->do_flush (conv_buffer)) {
+ switch ((*i)->do_flush (Session::ButlerContext)) {
case 0:
bytes += (*i)->write_data_count();
break;
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 73ba391873..0809aae6eb 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -196,7 +196,8 @@ Session::first_stage_init (string fullpath, string snapshot_name)
/* allocate conversion buffers */
_conversion_buffers[ButlerContext] = new char[AudioDiskstream::disk_io_frames() * 4];
_conversion_buffers[TransportContext] = new char[AudioDiskstream::disk_io_frames() * 4];
-
+ AudioDiskstream::allocate_working_buffers();
+
/* default short fade = 15ms */
Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));