summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/ardour/ardour/audioengine.h8
-rw-r--r--libs/ardour/ardour/buffer_manager.h31
-rw-r--r--libs/ardour/ardour/process_thread.h44
-rw-r--r--libs/ardour/ardour/session.h18
-rw-r--r--libs/ardour/ardour/thread_buffers.h33
-rw-r--r--libs/ardour/audioengine.cc67
-rw-r--r--libs/ardour/buffer_manager.cc82
-rw-r--r--libs/ardour/globals.cc5
-rw-r--r--libs/ardour/process_thread.cc149
-rw-r--r--libs/ardour/session.cc77
-rw-r--r--libs/ardour/session_process.cc5
-rw-r--r--libs/ardour/session_state.cc3
-rw-r--r--libs/ardour/thread_buffers.cc91
-rw-r--r--libs/ardour/wscript5
-rw-r--r--libs/pbd/pbd/ringbufferNPT.h1
15 files changed, 544 insertions, 75 deletions
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h
index e630e1a95e..63f9afeb2b 100644
--- a/libs/ardour/ardour/audioengine.h
+++ b/libs/ardour/ardour/audioengine.h
@@ -55,6 +55,7 @@ class InternalPort;
class MidiPort;
class Port;
class Session;
+class ProcessThread;
class AudioEngine : public SessionHandlePtr
{
@@ -69,6 +70,8 @@ class AudioEngine : public SessionHandlePtr
bool is_realtime () const;
+ ProcessThread* main_thread() const { return _main_thread; }
+
std::string client_name() const { return jack_client_name; }
int reconnect_to_jack ();
@@ -272,6 +275,8 @@ _ the regular process() call to session->process() is not made.
Port *register_port (DataType type, const std::string& portname, bool input);
int process_callback (nframes_t nframes);
+ void* process_thread ();
+ void finish_process_cycle (int status);
void remove_all_ports ();
std::string get_nth_physical (DataType type, uint32_t n, int flags);
@@ -284,6 +289,7 @@ _ the regular process() call to session->process() is not made.
#endif
static int _graph_order_callback (void *arg);
static int _process_callback (nframes_t nframes, void *arg);
+ static void* _process_thread (void *arg);
static int _sample_rate_callback (nframes_t nframes, void *arg);
static int _bufsize_callback (nframes_t nframes, void *arg);
static void _jack_timebase_callback (jack_transport_state_t, nframes_t, jack_position_t*, int, void*);
@@ -307,6 +313,8 @@ _ the regular process() call to session->process() is not made.
Glib::Thread* m_meter_thread;
static gint m_meter_exit;
+
+ ProcessThread* _main_thread;
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/buffer_manager.h b/libs/ardour/ardour/buffer_manager.h
new file mode 100644
index 0000000000..4da8d0637f
--- /dev/null
+++ b/libs/ardour/ardour/buffer_manager.h
@@ -0,0 +1,31 @@
+#ifndef __libardour_buffer_manager__
+#define __libardour_buffer_manager__
+
+#include <stdint.h>
+
+#include "pbd/ringbufferNPT.h"
+
+#include "ardour/chan_count.h"
+
+namespace ARDOUR {
+
+class ThreadBuffers;
+
+class BufferManager
+{
+ public:
+ static void init (uint32_t);
+
+ static ThreadBuffers* get_thread_buffers ();
+ static void put_thread_buffers (ThreadBuffers*);
+
+ static void ensure_buffers (ChanCount howmany = ChanCount::ZERO);
+
+ private:
+ typedef RingBufferNPT<ThreadBuffers*> ThreadBufferFIFO;
+ static ThreadBufferFIFO* thread_buffers;
+};
+
+}
+
+#endif /* __libardour_buffer_manager__ */
diff --git a/libs/ardour/ardour/process_thread.h b/libs/ardour/ardour/process_thread.h
new file mode 100644
index 0000000000..d6bbbfc6fc
--- /dev/null
+++ b/libs/ardour/ardour/process_thread.h
@@ -0,0 +1,44 @@
+#ifndef __libardour_process_thread__
+#define __libardour_process_thread__
+
+#include <glibmm/thread.h>
+
+#include "ardour/chan_count.h"
+#include "ardour/types.h"
+
+namespace ARDOUR {
+
+class ThreadBuffers;
+
+class ProcessThread
+{
+ public:
+ ProcessThread ();
+ ~ProcessThread ();
+
+ static void init();
+
+ void get_buffers ();
+ void drop_buffers ();
+
+ /* these MUST be called by a process thread's thread, nothing else
+ */
+
+ static BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO);
+ static BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
+ static BufferSet& get_mix_buffers (ChanCount count = ChanCount::ZERO);
+ static gain_t* gain_automation_buffer ();
+ static pan_t** pan_automation_buffer ();
+
+ protected:
+ void session_going_away ();
+
+ private:
+ Glib::Thread* _thread;
+
+ static Glib::Private<ThreadBuffers>* _private_thread_buffers;
+};
+
+} // namespace
+
+#endif /* __libardour_process_thread__ */
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 2b51e3f8ec..b5c818e6a2 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -106,6 +106,7 @@ class Playlist;
class PluginInsert;
class Port;
class PortInsert;
+class ProcessThread;
class Processor;
class Region;
class Return;
@@ -736,8 +737,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
/* 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; }
+ gain_t* gain_automation_buffer () const;
+ pan_t** pan_automation_buffer () const;
void ensure_buffer_set (BufferSet& buffers, const ChanCount& howmany);
@@ -859,9 +860,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
nframes64_t _last_slave_transport_frame;
nframes_t maximum_output_latency;
volatile nframes64_t _requested_return_frame;
- BufferSet* _scratch_buffers;
- BufferSet* _silent_buffers;
- BufferSet* _mix_buffers;
nframes_t current_block_size;
nframes_t _worst_output_latency;
nframes_t _worst_input_latency;
@@ -881,7 +879,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void update_latency_compensation_proxy (void* ignored);
- void ensure_buffers (ChanCount howmany);
+ void ensure_buffers (ChanCount howmany = ChanCount::ZERO);
void process_scrub (nframes_t);
void process_without_events (nframes_t);
@@ -894,6 +892,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void unblock_processing() { g_atomic_int_set (&processing_prohibited, 0); }
bool processing_blocked() const { return g_atomic_int_get (&processing_prohibited); }
+ Glib::Mutex process_thread_lock;
+ std::list<ProcessThread*> process_threads;
+
/* slave tracking */
static const int delta_accumulator_size = 25;
@@ -1389,11 +1390,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
boost::shared_ptr<Route> _master_out;
boost::shared_ptr<Route> _monitor_out;
- gain_t* _gain_automation_buffer;
- pan_t** _pan_automation_buffer;
- void allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force);
- uint32_t _npan_buffers;
-
/* VST support */
long _vst_callback (VSTPlugin*,
diff --git a/libs/ardour/ardour/thread_buffers.h b/libs/ardour/ardour/thread_buffers.h
new file mode 100644
index 0000000000..3c312176a8
--- /dev/null
+++ b/libs/ardour/ardour/thread_buffers.h
@@ -0,0 +1,33 @@
+#ifndef __libardour_thread_buffers__
+#define __libardour_thread_buffers__
+
+#include <glibmm/thread.h>
+
+#include "ardour/chan_count.h"
+#include "ardour/types.h"
+
+namespace ARDOUR {
+
+class BufferSet;
+
+class ThreadBuffers {
+ public:
+ ThreadBuffers ();
+ ~ThreadBuffers ();
+
+ void ensure_buffers (ChanCount howmany = ChanCount::ZERO);
+
+ BufferSet* silent_buffers;
+ BufferSet* scratch_buffers;
+ BufferSet* mix_buffers;
+ gain_t* gain_automation_buffer;
+ pan_t** pan_automation_buffer;
+ uint32_t npan_buffers;
+
+ private:
+ void allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force);
+};
+
+} // namespace
+
+#endif /* __libardour_thread_buffers__ */
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index db1c4f2ef5..196482f143 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -43,6 +43,7 @@
#include "ardour/io.h"
#include "ardour/meter.h"
#include "ardour/midi_port.h"
+#include "ardour/process_thread.h"
#include "ardour/port.h"
#include "ardour/port_set.h"
#include "ardour/session.h"
@@ -77,6 +78,7 @@ AudioEngine::AudioEngine (string client_name, string session_uuid)
_frame_rate = 0;
_buffer_size = 0;
_freewheeling = false;
+ _main_thread = 0;
m_meter_thread = 0;
g_atomic_int_set (&m_meter_exit, 0);
@@ -184,7 +186,8 @@ AudioEngine::start ()
jack_on_shutdown (_priv_jack, halted, this);
jack_set_graph_order_callback (_priv_jack, _graph_order_callback, this);
jack_set_thread_init_callback (_priv_jack, _thread_init_callback, this);
- jack_set_process_callback (_priv_jack, _process_callback, this);
+ // jack_set_process_callback (_priv_jack, _process_callback, this);
+ jack_set_process_thread (_priv_jack, _process_thread, this);
jack_set_sample_rate_callback (_priv_jack, _sample_rate_callback, this);
jack_set_buffer_size_callback (_priv_jack, _bufsize_callback, this);
jack_set_xrun_callback (_priv_jack, _xrun_callback, this);
@@ -336,6 +339,12 @@ AudioEngine::_process_callback (nframes_t nframes, void *arg)
return static_cast<AudioEngine *> (arg)->process_callback (nframes);
}
+void*
+AudioEngine::_process_thread (void *arg)
+{
+ return static_cast<AudioEngine *> (arg)->process_thread ();
+}
+
void
AudioEngine::_freewheel_callback (int onoff, void *arg)
{
@@ -372,6 +381,47 @@ AudioEngine::split_cycle (nframes_t offset)
}
}
+void
+AudioEngine::finish_process_cycle (int status)
+{
+ GET_PRIVATE_JACK_POINTER(_jack);
+ cerr << "signal process cycle end\n";
+ jack_cycle_signal (_jack, 0);
+}
+
+void*
+AudioEngine::process_thread ()
+{
+ /* JACK doesn't do this for us when we use the wait API
+ */
+
+ cerr << "JACK process thread is here\n";
+
+ _thread_init_callback (0);
+
+ cerr << " its initialized\n";
+
+ _main_thread = new ProcessThread;
+
+ cerr << " we have ProcThread\n";
+
+ while (1) {
+ cerr << "getting client ptr from " << _jack << endl;
+ GET_PRIVATE_JACK_POINTER_RET(_jack,0);
+ cerr << "Wait for JACK\n";
+ jack_nframes_t nframes = jack_cycle_wait (_jack);
+ cerr << "run process\n";
+
+ if (process_callback (nframes)) {
+ return 0;
+ }
+
+ finish_process_cycle (0);
+ }
+
+ return 0;
+}
+
/** Method called by JACK (via _process_callback) which says that there
* is work to be done.
* @param nframes Number of frames to process.
@@ -379,7 +429,7 @@ AudioEngine::split_cycle (nframes_t offset)
int
AudioEngine::process_callback (nframes_t nframes)
{
- GET_PRIVATE_JACK_POINTER_RET(_jack,0)
+ GET_PRIVATE_JACK_POINTER_RET(_jack,0);
// CycleTimer ct ("AudioEngine::process");
Glib::Mutex::Lock tm (_process_lock, Glib::TRY_LOCK);
@@ -434,6 +484,7 @@ AudioEngine::process_callback (nframes_t nframes)
} else {
if (_session) {
_session->process (nframes);
+
}
}
@@ -930,6 +981,8 @@ AudioEngine::get_ports (const string& port_name_pattern, const string& type_name
void
AudioEngine::halted (void *arg)
{
+ cerr << "HALTED by JACK\n";
+
/* called from jack shutdown handler */
AudioEngine* ae = static_cast<AudioEngine *> (arg);
@@ -1246,13 +1299,8 @@ AudioEngine::reconnect_to_jack ()
if (_session) {
_session->reset_jack_connection (_priv_jack);
- nframes_t blocksize = jack_get_buffer_size (_priv_jack);
- _session->set_block_size (blocksize);
+ jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
_session->set_frame_rate (jack_get_sample_rate (_priv_jack));
-
- _raw_buffer_sizes[DataType::AUDIO] = blocksize * sizeof(float);
- cout << "FIXME: Assuming maximum MIDI buffer size " << blocksize * 4 << "bytes" << endl;
- _raw_buffer_sizes[DataType::MIDI] = blocksize * 4;
}
last_monitor_check = 0;
@@ -1260,7 +1308,8 @@ AudioEngine::reconnect_to_jack ()
jack_on_shutdown (_priv_jack, halted, this);
jack_set_graph_order_callback (_priv_jack, _graph_order_callback, this);
jack_set_thread_init_callback (_priv_jack, _thread_init_callback, this);
- jack_set_process_callback (_priv_jack, _process_callback, this);
+ // jack_set_process_callback (_priv_jack, _process_callback, this);
+ jack_set_process_thread (_priv_jack, _process_thread, this);
jack_set_sample_rate_callback (_priv_jack, _sample_rate_callback, this);
jack_set_buffer_size_callback (_priv_jack, _bufsize_callback, this);
jack_set_xrun_callback (_priv_jack, _xrun_callback, this);
diff --git a/libs/ardour/buffer_manager.cc b/libs/ardour/buffer_manager.cc
new file mode 100644
index 0000000000..3436dac72d
--- /dev/null
+++ b/libs/ardour/buffer_manager.cc
@@ -0,0 +1,82 @@
+/*
+ Copyright (C) 2010 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.
+
+*/
+
+#include <iostream>
+#include "ardour/buffer_manager.h"
+#include "ardour/thread_buffers.h"
+
+using namespace ARDOUR;
+using namespace PBD;
+
+RingBufferNPT<ThreadBuffers*>* BufferManager::thread_buffers = 0;
+
+void
+BufferManager::init (uint32_t size)
+{
+ thread_buffers = new ThreadBufferFIFO (size+1); // must be one larger than requested
+
+ /* and populate with actual ThreadBuffers
+ */
+
+ std::cerr << "BM: initial read space: " << thread_buffers->read_space() << std::endl;
+
+ for (uint32_t n = 0; n < size; ++n) {
+ ThreadBuffers* ts = new ThreadBuffers;
+ thread_buffers->write (&ts, 1);
+ std::cerr << "BM: added one, read = " << thread_buffers->read_space()
+ << " write = " << thread_buffers->write_space()
+ << std::endl;
+ }
+
+ std::cerr << "BM: final, read = " << thread_buffers->read_space()
+ << " write = " << thread_buffers->write_space()
+ << std::endl;
+
+ std::cerr << "BUFFER MANAGER INITIALIZED WITH " << size << " BUFFERs\n";
+}
+
+ThreadBuffers*
+BufferManager::get_thread_buffers ()
+{
+ ThreadBuffers* tbp;
+
+ if (thread_buffers->read (&tbp, 1) == 1) {
+ return tbp;
+ }
+
+ return 0;
+}
+
+void
+BufferManager::put_thread_buffers (ThreadBuffers* tbp)
+{
+ thread_buffers->write (&tbp, 1);
+}
+
+void
+BufferManager::ensure_buffers (ChanCount howmany)
+{
+ /* this is protected by the audioengine's process lock: we do not */
+
+ std::cerr << "BufMgr: ensure " << thread_buffers->bufsize() - 1 << " buffers match " << howmany << std::endl;
+
+ for (uint32_t n = 0; n < thread_buffers->bufsize() - 1; ++n) {
+ thread_buffers->buffer()[n]->ensure_buffers (howmany);
+ }
+}
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index 9f3d99ead4..b78edc11d2 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -64,12 +64,14 @@
#include "ardour/audioengine.h"
#include "ardour/audioregion.h"
#include "ardour/audiosource.h"
+#include "ardour/buffer_manager.h"
#include "ardour/control_protocol_manager.h"
#include "ardour/debug.h"
#include "ardour/filesystem_paths.h"
#include "ardour/mix.h"
#include "ardour/playlist.h"
#include "ardour/plugin_manager.h"
+#include "ardour/process_thread.h"
#include "ardour/profile.h"
#include "ardour/region.h"
#include "ardour/rc_configuration.h"
@@ -405,6 +407,9 @@ ARDOUR::init (bool use_vst, bool try_optimization)
/* singleton - first object is "it" */
new PluginManager ();
+ ProcessThread::init ();
+ BufferManager::init (2); // XX should be num_processors_for_dsp
+
return 0;
}
diff --git a/libs/ardour/process_thread.cc b/libs/ardour/process_thread.cc
new file mode 100644
index 0000000000..e36639aaf5
--- /dev/null
+++ b/libs/ardour/process_thread.cc
@@ -0,0 +1,149 @@
+/*
+ Copyright (C) 2010 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.
+
+*/
+
+#include <iostream>
+#include "ardour/audioengine.h"
+#include "ardour/buffer.h"
+#include "ardour/buffer_manager.h"
+#include "ardour/buffer_set.h"
+#include "ardour/process_thread.h"
+#include "ardour/thread_buffers.h"
+
+using namespace ARDOUR;
+using namespace Glib;
+using namespace std;
+
+Private<ThreadBuffers>* ProcessThread::_private_thread_buffers = 0;
+
+static void
+release_thread_buffer (void* arg)
+{
+ BufferManager::put_thread_buffers ((ThreadBuffers*) arg);
+}
+
+void
+ProcessThread::init ()
+{
+ _private_thread_buffers = new Private<ThreadBuffers> (release_thread_buffer);
+}
+
+ProcessThread::ProcessThread ()
+ : _thread (0)
+{
+}
+
+ProcessThread::~ProcessThread ()
+{
+}
+
+void
+ProcessThread::get_buffers ()
+{
+ ThreadBuffers* tb = BufferManager::get_thread_buffers ();
+
+ assert (tb);
+ _private_thread_buffers->set (tb);
+ cerr << "ProcThread " << this << " using TBs at " << tb << " (aka. " << _private_thread_buffers->get() << endl;
+}
+
+void
+ProcessThread::drop_buffers ()
+{
+ ThreadBuffers* tb = _private_thread_buffers->get();
+ assert (tb);
+ BufferManager::put_thread_buffers (tb);
+ _private_thread_buffers->set (0);
+ cerr << "ProcThread " << this << " dropped TBs\n";
+}
+
+BufferSet&
+ProcessThread::get_silent_buffers (ChanCount count)
+{
+ ThreadBuffers* tb = _private_thread_buffers->get();
+ assert (tb);
+
+ BufferSet* sb = tb->silent_buffers;
+ assert (sb);
+
+ assert(sb->available() >= count);
+ sb->set_count(count);
+
+ for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+ for (size_t i= 0; i < count.get(*t); ++i) {
+ sb->get(*t, i).clear();
+ }
+ }
+
+ return *sb;
+}
+
+BufferSet&
+ProcessThread::get_scratch_buffers (ChanCount count)
+{
+ ThreadBuffers* tb = _private_thread_buffers->get();
+ assert (tb);
+
+ BufferSet* sb = tb->scratch_buffers;
+ assert (sb);
+
+ if (count != ChanCount::ZERO) {
+ assert(sb->available() >= count);
+ sb->set_count (count);
+ } else {
+ sb->set_count (sb->available());
+ }
+
+ return *sb;
+}
+
+BufferSet&
+ProcessThread::get_mix_buffers (ChanCount count)
+{
+ ThreadBuffers* tb = _private_thread_buffers->get();
+ assert (tb);
+
+ BufferSet* mb = tb->mix_buffers;
+
+ assert (mb);
+ assert (mb->available() >= count);
+ mb->set_count(count);
+ return *mb;
+}
+
+gain_t*
+ProcessThread::gain_automation_buffer()
+{
+ ThreadBuffers* tb = _private_thread_buffers->get();
+ assert (tb);
+
+ gain_t *g = tb->gain_automation_buffer;
+ assert (g);
+ return g;
+}
+
+pan_t**
+ProcessThread::pan_automation_buffer()
+{
+ ThreadBuffers* tb = _private_thread_buffers->get();
+ assert (tb);
+
+ pan_t** p = tb->pan_automation_buffer;
+ assert (p);
+ return p;
+}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 21ed454c29..ac8d5d030f 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1999-2004 Paul Davis
+ Copyright (C) 1999-2010 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,6 +52,7 @@
#include "ardour/audioplaylist.h"
#include "ardour/audioregion.h"
#include "ardour/auditioner.h"
+#include "ardour/buffer_manager.h"
#include "ardour/buffer_set.h"
#include "ardour/bundle.h"
#include "ardour/butler.h"
@@ -70,6 +71,7 @@
#include "ardour/midi_track.h"
#include "ardour/midi_ui.h"
#include "ardour/named_selection.h"
+#include "ardour/process_thread.h"
#include "ardour/playlist.h"
#include "ardour/plugin_insert.h"
#include "ardour/port_insert.h"
@@ -129,9 +131,6 @@ Session::Session (AudioEngine &eng,
: _engine (eng),
_target_transport_speed (0.0),
_requested_return_frame (-1),
- _scratch_buffers(new BufferSet()),
- _silent_buffers(new BufferSet()),
- _mix_buffers(new BufferSet()),
mmc (0),
_mmc_port (default_mmc_port),
_mtc_port (default_mtc_port),
@@ -243,10 +242,6 @@ Session::destroy ()
clear_clicks ();
- delete _scratch_buffers;
- delete _silent_buffers;
- delete _mix_buffers;
-
/* clear out any pending dead wood from RCU managed objects */
routes.flush ();
@@ -1193,12 +1188,7 @@ Session::set_block_size (nframes_t nframes)
{
current_block_size = nframes;
- ensure_buffers(_scratch_buffers->available());
-
- delete [] _gain_automation_buffer;
- _gain_automation_buffer = new gain_t[nframes];
-
- allocate_pan_automation_buffers (nframes, _npan_buffers, true);
+ ensure_buffers ();
boost::shared_ptr<RouteList> r = routes.reader ();
@@ -3209,18 +3199,7 @@ Session::tempo_map_changed (const PropertyChange&)
void
Session::ensure_buffers (ChanCount howmany)
{
- if (current_block_size == 0) {
- return; // too early? (is this ok?)
- }
-
- for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
- size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
- _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
- _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
- _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
- }
-
- allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
+ BufferManager::ensure_buffers (howmany);
}
void
@@ -3439,31 +3418,6 @@ Session::route_name_internal (string n) const
return false;
}
-void
-Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
-{
- if (!force && howmany <= _npan_buffers) {
- return;
- }
-
- if (_pan_automation_buffer) {
-
- for (uint32_t i = 0; i < _npan_buffers; ++i) {
- delete [] _pan_automation_buffer[i];
- }
-
- delete [] _pan_automation_buffer;
- }
-
- _pan_automation_buffer = new pan_t*[howmany];
-
- for (uint32_t i = 0; i < howmany; ++i) {
- _pan_automation_buffer[i] = new pan_t[nframes];
- }
-
- _npan_buffers = howmany;
-}
-
int
Session::freeze_all (InterThreadInfo& itt)
{
@@ -3649,9 +3603,23 @@ Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
return result;
}
+gain_t*
+Session::gain_automation_buffer() const
+{
+ return ProcessThread::gain_automation_buffer ();
+}
+
+pan_t**
+Session::pan_automation_buffer() const
+{
+ return ProcessThread::pan_automation_buffer ();
+}
+
BufferSet&
Session::get_silent_buffers (ChanCount count)
{
+ return ProcessThread::get_silent_buffers (count);
+#if 0
assert(_silent_buffers->available() >= count);
_silent_buffers->set_count(count);
@@ -3662,11 +3630,14 @@ Session::get_silent_buffers (ChanCount count)
}
return *_silent_buffers;
+#endif
}
BufferSet&
Session::get_scratch_buffers (ChanCount count)
{
+ return ProcessThread::get_scratch_buffers (count);
+#if 0
if (count != ChanCount::ZERO) {
assert(_scratch_buffers->available() >= count);
_scratch_buffers->set_count(count);
@@ -3675,14 +3646,18 @@ Session::get_scratch_buffers (ChanCount count)
}
return *_scratch_buffers;
+#endif
}
BufferSet&
Session::get_mix_buffers (ChanCount count)
{
+ return ProcessThread::get_mix_buffers (count);
+#if 0
assert(_mix_buffers->available() >= count);
_mix_buffers->set_count(count);
return *_mix_buffers;
+#endif
}
uint32_t
diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc
index 834280de91..85c424e40c 100644
--- a/libs/ardour/session_process.cc
+++ b/libs/ardour/session_process.cc
@@ -33,6 +33,7 @@
#include "ardour/auditioner.h"
#include "ardour/butler.h"
#include "ardour/debug.h"
+#include "ardour/process_thread.h"
#include "ardour/session.h"
#include "ardour/slave.h"
#include "ardour/timestamps.h"
@@ -65,9 +66,13 @@ Session::process (nframes_t nframes)
post_transport ();
}
}
+
+ _engine.main_thread()->get_buffers ();
(this->*process_function) (nframes);
+ _engine.main_thread()->drop_buffers ();
+
// the ticker is for sending time information like MidiClock
nframes_t transport_frames = transport_frame();
BBT_Time transport_bbt;
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index f67714401f..1f116d82bc 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -210,9 +210,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
g_atomic_int_set (&_capture_load_min, 100);
_play_range = false;
_exporting = false;
- _gain_automation_buffer = 0;
- _pan_automation_buffer = 0;
- _npan_buffers = 0;
pending_abort = false;
destructive_index = 0;
first_file_data_format_reset = true;
diff --git a/libs/ardour/thread_buffers.cc b/libs/ardour/thread_buffers.cc
new file mode 100644
index 0000000000..e319acc329
--- /dev/null
+++ b/libs/ardour/thread_buffers.cc
@@ -0,0 +1,91 @@
+/*
+ Copyright (C) 2010 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.
+
+*/
+
+#include <iostream>
+
+#include "ardour/audioengine.h"
+#include "ardour/buffer_set.h"
+#include "ardour/thread_buffers.h"
+
+using namespace ARDOUR;
+using namespace std;
+
+ThreadBuffers::ThreadBuffers ()
+ : silent_buffers (new BufferSet)
+ , scratch_buffers (new BufferSet)
+ , mix_buffers (new BufferSet)
+ , gain_automation_buffer (0)
+ , pan_automation_buffer (0)
+ , npan_buffers (0)
+{
+}
+
+void
+ThreadBuffers::ensure_buffers (ChanCount howmany)
+{
+ // std::cerr << "ThreadBuffers " << this << " resize buffers with count = " << howmany << std::endl;
+
+ /* this is all protected by the process lock in the Session
+ */
+
+ if (howmany.n_total() == 0) {
+ return;
+ }
+
+ AudioEngine* _engine = AudioEngine::instance ();
+
+ for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+ size_t count = std::max (scratch_buffers->available().get(*t), howmany.get(*t));
+ size_t size = _engine->raw_buffer_size (*t);
+
+ scratch_buffers->ensure_buffers (*t, count, size);
+ mix_buffers->ensure_buffers (*t, count, size);
+ silent_buffers->ensure_buffers (*t, count, size);
+ }
+
+ delete [] gain_automation_buffer;
+ gain_automation_buffer = new gain_t[_engine->raw_buffer_size (DataType::AUDIO)];
+
+ allocate_pan_automation_buffers (_engine->raw_buffer_size (DataType::AUDIO), howmany.n_audio(), false);
+}
+
+void
+ThreadBuffers::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
+{
+ if (!force && howmany <= npan_buffers) {
+ return;
+ }
+
+ if (pan_automation_buffer) {
+
+ for (uint32_t i = 0; i < npan_buffers; ++i) {
+ delete [] pan_automation_buffer[i];
+ }
+
+ delete [] pan_automation_buffer;
+ }
+
+ pan_automation_buffer = new pan_t*[howmany];
+
+ for (uint32_t i = 0; i < howmany; ++i) {
+ pan_automation_buffer[i] = new pan_t[nframes];
+ }
+
+ npan_buffers = howmany;
+}
diff --git a/libs/ardour/wscript b/libs/ardour/wscript
index ce9d41d795..32127b6f7f 100644
--- a/libs/ardour/wscript
+++ b/libs/ardour/wscript
@@ -57,6 +57,7 @@ libardour_sources = [
'beats_frames_converter.cc',
'broadcast_info.cc',
'buffer.cc',
+ 'buffer_manager.cc',
'buffer_set.cc',
'bundle.cc',
'butler.cc',
@@ -140,6 +141,7 @@ libardour_sources = [
'port.cc',
'port_insert.cc',
'port_set.cc',
+ 'process_thread.cc',
'processor.cc',
'quantize.cc',
'rc_configuration.cc',
@@ -187,6 +189,7 @@ libardour_sources = [
'template_utils.cc',
'tempo.cc',
'tempo_map_importer.cc',
+ 'thread_buffers.cc',
'ticker.cc',
'track.cc',
'transient_detector.cc',
@@ -218,7 +221,7 @@ def configure(conf):
autowaf.configure(conf)
conf.check_tool('compiler_cxx gas')
autowaf.check_pkg(conf, 'aubio', uselib_store='AUBIO', atleast_version='0.3.2')
- autowaf.check_pkg(conf, 'jack', uselib_store='JACK', atleast_version='0.109.0')
+ autowaf.check_pkg(conf, 'jack', uselib_store='JACK', atleast_version='0.119.0')
autowaf.check_pkg(conf, 'libxml-2.0', uselib_store='XML')
autowaf.check_pkg(conf, 'lrdf', uselib_store='LRDF', atleast_version='0.4.0')
autowaf.check_pkg(conf, 'samplerate', uselib_store='SAMPLERATE', atleast_version='0.1.0')
diff --git a/libs/pbd/pbd/ringbufferNPT.h b/libs/pbd/pbd/ringbufferNPT.h
index 30c71a8b1a..2b6aa03d62 100644
--- a/libs/pbd/pbd/ringbufferNPT.h
+++ b/libs/pbd/pbd/ringbufferNPT.h
@@ -22,6 +22,7 @@
//#include <sys/mman.h>
+#include <cstring>
#include <glib.h>
/* ringbuffer class where the element size is not required to be a power of two */