merge from trunk
authorHans Fugal <hans@fugal.net>
Sat, 12 Aug 2006 21:57:07 +0000 (21:57 +0000)
committerHans Fugal <hans@fugal.net>
Sat, 12 Aug 2006 21:57:07 +0000 (21:57 +0000)
git-svn-id: svn://localhost/ardour2/branches/undo@802 d708f5d6-7413-0410-9779-e7cbd77b26cf

13 files changed:
gtk2_ardour/SConscript
gtk2_ardour/au_pluginui.cc
gtk2_ardour/au_pluginui.h [new file with mode: 0644]
gtk2_ardour/audio_time_axis.cc
gtk2_ardour/mixer_strip.cc
gtk2_ardour/plugin_ui.cc
gtk2_ardour/plugin_ui.h
gtk2_ardour/redirect_box.cc
gtk2_ardour/region_view.cc
gtk2_ardour/route_time_axis.cc
libs/ardour/ardour/audio_unit.h
libs/ardour/audio_unit.cc
libs/pbd/pbd/rcu.h

index 2a7250eaa42fb0931abdf708ed91960a4c57252e..658caac1e3324788ea016a1795bf036b0b0b9065 100644 (file)
@@ -200,6 +200,11 @@ mtest_files=Split("""
 mtest.cc
 """)
 
+
+rcu_files=Split("""
+rcu.cc
+""")
+
 itest_files=Split("""
 itest.cc
 """)
@@ -215,6 +220,7 @@ if env['VST']:
 if gtkardour['COREAUDIO']:
     extra_sources += coreaudio_files
     gtkardour.Append(CCFLAGS='-DHAVE_COREAUDIO')
+    gtkardour.Append(LINKFLAGS='-framework Carbon')
     gtkardour.Merge([libraries['appleutility']])
  
 if env['FFT_ANALYSIS']:
