new internal port type, round I, plus tiny fix for legalize_for_xml() (also for 2...
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 17 Oct 2007 16:49:31 +0000 (16:49 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 17 Oct 2007 16:49:31 +0000 (16:49 +0000)
git-svn-id: svn://localhost/ardour2/trunk@2559 d708f5d6-7413-0410-9779-e7cbd77b26cf

18 files changed:
gtk2_ardour/route_time_axis.cc
libs/ardour/SConscript
libs/ardour/ardour/audio_buffer.h
libs/ardour/ardour/audio_port.h
libs/ardour/ardour/audioengine.h
libs/ardour/ardour/buffer.h
libs/ardour/ardour/internal_audio_port.h [new file with mode: 0644]
libs/ardour/ardour/internal_port.h [new file with mode: 0644]
libs/ardour/ardour/midi_buffer.h
libs/ardour/ardour/types.h
libs/ardour/audio_buffer.cc
libs/ardour/audio_port.cc
libs/ardour/audioengine.cc
libs/ardour/internal_audio_port.cc [new file with mode: 0644]
libs/ardour/internal_port.cc [new file with mode: 0644]
libs/ardour/io.cc
libs/ardour/jack_port.cc
libs/ardour/midi_buffer.cc

index b5f04f537b2c8928aaee71d30dd1fcf4bb3d25f0..38e5a4c33000fdf5316ba1b8cf1ac3f2771e7d3d 100644 (file)
@@ -1694,7 +1694,7 @@ static string
 legalize_for_xml_node (string str)
 {
        string::size_type pos;
-       string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=:";
+       string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=:";
        string legal;
 
        legal = str;
index 556c6c3c9b81868108186624cb44b594bee8c7a0..4d68dc77256e157c57023ed64ff0d913b4040d3f 100644 (file)
@@ -65,6 +65,8 @@ gain.cc
 gdither.cc
 globals.cc
 import.cc
+internal_port.cc
+internal_audio_port.cc
 io.cc
 io_processor.cc
 jack_port.cc
index b2c62466bf0ef58c188af97d2ec0274355e34ea1..9342ac196ba589228fd176d6df5f3cc8afa82ab4 100644 (file)
@@ -102,6 +102,12 @@ public:
                _silent = false;
        }
 
+       /** Reallocate the buffer used internally to handle at least @nframes of data
+        * 
+        * Constructor MUST have been passed capacity!=0 or this will die (to prevent mem leaks).
+        */
+       void resize (size_t nframes);
+
        const Sample* data () const { return _data; }
        Sample* data () { return _data; }
 
index c6df9e0a2f7674d170f5971036e9ef87620eab7e..035ac9ed5fa216cf35ee251ab52d5b173d276d7a 100644 (file)
@@ -35,11 +35,11 @@ class AudioPort : public virtual Port {
    public:
        DataType type() const { return DataType::AUDIO; }
 
-       Buffer& get_buffer () {
+       virtual Buffer& get_buffer () {
                return _buffer;
        }
        
-       AudioBuffer& get_audio_buffer() {
+       virtual AudioBuffer& get_audio_buffer() {
                return _buffer;
        }
 
@@ -70,7 +70,8 @@ class AudioPort : public virtual Port {
   protected:
        friend class AudioEngine;
 
-       AudioPort ();
+       AudioPort ();          // data buffer comes from elsewhere (e.g. JACK)
+       AudioPort (nframes_t); // data buffer owned by ardour
        void reset ();
        
        /* engine isn't supposed to access below here */
index 17ba9f96149a5efbefdba445501622681e410b0a..34f7eb8c22d083fa1d2ef3f1bb1b49e9131c87ff 100644 (file)
@@ -42,6 +42,7 @@ namespace ARDOUR {
 
 class Session;
 class Port;
+class InternalPort;
 
 class AudioEngine : public sigc::trackable
 {
@@ -113,8 +114,8 @@ class AudioEngine : public sigc::trackable
                virtual const char *what() const throw() { return "could not connect to engine backend"; }
        };
 
-       Port *register_input_port (DataType type, const std::string& portname);
-       Port *register_output_port (DataType type, const std::string& portname);
+       Port *register_input_port (PortType, DataType, const std::string& portname);
+       Port *register_output_port (PortType, DataType, const std::string& portname);
        int   unregister_port (Port &);
        
        int connect (const std::string& source, const std::string& destination);
@@ -219,11 +220,13 @@ class AudioEngine : public sigc::trackable
 
        SerializedRCUManager<Ports> ports;
 
-       Port *register_port (DataType type, const std::string& portname, bool input);
+       Port *register_port (PortType ptype, DataType type, const std::string& portname, bool input);
 
        int    process_callback (nframes_t nframes);
        void   remove_all_ports ();
 
+       InternalPort* get_internal_port (const std::string& short_name);
+
        typedef std::pair<std::string,std::string> PortConnection;
        typedef std::list<PortConnection> PortConnections;
 
index 18c83f8bfb6e3fafca80650781faee2eace23747..fd943602262572704cfde72ba156a3200b8c75b6 100644 (file)
@@ -59,6 +59,13 @@ public:
        DataType type() const { return _type; }
 
        bool silent() const { return _silent; }
+       
+       /** Reallocate the buffer used internally to handle at least @a size_t units of data.
+        *
+        * The buffer is not silent after this operation. the @a capacity argument
+        * passed to the constructor must have been non-zero.
+        */
+       virtual void resize(size_t) = 0;
 
        /** Clear (eg zero, or empty) buffer starting at TIME @a offset */
        virtual void silence(nframes_t len, nframes_t offset=0) = 0;
diff --git a/libs/ardour/ardour/internal_audio_port.h b/libs/ardour/ardour/internal_audio_port.h
new file mode 100644 (file)
index 0000000..7b70989
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+    Copyright (C) 2007 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: port.h 712 2006-07-28 01:08:57Z drobilla $
+*/
+
+#ifndef __ardour_internal_audio_port_h__
+#define __ardour_internal_audio_port_h__
+
+#include <sigc++/signal.h>
+#include <pbd/failed_constructor.h>
+#include <ardour/ardour.h>
+#include <ardour/internal_port.h>
+#include <ardour/audio_port.h>
+
+namespace ARDOUR {
+
+class AudioEngine;
+class InternalAudioPort : public AudioPort, public InternalPort {
+   public:
+       void cycle_start(nframes_t nframes) {
+               _buffer.silence (nframes);
+       }
+
+       AudioBuffer& get_audio_buffer();
+
+       void set_mixdown_function (void (*func)(const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t));
+       void reset ();
+
+  protected:
+       friend class AudioEngine;
+
+       InternalAudioPort (const std::string& name, Flags flags);
+       void (*_mixdown)(const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t);
+
+       static void default_mixdown (const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t);
+};
+} // namespace ARDOUR
+
+#endif /* __ardour_internal_audio_port_h__ */
diff --git a/libs/ardour/ardour/internal_port.h b/libs/ardour/ardour/internal_port.h
new file mode 100644 (file)
index 0000000..e6053c0
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+    Copyright (C) 2007 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_internal_port_h__
+#define __ardour_internal_port_h__
+
+#include <list>
+
+#include <sigc++/signal.h>
+#include <pbd/failed_constructor.h>
+#include <ardour/port.h>
+
+namespace ARDOUR {
+
+class AudioEngine;
+class Buffer;
+
+/** Abstract class representing internal (ardour<->ardour only) ports
+ */
+class InternalPort : public virtual Port {
+   public:
+
+       ~InternalPort();
+
+       std::string short_name();
+       
+       int set_name (std::string str);
+
+       int connected () const;
+
+       int reestablish ();
+       
+       bool connected_to (const std::string& portname) const;
+
+       const char ** get_connections () const;
+       bool monitoring_input () const { return false; }
+
+       void ensure_monitor_input (bool yn) {}
+       void request_monitor_input (bool yn) {}
+
+       nframes_t latency () const { return _latency; }
+       nframes_t total_latency() const { return _latency; }
+
+       void set_latency (nframes_t nframes);
+
+       static void connect (InternalPort& src, InternalPort& dst);
+       static void disconnect (InternalPort& a, InternalPort& b);
+
+  protected:
+       friend class AudioEngine;
+
+       InternalPort (const std::string&, DataType type, Flags flags);
+
+       int disconnect ();
+       void recompute_total_latency() const;
+       
+       std::list<InternalPort*> _connections;
+       nframes_t _latency;
+
+       static AudioEngine* engine;
+       static void set_engine (AudioEngine* e);
+};
+} // namespace ARDOUR
+
+#endif /* __ardour_internal_port_h__ */
index 2ba6a0990b116dadac1c9b49121794317e6e3ec7..953d424296a8f1930099aef2387850f28817e403 100644 (file)
@@ -42,6 +42,8 @@ public:
        bool  push_back(const ARDOUR::MidiEvent& event);
        bool  push_back(const jack_midi_event_t& event);
        Byte* reserve(double time, size_t size);
+
+       void resize(size_t);
        
        bool merge(const MidiBuffer& a, const MidiBuffer& b);
        
index 5b5071331352f9ed50e28e214fac0c4f5e6f0365..0c5a8e044f080a55cbb8d64043812224b627f96e 100644 (file)
@@ -379,6 +379,11 @@ namespace ARDOUR {
                SrcFastest
        };
 
+       enum PortType {
+               Jack,
+               Internal
+       };
+
 } // namespace ARDOUR
 
 std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf);
index 059b61ed2f1ea4a41c4446b130209c487274e8be..b07f70be1f8aa99f7afdca4875b645375a58e130 100644 (file)
@@ -29,19 +29,13 @@ namespace ARDOUR {
 
 AudioBuffer::AudioBuffer(size_t capacity)
        : Buffer(DataType::AUDIO, capacity)
-       , _owns_data(false)
-       , _data(NULL)
+       , _owns_data (false)
+       , _data (0)
 {
-       _size = capacity; // For audio buffers, size = capacity (always)
-       if (capacity > 0) {
-#ifdef NO_POSIX_MEMALIGN
-               _data =  (Sample *) malloc(sizeof(Sample) * capacity);
-#else
-               posix_memalign((void**)&_data, CPU_CACHE_ALIGN, sizeof(Sample) * capacity);
-#endif 
-               assert(_data);
-               _owns_data = true;
-               clear();
+       if (_capacity) {
+               _owns_data = true; // prevent resize() from gagging
+               resize (_capacity);
+               silence (_capacity);
        }
 }
 
@@ -51,6 +45,31 @@ AudioBuffer::~AudioBuffer()
                free(_data);
 }
 
+void
+AudioBuffer::resize (size_t size)
+{
+       assert (_owns_data);
+
+       if (size < _capacity) {
+               return;
+       }
+
+       if (_data) {
+               free (_data);
+       }
+
+       _capacity = size;
+       _size = size;
+       _silent = false;
+
+#ifdef NO_POSIX_MEMALIGN
+       _data =  (Sample *) malloc(sizeof(Sample) * _capacity);
+#else
+       posix_memalign((void**)&_data, CPU_CACHE_ALIGN, sizeof(Sample) * _capacity);
+#endif 
+       
+       _owns_data = true;
+}
 
 } // namespace ARDOUR
 
index 23c8ab8335cb520d338210eed427e6435e20dcee..aa8b363134627123d028b8deea7aa152357a0bba 100644 (file)
@@ -33,6 +33,13 @@ AudioPort::AudioPort()
        reset();
 }
 
+AudioPort::AudioPort(nframes_t nframes)
+       : _buffer (nframes)
+{
+       _type = DataType::AUDIO;
+       reset();
+}
+
 void
 AudioPort::reset()
 {
index 63a51b76c488159fd1715953f41d9d0bf8a00a2e..4552de11866c01ebc512928a54cea868bb2264db 100644 (file)
@@ -32,6 +32,7 @@
 #include <ardour/buffer.h>
 #include <ardour/port.h>
 #include <ardour/jack_audio_port.h>
+#include <ardour/internal_audio_port.h>
 #include <ardour/jack_midi_port.h>
 #include <ardour/session.h>
 #include <ardour/cycle_timer.h>
@@ -508,17 +509,33 @@ AudioEngine::remove_session ()
 }
 
 Port *
-AudioEngine::register_port (DataType type, const string& portname, bool input)
+AudioEngine::register_port (PortType ptype, DataType dtype, const string& portname, bool input)
 {
        Port* newport = 0;
 
        try {
-               if (type == DataType::AUDIO)
-                       newport = new JackAudioPort (portname, (input ? Port::IsInput : Port::IsOutput));
-               else if (type == DataType::MIDI)
-                       newport = new JackMidiPort (portname, (input ? Port::IsInput : Port::IsOutput));
-               else
-                       throw unknown_type();
+               switch (ptype) {
+               case Jack:
+                       if (dtype == DataType::AUDIO) {
+                               newport = new JackAudioPort (portname, (input ? Port::IsInput : Port::IsOutput));
+                       } else if (dtype == DataType::MIDI) {
+                               newport = new JackMidiPort (portname, (input ? Port::IsInput : Port::IsOutput));
+                       } else {
+                               throw unknown_type();
+                       }
+                       break;
+
+               case Internal:
+                       if (dtype == DataType::AUDIO) {
+                               newport = new InternalAudioPort (portname, (input ? Port::IsInput : Port::IsOutput));
+                       } else if (dtype == DataType::MIDI) {
+                               error << _("Internal MIDI ports are not implemented yet!") << endmsg;
+                               throw unknown_type();
+                       } else {
+                               throw unknown_type();
+                       }
+                       break;
+               }
        
                if (newport != 0) {
                        RCUWriter<Ports> writer (ports);
@@ -535,16 +552,30 @@ AudioEngine::register_port (DataType type, const string& portname, bool input)
        }
 }
 
+InternalPort*
+AudioEngine::get_internal_port (const std::string& short_name)
+{
+       boost::shared_ptr<Ports> p = ports.reader();
+       
+       for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
+               if ((*i)->short_name() == short_name) {
+                       return dynamic_cast<InternalPort*> (*i);
+               }
+       }
+       return 0;
+}
+
+
 Port *
-AudioEngine::register_input_port (DataType type, const string& portname)
+AudioEngine::register_input_port (PortType ptype, DataType type, const string& portname)
 {
-       return register_port (type, portname, true);
+       return register_port (ptype, type, portname, true);
 }
 
 Port *
-AudioEngine::register_output_port (DataType type, const string& portname)
+AudioEngine::register_output_port (PortType ptype, DataType type, const string& portname)
 {
-       return register_port (type, portname, false);
+       return register_port (ptype, type, portname, false);
 }
 
 int          
@@ -565,7 +596,6 @@ AudioEngine::unregister_port (Port& port)
                for (Ports::iterator i = ps->begin(); i != ps->end(); ++i) {
                        if ((*i) == &port) {
                                remove_connections_for (port);
-                               cerr << "eraseing " << (*i)->name() << endl;
                                delete *i;
                                ps->erase (i);
                                break;
@@ -581,6 +611,8 @@ AudioEngine::unregister_port (Port& port)
 int 
 AudioEngine::connect (const string& source, const string& destination)
 {
+       int ret;
+
        if (!_running) {
                if (!_has_run) {
                        fatal << _("connect called before engine was started") << endmsg;
@@ -589,11 +621,26 @@ AudioEngine::connect (const string& source, const string& destination)
                        return -1;
                }
        }
-       
+
        string s = make_port_name_non_relative (source);
        string d = make_port_name_non_relative (destination);
+               
+       if (source.substr (0, 9) == "internal:") {
+               if (destination.substr (0, 9) == "internal:") {
+                       InternalPort* src = get_internal_port (source);
+                       InternalPort* dst = get_internal_port (destination);
+
+                       InternalPort::connect (*src, *dst);
+                       ret = 0;
 
-       int ret = jack_connect (_jack, s.c_str(), d.c_str());
+               } else {
+                       ret = -1;
+               }
+
+       } else {
+       
+               ret = jack_connect (_jack, s.c_str(), d.c_str());
+       }
 
        if (ret == 0) {
                pair<string,string> c (s, d);
@@ -614,6 +661,8 @@ AudioEngine::connect (const string& source, const string& destination)
 int 
 AudioEngine::disconnect (const string& source, const string& destination)
 {
+       int ret;
+
        if (!_running) {
                if (!_has_run) {
                        fatal << _("disconnect called before engine was started") << endmsg;
@@ -626,7 +675,21 @@ AudioEngine::disconnect (const string& source, const string& destination)
        string s = make_port_name_non_relative (source);
        string d = make_port_name_non_relative (destination);
 
-       int ret = jack_disconnect (_jack, s.c_str(), d.c_str());
+       if (source.substr (0, 9) == "internal:") {
+               if (destination.substr (0, 9) == "internal:") {
+                       InternalPort* src = get_internal_port (source);
+                       InternalPort* dst = get_internal_port (destination);
+
+                       InternalPort::disconnect (*src, *dst);
+                       ret = 0;
+               } else {
+                       ret = -1;
+               }
+
+       } else {
+       
+               ret = jack_disconnect (_jack, s.c_str(), d.c_str());
+       }
 
        if (ret == 0) {
                pair<string,string> c (s, d);
diff --git a/libs/ardour/internal_audio_port.cc b/libs/ardour/internal_audio_port.cc
new file mode 100644 (file)
index 0000000..f5c5c5d
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+    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.
+*/
+
+#include <cassert>
+#include <ardour/internal_audio_port.h>
+#include <ardour/audioengine.h>
+
+using namespace ARDOUR;
+using namespace std;
+
+void
+InternalAudioPort::default_mixdown (const list<InternalPort*>& ports, AudioBuffer& dest, nframes_t cnt, nframes_t offset)
+{
+       list<InternalPort*>::const_iterator p = ports.begin();
+
+       dest.read_from ((dynamic_cast<AudioPort*>(*p))->get_audio_buffer(), cnt, offset);
+
+       for (; p != ports.end(); ++p) {
+               dest.accumulate_from ((dynamic_cast<AudioPort*>(*p))->get_audio_buffer(), cnt, offset);
+       }
+}
+
+InternalAudioPort::InternalAudioPort(const string& name, Flags flgs)
+       : AudioPort (engine->frames_per_cycle())
+       , InternalPort (name, DataType::AUDIO, flgs)
+{
+       _mixdown = default_mixdown;
+}
+
+void 
+InternalAudioPort::set_mixdown_function (void (*func)(const list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t))
+{
+       _mixdown = func;
+}
+
+void
+InternalAudioPort::reset ()
+{
+       _buffer.resize (engine->frames_per_cycle());
+       _buffer.silence (_buffer.size());
+}
+
+AudioBuffer&
+InternalAudioPort::get_audio_buffer ()
+{
+       if (_connections.empty()) {
+               return AudioPort::get_audio_buffer();
+       }
+
+       /* XXX what about offset/size being more dynamic ? */
+       
+       (*_mixdown) (_connections, _buffer, _buffer.size(), 0);
+
+       return _buffer;
+}
diff --git a/libs/ardour/internal_port.cc b/libs/ardour/internal_port.cc
new file mode 100644 (file)
index 0000000..3854931
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+    Copyright (C) 2007 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 <pbd/error.h>
+#include <ardour/internal_port.h>
+#include <ardour/audioengine.h>
+
+#include "i18n.h"
+
+using namespace ARDOUR;
+using namespace std;
+
+AudioEngine* InternalPort::engine = 0;
+
+void
+InternalPort::set_engine (AudioEngine* e) 
+{
+       engine = e;
+}
+
+InternalPort::InternalPort (const string& str, DataType type, Flags flags)
+{
+       set_name (str);
+       _type = type;
+       _flags = flags;
+}
+
+InternalPort::~InternalPort ()
+{
+       disconnect ();
+}
+
+void
+InternalPort::set_latency (nframes_t val)
+{
+       _latency = val;
+}
+
+bool
+InternalPort::connected_to (const string& portname) const
+{
+       /* caller must hold process lock */
+
+       for (list<InternalPort*>::const_iterator p = _connections.begin(); p != _connections.end(); ++p) {
+               if ((*p)->name() == portname) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+const char** 
+InternalPort::get_connections () const
+{
+       /* caller must hold process lock */
+
+       int i;
+       list<InternalPort*>::const_iterator p;
+
+       if (_connections.empty()) {
+               return 0;
+       }
+
+       char **names = (char**) malloc (sizeof (char*) * ( _connections.size() + 1));
+       
+
+       for (i = 0, p = _connections.begin(); p != _connections.end(); ++p, ++i) {
+               names[i] = (char*) (*p)->name().c_str();
+       }
+
+       names[i] = 0;
+
+       return (const char**) names;
+}
+
+int
+InternalPort::connected() const 
+{
+       /* caller must hold process lock */
+       return !_connections.empty();
+}
+
+int
+InternalPort::set_name (string str)
+{
+       _name = "internal:";
+       _name += str;
+
+       return 0;
+}
+
+string
+InternalPort::short_name () 
+{
+       return _name.substr (9);
+}
+
+void
+InternalPort::connect (InternalPort& src, InternalPort& dst)
+{
+       /* caller must hold process lock */
+
+       src._connections.push_back (&dst);
+       dst._connections.push_back (&src);
+}
+
+void
+InternalPort::disconnect (InternalPort& a, InternalPort& b)
+{
+       /* caller must hold process lock */
+       a._connections.remove (&b);
+       b._connections.remove (&a);
+}
+
+int
+InternalPort::disconnect ()
+{
+       /* caller must hold process lock */
+
+       for (list<InternalPort*>::const_iterator p = _connections.begin(); p != _connections.end(); ) {
+               list<InternalPort*>::const_iterator tmp;
+
+               tmp = p;
+               ++tmp;
+                      
+               disconnect (*this, **p);
+               
+               p = tmp;
+       }
+
+       _connections.clear ();
+       
+       return 0;
+}
+
+int
+InternalPort::reestablish ()
+{
+       return 0;
+}
+
+void
+InternalPort::recompute_total_latency () const
+{
+       return;
+}
+
index 0c4ee414963fbb6f72d95a2dff59cf1c1268b2af..95f40f1f80ea0ec2176c1205c03fc14b8c7254e5 100644 (file)
@@ -602,7 +602,7 @@ IO::add_output_port (string destination, void* src, DataType type)
                                snprintf (name, sizeof (name), _("%s/out %u"), _name.c_str(), find_output_port_hole());
                        }
                        
-                       if ((our_port = _session.engine().register_output_port (type, name)) == 0) {
+                       if ((our_port = _session.engine().register_output_port (Jack, type, name)) == 0) {
                                error << string_compose(_("IO: cannot register output port %1"), name) << endmsg;
                                return -1;
                        }
@@ -713,7 +713,7 @@ IO::add_input_port (string source, void* src, DataType type)
                                snprintf (name, sizeof (name), _("%s/in %u"), _name.c_str(), find_input_port_hole());
                        }
 
-                       if ((our_port = _session.engine().register_input_port (type, name)) == 0) {
+                       if ((our_port = _session.engine().register_input_port (Jack, type, name)) == 0) {
                                error << string_compose(_("IO: cannot register input port %1"), name) << endmsg;
                                return -1;
                        }
@@ -822,7 +822,7 @@ IO::ensure_inputs_locked (ChanCount count, bool clear, void* src)
 
                        try {
 
-                               if ((input_port = _session.engine().register_input_port (*t, buf)) == 0) {
+                               if ((input_port = _session.engine().register_input_port (Jack, *t, buf)) == 0) {
                                        error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
                                        return -1;
                                }
@@ -938,7 +938,7 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
                                }
 
                                try {
-                                       if ((port = _session.engine().register_input_port (*t, buf)) == 0) {
+                                       if ((port = _session.engine().register_input_port (Jack, *t, buf)) == 0) {
                                                error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
                                                return -1;
                                        }
@@ -970,7 +970,7 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
                                }
 
                                try { 
-                                       if ((port = _session.engine().register_output_port (*t, buf)) == 0) {
+                                       if ((port = _session.engine().register_output_port (Jack, *t, buf)) == 0) {
                                                error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
                                                return -1;
                                        }
@@ -1090,7 +1090,7 @@ IO::ensure_outputs_locked (ChanCount count, bool clear, void* src)
                                snprintf (buf, sizeof (buf), _("%s/out %u"), _name.c_str(), find_output_port_hole());
                        }
 
-                       if ((output_port = _session.engine().register_output_port (*t, buf)) == 0) {
+                       if ((output_port = _session.engine().register_output_port (Jack, *t, buf)) == 0) {
                                error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
                                return -1;
                        }
index 7f56e396ceb60fd63e7f942bd5c77f9a64cb9768..221e46b076ad1d9551565ea447bf4eabedabeec1 100644 (file)
@@ -109,3 +109,4 @@ JackPort::recompute_total_latency () const
 #endif
 }
 
+
index e971e9ae8ff1cae71f8a7ba920c94b18a742bbc9..52f04eaf910a9162ee6fa1d2aefd9ee75e0d30aa 100644 (file)
@@ -38,20 +38,31 @@ MidiBuffer::MidiBuffer(size_t capacity)
        , _events(NULL)
        , _data(NULL)
 {
-       assert(capacity > 0);
+       _data = 0;
+       resize (_capacity);
+       silence(_capacity);
+}
 
-       _size = 0;
+void
+MidiBuffer::resize (size_t size)
+{
+       assert(size > 0);
 
+       if (_data) {
+               free (_data);
+       }
+
+       _size = 0;
+       _capacity = size;
 #ifdef NO_POSIX_MEMALIGN
-       _events = (MidiEvent *) malloc(sizeof(MidiEvent) * capacity);
-       _data = (Byte *) malloc(sizeof(Byte) * capacity * MAX_EVENT_SIZE);
+       _events = (MidiEvent *) malloc(sizeof(MidiEvent) * _capacity);
+       _data = (Byte *) malloc(sizeof(Byte) * _capacity * MAX_EVENT_SIZE);
 #else
-       posix_memalign((void**)&_events, CPU_CACHE_ALIGN, sizeof(MidiEvent) * capacity);
-       posix_memalign((void**)&_data, CPU_CACHE_ALIGN, sizeof(Byte) * capacity * MAX_EVENT_SIZE);
+       posix_memalign((void**)&_events, CPU_CACHE_ALIGN, sizeof(MidiEvent) * _capacity);
+       posix_memalign((void**)&_data, CPU_CACHE_ALIGN, sizeof(Byte) * _capacity * MAX_EVENT_SIZE);
 #endif 
        assert(_data);
        assert(_events);
-       silence(_capacity);
 }
 
 void