Rework Port class hierarchy a bit. Hopefully now simpler, and should
authorCarl Hetherington <carl@carlh.net>
Wed, 21 Jan 2009 02:27:21 +0000 (02:27 +0000)
committerCarl Hetherington <carl@carlh.net>
Wed, 21 Jan 2009 02:27:21 +0000 (02:27 +0000)
support connection of JACK ports with internal ones.

git-svn-id: svn://localhost/ardour2/branches/3.0@4417 d708f5d6-7413-0410-9779-e7cbd77b26cf

40 files changed:
gtk2_ardour/io_selector.cc
gtk2_ardour/port_group.cc
libs/ardour/SConscript
libs/ardour/ardour/audio_diskstream.h
libs/ardour/ardour/audio_port.h
libs/ardour/ardour/audioengine.h
libs/ardour/ardour/base_audio_port.h [deleted file]
libs/ardour/ardour/base_midi_port.h [deleted file]
libs/ardour/ardour/diskstream.h
libs/ardour/ardour/internal_audio_port.h [deleted file]
libs/ardour/ardour/internal_port.h [deleted file]
libs/ardour/ardour/jack_audio_port.h [deleted file]
libs/ardour/ardour/jack_midi_port.h [deleted file]
libs/ardour/ardour/midi_diskstream.h
libs/ardour/ardour/midi_port.h
libs/ardour/ardour/port.h
libs/ardour/ardour/port_set.h
libs/ardour/audio_diskstream.cc
libs/ardour/audio_port.cc
libs/ardour/audio_track.cc
libs/ardour/audioengine.cc
libs/ardour/base_audio_port.cc [deleted file]
libs/ardour/base_midi_port.cc [deleted file]
libs/ardour/export_channel.cc
libs/ardour/internal_audio_port.cc [deleted file]
libs/ardour/internal_port.cc [deleted file]
libs/ardour/io.cc
libs/ardour/jack_audio_port.cc [deleted file]
libs/ardour/jack_midi_port.cc [deleted file]
libs/ardour/jack_port.cc [deleted file]
libs/ardour/meter.cc
libs/ardour/midi_port.cc
libs/ardour/mix.cc
libs/ardour/panner.cc
libs/ardour/plugin_insert.cc
libs/ardour/port.cc
libs/ardour/port_set.cc
libs/ardour/session.cc
libs/ardour/session_click.cc
libs/ardour/track.cc

index 06274df95effc45ba8838687c3d9246f1ff3a008..f438c21d3f354cdc3dd0b79aa671730aff25235a 100644 (file)
@@ -30,6 +30,7 @@
 #include "ardour/audio_track.h"
 #include "ardour/midi_track.h"
 #include "ardour/data_type.h"
+#include "ardour/port.h"
 #include "ardour/bundle.h"
 
 #include "io_selector.h"
index 4157348d8eb2689c06df5cac03ed9513114500da..228b5f0a4d96f8b395690fd94fe8f61c06332fb6 100644 (file)
@@ -24,6 +24,7 @@
 #include "ardour/audio_track.h"
 #include "ardour/midi_track.h"
 #include "ardour/audioengine.h"
+#include "ardour/port.h"
 #include "ardour/bundle.h"
 #include <boost/shared_ptr.hpp>
 #include <cstring>
index f21b623ed29bf28a5af4fcfc3f7a25e0cb50304e..f34dd9b078fdfb285d45b0eefde7879c1e8956eb 100644 (file)
@@ -52,8 +52,6 @@ automatable.cc
 automation.cc
 automation_control.cc
 automation_list.cc
-base_audio_port.cc
-base_midi_port.cc
 broadcast_info.cc
 buffer.cc
 buffer_set.cc
@@ -96,9 +94,6 @@ globals.cc
 import.cc
 io.cc
 io_processor.cc
-jack_audio_port.cc
-jack_midi_port.cc
-jack_port.cc
 jack_slave.cc
 ladspa_plugin.cc
 location.cc
index 79ffe3d490d5fe7f9f61b1649de79e1d896acb6c..92c8e82df82b91dabef2af1503a0f03101855615 100644 (file)
 #include <ardour/session.h>
 #include <ardour/route_group.h>
 #include <ardour/route.h>
-#include <ardour/port.h>
 #include <ardour/utils.h>
 #include <ardour/diskstream.h>
 #include <ardour/audioplaylist.h>
+#include <ardour/port.h>
 
 struct tm;
 
index fa416864e951535940ee264eca90a1043da3fd70..339165da0f71471c96e54ff4f267e0da36ebab0e 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2002 Paul Davis 
+    Copyright (C) 2002-2009 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
 #ifndef __ardour_audio_port_h__
 #define __ardour_audio_port_h__
 
-#include <ardour/base_audio_port.h>
+#include <ardour/port.h>
+#include <ardour/audio_buffer.h>
 
 namespace ARDOUR {
 
-class AudioPort : public BaseAudioPort, public PortFacade {
-
+class AudioPort : public Port 
+{
    public:
        ~AudioPort();
 
-       void reset ();
+       DataType type () const {
+               return DataType::AUDIO;
+       }
+       
+       void cycle_start (nframes_t, nframes_t);
+       void cycle_end (nframes_t, nframes_t);
 
-       void cycle_start (nframes_t nframes, nframes_t offset);
-       void cycle_end (nframes_t nframes, nframes_t offset);
+       Buffer& get_buffer (nframes_t nframes, nframes_t offset) {
+               return get_audio_buffer (nframes, offset);
+       }
        
-       AudioBuffer& get_audio_buffer( nframes_t nframes, nframes_t offset );
+       AudioBuffer& get_audio_buffer (nframes_t, nframes_t);
+
+       void reset ();
 
   protected:
        friend class AudioEngine;
 
-       AudioPort (const std::string&, Flags, bool external, nframes_t); 
+       AudioPort (std::string const &, Flags, bool, nframes_t);
+  
   private:
+       void mixdown (nframes_t, nframes_t, bool);
+
        bool _has_been_mixed_down;
+       AudioBuffer* _buffer;
+       bool _own_buffer;
 };
  
 } // namespace ARDOUR
index 89abc6669ac272400517aecd320fb526509ff70a..16090a7d77eebf408d7b7826d5a4d91c531217bf 100644 (file)
@@ -146,13 +146,11 @@ class AudioEngine : public sigc::trackable
                return get_nth_physical (type, n, JackPortIsOutput);
        }
 
-       nframes_t get_port_total_latency (const Port&);
        void update_total_latencies ();
        void update_total_latency (const Port&);
 