@@ -238,6 +244,7 @@ ardourlib = gtkardour.SharedLibrary(target = 'ardourgtk', source = gtkardour_fil
 
 mtest = gtkardour.Program(target = 'mtest', source = mtest_files)
 itest = gtkardour.Program(target = 'itest', source = itest_files)
+rcu = gtkardour.Program(target = 'rcu', source = rcu_files)
 
 my_subst_dict = { }
 my_subst_dict['%INSTALL_PREFIX%'] = install_prefix
index e4a5c73fe96f850d0dc1f0ad87f57b5a78715eda..092e34d50beaa0b0b477f35a5d68b10a53ef88c8 100644 (file)
 
 */
 
-#include <ardour/insert.h>
 #include <ardour/audio_unit.h>
+#include <ardour/insert.h>
+
+#include <gtkmm2ext/doi.h>
+
+#include "au_pluginui.h"
+#include "gui_thread.h"
 
-#include "plugin_ui.h"
+#include <appleutility/CAAudioUnit.h>
+#include <appleutility/CAComponent.h>
+
+#include <AudioUnit/AudioUnit.h>
 
 #include "i18n.h"
 
 using namespace ARDOUR;
 using namespace PBD;
 
-AUPluginUI::AUPluginUI (boost::shared_ptr<PluginInsert> ap)
+AUPluginUI::AUPluginUI (boost::shared_ptr<PluginInsert> insert)
 {
-       if ((au = boost::dynamic_pointer_cast<AUPlugin> (ap->plugin())) == 0) {
+       if ((au = boost::dynamic_pointer_cast<AUPlugin> (insert->plugin())) == 0) {
                error << _("unknown type of editor-supplying plugin (note: no AudioUnit support in this version of ardour)") << endmsg;
                throw failed_constructor ();
        }
 
+       OSStatus err = noErr;
+       
+       CAComponentDescription desc;
+       Component carbonViewComponent = NULL;
+       AudioUnitCarbonView carbonView = NULL;
+       
+       GetComponentInfo(au->get_comp()->Comp(), &desc, 0, 0, 0);
+       carbonViewComponent = get_carbon_view_component(desc.componentSubType);
+       err = OpenAComponent(carbonViewComponent, &carbonView);
+       
+       Rect rec;
+       rec.top = 0;
+       rec.left = 0;
+       rec.bottom = 400;
+       rec.right = 500;
+       
+       ProcessSerialNumber ourPSN;
+       
+       /* Here we will set the MacOSX native section of the process to the foreground for putting up this
+     * dialog box.  First step is to get our process serial number.  We do this by calling 
+     * GetCurrentProcess. 
+     * First Argument: On success this PSN will be our PSN on return.
+     * Return Value: A Macintosh error indicating success or failure.
+     */
+    err = GetCurrentProcess(&ourPSN);
+    
+    //If no error then set this process to be frontmost.
+    if (err == noErr) {
+        /* Calling SetFrontProcess to make us frontmost.
+         * First Argument: The Process Serial Number of the process we want to make frontmost.  Here
+         *    of course we pass our process serial number
+         * Return Value: An error value indicating success or failure.  We just ignore the return
+         *    value here.
+         */
+        (void)SetFrontProcess(&ourPSN);
+    } else {
+               error << "couldn't get current process" << endmsg;
+       }
+       
+       err = CreateNewWindow (kDocumentWindowClass, kWindowStandardFloatingAttributes, &rec, &wr);
+       
+       ComponentResult auResult;
+       ControlRef rootControl = NULL;
+       GetRootControl(wr, &rootControl);
+       
+       int width = 500;
+       int height = 400;
+       Float32Point location = {30, 30};
+       Float32Point size = {width, height};
+       ControlRef audioUnitControl = NULL;
+       
+       auResult = AudioUnitCarbonViewCreate(carbonView,
+                                            au->get_au()->AU(),
+                                            wr,
+                                            rootControl,
+                                            &location,
+                                            &size,
+                                            &audioUnitControl);    
+       
+       ShowWindow (wr);
+       BringToFront (wr);
+//     AudioUnitCarbonViewSetEventListener(carbonView, EventListener, this);
 #if 0
-       set_position (Gtk::WIN_POS_MOUSE);
        set_name ("PluginEditor");
        add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
 
        signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), reinterpret_cast<Window*> (this)));
-       insert->GoingAway.connect (mem_fun(*this, &PluginUIWindow::plugin_going_away));
+#endif 
 
-       if (scrollable) {
-               gint h = _pluginui->get_preferred_height ();
-               if (h > 600) h = 600;
-               set_default_size (450, h); 
-       }
-#endif
+       insert->GoingAway.connect (mem_fun(*this, &AUPluginUI::plugin_going_away));
+       
        info << "AUPluginUI created" << endmsg;
 }
 
@@ -56,3 +121,39 @@ AUPluginUI::~AUPluginUI ()
 {
        // nothing to do here - plugin destructor destroys the GUI
 }
+
+void
+AUPluginUI::plugin_going_away (ARDOUR::Redirect* ignored)
+{
+        ENSURE_GUI_THREAD(bind (mem_fun(*this, &AUPluginUI::plugin_going_away), ignored));
+
+        delete_when_idle (this);
+}
+
+Component
+AUPluginUI::get_carbon_view_component(OSType subtype)
+{
+       ComponentDescription desc;
+       Component component;
+       
+       desc.componentType = kAudioUnitCarbonViewComponentType; // 'auvw'
+       desc.componentSubType = subtype;
+       desc.componentManufacturer = 0;
+       desc.componentFlags = 0;
+       desc.componentFlagsMask = 0;
+       
+       // First see if we can find a carbon view designed specifically for this
+       // plug-in:
+       
+       component = FindNextComponent(NULL, &desc);
+       if (component)
+          return component;
+       
+       // If not, grab the generic carbon view, which will create a GUI for
+       // any Audio Unit.
+       
+       desc.componentSubType = kAUCarbonViewSubType_Generic;
+       component = FindNextComponent(NULL, &desc);
+       
+       return component;
+}
diff --git a/gtk2_ardour/au_pluginui.h b/gtk2_ardour/au_pluginui.h
new file mode 100644 (file)
index 0000000..2dcefcc
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+    Copyright (C) 2006 Paul Davis 
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __au_plugin_ui_h__
+#define __au_plugin_ui_h__
+
+#include <boost/shared_ptr.hpp>
+
+#include <Carbon/Carbon.h>
+#include <AudioUnit/AudioUnit.h>
+
+namespace ARDOUR {
+       class AUPlugin;
+       class PluginInsert;
+       class Redirect;
+}
+
+class AUPluginUI
+{
+  public:
+       AUPluginUI (boost::shared_ptr<ARDOUR::PluginInsert>);
+       ~AUPluginUI ();
+       
+  private:
+       WindowRef wr;
+       boost::shared_ptr<ARDOUR::AUPlugin> au;
+
+       void plugin_going_away (ARDOUR::Redirect*);
+       Component get_carbon_view_component(OSType subtype);
+};
+
+#endif // __au_plugin_ui_h__
index 9ae94d1fe0ac6c201fd9b3136236fb2b6a80951a..f8ace8244f9f04fbc3cf480b54ae26ee97f7886e 100644 (file)
@@ -60,8 +60,6 @@
 #include "keyboard.h"
 #include "pan_automation_time_axis.h"
 #include "playlist_selector.h"
-#include "plugin_selector.h"
-#include "plugin_ui.h"
 #include "prompter.h"
 #include "public_editor.h"
 #include "audio_region_view.h"
index 4f3dc720d917aac8074ca5bc8cbbbd4a901b392a..b089883c80a2d5a98f650af89ea1abaf0f589c32 100644 (file)
@@ -50,9 +50,7 @@
 #include "mixer_strip.h"
 #include "mixer_ui.h"
 #include "keyboard.h"
-#include "plugin_selector.h"
 #include "public_editor.h"
-#include "plugin_ui.h"
 #include "send_ui.h"
 #include "io_selector.h"
 #include "utils.h"
index 4619d50359755ee15855d479f32e668ffda3bc8d..154c2fd3cfb000325fbc43a183b58fd3b90e62e9 100644 (file)
@@ -205,3 +205,4 @@ PlugUIBase::bypass_toggled ()
                insert->set_active (!x, this);
        }
 }
+
index 5c940843f72fb226ffcf7d5c182b89253c1d5f03..fd5516cee12d408996258e89629f4ae074e2bd62 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2000 Paul Davis 
+    Copyright (C) 2000-2006 Paul Davis 
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -234,16 +234,4 @@ class VSTPluginUI : public PlugUIBase, public Gtk::VBox
 };
 #endif // VST_SUPPORT
 
-#ifdef HAVE_COREAUDIO
-class AUPluginUI
-{
-  public:
-       AUPluginUI (boost::shared_ptr<ARDOUR::PluginInsert>);
-       ~AUPluginUI ();
-       
-  private:
-       boost::shared_ptr<ARDOUR::AUPlugin> au;
-};
-#endif // HAVE_COREAUDIO
-
 #endif /* __ardour_plugin_ui_h__ */
index f93dfb9433c8fb88cea2982b5e53c0b6ee3b55a7..058cc9f5ab912d92713bc5b2c505e030ea78d48b 100644 (file)
@@ -54,7 +54,6 @@
 #include "route_redirect_selection.h"
 #include "mixer_ui.h"
 #include "actions.h"
-
 #include "plugin_ui.h"
 #include "send_ui.h"
 #include "io_selector.h"
 
 #include "i18n.h"
 