-       /** Caller may not delete the object pointed to by the return value
-       */
-       Port *get_port_by_name (const std::string& name, bool keep = true);
+       Port *get_port_by_name (const std::string &);
+       Port *get_port_by_name_locked (const std::string &);
 
        enum TransportState {
                TransportStopped = JackTransportStopped,
@@ -234,8 +232,6 @@ class AudioEngine : public sigc::trackable
        int    process_callback (nframes_t nframes);
        void   remove_all_ports ();
 
-       Port* get_port (const std::string& short_name);
-
        typedef std::pair<std::string,std::string> PortConnection;
        typedef std::list<PortConnection> PortConnections;
 
diff --git a/libs/ardour/ardour/base_audio_port.h b/libs/ardour/ardour/base_audio_port.h
deleted file mode 100644 (file)
index 5bad901..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
-    Copyright (C) 2002 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id: port.h 712 2006-07-28 01:08:57Z drobilla $
-*/
-
-#ifndef __ardour_base_audio_port_h__
-#define __ardour_base_audio_port_h__
-
-#include <string>
-
-#include <sigc++/signal.h>
-
-#include <pbd/failed_constructor.h>
-
-#include <ardour/ardour.h>
-#include <ardour/port.h>
-#include <ardour/audio_buffer.h>
-
-namespace ARDOUR {
-
-class AudioEngine;
-
-class BaseAudioPort : public virtual Port {
-  public:
-       virtual ~BaseAudioPort();
-
-       DataType type() const { return DataType::AUDIO; }
-
-       virtual Buffer& get_buffer ( nframes_t nframes, nframes_t offset ) {
-               return get_audio_buffer( nframes, offset);
-       }
-
-       virtual AudioBuffer& get_audio_buffer (nframes_t nframes, nframes_t offset) = 0;
-       
-       void reset ();
-
-       void reset_overs () {
-               /* XXX NOT THREAD SAFE */
-               _short_overs = 0;
-               _long_overs = 0;
-               _overlen = 0;
-       }
-
-       void reset_peak_meter () {
-               /* XXX NOT THREAD SAFE */
-               _peak = 0;
-       }
-       
-       void reset_meters () {
-               /* XXX NOT THREAD SAFE */
-               reset_peak_meter ();
-               reset_overs ();
-       }
-
-       float  peak_db() const { return _peak_db; }
-       Sample peak()    const { return _peak; }
-
-       uint32_t short_overs () const { return _short_overs; }
-       uint32_t long_overs ()  const { return _long_overs; }
-       
-       static void set_short_over_length (nframes_t);
-       static void set_long_over_length (nframes_t);
-
-       void set_mixdown_function (void (*func)(const std::set<Port*>&, AudioBuffer*, nframes_t, nframes_t, bool));
-
-  protected:
-       BaseAudioPort (const std::string& name, Flags flags);
-
-       AudioBuffer* _buffer;
-       nframes_t    _overlen;
-       Sample       _peak;
-       float        _peak_db;
-       uint32_t     _short_overs;
-       uint32_t     _long_overs;
-       bool         _own_buffer;
-
-       void (*_mixdown)(const std::set<Port*>&, AudioBuffer*, nframes_t, nframes_t, bool);
-
-       static void default_mixdown (const std::set<Port*>&, AudioBuffer*, nframes_t, nframes_t, bool);
-       
-       static nframes_t _long_over_length;
-       static nframes_t _short_over_length;
-};
-} // namespace ARDOUR
-
-#endif /* __ardour_base_audio_port_h__ */
diff --git a/libs/ardour/ardour/base_midi_port.h b/libs/ardour/ardour/base_midi_port.h
deleted file mode 100644 (file)
index 5ea18fc..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
-    Copyright (C) 2002 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id: port.h 712 2006-07-28 01:08:57Z drobilla $
-*/
-
-#ifndef __ardour_base_midi_port_h__
-#define __ardour_base_midi_port_h__
-
-#include <sigc++/signal.h>
-#include <pbd/failed_constructor.h>
-#include <ardour/ardour.h>
-#include <ardour/port.h>
-#include <ardour/midi_buffer.h>
-
-namespace ARDOUR {
-
-class MidiEngine;
-
-class BaseMidiPort : public virtual Port {
-   public:
-       virtual ~BaseMidiPort();
-       
-       DataType type() const { return DataType::MIDI; }
-
-       Buffer& get_buffer( nframes_t nframes, nframes_t offset ) {
-               return get_midi_buffer( nframes, offset );
-       }
-
-       virtual MidiBuffer& get_midi_buffer (nframes_t nframes, nframes_t offset ) = 0;
-       
-       size_t capacity() { return _buffer->capacity(); }
-       size_t size()     { return _buffer->size(); }
-
-       void set_mixdown_function (void (*func)(const std::set<Port*>&, MidiBuffer*, nframes_t, nframes_t, bool));
-
-  protected:
-       BaseMidiPort (const std::string& name, Flags);
-       
-       MidiBuffer*     _buffer;
-       bool            _own_buffer;
-
-       void (*_mixdown)(const std::set<Port*>&, MidiBuffer*, nframes_t, nframes_t, bool);
-       static void default_mixdown (const std::set<Port*>&, MidiBuffer*, nframes_t, nframes_t, bool);
-};
-} // namespace ARDOUR
-
-#endif /* __ardour_base_midi_port_h__ */
index 24655a1d416633e0ef72c368e7399b3b7f579053..b0ac26342ff110d73c0fd3a81b1f800f8cd9fd77 100644 (file)
@@ -40,7 +40,6 @@
 #include <ardour/session.h>
 #include <ardour/route_group.h>
 #include <ardour/route.h>
-#include <ardour/port.h>
 #include <ardour/utils.h>
 
 struct tm;
diff --git a/libs/ardour/ardour/internal_audio_port.h b/libs/ardour/ardour/internal_audio_port.h
deleted file mode 100644 (file)
index 7b70989..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-    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
deleted file mode 100644 (file)
index e6053c0..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-    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__ */
diff --git a/libs/ardour/ardour/jack_audio_port.h b/libs/ardour/ardour/jack_audio_port.h
deleted file mode 100644 (file)
index 5ca2713..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-    Copyright (C) 2002 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id: port.h 712 2006-07-28 01:08:57Z drobilla $
-*/
-
-#ifndef __ardour_jack_audio_port_h__
-#define __ardour_jack_audio_port_h__
-
-#include <sigc++/signal.h>
-#include <pbd/failed_constructor.h>
-#include <ardour/ardour.h>
-#include <ardour/jack_port.h>
-#include <ardour/audio_port.h>
-
-namespace ARDOUR {
-
-class AudioEngine;
-class JackAudioPort : public JackPort, public BaseAudioPort {
-   public:
-       void cycle_end (nframes_t nframes, nframes_t offset);
-       void cycle_start (nframes_t nframes, nframes_t offset);
-
-       int reestablish ();
-
-       AudioBuffer& get_audio_buffer( nframes_t nframes, nframes_t offset );
-
-  protected:
-       friend class AudioPort;
-
-       JackAudioPort (const std::string& name, Flags flags, AudioBuffer* buf);
-
-       AudioBuffer* _source_buffer;
-  private:
-       bool    _has_been_mixed_down;
-};
-} // namespace ARDOUR
-
-#endif /* __ardour_jack_audio_port_h__ */
diff --git a/libs/ardour/ardour/jack_midi_port.h b/libs/ardour/ardour/jack_midi_port.h
deleted file mode 100644 (file)
index 91cbd40..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-    Copyright (C) 2002 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id: port.h 712 2006-07-28 01:08:57Z drobilla $
-*/
-
-#ifndef __ardour_jack_midi_port_h__
-#define __ardour_jack_midi_port_h__
-
-#include <sigc++/signal.h>
-#include <pbd/failed_constructor.h>
-#include <ardour/ardour.h>
-#include <jack/jack.h>
-#include <jack/midiport.h>
-#include <ardour/port.h>
-#include <ardour/jack_port.h>
-#include <ardour/base_midi_port.h>
-#include <ardour/midi_buffer.h>
-
-namespace ARDOUR {
-
-class MidiEngine;
-
-class JackMidiPort : public JackPort, public BaseMidiPort {
-   public:
-       void cycle_start (nframes_t nframes, nframes_t offset);
-       void cycle_end (nframes_t nframes, nframes_t offset);
-       void flush_buffers (nframes_t nframes, nframes_t offset);
-       void set_buffer (MidiBuffer& buf);
-
-       MidiBuffer& get_midi_buffer( nframes_t nframes, nframes_t offset );
-
-  protected:
-       friend class MidiPort;
-
-       JackMidiPort (const std::string&, Flags, MidiBuffer*);
-  private:
-       bool _has_been_mixed_down;
-};
-} // namespace ARDOUR
-
-#endif /* __ardour_jack_midi_port_h__ */
index 56e704f88ec44f703554dc66cc758d3c61d66332..02b0132f7a89f84fbab0a0bcef01079ea39e7fff 100644 (file)
 
 #include <pbd/fastlog.h>
 #include <pbd/ringbufferNPT.h>
 
 #include <ardour/ardour.h>
 #include <ardour/configuration.h>
 #include <ardour/session.h>
 #include <ardour/route_group.h>
 #include <ardour/route.h>
-#include <ardour/port.h>
 #include <ardour/utils.h>
 #include <ardour/diskstream.h>
 #include <ardour/midi_playlist.h>
index a5a269b1ef62b8c0d89e69731be8c560f9ac55a8..a3c87ff702f03fd227d33dbb70461aef0f64d808 100644 (file)
 #ifndef __ardour_midi_port_h__
 #define __ardour_midi_port_h__
 
-#include <ardour/base_midi_port.h>
+#include <ardour/port.h>
+#include <ardour/midi_buffer.h>
 
 namespace ARDOUR {
 
 class MidiEngine;
 
-class MidiPort : public BaseMidiPort, public PortFacade {
+class MidiPort : public Port {
    public:
        ~MidiPort();
 
-       void reset ();
+       DataType type () const {
+               return DataType::MIDI;
+       }
 
        void cycle_start (nframes_t nframes, nframes_t offset);
        void cycle_end (nframes_t nframes, nframes_t offset);
        void flush_buffers (nframes_t nframes, nframes_t offset);
 
+       Buffer& get_buffer (nframes_t nframes, nframes_t offset) {
+               return get_midi_buffer (nframes, offset);
+       }
+       
        MidiBuffer& get_midi_buffer( nframes_t nframes, nframes_t offset );
 
   protected:
        friend class AudioEngine;
 
        MidiPort (const std::string& name, Flags, bool external, nframes_t bufsize);
+  
   private:
+       void mixdown (nframes_t, nframes_t, bool);
+       
+       MidiBuffer* _buffer;
        bool _has_been_mixed_down;
 };
  
index 6bd607c334dc11d3b96b207216c38d5836097d81..cf62429db30a4946e8e7ef2ba4a3632a8a12cdde 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2002 Paul Davis 
+    Copyright (C) 2009 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
 #ifndef __ardour_port_h__
 #define __ardour_port_h__
 
+#include "ardour/data_type.h"
+#include "ardour/types.h"
+#include <sigc++/trackable.h>
+#include <jack/jack.h>
+#include <string>
 #include <set>
 #include <vector>
-#include <string>
-#include <cstring>
-#include <sigc++/signal.h>
-#include <pbd/failed_constructor.h>
-#include <pbd/destructible.h>
-#include <ardour/ardour.h>
-#include <ardour/data_type.h>
-#include <jack/jack.h>
 
 namespace ARDOUR {
 
 class AudioEngine;
-class Buffer;
+class Buffer;  
 
-/** Abstract base for ports
- */
-class Port : public virtual PBD::Destructible {
-   public:
+class Port : public sigc::trackable
+{
+public:
        enum Flags {
                IsInput = JackPortIsInput,
                IsOutput = JackPortIsOutput,
-               IsPhysical = JackPortIsPhysical,
-               IsTerminal = JackPortIsTerminal,
-               CanMonitor = JackPortCanMonitor
        };
 
-       virtual ~Port();
+       virtual ~Port ();
 
-       std::string name() const { 
+       /** @return Port name (excluding prefix) */
+       std::string name () const {
                return _name;
        }
 
-       Flags flags() const {
+       int set_name (std::string const &);
+
+       /** @return flags */
+       Flags flags () const {
                return _flags;
        }
 
-       bool receives_input() const {
+       /** @return true if this Port receives input, otherwise false */
+       bool receives_input () const {
                return _flags & IsInput;
        }
 
+       /** @return true if this Port sends output, otherwise false */
        bool sends_output () const {
                return _flags & IsOutput;
        }
 
-       bool can_monitor () const {
-               return _flags & CanMonitor;
-       }
-
-       void enable_metering() {
-               _metering++;
-       }
-       
-       void disable_metering () {
-               if (_metering) { _metering--; }
+       /* @return true if this port is visible outside Ardour (via JACK) */
+       bool external () const {
+               return _jack_port != 0;
        }
 
-       virtual void cycle_start (nframes_t nframes, nframes_t offset) {}
-       virtual void cycle_end (nframes_t nframes, nframes_t offset) {}
-       virtual void flush_buffers (nframes_t nframes, nframes_t offset ) {}
-       virtual DataType type() const = 0;
-       virtual Buffer& get_buffer( nframes_t nframes, nframes_t offset ) = 0;
-
-       virtual bool connected () const;
-       virtual bool connected_to (const std::string& portname) const;
-       virtual int get_connections (std::vector<std::string>&) const;
+       bool connected () const;
+       int disconnect_all ();
+       int get_connections (std::vector<std::string> &) const;
 
-       virtual int connect (Port& other);
-       virtual int disconnect (Port& other);
-       virtual int disconnect_all ();
-       
-       virtual void reset ();
-       virtual int reestablish () {return 0; }
-       virtual int reconnect () { return 0; }
+       /* connection by name */
+       bool connected_to (std::string const &) const;
+       int connect (std::string const &);
+       int disconnect (std::string const &);
 
-       virtual int set_name (const std::string& str) {
-               _name = str;
-               return 0;
-       }
+       /* connection by Port* */
+       bool connected_to (Port *) const;
+       int connect (Port *);
+       int disconnect (Port *);
 
-       virtual std::string short_name() const = 0;
-       virtual bool monitoring_input () const = 0;
-       virtual void ensure_monitor_input (bool yn) = 0;
-       virtual void request_monitor_input (bool yn) = 0;
-       virtual nframes_t latency () const = 0;
-       virtual nframes_t total_latency () const = 0;
-       virtual void set_latency (nframes_t nframes) = 0;
+       void ensure_monitor_input (bool);
+       bool monitoring_input () const;
+       nframes_t total_latency () const;
+       int reestablish ();
+       int reconnect ();
+       void set_latency (nframes_t);
+       void request_monitor_input (bool);
+       void make_external ();
 
-       sigc::signal<void,bool> MonitorInputChanged;
-       sigc::signal<void,bool> ClockSyncChanged;
+       virtual void reset ();
 
-       static void set_engine (AudioEngine*);
+       virtual DataType type () const = 0;
+       virtual void cycle_start (nframes_t, nframes_t) = 0;
+       virtual void cycle_end (nframes_t, nframes_t) = 0;
+       virtual Buffer& get_buffer (nframes_t, nframes_t) = 0;
+       virtual void flush_buffers (nframes_t, nframes_t) {}
 
-  protected:
-       friend class AudioEngine;
+       static void set_engine (AudioEngine *);
 
-       Port (const std::string& name, Flags flgs);
+       sigc::signal<void, bool> MonitorInputChanged;
 
-       virtual void recompute_total_latency() const {}
+protected:
        
-       /* engine isn't supposed to access below here */
-
-       Flags          _flags;
-       std::string    _type;
-       std::string    _name;
-       unsigned short _metering;
-       bool           _last_monitor;
-       nframes_t      _latency;
-
-       std::set<Port*> _connections;
-
-       static AudioEngine* engine;
+       Port (std::string const &, DataType, Flags, bool);
 
-   private:
+       jack_port_t* _jack_port; ///< JACK port, or 0 if we don't have one
+       std::set<Port*> _connections; ///< internal Ports that we are connected to
 
-        void port_going_away (Port *);
-};
-
-class PortConnectableByName {
-  public:
-       PortConnectableByName() {}
-       virtual ~PortConnectableByName() {}
-
-       virtual int connect (const std::string& other_name) = 0;
-       virtual int disconnect (const std::string& other_name) = 0;
-};
-class PortFacade : public virtual Port, public PortConnectableByName { 
-  public:
-       PortFacade (const std::string& name, Flags flgs) : Port (name, flgs), _ext_port (0) {}
-       ~PortFacade() {}
-
-       void reset ();
-       int reestablish ();
-       int reconnect ();
+       static AudioEngine* _engine; ///< the AudioEngine
+       
+private:
+       friend class AudioEngine;
 
-       int connect (Port& other);
-       int disconnect (Port& other);
-       int disconnect_all ();
+       void recompute_total_latency () const;
+       void do_make_external (DataType);
+       
+       /* XXX */
+       bool _last_monitor;
+       nframes_t _latency;
 
-       int connect (const std::string& other_name);
-       int disconnect (const std::string& other_name);
+       std::string _name; ///< port name (excluding prefix)
+       Flags _flags; ///< flags
 
-       bool connected () const;
-       bool connected_to (const std::string& portname) const;
-       int get_connections (std::vector<std::string>&) const;
-
-       std::string short_name() const;
-       int         set_name (const std::string& str);
-       bool        monitoring_input () const;
-       void        ensure_monitor_input (bool yn);
-       void        request_monitor_input (bool yn);
-       nframes_t   latency () const;
-       nframes_t   total_latency () const;
-       void        set_latency (nframes_t nframes);
-
-  protected:
-       Port* _ext_port;
+       /// list of JACK ports that we are connected to; we only keep this around
+       /// so that we can implement ::reconnect ()
+       std::set<std::string> _named_connections;
 };
 
-} // namespace ARDOUR
+}
 
-#endif /* __ardour_port_h__ */
+#endif
index 51673472c399ab86f3402ce0ba1de86843bebaf0..7b9e716e4a84bef94ee4a1f4ed27fbe55670f018 100644 (file)
 #define __ardour_port_set_h__
 
 #include <vector>
-#include <ardour/port.h>
-#include <ardour/audio_port.h>
-#include <ardour/midi_port.h>
 #include <ardour/chan_count.h>
 
 namespace ARDOUR {
 
+class Port;
+class AudioPort;
+class MidiPort;
 
 /** An ordered list of Ports, possibly of various types.
  *
index 36903f76993133291b446ff9157e979339d2efca..0661cb27a95eb8543f5635887525742c1c7763c8 100644 (file)
@@ -52,6 +52,7 @@
 #include <ardour/audioregion.h>
 #include <ardour/audio_port.h>
 #include <ardour/source_factory.h>
+#include <ardour/audio_buffer.h>
 
 #include "i18n.h"
 #include <locale.h>
index 7e57a734b8cf60e3d28a257c410cb2944572a233..55d65d850d6a69ebf564998bb644ff136ae78282 100644 (file)
 
 #include <cassert>
 #include <ardour/audio_port.h>
-#include <ardour/jack_audio_port.h>
 #include <ardour/audioengine.h>
 #include <ardour/data_type.h>
+#include <ardour/audio_buffer.h>
 
 using namespace ARDOUR;
 using namespace std;
 
-AudioPort::AudioPort (const std::string& name, Flags flags, bool external, nframes_t capacity)
-       : Port (name, flags)
-       , BaseAudioPort (name, flags)
-       , PortFacade (name, flags)
-       , _has_been_mixed_down( false )
+AudioPort::AudioPort (const std::string& name, Flags flags, bool ext, nframes_t capacity)
+       : Port (name, DataType::AUDIO, flags, ext)
+       , _has_been_mixed_down (false)
+       , _buffer (0)
 {
-       if (!external || receives_input()) {
+       assert (name.find_first_of (':') == string::npos);
+       
+       if (external ()) {
+               
+               /* external ports use the external port buffer */
+               _buffer = new AudioBuffer (0);
 
-               /* internal-only and input ports need their own buffers.
-                  external output ports use the external port buffer.
-               */
+       } else {
 
+               /* internal ports need their own buffers */
                _buffer = new AudioBuffer (capacity);
-               _own_buffer = true;
-       }
-
-       if (!external) {
-
-               _ext_port = 0;
-               set_name (name);
-
-       } else {
                
-               /* make the JackAudioPort create its own buffer. For input,
-                  we will copy from it during cycle_start(). For output,
-                  we will set up our buffer to point to its buffer, which
-                  will in turn be using the JACK port buffer for data.
-               */
-
-               _ext_port = new JackAudioPort (name, flags, 0);
-
-               //if (sends_output()) {
-               //      _buffer = &dynamic_cast<JackAudioPort*>(_ext_port)->get_audio_buffer( nframes, offset );
-               //} 
-
-               Port::set_name (_ext_port->name());
        }
-
-       reset ();
+       
 }
 
 AudioPort::~AudioPort()
 {
-       delete _ext_port;
-       _ext_port = 0;
+       delete _buffer;
 }
 
-void
-AudioPort::reset()
-{
-       BaseAudioPort::reset();
-
-       if (_ext_port) {
-               _ext_port->reset ();
-       }
-}
-
-
 void
 AudioPort::cycle_start (nframes_t nframes, nframes_t offset)
 {
        /* caller must hold process lock */
 
-       if (_ext_port) {
-               _ext_port->cycle_start (nframes, offset);
-       }
        _has_been_mixed_down = false;
+
+       if (external ()) {
+               /* external ports use JACK's memory */
+               _buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes), nframes + offset);
+       }
 }
 
 AudioBuffer &
-AudioPort::get_audio_buffer( nframes_t nframes, nframes_t offset ) {
+AudioPort::get_audio_buffer (nframes_t nframes, nframes_t offset)
+{
+       /* caller must hold process lock */
 
-       if (_has_been_mixed_down)       
+       if (_has_been_mixed_down) {
                return *_buffer;
+       }
 
-       if (_flags & IsInput) {
-
-               if (_ext_port) {
-                       _buffer->read_from (dynamic_cast<BaseAudioPort*>(_ext_port)->get_audio_buffer (nframes, offset), nframes, offset);
+       if (receives_input ()) {
 
-                       if (!_connections.empty()) {
-                               (*_mixdown) (_connections, _buffer, nframes, offset, false);
-                       }
+               /* INPUT */
 
-               } else {
+               /* If we're external (), we have some data in our buffer set up by JACK;
+                  otherwise, we have an undefined buffer.  In either case we mix down
+                  our non-JACK inputs; either accumulating into the JACK data or
+                  overwriting the undefined data */
+                  
+               mixdown (nframes, offset, !external ());
                
-                       if (_connections.empty()) {
-                               _buffer->silence (nframes, offset);
-                       } else {
-                               (*_mixdown) (_connections, _buffer, nframes, offset, true);
-                       }
-               }
-
        } else {
-               
-               // XXX if we could get the output stage to not purely mix into, but also
-               // to initially overwrite the buffer, we could avoid this silence step.
-               if (_ext_port) {
-                       _buffer = & (dynamic_cast<BaseAudioPort*>(_ext_port)->get_audio_buffer( nframes, offset ));
-               }
-               if (nframes)
+
+               /* OUTPUT */
+
+               if (!external ()) {
+                       /* start internal output buffers with silence */
                        _buffer->silence (nframes, offset);
+               }
+               
        }
-       if (nframes)
+       
+       if (nframes) {
                _has_been_mixed_down = true;
+       }
 
        return *_buffer;
 }
@@ -137,5 +105,38 @@ AudioPort::get_audio_buffer( nframes_t nframes, nframes_t offset ) {
 void
 AudioPort::cycle_end (nframes_t nframes, nframes_t offset)
 {
-       _has_been_mixed_down=false;
+       _has_been_mixed_down = false;
+}
+
+void
+AudioPort::mixdown (nframes_t cnt, nframes_t offset, bool first_overwrite)
+{
+       if (_connections.empty()) {
+               if (first_overwrite) {
+                       _buffer->silence (cnt, offset);
+               }
+               return;
+       }
+       
+       set<Port*>::const_iterator p = _connections.begin();
+
+       if (first_overwrite) {
+               _buffer->read_from (dynamic_cast<AudioPort*>(*p)->get_audio_buffer (cnt, offset), cnt, offset);
+               ++p;
+       }
+
+       for (; p != _connections.end (); ++p) {
+               _buffer->accumulate_from (dynamic_cast<AudioPort*>(*p)->get_audio_buffer (cnt, offset), cnt, offset);
+       }
+}
+
+void
+AudioPort::reset ()
+{
+       Port::reset ();
+       
+       if (_buffer->capacity () != 0) {
+               _buffer->resize (_engine->frames_per_cycle ());
+               _buffer->clear ();
+       }
 }
index 816f08cbd5ec99b8b55c282152738185e78b39e4..e1c21a5d63a89e446d457d79fcf560c2a5606bc0 100644 (file)
@@ -39,6 +39,7 @@
 #include <ardour/panner.h>
 #include <ardour/utils.h>
 #include <ardour/buffer_set.h>
+#include <ardour/audio_buffer.h>
 #include "i18n.h"
 
 using namespace std;
index 0c36db6b01e5969233f887bf9483b92aa3f81479..095fb205c1b15144fe0b0a65fc8c71e64bb57081 100644 (file)
 #include <ardour/audioengine.h>
 #include <ardour/buffer.h>
 #include <ardour/port.h>
-#include <ardour/jack_audio_port.h>
-#include <ardour/jack_midi_port.h>
-#include <ardour/midi_port.h>
 #include <ardour/audio_port.h>
+#include <ardour/midi_port.h>
 #include <ardour/session.h>
 #include <ardour/cycle_timer.h>
 #include <ardour/utils.h>
@@ -356,6 +354,7 @@ AudioEngine::process_callback (nframes_t nframes)
                   which requires interleaving with route processing.
                */
 
+               /* XXX: we're running this on both inputs and outputs... */
                (*i)->cycle_start (nframes, 0);
        }
 
@@ -619,21 +618,6 @@ AudioEngine::register_port (DataType dtype, const string& portname, bool input,
        }
 }
 
-Port*
-AudioEngine::get_port (const std::string& full_name)
-{
-       boost::shared_ptr<Ports> p = ports.reader();
-       
-       for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
-               //cerr << "comparing port name '" << (*i)->name() << "' with '" << full_name << "'" << endl;
-               if ((*i)->name() == full_name) {
-                       return *i;
-               }
-       }
-       return 0;
-}
-
-
 Port *
 AudioEngine::register_input_port (DataType type, const string& portname, bool publish)
 {
@@ -692,6 +676,8 @@ AudioEngine::unregister_port (Port& port)
 int 
 AudioEngine::connect (const string& source, const string& destination)
 {
+       /* caller must hold process lock */
+       
        int ret;
 
        if (!_running) {
@@ -705,39 +691,24 @@ AudioEngine::connect (const string& source, const string& destination)
 
        string s = make_port_name_non_relative (source);
        string d = make_port_name_non_relative (destination);
-               
-       //cerr << "Trying to connect source: " << s << " with destination " << d << endl;
-       
-       Port* src = get_port (s);
-       Port* dst = get_port (d);
+
+       Port* src = get_port_by_name_locked (s);
+       Port* dst = get_port_by_name_locked (d);
 
        if (src && dst) {
 
                /* both ports are known to us, so do the internal connect stuff */
 
-               if ((ret = src->connect (*dst)) == 0) {
-                       ret = dst->connect (*src);
-               }
+               ret = src->connect (dst);
 
        } else if (src || dst) {
 
                /* one port is known to us, try to connect it to something external */
 
-               PortConnectableByName* pcn;
-               string other;
-
                if (src) {
-                       pcn = dynamic_cast<PortConnectableByName*>(src);
-                       other = d;
-               } else {
-                       pcn = dynamic_cast<PortConnectableByName*>(dst);
-                       other = s;
-               }
-
-               if (pcn) {
-                       ret = pcn->connect (other);
+                       ret = src->connect (d);
                } else {
-                       ret = -1;
+                       ret = dst->connect (s);
                }
 
        } else {
@@ -764,6 +735,8 @@ AudioEngine::connect (const string& source, const string& destination)
 int 
 AudioEngine::disconnect (const string& source, const string& destination)
 {
+       /* caller must hold process lock */
+       
        int ret;
 
        if (!_running) {
@@ -778,39 +751,23 @@ AudioEngine::disconnect (const string& source, const string& destination)
        string s = make_port_name_non_relative (source);
        string d = make_port_name_non_relative (destination);
 
-       //cerr << "trying to disconnect port '" << s << "' from port '" << d << endl;
-       
-       Port* src = get_port (s);
-       Port* dst = get_port (d);
+       Port* src = get_port_by_name_locked (s);
+       Port* dst = get_port_by_name_locked (d);
 
        if (src && dst) {
 
-               /* both ports are known to us, so do the internal connect stuff */
+               /* both ports are known to us, so do the internal disconnect stuff */
                
-               if ((ret = src->disconnect (*dst)) == 0) {
-                       ret = dst->disconnect (*src);
-               }
+               ret = src->disconnect (dst);
 
        } else if (src || dst) {
 
-               /* one port is known to us, try to connect it to something external */
-
-
-               PortConnectableByName* pcn;
-               string other;
+               /* one port is known to us, try to disconnect it from something external */
 
                if (src) {
-                       pcn = dynamic_cast<PortConnectableByName*>(src);
-                       other = d;
+                       ret = src->disconnect (d);
                } else {
-                       pcn = dynamic_cast<PortConnectableByName*>(dst);
-                       other = s;
-               }
-
-               if (pcn) {
-                       ret = pcn->disconnect (other);
-               } else {
-                       ret = -1;
+                       ret = dst->disconnect (s);
                }
 
        } else {
@@ -873,34 +830,53 @@ AudioEngine::frames_per_cycle ()
        }
 }
 
-/** Get a port by name.
- * Note this can return NULL, it will NOT create a port if it is not found (any more).
+/** @param name Full name of port (including prefix:)
+ *  @return Corresponding Port*, or 0.  This object remains the property of the AudioEngine
+ *  so must not be deleted.
  */
 Port *
-AudioEngine::get_port_by_name (const string& portname, bool keep)
+AudioEngine::get_port_by_name (const string& portname)
 {
        Glib::Mutex::Lock lm (_process_lock);
+       return get_port_by_name_locked (portname);
+}
+
+Port *
+AudioEngine::get_port_by_name_locked (const string& portname)
+{
+       /* caller must hold process lock */
 
        if (!_running) {
                if (!_has_run) {
-                       fatal << _("get_port_by_name() called before engine was started") << endmsg;
+                       fatal << _("get_port_by_name_locked() called before engine was started") << endmsg;
                        /*NOTREACHED*/
                } else {
                        return 0;
                }
        }
-       
+
+       if (portname.substr (0, jack_client_name.length ()) != jack_client_name) {
+               /* not an ardour: port */
+               return 0;
+       }
+
+       std::string const rel = make_port_name_relative (portname);
+
        boost::shared_ptr<Ports> pr = ports.reader();
-       
+
        for (Ports::iterator i = pr->begin(); i != pr->end(); ++i) {
-               if (portname == (*i)->name()) {
-                       return (*i);
+               if (rel == (*i)->name()) {
+                       return *i;
                }
        }
 
        return 0;
 }
 
+
+
+
+
 const char **
 AudioEngine::get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags)
 {
@@ -1071,12 +1047,6 @@ AudioEngine::get_nth_physical (DataType type, uint32_t n, int flag)
        return ret;
 }
 
-ARDOUR::nframes_t
-AudioEngine::get_port_total_latency (const Port& port)
-{
-       return port.total_latency ();
-}
-
 void
 AudioEngine::update_total_latency (const Port& port)
 {
diff --git a/libs/ardour/base_audio_port.cc b/libs/ardour/base_audio_port.cc
deleted file mode 100644 (file)
index 7110102..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-    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 <glib.h>
-#include <ardour/base_audio_port.h>
-#include <ardour/audioengine.h>
-#include <ardour/data_type.h>
-
-using namespace ARDOUR;
-using namespace std;
-
-nframes_t BaseAudioPort::_short_over_length = 2;
-nframes_t BaseAudioPort::_long_over_length = 10;
-
-BaseAudioPort::BaseAudioPort (const std::string& name, Flags flgs)
-       : Port (name, flgs)
-       , _buffer (0)
-       , _own_buffer (false)
-{
-       _type = DataType::AUDIO;
-       _mixdown = default_mixdown;
-}
-
-BaseAudioPort::~BaseAudioPort ()
-{
-       if (_own_buffer) {
-               delete _buffer;
-       }
-}
-
-void
-BaseAudioPort::reset()
-{
-       Port::reset();
-
-       if (_own_buffer && _buffer) {
-               _buffer->resize (engine->frames_per_cycle());
-               _buffer->clear ();
-       }
-       
-       _metering = 0;
-       reset_meters ();
-}
-
-void
-BaseAudioPort::default_mixdown (const set<Port*>& ports, AudioBuffer* dest, nframes_t cnt, nframes_t offset, bool first_overwrite)
-{
-       set<Port*>::const_iterator p = ports.begin();
-
-       if (first_overwrite) {
-               dest->read_from ((dynamic_cast<BaseAudioPort*>(*p))->get_audio_buffer( cnt, offset ), cnt, offset);
-               p++;
-       }
-
-       for (; p != ports.end(); ++p) {
-               dest->accumulate_from ((dynamic_cast<BaseAudioPort*>(*p))->get_audio_buffer( cnt, offset ), cnt, offset);
-       }
-}
-
-void 
-BaseAudioPort::set_mixdown_function (void (*func)(const set<Port*>&, AudioBuffer*, nframes_t, nframes_t, bool))
-{
-       g_atomic_pointer_set(&_mixdown, func);
-}
-
-
diff --git a/libs/ardour/base_midi_port.cc b/libs/ardour/base_midi_port.cc
deleted file mode 100644 (file)
index 0ba4b7c..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-    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 <iostream>
-#include <glib.h>
-#include <ardour/base_midi_port.h>
-#include <ardour/data_type.h>
-
-using namespace ARDOUR;
-using namespace std;
-
-BaseMidiPort::BaseMidiPort (const std::string& name, Flags flags)
-       : Port (name, flags)
-       , _buffer (0) 
-       , _own_buffer (false)
-{
-       _type = DataType::MIDI;
-       _mixdown = default_mixdown;
-}
-
-BaseMidiPort::~BaseMidiPort()
-{
-       if (_own_buffer) {
-               delete _buffer;
-       }
-}
-
-void
-BaseMidiPort::default_mixdown (const set<Port*>& ports, MidiBuffer* dest, nframes_t cnt, nframes_t offset, bool first_overwrite)
-{
-       set<Port*>::const_iterator p = ports.begin();
-
-       if (first_overwrite) {
-               cout << "first overwrite" << endl;
-               dest->read_from ((dynamic_cast<BaseMidiPort*>(*p))->get_midi_buffer(cnt, offset), cnt, offset);
-               p++;
-       }
-
-       // XXX DAVE: this is just a guess
-
-       for (; p != ports.end(); ++p) {
-               //cout << "merge" << endl;
-               dest->merge (*dest, (dynamic_cast<BaseMidiPort*>(*p))->get_midi_buffer(cnt, offset));
-       }
-}
-
-void 
-BaseMidiPort::set_mixdown_function (void (*func)(const set<Port*>&, MidiBuffer*, nframes_t, nframes_t, bool))
-{
-       g_atomic_pointer_set(&_mixdown, func);
-}
index 865c8fbf3b50353cdc049a405200d2be45af2170..ccb481dc8f6856ffff3f6ad92877ddbb0de7b4c8 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <ardour/export_failed.h>
 #include <ardour/audioengine.h>
+#include <ardour/audio_port.h>
+#include <ardour/audio_buffer.h>
 
 using namespace ARDOUR;
 
diff --git a/libs/ardour/internal_audio_port.cc b/libs/ardour/internal_audio_port.cc
deleted file mode 100644 (file)
index e5362cd..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-    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 flags)
-       : Port (DataType::AUDIO, flags)
-       , AudioPort (flags, engine->frames_per_cycle())
-       , InternalPort (name, DataType::AUDIO, flags)
-{
-       _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
deleted file mode 100644 (file)
index cec1174..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
-    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)
-       : Port (type, flags)
-{
-       set_name (str);
-}
-
-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 2b8f12680fcf69df9a37a7a6466638bcf1a93d9f..671ade36ea09b72b3d6a04ab2e56f5966153f594 100644 (file)
@@ -1965,13 +1965,13 @@ IO::set_name (const string& requested_name)
        }
 
        for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
-               string current_name = i->short_name();
+               string current_name = i->name();
                current_name.replace (current_name.find (_name), _name.length(), name);
                i->set_name (current_name);
        }
 
        for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
-               string current_name = i->short_name();
+               string current_name = i->name();
                current_name.replace (current_name.find (_name), _name.length(), name);
                i->set_name (current_name);
        }
@@ -2028,7 +2028,7 @@ IO::output_latency () const
        /* io lock not taken - must be protected by other means */
 
        for (PortSet::const_iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
-               if ((latency = _session.engine().get_port_total_latency (*i)) > max_latency) {
+               if ((latency = i->total_latency ()) > max_latency) {
                        max_latency = latency;
                }
        }
@@ -2047,7 +2047,7 @@ IO::input_latency () const
        /* io lock not taken - must be protected by other means */
 
        for (PortSet::const_iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
-               if ((latency = _session.engine().get_port_total_latency (*i)) > max_latency) {
+               if ((latency = i->total_latency ()) > max_latency) {
                        max_latency = latency;
                } 
        }
@@ -2473,7 +2473,7 @@ IO::find_input_port_hole (const char* base)
                snprintf (buf, jack_port_name_size(), _("%s %u"), base, n);
 
                for ( ; i != _inputs.end(); ++i) {
-                       if (i->short_name() == buf) {
+                       if (i->name() == buf) {
                                break;
                        }
                }
@@ -2506,7 +2506,7 @@ IO::find_output_port_hole (const char* base)
                snprintf (buf, jack_port_name_size(), _("%s %u"), base, n);
 
                for ( ; i != _outputs.end(); ++i) {
-                       if (i->short_name() == buf) {
+                       if (i->name() == buf) {
                                break;
                        }
                }
diff --git a/libs/ardour/jack_audio_port.cc b/libs/ardour/jack_audio_port.cc
deleted file mode 100644 (file)
index ed52ead..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-    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/audioengine.h>
-#include <ardour/jack_audio_port.h>
-
-using namespace ARDOUR;
-
-JackAudioPort::JackAudioPort (const std::string& name, Flags flgs, AudioBuffer* buf)
-       : Port (name, flgs)
-       , JackPort (name, DataType::AUDIO, flgs)
-       , BaseAudioPort (name, flgs)
-       , _has_been_mixed_down( false )
-{
-       if (buf) {
-
-               _buffer = buf;
-               _own_buffer = false;
-
-       } else {
-               
-               /* data space will be provided by JACK */
-
-               _buffer = new AudioBuffer (0);
-               _own_buffer = true;
-       }
-}
-
-int
-JackAudioPort::reestablish ()
-{
-       int ret = JackPort::reestablish ();
-       
-       if (ret == 0 && _flags & IsOutput) {
-               _buffer->clear ();
-       }
-
-       return ret;
-}
-
-AudioBuffer&
-JackAudioPort::get_audio_buffer (nframes_t nframes, nframes_t offset) {
-       assert (_buffer);
-
-       if (_has_been_mixed_down)
-               return *_buffer;
-
-       if( _flags & IsInput )
-               _buffer->set_data ((Sample*) jack_port_get_buffer (_port, nframes), nframes+offset);
-
-
-       if (nframes)
-               _has_been_mixed_down = true;
-
-       return *_buffer;
-}
-
-void
-JackAudioPort::cycle_start (nframes_t nframes, nframes_t offset) {
-       if( _flags & IsOutput )
-               _buffer->set_data ((Sample*) jack_port_get_buffer (_port, nframes), nframes+offset);
-}
-void
-JackAudioPort::cycle_end (nframes_t nframes, nframes_t offset) {
-       _has_been_mixed_down=false;
-}
diff --git a/libs/ardour/jack_midi_port.cc b/libs/ardour/jack_midi_port.cc
deleted file mode 100644 (file)
index 4b7b66c..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
-    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/jack_midi_port.h>
-
-using namespace ARDOUR;
-JackMidiPort::JackMidiPort (const std::string& name, Flags flgs, MidiBuffer* buf)
-       : Port (name, flgs)
-       , JackPort (name, DataType::MIDI, flgs)
-       , BaseMidiPort (name, flgs) 
-       , _has_been_mixed_down (false)
-{
-       // MIDI ports always need a buffer since jack buffer format is different
-       assert(buf);
-
-       _buffer = buf;
-       _own_buffer = false;
-}
-
-void
-JackMidiPort::cycle_start (nframes_t nframes, nframes_t offset)
-{
-       /* FIXME: offset */
-
-       _buffer->clear();
-       assert(_buffer->size() == 0);
-
-       if (_flags & IsInput) {
-               return;
-       }
-
-       // We're an output - delete the midi_events.
-       
-       void* jack_buffer = jack_port_get_buffer (_port, nframes);
-
-       jack_midi_clear_buffer (jack_buffer);
-}
-
-MidiBuffer &
-JackMidiPort::get_midi_buffer( nframes_t nframes, nframes_t offset ) {
-
-       if (_has_been_mixed_down)
-           return *_buffer;
-
-       if (_flags & IsOutput) {
-               return *_buffer;
-       }
-
-       // We're an input - copy Jack events to internal buffer
-       
-       void* jack_buffer = jack_port_get_buffer(_port, nframes);
-       const nframes_t event_count = jack_midi_get_event_count(jack_buffer);
-
-       assert(event_count < _buffer->capacity());
-
-       jack_midi_event_t ev;
-
-       for (nframes_t i=0; i < event_count; ++i) {
-
-               jack_midi_event_get (&ev, jack_buffer, i);
-
-               // i guess this should do but i leave it off to test the rest first.
-               //if (ev.time > offset && ev.time < offset+nframes)
-                       _buffer->push_back (ev);
-       }
-
-       assert(_buffer->size() == event_count);
-
-       /*if (_buffer->size() > 0)
-               cerr << "JackMIDIPort got " << event_count << " events (buf " << _buffer << ")" << endl;*/
-       if (nframes)
-               _has_been_mixed_down = true;
-
-       return *_buffer;
-}
-
-void
-JackMidiPort::cycle_end (nframes_t nframes, nframes_t offset)
-{
-       /* FIXME: offset */
-
-       _has_been_mixed_down = false;
-
-#if 0
-       if (_flags & IsInput) {
-               return;
-       }
-
-       // We're an output - copy events from source buffer to Jack buffer
-       
-       void* jack_buffer = jack_port_get_buffer (_port, nframes);
-
-       jack_midi_clear_buffer (jack_buffer);
-
-       for (MidiBuffer::iterator i = _buffer->begin(); i != _buffer->end(); ++i) {
-               const Evoral::Event& ev = *i;
-
-               // event times should be frames, relative to cycle start
-               assert(ev.time() >= 0);
-               assert(ev.time() < nframes);
-               jack_midi_event_write (jack_buffer, (jack_nframes_t) ev.time(), ev.buffer(), ev.size());
-       }
-#endif
-}
-
-void
-JackMidiPort::flush_buffers (nframes_t nframes, nframes_t offset)
-{
-       /* FIXME: offset */
-
-       if (_flags & IsInput) {
-               return;
-       }
-
-       void* jack_buffer = jack_port_get_buffer (_port, nframes);
-
-       for (MidiBuffer::iterator i = _buffer->begin(); i != _buffer->end(); ++i) {
-               const Evoral::Event& ev = *i;
-               // event times should be frames, relative to cycle start
-               assert(ev.time() >= 0);
-               assert(ev.time() < (nframes+offset));
-               if (ev.time() >= offset)
-                       jack_midi_event_write (jack_buffer, (jack_nframes_t) ev.time(), ev.buffer(), ev.size());
-       }
-}
diff --git a/libs/ardour/jack_port.cc b/libs/ardour/jack_port.cc
deleted file mode 100644 (file)
index 5fac52a..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
-    Copyright (C) 2002-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 <pbd/error.h>
-
-#include <ardour/jack_port.h>
-#include <ardour/audioengine.h>
-
-#include "i18n.h"
-
-using namespace ARDOUR;
-using namespace PBD;
-using namespace std;
-
-JackPort::JackPort (const std::string& name, DataType type, Flags flgs) 
-       : Port (name, flgs), _port (0)
-{
-       _port = jack_port_register (engine->jack(), name.c_str(), type.to_jack_type(), flgs, 0);
-
-       if (_port == 0) {
-               throw failed_constructor();
-       }
-       
-       _flags = flgs;
-       _type  = type;
-       _name = jack_port_name (_port);
-}
-
-JackPort::~JackPort ()
-{
-       cerr << "deleting jack port " << _name << endl;
-
-       jack_port_unregister (engine->jack(), _port);
-}
-
-int 
-JackPort::set_name (const string& str)
-{
-       int ret;
-
-       if ((ret = jack_port_set_name (_port, str.c_str())) == 0) {
-               _name = str;
-       }
-       
-       return ret;
-}
-
-int
-JackPort::disconnect ()
-{
-       return jack_port_disconnect (engine->jack(), _port);
-}      
-
-nframes_t
-JackPort::total_latency () const
-{
-       return jack_port_get_total_latency (engine->jack(), _port);
-}
-
-int
-JackPort::reestablish ()
-{
-       string short_name;
-       
-       short_name = _name.substr (_name.find_last_of (':') + 1);
-
-       _port = jack_port_register (engine->jack(), short_name.c_str(), type().to_jack_type(), _flags, 0);
-
-       if (_port == 0) {
-               error << string_compose (_("could not reregister %1"), _name) << endmsg;
-               return -1;
-       }
-
-       reset ();
-       
-
-       return 0;
-}
-
-void
-JackPort::recompute_total_latency () const
-{
-#ifdef HAVE_JACK_RECOMPUTE_LATENCY
-       jack_recompute_total_latency (engine->jack(), _port);
-#endif
-}
-
-int
-JackPort::reconnect ()
-{
-       /* caller must hold process lock; intended to be used only after reestablish() */
-
-       for (set<string>::iterator i = _named_connections.begin(); i != _named_connections.end(); ++i) {
-               if (connect (*i)) {
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-int
-JackPort::connect (const std::string& other)
-{
-       int ret;
-
-       if (_flags & IsOutput) {
-               /* this is the source */
-               ret = jack_connect (engine->jack(), _name.c_str(), other.c_str());
-       } else {
-               ret = jack_connect (engine->jack(), other.c_str(), _name.c_str());
-       }
-
-       if (ret == 0) {
-               _named_connections.insert (other);
-       }
-       
-       return ret;
-}
-
-int
-JackPort::disconnect (const std::string& other)
-{
-       int ret;
-
-       if (_flags & IsInput) {
-               ret = jack_disconnect (engine->jack(), other.c_str(), _name.c_str());
-       } else {
-               ret = jack_disconnect (engine->jack(), _name.c_str(), other.c_str());
-       }
-
-       set<string>::iterator i = _named_connections.find (other);
-
-       if (i != _named_connections.end()) {
-               _named_connections.erase (i);
-       }
-
-       return ret;
-}
-
-int
-JackPort::disconnect_all ()
-{
-       _named_connections.clear ();
-       return jack_port_disconnect (engine->jack(), _port);
-}
-
-int
-JackPort::get_connections (vector<string>& names) const
-{
-       const char** cstrs =  jack_port_get_connections (_port);
-       int i;
-       
-       if (!cstrs) {
-               return 0;
-       }
-       
-       for (i = 0; cstrs[i]; ++i) {
-               names.push_back (string (cstrs[i]));
-       }
-
-       return i;
-}
index ebfefeee3624b9ebf96563d2b5f40f36246cb101..3a2ac2e77b5c01a061f31581d80b6929baf4e469 100644 (file)
@@ -23,8 +23,9 @@
 #include <ardour/peak.h>
 #include <ardour/dB.h>
 #include <ardour/session.h>
-#include <ardour/audio_buffer.h>
 #include <ardour/midi_buffer.h>
+#include <ardour/audio_buffer.h>
+#include <ardour/runtime_functions.h>
 
 namespace ARDOUR {
 
index 93ea3b7c60bcf8b7d96105619f76cfa9431fd8d5..23fff7c976291b59baeceecacf88a5dbbb31c8ae 100644 (file)
 #include <iostream>
 
 #include <ardour/midi_port.h>
-#include <ardour/jack_midi_port.h>
 #include <ardour/data_type.h>
 
 using namespace ARDOUR;
 using namespace std;
 
-MidiPort::MidiPort (const std::string& name, Flags flags, bool external, nframes_t capacity)
-       : Port (name, flags)
-       , BaseMidiPort (name, flags)
-       , PortFacade (name, flags)
+MidiPort::MidiPort (const std::string& name, Flags flags, bool ext, nframes_t capacity)
+        : Port (name, DataType::MIDI, flags, ext)
        , _has_been_mixed_down (false)
 {
        // FIXME: size kludge (see BufferSet::ensure_buffers)
        // Jack needs to tell us this
        _buffer = new MidiBuffer (capacity * 8);
-
-       if (external) {
-               /* external ports use the same buffer for the jack port (_ext_port)
-                * and internal ports (this) */
-               _ext_port = new JackMidiPort (name, flags, _buffer);
-               Port::set_name (_ext_port->name());
-       } else {
-               /* internal ports just have a single buffer, no jack port */
-               _ext_port = 0;
-               set_name (name);
-       }
-
-       reset ();
 }
 
 MidiPort::~MidiPort()
 {
-       delete _ext_port;
-       _ext_port = 0;
+       delete _buffer;
 }
 
-void
-MidiPort::reset()
-{
-       BaseMidiPort::reset();
-
-       if (_ext_port) {
-               _ext_port->reset ();
-       }
-}
 
 void
 MidiPort::cycle_start (nframes_t nframes, nframes_t offset)
 {
-       if (_ext_port) {
-               _ext_port->cycle_start (nframes, offset);
+       if (external ()) {
+               _buffer->clear ();
+               assert (_buffer->size () == 0);
+
+               if (sends_output ()) {
+                       jack_midi_clear_buffer (jack_port_get_buffer (_jack_port, nframes));
+               }
        }
 }
 
 MidiBuffer &
 MidiPort::get_midi_buffer( nframes_t nframes, nframes_t offset ) {
        
-       if (_has_been_mixed_down)
+       if (_has_been_mixed_down) {
            return *_buffer;
+       }
 
-       if (_flags & IsInput) {
+       if (receives_input ()) {
                        
-               if (_ext_port) {
+               if (external ()) {
                
-                       BaseMidiPort* mprt = dynamic_cast<BaseMidiPort*>(_ext_port);
-                       assert(mprt);
-                       assert(&mprt->get_midi_buffer(nframes,offset) == _buffer);
+                       void* jack_buffer = jack_port_get_buffer (_jack_port, nframes);
+                       const nframes_t event_count = jack_midi_get_event_count(jack_buffer);
+
+                       assert (event_count < _buffer->capacity());
+
+                       jack_midi_event_t ev;
+
+                       for (nframes_t i = 0; i < event_count; ++i) {
+
+                               jack_midi_event_get (&ev, jack_buffer, i);
+
+                               // i guess this should do but i leave it off to test the rest first.
+                               //if (ev.time > offset && ev.time < offset+nframes)
+                               _buffer->push_back (ev);
+                       }
+
+                       assert(_buffer->size() == event_count);
+
+                       if (nframes) {
+                               _has_been_mixed_down = true;
+                       }
 
                        if (!_connections.empty()) {
-                               (*_mixdown) (_connections, _buffer, nframes, offset, false);
+                               mixdown (nframes, offset, false);
                        }
 
                } else {
@@ -97,15 +95,17 @@ MidiPort::get_midi_buffer( nframes_t nframes, nframes_t offset ) {
                        if (_connections.empty()) {
                                _buffer->silence (nframes, offset);
                        } else {
-                               (*_mixdown) (_connections, _buffer, nframes, offset, true);
+                               mixdown (nframes, offset, true);
                        }
                }
 
        } else {
                _buffer->silence (nframes, offset);
        }
-       if (nframes)
+       
+       if (nframes) {
                _has_been_mixed_down = true;
+       }
 
        return *_buffer;
 }
@@ -114,16 +114,65 @@ MidiPort::get_midi_buffer( nframes_t nframes, nframes_t offset ) {
 void
 MidiPort::cycle_end (nframes_t nframes, nframes_t offset)
 {
-       if (_ext_port) {
-               _ext_port->cycle_end (nframes, offset);
+#if 0
+
+       if (external () && sends_output ()) {
+               /* FIXME: offset */
+
+               // We're an output - copy events from source buffer to Jack buffer
+               
+               void* jack_buffer = jack_port_get_buffer (_jack_port, nframes);
+               
+               jack_midi_clear_buffer (jack_buffer);
+               
+               for (MidiBuffer::iterator i = _buffer->begin(); i != _buffer->end(); ++i) {
+                       const Evoral::Event& ev = *i;
+
+                       // event times should be frames, relative to cycle start
+                       assert(ev.time() >= 0);
+                       assert(ev.time() < nframes);
+                       jack_midi_event_write (jack_buffer, (jack_nframes_t) ev.time(), ev.buffer(), ev.size());
+               }
        }
+#endif
+
        _has_been_mixed_down = false;
 }
 
 void
 MidiPort::flush_buffers (nframes_t nframes, nframes_t offset)
 {
-       if (_ext_port) {
-               _ext_port->flush_buffers (nframes, offset);
+       /* FIXME: offset */
+       
+       if (external () && sends_output ()) {
+               
+               void* jack_buffer = jack_port_get_buffer (_jack_port, nframes);
+
+               for (MidiBuffer::iterator i = _buffer->begin(); i != _buffer->end(); ++i) {
+                       const Evoral::Event& ev = *i;
+                       // event times should be frames, relative to cycle start
+                       assert(ev.time() >= 0);
+                       assert(ev.time() < (nframes+offset));
+                       if (ev.time() >= offset) {
+                               jack_midi_event_write (jack_buffer, (jack_nframes_t) ev.time(), ev.buffer(), ev.size());
+                       }
+               }
+       }
+}
+
+void
+MidiPort::mixdown (nframes_t cnt, nframes_t offset, bool first_overwrite)
+{
+       set<Port*>::const_iterator p = _connections.begin();
+
+       if (first_overwrite) {
+               _buffer->read_from ((dynamic_cast<MidiPort*>(*p))->get_midi_buffer (cnt, offset), cnt, offset);
+               p++;
+       }
+
+       // XXX DAVE: this is just a guess
+
+       for (; p != _connections.end(); ++p) {
+               _buffer->merge (*_buffer, (dynamic_cast<MidiPort*>(*p))->get_midi_buffer (cnt, offset));
        }
 }
index 726d3754530fc0c765806424a7a79feed968f0c8..4b9c31dc4f40ec1df7dda309d0df3f8e47e6d5c2 100644 (file)
@@ -21,6 +21,7 @@
 #include <ardour/types.h>
 #include <ardour/utils.h>
 #include <ardour/mix.h>
+#include <ardour/runtime_functions.h>
 #include <stdint.h>
 
 using namespace ARDOUR;
index c5e28321bf8acd195ec07960d173be3e24af3b95..a7cf40519008d64c5b702a4c0c01d573b13c4af3 100644 (file)
@@ -44,6 +44,7 @@
 
 #include <ardour/runtime_functions.h>
 #include <ardour/buffer_set.h>
+#include <ardour/audio_buffer.h>
 
 #include "i18n.h"
 
index e199dbcec5be2b5a9dadec915bb190bc19585059..431c91762e283d52e1f64865135acd2eef82277b 100644 (file)
@@ -31,6 +31,7 @@
 #include <ardour/ladspa_plugin.h>
 #include <ardour/buffer_set.h>
 #include <ardour/automation_list.h>
+#include <ardour/audio_buffer.h>
 
 #ifdef HAVE_SLV2
 #include <ardour/lv2_plugin.h>
index f3e0739e83031e57d32edf904b7f003f233058fa..208c3914324027b0332fcd3f3c2ba0ba44d13f3e 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2002-2006 Paul Davis 
+    Copyright (C) 2009 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
 
 */
 
-#include <ardour/port.h>
+#include "ardour/port.h"
+#include "ardour/audioengine.h"
+#include "ardour/i18n.h"
+#include "pbd/failed_constructor.h"
+#include "pbd/error.h"
+#include "pbd/compose.h"
+#include <stdexcept>
 
-using namespace ARDOUR;
-using namespace std;
+ARDOUR::AudioEngine* ARDOUR::Port::_engine = 0;
 
-AudioEngine* Port::engine = 0;
-
-Port::Port (const std::string& name, Flags flgs)
-       : _flags (flgs)
-       , _name (name)
-       , _metering (0)
-       , _last_monitor (false)
+ARDOUR::Port::Port (std::string const & n, DataType t, Flags f, bool e) : _jack_port (0), _last_monitor (false), _latency (0), _name (n), _flags (f)
 {
+       /* Unfortunately we have to pass the DataType into this constructor so that we can
+          create the right kind of JACK port; aside from this we'll use the virtual function type ()
+          to establish type. */
+       
+       if (e) {
+               try {
+                       do_make_external (t);
+               }
+               catch (...) {
+                       throw failed_constructor ();
+               }
+       }
 }
 
-Port::~Port ()
+/** Port destructor */
+ARDOUR::Port::~Port ()
 {
-       drop_references ();
-       disconnect_all ();
+       if (_jack_port) {
+               jack_port_unregister (_engine->jack (), _jack_port);
+       }
 }
 
+/** Make this port externally visible by setting it up to use a JACK port.
+ * @param t Data type, so that we can call this method from the constructor.
+ */
 void
-Port::reset ()
+ARDOUR::Port::do_make_external (DataType t)
 {
-       _last_monitor = false;
+       if (_jack_port) {
+               /* already external */
+               return;
+       }
+       
+       _jack_port = jack_port_register (_engine->jack (), _name.c_str (), t.to_jack_type (), _flags, 0);
+       if (_jack_port == 0) {
+               throw std::runtime_error ("Could not register JACK port");
+       }
 }
 
 void
-Port::set_engine (AudioEngine* e) 
+ARDOUR::Port::make_external ()
 {
-       engine = e;
+       do_make_external (type ());
 }
 
-int
-Port::connect (Port& other)
+/** @return true if this port is connected to anything */
+bool
+ARDOUR::Port::connected () const
 {
-       /* caller must hold process lock */
-
-       pair<set<Port*>::iterator,bool> result;
-
-       result = _connections.insert (&other);
-
-       if (result.second) {
-               other.GoingAway.connect (sigc::bind (mem_fun (*this, &Port::port_going_away), &other));
-               return 0;
-       } else {
-               return 1;
+       if (!_connections.empty ()) {
+               /* connected to a Port* */
+               return true;
        }
-}
 
-int
-Port::disconnect (Port& other)
-{
-       /* caller must hold process lock */
-       
-       for (set<Port*>::iterator i = _connections.begin(); i != _connections.end(); ++i) {
-               if ((*i) == &other) {
-                       _connections.erase (i);
-                       return 0;
-               }
+       if (_jack_port == 0) {
+               /* not using a JACK port, so can't be connected to anything else */
+               return false;
        }
-
-       return -1;
+       
+       return (jack_port_connected (_jack_port) != 0);
 }
 
-
 int
-Port::disconnect_all ()
+ARDOUR::Port::disconnect_all ()
 {
-       /* caller must hold process lock */
+       /* Disconnect from Port* connections */
+       for (std::set<Port*>::iterator i = _connections.begin (); i != _connections.end (); ++i) {
+               (*i)->_connections.erase (this);
+       }
 
        _connections.clear ();
-       return 0;
-}
 
-void
-Port::set_latency (nframes_t val)
-{
-       _latency = val;
-}
+       /* And JACK connections */
+       jack_port_disconnect (_engine->jack(), _jack_port);
+       _named_connections.clear ();
 
-bool
-Port::connected() const
-{
-       /* caller must hold process lock */
-       return !_connections.empty();
+       return 0;
 }
 
+/** @param o Port name
+ * @return true if this port is connected to o, otherwise false.
+ */
 bool
-Port::connected_to (const string& portname) const
+ARDOUR::Port::connected_to (std::string const & o) const
 {
-       /* caller must hold process lock */
+       if (_jack_port && jack_port_connected_to (_jack_port, o.c_str ())) {
+               /* connected via JACK */
+               return true;
+       }
 
-       for (set<Port*>::const_iterator p = _connections.begin(); p != _connections.end(); ++p) {
-               if ((*p)->name() == portname) {
+       for (std::set<Port*>::iterator i = _connections.begin (); i != _connections.end (); ++i) {
+               if ((*i)->name () == o) {
+                       /* connected internally */
                        return true;
                }
        }
@@ -120,271 +130,259 @@ Port::connected_to (const string& portname) const
 }
 
 int
-Port::get_connections (vector<string>& names) const
+ARDOUR::Port::get_connections (std::vector<std::string> & c) const
 {
-       /* caller must hold process lock */
-       int i = 0;
-       set<Port*>::const_iterator p;
+       int n = 0;
+
+       /* JACK connections */
+       if (_jack_port) {
+               const char** jc = jack_port_get_connections (_jack_port);
+               if (jc) {
+                       for (int i = 0; jc[i]; ++i) {
+                               c.push_back (jc[i]);
+                               ++n;
+                       }
+               }
+       }
 
-       for (i = 0, p = _connections.begin(); p != _connections.end(); ++p, ++i) {
-               names.push_back ((*p)->name());
+       /* Internal connections */
+       for (std::set<Port*>::iterator i = _connections.begin (); i != _connections.end (); ++i) {
+               c.push_back ((*i)->name ());
+               ++n;
        }
 
-       return i;
+       return n;
 }
 
-void
-Port::port_going_away (Port* p)
+int
+ARDOUR::Port::connect (std::string const & other)
 {
        /* caller must hold process lock */
+       
+       Port* p = _engine->get_port_by_name_locked (other);
+       
+       int r;
+       
+       if (p && !p->external ()) {
+               /* non-external Ardour port; connect using Port* */
+               r = connect (p);
+       } else {
+               /* connect using name */
 
-       disconnect (*p);
-}
-
+               /* for this to work, we must be an external port */
+               if (!external ()) {
+                       make_external ();
+               }
 
-//-------------------------------------
+               std::string const this_nr = _engine->make_port_name_non_relative (_name);
+               std::string const other_nr = _engine->make_port_name_non_relative (other);
 
-int
-PortFacade::set_name (const std::string& str)
-{
-       int ret;
+               if (sends_output ()) {
+                       r = jack_connect (_engine->jack (), this_nr.c_str (), other_nr.c_str ());
+               } else {
+                       r = jack_connect (_engine->jack (), other_nr.c_str (), this_nr.c_str());
+               }
 
-       if (_ext_port) {
-               if ((ret = _ext_port->set_name (str)) == 0) {
-                       _name = _ext_port->name();
+               if (r == 0) {
+                       _named_connections.insert (other);
                }
-       } else {
-               _name = str;
-               ret = 0;
        }
 
-       return ret;
+       return r;
 }
 
-string
-PortFacade::short_name ()  const
+int
+ARDOUR::Port::disconnect (std::string const & other)
 {
-       if (_ext_port) {
-               return _ext_port->short_name(); 
+       /* caller must hold process lock */
+       
+       Port* p = _engine->get_port_by_name_locked (other);
+       int r;
+
+       if (p && !p->external ()) {
+               /* non-external Ardour port; disconnect using Port* */
+               r = disconnect (p);
        } else {
-               return _name;
+               /* disconnect using name */
+
+               std::string const this_nr = _engine->make_port_name_non_relative (_name);
+               std::string const other_nr = _engine->make_port_name_non_relative (other);
+
+               if (sends_output ()) {
+                       r = jack_disconnect (_engine->jack (), this_nr.c_str (), other_nr.c_str ());
+               } else {
+                       r = jack_disconnect (_engine->jack (), other_nr.c_str (), this_nr.c_str ());
+               }
+
+               if (r == 0) {
+                       _named_connections.erase (other);
+               }
        }
+
+       return r;
 }
 
 
-int
-PortFacade::reestablish ()
+bool
+ARDOUR::Port::connected_to (Port *o) const
 {
-       if (_ext_port) {
-               return _ext_port->reestablish ();
-       } else {
-               return 0;
-       }
+       return connected_to (o->name ());
 }
 
-
 int
-PortFacade::reconnect()
+ARDOUR::Port::connect (Port* o)
 {
-       if (_ext_port) {
-               return _ext_port->reconnect ();
-       } else {
-               return 0;
+       /* caller must hold process lock */
+
+       if (external () && o->external ()) {
+               /* we're both external; connect using name */
+               return connect (o->name ());
        }
+
+       /* otherwise connect by Port* */
+       _connections.insert (o);
+       o->_connections.insert (this);
+
+       return 0;
 }
 
-void
-PortFacade::set_latency (nframes_t val)
+int
+ARDOUR::Port::disconnect (Port* o)
 {
-       if (_ext_port) {
-               _ext_port->set_latency (val);
-       } else {
-               _latency = val;
+       if (external () && o->external ()) {
+               /* we're both external; try disconnecting using name */
+               int const r = disconnect (o->name ());
+               if (r == 0) {
+                       return 0;
+               }
        }
+       
+       _connections.erase (o);
+       o->_connections.erase (this);
+
+       return 0;
 }
 
-nframes_t
-PortFacade::latency() const
+void
+ARDOUR::Port::set_engine (AudioEngine* e)
 {
-       if (_ext_port) {
-               return _ext_port->latency();
-       } else {
-               return _latency;
-       }
+       _engine = e;
 }
 
-nframes_t
-PortFacade::total_latency() const
+void
+ARDOUR::Port::ensure_monitor_input (bool yn)
 {
-       if (_ext_port) {
-               return _ext_port->total_latency();
-       } else {
-               return _latency;
+       if (_jack_port) {
+               jack_port_ensure_monitor (_jack_port, yn);
        }
 }
 
 bool
-PortFacade::monitoring_input() const
+ARDOUR::Port::monitoring_input () const
 {
-       if (_ext_port) {
-               return _ext_port->monitoring_input ();
+       if (_jack_port) {
+               return jack_port_monitoring_input (_jack_port);
        } else {
                return false;
        }
 }
 
 void
-PortFacade::ensure_monitor_input (bool yn)
+ARDOUR::Port::reset ()
 {
-       if (_ext_port) {
-               _ext_port->ensure_monitor_input (yn);
-       }
+       _last_monitor = false;
+
+       // XXX
+       // _metering = 0;
+       // reset_meters ();
 }
 
 void
-PortFacade::request_monitor_input (bool yn)
+ARDOUR::Port::recompute_total_latency () const
 {
-       if (_ext_port) {
-               _ext_port->request_monitor_input (yn);
-       } 
+#ifdef HAVE_JACK_RECOMPUTE_LATENCY     
+       if (_jack_port) {
+               jack_recompute_total_latency (_engine->jack (), _jack_port);
+       }
+#endif 
 }
 
-int
-PortFacade::connect (Port& other)
+nframes_t
+ARDOUR::Port::total_latency () const
 {
-       int ret;
-       
-       if (_ext_port) {
-               ret = _ext_port->connect (other);
+       if (_jack_port) {
+               return jack_port_get_total_latency (_engine->jack (), _jack_port);
        } else {
-               ret = 0;
-       }
-
-       if (ret == 0) {
-               ret = Port::connect (other);
+               return _latency;
        }
-
-       return ret;
 }
 
 int
-PortFacade::connect (const std::string& other)
+ARDOUR::Port::reestablish ()
 {
-       PortConnectableByName* pcn;
-
-       if (!_ext_port) {
-               return -1;
-       }
-               
-       pcn = dynamic_cast<PortConnectableByName*>(_ext_port);
-
-       if (pcn) {
-               return pcn->connect (other);
-       } else {
-               return -1;
+       if (!_jack_port) {
+               return 0;
        }
-}
 
+       _jack_port = jack_port_register (_engine->jack(), _name.c_str(), type().to_jack_type(), _flags, 0);
 
-int
-PortFacade::disconnect (Port& other)
-{
-       int reta;
-       int retb;
-       
-       if (_ext_port) {
-               reta = _ext_port->disconnect (other);
-       } else {
-               reta = 0;
+       if (_jack_port == 0) {
+               PBD::error << string_compose (_("could not reregister %1"), _name) << endmsg;
+               return -1;
        }
 
-       retb = Port::disconnect (other);
+       reset ();
 
-       return reta || retb;
+       return 0;
 }
 
-int 
-PortFacade::disconnect_all ()
-{
-       int reta = 0;
-       int retb = 0;
-
-       if (_ext_port) {
-               reta = _ext_port->disconnect_all ();
-       } 
-
-       retb = Port::disconnect_all ();
 
-       return reta || retb;
-}
-               
 int
-PortFacade::disconnect (const std::string& other)
+ARDOUR::Port::reconnect ()
 {
-       PortConnectableByName* pcn;
+       /* caller must hold process lock; intended to be used only after reestablish() */
 
-       if (!_ext_port) {
-               return -1;
-       }
-               
-       pcn = dynamic_cast<PortConnectableByName*>(_ext_port);
-
-       if (pcn) {
-               return pcn->disconnect (other);
-       } else {
-               return -1;
-       }
-}
-
-bool
-PortFacade::connected () const 
-{
-       if (Port::connected()) {
-               return true;
+       if (!_jack_port) {
+               return 0;
        }
-
-       if (_ext_port) {
-               return _ext_port->connected();
+       
+       for (std::set<string>::iterator i = _named_connections.begin(); i != _named_connections.end(); ++i) {
+               if (connect (*i)) {
+                       return -1;
+               }
        }
 
-       return false;
+       return 0;
 }
-bool
-PortFacade::connected_to (const std::string& portname) const 
-{
-       if (Port::connected_to (portname)) {
-               return true;
-       }
-
-       if (_ext_port) {
-               return _ext_port->connected_to (portname);
-       }
-
-       return false;
 
-}
 
 int
-PortFacade::get_connections (vector<string>& names) const 
+ARDOUR::Port::set_name (std::string const & n)
 {
-       int i = 0;
-
-       if (_ext_port) {
-               i = _ext_port->get_connections (names);
+       int r = 0;
+       
+       if (_jack_port) {
+               r = jack_port_set_name (_jack_port, n.c_str());
+               if (r) {
+                       _name = n;
+               }
+       } else {
+               _name = n;
        }
 
-       i += Port::get_connections (names);
-
-       return i;
+       return r;
 }
 
 void
-PortFacade::reset ()
+ARDOUR::Port::set_latency (nframes_t n)
 {
-       Port::reset ();
+       _latency = n;
+}
 
-       if (_ext_port) {
-               _ext_port->reset ();
+void
+ARDOUR::Port::request_monitor_input (bool yn)
+{
+       if (_jack_port) {
+               jack_port_request_monitor (_jack_port, yn);
        }
 }
-
index 3182c2b9598a5f7301d0c0e25796f2743fbd8774..12af468d9ba4d9fb123c31e16604267c55ea678d 100644 (file)
@@ -17,6 +17,8 @@
 */
 
 #include <ardour/port_set.h>
+#include <ardour/midi_port.h>
+#include <ardour/audio_port.h>
 
 namespace ARDOUR {
 
index 2b4d264bbbdcbfbe21acda962a4346ddfff4d06c..77d197ced5d4ab49aa83672e862b461dd6c76dd9 100644 (file)
@@ -81,6 +81,7 @@
 #include <ardour/session_directory.h>
 #include <ardour/tape_file_matcher.h>
 #include <ardour/analyser.h>
+#include <ardour/audio_buffer.h>
 #include <ardour/bundle.h>
 
 #include "i18n.h"
index fde698803ca6b4eaedc8fe59134adae91ed6e920..71e444893fb02bfbce198b6f8390d10d3100341d 100644 (file)
@@ -25,6 +25,7 @@
 #include <ardour/tempo.h>
 #include <ardour/io.h>
 #include <ardour/buffer_set.h>
+#include <ardour/audio_buffer.h>
 
 #include <sndfile.h>
 
index ed52fd70a95cf1a608569d98caef96eb2d9a6343..ee44ce0c8624e99f03cb645a720564dfeb64730d 100644 (file)
@@ -31,6 +31,7 @@
 #include <ardour/audioplaylist.h>
 #include <ardour/panner.h>
 #include <ardour/utils.h>
+#include <ardour/port.h>
 
 #include "i18n.h"