+#ifdef HAVE_COREAUDIO
+#include "au_pluginui.h"
+#endif
+
 using namespace sigc;
 using namespace ARDOUR;
 using namespace PBD;
index ebec4261ac77104084fc7b10f5c7a3b50c9cb1e1..8e80b147e500ef2302fa92d0ccefaebd24314f83 100644 (file)
@@ -111,10 +111,14 @@ RegionView::init (Gdk::Color& basic_color, bool wfd)
        compute_colors (basic_color);
 
        name_highlight->set_data ("regionview", this);
-       name_text->set_data ("regionview", this);
+
+       if (name_text) {
+               name_text->set_data ("regionview", this);
+       }
 
        /* an equilateral triangle */
-    ArdourCanvas::Points shape;
+
+       ArdourCanvas::Points shape;
        shape.push_back (Gnome::Art::Point (-((sync_mark_width-1)/2), 1));
        shape.push_back (Gnome::Art::Point ((sync_mark_width - 1)/2, 1));
        shape.push_back (Gnome::Art::Point (0, sync_mark_width - 1));
index 0d7405e4f6f467fc7f3a30e955e7404249083370..6e578a13e7cc75b6868d3875b197c247409a750a 100644 (file)
@@ -61,8 +61,6 @@
 #include "gui_thread.h"
 #include "keyboard.h"
 #include "playlist_selector.h"
-#include "plugin_selector.h"
-#include "plugin_ui.h"
 #include "point_selection.h"
 #include "prompter.h"
 #include "public_editor.h"
index 348a8ff86313fdba0163e798357575352187485d..a007f41d2b6bdcc1ceab0b616edda961e02d317a 100644 (file)
@@ -86,6 +86,9 @@ class AUPlugin : public ARDOUR::Plugin
     
        bool has_editor () const;
        
+       CAAudioUnit* get_au () { return unit; }
+       CAComponent* get_comp () { return comp; }
+       
   private:
        CAComponent* comp;
     CAAudioUnit* unit;
@@ -110,6 +113,7 @@ class AUPluginInfo : public PluginInfo {
 
   private:
        static std::string get_name (CAComponentDescription&);
+       void setup_nchannels (CAComponentDescription&);
 };
 
 typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
index 0a31df40ee7c207ce7456d3b3a4253ae5339f988..ad9862181407fe0ba9389fae42d817756b5df266 100644 (file)
@@ -137,7 +137,7 @@ AUPlugin::get_parameter (uint32_t which) const
 int
 AUPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const
 {
-       return -1;
+       return 0;
 }
 
 uint32_t
@@ -325,6 +325,7 @@ AUPluginInfo::discover ()
                plug->type = ARDOUR::AudioUnit;
                plug->n_inputs = 0;
                plug->n_outputs = 0;
+               // plug->setup_nchannels (temp);
                plug->category = "AudioUnit";
                plug->desc = new CAComponentDescription(temp);
 
@@ -376,3 +377,20 @@ AUPluginInfo::get_name (CAComponentDescription& comp_desc)
        
        return CFStringRefToStdString(itemName);
 }
+
+void
+AUPluginInfo::setup_nchannels (CAComponentDescription& comp_desc)
+{
+       CAAudioUnit unit;
+       
+       CAAudioUnit::Open (comp_desc, unit);
+       
+       if (unit.SupportsNumChannels()) {
+               n_inputs = n_outputs = 0;
+       } else {
+               AUChannelInfo cinfo;
+               size_t info_size = sizeof(cinfo);
+               OSStatus err = AudioUnitGetProperty (unit.AU(), kAudioUnitProperty_SupportedNumChannels, kAudioUnitScope_Global,
+                                             0, &cinfo, &info_size);
+       }
+}
index 6d9586cb3c6bfc68b7be43b762d8da92f2f3c834..58a92a206a574e3e4066af422ff065cbfad304b8 100644 (file)
@@ -6,32 +6,29 @@
  
 #include <list> 
  
 template<class T>
 class RCUManager
 {
-public:
-       RCUManager (T* new_rcu_value)
-               : m_rcu_value(new_rcu_value)
-       {
+  public:
  
+       RCUManager (T* new_rcu_value) {
+               m_rcu_value = new boost::shared_ptr<T> (new_rcu_value);
        }
  
-       virtual ~RCUManager() { }
+       virtual ~RCUManager() { delete m_rcu_value; }
  
-       boost::shared_ptr<T> reader () const { return m_rcu_value; }
+        boost::shared_ptr<T> reader () const { return *((boost::shared_ptr<T> *) g_atomic_pointer_get (&m_rcu_value)); }
  
-       // should be private
        virtual boost::shared_ptr<T> write_copy () = 0;
-       // should be private
-       virtual void update (boost::shared_ptr<T> new_value) = 0;
-protected:
-       boost::shared_ptr<T> m_rcu_value;
+       virtual bool update (boost::shared_ptr<T> new_value) = 0;
+
+  protected:
+       boost::shared_ptr<T>* m_rcu_value;
+
+       // this monstrosity is needed because of some wierd behavior by g++
+
+       gpointer * the_pointer() const { return (gpointer *) &m_rcu_value; }
 };
  
  
@@ -49,37 +46,63 @@ public:
        virtual boost::shared_ptr<T> write_copy ()
        {
                m_lock.lock();
-               // I hope this is doing what I think it is doing :)
-               boost::shared_ptr<T> new_copy(new T(*RCUManager<T>::m_rcu_value));
-               // XXX todo remove old copies with only 1 reference from the list.
+
+               // clean out any dead wood
+
+               typename std::list<boost::shared_ptr<T> >::iterator i;
+
+               for (i = m_dead_wood.begin(); i != m_dead_wood.end(); ) {
+                       if ((*i).use_count() == 1) {
+                               i = m_dead_wood.erase (i);
+                       } else {
+                               ++i;
+                       }
+               }
+
+               // store the current 
+
+               current_write_old = RCUManager<T>::m_rcu_value;
+               
+               boost::shared_ptr<T> new_copy (new T(**current_write_old));
+               
                return new_copy;
        }
  
-       virtual void update (boost::shared_ptr<T> new_value)
+       virtual bool update (boost::shared_ptr<T> new_value)
        {
-               // So a current reader doesn't hold the only reference to
-               // the existing value when we assign it a new value which 
-               // should ensure that deletion of old values doesn't
-               // occur in a reader thread.
-               boost::shared_ptr<T> old_copy = RCUManager<T>::m_rcu_value;
                // we hold the lock at this point effectively blocking
                // other writers.
-               RCUManager<T>::m_rcu_value = new_value;
-               // XXX add the old value to the list of old copies.
+
+               boost::shared_ptr<T>* new_spp = new boost::shared_ptr<T> (new_value);
+
+               // update, checking that nobody beat us to it
+
+               bool ret = g_atomic_pointer_compare_and_exchange (RCUManager<T>::the_pointer(),
+                                                                 (gpointer) current_write_old,
+                                                                 (gpointer) new_spp);
+               
+               if (ret) {
+
+                       // successful update : put the old value into dead_wood,
+
+                       m_dead_wood.push_back (*current_write_old);
+
+                       // now delete it - this gets rid of the shared_ptr<T> but
+                       // because dead_wood contains another shared_ptr<T> that
+                       // references the same T, the underlying object lives on
+
+                       delete current_write_old;
+               }
+
                m_lock.unlock();
+
+               return ret;
        }
  
 private:
-       Glib::Mutex                     m_lock;
-       std::list<boost::shared_ptr<T> > m_old_values;
+       Glib::Mutex                      m_lock;
+       boost::shared_ptr<T>*            current_write_old;
+       std::list<boost::shared_ptr<T> > m_dead_wood;
 };
  
 template<class T>