Merged with trunk R776
git-svn-id: svn://localhost/ardour2/branches/midi@777 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
38c7d34d8c
commit
ab6f1ed9ba
18
SConstruct
18
SConstruct
|
@ -454,6 +454,9 @@ conf = Configure (libraries['flac'])
|
|||
conf.CheckLib ('FLAC', 'FLAC__stream_decoder_new', language='CXX')
|
||||
libraries['flac'] = conf.Finish ()
|
||||
|
||||
# or if that fails...
|
||||
#libraries['flac'] = LibraryInfo (LIBS='FLAC')
|
||||
|
||||
#
|
||||
# Check for liblo
|
||||
|
||||
|
@ -547,6 +550,10 @@ if env['SYSLIBS']:
|
|||
# libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
|
||||
libraries['soundtouch'] = LibraryInfo()
|
||||
libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
|
||||
|
||||
libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
|
||||
LIBPATH='#libs/appleutility',
|
||||
CPPPATH='#libs/appleutility')
|
||||
|
||||
coredirs = [
|
||||
'templates'
|
||||
|
@ -561,6 +568,9 @@ if env['SYSLIBS']:
|
|||
|
||||
if env['VST']:
|
||||
subdirs = ['libs/fst'] + subdirs + ['vst']
|
||||
|
||||
if env['COREAUDIO']:
|
||||
subdirs = subdirs + ['libs/appleutility']
|
||||
|
||||
gtk_subdirs = [
|
||||
# 'libs/flowcanvas',
|
||||
|
@ -600,7 +610,10 @@ else:
|
|||
# libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
|
||||
# LIBPATH='#libs/libglademm',
|
||||
# CPPPATH='#libs/libglademm')
|
||||
|
||||
libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
|
||||
LIBPATH='#libs/appleutility',
|
||||
CPPPATH='#libs/appleutility')
|
||||
|
||||
coredirs = [
|
||||
'libs/soundtouch',
|
||||
'templates'
|
||||
|
@ -616,6 +629,9 @@ else:
|
|||
|
||||
if env['VST']:
|
||||
subdirs = ['libs/fst'] + subdirs + ['vst']
|
||||
|
||||
if env['COREAUDIO']:
|
||||
subdirs = subdirs + ['libs/appleutility']
|
||||
|
||||
gtk_subdirs = [
|
||||
'libs/glibmm2',
|
||||
|
|
|
@ -972,13 +972,13 @@ ENABLE_PREPROCESSING = YES
|
|||
# compilation will be performed. Macro expansion can be done in a controlled
|
||||
# way by setting EXPAND_ONLY_PREDEF to YES.
|
||||
|
||||
MACRO_EXPANSION = NO
|
||||
MACRO_EXPANSION = YES
|
||||
|
||||
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
|
||||
# then the macro expansion is limited to the macros specified with the
|
||||
# PREDEFINED and EXPAND_AS_DEFINED tags.
|
||||
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
|
||||
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
|
||||
# in the INCLUDE_PATH (see below) will be search if a #include is found.
|
||||
|
@ -1006,7 +1006,7 @@ INCLUDE_FILE_PATTERNS =
|
|||
# undefined via #undef or recursively expanded use the := operator
|
||||
# instead of the = operator.
|
||||
|
||||
PREDEFINED =
|
||||
PREDEFINED = HAVE_COREAUDIO VST_SUPPORT HAVE_LIBLO FFT_ANALYSIS
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
||||
# this tag can be used to specify a list of macro names that should be expanded.
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright (C) 2006 Paul Davis
|
||||
Written by Taybin Rutkin
|
||||
|
||||
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 <ardour/insert.h>
|
||||
#include <ardour/audio_unit.h>
|
||||
|
||||
#include "plugin_ui.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
AUPluginUI::AUPluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_ptr<AUPlugin> ap)
|
||||
: PlugUIBase (pi),
|
||||
au (ap)
|
||||
{
|
||||
info << "AUPluginUI created" << endmsg;
|
||||
}
|
||||
|
||||
AUPluginUI::~AUPluginUI ()
|
||||
{
|
||||
// nothing to do here - plugin destructor destroys the GUI
|
||||
}
|
||||
|
||||
int
|
||||
AUPluginUI::get_preferred_height ()
|
||||
{
|
||||
return -1;
|
||||
}
|
|
@ -59,6 +59,7 @@ if gtkardour['FFT_ANALYSIS']:
|
|||
|
||||
if gtkardour['COREAUDIO']:
|
||||
gtkardour.Append(CCFLAGS='-DHAVE_COREAUDIO')
|
||||
gtkardour.Merge([libraries['appleutility']])
|
||||
|
||||
skipped_files=Split("""
|
||||
connection_editor.cc
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
export ARDOUR_PATH=./glade:./pixmaps:.
|
||||
|
||||
export LD_LIBRARY_PATH=../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libsndfile:$LD_LIBRARY_PATH
|
||||
export LD_LIBRARY_PATH=../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libsndfile:../libs/appleutility:$LD_LIBRARY_PATH
|
||||
|
||||
# DYLD_LIBRARY_PATH is for darwin.
|
||||
export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
|
||||
|
|
|
@ -219,6 +219,14 @@ style "mute_button" = "small_button"
|
|||
fg[PRELIGHT] = { 0, 0, 0 }
|
||||
}
|
||||
|
||||
|
||||
style "multiline_combo" = "small_button"
|
||||
{
|
||||
font_name = "sans 8"
|
||||
xthickness = 0
|
||||
ythickness = 0
|
||||
}
|
||||
|
||||
style "mixer_mute_button" = "mute_button"
|
||||
{
|
||||
font_name = "sans 7"
|
||||
|
@ -951,6 +959,7 @@ widget "*TrackRecordEnableButton" style "track_rec_enable_button"
|
|||
widget "*TrackRecordEnableButton*" style "track_rec_enable_button"
|
||||
widget "*TrackMuteButton*" style "mute_button"
|
||||
widget "*TrackLoopButton*" style "track_loop_button"
|
||||
widget "*PanAutomationLineSelector*" style "multiline_combo"
|
||||
widget "*EditorTimeButton*" style "time_button"
|
||||
widget "*EditorMixerButton*" style "default_buttons_menus"
|
||||
widget "*SoloButton*" style "solo_button"
|
||||
|
|
|
@ -1326,6 +1326,7 @@ ARDOUR_UI::start_engine ()
|
|||
settings for a new session
|
||||
*/
|
||||
session->save_state ("");
|
||||
session->save_history ();
|
||||
}
|
||||
|
||||
/* there is too much going on, in too many threads, for us to
|
||||
|
@ -1499,6 +1500,7 @@ ARDOUR_UI::save_state_canfail (string name)
|
|||
}
|
||||
|
||||
if ((ret = session->save_state (name)) != 0) {
|
||||
session->save_history();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,6 +156,7 @@ ARDOUR_UI::unload_session ()
|
|||
|
||||
case 1:
|
||||
session->save_state ("");
|
||||
session->save_history();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <ardour/audioregion.h>
|
||||
#include <ardour/audiosource.h>
|
||||
#include <ardour/audio_diskstream.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "streamview.h"
|
||||
#include "audio_region_view.h"
|
||||
|
@ -896,18 +897,20 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
|
|||
gain_line->view_to_model_y (y);
|
||||
|
||||
trackview.session().begin_reversible_command (_("add gain control point"));
|
||||
trackview.session().add_undo (audio_region().envelope().get_memento());
|
||||
XMLNode &before = audio_region().envelope().get_state();
|
||||
|
||||
|
||||
if (!audio_region().envelope_active()) {
|
||||
trackview.session().add_undo( bind( mem_fun(audio_region(), &AudioRegion::set_envelope_active), false) );
|
||||
XMLNode &before = audio_region().get_state();
|
||||
audio_region().set_envelope_active(true);
|
||||
trackview.session().add_redo( bind( mem_fun(audio_region(), &AudioRegion::set_envelope_active), true) );
|
||||
XMLNode &after = audio_region().get_state();
|
||||
trackview.session().add_command (new MementoCommand<AudioRegion>(audio_region(), before, after));
|
||||
}
|
||||
|
||||
audio_region().envelope().add (fx, y);
|
||||
|
||||
trackview.session().add_redo_no_execute (audio_region().envelope().get_memento());
|
||||
XMLNode &after = audio_region().envelope().get_state();
|
||||
trackview.session().add_command (new MementoCommand<Curve>(audio_region().envelope(), before, after));
|
||||
trackview.session().commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <pbd/error.h>
|
||||
#include <pbd/stl_delete.h>
|
||||
#include <pbd/whitespace.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include <gtkmm2ext/gtk_ui.h>
|
||||
#include <gtkmm2ext/selector.h>
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include <pbd/stl_delete.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include <ardour/automation_event.h>
|
||||
#include <ardour/curve.h>
|
||||
|
@ -887,7 +888,7 @@ AutomationLine::start_drag (ControlPoint* cp, float fraction)
|
|||
}
|
||||
|
||||
trackview.editor.current_session()->begin_reversible_command (str);
|
||||
trackview.editor.current_session()->add_undo (get_memento());
|
||||
trackview.editor.current_session()->add_command (new MementoUndoCommand<AutomationLine>(*this, get_state()));
|
||||
|
||||
first_drag_fraction = fraction;
|
||||
last_drag_fraction = fraction;
|
||||
|
@ -936,7 +937,7 @@ AutomationLine::end_drag (ControlPoint* cp)
|
|||
|
||||
update_pending = false;
|
||||
|
||||
trackview.editor.current_session()->add_redo_no_execute (get_memento());
|
||||
trackview.editor.current_session()->add_command (new MementoRedoCommand<AutomationLine>(*this, get_state()));
|
||||
trackview.editor.current_session()->commit_reversible_command ();
|
||||
trackview.editor.current_session()->set_dirty ();
|
||||
}
|
||||
|
@ -1013,11 +1014,11 @@ AutomationLine::remove_point (ControlPoint& cp)
|
|||
model_representation (cp, mr);
|
||||
|
||||
trackview.editor.current_session()->begin_reversible_command (_("remove control point"));
|
||||
trackview.editor.current_session()->add_undo (get_memento());
|
||||
XMLNode &before = get_state();
|
||||
|
||||
alist.erase (mr.start, mr.end);
|
||||
|
||||
trackview.editor.current_session()->add_redo_no_execute (get_memento());
|
||||
trackview.editor.current_session()->add_command(new MementoCommand<AutomationLine>(*this, before, get_state()));
|
||||
trackview.editor.current_session()->commit_reversible_command ();
|
||||
trackview.editor.current_session()->set_dirty ();
|
||||
}
|
||||
|
@ -1225,9 +1226,9 @@ void
|
|||
AutomationLine::clear ()
|
||||
{
|
||||
/* parent must create command */
|
||||
trackview.editor.current_session()->add_undo (get_memento());
|
||||
XMLNode &before = get_state();
|
||||
alist.clear();
|
||||
trackview.editor.current_session()->add_redo_no_execute (get_memento());
|
||||
trackview.editor.current_session()->add_command (new MementoCommand<AutomationLine>(*this, before, get_state()));
|
||||
trackview.editor.current_session()->commit_reversible_command ();
|
||||
trackview.editor.current_session()->set_dirty ();
|
||||
}
|
||||
|
@ -1266,3 +1267,16 @@ AutomationLine::hide_all_but_selected_control_points ()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
XMLNode &AutomationLine::get_state(void)
|
||||
{
|
||||
// TODO
|
||||
return alist.get_state();
|
||||
}
|
||||
|
||||
int AutomationLine::set_state(const XMLNode &node)
|
||||
{
|
||||
// TODO
|
||||
alist.set_state(node);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ class ControlPoint
|
|||
ShapeType _shape;
|
||||
};
|
||||
|
||||
class AutomationLine : public sigc::trackable
|
||||
class AutomationLine : public sigc::trackable, public Stateful
|
||||
{
|
||||
public:
|
||||
AutomationLine (const string & name, TimeAxisView&, ArdourCanvas::Group&, ARDOUR::AutomationList&);
|
||||
|
@ -158,7 +158,12 @@ class AutomationLine : public sigc::trackable
|
|||
bool is_last_point (ControlPoint &);
|
||||
bool is_first_point (ControlPoint &);
|
||||
|
||||
XMLNode& get_state (void);
|
||||
int set_state (const XMLNode&);
|
||||
|
||||
PBD::ID id() { return _id; }
|
||||
protected:
|
||||
PBD::ID _id;
|
||||
string _name;
|
||||
guint32 _height;
|
||||
uint32_t _line_color;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <ardour/route.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "ardour_ui.h"
|
||||
#include "automation_time_axis.h"
|
||||
|
@ -40,6 +41,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Ro
|
|||
auto_write_item = 0;
|
||||
auto_play_item = 0;
|
||||
ignore_state_request = false;
|
||||
first_call_to_set_height = true;
|
||||
|
||||
// base_rect = gnome_canvas_item_new (GNOME_CANVAS_GROUP(canvas_display),
|
||||
// gnome_canvas_simplerect_get_type(),
|
||||
|
@ -72,6 +74,8 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Ro
|
|||
clear_button.set_name ("TrackVisualButton");
|
||||
hide_button.set_name ("TrackRemoveButton");
|
||||
|
||||
controls_table.set_no_show_all();
|
||||
|
||||
ARDOUR_UI::instance()->tooltips().set_tip(height_button, _("track height"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip(auto_button, _("automation state"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip(clear_button, _("clear track"));
|
||||
|
@ -98,7 +102,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Ro
|
|||
}
|
||||
}
|
||||
name_label.set_text (shortpname);
|
||||
name_label.set_alignment (1.0, 0.5);
|
||||
name_label.set_alignment (Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
|
||||
|
||||
if (nomparent.length()) {
|
||||
|
||||
|
@ -114,7 +118,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Ro
|
|||
|
||||
plugname = new Label (pname);
|
||||
plugname->set_name (X_("TrackPlugName"));
|
||||
plugname->set_alignment (1.0, 0.5);
|
||||
plugname->show();
|
||||
name_label.set_name (X_("TrackParameterName"));
|
||||
controls_table.remove (name_hbox);
|
||||
controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
|
@ -138,8 +142,8 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Ro
|
|||
controls_table.attach (hide_button, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
controls_table.attach (height_button, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
|
||||
controls_table.attach (auto_button, 6, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
controls_table.attach (clear_button, 6, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
controls_table.attach (auto_button, 5, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
controls_table.attach (clear_button, 5, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
|
||||
controls_table.show_all ();
|
||||
|
||||
|
@ -281,11 +285,11 @@ AutomationTimeAxisView::set_height (TrackHeight ht)
|
|||
uint32_t h = height_to_pixels (ht);
|
||||
bool changed = (height != (uint32_t) h);
|
||||
|
||||
bool changed_between_small_and_normal = ( (ht == Small || ht == Smaller) ^ (height_style == Small || height_style == Smaller) );
|
||||
|
||||
TimeAxisView* state_parent = get_parent_with_state ();
|
||||
XMLNode* xml_node = state_parent->get_child_xml_node (_state_name);
|
||||
|
||||
//controls_table.show_all ();
|
||||
|
||||
TimeAxisView::set_height (ht);
|
||||
base_rect->property_y2() = h;
|
||||
|
||||
|
@ -297,117 +301,88 @@ AutomationTimeAxisView::set_height (TrackHeight ht)
|
|||
(*i)->set_height ();
|
||||
}
|
||||
|
||||
|
||||
switch (ht) {
|
||||
case Largest:
|
||||
xml_node->add_property ("track_height", "largest");
|
||||
controls_table.remove (name_hbox);
|
||||
if (plugname) {
|
||||
if (plugname_packed) {
|
||||
controls_table.remove (*plugname);
|
||||
plugname_packed = false;
|
||||
}
|
||||
controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
plugname_packed = true;
|
||||
controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
} else {
|
||||
controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
}
|
||||
controls_table.show_all ();
|
||||
|
||||
hide_name_entry ();
|
||||
show_name_label ();
|
||||
break;
|
||||
|
||||
case Large:
|
||||
xml_node->add_property ("track_height", "large");
|
||||
controls_table.remove (name_hbox);
|
||||
if (plugname) {
|
||||
if (plugname_packed) {
|
||||
controls_table.remove (*plugname);
|
||||
plugname_packed = false;
|
||||
}
|
||||
controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
plugname_packed = true;
|
||||
} else {
|
||||
controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
}
|
||||
controls_table.show_all ();
|
||||
hide_name_entry ();
|
||||
show_name_label ();
|
||||
break;
|
||||
|
||||
case Larger:
|
||||
xml_node->add_property ("track_height", "larger");
|
||||
controls_table.remove (name_hbox);
|
||||
if (plugname) {
|
||||
if (plugname_packed) {
|
||||
controls_table.remove (*plugname);
|
||||
plugname_packed = false;
|
||||
}
|
||||
controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
plugname_packed = true;
|
||||
} else {
|
||||
controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
}
|
||||
controls_table.show_all ();
|
||||
hide_name_entry ();
|
||||
show_name_label ();
|
||||
break;
|
||||
|
||||
case Normal:
|
||||
xml_node->add_property ("track_height", "normal");
|
||||
controls_table.remove (name_hbox);
|
||||
if (plugname) {
|
||||
if (plugname_packed) {
|
||||
controls_table.remove (*plugname);
|
||||
plugname_packed = false;
|
||||
}
|
||||
controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
plugname_packed = true;
|
||||
controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
} else {
|
||||
controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
}
|
||||
controls_table.show_all ();
|
||||
hide_name_entry ();
|
||||
show_name_label ();
|
||||
break;
|
||||
|
||||
case Smaller:
|
||||
xml_node->add_property ("track_height", "smaller");
|
||||
controls_table.remove (name_hbox);
|
||||
if (plugname) {
|
||||
if (plugname_packed) {
|
||||
controls_table.remove (*plugname);
|
||||
plugname_packed = false;
|
||||
}
|
||||
}
|
||||
controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
controls_table.hide_all ();
|
||||
hide_name_entry ();
|
||||
show_name_label ();
|
||||
name_hbox.show_all ();
|
||||
controls_table.show ();
|
||||
break;
|
||||
|
||||
case Small:
|
||||
xml_node->add_property ("track_height", "small");
|
||||
controls_table.remove (name_hbox);
|
||||
if (plugname) {
|
||||
if (plugname_packed) {
|
||||
controls_table.remove (*plugname);
|
||||
plugname_packed = false;
|
||||
}
|
||||
}
|
||||
controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
controls_table.hide_all ();
|
||||
hide_name_entry ();
|
||||
show_name_label ();
|
||||
name_hbox.show_all ();
|
||||
controls_table.show ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (changed_between_small_and_normal || first_call_to_set_height) {
|
||||
first_call_to_set_height = false;
|
||||
switch (ht) {
|
||||
case Largest:
|
||||
case Large:
|
||||
case Larger:
|
||||
case Normal:
|
||||
|
||||
controls_table.remove (name_hbox);
|
||||
|
||||
if (plugname) {
|
||||
if (plugname_packed) {
|
||||
controls_table.remove (*plugname);
|
||||
plugname_packed = false;
|
||||
}
|
||||
controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
plugname_packed = true;
|
||||
controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
} else {
|
||||
controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
}
|
||||
hide_name_entry ();
|
||||
show_name_label ();
|
||||
name_hbox.show_all ();
|
||||
|
||||
auto_button.show();
|
||||
height_button.show();
|
||||
clear_button.show();
|
||||
hide_button.show_all();
|
||||
break;
|
||||
|
||||
case Smaller:
|
||||
case Small:
|
||||
|
||||
controls_table.remove (name_hbox);
|
||||
if (plugname) {
|
||||
if (plugname_packed) {
|
||||
controls_table.remove (*plugname);
|
||||
plugname_packed = false;
|
||||
}
|
||||
}
|
||||
controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
controls_table.hide_all ();
|
||||
hide_name_entry ();
|
||||
show_name_label ();
|
||||
name_hbox.show_all ();
|
||||
|
||||
auto_button.hide();
|
||||
height_button.hide();
|
||||
clear_button.hide();
|
||||
hide_button.hide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
/* only emit the signal if the height really changed */
|
||||
route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
|
||||
|
@ -501,13 +476,13 @@ AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& sel
|
|||
AutomationList& alist (line.the_list());
|
||||
bool ret = false;
|
||||
|
||||
_session.add_undo (alist.get_memento());
|
||||
XMLNode &before = alist.get_state();
|
||||
|
||||
switch (op) {
|
||||
case Cut:
|
||||
if ((what_we_got = alist.cut (selection.time.front().start, selection.time.front().end)) != 0) {
|
||||
editor.get_cut_buffer().add (what_we_got);
|
||||
_session.add_redo_no_execute (alist.get_memento());
|
||||
_session.add_command(new MementoCommand<AutomationList>(alist, before, alist.get_state()));
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
|
@ -519,7 +494,7 @@ AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& sel
|
|||
|
||||
case Clear:
|
||||
if ((what_we_got = alist.cut (selection.time.front().start, selection.time.front().end)) != 0) {
|
||||
_session.add_redo_no_execute (alist.get_memento());
|
||||
_session.add_command(new MementoCommand<AutomationList>(alist, before, alist.get_state()));
|
||||
delete what_we_got;
|
||||
what_we_got = 0;
|
||||
ret = true;
|
||||
|
@ -551,7 +526,7 @@ AutomationTimeAxisView::reset_objects_one (AutomationLine& line, PointSelection&
|
|||
{
|
||||
AutomationList& alist (line.the_list());
|
||||
|
||||
_session.add_undo (alist.get_memento());
|
||||
_session.add_command (new MementoUndoCommand<AutomationList>(alist, alist.get_state()));
|
||||
|
||||
for (PointSelection::iterator i = selection.begin(); i != selection.end(); ++i) {
|
||||
|
||||
|
@ -582,7 +557,7 @@ AutomationTimeAxisView::cut_copy_clear_objects_one (AutomationLine& line, PointS
|
|||
AutomationList& alist (line.the_list());
|
||||
bool ret = false;
|
||||
|
||||
_session.add_undo (alist.get_memento());
|
||||
XMLNode &before = alist.get_state();
|
||||
|
||||
for (PointSelection::iterator i = selection.begin(); i != selection.end(); ++i) {
|
||||
|
||||
|
@ -594,7 +569,7 @@ AutomationTimeAxisView::cut_copy_clear_objects_one (AutomationLine& line, PointS
|
|||
case Cut:
|
||||
if ((what_we_got = alist.cut ((*i).start, (*i).end)) != 0) {
|
||||
editor.get_cut_buffer().add (what_we_got);
|
||||
_session.add_redo_no_execute (alist.get_memento());
|
||||
_session.add_command (new MementoCommand<AutomationList>(alist, before, alist.get_state()));
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
|
@ -606,7 +581,7 @@ AutomationTimeAxisView::cut_copy_clear_objects_one (AutomationLine& line, PointS
|
|||
|
||||
case Clear:
|
||||
if ((what_we_got = alist.cut ((*i).start, (*i).end)) != 0) {
|
||||
_session.add_redo_no_execute (alist.get_memento());
|
||||
_session.add_command (new MementoCommand<AutomationList>(alist, before, alist.get_state()));
|
||||
delete what_we_got;
|
||||
what_we_got = 0;
|
||||
ret = true;
|
||||
|
@ -663,9 +638,9 @@ AutomationTimeAxisView::paste_one (AutomationLine& line, jack_nframes_t pos, flo
|
|||
(*x)->value = foo;
|
||||
}
|
||||
|
||||
_session.add_undo (alist.get_memento());
|
||||
XMLNode &before = alist.get_state();
|
||||
alist.paste (copy, pos, times);
|
||||
_session.add_redo_no_execute (alist.get_memento());
|
||||
_session.add_command (new MementoCommand<AutomationList>(alist, before, alist.get_state()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -84,6 +84,8 @@ class AutomationTimeAxisView : public TimeAxisView {
|
|||
string _state_name;
|
||||
bool in_destructor;
|
||||
|
||||
bool first_call_to_set_height;
|
||||
|
||||
Gtk::Button hide_button;
|
||||
Gtk::Button height_button;
|
||||
Gtk::Button clear_button;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <pbd/convert.h>
|
||||
#include <pbd/error.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include <gtkmm/image.h>
|
||||
#include <gdkmm/color.h>
|
||||
|
@ -2878,8 +2879,8 @@ void
|
|||
Editor::begin_reversible_command (string name)
|
||||
{
|
||||
if (session) {
|
||||
UndoAction ua = get_memento();
|
||||
session->begin_reversible_command (name, &ua);
|
||||
before = &get_state();
|
||||
session->begin_reversible_command (name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2887,8 +2888,7 @@ void
|
|||
Editor::commit_reversible_command ()
|
||||
{
|
||||
if (session) {
|
||||
UndoAction ua = get_memento();
|
||||
session->commit_reversible_command (&ua);
|
||||
session->commit_reversible_command (new MementoCommand<Editor>(*this, *before, get_state()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,8 @@ class Editor : public PublicEditor
|
|||
XMLNode& get_state ();
|
||||
int set_state (const XMLNode& );
|
||||
|
||||
PBD::ID id() { return _id; }
|
||||
|
||||
void set_mouse_mode (Editing::MouseMode, bool force=true);
|
||||
void step_mouse_mode (bool next);
|
||||
Editing::MouseMode current_mouse_mode () { return mouse_mode; }
|
||||
|
@ -346,6 +348,8 @@ class Editor : public PublicEditor
|
|||
ARDOUR::AudioEngine& engine;
|
||||
bool constructed;
|
||||
|
||||
PBD::ID _id;
|
||||
|
||||
PlaylistSelector* _playlist_selector;
|
||||
|
||||
void set_frames_per_unit (double);
|
||||
|
@ -1595,13 +1599,14 @@ class Editor : public PublicEditor
|
|||
|
||||
UndoAction get_memento() const;
|
||||
|
||||
XMLNode *before; /* used in *_reversible_command */
|
||||
void begin_reversible_command (string cmd_name);
|
||||
void commit_reversible_command ();
|
||||
|
||||
/* visual history */
|
||||
|
||||
UndoHistory visual_history;
|
||||
UndoCommand current_visual_command;
|
||||
UndoTransaction current_visual_command;
|
||||
|
||||
void begin_reversible_visual_command (const string & cmd_name);
|
||||
void commit_reversible_visual_command ();
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <ardour/audio_track.h>
|
||||
#include <ardour/audioplaylist.h>
|
||||
#include <ardour/audiofilesource.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "ardour_ui.h"
|
||||
#include "editor.h"
|
||||
|
@ -320,9 +321,9 @@ Editor::finish_bringing_in_audio (AudioRegion& region, uint32_t in_chans, uint32
|
|||
|
||||
AudioRegion* copy = new AudioRegion (region);
|
||||
begin_reversible_command (_("insert sndfile"));
|
||||
session->add_undo (playlist->get_memento());
|
||||
XMLNode &before = playlist->get_state();
|
||||
playlist->add_region (*copy, pos);
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
session->add_command (new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
|
||||
commit_reversible_command ();
|
||||
|
||||
pos += region.length();
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <ardour/audioregion.h>
|
||||
#include <ardour/playlist.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "editor.h"
|
||||
#include "region_view.h"
|
||||
|
@ -102,11 +103,12 @@ Editor::kbd_mute_unmute_region ()
|
|||
{
|
||||
if (entered_regionview) {
|
||||
begin_reversible_command (_("mute region"));
|
||||
session->add_undo (entered_regionview->region().playlist()->get_memento());
|
||||
XMLNode &before = entered_regionview->region().playlist()->get_state();
|
||||
|
||||
entered_regionview->region().set_muted (!entered_regionview->region().muted());
|
||||
|
||||
session->add_redo_no_execute (entered_regionview->region().playlist()->get_memento());
|
||||
XMLNode &after = entered_regionview->region().playlist()->get_state();
|
||||
session->add_command (new MementoCommand<ARDOUR::Playlist>(*(entered_regionview->region().playlist()), before, after));
|
||||
commit_reversible_command();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <gtkmm2ext/gtk_ui.h>
|
||||
|
||||
#include <ardour/location.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "editor.h"
|
||||
#include "marker.h"
|
||||
|
@ -290,9 +291,10 @@ Editor::mouse_add_new_marker (jack_nframes_t where)
|
|||
if (session) {
|
||||
Location *location = new Location (where, where, "mark", Location::IsMark);
|
||||
session->begin_reversible_command (_("add marker"));
|
||||
session->add_undo (session->locations()->get_memento());
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
session->locations()->add (location, true);
|
||||
session->add_redo_no_execute (session->locations()->get_memento());
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
session->commit_reversible_command ();
|
||||
}
|
||||
}
|
||||
|
@ -329,9 +331,10 @@ gint
|
|||
Editor::really_remove_marker (Location* loc)
|
||||
{
|
||||
session->begin_reversible_command (_("remove marker"));
|
||||
session->add_undo (session->locations()->get_memento());
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
session->locations()->remove (loc);
|
||||
session->add_redo_no_execute (session->locations()->get_memento());
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
session->commit_reversible_command ();
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -838,12 +841,13 @@ Editor::marker_menu_rename ()
|
|||
}
|
||||
|
||||
begin_reversible_command ( _("rename marker") );
|
||||
session->add_undo( session->locations()->get_memento() );
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
|
||||
dialog.get_result(txt);
|
||||
loc->set_name (txt);
|
||||
|
||||
session->add_redo_no_execute( session->locations()->get_memento() );
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -868,16 +872,18 @@ Editor::new_transport_marker_menu_set_loop ()
|
|||
|
||||
if ((tll = transport_loop_location()) == 0) {
|
||||
Location* loc = new Location (temp_location->start(), temp_location->end(), _("Loop"), Location::IsAutoLoop);
|
||||
session->add_undo (session->locations()->get_memento());
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
session->locations()->add (loc, true);
|
||||
session->set_auto_loop_location (loc);
|
||||
session->add_redo_no_execute (session->locations()->get_memento());
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
}
|
||||
else {
|
||||
session->add_undo (retype_return<void>(bind (mem_fun (*tll, &Location::set), tll->start(), tll->end())));
|
||||
session->add_redo (retype_return<void>(bind (mem_fun (*tll, &Location::set), temp_location->start(), temp_location->end())));
|
||||
XMLNode &before = tll->get_state();
|
||||
tll->set_hidden (false, this);
|
||||
tll->set (temp_location->start(), temp_location->end());
|
||||
XMLNode &after = tll->get_state();
|
||||
session->add_command (new MementoCommand<Location>(*tll, before, after));
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
@ -894,15 +900,17 @@ Editor::new_transport_marker_menu_set_punch ()
|
|||
|
||||
if ((tpl = transport_punch_location()) == 0) {
|
||||
tpl = new Location (temp_location->start(), temp_location->end(), _("Punch"), Location::IsAutoPunch);
|
||||
session->add_undo (session->locations()->get_memento());
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
session->locations()->add (tpl, true);
|
||||
session->set_auto_punch_location (tpl);
|
||||
session->add_redo_no_execute (session->locations()->get_memento());
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
} else {
|
||||
session->add_undo (retype_return<void>(bind (mem_fun (*tpl, &Location::set), tpl->start(), tpl->end())));
|
||||
session->add_redo (retype_return<void>(bind (mem_fun (*tpl, &Location::set), temp_location->start(), temp_location->end())));
|
||||
XMLNode &before = tpl->get_state();
|
||||
tpl->set_hidden(false, this);
|
||||
tpl->set(temp_location->start(), temp_location->end());
|
||||
XMLNode &after = tpl->get_state();
|
||||
session->add_command (new MementoCommand<Location>(*tpl, before, after));
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <pbd/error.h>
|
||||
#include <gtkmm2ext/utils.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "ardour_ui.h"
|
||||
#include "editor.h"
|
||||
|
@ -1818,9 +1819,14 @@ Editor::fade_in_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* even
|
|||
}
|
||||
|
||||
begin_reversible_command (_("change fade in length"));
|
||||
session->add_undo (arv->region().get_memento());
|
||||
XMLNode &before = arv->audio_region().get_state();
|
||||
|
||||
arv->audio_region().set_fade_in_length (fade_length);
|
||||
session->add_redo_no_execute (arv->region().get_memento());
|
||||
|
||||
XMLNode &after = arv->audio_region().get_state();
|
||||
session->add_command(new MementoCommand<ARDOUR::AudioRegion>(arv->audio_region(),
|
||||
before,
|
||||
after));
|
||||
commit_reversible_command ();
|
||||
fade_in_drag_motion_callback (item, event);
|
||||
}
|
||||
|
@ -1910,9 +1916,12 @@ Editor::fade_out_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* eve
|
|||
}
|
||||
|
||||
begin_reversible_command (_("change fade out length"));
|
||||
session->add_undo (arv->region().get_memento());
|
||||
XMLNode &before = arv->region().get_state();
|
||||
|
||||
arv->audio_region().set_fade_out_length (fade_length);
|
||||
session->add_redo_no_execute (arv->region().get_memento());
|
||||
|
||||
XMLNode &after = arv->region().get_state();
|
||||
session->add_command(new MementoCommand<ARDOUR::Region>(arv->region(), before, after));
|
||||
commit_reversible_command ();
|
||||
|
||||
fade_out_drag_motion_callback (item, event);
|
||||
|
@ -2154,7 +2163,7 @@ Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
|
|||
|
||||
|
||||
begin_reversible_command ( _("move marker") );
|
||||
session->add_undo( session->locations()->get_memento() );
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
|
||||
Location * location = find_location_from_marker (marker, is_start);
|
||||
|
||||
|
@ -2166,7 +2175,8 @@ Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
|
|||
}
|
||||
}
|
||||
|
||||
session->add_redo_no_execute( session->locations()->get_memento() );
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
commit_reversible_command ();
|
||||
|
||||
marker_drag_line->hide();
|
||||
|
@ -2280,9 +2290,10 @@ Editor::meter_marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent*
|
|||
|
||||
if (drag_info.copy == true) {
|
||||
begin_reversible_command (_("copy meter mark"));
|
||||
session->add_undo (map.get_memento());
|
||||
XMLNode &before = map.get_state();
|
||||
map.add_meter (marker->meter(), when);
|
||||
session->add_redo_no_execute (map.get_memento());
|
||||
XMLNode &after = map.get_state();
|
||||
session->add_command(new MementoCommand<TempoMap>(map, before, after));
|
||||
commit_reversible_command ();
|
||||
|
||||
// delete the dummy marker we used for visual representation of copying.
|
||||
|
@ -2290,9 +2301,10 @@ Editor::meter_marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent*
|
|||
delete marker;
|
||||
} else {
|
||||
begin_reversible_command (_("move meter mark"));
|
||||
session->add_undo (map.get_memento());
|
||||
XMLNode &before = map.get_state();
|
||||
map.move_meter (marker->meter(), when);
|
||||
session->add_redo_no_execute (map.get_memento());
|
||||
XMLNode &after = map.get_state();
|
||||
session->add_command(new MementoCommand<TempoMap>(map, before, after));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
}
|
||||
|
@ -2407,12 +2419,13 @@ Editor::tempo_marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent*
|
|||
|
||||
TempoMap& map (session->tempo_map());
|
||||
map.bbt_time (drag_info.last_pointer_frame, when);
|
||||
|
||||
|
||||
if (drag_info.copy == true) {
|
||||
begin_reversible_command (_("copy tempo mark"));
|
||||
session->add_undo (map.get_memento());
|
||||
XMLNode &before = map.get_state();
|
||||
map.add_tempo (marker->tempo(), when);
|
||||
session->add_redo_no_execute (map.get_memento());
|
||||
XMLNode &after = map.get_state();
|
||||
session->add_command (new MementoCommand<TempoMap>(map, before, after));
|
||||
commit_reversible_command ();
|
||||
|
||||
// delete the dummy marker we used for visual representation of copying.
|
||||
|
@ -2420,9 +2433,10 @@ Editor::tempo_marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent*
|
|||
delete marker;
|
||||
} else {
|
||||
begin_reversible_command (_("move tempo mark"));
|
||||
session->add_undo (map.get_memento());
|
||||
XMLNode &before = map.get_state();
|
||||
map.move_tempo (marker->tempo(), when);
|
||||
session->add_redo_no_execute (map.get_memento());
|
||||
XMLNode &after = map.get_state();
|
||||
session->add_command (new MementoCommand<TempoMap>(map, before, after));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
}
|
||||
|
@ -2786,7 +2800,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
|||
|
||||
insert_result = affected_playlists.insert (to_playlist);
|
||||
if (insert_result.second) {
|
||||
session->add_undo (to_playlist->get_memento ());
|
||||
session->add_command (new MementoUndoCommand<Playlist>(*to_playlist, to_playlist->get_state()));
|
||||
}
|
||||
|
||||
latest_regionview = 0;
|
||||
|
@ -3224,7 +3238,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
|||
insert_result = motion_frozen_playlists.insert (pl);
|
||||
if (insert_result.second) {
|
||||
pl->freeze();
|
||||
session->add_undo(pl->get_memento());
|
||||
session->add_command(new MementoUndoCommand<Playlist>(*pl, pl->get_state()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3352,7 +3366,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
|
|||
insert_result = motion_frozen_playlists.insert(to_playlist);
|
||||
if (insert_result.second) {
|
||||
to_playlist->freeze();
|
||||
session->add_undo(to_playlist->get_memento());
|
||||
session->add_command(new MementoUndoCommand<Playlist>(*to_playlist, to_playlist->get_state()));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3434,7 +3448,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
|
|||
out:
|
||||
for (set<Playlist*>::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
|
||||
(*p)->thaw ();
|
||||
session->add_redo_no_execute ((*p)->get_memento());
|
||||
session->add_command (new MementoRedoCommand<Playlist>(*(*p), (*p)->get_state()));
|
||||
}
|
||||
|
||||
motion_frozen_playlists.clear ();
|
||||
|
@ -3629,9 +3643,10 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event)
|
|||
|
||||
Playlist* playlist = clicked_trackview->playlist();
|
||||
|
||||
session->add_undo (playlist->get_memento ());
|
||||
before = &(playlist->get_state());
|
||||
clicked_trackview->playlist()->add_region (*region, selection->time[clicked_selection].start);
|
||||
session->add_redo_no_execute (playlist->get_memento ());
|
||||
XMLNode &after = playlist->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*playlist, *before, after));
|
||||
|
||||
commit_reversible_command ();
|
||||
|
||||
|
@ -3998,7 +4013,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
|||
Playlist * pl = (*i)->region().playlist();
|
||||
insert_result = motion_frozen_playlists.insert (pl);
|
||||
if (insert_result.second) {
|
||||
session->add_undo (pl->get_memento());
|
||||
session->add_command(new MementoUndoCommand<Playlist>(*pl, pl->get_state()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4188,8 +4203,8 @@ Editor::trim_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
|||
|
||||
for (set<Playlist*>::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
|
||||
//(*p)->thaw ();
|
||||
session->add_redo_no_execute ((*p)->get_memento());
|
||||
}
|
||||
session->add_command (new MementoRedoCommand<Playlist>(*(*p), (*p)->get_state()));
|
||||
}
|
||||
|
||||
motion_frozen_playlists.clear ();
|
||||
|
||||
|
@ -4222,18 +4237,22 @@ Editor::point_trim (GdkEvent* event)
|
|||
i != selection->regions.by_layer().end(); ++i)
|
||||
{
|
||||
if (!(*i)->region().locked()) {
|
||||
session->add_undo ((*i)->region().playlist()->get_memento());
|
||||
Playlist *pl = (*i)->region().playlist();
|
||||
XMLNode &before = pl->get_state();
|
||||
(*i)->region().trim_front (new_bound, this);
|
||||
session->add_redo_no_execute ((*i)->region().playlist()->get_memento());
|
||||
XMLNode &after = pl->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*pl, before, after));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (!rv->region().locked()) {
|
||||
session->add_undo (rv->region().playlist()->get_memento());
|
||||
Playlist *pl = rv->region().playlist();
|
||||
XMLNode &before = pl->get_state();
|
||||
rv->region().trim_front (new_bound, this);
|
||||
session->add_redo_no_execute (rv->region().playlist()->get_memento());
|
||||
XMLNode &after = pl->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*pl, before, after));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4249,18 +4268,22 @@ Editor::point_trim (GdkEvent* event)
|
|||
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i)
|
||||
{
|
||||
if (!(*i)->region().locked()) {
|
||||
session->add_undo ((*i)->region().playlist()->get_memento());
|
||||
Playlist *pl = (*i)->region().playlist();
|
||||
XMLNode &before = pl->get_state();
|
||||
(*i)->region().trim_end (new_bound, this);
|
||||
session->add_redo_no_execute ((*i)->region().playlist()->get_memento());
|
||||
XMLNode &after = pl->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*pl, before, after));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (!rv->region().locked()) {
|
||||
session->add_undo (rv->region().playlist()->get_memento());
|
||||
Playlist *pl = rv->region().playlist();
|
||||
XMLNode &before = pl->get_state();
|
||||
rv->region().trim_end (new_bound, this);
|
||||
session->add_redo_no_execute (rv->region().playlist()->get_memento());
|
||||
XMLNode &after = pl->get_state();
|
||||
session->add_command (new MementoCommand<Playlist>(*pl, before, after));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4282,7 +4305,8 @@ Editor::thaw_region_after_trim (RegionView& rv)
|
|||
}
|
||||
|
||||
region.thaw (_("trimmed region"));
|
||||
session->add_redo_no_execute (region.playlist()->get_memento());
|
||||
XMLNode &after = region.playlist()->get_state();
|
||||
session->add_command (new MementoRedoCommand<Playlist>(*(region.playlist()), after));
|
||||
|
||||
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(&rv);
|
||||
if (arv)
|
||||
|
@ -4421,16 +4445,19 @@ Editor::end_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event)
|
|||
|
||||
switch (range_marker_op) {
|
||||
case CreateRangeMarker:
|
||||
{
|
||||
begin_reversible_command (_("new range marker"));
|
||||
session->add_undo (session->locations()->get_memento());
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
newloc = new Location(temp_location->start(), temp_location->end(), "unnamed", Location::IsRangeMarker);
|
||||
session->locations()->add (newloc, true);
|
||||
session->add_redo_no_execute (session->locations()->get_memento());
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
commit_reversible_command ();
|
||||
|
||||
range_bar_drag_rect->hide();
|
||||
range_marker_drag_rect->hide();
|
||||
break;
|
||||
}
|
||||
|
||||
case CreateTransportMarker:
|
||||
// popup menu to pick loop or punch
|
||||
|
@ -4804,9 +4831,10 @@ Editor::mouse_brush_insert_region (RegionView* rv, jack_nframes_t pos)
|
|||
Playlist* playlist = atv->playlist();
|
||||
double speed = atv->get_diskstream()->speed();
|
||||
|
||||
session->add_undo (playlist->get_memento());
|
||||
XMLNode &before = playlist->get_state();
|
||||
playlist->add_region (*(new AudioRegion (arv->audio_region())), (jack_nframes_t) (pos * speed));
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
XMLNode &after = playlist->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*playlist, before, after));
|
||||
|
||||
// playlist is frozen, so we have to update manually
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <pbd/error.h>
|
||||
#include <pbd/basename.h>
|
||||
#include <pbd/pthread_utils.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include <gtkmm2ext/utils.h>
|
||||
#include <gtkmm2ext/choice.h>
|
||||
|
@ -209,9 +210,10 @@ Editor::split_regions_at (jack_nframes_t where, RegionSelection& regions)
|
|||
_new_regionviews_show_envelope = arv->envelope_visible();
|
||||
|
||||
if (pl) {
|
||||
session->add_undo (pl->get_memento());
|
||||
XMLNode &before = pl->get_state();
|
||||
pl->split_region ((*a)->region(), where);
|
||||
session->add_redo_no_execute (pl->get_memento());
|
||||
XMLNode &after = pl->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*pl, before, after));
|
||||
}
|
||||
|
||||
a = tmp;
|
||||
|
@ -231,9 +233,10 @@ Editor::remove_clicked_region ()
|
|||
Playlist* playlist = clicked_audio_trackview->playlist();
|
||||
|
||||
begin_reversible_command (_("remove region"));
|
||||
session->add_undo (playlist->get_memento());
|
||||
XMLNode &before = playlist->get_state();
|
||||
playlist->remove_region (&clicked_regionview->region());
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
XMLNode &after = playlist->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*playlist, before, after));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -406,9 +409,10 @@ Editor::nudge_forward (bool next)
|
|||
distance = next_distance;
|
||||
}
|
||||
|
||||
session->add_undo (r.playlist()->get_memento());
|
||||
XMLNode &before = r.playlist()->get_state();
|
||||
r.set_position (r.position() + distance, this);
|
||||
session->add_redo_no_execute (r.playlist()->get_memento());
|
||||
XMLNode &after = r.playlist()->get_state();
|
||||
session->add_command (new MementoCommand<Playlist>(*(r.playlist()), before, after));
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
@ -440,14 +444,15 @@ Editor::nudge_backward (bool next)
|
|||
distance = next_distance;
|
||||
}
|
||||
|
||||
session->add_undo (r.playlist()->get_memento());
|
||||
XMLNode &before = r.playlist()->get_state();
|
||||
|
||||
if (r.position() > distance) {
|
||||
r.set_position (r.position() - distance, this);
|
||||
} else {
|
||||
r.set_position (0, this);
|
||||
}
|
||||
session->add_redo_no_execute (r.playlist()->get_memento());
|
||||
XMLNode &after = r.playlist()->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*(r.playlist()), before, after));
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
@ -480,9 +485,10 @@ Editor::nudge_forward_capture_offset ()
|
|||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
Region& r ((*i)->region());
|
||||
|
||||
session->add_undo (r.playlist()->get_memento());
|
||||
XMLNode &before = r.playlist()->get_state();
|
||||
r.set_position (r.position() + distance, this);
|
||||
session->add_redo_no_execute (r.playlist()->get_memento());
|
||||
XMLNode &after = r.playlist()->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*(r.playlist()), before, after));
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
@ -506,14 +512,15 @@ Editor::nudge_backward_capture_offset ()
|
|||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
Region& r ((*i)->region());
|
||||
|
||||
session->add_undo (r.playlist()->get_memento());
|
||||
XMLNode &before = r.playlist()->get_state();
|
||||
|
||||
if (r.position() > distance) {
|
||||
r.set_position (r.position() - distance, this);
|
||||
} else {
|
||||
r.set_position (0, this);
|
||||
}
|
||||
session->add_redo_no_execute (r.playlist()->get_memento());
|
||||
XMLNode &after = r.playlist()->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*(r.playlist()), before, after));
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
@ -1290,9 +1297,10 @@ Editor::add_location_from_selection ()
|
|||
Location *location = new Location (start, end, "selection");
|
||||
|
||||
session->begin_reversible_command (_("add marker"));
|
||||
session->add_undo (session->locations()->get_memento());
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
session->locations()->add (location, true);
|
||||
session->add_redo_no_execute (session->locations()->get_memento());
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
session->commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -1303,9 +1311,10 @@ Editor::add_location_from_playhead_cursor ()
|
|||
|
||||
Location *location = new Location (where, where, "mark", Location::IsMark);
|
||||
session->begin_reversible_command (_("add marker"));
|
||||
session->add_undo (session->locations()->get_memento());
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
session->locations()->add (location, true);
|
||||
session->add_redo_no_execute (session->locations()->get_memento());
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
session->commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -1321,9 +1330,10 @@ Editor::add_location_from_audio_region ()
|
|||
|
||||
Location *location = new Location (region.position(), region.last_frame(), region.name());
|
||||
session->begin_reversible_command (_("add marker"));
|
||||
session->add_undo (session->locations()->get_memento());
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
session->locations()->add (location, true);
|
||||
session->add_redo_no_execute (session->locations()->get_memento());
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
session->commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -1739,9 +1749,10 @@ Editor::clear_markers ()
|
|||
{
|
||||
if (session) {
|
||||
session->begin_reversible_command (_("clear markers"));
|
||||
session->add_undo (session->locations()->get_memento());
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
session->locations()->clear_markers ();
|
||||
session->add_redo_no_execute (session->locations()->get_memento());
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
session->commit_reversible_command ();
|
||||
}
|
||||
}
|
||||
|
@ -1751,7 +1762,7 @@ Editor::clear_ranges ()
|
|||
{
|
||||
if (session) {
|
||||
session->begin_reversible_command (_("clear ranges"));
|
||||
session->add_undo (session->locations()->get_memento());
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
|
||||
Location * looploc = session->locations()->auto_loop_location();
|
||||
Location * punchloc = session->locations()->auto_punch_location();
|
||||
|
@ -1761,7 +1772,8 @@ Editor::clear_ranges ()
|
|||
if (looploc) session->locations()->add (looploc);
|
||||
if (punchloc) session->locations()->add (punchloc);
|
||||
|
||||
session->add_redo_no_execute (session->locations()->get_memento());
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
session->commit_reversible_command ();
|
||||
}
|
||||
}
|
||||
|
@ -1770,9 +1782,10 @@ void
|
|||
Editor::clear_locations ()
|
||||
{
|
||||
session->begin_reversible_command (_("clear locations"));
|
||||
session->add_undo (session->locations()->get_memento());
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
session->locations()->clear ();
|
||||
session->add_redo_no_execute (session->locations()->get_memento());
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
session->commit_reversible_command ();
|
||||
session->locations()->clear ();
|
||||
}
|
||||
|
@ -1820,9 +1833,9 @@ Editor::insert_region_list_drag (AudioRegion& region, int x, int y)
|
|||
snap_to (where);
|
||||
|
||||
begin_reversible_command (_("insert dragged region"));
|
||||
session->add_undo (playlist->get_memento());
|
||||
XMLNode &before = playlist->get_state();
|
||||
playlist->add_region (*(new AudioRegion (region)), where, 1.0);
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
session->add_command(new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -1856,9 +1869,9 @@ Editor::insert_region_list_selection (float times)
|
|||
Region* region = (*i)[region_list_columns.region];
|
||||
|
||||
begin_reversible_command (_("insert region"));
|
||||
session->add_undo (playlist->get_memento());
|
||||
XMLNode &before = playlist->get_state();
|
||||
playlist->add_region (*(createRegion (*region)), edit_cursor->current_frame, times);
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
session->add_command(new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -2283,7 +2296,9 @@ Editor::separate_region_from_selection ()
|
|||
begin_reversible_command (_("separate"));
|
||||
doing_undo = true;
|
||||
}
|
||||
if (doing_undo) session->add_undo ((playlist)->get_memento());
|
||||
XMLNode *before;
|
||||
if (doing_undo)
|
||||
before = &(playlist->get_state());
|
||||
|
||||
/* XXX need to consider musical time selections here at some point */
|
||||
|
||||
|
@ -2293,7 +2308,8 @@ Editor::separate_region_from_selection ()
|
|||
playlist->partition ((jack_nframes_t)((*t).start * speed), (jack_nframes_t)((*t).end * speed), true);
|
||||
}
|
||||
|
||||
if (doing_undo) session->add_redo_no_execute (playlist->get_memento());
|
||||
if (doing_undo)
|
||||
session->add_command(new MementoCommand<Playlist>(*playlist, *before, playlist->get_state()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2328,11 +2344,14 @@ Editor::separate_regions_using_location (Location& loc)
|
|||
if (atv->is_audio_track()) {
|
||||
|
||||
if ((playlist = atv->playlist()) != 0) {
|
||||
XMLNode *before;
|
||||
if (!doing_undo) {
|
||||
begin_reversible_command (_("separate"));
|
||||
doing_undo = true;
|
||||
}
|
||||
if (doing_undo) session->add_undo ((playlist)->get_memento());
|
||||
if (doing_undo)
|
||||
before = &(playlist->get_state());
|
||||
|
||||
|
||||
/* XXX need to consider musical time selections here at some point */
|
||||
|
||||
|
@ -2340,7 +2359,8 @@ Editor::separate_regions_using_location (Location& loc)
|
|||
|
||||
|
||||
playlist->partition ((jack_nframes_t)(loc.start() * speed), (jack_nframes_t)(loc.end() * speed), true);
|
||||
if (doing_undo) session->add_redo_no_execute (playlist->get_memento());
|
||||
if (doing_undo)
|
||||
session->add_command(new MementoCommand<Playlist>(*playlist, *before, playlist->get_state()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2411,9 +2431,10 @@ Editor::crop_region_to_selection ()
|
|||
end = min (selection->time.end_frame(), start + region->length() - 1);
|
||||
cnt = end - start + 1;
|
||||
|
||||
session->add_undo ((*i)->get_memento());
|
||||
XMLNode &before = (*i)->get_state();
|
||||
region->trim_to (start, cnt, this);
|
||||
session->add_redo_no_execute ((*i)->get_memento());
|
||||
XMLNode &after = (*i)->get_state();
|
||||
session->add_command (new MementoCommand<Playlist>(*(*i), before, after));
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
@ -2454,9 +2475,9 @@ Editor::region_fill_track ()
|
|||
return;
|
||||
}
|
||||
|
||||
session->add_undo (pl->get_memento());
|
||||
XMLNode &before = pl->get_state();
|
||||
pl->add_region (*(new AudioRegion (*ar)), ar->last_frame(), times);
|
||||
session->add_redo_no_execute (pl->get_memento());
|
||||
session->add_command (new MementoCommand<Playlist>(*pl, before, pl->get_state()));
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
@ -2504,9 +2525,9 @@ Editor::region_fill_selection ()
|
|||
continue;
|
||||
}
|
||||
|
||||
session->add_undo (playlist->get_memento());
|
||||
XMLNode &before = playlist->get_state();
|
||||
playlist->add_region (*(createRegion (*region)), start, times);
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
session->add_command (new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
@ -2521,9 +2542,10 @@ Editor::set_a_regions_sync_position (Region& region, jack_nframes_t position)
|
|||
return;
|
||||
}
|
||||
begin_reversible_command (_("set region sync position"));
|
||||
session->add_undo (region.playlist()->get_memento());
|
||||
XMLNode &before = region.playlist()->get_state();
|
||||
region.set_sync_position (position);
|
||||
session->add_redo_no_execute (region.playlist()->get_memento());
|
||||
XMLNode &after = region.playlist()->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -2541,9 +2563,10 @@ Editor::set_region_sync_from_edit_cursor ()
|
|||
|
||||
Region& region (clicked_regionview->region());
|
||||
begin_reversible_command (_("set sync from edit cursor"));
|
||||
session->add_undo (region.playlist()->get_memento());
|
||||
XMLNode &before = region.playlist()->get_state();
|
||||
region.set_sync_position (edit_cursor->current_frame);
|
||||
session->add_redo_no_execute (region.playlist()->get_memento());
|
||||
XMLNode &after = region.playlist()->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -2553,9 +2576,10 @@ Editor::remove_region_sync ()
|
|||
if (clicked_regionview) {
|
||||
Region& region (clicked_regionview->region());
|
||||
begin_reversible_command (_("remove sync"));
|
||||
session->add_undo (region.playlist()->get_memento());
|
||||
XMLNode &before = region.playlist()->get_state();
|
||||
region.clear_sync_position ();
|
||||
session->add_redo_no_execute (region.playlist()->get_memento());
|
||||
XMLNode &after = region.playlist()->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
}
|
||||
|
@ -2568,9 +2592,10 @@ Editor::naturalize ()
|
|||
}
|
||||
begin_reversible_command (_("naturalize"));
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
session->add_undo ((*i)->region().get_memento());
|
||||
XMLNode &before = (*i)->region().get_state();
|
||||
(*i)->region().move_to_natural_position (this);
|
||||
session->add_redo_no_execute ((*i)->region().get_memento());
|
||||
XMLNode &after = (*i)->region().get_state();
|
||||
session->add_command (new MementoCommand<Region>((*i)->region(), before, after));
|
||||
}
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
@ -2636,7 +2661,7 @@ Editor::align_selection_relative (RegionPoint point, jack_nframes_t position)
|
|||
|
||||
Region& region ((*i)->region());
|
||||
|
||||
session->add_undo (region.playlist()->get_memento());
|
||||
XMLNode &before = region.playlist()->get_state();
|
||||
|
||||
if (dir > 0) {
|
||||
region.set_position (region.position() + distance, this);
|
||||
|
@ -2644,7 +2669,8 @@ Editor::align_selection_relative (RegionPoint point, jack_nframes_t position)
|
|||
region.set_position (region.position() - distance, this);
|
||||
}
|
||||
|
||||
session->add_redo_no_execute (region.playlist()->get_memento());
|
||||
XMLNode &after = region.playlist()->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
|
||||
|
||||
}
|
||||
|
||||
|
@ -2678,7 +2704,7 @@ Editor::align_region (Region& region, RegionPoint point, jack_nframes_t position
|
|||
void
|
||||
Editor::align_region_internal (Region& region, RegionPoint point, jack_nframes_t position)
|
||||
{
|
||||
session->add_undo (region.playlist()->get_memento());
|
||||
XMLNode &before = region.playlist()->get_state();
|
||||
|
||||
switch (point) {
|
||||
case SyncPoint:
|
||||
|
@ -2696,7 +2722,8 @@ Editor::align_region_internal (Region& region, RegionPoint point, jack_nframes_t
|
|||
break;
|
||||
}
|
||||
|
||||
session->add_redo_no_execute (region.playlist()->get_memento());
|
||||
XMLNode &after = region.playlist()->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2718,9 +2745,10 @@ Editor::trim_region_to_edit_cursor ()
|
|||
}
|
||||
|
||||
begin_reversible_command (_("trim to edit"));
|
||||
session->add_undo (region.playlist()->get_memento());
|
||||
XMLNode &before = region.playlist()->get_state();
|
||||
region.trim_end( session_frame_to_track_frame(edit_cursor->current_frame, speed), this);
|
||||
session->add_redo_no_execute (region.playlist()->get_memento());
|
||||
XMLNode &after = region.playlist()->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -2743,9 +2771,10 @@ Editor::trim_region_from_edit_cursor ()
|
|||
}
|
||||
|
||||
begin_reversible_command (_("trim to edit"));
|
||||
session->add_undo (region.playlist()->get_memento());
|
||||
XMLNode &before = region.playlist()->get_state();
|
||||
region.trim_front ( session_frame_to_track_frame(edit_cursor->current_frame, speed), this);
|
||||
session->add_redo_no_execute (region.playlist()->get_memento());
|
||||
XMLNode &after = region.playlist()->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -2857,9 +2886,10 @@ Editor::bounce_range_selection ()
|
|||
itt.cancel = false;
|
||||
itt.progress = false;
|
||||
|
||||
session->add_undo (playlist->get_memento());
|
||||
XMLNode &before = playlist->get_state();
|
||||
atv->audio_track()->bounce_range (start, cnt, itt);
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
XMLNode &after = playlist->get_state();
|
||||
session->add_command (new MementoCommand<Playlist> (*playlist, before, after));
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
@ -2977,7 +3007,7 @@ Editor::cut_copy_regions (CutCopyOp op)
|
|||
insert_result = freezelist.insert (pl);
|
||||
if (insert_result.second) {
|
||||
pl->freeze ();
|
||||
session->add_undo (pl->get_memento());
|
||||
session->add_command (new MementoUndoCommand<Playlist>(*pl, pl->get_state()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3041,7 +3071,7 @@ Editor::cut_copy_regions (CutCopyOp op)
|
|||
|
||||
for (set<Playlist*>::iterator pl = freezelist.begin(); pl != freezelist.end(); ++pl) {
|
||||
(*pl)->thaw ();
|
||||
session->add_redo_no_execute ((*pl)->get_memento());
|
||||
session->add_command (new MementoRedoCommand<Playlist>(*(*pl), (*pl)->get_state()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3154,9 +3184,9 @@ Editor::paste_named_selection (float times)
|
|||
tmp = chunk;
|
||||
++tmp;
|
||||
|
||||
session->add_undo (apl->get_memento());
|
||||
XMLNode &before = apl->get_state();
|
||||
apl->paste (**chunk, edit_cursor->current_frame, times);
|
||||
session->add_redo_no_execute (apl->get_memento());
|
||||
session->add_command(new MementoCommand<AudioPlaylist>(*apl, before, apl->get_state()));
|
||||
|
||||
if (tmp != ns->playlists.end()) {
|
||||
chunk = tmp;
|
||||
|
@ -3185,9 +3215,9 @@ Editor::duplicate_some_regions (RegionSelection& regions, float times)
|
|||
sigc::connection c = atv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
|
||||
|
||||
playlist = (*i)->region().playlist();
|
||||
session->add_undo (playlist->get_memento());
|
||||
XMLNode &before = playlist->get_state();
|
||||
playlist->duplicate (r, r.last_frame(), times);
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
session->add_command(new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
|
||||
|
||||
c.disconnect ();
|
||||
|
||||
|
@ -3225,9 +3255,10 @@ Editor::duplicate_selection (float times)
|
|||
if ((playlist = (*i)->playlist()) == 0) {
|
||||
continue;
|
||||
}
|
||||
session->add_undo (playlist->get_memento());
|
||||
XMLNode &before = playlist->get_state();
|
||||
playlist->duplicate (**ri, selection->time[clicked_selection].end, times);
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
XMLNode &after = playlist->get_state();
|
||||
session->add_command (new MementoCommand<Playlist>(*playlist, before, after));
|
||||
|
||||
++ri;
|
||||
if (ri == new_regions.end()) {
|
||||
|
@ -3275,9 +3306,10 @@ void
|
|||
Editor::clear_playlist (Playlist& playlist)
|
||||
{
|
||||
begin_reversible_command (_("clear playlist"));
|
||||
session->add_undo (playlist.get_memento());
|
||||
XMLNode &before = playlist.get_state();
|
||||
playlist.clear ();
|
||||
session->add_redo_no_execute (playlist.get_memento());
|
||||
XMLNode &after = playlist.get_state();
|
||||
session->add_command (new MementoCommand<Playlist>(playlist, before, after));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -3311,9 +3343,10 @@ Editor::nudge_track (bool use_edit_cursor, bool forwards)
|
|||
continue;
|
||||
}
|
||||
|
||||
session->add_undo (playlist->get_memento());
|
||||
XMLNode &before = playlist->get_state();
|
||||
playlist->nudge_after (start, distance, forwards);
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
XMLNode &after = playlist->get_state();
|
||||
session->add_command (new MementoCommand<Playlist>(*playlist, before, after));
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
@ -3367,9 +3400,9 @@ Editor::normalize_region ()
|
|||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
|
||||
if (!arv)
|
||||
continue;
|
||||
session->add_undo (arv->region().get_memento());
|
||||
XMLNode &before = arv->region().get_state();
|
||||
arv->audio_region().normalize_to (0.0f);
|
||||
session->add_redo_no_execute (arv->region().get_memento());
|
||||
session->add_command (new MementoCommand<Region>(arv->region(), before, arv->region().get_state()));
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
@ -3394,9 +3427,9 @@ Editor::denormalize_region ()
|
|||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
|
||||
if (!arv)
|
||||
continue;
|
||||
session->add_undo (arv->region().get_memento());
|
||||
XMLNode &before = arv->region().get_state();
|
||||
arv->audio_region().set_scale_amplitude (1.0f);
|
||||
session->add_redo_no_execute (arv->region().get_memento());
|
||||
session->add_command (new MementoCommand<Region>(arv->region(), before, arv->region().get_state()));
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
@ -3440,9 +3473,10 @@ Editor::apply_filter (AudioFilter& filter, string command)
|
|||
|
||||
if (arv->audio_region().apply (filter) == 0) {
|
||||
|
||||
session->add_undo (playlist->get_memento());
|
||||
XMLNode &before = playlist->get_state();
|
||||
playlist->replace_region (arv->region(), *(filter.results.front()), arv->region().position());
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
XMLNode &after = playlist->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*playlist, before, after));
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <libgnomecanvasmm.h>
|
||||
|
||||
#include <pbd/error.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include <gtkmm2ext/utils.h>
|
||||
#include <gtkmm2ext/gtk_ui.h>
|
||||
|
@ -273,9 +274,10 @@ Editor::mouse_add_new_tempo_event (jack_nframes_t frame)
|
|||
tempo_dialog.get_bbt_time (requested);
|
||||
|
||||
begin_reversible_command (_("add tempo mark"));
|
||||
session->add_undo (map.get_memento());
|
||||
XMLNode &before = map.get_state();
|
||||
map.add_tempo (Tempo (bpm), requested);
|
||||
session->add_redo_no_execute (map.get_memento());
|
||||
XMLNode &after = map.get_state();
|
||||
session->add_command(new MementoCommand<TempoMap>(map, before, after));
|
||||
commit_reversible_command ();
|
||||
|
||||
map.dump (cerr);
|
||||
|
@ -313,9 +315,9 @@ Editor::mouse_add_new_meter_event (jack_nframes_t frame)
|
|||
meter_dialog.get_bbt_time (requested);
|
||||
|
||||
begin_reversible_command (_("add meter mark"));
|
||||
session->add_undo (map.get_memento());
|
||||
XMLNode &before = map.get_state();
|
||||
map.add_meter (Meter (bpb, note_type), requested);
|
||||
session->add_redo_no_execute (map.get_memento());
|
||||
session->add_command(new MementoCommand<TempoMap>(map, before, map.get_state()));
|
||||
commit_reversible_command ();
|
||||
|
||||
map.dump (cerr);
|
||||
|
@ -364,9 +366,10 @@ Editor::edit_meter_section (MeterSection* section)
|
|||
double note_type = meter_dialog.get_note_type ();
|
||||
|
||||
begin_reversible_command (_("replace tempo mark"));
|
||||
session->add_undo (session->tempo_map().get_memento());
|
||||
XMLNode &before = session->tempo_map().get_state();
|
||||
session->tempo_map().replace_meter (*section, Meter (bpb, note_type));
|
||||
session->add_redo_no_execute (session->tempo_map().get_memento());
|
||||
XMLNode &after = session->tempo_map().get_state();
|
||||
session->add_command(new MementoCommand<TempoMap>(session->tempo_map(), before, after));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -392,10 +395,11 @@ Editor::edit_tempo_section (TempoSection* section)
|
|||
bpm = max (0.01, bpm);
|
||||
|
||||
begin_reversible_command (_("replace tempo mark"));
|
||||
session->add_undo (session->tempo_map().get_memento());
|
||||
XMLNode &before = session->tempo_map().get_state();
|
||||
session->tempo_map().replace_tempo (*section, Tempo (bpm));
|
||||
session->tempo_map().move_tempo (*section, when);
|
||||
session->add_redo_no_execute (session->tempo_map().get_memento());
|
||||
XMLNode &after = session->tempo_map().get_state();
|
||||
session->add_command (new MementoCommand<TempoMap>(session->tempo_map(), before, after));
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -441,9 +445,10 @@ gint
|
|||
Editor::real_remove_tempo_marker (TempoSection *section)
|
||||
{
|
||||
begin_reversible_command (_("remove tempo mark"));
|
||||
session->add_undo (session->tempo_map().get_memento());
|
||||
XMLNode &before = session->tempo_map().get_state();
|
||||
session->tempo_map().remove_tempo (*section);
|
||||
session->add_redo_no_execute (session->tempo_map().get_memento());
|
||||
XMLNode &after = session->tempo_map().get_state();
|
||||
session->add_command(new MementoCommand<TempoMap>(session->tempo_map(), before, after));
|
||||
commit_reversible_command ();
|
||||
|
||||
return FALSE;
|
||||
|
@ -474,9 +479,10 @@ gint
|
|||
Editor::real_remove_meter_marker (MeterSection *section)
|
||||
{
|
||||
begin_reversible_command (_("remove tempo mark"));
|
||||
session->add_undo (session->tempo_map().get_memento());
|
||||
XMLNode &before = session->tempo_map().get_state();
|
||||
session->tempo_map().remove_meter (*section);
|
||||
session->add_redo_no_execute (session->tempo_map().get_memento());
|
||||
XMLNode &after = session->tempo_map().get_state();
|
||||
session->add_command(new MementoCommand<TempoMap>(session->tempo_map(), before, after));
|
||||
commit_reversible_command ();
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <pbd/error.h>
|
||||
#include <pbd/pthread_utils.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "editor.h"
|
||||
#include "audio_time_axis.h"
|
||||
|
@ -206,9 +207,10 @@ Editor::do_timestretch (TimeStretchDialog& dialog)
|
|||
return;
|
||||
}
|
||||
|
||||
session->add_undo (playlist->get_memento());
|
||||
XMLNode &before = playlist->get_state();
|
||||
playlist->replace_region (region, *new_region, region.position());
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
XMLNode &after = playlist->get_state();
|
||||
session->add_command (new MementoCommand<Playlist>(*playlist, before, after));
|
||||
|
||||
i = tmp;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <ardour/curve.h>
|
||||
#include <ardour/route.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "gain_automation_time_axis.h"
|
||||
#include "automation_line.h"
|
||||
|
@ -63,9 +64,10 @@ GainAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkE
|
|||
|
||||
_session.begin_reversible_command (_("add gain automation event"));
|
||||
|
||||
_session.add_undo (curve.get_memento());
|
||||
XMLNode &before = curve.get_state();
|
||||
curve.add (when, y);
|
||||
_session.add_redo_no_execute (curve.get_memento());
|
||||
XMLNode &after = curve.get_state();
|
||||
_session.add_command(new MementoCommand<ARDOUR::Curve>(curve, before, after));
|
||||
_session.commit_reversible_command ();
|
||||
_session.set_dirty ();
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <ardour/utils.h>
|
||||
#include <ardour/configuration.h>
|
||||
#include <ardour/session.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "ardour_ui.h"
|
||||
#include "prompter.h"
|
||||
|
@ -654,9 +655,10 @@ gint LocationUI::do_location_remove (ARDOUR::Location *loc)
|
|||
}
|
||||
|
||||
session->begin_reversible_command (_("remove marker"));
|
||||
session->add_undo (session->locations()->get_memento());
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
session->locations()->remove (loc);
|
||||
session->add_redo_no_execute (session->locations()->get_memento());
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
session->commit_reversible_command ();
|
||||
|
||||
return FALSE;
|
||||
|
@ -772,9 +774,10 @@ LocationUI::add_new_location()
|
|||
jack_nframes_t where = session->audible_frame();
|
||||
Location *location = new Location (where, where, "mark", Location::IsMark);
|
||||
session->begin_reversible_command (_("add marker"));
|
||||
session->add_undo (session->locations()->get_memento());
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
session->locations()->add (location, true);
|
||||
session->add_redo_no_execute (session->locations()->get_memento());
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
session->commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -788,9 +791,10 @@ LocationUI::add_new_range()
|
|||
Location *location = new Location (where, where, "unnamed",
|
||||
Location::IsRangeMarker);
|
||||
session->begin_reversible_command (_("add range marker"));
|
||||
session->add_undo (session->locations()->get_memento());
|
||||
XMLNode &before = session->locations()->get_state();
|
||||
session->locations()->add (location, true);
|
||||
session->add_redo_no_execute (session->locations()->get_memento());
|
||||
XMLNode &after = session->locations()->get_state();
|
||||
session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
|
||||
session->commit_reversible_command ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -293,60 +293,43 @@ Please consider the possibilities, and perhaps (re)start JACK."));
|
|||
static bool
|
||||
maybe_load_session ()
|
||||
{
|
||||
/* If no session name is given: we're not loading a session yet, nor creating a new one */
|
||||
if (!session_name.length()) {
|
||||
ui->hide_splash ();
|
||||
if (!Config->get_no_new_session_dialog()) {
|
||||
ui->new_session (true);
|
||||
}
|
||||
|
||||
/* load session, if given */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Load session or start the new session dialog */
|
||||
string name, path;
|
||||
|
||||
if (session_name.length()){
|
||||
bool isnew;
|
||||
bool isnew;
|
||||
|
||||
if (Session::find_session (session_name, path, name, isnew)) {
|
||||
error << string_compose(_("could not load command line session \"%1\""), session_name) << endmsg;
|
||||
} else {
|
||||
if (Session::find_session (session_name, path, name, isnew)) {
|
||||
error << string_compose(_("could not load command line session \"%1\""), session_name) << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (new_session) {
|
||||
|
||||
/* command line required that the session be new */
|
||||
|
||||
if (isnew) {
|
||||
|
||||
/* popup the new session dialog
|
||||
once everything else is OK.
|
||||
*/
|
||||
|
||||
Glib::signal_idle().connect (bind (mem_fun (*ui, &ARDOUR_UI::cmdline_new_session), path));
|
||||
ui->set_will_create_new_session_automatically (true);
|
||||
|
||||
} else {
|
||||
|
||||
/* it wasn't new, but we require a new session */
|
||||
|
||||
error << string_compose (_("\n\nA session named \"%1\" already exists.\n\
|
||||
To avoid this message, start ardour as \"ardour %1"), path)
|
||||
<< endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* command line didn't require a new session */
|
||||
|
||||
if (isnew) {
|
||||
error << string_compose (_("\n\nNo session named \"%1\" exists.\n\
|
||||
To create it from the command line, start ardour as \"ardour --new %1"), path)
|
||||
<< endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
ui->load_session (path, name);
|
||||
}
|
||||
if (!new_session) {
|
||||
|
||||
/* Loading a session, but the session doesn't exist */
|
||||
if (isnew) {
|
||||
error << string_compose (_("\n\nNo session named \"%1\" exists.\n\
|
||||
To create it from the command line, start ardour as \"ardour --new %1"), path) << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (no_splash) {
|
||||
ui->show();
|
||||
}
|
||||
ui->load_session (path, name);
|
||||
|
||||
} else {
|
||||
/* TODO: This bit of code doesn't work properly yet
|
||||
Glib::signal_idle().connect (bind (mem_fun (*ui, &ARDOUR_UI::cmdline_new_session), path));
|
||||
ui->set_will_create_new_session_automatically (true); */
|
||||
|
||||
/* Show the NSD */
|
||||
ui->hide_splash ();
|
||||
if (!Config->get_no_new_session_dialog()) {
|
||||
ui->new_session (true);
|
||||
|
|
|
@ -32,12 +32,15 @@
|
|||
#include <gtkmm/filefilter.h>
|
||||
#include <gtkmm/stock.h>
|
||||
|
||||
#include "opts.h"
|
||||
|
||||
NewSessionDialog::NewSessionDialog()
|
||||
: ArdourDialog ("New Session Dialog")
|
||||
{
|
||||
session_name_label = Gtk::manage(new class Gtk::Label(_("New Session Name :")));
|
||||
m_name = Gtk::manage(new class Gtk::Entry());
|
||||
m_name->set_text(GTK_ARDOUR::session_name);
|
||||
|
||||
session_location_label = Gtk::manage(new class Gtk::Label(_("Create Session Directory In :")));
|
||||
m_folder = Gtk::manage(new class Gtk::FileChooserButton(Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER));
|
||||
session_template_label = Gtk::manage(new class Gtk::Label(_("Use Session Template :")));
|
||||
|
@ -324,13 +327,21 @@ NewSessionDialog::NewSessionDialog()
|
|||
m_folder->set_current_folder(getenv ("HOME"));
|
||||
m_folder->set_title(_("select directory"));
|
||||
|
||||
set_default_response (Gtk::RESPONSE_OK);
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, false);
|
||||
set_response_sensitive (Gtk::RESPONSE_NONE, false);
|
||||
on_new_session_page = true;
|
||||
m_notebook->set_current_page(0);
|
||||
m_notebook->show();
|
||||
m_notebook->show_all_children();
|
||||
|
||||
|
||||
set_default_response (Gtk::RESPONSE_OK);
|
||||
if (!GTK_ARDOUR::session_name.length()) {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, false);
|
||||
set_response_sensitive (Gtk::RESPONSE_NONE, false);
|
||||
} else {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, true);
|
||||
set_response_sensitive (Gtk::RESPONSE_NONE, true);
|
||||
}
|
||||
|
||||
///@ connect some signals
|
||||
|
||||
m_connect_inputs->signal_clicked().connect (mem_fun (*this, &NewSessionDialog::connect_inputs_clicked));
|
||||
|
@ -501,11 +512,11 @@ NewSessionDialog::reset_name()
|
|||
bool
|
||||
NewSessionDialog::entry_key_release (GdkEventKey* ev)
|
||||
{
|
||||
if (m_name->get_text() != "") {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, true);
|
||||
if (m_name->get_text() != "") {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, true);
|
||||
set_response_sensitive (Gtk::RESPONSE_NONE, true);
|
||||
} else {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, false);
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -513,25 +524,27 @@ NewSessionDialog::entry_key_release (GdkEventKey* ev)
|
|||
void
|
||||
NewSessionDialog::notebook_page_changed (GtkNotebookPage* np, uint pagenum)
|
||||
{
|
||||
if (pagenum == 1) {
|
||||
m_okbutton->set_label(_("Open"));
|
||||
set_response_sensitive (Gtk::RESPONSE_NONE, false);
|
||||
m_okbutton->set_image (*(new Gtk::Image (Gtk::Stock::OPEN, Gtk::ICON_SIZE_BUTTON)));
|
||||
if (m_treeview->get_selection()->count_selected_rows() == 0) {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, false);
|
||||
if (pagenum == 1) {
|
||||
on_new_session_page = false;
|
||||
m_okbutton->set_label(_("Open"));
|
||||
set_response_sensitive (Gtk::RESPONSE_NONE, false);
|
||||
m_okbutton->set_image (*(new Gtk::Image (Gtk::Stock::OPEN, Gtk::ICON_SIZE_BUTTON)));
|
||||
if (m_treeview->get_selection()->count_selected_rows() == 0) {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, false);
|
||||
} else {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, true);
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, true);
|
||||
}
|
||||
} else {
|
||||
if (m_name->get_text() != "") {
|
||||
set_response_sensitive (Gtk::RESPONSE_NONE, true);
|
||||
on_new_session_page = true;
|
||||
if (m_name->get_text() != "") {
|
||||
set_response_sensitive (Gtk::RESPONSE_NONE, true);
|
||||
}
|
||||
m_okbutton->set_label(_("New"));
|
||||
m_okbutton->set_image (*(new Gtk::Image (Gtk::Stock::NEW, Gtk::ICON_SIZE_BUTTON)));
|
||||
m_okbutton->set_label(_("New"));
|
||||
m_okbutton->set_image (*(new Gtk::Image (Gtk::Stock::NEW, Gtk::ICON_SIZE_BUTTON)));
|
||||
if (m_name->get_text() == "") {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, false);
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, false);
|
||||
} else {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, true);
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -540,35 +553,37 @@ void
|
|||
NewSessionDialog::treeview_selection_changed ()
|
||||
{
|
||||
if (m_treeview->get_selection()->count_selected_rows() == 0) {
|
||||
if (!m_open_filechooser->get_filename().empty()) {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, true);
|
||||
if (!m_open_filechooser->get_filename().empty()) {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, true);
|
||||
} else {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, false);
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, false);
|
||||
}
|
||||
} else {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, true);
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NewSessionDialog::file_chosen ()
|
||||
{
|
||||
m_treeview->get_selection()->unselect_all();
|
||||
if (on_new_session_page) return;
|
||||
|
||||
m_treeview->get_selection()->unselect_all();
|
||||
|
||||
if (!m_open_filechooser->get_filename().empty()) {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, true);
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, true);
|
||||
} else {
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, false);
|
||||
set_response_sensitive (Gtk::RESPONSE_OK, false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NewSessionDialog::template_chosen ()
|
||||
{
|
||||
if (m_template->get_filename() != "" ) {;
|
||||
set_response_sensitive (Gtk::RESPONSE_NONE, true);
|
||||
if (m_template->get_filename() != "" ) {;
|
||||
set_response_sensitive (Gtk::RESPONSE_NONE, true);
|
||||
} else {
|
||||
set_response_sensitive (Gtk::RESPONSE_NONE, false);
|
||||
set_response_sensitive (Gtk::RESPONSE_NONE, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -182,6 +182,8 @@ protected:
|
|||
void master_bus_button_clicked ();
|
||||
void monitor_bus_button_clicked ();
|
||||
|
||||
bool on_new_session_page;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -143,14 +143,19 @@ GTK_ARDOUR::parse_opts (int argc, char *argv[])
|
|||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
return print_help(execname);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
if (new_session) {
|
||||
cerr << "Illogical combination: you can either create a new session, or a load an existing session but not both!" << endl;
|
||||
return print_help(execname);
|
||||
}
|
||||
session_name = argv[optind++];
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,10 +23,12 @@
|
|||
#include <ardour/panner.h>
|
||||
|
||||
#include <gtkmm2ext/popup.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "pan_automation_time_axis.h"
|
||||
#include "automation_line.h"
|
||||
#include "canvas_impl.h"
|
||||
#include "route_ui.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
@ -42,7 +44,7 @@ PanAutomationTimeAxisView::PanAutomationTimeAxisView (Session& s, boost::shared_
|
|||
{
|
||||
multiline_selector.set_name ("PanAutomationLineSelector");
|
||||
|
||||
controls_table.attach (multiline_selector, 1, 5, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
controls_table.attach (multiline_selector, 1, 5, 1, 2, Gtk::EXPAND, Gtk::EXPAND);
|
||||
}
|
||||
|
||||
PanAutomationTimeAxisView::~PanAutomationTimeAxisView ()
|
||||
|
@ -87,9 +89,10 @@ PanAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEv
|
|||
AutomationList& alist (lines[line_index]->the_list());
|
||||
|
||||
_session.begin_reversible_command (_("add pan automation event"));
|
||||
_session.add_undo (alist.get_memento());
|
||||
XMLNode &before = alist.get_state();
|
||||
alist.add (when, y);
|
||||
_session.add_redo_no_execute (alist.get_memento());
|
||||
XMLNode &after = alist.get_state();
|
||||
_session.add_command(new MementoCommand<AutomationList>(alist, before, after));
|
||||
_session.commit_reversible_command ();
|
||||
_session.set_dirty ();
|
||||
}
|
||||
|
@ -105,15 +108,18 @@ void
|
|||
PanAutomationTimeAxisView::add_line (AutomationLine& line)
|
||||
{
|
||||
char buf[32];
|
||||
snprintf(buf,32,"Line %ld",lines.size()+1);
|
||||
snprintf(buf,32,"Line %zu",lines.size()+1);
|
||||
multiline_selector.append_text(buf);
|
||||
|
||||
if (lines.empty()) {
|
||||
multiline_selector.set_active(0);
|
||||
}
|
||||
|
||||
if (lines.size() + 1 > 1) {
|
||||
if (lines.size() + 1 > 1 && (height_style != Small && height_style != Smaller)) {
|
||||
multiline_selector.show();
|
||||
} else {
|
||||
multiline_selector.hide();
|
||||
|
||||
}
|
||||
|
||||
AutomationTimeAxisView::add_line(line);
|
||||
|
@ -129,9 +135,10 @@ PanAutomationTimeAxisView::set_height (TimeAxisView::TrackHeight th)
|
|||
case Large:
|
||||
case Larger:
|
||||
case Normal:
|
||||
multiline_selector.show();
|
||||
break;
|
||||
|
||||
if (lines.size() > 1) {
|
||||
multiline_selector.show();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
multiline_selector.hide();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -48,8 +48,6 @@ PluginSelector::PluginSelector (PluginManager *mgr)
|
|||
|
||||
manager = mgr;
|
||||
session = 0;
|
||||
o_selected_plug = -1;
|
||||
i_selected_plug = 0;
|
||||
|
||||
current_selection = PluginInfo::LADSPA;
|
||||
|
||||
|
@ -305,7 +303,7 @@ void
|
|||
PluginSelector::au_refiller ()
|
||||
{
|
||||
guint row;
|
||||
PluginInfoList &plugs = manager->au_plugin_info ();
|
||||
PluginInfoList plugs (AUPluginInfo::discover ());
|
||||
PluginInfoList::iterator i;
|
||||
char ibuf[16], obuf[16];
|
||||
aumodel->clear();
|
||||
|
@ -346,7 +344,7 @@ PluginSelector::use_plugin (PluginInfoPtr pi)
|
|||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Plugin> plugin = manager->load (*session, pi);
|
||||
PluginPtr plugin = pi->load (*session);
|
||||
|
||||
if (plugin) {
|
||||
PluginCreated (plugin);
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
namespace ARDOUR {
|
||||
class Session;
|
||||
class PluginManager;
|
||||
class PluginInfo;
|
||||
}
|
||||
|
||||
class PluginSelector : public ArdourDialog
|
||||
|
@ -134,12 +133,6 @@ class PluginSelector : public ArdourDialog
|
|||
void au_display_selection_changed();
|
||||
#endif //HAVE_COREAUDIO
|
||||
|
||||
ARDOUR::PluginInfo* i_selected_plug;
|
||||
|
||||
// We need an integer for the output side because
|
||||
// the name isn't promised to be unique.
|
||||
gint o_selected_plug;
|
||||
|
||||
ARDOUR::PluginManager *manager;
|
||||
|
||||
static void _input_refiller (void *);
|
||||
|
|
|
@ -90,13 +90,13 @@ PluginUIWindow::PluginUIWindow (AudioEngine &engine, boost::shared_ptr<PluginIns
|
|||
|
||||
} else {
|
||||
|
||||
PluginUI* pu = new PluginUI (engine, insert, scrollable);
|
||||
LadspaPluginUI* pu = new LadspaPluginUI (engine, insert, scrollable);
|
||||
|
||||
_pluginui = pu;
|
||||
get_vbox()->add (*pu);
|
||||
|
||||
signal_map_event().connect (mem_fun (*pu, &PluginUI::start_updating));
|
||||
signal_unmap_event().connect (mem_fun (*pu, &PluginUI::stop_updating));
|
||||
signal_map_event().connect (mem_fun (*pu, &LadspaPluginUI::start_updating));
|
||||
signal_unmap_event().connect (mem_fun (*pu, &LadspaPluginUI::stop_updating));
|
||||
}
|
||||
|
||||
set_position (Gtk::WIN_POS_MOUSE);
|
||||
|
@ -117,7 +117,7 @@ PluginUIWindow::~PluginUIWindow ()
|
|||
{
|
||||
}
|
||||
|
||||
PluginUI::PluginUI (AudioEngine &engine, boost::shared_ptr<PluginInsert> pi, bool scrollable)
|
||||
LadspaPluginUI::LadspaPluginUI (AudioEngine &engine, boost::shared_ptr<PluginInsert> pi, bool scrollable)
|
||||
: PlugUIBase (pi),
|
||||
engine(engine),
|
||||
button_table (initial_button_rows, initial_button_cols),
|
||||
|
@ -165,13 +165,13 @@ PluginUI::PluginUI (AudioEngine &engine, boost::shared_ptr<PluginInsert> pi, boo
|
|||
pack_start (hpacker, false, false);
|
||||
}
|
||||
|
||||
insert->active_changed.connect (mem_fun(*this, &PluginUI::redirect_active_changed));
|
||||
insert->active_changed.connect (mem_fun(*this, &LadspaPluginUI::redirect_active_changed));
|
||||
bypass_button.set_active (!insert->active());
|
||||
|
||||
build (engine);
|
||||
}
|
||||
|
||||
PluginUI::~PluginUI ()
|
||||
LadspaPluginUI::~LadspaPluginUI ()
|
||||
{
|
||||
if (output_controls.size() > 0) {
|
||||
screen_update_connection.disconnect();
|
||||
|
@ -179,7 +179,7 @@ PluginUI::~PluginUI ()
|
|||
}
|
||||
|
||||
void
|
||||
PluginUI::build (AudioEngine &engine)
|
||||
LadspaPluginUI::build (AudioEngine &engine)
|
||||
|
||||
{
|
||||
guint32 i = 0;
|
||||
|
@ -326,8 +326,8 @@ PluginUI::build (AudioEngine &engine)
|
|||
}
|
||||
}
|
||||
|
||||
n_ins = plugin->get_info().n_inputs;
|
||||
n_outs = plugin->get_info().n_outputs;
|
||||
n_ins = plugin->get_info()->n_inputs;
|
||||
n_outs = plugin->get_info()->n_outputs;
|
||||
|
||||
if (box->children().empty()) {
|
||||
hpacker.remove (*frame);
|
||||
|
@ -350,7 +350,7 @@ PluginUI::build (AudioEngine &engine)
|
|||
button_table.show_all ();
|
||||
}
|
||||
|
||||
PluginUI::ControlUI::ControlUI ()
|
||||
LadspaPluginUI::ControlUI::ControlUI ()
|
||||
: automate_button (X_("")) // force creation of a label
|
||||
{
|
||||
automate_button.set_name ("PluginAutomateButton");
|
||||
|
@ -370,7 +370,7 @@ PluginUI::ControlUI::ControlUI ()
|
|||
meterinfo = 0;
|
||||
}
|
||||
|
||||
PluginUI::ControlUI::~ControlUI()
|
||||
LadspaPluginUI::ControlUI::~ControlUI()
|
||||
{
|
||||
if (adjustment) {
|
||||
delete adjustment;
|
||||
|
@ -383,7 +383,7 @@ PluginUI::ControlUI::~ControlUI()
|
|||
}
|
||||
|
||||
void
|
||||
PluginUI::automation_state_changed (ControlUI* cui)
|
||||
LadspaPluginUI::automation_state_changed (ControlUI* cui)
|
||||
{
|
||||
/* update button label */
|
||||
|
||||
|
@ -413,13 +413,13 @@ static void integer_printer (char buf[32], Adjustment &adj, void *arg)
|
|||
}
|
||||
|
||||
void
|
||||
PluginUI::print_parameter (char *buf, uint32_t len, uint32_t param)
|
||||
LadspaPluginUI::print_parameter (char *buf, uint32_t len, uint32_t param)
|
||||
{
|
||||
plugin->print_parameter (param, buf, len);
|
||||
}
|
||||
|
||||
PluginUI::ControlUI*
|
||||
PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, PBD::Controllable* mcontrol)
|
||||
LadspaPluginUI::ControlUI*
|
||||
LadspaPluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, PBD::Controllable* mcontrol)
|
||||
|
||||
{
|
||||
ControlUI* control_ui;
|
||||
|
@ -452,8 +452,8 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, PBD::Contro
|
|||
control_ui->combo = new Gtk::ComboBoxText;
|
||||
//control_ui->combo->set_value_in_list(true, false);
|
||||
set_popdown_strings (*control_ui->combo, setup_scale_values(port_index, control_ui));
|
||||
control_ui->combo->signal_changed().connect (bind (mem_fun(*this, &PluginUI::control_combo_changed), control_ui));
|
||||
plugin->ParameterChanged.connect (bind (mem_fun (*this, &PluginUI::parameter_changed), control_ui));
|
||||
control_ui->combo->signal_changed().connect (bind (mem_fun(*this, &LadspaPluginUI::control_combo_changed), control_ui));
|
||||
plugin->ParameterChanged.connect (bind (mem_fun (*this, &LadspaPluginUI::parameter_changed), control_ui));
|
||||
control_ui->pack_start(control_ui->label, true, true);
|
||||
control_ui->pack_start(*control_ui->combo, false, true);
|
||||
|
||||
|
@ -476,7 +476,7 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, PBD::Contro
|
|||
control_ui->pack_start (*control_ui->button, false, true);
|
||||
control_ui->pack_start (control_ui->automate_button, false, false);
|
||||
|
||||
control_ui->button->signal_clicked().connect (bind (mem_fun(*this, &PluginUI::control_port_toggled), control_ui));
|
||||
control_ui->button->signal_clicked().connect (bind (mem_fun(*this, &LadspaPluginUI::control_port_toggled), control_ui));
|
||||
|
||||
if(plugin->get_parameter (port_index) == 1){
|
||||
control_ui->button->set_active(true);
|
||||
|
@ -514,7 +514,7 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, PBD::Contro
|
|||
Gtkmm2ext::set_size_request_to_display_given_text (*control_ui->clickbox, "g9999999", 2, 2);
|
||||
control_ui->clickbox->set_print_func (integer_printer, 0);
|
||||
} else {
|
||||
sigc::slot<void,char*,uint32_t> pslot = sigc::bind (mem_fun(*this, &PluginUI::print_parameter), (uint32_t) port_index);
|
||||
sigc::slot<void,char*,uint32_t> pslot = sigc::bind (mem_fun(*this, &LadspaPluginUI::print_parameter), (uint32_t) port_index);
|
||||
|
||||
control_ui->control = new BarController (*control_ui->adjustment, *mcontrol, pslot);
|
||||
// should really match the height of the text in the automation button+label
|
||||
|
@ -523,8 +523,8 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, PBD::Contro
|
|||
control_ui->control->set_style (BarController::LeftToRight);
|
||||
control_ui->control->set_use_parent (true);
|
||||
|
||||
control_ui->control->StartGesture.connect (bind (mem_fun(*this, &PluginUI::start_touch), control_ui));
|
||||
control_ui->control->StopGesture.connect (bind (mem_fun(*this, &PluginUI::stop_touch), control_ui));
|
||||
control_ui->control->StartGesture.connect (bind (mem_fun(*this, &LadspaPluginUI::start_touch), control_ui));
|
||||
control_ui->control->StopGesture.connect (bind (mem_fun(*this, &LadspaPluginUI::stop_touch), control_ui));
|
||||
|
||||
}
|
||||
|
||||
|
@ -547,14 +547,14 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, PBD::Contro
|
|||
}
|
||||
|
||||
control_ui->pack_start (control_ui->automate_button, false, false);
|
||||
control_ui->adjustment->signal_value_changed().connect (bind (mem_fun(*this, &PluginUI::control_adjustment_changed), control_ui));
|
||||
control_ui->automate_button.signal_clicked().connect (bind (mem_fun(*this, &PluginUI::astate_clicked), control_ui, (uint32_t) port_index));
|
||||
control_ui->adjustment->signal_value_changed().connect (bind (mem_fun(*this, &LadspaPluginUI::control_adjustment_changed), control_ui));
|
||||
control_ui->automate_button.signal_clicked().connect (bind (mem_fun(*this, &LadspaPluginUI::astate_clicked), control_ui, (uint32_t) port_index));
|
||||
|
||||
automation_state_changed (control_ui);
|
||||
|
||||
plugin->ParameterChanged.connect (bind (mem_fun(*this, &PluginUI::parameter_changed), control_ui));
|
||||
plugin->ParameterChanged.connect (bind (mem_fun(*this, &LadspaPluginUI::parameter_changed), control_ui));
|
||||
insert->automation_list (port_index).automation_state_changed.connect
|
||||
(bind (mem_fun(*this, &PluginUI::automation_state_changed), control_ui));
|
||||
(bind (mem_fun(*this, &LadspaPluginUI::automation_state_changed), control_ui));
|
||||
|
||||
} else if (plugin->parameter_is_output (port_index)) {
|
||||
|
||||
|
@ -603,24 +603,24 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, PBD::Contro
|
|||
output_controls.push_back (control_ui);
|
||||
}
|
||||
|
||||
plugin->ParameterChanged.connect (bind (mem_fun(*this, &PluginUI::parameter_changed), control_ui));
|
||||
plugin->ParameterChanged.connect (bind (mem_fun(*this, &LadspaPluginUI::parameter_changed), control_ui));
|
||||
return control_ui;
|
||||
}
|
||||
|
||||
void
|
||||
PluginUI::start_touch (PluginUI::ControlUI* cui)
|
||||
LadspaPluginUI::start_touch (LadspaPluginUI::ControlUI* cui)
|
||||
{
|
||||
insert->automation_list (cui->port_index).start_touch ();
|
||||
}
|
||||
|
||||
void
|
||||
PluginUI::stop_touch (PluginUI::ControlUI* cui)
|
||||
LadspaPluginUI::stop_touch (LadspaPluginUI::ControlUI* cui)
|
||||
{
|
||||
insert->automation_list (cui->port_index).stop_touch ();
|
||||
}
|
||||
|
||||
void
|
||||
PluginUI::astate_clicked (ControlUI* cui, uint32_t port)
|
||||
LadspaPluginUI::astate_clicked (ControlUI* cui, uint32_t port)
|
||||
{
|
||||
using namespace Menu_Helpers;
|
||||
|
||||
|
@ -633,25 +633,25 @@ PluginUI::astate_clicked (ControlUI* cui, uint32_t port)
|
|||
|
||||
items.clear ();
|
||||
items.push_back (MenuElem (_("Off"),
|
||||
bind (mem_fun(*this, &PluginUI::set_automation_state), (AutoState) Off, cui)));
|
||||
bind (mem_fun(*this, &LadspaPluginUI::set_automation_state), (AutoState) Off, cui)));
|
||||
items.push_back (MenuElem (_("Play"),
|
||||
bind (mem_fun(*this, &PluginUI::set_automation_state), (AutoState) Play, cui)));
|
||||
bind (mem_fun(*this, &LadspaPluginUI::set_automation_state), (AutoState) Play, cui)));
|
||||
items.push_back (MenuElem (_("Write"),
|
||||
bind (mem_fun(*this, &PluginUI::set_automation_state), (AutoState) Write, cui)));
|
||||
bind (mem_fun(*this, &LadspaPluginUI::set_automation_state), (AutoState) Write, cui)));
|
||||
items.push_back (MenuElem (_("Touch"),
|
||||
bind (mem_fun(*this, &PluginUI::set_automation_state), (AutoState) Touch, cui)));
|
||||
bind (mem_fun(*this, &LadspaPluginUI::set_automation_state), (AutoState) Touch, cui)));
|
||||
|
||||
automation_menu->popup (1, 0);
|
||||
}
|
||||
|
||||
void
|
||||
PluginUI::set_automation_state (AutoState state, ControlUI* cui)
|
||||
LadspaPluginUI::set_automation_state (AutoState state, ControlUI* cui)
|
||||
{
|
||||
insert->set_port_automation_state (cui->port_index, state);
|
||||
}
|
||||
|
||||
void
|
||||
PluginUI::control_adjustment_changed (ControlUI* cui)
|
||||
LadspaPluginUI::control_adjustment_changed (ControlUI* cui)
|
||||
{
|
||||
if (cui->ignore_change) {
|
||||
return;
|
||||
|
@ -667,18 +667,18 @@ PluginUI::control_adjustment_changed (ControlUI* cui)
|
|||
}
|
||||
|
||||
void
|
||||
PluginUI::parameter_changed (uint32_t abs_port_id, float val, ControlUI* cui)
|
||||
LadspaPluginUI::parameter_changed (uint32_t abs_port_id, float val, ControlUI* cui)
|
||||
{
|
||||
if (cui->port_index == abs_port_id) {
|
||||
if (!cui->update_pending) {
|
||||
cui->update_pending = true;
|
||||
Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &PluginUI::update_control_display), cui));
|
||||
Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &LadspaPluginUI::update_control_display), cui));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginUI::update_control_display (ControlUI* cui)
|
||||
LadspaPluginUI::update_control_display (ControlUI* cui)
|
||||
{
|
||||
/* XXX how do we handle logarithmic stuff here ? */
|
||||
|
||||
|
@ -715,7 +715,7 @@ PluginUI::update_control_display (ControlUI* cui)
|
|||
}
|
||||
|
||||
void
|
||||
PluginUI::control_port_toggled (ControlUI* cui)
|
||||
LadspaPluginUI::control_port_toggled (ControlUI* cui)
|
||||
{
|
||||
if (!cui->ignore_change) {
|
||||
insert->set_parameter (cui->port_index, cui->button->get_active());
|
||||
|
@ -723,7 +723,7 @@ PluginUI::control_port_toggled (ControlUI* cui)
|
|||
}
|
||||
|
||||
void
|
||||
PluginUI::control_combo_changed (ControlUI* cui)
|
||||
LadspaPluginUI::control_combo_changed (ControlUI* cui)
|
||||
{
|
||||
if (!cui->ignore_change) {
|
||||
string value = cui->combo->get_active_text();
|
||||
|
@ -743,26 +743,26 @@ PluginUIWindow::plugin_going_away (ARDOUR::Redirect* ignored)
|
|||
}
|
||||
|
||||
void
|
||||
PluginUI::redirect_active_changed (Redirect* r, void* src)
|
||||
LadspaPluginUI::redirect_active_changed (Redirect* r, void* src)
|
||||
{
|
||||
ENSURE_GUI_THREAD(bind (mem_fun(*this, &PluginUI::redirect_active_changed), r, src));
|
||||
ENSURE_GUI_THREAD(bind (mem_fun(*this, &LadspaPluginUI::redirect_active_changed), r, src));
|
||||
|
||||
bypass_button.set_active (!r->active());
|
||||
}
|
||||
|
||||
bool
|
||||
PluginUI::start_updating (GdkEventAny* ignored)
|
||||
LadspaPluginUI::start_updating (GdkEventAny* ignored)
|
||||
{
|
||||
if (output_controls.size() > 0 ) {
|
||||
screen_update_connection.disconnect();
|
||||
screen_update_connection = ARDOUR_UI::instance()->RapidScreenUpdate.connect
|
||||
(mem_fun(*this, &PluginUI::output_update));
|
||||
(mem_fun(*this, &LadspaPluginUI::output_update));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginUI::stop_updating (GdkEventAny* ignored)
|
||||
LadspaPluginUI::stop_updating (GdkEventAny* ignored)
|
||||
{
|
||||
if (output_controls.size() > 0 ) {
|
||||
screen_update_connection.disconnect();
|
||||
|
@ -771,7 +771,7 @@ PluginUI::stop_updating (GdkEventAny* ignored)
|
|||
}
|
||||
|
||||
void
|
||||
PluginUI::output_update ()
|
||||
LadspaPluginUI::output_update ()
|
||||
{
|
||||
for (vector<ControlUI*>::iterator i = output_controls.begin(); i != output_controls.end(); ++i) {
|
||||
float val = plugin->get_parameter ((*i)->port_index);
|
||||
|
@ -805,7 +805,7 @@ PluginUI::output_update ()
|
|||
}
|
||||
|
||||
vector<string>
|
||||
PluginUI::setup_scale_values(guint32 port_index, ControlUI* cui)
|
||||
LadspaPluginUI::setup_scale_values(guint32 port_index, ControlUI* cui)
|
||||
{
|
||||
vector<string> enums;
|
||||
boost::shared_ptr<LadspaPlugin> lp = boost::dynamic_pointer_cast<LadspaPlugin> (plugin);
|
||||
|
|
|
@ -50,6 +50,7 @@ namespace ARDOUR {
|
|||
class Plugin;
|
||||
class VSTPlugin;
|
||||
class Redirect;
|
||||
class AUPlugin;
|
||||
}
|
||||
|
||||
namespace PBD {
|
||||
|
@ -86,11 +87,11 @@ class PlugUIBase : public virtual sigc::trackable
|
|||
void bypass_toggled();
|
||||
};
|
||||
|
||||
class PluginUI : public PlugUIBase, public Gtk::VBox
|
||||
class LadspaPluginUI : public PlugUIBase, public Gtk::VBox
|
||||
{
|
||||
public:
|
||||
PluginUI (ARDOUR::AudioEngine &, boost::shared_ptr<ARDOUR::PluginInsert> plug, bool scrollable=false);
|
||||
~PluginUI ();
|
||||
LadspaPluginUI (ARDOUR::AudioEngine &, boost::shared_ptr<ARDOUR::PluginInsert> plug, bool scrollable=false);
|
||||
~LadspaPluginUI ();
|
||||
|
||||
gint get_preferred_height () { return prefheight; }
|
||||
|
||||
|
@ -231,6 +232,22 @@ class VSTPluginUI : public PlugUIBase, public Gtk::VBox
|
|||
bool configure_handler (GdkEventConfigure*, Gtk::Socket*);
|
||||
void save_plugin_setting ();
|
||||
};
|
||||
#endif
|
||||
#endif // VST_SUPPORT
|
||||
|
||||
#ifdef HAVE_COREAUDIO
|
||||
class AUPluginUI : public PlugUIBase
|
||||
{
|
||||
public:
|
||||
AUPluginUI (boost::shared_ptr<ARDOUR::PluginInsert>, boost::shared_ptr<ARDOUR::AUPlugin>);
|
||||
~AUPluginUI ();
|
||||
|
||||
gint get_preferred_height ();
|
||||
bool start_updating(GdkEventAny*) {return false;}
|
||||
bool stop_updating(GdkEventAny*) {return false;}
|
||||
|
||||
private:
|
||||
boost::shared_ptr<ARDOUR::AUPlugin> au;
|
||||
};
|
||||
#endif // HAVE_COREAUDIO
|
||||
|
||||
#endif /* __ardour_plugin_ui_h__ */
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <ardour/redirect.h>
|
||||
#include <ardour/session.h>
|
||||
#include <cstdlib>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "redirect_automation_time_axis.h"
|
||||
#include "automation_line.h"
|
||||
|
@ -98,9 +99,10 @@ RedirectAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item,
|
|||
lines.front()->view_to_model_y (y);
|
||||
|
||||
_session.begin_reversible_command (description);
|
||||
_session.add_undo (alist.get_memento());
|
||||
XMLNode &before = alist.get_state();
|
||||
alist.add (when, y);
|
||||
_session.add_redo_no_execute (alist.get_memento());
|
||||
XMLNode &after = alist.get_state();
|
||||
_session.add_command(new MementoCommand<AutomationList>(alist, before, after));
|
||||
_session.commit_reversible_command ();
|
||||
_session.set_dirty ();
|
||||
}
|
||||
|
|
|
@ -378,7 +378,7 @@ RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, boost::shared_ptr
|
|||
|
||||
/* i hate this kind of code */
|
||||
|
||||
if (streams > p.get_info().n_inputs) {
|
||||
if (streams > p.get_info()->n_inputs) {
|
||||
label.set_text (string_compose (_(
|
||||
"You attempted to add a plugin (%1).\n"
|
||||
"The plugin has %2 inputs\n"
|
||||
|
@ -388,9 +388,9 @@ RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, boost::shared_ptr
|
|||
"This makes no sense - you are throwing away\n"
|
||||
"part of the signal."),
|
||||
p.name(),
|
||||
p.get_info().n_inputs,
|
||||
p.get_info()->n_inputs,
|
||||
streams));
|
||||
} else if (streams < p.get_info().n_inputs) {
|
||||
} else if (streams < p.get_info()->n_inputs) {
|
||||
label.set_text (string_compose (_(
|
||||
"You attempted to add a plugin (%1).\n"
|
||||
"The plugin has %2 inputs\n"
|
||||
|
@ -401,7 +401,7 @@ RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, boost::shared_ptr
|
|||
"side-chain inputs. A future version of Ardour will\n"
|
||||
"support this type of configuration."),
|
||||
p.name(),
|
||||
p.get_info().n_inputs,
|
||||
p.get_info()->n_inputs,
|
||||
streams));
|
||||
} else {
|
||||
label.set_text (string_compose (_(
|
||||
|
@ -415,8 +415,8 @@ RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, boost::shared_ptr
|
|||
"\n"
|
||||
"Ardour does not understand what to do in such situations.\n"),
|
||||
p.name(),
|
||||
p.get_info().n_inputs,
|
||||
p.get_info().n_outputs,
|
||||
p.get_info()->n_inputs,
|
||||
p.get_info()->n_outputs,
|
||||
io->n_inputs(),
|
||||
io->n_outputs(),
|
||||
streams));
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: region_editor.h 231 2006-01-03 14:16:27Z karstenweise $
|
||||
$Id: /local/undo/gtk2_ardour/region_editor.h 5 2006-05-31T02:48:48.738745Z paul $
|
||||
*/
|
||||
|
||||
#ifndef __gtk_ardour_region_edit_h__
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <ardour/curve.h>
|
||||
#include <ardour/audioregion.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "region_gain_line.h"
|
||||
#include "audio_region_view.h"
|
||||
|
@ -47,7 +48,8 @@ AudioRegionGainLine::start_drag (ControlPoint* cp, float fraction)
|
|||
{
|
||||
AutomationLine::start_drag(cp,fraction);
|
||||
if (!rv.audio_region().envelope_active()) {
|
||||
trackview.session().add_undo( bind( mem_fun(rv.audio_region(), &AudioRegion::set_envelope_active), false) );
|
||||
trackview.session().add_command(new MementoUndoCommand<AudioRegion>(rv.audio_region(), rv.audio_region().get_state()));
|
||||
rv.audio_region().set_envelope_active(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,17 +62,18 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
|
|||
model_representation (cp, mr);
|
||||
|
||||
trackview.editor.current_session()->begin_reversible_command (_("remove control point"));
|
||||
trackview.editor.current_session()->add_undo (get_memento());
|
||||
XMLNode &before = get_state();
|
||||
|
||||
if (!rv.audio_region().envelope_active()) {
|
||||
trackview.session().add_undo( bind( mem_fun(rv.audio_region(), &AudioRegion::set_envelope_active), false) );
|
||||
trackview.session().add_redo( bind( mem_fun(rv.audio_region(), &AudioRegion::set_envelope_active), true) );
|
||||
XMLNode &before = rv.audio_region().get_state();
|
||||
rv.audio_region().set_envelope_active(true);
|
||||
XMLNode &after = rv.audio_region().get_state();
|
||||
trackview.session().add_command(new MementoCommand<AudioRegion>(rv.audio_region(), before, after));
|
||||
}
|
||||
|
||||
alist.erase (mr.start, mr.end);
|
||||
|
||||
trackview.editor.current_session()->add_redo_no_execute (get_memento());
|
||||
trackview.editor.current_session()->add_command (new MementoCommand<AudioRegionGainLine>(*this, before, get_state()));
|
||||
trackview.editor.current_session()->commit_reversible_command ();
|
||||
trackview.editor.current_session()->set_dirty ();
|
||||
}
|
||||
|
@ -79,8 +82,8 @@ void
|
|||
AudioRegionGainLine::end_drag (ControlPoint* cp)
|
||||
{
|
||||
if (!rv.audio_region().envelope_active()) {
|
||||
trackview.session().add_redo( bind( mem_fun(rv.audio_region(), &AudioRegion::set_envelope_active), true) );
|
||||
rv.audio_region().set_envelope_active(true);
|
||||
trackview.session().add_command(new MementoRedoCommand<AudioRegion>(rv.audio_region(), rv.audio_region().get_state()));
|
||||
}
|
||||
AutomationLine::end_drag(cp);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ class AudioRegionGainLine : public AutomationLine
|
|||
|
||||
void remove_point (ControlPoint&);
|
||||
|
||||
PBD::ID id() { return _id; }
|
||||
|
||||
|
||||
private:
|
||||
|
@ -33,6 +34,8 @@ class AudioRegionGainLine : public AutomationLine
|
|||
AudioRegionView& rv;
|
||||
|
||||
UndoAction get_memento();
|
||||
|
||||
PBD::ID _id;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -287,9 +287,9 @@ void
|
|||
RouteParams_UI::cleanup_pre_view (bool stopupdate)
|
||||
{
|
||||
if (_active_pre_view) {
|
||||
PluginUI * plugui = 0;
|
||||
LadspaPluginUI * plugui = 0;
|
||||
|
||||
if (stopupdate && (plugui = dynamic_cast<PluginUI*>(_active_pre_view)) != 0) {
|
||||
if (stopupdate && (plugui = dynamic_cast<LadspaPluginUI*>(_active_pre_view)) != 0) {
|
||||
plugui->stop_updating (0);
|
||||
}
|
||||
|
||||
|
@ -304,9 +304,9 @@ void
|
|||
RouteParams_UI::cleanup_post_view (bool stopupdate)
|
||||
{
|
||||
if (_active_post_view) {
|
||||
PluginUI * plugui = 0;
|
||||
LadspaPluginUI * plugui = 0;
|
||||
|
||||
if (stopupdate && (plugui = dynamic_cast<PluginUI*>(_active_post_view)) != 0) {
|
||||
if (stopupdate && (plugui = dynamic_cast<LadspaPluginUI*>(_active_post_view)) != 0) {
|
||||
plugui->stop_updating (0);
|
||||
}
|
||||
_post_plugin_conn.disconnect();
|
||||
|
@ -556,7 +556,7 @@ RouteParams_UI::redirect_selected (boost::shared_ptr<ARDOUR::Redirect> redirect,
|
|||
|
||||
if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (insert)) != 0) {
|
||||
|
||||
PluginUI *plugin_ui = new PluginUI (session->engine(), plugin_insert, true);
|
||||
LadspaPluginUI *plugin_ui = new LadspaPluginUI (session->engine(), plugin_insert, true);
|
||||
|
||||
if (place == PreFader) {
|
||||
cleanup_pre_view();
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <pbd/error.h>
|
||||
#include <pbd/stl_delete.h>
|
||||
#include <pbd/whitespace.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include <gtkmm/menu.h>
|
||||
#include <gtkmm/menuitem.h>
|
||||
|
@ -575,46 +576,88 @@ RouteTimeAxisView::set_height (TrackHeight h)
|
|||
switch (height_style) {
|
||||
case Largest:
|
||||
xml_node->add_property ("track_height", "largest");
|
||||
show_name_entry ();
|
||||
hide_name_label ();
|
||||
controls_table.show_all();
|
||||
break;
|
||||
|
||||
case Large:
|
||||
xml_node->add_property ("track_height", "large");
|
||||
show_name_entry ();
|
||||
hide_name_label ();
|
||||
controls_table.show_all();
|
||||
break;
|
||||
|
||||
case Larger:
|
||||
xml_node->add_property ("track_height", "larger");
|
||||
show_name_entry ();
|
||||
hide_name_label ();
|
||||
controls_table.show_all();
|
||||
break;
|
||||
|
||||
case Normal:
|
||||
xml_node->add_property ("track_height", "normal");
|
||||
show_name_entry ();
|
||||
hide_name_label ();
|
||||
controls_table.show_all();
|
||||
break;
|
||||
|
||||
case Smaller:
|
||||
xml_node->add_property ("track_height", "smaller");
|
||||
controls_table.show_all ();
|
||||
break;
|
||||
|
||||
case Small:
|
||||
xml_node->add_property ("track_height", "small");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (height_style) {
|
||||
case Largest:
|
||||
case Large:
|
||||
case Larger:
|
||||
case Normal:
|
||||
show_name_entry ();
|
||||
hide_name_label ();
|
||||
|
||||
mute_button->show_all();
|
||||
solo_button->show_all();
|
||||
if (rec_enable_button)
|
||||
rec_enable_button->show_all();
|
||||
|
||||
edit_group_button.show_all();
|
||||
hide_button.show_all();
|
||||
visual_button.show_all();
|
||||
size_button.show_all();
|
||||
automation_button.show_all();
|
||||
|
||||
if (is_track() && track()->mode() == ARDOUR::Normal) {
|
||||
playlist_button.show_all();
|
||||
}
|
||||
break;
|
||||
|
||||
case Smaller:
|
||||
show_name_entry ();
|
||||
hide_name_label ();
|
||||
|
||||
mute_button->show_all();
|
||||
solo_button->show_all();
|
||||
if (rec_enable_button)
|
||||
rec_enable_button->show_all();
|
||||
|
||||
edit_group_button.hide ();
|
||||
hide_button.hide ();
|
||||
visual_button.hide ();
|
||||
size_button.hide ();
|
||||
automation_button.hide ();
|
||||
|
||||
if (is_track() && track()->mode() == ARDOUR::Normal) {
|
||||
playlist_button.hide ();
|
||||
}
|
||||
break;
|
||||
|
||||
case Small:
|
||||
hide_name_entry ();
|
||||
show_name_label ();
|
||||
|
||||
mute_button->hide();
|
||||
solo_button->hide();
|
||||
if (rec_enable_button)
|
||||
rec_enable_button->hide();
|
||||
|
||||
edit_group_button.hide ();
|
||||
hide_button.hide ();
|
||||
visual_button.hide ();
|
||||
size_button.hide ();
|
||||
automation_button.hide ();
|
||||
playlist_button.hide ();
|
||||
break;
|
||||
case Small:
|
||||
xml_node->add_property ("track_height", "small");
|
||||
controls_table.hide_all ();
|
||||
controls_table.show ();
|
||||
hide_name_entry ();
|
||||
show_name_label ();
|
||||
name_label.set_text (_route->name());
|
||||
break;
|
||||
}
|
||||
|
@ -1008,12 +1051,12 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
|
|||
}
|
||||
}
|
||||
|
||||
XMLNode &before = playlist->get_state();
|
||||
switch (op) {
|
||||
case Cut:
|
||||
_session.add_undo (playlist->get_memento());
|
||||
if ((what_we_got = playlist->cut (time)) != 0) {
|
||||
editor.get_cut_buffer().add (what_we_got);
|
||||
_session.add_redo_no_execute (playlist->get_memento());
|
||||
_session.add_command( new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
|
@ -1024,9 +1067,8 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
|
|||
break;
|
||||
|
||||
case Clear:
|
||||
_session.add_undo (playlist->get_memento());
|
||||
if ((what_we_got = playlist->cut (time)) != 0) {
|
||||
_session.add_redo_no_execute (playlist->get_memento());
|
||||
_session.add_command( new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
|
||||
what_we_got->unref ();
|
||||
ret = true;
|
||||
}
|
||||
|
@ -1055,9 +1097,9 @@ RouteTimeAxisView::paste (jack_nframes_t pos, float times, Selection& selection,
|
|||
if (get_diskstream()->speed() != 1.0f)
|
||||
pos = session_frame_to_track_frame(pos, get_diskstream()->speed() );
|
||||
|
||||
_session.add_undo (playlist->get_memento());
|
||||
XMLNode &before = playlist->get_state();
|
||||
playlist->paste (**p, pos, times);
|
||||
_session.add_redo_no_execute (playlist->get_memento());
|
||||
_session.add_command( new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <gtkmm2ext/bindable_button.h>
|
||||
|
||||
#include <ardour/route_group.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include "route_ui.h"
|
||||
#include "keyboard.h"
|
||||
|
@ -130,9 +131,10 @@ RouteUI::mute_press(GdkEventButton* ev)
|
|||
/* ctrl-shift-click applies change to all routes */
|
||||
|
||||
_session.begin_reversible_command (_("mute change"));
|
||||
_session.add_undo (_session.global_mute_memento(this));
|
||||
Session::GlobalMuteStateCommand *cmd = new Session::GlobalMuteStateCommand(_session, this);
|
||||
_session.set_all_mute (!_route->muted());
|
||||
_session.add_redo_no_execute (_session.global_mute_memento(this));
|
||||
cmd->mark();
|
||||
_session.add_command(cmd);
|
||||
_session.commit_reversible_command ();
|
||||
|
||||
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
|
||||
|
@ -205,9 +207,10 @@ RouteUI::solo_press(GdkEventButton* ev)
|
|||
/* ctrl-shift-click applies change to all routes */
|
||||
|
||||
_session.begin_reversible_command (_("solo change"));
|
||||
_session.add_undo (_session.global_solo_memento(this));
|
||||
Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand(_session, this);
|
||||
_session.set_all_solo (!_route->soloed());
|
||||
_session.add_redo_no_execute (_session.global_solo_memento(this));
|
||||
cmd->mark();
|
||||
_session.add_command (cmd);
|
||||
_session.commit_reversible_command ();
|
||||
|
||||
} else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Alt))) {
|
||||
|
@ -215,10 +218,11 @@ RouteUI::solo_press(GdkEventButton* ev)
|
|||
// ctrl-alt-click: exclusively solo this track, not a toggle */
|
||||
|
||||
_session.begin_reversible_command (_("solo change"));
|
||||
_session.add_undo (_session.global_solo_memento(this));
|
||||
Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand (_session, this);
|
||||
_session.set_all_solo (false);
|
||||
_route->set_solo (true, this);
|
||||
_session.add_redo_no_execute (_session.global_solo_memento(this));
|
||||
cmd->mark();
|
||||
_session.add_command(cmd);
|
||||
_session.commit_reversible_command ();
|
||||
|
||||
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
|
||||
|
@ -278,7 +282,7 @@ RouteUI::rec_enable_press(GdkEventButton* ev)
|
|||
else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) {
|
||||
|
||||
_session.begin_reversible_command (_("rec-enable change"));
|
||||
_session.add_undo (_session.global_record_enable_memento(this));
|
||||
Session::GlobalRecordEnableStateCommand *cmd = new Session::GlobalRecordEnableStateCommand(_session, this);
|
||||
|
||||
if (rec_enable_button->get_active()) {
|
||||
_session.record_disenable_all ();
|
||||
|
@ -286,7 +290,8 @@ RouteUI::rec_enable_press(GdkEventButton* ev)
|
|||
_session.record_enable_all ();
|
||||
}
|
||||
|
||||
_session.add_redo_no_execute (_session.global_record_enable_memento(this));
|
||||
cmd->mark();
|
||||
_session.add_command(cmd);
|
||||
_session.commit_reversible_command ();
|
||||
|
||||
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
|
||||
|
@ -555,9 +560,10 @@ RouteUI::set_mix_group_solo(boost::shared_ptr<Route> route, bool yn)
|
|||
|
||||
if((mix_group = route->mix_group()) != 0){
|
||||
_session.begin_reversible_command (_("mix group solo change"));
|
||||
_session.add_undo (_session.global_solo_memento (this));
|
||||
Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand(_session, this);
|
||||
mix_group->apply(&Route::set_solo, yn, this);
|
||||
_session.add_redo_no_execute (_session.global_solo_memento(this));
|
||||
cmd->mark();
|
||||
_session.add_command (cmd);
|
||||
_session.commit_reversible_command ();
|
||||
} else {
|
||||
reversibly_apply_route_boolean ("solo change", &Route::set_solo, !route->soloed(), this);
|
||||
|
@ -568,8 +574,10 @@ void
|
|||
RouteUI::reversibly_apply_route_boolean (string name, void (Route::*func)(bool, void *), bool yn, void *arg)
|
||||
{
|
||||
_session.begin_reversible_command (name);
|
||||
_session.add_undo (bind (mem_fun (*_route, func), !yn, (void *) arg));
|
||||
_session.add_redo (bind (mem_fun (*_route, func), yn, (void *) arg));
|
||||
XMLNode &before = _route->get_state();
|
||||
bind(mem_fun(*_route, func), yn, arg)();
|
||||
XMLNode &after = _route->get_state();
|
||||
_session.add_command (new MementoCommand<Route>(*_route, before, after));
|
||||
_session.commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -577,8 +585,10 @@ void
|
|||
RouteUI::reversibly_apply_audio_track_boolean (string name, void (AudioTrack::*func)(bool, void *), bool yn, void *arg)
|
||||
{
|
||||
_session.begin_reversible_command (name);
|
||||
_session.add_undo (bind (mem_fun (*audio_track(), func), !yn, (void *) arg));
|
||||
_session.add_redo (bind (mem_fun (*audio_track(), func), yn, (void *) arg));
|
||||
XMLNode &before = audio_track()->get_state();
|
||||
bind (mem_fun (*audio_track(), func), yn, arg)();
|
||||
XMLNode &after = audio_track()->get_state();
|
||||
_session.add_command (new MementoCommand<AudioTrack>(*audio_track(), before, after));
|
||||
_session.commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -589,9 +599,10 @@ RouteUI::set_mix_group_mute(boost::shared_ptr<Route> route, bool yn)
|
|||
|
||||
if((mix_group = route->mix_group()) != 0){
|
||||
_session.begin_reversible_command (_("mix group mute change"));
|
||||
_session.add_undo (_session.global_mute_memento (this));
|
||||
Session::GlobalMuteStateCommand *cmd = new Session::GlobalMuteStateCommand (_session, this);
|
||||
mix_group->apply(&Route::set_mute, yn, this);
|
||||
_session.add_redo_no_execute (_session.global_mute_memento(this));
|
||||
cmd->mark();
|
||||
_session.add_command(cmd);
|
||||
_session.commit_reversible_command ();
|
||||
} else {
|
||||
reversibly_apply_route_boolean ("mute change", &Route::set_mute, !route->muted(), this);
|
||||
|
@ -605,9 +616,10 @@ RouteUI::set_mix_group_rec_enable(boost::shared_ptr<Route> route, bool yn)
|
|||
|
||||
if((mix_group = route->mix_group()) != 0){
|
||||
_session.begin_reversible_command (_("mix group rec-enable change"));
|
||||
_session.add_undo (_session.global_record_enable_memento (this));
|
||||
Session::GlobalRecordEnableStateCommand *cmd = new Session::GlobalRecordEnableStateCommand(_session, this);
|
||||
mix_group->apply (&Route::set_record_enable, yn, this);
|
||||
_session.add_redo_no_execute (_session.global_record_enable_memento(this));
|
||||
cmd->mark();
|
||||
_session.add_command(cmd);
|
||||
_session.commit_reversible_command ();
|
||||
} else {
|
||||
reversibly_apply_route_boolean ("rec-enable change", &Route::set_record_enable, !_route->record_enabled(), this);
|
||||
|
|
|
@ -128,6 +128,7 @@ TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisVie
|
|||
|
||||
controls_table.attach (name_hbox, 0, 4, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||
controls_table.show_all ();
|
||||
controls_table.set_no_show_all ();
|
||||
|
||||
controls_vbox.pack_start (controls_table, false, false);
|
||||
controls_vbox.show ();
|
||||
|
|
|
@ -31,17 +31,17 @@ using namespace Gtk;
|
|||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
VSTPluginUI::VSTPluginUI (PluginInsert& pi, VSTPlugin& vp)
|
||||
VSTPluginUI::VSTPluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_ptr<VSTPlugin> vp)
|
||||
: PlugUIBase (pi),
|
||||
vst (vp)
|
||||
{
|
||||
fst_run_editor (vst.fst());
|
||||
fst_run_editor (vst->fst());
|
||||
|
||||
preset_box.pack_end (bypass_button, false, false, 10);
|
||||
preset_box.pack_end (save_button, false, false);
|
||||
preset_box.pack_end (combo, false, false);
|
||||
|
||||
bypass_button.set_active (!insert.active());
|
||||
bypass_button.set_active (!insert->active());
|
||||
|
||||
pack_start (preset_box, false, false);
|
||||
pack_start (socket, true, true);
|
||||
|
@ -55,7 +55,7 @@ VSTPluginUI::~VSTPluginUI ()
|
|||
int
|
||||
VSTPluginUI::get_preferred_height ()
|
||||
{
|
||||
return vst.fst()->height;
|
||||
return vst->fst()->height;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -69,7 +69,7 @@ VSTPluginUI::package (Gtk::Window& win)
|
|||
this assumes that the window's owner understands the XEmbed protocol.
|
||||
*/
|
||||
|
||||
socket.add_id (fst_get_XID (vst.fst()));
|
||||
socket.add_id (fst_get_XID (vst->fst()));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
AUOutputBL.h
|
||||
|
||||
=============================================================================*/
|
||||
#include "AUOutputBL.h"
|
||||
|
||||
/*
|
||||
struct AudioBufferList
|
||||
{
|
||||
UInt32 mNumberBuffers;
|
||||
AudioBuffer mBuffers[1];
|
||||
};
|
||||
struct AudioBuffer
|
||||
{
|
||||
UInt32 mNumberChannels; // number of interleaved channels in the buffer
|
||||
UInt32 mDataByteSize; // the size of the buffer pointed to by mData
|
||||
void* mData; // the pointer to the buffer
|
||||
};
|
||||
*/
|
||||
|
||||
AUOutputBL::AUOutputBL (const CAStreamBasicDescription &inDesc, UInt32 inDefaultNumFrames)
|
||||
: mFormat (inDesc),
|
||||
mBufferMemory(NULL),
|
||||
mBufferList (NULL),
|
||||
mNumberBuffers (0), // keep this here, so can ensure integrity of ABL
|
||||
mBufferSize (0),
|
||||
mFrames(inDefaultNumFrames)
|
||||
{
|
||||
mNumberBuffers = mFormat.IsInterleaved() ? 1 : mFormat.NumberChannels();
|
||||
mBufferList = reinterpret_cast<AudioBufferList*>(new Byte[sizeof(UInt32) + (mNumberBuffers * sizeof(AudioBuffer))]);
|
||||
}
|
||||
|
||||
AUOutputBL::~AUOutputBL()
|
||||
{
|
||||
if (mBufferMemory)
|
||||
delete[] mBufferMemory;
|
||||
|
||||
if (mBufferList)
|
||||
delete [] mBufferList;
|
||||
}
|
||||
|
||||
void AUOutputBL::Prepare (UInt32 inNumFrames, bool inWantNullBufferIfAllocated)
|
||||
{
|
||||
UInt32 channelsPerBuffer = mFormat.IsInterleaved() ? mFormat.NumberChannels() : 1;
|
||||
|
||||
if (mBufferMemory == NULL || inWantNullBufferIfAllocated)
|
||||
{
|
||||
mBufferList->mNumberBuffers = mNumberBuffers;
|
||||
AudioBuffer *buf = &mBufferList->mBuffers[0];
|
||||
for (UInt32 i = 0; i < mNumberBuffers; ++i, ++buf) {
|
||||
buf->mNumberChannels = channelsPerBuffer;
|
||||
buf->mDataByteSize = mFormat.FramesToBytes (inNumFrames);
|
||||
buf->mData = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 nBytes = mFormat.FramesToBytes (inNumFrames);
|
||||
if ((nBytes * mNumberBuffers) > AllocatedBytes())
|
||||
throw OSStatus(-10874);//(kAudioUnitErr_TooManyFramesToProcess);
|
||||
|
||||
mBufferList->mNumberBuffers = mNumberBuffers;
|
||||
AudioBuffer *buf = &mBufferList->mBuffers[0];
|
||||
Byte* p = mBufferMemory;
|
||||
for (UInt32 i = 0; i < mNumberBuffers; ++i, ++buf) {
|
||||
buf->mNumberChannels = channelsPerBuffer;
|
||||
buf->mDataByteSize = nBytes;
|
||||
buf->mData = p;
|
||||
p += mBufferSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AUOutputBL::Allocate (UInt32 inNumFrames)
|
||||
{
|
||||
if (inNumFrames)
|
||||
{
|
||||
UInt32 nBytes = mFormat.FramesToBytes (inNumFrames);
|
||||
|
||||
if (nBytes <= AllocatedBytes())
|
||||
return;
|
||||
|
||||
// align successive buffers for Altivec and to take alternating
|
||||
// cache line hits by spacing them by odd multiples of 16
|
||||
if (mNumberBuffers > 1)
|
||||
nBytes = (nBytes + (0x10 - (nBytes & 0xF))) | 0x10;
|
||||
|
||||
mBufferSize = nBytes;
|
||||
|
||||
UInt32 memorySize = mBufferSize * mNumberBuffers;
|
||||
Byte *newMemory = new Byte[memorySize];
|
||||
memset(newMemory, 0, memorySize); // make buffer "hot"
|
||||
|
||||
Byte *oldMemory = mBufferMemory;
|
||||
mBufferMemory = newMemory;
|
||||
delete[] oldMemory;
|
||||
|
||||
mFrames = inNumFrames;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mBufferMemory) {
|
||||
delete [] mBufferMemory;
|
||||
mBufferMemory = NULL;
|
||||
}
|
||||
mBufferSize = 0;
|
||||
mFrames = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
void AUOutputBL::Print()
|
||||
{
|
||||
printf ("AUOutputBL::Print\n");
|
||||
mFormat.Print();
|
||||
printf ("Num Buffers:%ld, mFrames:%ld, allocatedMemory:%c\n", mBufferList->mNumberBuffers, mFrames, (mBufferMemory != NULL ? 'T' : 'F'));
|
||||
AudioBuffer *buf = &mBufferList->mBuffers[0];
|
||||
for (UInt32 i = 0; i < mBufferList->mNumberBuffers; ++i, ++buf)
|
||||
printf ("\tBuffer:%ld, Size:%ld, Chans:%ld, Buffer:%X\n", i, buf->mDataByteSize, buf->mNumberChannels, int(buf->mData));
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
AUOutputBL.h
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef __AUOutputBL_h__
|
||||
#define __AUOutputBL_h__
|
||||
|
||||
#include "CAStreamBasicDescription.h"
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#else
|
||||
#include <AssertMacros.h>
|
||||
#endif
|
||||
|
||||
// ____________________________________________________________________________
|
||||
//
|
||||
// AUOutputBL - Simple Buffer List wrapper targetted to use with retrieving AU output
|
||||
// Works in one of two ways (both adjustable)... Can use it with NULL pointers, or allocate
|
||||
// memory to receive the data in.
|
||||
|
||||
// Before using this with any call to AudioUnitRender, it needs to be Prepared
|
||||
// as some calls to AudioUnitRender can reset the ABL
|
||||
|
||||
class AUOutputBL {
|
||||
public:
|
||||
|
||||
// you CANNOT use one of these - it will crash!
|
||||
// AUOutputBL ();
|
||||
|
||||
// this is the constructor that you use
|
||||
// it can't be reset once you've constructed it
|
||||
AUOutputBL (const CAStreamBasicDescription &inDesc, UInt32 inDefaultNumFrames = 512);
|
||||
~AUOutputBL();
|
||||
|
||||
void Prepare ()
|
||||
{
|
||||
Prepare (mFrames);
|
||||
}
|
||||
|
||||
// this version can throw if this is an allocted ABL and inNumFrames is > AllocatedFrames()
|
||||
// you can set the bool to true if you want a NULL buffer list even if allocated
|
||||
// inNumFrames must be a valid number (will throw if inNumFrames is 0)
|
||||
void Prepare (UInt32 inNumFrames, bool inWantNullBufferIfAllocated = false);
|
||||
|
||||
AudioBufferList* ABL() { return mBufferList; }
|
||||
|
||||
// You only need to call this if you want to allocate a buffer list
|
||||
// if you want an empty buffer list, just call Prepare()
|
||||
// if you want to dispose previously allocted memory, pass in 0
|
||||
// then you either have an empty buffer list, or you can re-allocate
|
||||
// Memory is kept around if an Allocation request is less than what is currently allocated
|
||||
void Allocate (UInt32 inNumberFrames);
|
||||
|
||||
UInt32 AllocatedFrames() const { return mFrames; }
|
||||
|
||||
const CAStreamBasicDescription& GetFormat() const { return mFormat; }
|
||||
|
||||
#if DEBUG
|
||||
void Print();
|
||||
#endif
|
||||
|
||||
private:
|
||||
UInt32 AllocatedBytes () const { return (mBufferSize * mNumberBuffers); }
|
||||
|
||||
CAStreamBasicDescription mFormat;
|
||||
Byte* mBufferMemory;
|
||||
AudioBufferList* mBufferList;
|
||||
UInt32 mNumberBuffers;
|
||||
UInt32 mBufferSize;
|
||||
UInt32 mFrames;
|
||||
|
||||
// don't want to copy these.. can if you want, but more code to write!
|
||||
AUOutputBL (const AUOutputBL &c) {}
|
||||
AUOutputBL& operator= (const AUOutputBL& c) { return *this; }
|
||||
};
|
||||
|
||||
#endif // __AUOutputBL_h__
|
|
@ -0,0 +1,138 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CAAudioChannelLayout.cpp
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
// Self Include
|
||||
#include "CAAudioChannelLayout.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
//=============================================================================
|
||||
// CAAudioChannelLayout
|
||||
//=============================================================================
|
||||
|
||||
AudioChannelLayout* CAAudioChannelLayout::Create(UInt32 inNumberChannelDescriptions)
|
||||
{
|
||||
UInt32 theSize = CalculateByteSize(inNumberChannelDescriptions);
|
||||
AudioChannelLayout* theAnswer = static_cast<AudioChannelLayout*>(calloc(1, theSize));
|
||||
if(theAnswer != NULL)
|
||||
{
|
||||
SetAllToUnknown(*theAnswer, inNumberChannelDescriptions);
|
||||
}
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
void CAAudioChannelLayout::Destroy(AudioChannelLayout* inChannelLayout)
|
||||
{
|
||||
free(inChannelLayout);
|
||||
}
|
||||
|
||||
void CAAudioChannelLayout::SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions)
|
||||
{
|
||||
outChannelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
|
||||
outChannelLayout.mChannelBitmap = 0;
|
||||
outChannelLayout.mNumberChannelDescriptions = inNumberChannelDescriptions;
|
||||
for(UInt32 theChannelIndex = 0; theChannelIndex < inNumberChannelDescriptions; ++theChannelIndex)
|
||||
{
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelLabel = kAudioChannelLabel_Unknown;
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelFlags = 0;
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[0] = 0;
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[1] = 0;
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator== (const AudioChannelLayout &x, const AudioChannelLayout &y)
|
||||
{
|
||||
// compare based on the number of channel descriptions present
|
||||
// (this may be too strict a comparison if all you care about are matching layout tags)
|
||||
UInt32 theSize1 = CAAudioChannelLayout::CalculateByteSize(x.mNumberChannelDescriptions);
|
||||
UInt32 theSize2 = CAAudioChannelLayout::CalculateByteSize(y.mNumberChannelDescriptions);
|
||||
|
||||
if (theSize1 != theSize2)
|
||||
return false;
|
||||
|
||||
return !memcmp (&x, &y, theSize1);
|
||||
}
|
||||
|
||||
// counting the one bits in a word
|
||||
inline UInt32 CountOnes(UInt32 x)
|
||||
{
|
||||
// secret magic algorithm for counting bits in a word.
|
||||
UInt32 t;
|
||||
x = x - ((x >> 1) & 0x55555555);
|
||||
t = ((x >> 2) & 0x33333333);
|
||||
x = (x & 0x33333333) + t;
|
||||
x = (x + (x >> 4)) & 0x0F0F0F0F;
|
||||
x = x + (x << 8);
|
||||
x = x + (x << 16);
|
||||
return x >> 24;
|
||||
}
|
||||
|
||||
UInt32 CAAudioChannelLayout::NumberChannels (const AudioChannelLayout& inLayout)
|
||||
{
|
||||
if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
|
||||
return inLayout.mNumberChannelDescriptions;
|
||||
|
||||
if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
|
||||
return CountOnes (inLayout.mChannelBitmap);
|
||||
|
||||
return AudioChannelLayoutTag_GetNumberOfChannels(inLayout.mChannelLayoutTag);
|
||||
}
|
||||
|
||||
void CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout)
|
||||
{
|
||||
fprintf (file, "\tTag=0x%lX, ", layout->mChannelLayoutTag);
|
||||
if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
|
||||
fprintf (file, "Using Bitmap:0x%lX\n", layout->mChannelBitmap);
|
||||
else {
|
||||
fprintf (file, "Num Chan Descs=%ld\n", layout->mNumberChannelDescriptions);
|
||||
const AudioChannelDescription *desc = layout->mChannelDescriptions;
|
||||
for (unsigned int i = 0; i < layout->mNumberChannelDescriptions; ++i, ++desc) {
|
||||
fprintf (file, "\t\tLabel=%ld, Flags=0x%lX, ", desc->mChannelLabel, desc->mChannelFlags);
|
||||
fprintf (file, "[az=%f,el=%f,dist=%f]\n", desc->mCoordinates[0], desc->mCoordinates[1], desc->mCoordinates[2]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CAAudioChannelLayout.h
|
||||
|
||||
=============================================================================*/
|
||||
#if !defined(__CAAudioChannelLayout_h__)
|
||||
#define __CAAudioChannelLayout_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
// System Includes
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#include <CoreFoundation.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !HAL_Build
|
||||
#include "CAReferenceCounted.h"
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CAAudioChannelLayout
|
||||
//=============================================================================
|
||||
|
||||
bool operator== (const AudioChannelLayout &x, const AudioChannelLayout &y);
|
||||
|
||||
extern "C" void CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout);
|
||||
|
||||
class CAAudioChannelLayout
|
||||
{
|
||||
// static Construction/Destruction
|
||||
public:
|
||||
static AudioChannelLayout* Create(UInt32 inNumberChannelDescriptions);
|
||||
static void Destroy(AudioChannelLayout* inChannelLayout);
|
||||
static UInt32 CalculateByteSize(UInt32 inNumberChannelDescriptions) {
|
||||
return offsetof(AudioChannelLayout, mChannelDescriptions) + inNumberChannelDescriptions * sizeof(AudioChannelDescription);
|
||||
}
|
||||
static void SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions);
|
||||
static UInt32 NumberChannels(const AudioChannelLayout& inLayout);
|
||||
|
||||
#if !HAL_Build
|
||||
// object methods
|
||||
public:
|
||||
CAAudioChannelLayout ();
|
||||
|
||||
CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround);
|
||||
// if inChooseSurround is false, then symmetrical speaker arrangements
|
||||
// are chosen in place of surround layouts if there is a choice
|
||||
// This call chooses layouts based on the expected defaults in
|
||||
// AudioUnit usage
|
||||
CAAudioChannelLayout (AudioChannelLayoutTag inTag);
|
||||
CAAudioChannelLayout (const CAAudioChannelLayout &c);
|
||||
CAAudioChannelLayout (const AudioChannelLayout* inChannelLayout);
|
||||
~CAAudioChannelLayout();
|
||||
|
||||
CAAudioChannelLayout& operator= (const AudioChannelLayout* inChannelLayout);
|
||||
CAAudioChannelLayout& operator= (const CAAudioChannelLayout& c);
|
||||
bool operator== (const CAAudioChannelLayout &c) const;
|
||||
|
||||
void SetWithTag(AudioChannelLayoutTag inTag);
|
||||
|
||||
bool IsValid() const { return NumberChannels() > 0; }
|
||||
UInt32 Size() const { return mLayoutHolder ? mLayoutHolder->Size() : 0; }
|
||||
|
||||
UInt32 NumberChannels() const { return NumberChannels(Layout()); }
|
||||
|
||||
AudioChannelLayoutTag Tag() const { return Layout().mChannelLayoutTag; }
|
||||
const AudioChannelLayout& Layout() const { return mLayoutHolder->Layout(); }
|
||||
operator const AudioChannelLayout *() const { return &Layout(); }
|
||||
|
||||
void Print () const { Print (stdout); }
|
||||
void Print (FILE* file) const;
|
||||
|
||||
OSStatus Save (CFPropertyListRef *outData) const;
|
||||
OSStatus Restore (CFPropertyListRef &inData);
|
||||
|
||||
private:
|
||||
class ACLRefCounter : public CAReferenceCounted {
|
||||
public:
|
||||
ACLRefCounter (UInt32 inDataSize)
|
||||
{
|
||||
if (inDataSize < offsetof(AudioChannelLayout, mChannelDescriptions))
|
||||
inDataSize = offsetof(AudioChannelLayout, mChannelDescriptions);
|
||||
|
||||
mLayout = static_cast<AudioChannelLayout*>(malloc (inDataSize));
|
||||
memset (mLayout, 0, inDataSize);
|
||||
mByteSize = inDataSize;
|
||||
}
|
||||
|
||||
const AudioChannelLayout & Layout() const { return *mLayout; }
|
||||
|
||||
UInt32 Size () const { return mByteSize; }
|
||||
|
||||
private:
|
||||
AudioChannelLayout *mLayout;
|
||||
UInt32 mByteSize;
|
||||
|
||||
// only the constructors can change the actual state of the layout
|
||||
friend CAAudioChannelLayout::CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround);
|
||||
friend OSStatus CAAudioChannelLayout::Restore (CFPropertyListRef &inData);
|
||||
friend CAAudioChannelLayout& CAAudioChannelLayout::operator= (const AudioChannelLayout* inChannelLayout);
|
||||
friend void CAAudioChannelLayout::SetWithTag(AudioChannelLayoutTag inTag);
|
||||
|
||||
AudioChannelLayout * GetLayout() { return mLayout; }
|
||||
~ACLRefCounter() { if (mLayout) { free(mLayout); mLayout = NULL; } }
|
||||
|
||||
private:
|
||||
ACLRefCounter () : mLayout(NULL) { }
|
||||
ACLRefCounter(const ACLRefCounter& c) : mLayout(NULL) { }
|
||||
ACLRefCounter& operator=(const ACLRefCounter& c) { return *this; }
|
||||
};
|
||||
|
||||
ACLRefCounter *mLayoutHolder;
|
||||
#endif // HAL_Build
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,199 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CAAudioChannelLayoutObject.cpp
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "CAAudioChannelLayout.h"
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <AudioToolbox/AudioFormat.h>
|
||||
#else
|
||||
#include <CoreServices.h>
|
||||
#include <AudioFormat.h>
|
||||
#endif
|
||||
|
||||
|
||||
CAAudioChannelLayout::CAAudioChannelLayout ()
|
||||
{
|
||||
mLayoutHolder = new ACLRefCounter (offsetof(AudioChannelLayout, mChannelDescriptions));
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// CAAudioChannelLayout::CAAudioChannelLayout
|
||||
//=============================================================================
|
||||
CAAudioChannelLayout::CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround)
|
||||
{
|
||||
// this chooses default layouts based on the number of channels...
|
||||
UInt32 theSize = CalculateByteSize (inNumberChannels);
|
||||
|
||||
mLayoutHolder = new ACLRefCounter (theSize);
|
||||
|
||||
AudioChannelLayout* layout = mLayoutHolder->GetLayout();
|
||||
|
||||
layout->mNumberChannelDescriptions = inNumberChannels;
|
||||
|
||||
switch (inNumberChannels)
|
||||
{
|
||||
case 1:
|
||||
layout->mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
|
||||
break;
|
||||
case 2:
|
||||
layout->mChannelLayoutTag = inChooseSurround ? kAudioChannelLayoutTag_Binaural : kAudioChannelLayoutTag_Stereo;
|
||||
break;
|
||||
case 4:
|
||||
layout->mChannelLayoutTag = inChooseSurround ? kAudioChannelLayoutTag_Ambisonic_B_Format : kAudioChannelLayoutTag_AudioUnit_4;
|
||||
break;
|
||||
case 5:
|
||||
layout->mChannelLayoutTag = inChooseSurround ? kAudioChannelLayoutTag_AudioUnit_5_0 : kAudioChannelLayoutTag_AudioUnit_5;
|
||||
break;
|
||||
case 6:
|
||||
layout->mChannelLayoutTag = inChooseSurround ? kAudioChannelLayoutTag_AudioUnit_6_0 : kAudioChannelLayoutTag_AudioUnit_6;
|
||||
break;
|
||||
case 7:
|
||||
layout->mChannelLayoutTag = kAudioChannelLayoutTag_AudioUnit_7_0;
|
||||
break;
|
||||
case 8:
|
||||
layout->mChannelLayoutTag = kAudioChannelLayoutTag_AudioUnit_8;
|
||||
break;
|
||||
default:
|
||||
// here we have a "broken" layout, in the sense that we haven't any idea how to lay this out
|
||||
// the layout itself is all set to zeros
|
||||
// ### no longer true ###
|
||||
SetAllToUnknown(*layout, inNumberChannels);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// CAAudioChannelLayout::CAAudioChannelLayout
|
||||
//=============================================================================
|
||||
CAAudioChannelLayout::CAAudioChannelLayout (AudioChannelLayoutTag inLayoutTag)
|
||||
: mLayoutHolder(NULL)
|
||||
{
|
||||
SetWithTag(inLayoutTag);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// CAAudioChannelLayout::CAAudioChannelLayout
|
||||
//=============================================================================
|
||||
CAAudioChannelLayout::CAAudioChannelLayout (const CAAudioChannelLayout &c)
|
||||
: mLayoutHolder(NULL)
|
||||
{
|
||||
*this = c;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// CAAudioChannelLayout::AudioChannelLayout
|
||||
//=============================================================================
|
||||
CAAudioChannelLayout::CAAudioChannelLayout (const AudioChannelLayout* inChannelLayout)
|
||||
: mLayoutHolder(NULL)
|
||||
{
|
||||
*this = inChannelLayout;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// CAAudioChannelLayout::~CAAudioChannelLayout
|
||||
//=============================================================================
|
||||
CAAudioChannelLayout::~CAAudioChannelLayout ()
|
||||
{
|
||||
if (mLayoutHolder) {
|
||||
mLayoutHolder->release();
|
||||
mLayoutHolder = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// CAAudioChannelLayout::CAAudioChannelLayout
|
||||
//=============================================================================
|
||||
CAAudioChannelLayout& CAAudioChannelLayout::operator= (const CAAudioChannelLayout &c)
|
||||
{
|
||||
if (mLayoutHolder != c.mLayoutHolder) {
|
||||
if (mLayoutHolder)
|
||||
mLayoutHolder->release();
|
||||
|
||||
if ((mLayoutHolder = c.mLayoutHolder) != NULL)
|
||||
mLayoutHolder->retain();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CAAudioChannelLayout& CAAudioChannelLayout::operator= (const AudioChannelLayout* inChannelLayout)
|
||||
{
|
||||
if (mLayoutHolder)
|
||||
mLayoutHolder->release();
|
||||
|
||||
UInt32 theSize = CalculateByteSize (inChannelLayout->mNumberChannelDescriptions);
|
||||
|
||||
mLayoutHolder = new ACLRefCounter (theSize);
|
||||
|
||||
memcpy(mLayoutHolder->mLayout, inChannelLayout, theSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CAAudioChannelLayout::SetWithTag(AudioChannelLayoutTag inTag)
|
||||
{
|
||||
if (mLayoutHolder)
|
||||
mLayoutHolder->release();
|
||||
|
||||
mLayoutHolder = new ACLRefCounter(offsetof(AudioChannelLayout, mChannelDescriptions[0]));
|
||||
AudioChannelLayout* layout = mLayoutHolder->GetLayout();
|
||||
layout->mChannelLayoutTag = inTag;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// CAAudioChannelLayout::operator==
|
||||
//=============================================================================
|
||||
bool CAAudioChannelLayout::operator== (const CAAudioChannelLayout &c) const
|
||||
{
|
||||
if (mLayoutHolder == c.mLayoutHolder)
|
||||
return true;
|
||||
return Layout() == c.Layout();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// CAAudioChannelLayout::Print
|
||||
//=============================================================================
|
||||
void CAAudioChannelLayout::Print (FILE* file) const
|
||||
{
|
||||
CAShowAudioChannelLayout (file, &Layout());
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,383 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CAAudioUnit.h
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef __CAAudioUnit_h__
|
||||
#define __CAAudioUnit_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <CoreAudio/CoreAudio.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioToolbox/AUGraph.h>
|
||||
#else
|
||||
#include <ConditionalMacros.h>
|
||||
#include <CoreServices.h>
|
||||
#include <CoreAudioTypes.h>
|
||||
#include <AudioUnit.h>
|
||||
#include <AUGraph.h>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include "CAStreamBasicDescription.h"
|
||||
#include "CAComponent.h"
|
||||
#include "CAAudioChannelLayout.h"
|
||||
|
||||
// defined below
|
||||
class CAAUChanHelper;
|
||||
|
||||
// These constructors will NOT throw exceptions - so "check" after creation if AU IsValid()
|
||||
// The destructor will NOT automatically close the AU down
|
||||
// This state should be managed by the Caller
|
||||
// once closed, the unit represented by this object is no longer valid
|
||||
// it is up to the user of this object to ensure its validity is in sync
|
||||
// if it is removed from a graph
|
||||
|
||||
// methods that can significantly change the state of the AU (like its format) are
|
||||
// NOT const whereas those that don't change the externally related state of the AU are not const
|
||||
|
||||
class CAAudioUnit {
|
||||
public:
|
||||
typedef std::vector<AudioChannelLayoutTag> ChannelTagVector;
|
||||
typedef ChannelTagVector::iterator ChannelTagVectorIter;
|
||||
|
||||
public:
|
||||
CAAudioUnit ()
|
||||
: mDataPtr(0) {}
|
||||
|
||||
CAAudioUnit (const AudioUnit& inUnit);
|
||||
|
||||
CAAudioUnit (const AUNode &inNode, const AudioUnit& inUnit);
|
||||
|
||||
CAAudioUnit (const CAAudioUnit& y)
|
||||
: mDataPtr(0) { *this = y; }
|
||||
|
||||
static OSStatus Open (const CAComponent& inComp, CAAudioUnit &outUnit);
|
||||
|
||||
~CAAudioUnit ();
|
||||
|
||||
|
||||
CAAudioUnit& operator= (const CAAudioUnit& y);
|
||||
|
||||
bool operator== (const CAAudioUnit& y) const;
|
||||
|
||||
bool operator== (const AudioUnit& y) const;
|
||||
|
||||
#pragma mark __State Management
|
||||
bool IsValid () const;
|
||||
|
||||
AudioUnit AU() const;
|
||||
operator AudioUnit () const { return AU(); }
|
||||
|
||||
const CAComponent& Comp() const { return mComp; }
|
||||
|
||||
bool FromAUGraph () const { return GetAUNode() != 0 || GetAUNode() != -1; }
|
||||
|
||||
AUNode GetAUNode () const;
|
||||
operator AUNode () const { return GetAUNode(); }
|
||||
|
||||
#pragma mark __API Wrapper
|
||||
OSStatus Initialize() const { return AudioUnitInitialize(AU()); }
|
||||
OSStatus Uninitialize() const { return AudioUnitUninitialize(AU()); }
|
||||
OSStatus GetPropertyInfo(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
|
||||
UInt32 *outDataSize, Boolean *outWritable) const
|
||||
{
|
||||
return AudioUnitGetPropertyInfo(AU(), propID, scope, element, outDataSize, outWritable);
|
||||
}
|
||||
OSStatus GetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
|
||||
void *outData, UInt32 *ioDataSize) const
|
||||
{
|
||||
return AudioUnitGetProperty(AU(), propID, scope, element, outData, ioDataSize);
|
||||
}
|
||||
OSStatus SetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
|
||||
const void *inData, UInt32 inDataSize)
|
||||
{
|
||||
return AudioUnitSetProperty(AU(), propID, scope, element, inData, inDataSize);
|
||||
}
|
||||
OSStatus SetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
|
||||
Float32 value, UInt32 bufferOffsetFrames=0);
|
||||
|
||||
OSStatus GetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
|
||||
Float32 &outValue) const;
|
||||
|
||||
OSStatus Render (AudioUnitRenderActionFlags * ioActionFlags,
|
||||
const AudioTimeStamp * inTimeStamp,
|
||||
UInt32 inOutputBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList * ioData);
|
||||
|
||||
OSStatus Reset (AudioUnitScope scope, AudioUnitElement element)
|
||||
{
|
||||
return AudioUnitReset (AU(), scope, element);
|
||||
}
|
||||
OSStatus GlobalReset ()
|
||||
{
|
||||
return AudioUnitReset (AU(), kAudioUnitScope_Global, 0);
|
||||
}
|
||||
|
||||
OSStatus Preroll (UInt32 inFrameSize);
|
||||
|
||||
OSStatus AddRenderNotify (AURenderCallback inProc, void *inProcRefCon)
|
||||
{
|
||||
return AudioUnitAddRenderNotify (AU(), inProc, inProcRefCon);
|
||||
}
|
||||
|
||||
OSStatus RemoveRenderNotify (AURenderCallback inProc, void *inProcRefCon)
|
||||
{
|
||||
return AudioUnitRemoveRenderNotify (AU(), inProc, inProcRefCon);
|
||||
}
|
||||
|
||||
|
||||
// Fast dispatch support for MIDI Effects or Music Devices
|
||||
OSStatus MIDIEvent (UInt32 inStatus,
|
||||
UInt32 inData1,
|
||||
UInt32 inData2,
|
||||
UInt32 inOffsetSampleFrame);
|
||||
|
||||
// uses the default VoiceForGroup value - this is the normal case
|
||||
OSStatus StartNote (MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID * outNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame,
|
||||
const MusicDeviceNoteParams * inParams)
|
||||
{
|
||||
return StartNote (kMusicNoteEvent_UseGroupInstrument,
|
||||
inGroupID, outNoteInstanceID,
|
||||
inOffsetSampleFrame, inParams);
|
||||
}
|
||||
|
||||
OSStatus StartNote (MusicDeviceInstrumentID inInstrument,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID * outNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame,
|
||||
const MusicDeviceNoteParams * inParams);
|
||||
|
||||
OSStatus StopNote (MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID inNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame);
|
||||
|
||||
#pragma mark __Format Utilities
|
||||
// typically you ask this about an AU
|
||||
// These Questions are asking about Input and Output...
|
||||
|
||||
// These ones just say whether an AU can do a single combination of channels
|
||||
// and is fine if the AU has a single output (and if an input, a single input)
|
||||
bool CanDo (int inChannelsInOut) const
|
||||
{
|
||||
return CanDo (inChannelsInOut, inChannelsInOut);
|
||||
}
|
||||
|
||||
bool CanDo ( int inChannelsIn,
|
||||
int inChannelsOut) const;
|
||||
|
||||
// This version does a more thorough test for ANY AU with ANY ins/outs
|
||||
// you pass in the channel helper (for the current element count on that scope)
|
||||
|
||||
bool CanDo ( const CAAUChanHelper &input,
|
||||
const CAAUChanHelper &output) const;
|
||||
|
||||
bool SupportsNumChannels () const;
|
||||
|
||||
bool HasChannelLayouts (AudioUnitScope inScope,
|
||||
AudioUnitElement inEl) const;
|
||||
|
||||
bool GetChannelLayouts (AudioUnitScope inScope,
|
||||
AudioUnitElement inEl,
|
||||
ChannelTagVector &outChannelVector) const;
|
||||
|
||||
OSStatus GetChannelLayout (AudioUnitScope inScope,
|
||||
AudioUnitElement inEl,
|
||||
CAAudioChannelLayout &outLayout) const;
|
||||
|
||||
OSStatus SetChannelLayout (AudioUnitScope inScope,
|
||||
AudioUnitElement inEl,
|
||||
CAAudioChannelLayout &inLayout);
|
||||
|
||||
OSStatus SetChannelLayout (AudioUnitScope inScope,
|
||||
AudioUnitElement inEl,
|
||||
AudioChannelLayout &inLayout,
|
||||
UInt32 inSize);
|
||||
|
||||
OSStatus ClearChannelLayout (AudioUnitScope inScope,
|
||||
AudioUnitElement inEl);
|
||||
|
||||
OSStatus GetFormat (AudioUnitScope inScope,
|
||||
AudioUnitElement inEl,
|
||||
AudioStreamBasicDescription &outFormat) const;
|
||||
// if an AudioChannelLayout is either required or set, this call can fail
|
||||
// and the SetChannelLayout call should be used to set the format
|
||||
OSStatus SetFormat (AudioUnitScope inScope,
|
||||
AudioUnitElement inEl,
|
||||
const AudioStreamBasicDescription &inFormat);
|
||||
|
||||
OSStatus GetSampleRate (AudioUnitScope inScope,
|
||||
AudioUnitElement inEl,
|
||||
Float64 &outRate) const;
|
||||
OSStatus SetSampleRate (AudioUnitScope inScope,
|
||||
AudioUnitElement inEl,
|
||||
Float64 inRate);
|
||||
|
||||
// this sets the sample rate on all in/out buses of the AU
|
||||
OSStatus SetSampleRate (Float64 inSampleRate);
|
||||
|
||||
OSStatus NumberChannels (AudioUnitScope inScope,
|
||||
AudioUnitElement inEl,
|
||||
UInt32 &outChans) const;
|
||||
|
||||
OSStatus GetNumberChannels (AudioUnitScope inScope,
|
||||
AudioUnitElement inEl,
|
||||
UInt32 &outChans) const
|
||||
{
|
||||
return NumberChannels (inScope, inEl, outChans);
|
||||
}
|
||||
|
||||
OSStatus SetNumberChannels (AudioUnitScope inScope,
|
||||
AudioUnitElement inEl,
|
||||
UInt32 inChans);
|
||||
|
||||
OSStatus IsElementCountWritable (AudioUnitScope inScope, bool &outWritable) const;
|
||||
|
||||
OSStatus GetElementCount (AudioUnitScope inScope, UInt32 &outCount) const;
|
||||
|
||||
OSStatus SetElementCount (AudioUnitScope inScope, UInt32 inCount);
|
||||
|
||||
// value of -1 for outTotalNumChannels indicates no restriction on num channels
|
||||
// for ex. the Matrix Mixer satisfies this (its in/out element count is writable, and can be set to
|
||||
// any number of channels.
|
||||
// outTotalNumChannels is only valid if method returns true...
|
||||
bool HasDynamicInputs (SInt32 &outTotalNumChannels) const
|
||||
{
|
||||
return HasDynamicScope (kAudioUnitScope_Input, outTotalNumChannels);
|
||||
}
|
||||
|
||||
bool HasDynamicOutputs (SInt32 &outTotalNumChannels) const
|
||||
{
|
||||
return HasDynamicScope (kAudioUnitScope_Output, outTotalNumChannels);
|
||||
}
|
||||
|
||||
// here, if the in (or out) elements are dynamic, then you supply the number of elements
|
||||
// you want on in (or out) scope, and the number of channels on each consecutive element
|
||||
OSStatus ConfigureDynamicInput (UInt32 inNumElements, UInt32 *inChannelsPerElement, Float64 inSampleRate)
|
||||
{
|
||||
return ConfigureDynamicScope (kAudioUnitScope_Input, inNumElements, inChannelsPerElement, inSampleRate);
|
||||
}
|
||||
|
||||
OSStatus ConfigureDynamicOutput (UInt32 inNumElements, UInt32 *inChannelsPerElement, Float64 inSampleRate)
|
||||
{
|
||||
return ConfigureDynamicScope (kAudioUnitScope_Output, inNumElements, inChannelsPerElement, inSampleRate);
|
||||
}
|
||||
|
||||
bool CanBypass () const;
|
||||
|
||||
bool GetBypass () const;
|
||||
|
||||
OSStatus SetBypass (bool inBypass) const;
|
||||
|
||||
Float64 Latency () const;
|
||||
|
||||
// these calls just deal with the global preset state
|
||||
// you could rescope them to deal with presets on the part scope
|
||||
OSStatus GetAUPreset (CFPropertyListRef &outData) const;
|
||||
|
||||
OSStatus SetAUPreset (CFPropertyListRef &inData);
|
||||
|
||||
OSStatus GetPresentPreset (AUPreset &outData) const;
|
||||
|
||||
OSStatus SetPresentPreset (AUPreset &inData);
|
||||
|
||||
bool HasCustomView () const;
|
||||
|
||||
#pragma mark __Print
|
||||
void Print () const { Print (stdout); }
|
||||
void Print (FILE* file) const;
|
||||
|
||||
private:
|
||||
CAComponent mComp;
|
||||
|
||||
class AUState;
|
||||
AUState* mDataPtr;
|
||||
|
||||
// this can throw - so wrap this up in a static that returns a result code...
|
||||
CAAudioUnit (const CAComponent& inComp);
|
||||
|
||||
bool HasDynamicScope (AudioUnitScope inScope, SInt32 &outTotalNumChannels) const;
|
||||
OSStatus ConfigureDynamicScope (AudioUnitScope inScope,
|
||||
UInt32 inNumElements,
|
||||
UInt32 *inChannelsPerElement,
|
||||
Float64 inSampleRate);
|
||||
bool ValidateChannelPair (int inChannelsIn,
|
||||
int inChannelsOut,
|
||||
const AUChannelInfo * info,
|
||||
UInt32 numChanInfo) const;
|
||||
|
||||
bool ValidateDynamicScope (AudioUnitScope inScope,
|
||||
SInt32 &outTotalNumChannels,
|
||||
const AUChannelInfo * info,
|
||||
UInt32 numInfo) const;
|
||||
bool CheckOneSide (const CAAUChanHelper &inHelper,
|
||||
bool checkOutput,
|
||||
const AUChannelInfo *info,
|
||||
UInt32 numInfo) const;
|
||||
|
||||
};
|
||||
|
||||
class CAAUChanHelper {
|
||||
public:
|
||||
CAAUChanHelper()
|
||||
: mChans(mStaticChans), mNumEls(0), mDidAllocate(false)
|
||||
{
|
||||
memset (mChans, 0, sizeof(UInt32) * 8);
|
||||
}
|
||||
CAAUChanHelper(const CAAudioUnit &inAU, AudioUnitScope inScope);
|
||||
CAAUChanHelper (const CAAUChanHelper &c) :mChans(mStaticChans), mNumEls(0), mDidAllocate(false) { *this = c; }
|
||||
|
||||
~CAAUChanHelper();
|
||||
|
||||
CAAUChanHelper& operator= (const CAAUChanHelper &c);
|
||||
|
||||
UInt32 * mChans;
|
||||
UInt32 mNumEls;
|
||||
|
||||
private:
|
||||
UInt32 mStaticChans[8];
|
||||
bool mDidAllocate;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,478 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CACFDictionary.cpp
|
||||
CAAudioEngine
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
// Self Include
|
||||
#include "CACFDictionary.h"
|
||||
|
||||
// PublicUtility Includes
|
||||
#include "CACFString.h"
|
||||
#include "CACFNumber.h"
|
||||
|
||||
//=============================================================================
|
||||
// CACFDictionary
|
||||
//=============================================================================
|
||||
|
||||
bool CACFDictionary::HasKey(const CFStringRef inKey) const
|
||||
{
|
||||
return CFDictionaryContainsKey(mCFDictionary, inKey) != 0;
|
||||
}
|
||||
|
||||
UInt32 CACFDictionary::Size () const
|
||||
{
|
||||
return CFDictionaryGetCount(mCFDictionary);
|
||||
}
|
||||
|
||||
void CACFDictionary::GetKeys (const void **keys) const
|
||||
{
|
||||
CFDictionaryGetKeysAndValues(mCFDictionary, keys, NULL);
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetBool(const CFStringRef inKey, bool& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFBooleanGetTypeID()))
|
||||
{
|
||||
outValue = CFBooleanGetValue(static_cast<CFBooleanRef>(theValue));
|
||||
theAnswer = true;
|
||||
}
|
||||
else if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
SInt32 theNumericValue = 0;
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &theNumericValue);
|
||||
outValue = theNumericValue != 0;
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetSInt32(const CFStringRef inKey, SInt32& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetUInt32(const CFStringRef inKey, UInt32& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetSInt64(const CFStringRef inKey, SInt64& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &outValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetUInt64(const CFStringRef inKey, UInt64& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &outValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetFloat32(const CFStringRef inKey, Float32& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberFloat32Type, &outValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetFloat64(const CFStringRef inKey, Float64& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberFloat64Type, &outValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetString(const CFStringRef inKey, CFStringRef& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
|
||||
{
|
||||
outValue = static_cast<CFStringRef>(theValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetArray(const CFStringRef inKey, CFArrayRef& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFArrayGetTypeID()))
|
||||
{
|
||||
outValue = static_cast<CFArrayRef>(theValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetDictionary(const CFStringRef inKey, CFDictionaryRef& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFDictionaryGetTypeID()))
|
||||
{
|
||||
outValue = static_cast<CFDictionaryRef>(theValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetData(const CFStringRef inKey, CFDataRef& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFDataGetTypeID()))
|
||||
{
|
||||
outValue = static_cast<CFDataRef>(theValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetCFType(const CFStringRef inKey, CFTypeRef& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mCFDictionary != NULL)
|
||||
{
|
||||
outValue = CFDictionaryGetValue(mCFDictionary, inKey);
|
||||
theAnswer = (outValue != NULL);
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetCFTypeWithCStringKey(const char* inKey, CFTypeRef& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mCFDictionary != NULL)
|
||||
{
|
||||
CACFString theKey(inKey);
|
||||
if(theKey.IsValid())
|
||||
{
|
||||
theAnswer = GetCFType(theKey.GetCFString(), outValue);
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddSInt32(const CFStringRef inKey, SInt32 inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL))
|
||||
{
|
||||
CACFNumber theValue(inValue);
|
||||
theAnswer = AddCFType(inKey, theValue.GetCFNumber());
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddUInt32(const CFStringRef inKey, UInt32 inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL))
|
||||
{
|
||||
CACFNumber theValue(inValue);
|
||||
theAnswer = AddCFType(inKey, theValue.GetCFNumber());
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddSInt64(const CFStringRef inKey, SInt64 inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL))
|
||||
{
|
||||
CACFNumber theValue(inValue);
|
||||
theAnswer = AddCFType(inKey, theValue.GetCFNumber());
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddUInt64(const CFStringRef inKey, UInt64 inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL))
|
||||
{
|
||||
CACFNumber theValue(inValue);
|
||||
theAnswer = AddCFType(inKey, theValue.GetCFNumber());
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddFloat32(const CFStringRef inKey, Float32 inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL))
|
||||
{
|
||||
CACFNumber theValue(inValue);
|
||||
theAnswer = AddCFType(inKey, theValue.GetCFNumber());
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddFloat64(const CFStringRef inKey, Float64 inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL))
|
||||
{
|
||||
CACFNumber theValue(inValue);
|
||||
theAnswer = AddCFType(inKey, theValue.GetCFNumber());
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddNumber(const CFStringRef inKey, const CFNumberRef inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL))
|
||||
{
|
||||
theAnswer = AddCFType(inKey, inValue);
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddString(const CFStringRef inKey, const CFStringRef inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL))
|
||||
{
|
||||
theAnswer = AddCFType(inKey, inValue);
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddArray(const CFStringRef inKey, const CFArrayRef inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL))
|
||||
{
|
||||
theAnswer = AddCFType(inKey, inValue);
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddDictionary(const CFStringRef inKey, const CFDictionaryRef inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL))
|
||||
{
|
||||
theAnswer = AddCFType(inKey, inValue);
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddData(const CFStringRef inKey, const CFDataRef inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL))
|
||||
{
|
||||
theAnswer = AddCFType(inKey, inValue);
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddCFType(const CFStringRef inKey, const CFTypeRef inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL))
|
||||
{
|
||||
CFDictionarySetValue(mCFDictionary, inKey, inValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddCFTypeWithCStringKey(const char* inKey, const CFTypeRef inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL))
|
||||
{
|
||||
CACFString theKey(inKey);
|
||||
if(theKey.IsValid())
|
||||
{
|
||||
theAnswer = AddCFType(theKey.GetCFString(), inValue);
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddCString(const CFStringRef inKey, const char* inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL))
|
||||
{
|
||||
CACFString theValue(inValue);
|
||||
if(theValue.IsValid())
|
||||
{
|
||||
theAnswer = AddCFType(inKey, theValue.GetCFString());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CACFDictionary.h
|
||||
|
||||
=============================================================================*/
|
||||
#if !defined(__CACFDictionary_h__)
|
||||
#define __CACFDictionary_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
// System Includes
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#else
|
||||
#include <CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CACFDictionary
|
||||
//=============================================================================
|
||||
|
||||
class CACFDictionary
|
||||
{
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CACFDictionary(bool inRelease) : mCFDictionary(CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)), mRelease(inRelease), mMutable(true) {}
|
||||
CACFDictionary(const CFDictionaryRef inCFDictionary, bool inRelease) : mCFDictionary(const_cast<CFMutableDictionaryRef>(inCFDictionary)), mRelease(inRelease), mMutable(true) {}
|
||||
CACFDictionary(const CFMutableDictionaryRef inCFDictionary, bool inRelease) : mCFDictionary(inCFDictionary), mRelease(inRelease), mMutable(true) {}
|
||||
CACFDictionary(const CACFDictionary& inDictionary) : mCFDictionary(inDictionary.mCFDictionary), mRelease(inDictionary.mRelease), mMutable(inDictionary.mMutable) { if(mRelease && (mCFDictionary != NULL)) { CFRetain(mCFDictionary); } }
|
||||
CACFDictionary& operator=(const CACFDictionary& inDictionary) { mCFDictionary = inDictionary.mCFDictionary; mRelease = inDictionary.mRelease; mMutable = inDictionary.mMutable; if(mRelease && (mCFDictionary != NULL)) { CFRetain(mCFDictionary); } return *this; }
|
||||
~CACFDictionary() { if(mRelease && (mCFDictionary != NULL)) { CFRelease(mCFDictionary); } }
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
bool IsValid() const { return mCFDictionary != NULL; }
|
||||
bool IsMutable() const { return mMutable;}
|
||||
bool CanModify() const { return mMutable && (mCFDictionary != NULL); }
|
||||
|
||||
bool WillRelease() const { return mRelease; }
|
||||
void ShouldRelease(bool inRelease) { mRelease = inRelease; }
|
||||
|
||||
CFDictionaryRef GetDict() const { return mCFDictionary; }
|
||||
CFDictionaryRef GetCFDictionary() const { return mCFDictionary; }
|
||||
CFDictionaryRef CopyCFDictionary() const { if(mCFDictionary != NULL) { CFRetain(mCFDictionary); } return mCFDictionary; }
|
||||
|
||||
CFMutableDictionaryRef GetMutableDict() { return mCFDictionary; }
|
||||
CFMutableDictionaryRef GetCFMutableDictionary() const { return mCFDictionary; }
|
||||
CFMutableDictionaryRef CopyCFMutableDictionary() const { if(mCFDictionary != NULL) { CFRetain(mCFDictionary); } return mCFDictionary; }
|
||||
void SetCFMutableDictionaryFromCopy(CFDictionaryRef inDictionary, bool inRelease = true) { if(mRelease && (mCFDictionary != NULL)) { CFRelease(mCFDictionary); } mCFDictionary = CFDictionaryCreateMutableCopy(NULL, 0, inDictionary); mMutable = true; mRelease = inRelease; }
|
||||
|
||||
CFPropertyListRef AsPropertyList() const { return mCFDictionary; }
|
||||
OSStatus GetDictIfMutable(CFMutableDictionaryRef& outDict) const { OSStatus theAnswer = -1; if(mMutable) { outDict = mCFDictionary; theAnswer = 0; } return theAnswer; }
|
||||
|
||||
// Item Operations
|
||||
public:
|
||||
bool HasKey(const CFStringRef inKey) const;
|
||||
UInt32 Size() const;
|
||||
void GetKeys(const void** keys) const;
|
||||
|
||||
bool GetBool(const CFStringRef inKey, bool& outValue) const;
|
||||
bool GetSInt32(const CFStringRef inKey, SInt32& outValue) const;
|
||||
bool GetUInt32(const CFStringRef inKey, UInt32& outValue) const;
|
||||
bool GetSInt64(const CFStringRef inKey, SInt64& outValue) const;
|
||||
bool GetUInt64(const CFStringRef inKey, UInt64& outValue) const;
|
||||
bool GetFloat32(const CFStringRef inKey, Float32& outValue) const;
|
||||
bool GetFloat64(const CFStringRef inKey, Float64& outValue) const;
|
||||
bool GetString(const CFStringRef inKey, CFStringRef& outValue) const;
|
||||
bool GetArray(const CFStringRef inKey, CFArrayRef& outValue) const;
|
||||
bool GetDictionary(const CFStringRef inKey, CFDictionaryRef& outValue) const;
|
||||
bool GetData(const CFStringRef inKey, CFDataRef& outValue) const;
|
||||
bool GetCFType(const CFStringRef inKey, CFTypeRef& outValue) const;
|
||||
|
||||
bool GetCFTypeWithCStringKey(const char* inKey, CFTypeRef& outValue) const;
|
||||
|
||||
bool AddSInt32(const CFStringRef inKey, SInt32 inValue);
|
||||
bool AddUInt32(const CFStringRef inKey, UInt32 inValue);
|
||||
bool AddSInt64(const CFStringRef inKey, SInt64 inValue);
|
||||
bool AddUInt64(const CFStringRef inKey, UInt64 inValue);
|
||||
bool AddFloat32(const CFStringRef inKey, Float32 inValue);
|
||||
bool AddFloat64(const CFStringRef inKey, Float64 inValue);
|
||||
bool AddNumber(const CFStringRef inKey, const CFNumberRef inValue);
|
||||
bool AddString(const CFStringRef inKey, const CFStringRef inValue);
|
||||
bool AddArray(const CFStringRef inKey, const CFArrayRef inValue);
|
||||
bool AddDictionary(const CFStringRef inKey, const CFDictionaryRef inValue);
|
||||
bool AddData(const CFStringRef inKey, const CFDataRef inValue);
|
||||
bool AddCFType(const CFStringRef inKey, const CFTypeRef inValue);
|
||||
|
||||
bool AddCFTypeWithCStringKey(const char* inKey, const CFTypeRef inValue);
|
||||
bool AddCString(const CFStringRef inKey, const char* inValue);
|
||||
|
||||
void Clear() { if(CanModify()) { CFDictionaryRemoveAllValues(mCFDictionary); } }
|
||||
|
||||
void Show() { CFShow(mCFDictionary); }
|
||||
|
||||
// Implementation
|
||||
private:
|
||||
CFMutableDictionaryRef mCFDictionary;
|
||||
bool mRelease;
|
||||
bool mMutable;
|
||||
};
|
||||
|
||||
#endif //__CACFDictionary_h__
|
|
@ -0,0 +1,65 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CACFNumber.cp
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#include "CACFNumber.h"
|
||||
|
||||
//=============================================================================
|
||||
// CACFNumber
|
||||
//=============================================================================
|
||||
|
||||
Float32 CACFNumber::GetFixed32() const
|
||||
{
|
||||
SInt32 theFixedValue = GetSInt32();
|
||||
|
||||
// this is a 16.16 value so convert it to a float
|
||||
Float32 theSign = theFixedValue < 0 ? -1.0 : 1.0;
|
||||
theFixedValue *= (SInt32)theSign;
|
||||
Float32 theWholePart = (theFixedValue & 0x7FFF0000) >> 16;
|
||||
Float32 theFractPart = theFixedValue & 0x0000FFFF;
|
||||
theFractPart /= 65536.0;
|
||||
|
||||
return theSign * (theWholePart + theFractPart);
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CACFNumber.h
|
||||
|
||||
=============================================================================*/
|
||||
#if !defined(__CACFNumber_h__)
|
||||
#define __CACFNumber_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <CoreFoundation/CFNumber.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#include <CFNumber.h>
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CACFNumber
|
||||
//=============================================================================
|
||||
|
||||
class CACFNumber
|
||||
{
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CACFNumber(CFNumberRef inCFNumber, bool inWillRelease = true) : mCFNumber(inCFNumber), mWillRelease(inWillRelease) {}
|
||||
CACFNumber(SInt32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt32Type, &inValue)), mWillRelease(true) {}
|
||||
CACFNumber(UInt32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt32Type, &inValue)), mWillRelease(true) {}
|
||||
CACFNumber(SInt64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt64Type, &inValue)), mWillRelease(true) {}
|
||||
CACFNumber(UInt64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt64Type, &inValue)), mWillRelease(true) {}
|
||||
CACFNumber(Float32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberFloat32Type, &inValue)), mWillRelease(true) {}
|
||||
CACFNumber(Float64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberFloat64Type, &inValue)), mWillRelease(true) {}
|
||||
~CACFNumber() { Release(); }
|
||||
CACFNumber(const CACFNumber& inNumber) : mCFNumber(inNumber.mCFNumber), mWillRelease(inNumber.mWillRelease) { Retain(); }
|
||||
CACFNumber& operator=(const CACFNumber& inNumber) { Release(); mCFNumber = inNumber.mCFNumber; mWillRelease = inNumber.mWillRelease; Retain(); return *this; }
|
||||
CACFNumber& operator=(CFNumberRef inCFNumber) { Release(); mCFNumber = inCFNumber; mWillRelease = true; return *this; }
|
||||
|
||||
private:
|
||||
void Retain() { if(mWillRelease && (mCFNumber != NULL)) { CFRetain(mCFNumber); } }
|
||||
void Release() { if(mWillRelease && (mCFNumber != NULL)) { CFRelease(mCFNumber); } }
|
||||
|
||||
CFNumberRef mCFNumber;
|
||||
bool mWillRelease;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void AllowRelease() { mWillRelease = true; }
|
||||
void DontAllowRelease() { mWillRelease = false; }
|
||||
bool IsValid() { return mCFNumber != NULL; }
|
||||
|
||||
// Value Access
|
||||
public:
|
||||
CFNumberRef GetCFNumber() const { return mCFNumber; }
|
||||
CFNumberRef CopyCFNumber() const { if(mCFNumber != NULL) { CFRetain(mCFNumber); } return mCFNumber; }
|
||||
|
||||
SInt8 GetSInt8() const { SInt8 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt8Type, &theAnswer); } return theAnswer; }
|
||||
SInt32 GetSInt32() const { SInt32 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt32Type, &theAnswer); } return theAnswer; }
|
||||
Float32 GetFloat32() const { Float32 theAnswer = 0.0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberFloat32Type, &theAnswer); } return theAnswer; }
|
||||
Float32 GetFixed32() const;
|
||||
SInt64 GetSInt64() const { SInt64 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt64Type, &theAnswer); } return theAnswer; }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,106 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CACFString.cp
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#include "CACFString.h"
|
||||
|
||||
//=============================================================================
|
||||
// CACFString
|
||||
//=============================================================================
|
||||
|
||||
UInt32 CACFString::GetStringByteLength(CFStringRef inCFString, CFStringEncoding inEncoding)
|
||||
{
|
||||
UInt32 theAnswer = 0;
|
||||
|
||||
if(inCFString != NULL)
|
||||
{
|
||||
CFRange theRange = { 0, CFStringGetLength(inCFString) };
|
||||
CFStringGetBytes(inCFString, theRange, inEncoding, 0, false, NULL, 0x7FFFFFFF, (CFIndex*)&theAnswer);
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
void CACFString::GetCString(CFStringRef inCFString, char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding)
|
||||
{
|
||||
if(ioStringSize > 0)
|
||||
{
|
||||
if(inCFString != NULL)
|
||||
{
|
||||
CFIndex theLength = 0;
|
||||
CFRange theRange = { 0, CFStringGetLength(inCFString) };
|
||||
CFStringGetBytes(inCFString, theRange, inEncoding, 0, false, (UInt8*)outString, ioStringSize - 1, &theLength);
|
||||
outString[theLength] = 0;
|
||||
ioStringSize = theLength + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
outString[0] = 0;
|
||||
ioStringSize = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CACFString::GetUnicodeString(CFStringRef inCFString, UInt16* outString, UInt32& ioStringSize)
|
||||
{
|
||||
if(ioStringSize > 0)
|
||||
{
|
||||
if(inCFString != NULL)
|
||||
{
|
||||
CFRange theStringRange = { 0, CFStringGetLength(inCFString) };
|
||||
if(static_cast<UInt32>(theStringRange.length) > ioStringSize)
|
||||
{
|
||||
theStringRange.length = ioStringSize;
|
||||
}
|
||||
CFStringGetCharacters(inCFString, theStringRange, outString);
|
||||
ioStringSize = theStringRange.length;
|
||||
}
|
||||
else
|
||||
{
|
||||
outString[0] = 0;
|
||||
ioStringSize = 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CACFString.h
|
||||
|
||||
=============================================================================*/
|
||||
#if !defined(__CACFString_h__)
|
||||
#define __CACFString_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <CoreFoundation/CFString.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#include <CFString.h>
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CACFString
|
||||
//=============================================================================
|
||||
|
||||
class CACFString
|
||||
{
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CACFString() : mCFString(NULL), mWillRelease(true) {}
|
||||
CACFString(CFStringRef inCFString, bool inWillRelease = true) : mCFString(inCFString), mWillRelease(inWillRelease) {}
|
||||
CACFString(const char* inCString, bool inWillRelease = true) : mCFString(CFStringCreateWithCString(NULL, inCString, kCFStringEncodingASCII)), mWillRelease(inWillRelease) {}
|
||||
CACFString(const char* inCString, CFStringEncoding inCStringEncoding, bool inWillRelease = true) : mCFString(CFStringCreateWithCString(NULL, inCString, inCStringEncoding)), mWillRelease(inWillRelease) {}
|
||||
~CACFString() { Release(); }
|
||||
CACFString(const CACFString& inString) : mCFString(inString.mCFString), mWillRelease(inString.mWillRelease) { Retain(); }
|
||||
CACFString& operator=(const CACFString& inString) { Release(); mCFString = inString.mCFString; mWillRelease = inString.mWillRelease; Retain(); return *this; }
|
||||
CACFString& operator=(CFStringRef inCFString) { Release(); mCFString = inCFString; mWillRelease = true; return *this; }
|
||||
|
||||
private:
|
||||
void Retain() { if(mWillRelease && (mCFString != NULL)) { CFRetain(mCFString); } }
|
||||
void Release() { if(mWillRelease && (mCFString != NULL)) { CFRelease(mCFString); } }
|
||||
|
||||
CFStringRef mCFString;
|
||||
bool mWillRelease;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void AllowRelease() { mWillRelease = true; }
|
||||
void DontAllowRelease() { mWillRelease = false; }
|
||||
bool IsValid() const { return mCFString != NULL; }
|
||||
bool StartsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFString != NULL) { theAnswer = CFStringHasPrefix(mCFString, inString); } return theAnswer; }
|
||||
bool EndsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFString != NULL) { theAnswer = CFStringHasSuffix(mCFString, inString); } return theAnswer; }
|
||||
|
||||
// Value Access
|
||||
public:
|
||||
CFStringRef GetCFString() const { return mCFString; }
|
||||
CFStringRef CopyCFString() const { if(mCFString != NULL) { CFRetain(mCFString); } return mCFString; }
|
||||
UInt32 GetLength() const { UInt32 theAnswer = 0; if(mCFString != NULL) { theAnswer = CFStringGetLength(mCFString); } return theAnswer; }
|
||||
UInt32 GetByteLength(CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { UInt32 theAnswer = 0; if(mCFString != NULL) { theAnswer = GetStringByteLength(mCFString, inEncoding); } return theAnswer; }
|
||||
void GetCString(char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { GetCString(mCFString, outString, ioStringSize, inEncoding); }
|
||||
void GetUnicodeString(UInt16* outString, UInt32& ioStringSize) const { GetUnicodeString(mCFString, outString, ioStringSize); }
|
||||
|
||||
static UInt32 GetStringByteLength(CFStringRef inCFString, CFStringEncoding inEncoding = kCFStringEncodingUTF8);
|
||||
static void GetCString(CFStringRef inCFString, char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8);
|
||||
static void GetUnicodeString(CFStringRef inCFString, UInt16* outString, UInt32& ioStringSize);
|
||||
|
||||
};
|
||||
|
||||
inline bool operator<(const CACFString& x, const CACFString& y) { return CFStringCompare(x.GetCFString(), y.GetCFString(), 0) == kCFCompareLessThan; }
|
||||
inline bool operator==(const CACFString& x, const CACFString& y) { return CFStringCompare(x.GetCFString(), y.GetCFString(), 0) == kCFCompareEqualTo; }
|
||||
inline bool operator!=(const CACFString& x, const CACFString& y) { return !(x == y); }
|
||||
inline bool operator<=(const CACFString& x, const CACFString& y) { return (x < y) || (x == y); }
|
||||
inline bool operator>=(const CACFString& x, const CACFString& y) { return !(x < y); }
|
||||
inline bool operator>(const CACFString& x, const CACFString& y) { return !((x < y) || (x == y)); }
|
||||
|
||||
//=============================================================================
|
||||
// CACFMutableString
|
||||
//=============================================================================
|
||||
|
||||
class CACFMutableString
|
||||
{
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CACFMutableString() : mCFMutableString(NULL), mWillRelease(true) {}
|
||||
CACFMutableString(CFMutableStringRef inCFMutableString, bool inWillRelease = true) : mCFMutableString(inCFMutableString), mWillRelease(inWillRelease) {}
|
||||
CACFMutableString(CFStringRef inStringToCopy, bool /*inMakeCopy*/, bool inWillRelease = true) : mCFMutableString(CFStringCreateMutableCopy(NULL, 0, inStringToCopy)), mWillRelease(inWillRelease) {}
|
||||
CACFMutableString(const char* inCString, bool inWillRelease = true) : mCFMutableString(NULL), mWillRelease(inWillRelease) { CACFString theString(inCString); mCFMutableString = CFStringCreateMutableCopy(NULL, 0, theString.GetCFString()); }
|
||||
CACFMutableString(const char* inCString, CFStringEncoding inCStringEncoding, bool inWillRelease = true) : mCFMutableString(NULL), mWillRelease(inWillRelease) { CACFString theString(inCString, inCStringEncoding); mCFMutableString = CFStringCreateMutableCopy(NULL, 0, theString.GetCFString()); }
|
||||
~CACFMutableString() { Release(); }
|
||||
CACFMutableString(const CACFMutableString& inString) : mCFMutableString(inString.mCFMutableString), mWillRelease(inString.mWillRelease) { Retain(); }
|
||||
CACFMutableString operator=(const CACFMutableString& inString) { Release(); mCFMutableString = inString.mCFMutableString; mWillRelease = inString.mWillRelease; Retain(); return *this; }
|
||||
CACFMutableString operator=(CFMutableStringRef inCFMutableString) { Release(); mCFMutableString = inCFMutableString; mWillRelease = true; return *this; }
|
||||
|
||||
private:
|
||||
void Retain() { if(mWillRelease && (mCFMutableString != NULL)) { CFRetain(mCFMutableString); } }
|
||||
void Release() { if(mWillRelease && (mCFMutableString != NULL)) { CFRelease(mCFMutableString); } }
|
||||
|
||||
CFMutableStringRef mCFMutableString;
|
||||
bool mWillRelease;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void AllowRelease() { mWillRelease = true; }
|
||||
void DontAllowRelease() { mWillRelease = false; }
|
||||
bool IsValid() { return mCFMutableString != NULL; }
|
||||
bool StartsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFMutableString != NULL) { theAnswer = CFStringHasPrefix(mCFMutableString, inString); } return theAnswer; }
|
||||
bool EndsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFMutableString != NULL) { theAnswer = CFStringHasSuffix(mCFMutableString, inString); } return theAnswer; }
|
||||
void Append(CFStringRef inString) { if(mCFMutableString != NULL) { CFStringAppend(mCFMutableString, inString); } }
|
||||
|
||||
// Value Access
|
||||
public:
|
||||
CFMutableStringRef GetCFMutableString() const { return mCFMutableString; }
|
||||
CFMutableStringRef CopyCFMutableString() const { if(mCFMutableString != NULL) { CFRetain(mCFMutableString); } return mCFMutableString; }
|
||||
UInt32 GetLength() const { UInt32 theAnswer = 0; if(mCFMutableString != NULL) { theAnswer = CFStringGetLength(mCFMutableString); } return theAnswer; }
|
||||
UInt32 GetByteLength(CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { UInt32 theAnswer = 0; if(mCFMutableString != NULL) { theAnswer = CACFString::GetStringByteLength(mCFMutableString, inEncoding); } return theAnswer; }
|
||||
void GetCString(char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { CACFString::GetCString(mCFMutableString, outString, ioStringSize, inEncoding); }
|
||||
void GetUnicodeString(UInt16* outString, UInt32& ioStringSize) const { CACFString::GetUnicodeString(mCFMutableString, outString, ioStringSize); }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,257 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CAComponent.cpp
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "CAComponent.h"
|
||||
#include "CAComponentDescription.h"
|
||||
#include "CACFDictionary.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
CAComponent::CAComponent (const ComponentDescription& inDesc, CAComponent* next)
|
||||
: mManuName(0), mAUName(0), mCompName(0), mCompInfo (0)
|
||||
{
|
||||
mComp = FindNextComponent ((next ? next->Comp() : NULL), const_cast<ComponentDescription*>(&inDesc));
|
||||
if (mComp)
|
||||
GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL);
|
||||
else
|
||||
memcpy (&mDesc, &inDesc, sizeof(ComponentDescription));
|
||||
}
|
||||
|
||||
CAComponent::CAComponent (const Component& comp)
|
||||
: mComp (comp),
|
||||
mManuName(0),
|
||||
mAUName(0),
|
||||
mCompName(0),
|
||||
mCompInfo (0)
|
||||
{
|
||||
GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
CAComponent::CAComponent (const ComponentInstance& compInst)
|
||||
: mComp (Component(compInst)),
|
||||
mManuName(0),
|
||||
mAUName(0),
|
||||
mCompName(0),
|
||||
mCompInfo (0)
|
||||
{
|
||||
GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
CAComponent::CAComponent (OSType inType, OSType inSubtype, OSType inManu)
|
||||
: mDesc (inType, inSubtype, inManu),
|
||||
mManuName(0), mAUName(0), mCompName(0), mCompInfo (0)
|
||||
{
|
||||
mComp = FindNextComponent (NULL, &mDesc);
|
||||
GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
CAComponent::~CAComponent ()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
OSStatus CAComponent::GetResourceVersion (UInt32 &outVersion) const
|
||||
{
|
||||
bool versionFound = false;
|
||||
short componentResFileID = kResFileNotOpened;
|
||||
OSStatus result;
|
||||
short thngResourceCount;
|
||||
|
||||
short curRes = CurResFile();
|
||||
require_noerr (result = OpenAComponentResFile( mComp, &componentResFileID), home);
|
||||
require_noerr (result = componentResFileID <= 0, home);
|
||||
|
||||
UseResFile(componentResFileID);
|
||||
|
||||
thngResourceCount = Count1Resources(kComponentResourceType);
|
||||
|
||||
require_noerr (result = ResError(), home);
|
||||
// only go on if we successfully found at least 1 thng resource
|
||||
require_noerr (thngResourceCount <= 0 ? -1 : 0, home);
|
||||
|
||||
// loop through all of the Component thng resources trying to
|
||||
// find one that matches this Component description
|
||||
for (short i = 0; i < thngResourceCount && (!versionFound); i++)
|
||||
{
|
||||
// try to get a handle to this code resource
|
||||
Handle thngResourceHandle = Get1IndResource(kComponentResourceType, i+1);
|
||||
if (thngResourceHandle != NULL && ((*thngResourceHandle) != NULL))
|
||||
{
|
||||
if (UInt32(GetHandleSize(thngResourceHandle)) >= sizeof(ExtComponentResource))
|
||||
{
|
||||
ExtComponentResource * componentThng = (ExtComponentResource*) (*thngResourceHandle);
|
||||
|
||||
// check to see if this is the thng resource for the particular Component that we are looking at
|
||||
// (there often is more than one Component described in the resource)
|
||||
if ((componentThng->cd.componentType == mDesc.Type())
|
||||
&& (componentThng->cd.componentSubType == mDesc.SubType())
|
||||
&& (componentThng->cd.componentManufacturer == mDesc.Manu()))
|
||||
{
|
||||
outVersion = componentThng->componentVersion;
|
||||
versionFound = true;
|
||||
}
|
||||
}
|
||||
ReleaseResource(thngResourceHandle);
|
||||
}
|
||||
}
|
||||
|
||||
if (!versionFound)
|
||||
result = resNotFound;
|
||||
|
||||
UseResFile(curRes); // revert
|
||||
|
||||
if ( componentResFileID != kResFileNotOpened )
|
||||
CloseComponentResFile(componentResFileID);
|
||||
|
||||
home:
|
||||
return result;
|
||||
}
|
||||
|
||||
void CAComponent::Clear ()
|
||||
{
|
||||
if (mManuName) { CFRelease (mManuName); mManuName = 0; }
|
||||
if (mAUName) { CFRelease (mAUName); mAUName = 0; }
|
||||
if (mCompName) { CFRelease (mCompName); mCompName = 0; }
|
||||
if (mCompInfo) { CFRelease (mCompInfo); mCompInfo = 0; }
|
||||
}
|
||||
|
||||
CAComponent& CAComponent::operator= (const CAComponent& y)
|
||||
{
|
||||
Clear();
|
||||
|
||||
mComp = y.mComp;
|
||||
mDesc = y.mDesc;
|
||||
|
||||
if (y.mManuName) { mManuName = y.mManuName; CFRetain (mManuName); }
|
||||
if (y.mAUName) { mAUName = y.mAUName; CFRetain (mAUName); }
|
||||
if (y.mCompName) { mCompName = y.mCompName; CFRetain (mCompName); }
|
||||
if (y.mCompInfo) { mCompInfo = y.mCompInfo; CFRetain (mCompInfo); }
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CAComponent::SetCompNames () const
|
||||
{
|
||||
if (!mCompName) {
|
||||
Handle h1 = NewHandle(4);
|
||||
CAComponentDescription desc;
|
||||
OSStatus err = GetComponentInfo (Comp(), &desc, h1, 0, 0);
|
||||
|
||||
if (err) { DisposeHandle(h1); return; }
|
||||
|
||||
HLock(h1);
|
||||
char* ptr1 = *h1;
|
||||
// Get the manufacturer's name... look for the ':' character convention
|
||||
int len = *ptr1++;
|
||||
char* displayStr = 0;
|
||||
|
||||
const_cast<CAComponent*>(this)->mCompName = CFStringCreateWithPascalString(NULL, (const unsigned char*)*h1, kCFStringEncodingMacRoman);
|
||||
|
||||
for (int i = 0; i < len; ++i) {
|
||||
if (ptr1[i] == ':') { // found the name
|
||||
ptr1[i] = 0;
|
||||
displayStr = ptr1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (displayStr)
|
||||
{
|
||||
const_cast<CAComponent*>(this)->mManuName = CFStringCreateWithCString(NULL, displayStr, kCFStringEncodingMacRoman);
|
||||
|
||||
//move displayStr ptr past the manu, to the name
|
||||
// we move the characters down a index, because the handle doesn't have any room
|
||||
// at the end for the \0
|
||||
int i = strlen(displayStr), j = 0;
|
||||
while (displayStr[++i] == ' ' && i < len)
|
||||
;
|
||||
while (i < len)
|
||||
displayStr[j++] = displayStr[i++];
|
||||
displayStr[j] = 0;
|
||||
|
||||
const_cast<CAComponent*>(this)->mAUName = CFStringCreateWithCString(NULL, displayStr, kCFStringEncodingMacRoman);
|
||||
}
|
||||
|
||||
DisposeHandle (h1);
|
||||
}
|
||||
}
|
||||
|
||||
void CAComponent::SetCompInfo () const
|
||||
{
|
||||
if (!mCompInfo) {
|
||||
Handle h1 = NewHandle(4);
|
||||
CAComponentDescription desc;
|
||||
OSStatus err = GetComponentInfo (Comp(), &desc, 0, h1, 0);
|
||||
if (err) return;
|
||||
HLock (h1);
|
||||
const_cast<CAComponent*>(this)->mCompInfo = CFStringCreateWithPascalString(NULL, (const unsigned char*)*h1, kCFStringEncodingMacRoman);
|
||||
|
||||
DisposeHandle (h1);
|
||||
}
|
||||
}
|
||||
|
||||
void _ShowCF (FILE* file, CFStringRef str)
|
||||
{
|
||||
if (CFGetTypeID(str) != CFStringGetTypeID()) {
|
||||
CFShow(str);
|
||||
return;
|
||||
}
|
||||
|
||||
UInt32 len = CFStringGetLength(str);
|
||||
char* chars = (char*)malloc (len * 2); // give us plenty of room for unichar chars
|
||||
if (CFStringGetCString (str, chars, len * 2, kCFStringEncodingUTF8))
|
||||
fprintf (file, "%s", chars);
|
||||
else
|
||||
CFShow (str);
|
||||
|
||||
free (chars);
|
||||
}
|
||||
|
||||
void CAComponent::Print(FILE* file) const
|
||||
{
|
||||
fprintf (file, "CAComponent: 0x%X", int(Comp()));
|
||||
if (mManuName) {
|
||||
fprintf (file, ", Manu:"); _ShowCF (file, mManuName);
|
||||
if (mAUName) fprintf (file, ", Name:"); _ShowCF (file, mAUName);
|
||||
}
|
||||
fprintf (file, ", ");
|
||||
Desc ().Print(file);
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CAComponent.h
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef __CAComponent_h__
|
||||
#define __CAComponent_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#else
|
||||
#include <ConditionalMacros.h>
|
||||
#include <CoreServices.h>
|
||||
#endif
|
||||
|
||||
#include "CAComponentDescription.h"
|
||||
|
||||
class CAComponent
|
||||
{
|
||||
public:
|
||||
CAComponent ()
|
||||
: mComp (0), mDesc(), mManuName(0), mAUName(0), mCompName(0), mCompInfo (0) {}
|
||||
|
||||
// if next is specifed that is used to find the next component after that one
|
||||
CAComponent (const ComponentDescription& inDesc, CAComponent* next = 0);
|
||||
|
||||
CAComponent (const CAComponent& y)
|
||||
: mComp (0), mDesc(), mManuName(0), mAUName(0), mCompName(0), mCompInfo (0) { *this = y; }
|
||||
|
||||
CAComponent (const Component& comp);
|
||||
|
||||
CAComponent (const ComponentInstance& compInst);
|
||||
|
||||
CAComponent (OSType inType, OSType inSubtype = 0, OSType inManu = 0);
|
||||
|
||||
~CAComponent ();
|
||||
|
||||
CAComponent& operator= (const CAComponent& y);
|
||||
|
||||
// returns true if this object references a valid component
|
||||
bool IsValid () const { return Comp() != 0; }
|
||||
|
||||
bool HasAUStrings() const { SetCompNames (); return mManuName != 0; }
|
||||
|
||||
// CFStringRef should be retained by caller if needed beyond lifetime of this object
|
||||
|
||||
// Can return NULL if component doesn't follow AU naming conventions
|
||||
CFStringRef GetAUManu () const { SetCompNames (); return mManuName; }
|
||||
CFStringRef GetAUName () const { SetCompNames (); return mAUName ? mAUName : mCompName; }
|
||||
|
||||
// Return value of NULL indicates a problem getting that information from the component
|
||||
CFStringRef GetCompName () const { SetCompNames(); return mCompName; }
|
||||
CFStringRef GetCompInfo () const { SetCompInfo(); return mCompInfo; }
|
||||
|
||||
const CAComponentDescription& Desc () const { return mDesc; }
|
||||
|
||||
OSStatus Open (ComponentInstance& outInst) const
|
||||
{
|
||||
return OpenAComponent (Comp(), &outInst);
|
||||
}
|
||||
|
||||
OSStatus GetResourceVersion (UInt32 &outVersion) const;
|
||||
|
||||
const Component& Comp() const { return mComp; }
|
||||
|
||||
void Print(FILE* file = stdout) const;
|
||||
|
||||
OSStatus Save (CFPropertyListRef *outData) const;
|
||||
|
||||
OSStatus Restore (CFPropertyListRef &inData);
|
||||
|
||||
private:
|
||||
Component mComp;
|
||||
CAComponentDescription mDesc;
|
||||
|
||||
CFStringRef mManuName, mAUName, mCompName, mCompInfo;
|
||||
|
||||
void SetCompNames () const;
|
||||
void SetCompInfo () const;
|
||||
void Clear ();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,123 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CAComponentDescription.cpp
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "CAComponentDescription.h"
|
||||
#include <ctype.h>
|
||||
|
||||
extern "C" void CAShowComponentDescription(const ComponentDescription *desc)
|
||||
{
|
||||
CAComponentDescription::_CAShowComponentDescription (desc, stdout);
|
||||
}
|
||||
|
||||
char *StringForOSType (OSType t, char *writeLocation)
|
||||
{
|
||||
char *p = writeLocation;
|
||||
unsigned char str[4], *q = str;
|
||||
*(UInt32 *)str = EndianU32_NtoB(t);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (isprint(*q) && *q != '\\')
|
||||
*p++ = *q++;
|
||||
else {
|
||||
sprintf(p, "\\x%02X", *q++);
|
||||
p += 4;
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
return writeLocation;
|
||||
}
|
||||
|
||||
|
||||
void CAComponentDescription::_CAShowComponentDescription(const ComponentDescription *desc, FILE* file)
|
||||
{
|
||||
if (desc)
|
||||
{
|
||||
char str[24];
|
||||
fprintf (file, "ComponentDescription: %s - ", StringForOSType(desc->componentType, str));
|
||||
fprintf (file, "%s - ", StringForOSType(desc->componentSubType, str));
|
||||
fprintf (file, "%s", StringForOSType(desc->componentManufacturer, str));
|
||||
fprintf (file, ", 0x%lX, 0x%lX\n", desc->componentFlags, desc->componentFlagsMask);
|
||||
}
|
||||
}
|
||||
|
||||
CAComponentDescription::CAComponentDescription (OSType inType, OSType inSubtype, OSType inManu)
|
||||
{
|
||||
componentType = inType;
|
||||
componentSubType = inSubtype;
|
||||
componentManufacturer = inManu;
|
||||
componentFlags = 0;
|
||||
componentFlagsMask = 0;
|
||||
}
|
||||
|
||||
bool CAComponentDescription::IsAU () const
|
||||
{
|
||||
bool flag = IsEffect() || IsMusicDevice() || IsOffline();
|
||||
if (flag) return true;
|
||||
|
||||
switch (componentType) {
|
||||
case kAudioUnitType_Output:
|
||||
case kAudioUnitType_FormatConverter:
|
||||
case kAudioUnitType_Mixer:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool _MatchTest (const OSType &inTypeA, const OSType &inTypeB)
|
||||
{
|
||||
return ((inTypeA == inTypeB) || (!inTypeA && !inTypeB) || (inTypeA && !inTypeB) || (!inTypeA && inTypeB));
|
||||
}
|
||||
|
||||
bool CAComponentDescription::Matches (const ComponentDescription &desc) const
|
||||
{
|
||||
bool matches = false;
|
||||
|
||||
// see if the type matches
|
||||
matches = _MatchTest (componentType, desc.componentType);
|
||||
|
||||
if (matches)
|
||||
matches = _MatchTest (componentSubType, desc.componentSubType);
|
||||
|
||||
if (matches)
|
||||
matches = _MatchTest (componentManufacturer, desc.componentManufacturer);
|
||||
|
||||
return matches;
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CAComponentDescription.h
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef __CAComponentDescription_h__
|
||||
#define __CAComponentDescription_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#else
|
||||
#include <ConditionalMacros.h>
|
||||
#include <CoreServices.h>
|
||||
#include <AudioUnit.h>
|
||||
#endif
|
||||
|
||||
#include "CACFDictionary.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void CAShowComponentDescription(const ComponentDescription *desc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// ____________________________________________________________________________
|
||||
//
|
||||
// CAComponentDescription
|
||||
class CAComponentDescription : public ComponentDescription {
|
||||
public:
|
||||
CAComponentDescription() { memset (this, 0, sizeof (ComponentDescription)); }
|
||||
|
||||
CAComponentDescription (OSType inType, OSType inSubtype = 0, OSType inManu = 0);
|
||||
|
||||
CAComponentDescription(const ComponentDescription& desc) { memcpy (this, &desc, sizeof (ComponentDescription)); }
|
||||
|
||||
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
//
|
||||
// interrogation
|
||||
|
||||
bool IsAU () const;
|
||||
|
||||
bool IsAUFX() const { return componentType == kAudioUnitType_Effect; }
|
||||
bool IsAUFM() const { return componentType == kAudioUnitType_MusicEffect; }
|
||||
|
||||
bool IsEffect () const { return IsAUFX() || IsAUFM() || IsPanner(); }
|
||||
|
||||
bool IsOffline () const { return componentType == 'auol'; }
|
||||
|
||||
bool IsFConv () const { return componentType == kAudioUnitType_FormatConverter; }
|
||||
|
||||
bool IsPanner () const { return componentType == kAudioUnitType_Panner; }
|
||||
|
||||
bool IsMusicDevice () const { return componentType == kAudioUnitType_MusicDevice; }
|
||||
|
||||
#ifndef MAC_OS_X_VERSION_10_4
|
||||
bool IsGenerator () const { return componentType =='augn'; }
|
||||
#else
|
||||
bool IsGenerator () const { return componentType ==kAudioUnitType_Generator; }
|
||||
#endif
|
||||
|
||||
bool IsOutput () const { return componentType == kAudioUnitType_Output; }
|
||||
|
||||
bool IsSource () const { return IsMusicDevice() || IsGenerator(); }
|
||||
|
||||
OSType Type () const { return componentType; }
|
||||
OSType SubType () const { return componentSubType; }
|
||||
OSType Manu () const { return componentManufacturer; }
|
||||
|
||||
int Count() const { return CountComponents(const_cast<CAComponentDescription*>(this)); }
|
||||
|
||||
// does a semantic match where "wild card" values for type, subtype, manu will match
|
||||
bool Matches (const ComponentDescription &desc) const;
|
||||
|
||||
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
//
|
||||
// other
|
||||
|
||||
void Print(FILE* file = stdout) const { _CAShowComponentDescription (this, file); }
|
||||
|
||||
OSStatus Save (CFPropertyListRef *outData) const;
|
||||
OSStatus Restore (CFPropertyListRef &inData);
|
||||
|
||||
private:
|
||||
static void _CAShowComponentDescription (const ComponentDescription *desc, FILE* file);
|
||||
friend void CAShowComponentDescription (const ComponentDescription *desc);
|
||||
};
|
||||
|
||||
inline bool operator< (const ComponentDescription& x, const ComponentDescription& y)
|
||||
{
|
||||
return memcmp (&x, &y, offsetof (ComponentDescription, componentFlags)) < 0;
|
||||
}
|
||||
|
||||
inline bool operator== (const ComponentDescription& x, const ComponentDescription& y)
|
||||
{
|
||||
return !memcmp (&x, &y, offsetof (ComponentDescription, componentFlags));
|
||||
}
|
||||
|
||||
inline bool operator!= (const ComponentDescription& x, const ComponentDescription& y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,74 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CAConditionalMacros.h
|
||||
|
||||
=============================================================================*/
|
||||
#if !defined(__CAConditionalMacros_h__)
|
||||
#define __CAConditionalMacros_h__
|
||||
|
||||
//=============================================================================
|
||||
// This file exists to make figuring out how to include system headers
|
||||
// easier in a cross platform world. We throw in an include of the standard
|
||||
// ConditionalMacros too.
|
||||
//=============================================================================
|
||||
|
||||
// ########## THIS FILE SHOULD GO AWAY SOON, replaced by __COREAUDIO_USE_FLAT_INCLUDES__
|
||||
// but for now, use this as a way to define __COREAUDIO_USE_FLAT_INCLUDES__ programmatically
|
||||
|
||||
// TargetConditionals.h defines the bare minimum we need
|
||||
#include "TargetConditionals.h"
|
||||
|
||||
// Determine whether or not to use framework style includes for system headers
|
||||
#if !defined(CoreAudio_Use_Framework_Includes) && !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#if TARGET_RT_MAC_MACHO
|
||||
#define CoreAudio_Use_Framework_Includes 1
|
||||
#else
|
||||
#define CoreAudio_Use_Framework_Includes 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Include the regular ConditionalMacros.h too, since it has useful stuff that
|
||||
// TargetConditionals.h lacks for some reason.
|
||||
#if CoreAudio_Use_Framework_Includes
|
||||
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/ConditionalMacros.h>
|
||||
#else
|
||||
#include "ConditionalMacros.h"
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,84 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CADebugMacros.cp
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "CADebugMacros.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#if TARGET_API_MAC_OSX
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
|
||||
void DebugPrint(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
#if TARGET_API_MAC_OSX
|
||||
void LogError(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
#if DEBUG
|
||||
vprintf(fmt, args);
|
||||
#endif
|
||||
vsyslog(LOG_ERR, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void LogWarning(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
#if DEBUG
|
||||
vprintf(fmt, args);
|
||||
#endif
|
||||
vsyslog(LOG_WARNING, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,414 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CADebugMacros.h
|
||||
|
||||
=============================================================================*/
|
||||
#if !defined(__CADebugMacros_h__)
|
||||
#define __CADebugMacros_h__
|
||||
|
||||
//=============================================================================
|
||||
// CADebugMacros
|
||||
//=============================================================================
|
||||
|
||||
//#define CoreAudio_StopOnFailure 1
|
||||
//#define CoreAudio_TimeStampMessages 1
|
||||
//#define CoreAudio_ThreadStampMessages 1
|
||||
//#define CoreAudio_FlushDebugMessages 1
|
||||
|
||||
#define CA4CCToCString(the4CC) { ((char*)&the4CC)[0], ((char*)&the4CC)[1], ((char*)&the4CC)[2], ((char*)&the4CC)[3], 0 }
|
||||
|
||||
#pragma mark Basic Definitions
|
||||
|
||||
#if DEBUG || CoreAudio_Debug
|
||||
|
||||
// can be used to break into debugger immediately, also see CADebugger
|
||||
#define BusError() (*(long *)0 = 0)
|
||||
|
||||
// basic debugging print routines
|
||||
#if TARGET_OS_MAC && !TARGET_API_MAC_CARBON
|
||||
extern pascal void DebugStr(const unsigned char* debuggerMsg);
|
||||
#define DebugMessage(msg) DebugStr("\p"msg)
|
||||
#define DebugMessageN1(msg, N1)
|
||||
#define DebugMessageN2(msg, N1, N2)
|
||||
#define DebugMessageN3(msg, N1, N2, N3)
|
||||
#else
|
||||
#include "CADebugPrintf.h"
|
||||
|
||||
#if (CoreAudio_FlushDebugMessages && !CoreAudio_UseSysLog) || defined(CoreAudio_UseSideFile)
|
||||
#define FlushRtn ;fflush(DebugPrintfFile)
|
||||
#else
|
||||
#define FlushRtn
|
||||
#endif
|
||||
|
||||
#if CoreAudio_ThreadStampMessages
|
||||
#include <pthread.h>
|
||||
#include "CAHostTimeBase.h"
|
||||
#define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn
|
||||
#define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn
|
||||
#define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn
|
||||
#define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn
|
||||
#define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn
|
||||
#define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn
|
||||
#define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn
|
||||
#define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn
|
||||
#define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn
|
||||
#define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn
|
||||
#elif CoreAudio_TimeStampMessages
|
||||
#include "CAHostTimeBase.h"
|
||||
#define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFile, "%.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn
|
||||
#define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn
|
||||
#define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn
|
||||
#define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn
|
||||
#define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn
|
||||
#define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn
|
||||
#define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn
|
||||
#define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn
|
||||
#define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn
|
||||
#define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn
|
||||
#else
|
||||
#define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFile, "%s"DebugPrintfLineEnding, msg) FlushRtn
|
||||
#define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1) FlushRtn
|
||||
#define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2) FlushRtn
|
||||
#define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3) FlushRtn
|
||||
#define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4) FlushRtn
|
||||
#define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5) FlushRtn
|
||||
#define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6) FlushRtn
|
||||
#define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7) FlushRtn
|
||||
#define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn
|
||||
#define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn
|
||||
#endif
|
||||
#endif
|
||||
void DebugPrint(const char *fmt, ...); // can be used like printf
|
||||
#define DEBUGPRINT(msg) DebugPrint msg // have to double-parenthesize arglist (see Debugging.h)
|
||||
#if VERBOSE
|
||||
#define vprint(msg) DEBUGPRINT(msg)
|
||||
#else
|
||||
#define vprint(msg)
|
||||
#endif
|
||||
|
||||
#if CoreAudio_StopOnFailure
|
||||
#include "CADebugger.h"
|
||||
#define STOP CADebuggerStop()
|
||||
#else
|
||||
#define STOP
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define DebugMessage(msg)
|
||||
#define DebugMessageN1(msg, N1)
|
||||
#define DebugMessageN2(msg, N1, N2)
|
||||
#define DebugMessageN3(msg, N1, N2, N3)
|
||||
#define DebugMessageN4(msg, N1, N2, N3, N4)
|
||||
#define DebugMessageN5(msg, N1, N2, N3, N4, N5)
|
||||
#define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6)
|
||||
#define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7)
|
||||
#define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8)
|
||||
#define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9)
|
||||
#define DEBUGPRINT(msg)
|
||||
#define vprint(msg)
|
||||
#define STOP
|
||||
#endif
|
||||
|
||||
void LogError(const char *fmt, ...); // writes to syslog (and stderr if debugging)
|
||||
void LogWarning(const char *fmt, ...); // writes to syslog (and stderr if debugging)
|
||||
|
||||
#if DEBUG || CoreAudio_Debug
|
||||
|
||||
#pragma mark Debug Macros
|
||||
|
||||
#define Assert(inCondition, inMessage) \
|
||||
if(!(inCondition)) \
|
||||
{ \
|
||||
DebugMessage(inMessage); \
|
||||
STOP; \
|
||||
}
|
||||
|
||||
#define AssertNoError(inError, inMessage) \
|
||||
{ \
|
||||
SInt32 __Err = (inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
char __4CC[5] = CA4CCToCString(__Err); \
|
||||
DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \
|
||||
STOP; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define AssertNoKernelError(inError, inMessage) \
|
||||
{ \
|
||||
unsigned int __Err = (unsigned int)(inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
|
||||
STOP; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FailIf(inCondition, inHandler, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
DebugMessage(inMessage); \
|
||||
STOP; \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailWithAction(inCondition, inAction, inHandler, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
DebugMessage(inMessage); \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \
|
||||
if((inPointer) == NULL) \
|
||||
{ \
|
||||
DebugMessage(inMessage); \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfKernelError(inKernelError, inException, inMessage) \
|
||||
{ \
|
||||
kern_return_t __Err = (inKernelError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FailIfError(inError, inException, inMessage) \
|
||||
{ \
|
||||
SInt32 __Err = (inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
char __4CC[5] = CA4CCToCString(__Err); \
|
||||
DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
} \
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
#define Throw(inException) STOP; throw (inException)
|
||||
|
||||
#define ThrowIf(inCondition, inException, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
DebugMessage(inMessage); \
|
||||
Throw(inException); \
|
||||
}
|
||||
|
||||
#define ThrowIfNULL(inPointer, inException, inMessage) \
|
||||
if((inPointer) == NULL) \
|
||||
{ \
|
||||
DebugMessage(inMessage); \
|
||||
Throw(inException); \
|
||||
}
|
||||
|
||||
#define ThrowIfKernelError(inKernelError, inException, inMessage) \
|
||||
{ \
|
||||
kern_return_t __Err = (inKernelError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
|
||||
Throw(inException); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ThrowIfError(inError, inException, inMessage) \
|
||||
{ \
|
||||
SInt32 __Err = (inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
char __4CC[5] = CA4CCToCString(__Err); \
|
||||
DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \
|
||||
Throw(inException); \
|
||||
} \
|
||||
}
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#define ThrowIfWinError(inError, inException, inMessage) \
|
||||
{ \
|
||||
HRESULT __Err = (inError); \
|
||||
if(FAILED(__Err)) \
|
||||
{ \
|
||||
DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
|
||||
Throw(inException); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SubclassResponsibility(inMethodName, inException) \
|
||||
{ \
|
||||
DebugMessage(inMethodName": Subclasses must implement this method"); \
|
||||
Throw(inException); \
|
||||
}
|
||||
|
||||
#endif // defined(__cplusplus)
|
||||
|
||||
#else
|
||||
|
||||
#pragma mark Release Macros
|
||||
|
||||
#define Assert(inCondition, inMessage) \
|
||||
if(!(inCondition)) \
|
||||
{ \
|
||||
STOP; \
|
||||
}
|
||||
|
||||
#define AssertNoError(inError, inMessage) \
|
||||
{ \
|
||||
SInt32 __Err = (inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
STOP; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define AssertNoKernelError(inError, inMessage) \
|
||||
{ \
|
||||
unsigned int __Err = (unsigned int)(inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
STOP; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FailIf(inCondition, inHandler, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
STOP; \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailWithAction(inCondition, inAction, inHandler, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \
|
||||
if((inPointer) == NULL) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfKernelError(inKernelError, inException, inMessage) \
|
||||
if((inKernelError) != 0) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfError(inError, inException, inMessage) \
|
||||
if((inError) != 0) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
#define Throw(inException) STOP; throw (inException)
|
||||
|
||||
#define ThrowIf(inCondition, inException, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
Throw(inException); \
|
||||
}
|
||||
|
||||
#define ThrowIfNULL(inPointer, inException, inMessage) \
|
||||
if((inPointer) == NULL) \
|
||||
{ \
|
||||
Throw(inException); \
|
||||
}
|
||||
|
||||
#define ThrowIfKernelError(inKernelError, inException, inMessage) \
|
||||
{ \
|
||||
kern_return_t __Err = (inKernelError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
Throw(inException); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ThrowIfError(inError, inException, inMessage) \
|
||||
{ \
|
||||
SInt32 __Err = (inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
Throw(inException); \
|
||||
} \
|
||||
}
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#define ThrowIfWinError(inError, inException, inMessage) \
|
||||
{ \
|
||||
HRESULT __Err = (inError); \
|
||||
if(FAILED(__Err)) \
|
||||
{ \
|
||||
Throw(inException); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SubclassResponsibility(inMethodName, inException) \
|
||||
{ \
|
||||
Throw(inException); \
|
||||
}
|
||||
|
||||
#endif // defined(__cplusplus)
|
||||
|
||||
#endif // DEBUG || CoreAudio_Debug
|
||||
|
||||
#endif
|
|
@ -0,0 +1,64 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CAMath.h
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef __CAMath_h__
|
||||
#define __CAMath_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#endif
|
||||
|
||||
inline bool fiszero(Float64 f) { return (f == 0.); }
|
||||
inline bool fiszero(Float32 f) { return (f == 0.f); }
|
||||
|
||||
inline bool fnonzero(Float64 f) { return !fiszero(f); }
|
||||
inline bool fnonzero(Float32 f) { return !fiszero(f); }
|
||||
|
||||
inline bool fequal(const Float64 &a, const Float64 &b) { return a == b; }
|
||||
inline bool fequal(const Float32 &a, const Float32 &b) { return a == b; }
|
||||
|
||||
inline bool fnotequal(const Float64 &a, const Float64 &b) { return !fequal(a, b); }
|
||||
inline bool fnotequal(const Float32 &a, const Float32 &b) { return !fequal(a, b); }
|
||||
|
||||
#endif // __CAMath_h__
|
|
@ -0,0 +1,83 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CAReferenceCounted.h
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef __CAReferenceCounted_h__
|
||||
#define __CAReferenceCounted_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#else
|
||||
#include <CoreServices.h>
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#include "CAWindows.h"
|
||||
#endif
|
||||
|
||||
// base class for reference-counted objects
|
||||
class CAReferenceCounted {
|
||||
public:
|
||||
CAReferenceCounted() : mRefCount(1) {}
|
||||
|
||||
void retain() { IncrementAtomic(&mRefCount); }
|
||||
|
||||
void release()
|
||||
{
|
||||
// this returns the ORIGINAL value, not the new one.
|
||||
SInt32 rc = DecrementAtomic(&mRefCount);
|
||||
if (rc == 1) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~CAReferenceCounted() { }
|
||||
|
||||
private:
|
||||
SInt32 mRefCount;
|
||||
|
||||
CAReferenceCounted(const CAReferenceCounted &a) : mRefCount(0) { }
|
||||
CAReferenceCounted operator=(const CAReferenceCounted &a) { return *this; }
|
||||
};
|
||||
|
||||
|
||||
#endif // __CAReferenceCounted_h__
|
|
@ -0,0 +1,520 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CAStreamBasicDescription.cpp
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "CAConditionalMacros.h"
|
||||
|
||||
#include "CAStreamBasicDescription.h"
|
||||
#include "CAMath.h"
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreFoundation/CFByteOrder.h>
|
||||
#else
|
||||
#include <CFByteOrder.h>
|
||||
#endif
|
||||
|
||||
#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it
|
||||
|
||||
const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
CAStreamBasicDescription::CAStreamBasicDescription(double inSampleRate, UInt32 inFormatID,
|
||||
UInt32 inBytesPerPacket, UInt32 inFramesPerPacket,
|
||||
UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame,
|
||||
UInt32 inBitsPerChannel, UInt32 inFormatFlags)
|
||||
{
|
||||
mSampleRate = inSampleRate;
|
||||
mFormatID = inFormatID;
|
||||
mBytesPerPacket = inBytesPerPacket;
|
||||
mFramesPerPacket = inFramesPerPacket;
|
||||
mBytesPerFrame = inBytesPerFrame;
|
||||
mChannelsPerFrame = inChannelsPerFrame;
|
||||
mBitsPerChannel = inBitsPerChannel;
|
||||
mFormatFlags = inFormatFlags;
|
||||
}
|
||||
|
||||
void CAStreamBasicDescription::PrintFormat(FILE *f, const char *indent, const char *name) const
|
||||
{
|
||||
fprintf(f, "%s%s ", indent, name);
|
||||
char formatID[5];
|
||||
*(UInt32 *)formatID = CFSwapInt32HostToBig(mFormatID);
|
||||
formatID[4] = '\0';
|
||||
fprintf(f, "%2ld ch, %6.0f Hz, '%-4.4s' (0x%08lX) ",
|
||||
NumberChannels(), mSampleRate, formatID,
|
||||
mFormatFlags);
|
||||
if (mFormatID == kAudioFormatLinearPCM) {
|
||||
bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat);
|
||||
int wordSize = SampleWordSize();
|
||||
const char *endian = (wordSize > 1) ?
|
||||
((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : "";
|
||||
const char *sign = isInt ?
|
||||
((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : "";
|
||||
const char *floatInt = isInt ? "integer" : "float";
|
||||
char packed[32];
|
||||
if (wordSize > 0 && PackednessIsSignificant()) {
|
||||
if (mFormatFlags & kLinearPCMFormatFlagIsPacked)
|
||||
sprintf(packed, "packed in %d bytes", wordSize);
|
||||
else
|
||||
sprintf(packed, "unpacked in %d bytes", wordSize);
|
||||
} else
|
||||
packed[0] = '\0';
|
||||
const char *align = (wordSize > 0 && AlignmentIsSignificant()) ?
|
||||
((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : "";
|
||||
const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : "";
|
||||
const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : "";
|
||||
|
||||
fprintf(f, "%ld-bit%s%s %s%s%s%s%s\n",
|
||||
mBitsPerChannel, endian, sign, floatInt,
|
||||
commaSpace, packed, align, deinter);
|
||||
} else if (mFormatID == 'alac') { // kAudioFormatAppleLossless
|
||||
int sourceBits = 0;
|
||||
switch (mFormatFlags)
|
||||
{
|
||||
case 1: // kAppleLosslessFormatFlag_16BitSourceData
|
||||
sourceBits = 16;
|
||||
break;
|
||||
case 2: // kAppleLosslessFormatFlag_20BitSourceData
|
||||
sourceBits = 20;
|
||||
break;
|
||||
case 3: // kAppleLosslessFormatFlag_24BitSourceData
|
||||
sourceBits = 24;
|
||||
break;
|
||||
case 4: // kAppleLosslessFormatFlag_32BitSourceData
|
||||
sourceBits = 32;
|
||||
break;
|
||||
}
|
||||
if (sourceBits)
|
||||
fprintf(f, "from %d-bit source, ", sourceBits);
|
||||
else
|
||||
fprintf(f, "from UNKNOWN source bit depth, ");
|
||||
|
||||
fprintf(f, "%ld frames/packet\n", mFramesPerPacket);
|
||||
}
|
||||
else
|
||||
fprintf(f, "%ld bits/channel, %ld bytes/packet, %ld frames/packet, %ld bytes/frame\n",
|
||||
mBitsPerChannel, mBytesPerPacket, mFramesPerPacket, mBytesPerFrame);
|
||||
}
|
||||
|
||||
void CAStreamBasicDescription::NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription)
|
||||
{
|
||||
// the only thing that changes is to make mixable linear PCM into the canonical linear PCM format
|
||||
if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0))
|
||||
{
|
||||
// the canonical linear PCM format is 32 bit native endian floats
|
||||
ioDescription.mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
|
||||
ioDescription.mBytesPerPacket = sizeof(Float32) * ioDescription.mChannelsPerFrame;
|
||||
ioDescription.mFramesPerPacket = 1;
|
||||
ioDescription.mBytesPerFrame = sizeof(Float32) * ioDescription.mChannelsPerFrame;
|
||||
ioDescription.mBitsPerChannel = 8 * sizeof(Float32);
|
||||
}
|
||||
}
|
||||
|
||||
void CAStreamBasicDescription::ResetFormat(AudioStreamBasicDescription& ioDescription)
|
||||
{
|
||||
ioDescription.mSampleRate = 0;
|
||||
ioDescription.mFormatID = 0;
|
||||
ioDescription.mBytesPerPacket = 0;
|
||||
ioDescription.mFramesPerPacket = 0;
|
||||
ioDescription.mBytesPerFrame = 0;
|
||||
ioDescription.mChannelsPerFrame = 0;
|
||||
ioDescription.mBitsPerChannel = 0;
|
||||
ioDescription.mFormatFlags = 0;
|
||||
}
|
||||
|
||||
void CAStreamBasicDescription::FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription)
|
||||
{
|
||||
if(fiszero(ioDescription.mSampleRate))
|
||||
{
|
||||
ioDescription.mSampleRate = inTemplateDescription.mSampleRate;
|
||||
}
|
||||
if(ioDescription.mFormatID == 0)
|
||||
{
|
||||
ioDescription.mFormatID = inTemplateDescription.mFormatID;
|
||||
}
|
||||
if(ioDescription.mFormatFlags == 0)
|
||||
{
|
||||
ioDescription.mFormatFlags = inTemplateDescription.mFormatFlags;
|
||||
}
|
||||
if(ioDescription.mBytesPerPacket == 0)
|
||||
{
|
||||
ioDescription.mBytesPerPacket = inTemplateDescription.mBytesPerPacket;
|
||||
}
|
||||
if(ioDescription.mFramesPerPacket == 0)
|
||||
{
|
||||
ioDescription.mFramesPerPacket = inTemplateDescription.mFramesPerPacket;
|
||||
}
|
||||
if(ioDescription.mBytesPerFrame == 0)
|
||||
{
|
||||
ioDescription.mBytesPerFrame = inTemplateDescription.mBytesPerFrame;
|
||||
}
|
||||
if(ioDescription.mChannelsPerFrame == 0)
|
||||
{
|
||||
ioDescription.mChannelsPerFrame = inTemplateDescription.mChannelsPerFrame;
|
||||
}
|
||||
if(ioDescription.mBitsPerChannel == 0)
|
||||
{
|
||||
ioDescription.mBitsPerChannel = inTemplateDescription.mBitsPerChannel;
|
||||
}
|
||||
}
|
||||
|
||||
void CAStreamBasicDescription::GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate)
|
||||
{
|
||||
switch(inDescription.mFormatID)
|
||||
{
|
||||
case kAudioFormatLinearPCM:
|
||||
{
|
||||
const char* theEndianString = NULL;
|
||||
if((inDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0)
|
||||
{
|
||||
#if TARGET_RT_LITTLE_ENDIAN
|
||||
theEndianString = "Big Endian";
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if TARGET_RT_BIG_ENDIAN
|
||||
theEndianString = "Little Endian";
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* theKindString = NULL;
|
||||
if((inDescription.mFormatFlags & kAudioFormatFlagIsFloat) != 0)
|
||||
{
|
||||
theKindString = (inAbbreviate ? "Float" : "Floating Point");
|
||||
}
|
||||
else if((inDescription.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0)
|
||||
{
|
||||
theKindString = (inAbbreviate ? "SInt" : "Signed Integer");
|
||||
}
|
||||
else
|
||||
{
|
||||
theKindString = (inAbbreviate ? "UInt" : "Unsigned Integer");
|
||||
}
|
||||
|
||||
const char* thePackingString = NULL;
|
||||
if((inDescription.mFormatFlags & kAudioFormatFlagIsPacked) == 0)
|
||||
{
|
||||
if((inDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0)
|
||||
{
|
||||
thePackingString = "High";
|
||||
}
|
||||
else
|
||||
{
|
||||
thePackingString = "Low";
|
||||
}
|
||||
}
|
||||
|
||||
const char* theMixabilityString = NULL;
|
||||
if((inDescription.mFormatFlags & kIsNonMixableFlag) == 0)
|
||||
{
|
||||
theMixabilityString = "Mixable";
|
||||
}
|
||||
else
|
||||
{
|
||||
theMixabilityString = "Unmixable";
|
||||
}
|
||||
|
||||
if(inAbbreviate)
|
||||
{
|
||||
if(theEndianString != NULL)
|
||||
{
|
||||
if(thePackingString != NULL)
|
||||
{
|
||||
sprintf(outName, "%s %d Ch %s %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(outName, "%s %d Ch %s %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(thePackingString != NULL)
|
||||
{
|
||||
sprintf(outName, "%s %d Ch %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)((inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(outName, "%s %d Ch %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(theEndianString != NULL)
|
||||
{
|
||||
if(thePackingString != NULL)
|
||||
{
|
||||
sprintf(outName, "%s %d Channel %d Bit %s %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(outName, "%s %d Channel %d Bit %s %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(thePackingString != NULL)
|
||||
{
|
||||
sprintf(outName, "%s %d Channel %d Bit %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(outName, "%s %d Channel %d Bit %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioFormatAC3:
|
||||
strcpy(outName, "AC-3");
|
||||
break;
|
||||
|
||||
case kAudioFormat60958AC3:
|
||||
strcpy(outName, "AC-3 for SPDIF");
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
char* the4CCString = (char*)&inDescription.mFormatID;
|
||||
outName[0] = the4CCString[0];
|
||||
outName[1] = the4CCString[1];
|
||||
outName[2] = the4CCString[2];
|
||||
outName[3] = the4CCString[3];
|
||||
outName[4] = 0;
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
#if CoreAudio_Debug
|
||||
#include "CALogMacros.h"
|
||||
|
||||
void CAStreamBasicDescription::PrintToLog(const AudioStreamBasicDescription& inDesc)
|
||||
{
|
||||
PrintFloat (" Sample Rate: ", inDesc.mSampleRate);
|
||||
Print4CharCode (" Format ID: ", inDesc.mFormatID);
|
||||
PrintHex (" Format Flags: ", inDesc.mFormatFlags);
|
||||
PrintInt (" Bytes per Packet: ", inDesc.mBytesPerPacket);
|
||||
PrintInt (" Frames per Packet: ", inDesc.mFramesPerPacket);
|
||||
PrintInt (" Bytes per Frame: ", inDesc.mBytesPerFrame);
|
||||
PrintInt (" Channels per Frame: ", inDesc.mChannelsPerFrame);
|
||||
PrintInt (" Bits per Channel: ", inDesc.mBitsPerChannel);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
bool isDone = false;
|
||||
|
||||
// note that if either side is 0, that field is skipped
|
||||
|
||||
// format ID is the first order sort
|
||||
if((!isDone) && ((x.mFormatID != 0) && (y.mFormatID != 0)))
|
||||
{
|
||||
if(x.mFormatID != y.mFormatID)
|
||||
{
|
||||
// formats are sorted numerically except that linear
|
||||
// PCM is always first
|
||||
if(x.mFormatID == kAudioFormatLinearPCM)
|
||||
{
|
||||
theAnswer = true;
|
||||
}
|
||||
else if(y.mFormatID == kAudioFormatLinearPCM)
|
||||
{
|
||||
theAnswer = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
theAnswer = x.mFormatID < y.mFormatID;
|
||||
}
|
||||
isDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// mixable is always better than non-mixable for linear PCM and should be the second order sort item
|
||||
if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM)))
|
||||
{
|
||||
if(((x.mFormatFlags & kIsNonMixableFlag) == 0) && ((y.mFormatFlags & kIsNonMixableFlag) != 0))
|
||||
{
|
||||
theAnswer = true;
|
||||
isDone = true;
|
||||
}
|
||||
else if(((x.mFormatFlags & kIsNonMixableFlag) != 0) && ((y.mFormatFlags & kIsNonMixableFlag) == 0))
|
||||
{
|
||||
theAnswer = false;
|
||||
isDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
// floating point vs integer for linear PCM only
|
||||
if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM)))
|
||||
{
|
||||
if((x.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormatFlags & kAudioFormatFlagIsFloat))
|
||||
{
|
||||
// floating point is better than integer
|
||||
theAnswer = y.mFormatFlags & kAudioFormatFlagIsFloat;
|
||||
isDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
// bit depth
|
||||
if((!isDone) && ((x.mBitsPerChannel != 0) && (y.mBitsPerChannel != 0)))
|
||||
{
|
||||
if(x.mBitsPerChannel != y.mBitsPerChannel)
|
||||
{
|
||||
// deeper bit depths are higher quality
|
||||
theAnswer = x.mBitsPerChannel < y.mBitsPerChannel;
|
||||
isDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
// sample rate
|
||||
if((!isDone) && fnonzero(x.mSampleRate) && fnonzero(y.mSampleRate))
|
||||
{
|
||||
if(fnotequal(x.mSampleRate, y.mSampleRate))
|
||||
{
|
||||
// higher sample rates are higher quality
|
||||
theAnswer = x.mSampleRate < y.mSampleRate;
|
||||
isDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
// number of channels
|
||||
if((!isDone) && ((x.mChannelsPerFrame != 0) && (y.mChannelsPerFrame != 0)))
|
||||
{
|
||||
if(x.mChannelsPerFrame != y.mChannelsPerFrame)
|
||||
{
|
||||
// more channels is higher quality
|
||||
theAnswer = x.mChannelsPerFrame < y.mChannelsPerFrame;
|
||||
isDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
|
||||
{
|
||||
UInt32 xFlags = x.mFormatFlags;
|
||||
UInt32 yFlags = y.mFormatFlags;
|
||||
|
||||
// match wildcards
|
||||
if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0)
|
||||
return true;
|
||||
|
||||
if (x.mFormatID == kAudioFormatLinearPCM)
|
||||
{
|
||||
// knock off the all clear flag
|
||||
xFlags = xFlags & ~kAudioFormatFlagsAreAllClear;
|
||||
yFlags = yFlags & ~kAudioFormatFlagsAreAllClear;
|
||||
|
||||
// if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit.
|
||||
if (xFlags & yFlags & kAudioFormatFlagIsPacked) {
|
||||
xFlags = xFlags & ~kAudioFormatFlagIsAlignedHigh;
|
||||
yFlags = yFlags & ~kAudioFormatFlagIsAlignedHigh;
|
||||
}
|
||||
|
||||
// if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit.
|
||||
if (xFlags & yFlags & kAudioFormatFlagIsFloat) {
|
||||
xFlags = xFlags & ~kAudioFormatFlagIsSignedInteger;
|
||||
yFlags = yFlags & ~kAudioFormatFlagIsSignedInteger;
|
||||
}
|
||||
|
||||
// if the bit depth is 8 bits or less and the format is packed, we don't care about endianness
|
||||
if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
|
||||
{
|
||||
xFlags = xFlags & ~kAudioFormatFlagIsBigEndian;
|
||||
}
|
||||
if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
|
||||
{
|
||||
yFlags = yFlags & ~kAudioFormatFlagIsBigEndian;
|
||||
}
|
||||
|
||||
// if the number of channels is 0 or 1, we don't care about non-interleavedness
|
||||
if (x.mChannelsPerFrame <= 1 && y.mChannelsPerFrame <= 1) {
|
||||
xFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
|
||||
yFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
|
||||
}
|
||||
}
|
||||
return xFlags == yFlags;
|
||||
}
|
||||
|
||||
bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
|
||||
{
|
||||
// the semantics for equality are:
|
||||
// 1) Values must match exactly
|
||||
// 2) wildcard's are ignored in the comparison
|
||||
|
||||
#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name))
|
||||
|
||||
return
|
||||
// check the sample rate
|
||||
(fiszero(x.mSampleRate) || fiszero(y.mSampleRate) || fequal(x.mSampleRate, y.mSampleRate))
|
||||
|
||||
// check the format ids
|
||||
&& MATCH(mFormatID)
|
||||
|
||||
// check the format flags
|
||||
&& MatchFormatFlags(x, y)
|
||||
|
||||
// check the bytes per packet
|
||||
&& MATCH(mBytesPerPacket)
|
||||
|
||||
// check the frames per packet
|
||||
&& MATCH(mFramesPerPacket)
|
||||
|
||||
// check the bytes per frame
|
||||
&& MATCH(mBytesPerFrame)
|
||||
|
||||
// check the channels per frame
|
||||
&& MATCH(mChannelsPerFrame)
|
||||
|
||||
// check the channels per frame
|
||||
&& MATCH(mBitsPerChannel) ;
|
||||
}
|
||||
|
||||
bool SanityCheck(const AudioStreamBasicDescription& x)
|
||||
{
|
||||
return (x.mSampleRate >= 0.);
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CAStreamBasicDescription.h
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef __CAStreamBasicDescription_h__
|
||||
#define __CAStreamBasicDescription_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#else
|
||||
#include "CoreAudioTypes.h"
|
||||
#include "CoreFoundation.h"
|
||||
#endif
|
||||
|
||||
#include "CADebugMacros.h"
|
||||
#include <string.h> // for memset, memcpy
|
||||
#include <stdio.h> // for FILE *
|
||||
|
||||
#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it
|
||||
|
||||
// define the IsMixable format flag for all versions of the system
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
|
||||
enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable };
|
||||
#else
|
||||
enum { kIsNonMixableFlag = (1L << 6) };
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CAStreamBasicDescription
|
||||
//
|
||||
// This is a wrapper class for the AudioStreamBasicDescription struct.
|
||||
// It adds a number of convenience routines, but otherwise adds nothing
|
||||
// to the footprint of the original struct.
|
||||
//=============================================================================
|
||||
class CAStreamBasicDescription :
|
||||
public AudioStreamBasicDescription
|
||||
{
|
||||
|
||||
// Constants
|
||||
public:
|
||||
static const AudioStreamBasicDescription sEmpty;
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CAStreamBasicDescription() { memset (this, 0, sizeof(AudioStreamBasicDescription)); }
|
||||
|
||||
CAStreamBasicDescription(const AudioStreamBasicDescription &desc)
|
||||
{
|
||||
SetFrom(desc);
|
||||
}
|
||||
|
||||
CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID,
|
||||
UInt32 inBytesPerPacket, UInt32 inFramesPerPacket,
|
||||
UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame,
|
||||
UInt32 inBitsPerChannel, UInt32 inFormatFlags);
|
||||
|
||||
// Assignment
|
||||
CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; }
|
||||
|
||||
void SetFrom(const AudioStreamBasicDescription &desc)
|
||||
{
|
||||
memcpy(this, &desc, sizeof(AudioStreamBasicDescription));
|
||||
}
|
||||
|
||||
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
//
|
||||
// interrogation
|
||||
|
||||
bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; }
|
||||
|
||||
bool PackednessIsSignificant() const
|
||||
{
|
||||
Assert(IsPCM(), "PackednessIsSignificant only applies for PCM");
|
||||
return (SampleWordSize() << 3) != mBitsPerChannel;
|
||||
}
|
||||
|
||||
bool AlignmentIsSignificant() const
|
||||
{
|
||||
return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0;
|
||||
}
|
||||
|
||||
bool IsInterleaved() const
|
||||
{
|
||||
return !IsPCM() || !(mFormatFlags & kAudioFormatFlagIsNonInterleaved);
|
||||
}
|
||||
|
||||
// for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these:
|
||||
UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; }
|
||||
UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; }
|
||||
UInt32 NumberChannels() const { return mChannelsPerFrame; }
|
||||
UInt32 SampleWordSize() const { return (mBytesPerFrame > 0) ? mBytesPerFrame / NumberInterleavedChannels() : 0;}
|
||||
|
||||
UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; }
|
||||
UInt32 BytesToFrames(UInt32 nbytes) const {
|
||||
Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames");
|
||||
return nbytes / mBytesPerFrame;
|
||||
}
|
||||
|
||||
bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const
|
||||
{
|
||||
return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved();
|
||||
}
|
||||
|
||||
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
//
|
||||
// manipulation
|
||||
|
||||
void SetCanonical(UInt32 nChannels, bool interleaved)
|
||||
// note: leaves sample rate untouched
|
||||
{
|
||||
mFormatID = kAudioFormatLinearPCM;
|
||||
mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
|
||||
mBitsPerChannel = 32;
|
||||
mChannelsPerFrame = nChannels;
|
||||
mFramesPerPacket = 1;
|
||||
if (interleaved)
|
||||
mBytesPerPacket = mBytesPerFrame = nChannels * sizeof(Float32);
|
||||
else {
|
||||
mBytesPerPacket = mBytesPerFrame = sizeof(Float32);
|
||||
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeNumberChannels(UInt32 nChannels, bool interleaved)
|
||||
// alter an existing format
|
||||
{
|
||||
Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats");
|
||||
UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING
|
||||
if (wordSize == 0)
|
||||
wordSize = (mBitsPerChannel + 7) / 8;
|
||||
mChannelsPerFrame = nChannels;
|
||||
mFramesPerPacket = 1;
|
||||
if (interleaved) {
|
||||
mBytesPerPacket = mBytesPerFrame = nChannels * wordSize;
|
||||
mFormatFlags &= ~kAudioFormatFlagIsNonInterleaved;
|
||||
} else {
|
||||
mBytesPerPacket = mBytesPerFrame = wordSize;
|
||||
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
|
||||
}
|
||||
}
|
||||
|
||||
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
//
|
||||
// other
|
||||
|
||||
void Print() const
|
||||
{
|
||||
Print (stdout);
|
||||
}
|
||||
|
||||
void Print(FILE* file) const
|
||||
{
|
||||
PrintFormat (file, "", "AudioStreamBasicDescription:");
|
||||
}
|
||||
|
||||
void PrintFormat(FILE *f, const char *indent, const char *name) const;
|
||||
|
||||
OSStatus Save(CFPropertyListRef *outData) const;
|
||||
|
||||
OSStatus Restore(CFPropertyListRef &inData);
|
||||
|
||||
// Operations
|
||||
static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); }
|
||||
static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription);
|
||||
static void ResetFormat(AudioStreamBasicDescription& ioDescription);
|
||||
static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription);
|
||||
static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate);
|
||||
#if CoreAudio_Debug
|
||||
static void PrintToLog(const AudioStreamBasicDescription& inDesc);
|
||||
#endif
|
||||
};
|
||||
|
||||
bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
|
||||
bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
|
||||
#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600))
|
||||
inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); }
|
||||
inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); }
|
||||
inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); }
|
||||
inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); }
|
||||
#endif
|
||||
|
||||
bool SanityCheck(const AudioStreamBasicDescription& x);
|
||||
|
||||
|
||||
#endif // __CAStreamBasicDescription_h__
|
|
@ -0,0 +1,23 @@
|
|||
# -*- python -*-
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import glob
|
||||
|
||||
appleutility_files = glob.glob('*.cpp')
|
||||
|
||||
Import('env install_prefix')
|
||||
appleutility = env.Copy()
|
||||
|
||||
appleutility.Append(LINKFLAGS='-framework AudioToolbox')
|
||||
appleutility.Append(LINKFLAGS='-framework AudioUnit')
|
||||
appleutility.Append(LINKFLAGS='-framework CoreFoundation')
|
||||
appleutility.Append(LINKFLAGS='-framework CoreServices')
|
||||
|
||||
libappleutility = appleutility.SharedLibrary('appleutility', appleutility_files)
|
||||
|
||||
Default(libappleutility)
|
||||
|
||||
env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libappleutility))
|
||||
|
||||
env.Alias('tarball', env.Distribute (env['DISTTREE'], ['SConscript'] + appleutility_files + glob.glob('*.h') ))
|
|
@ -83,6 +83,7 @@ send.cc
|
|||
session.cc
|
||||
session_butler.cc
|
||||
session_click.cc
|
||||
session_command.cc
|
||||
session_events.cc
|
||||
session_export.cc
|
||||
session_midi.cc
|
||||
|
@ -215,6 +216,9 @@ ardour.Merge ([
|
|||
if ardour['LIBLO']:
|
||||
ardour.Merge ([ libraries['lo'] ])
|
||||
|
||||
if ardour['COREAUDIO']:
|
||||
ardour.Merge ([ libraries['appleutility'] ])
|
||||
|
||||
ardour.VersionBuild(['version.cc', 'ardour/version.h'], 'SConscript')
|
||||
|
||||
def SharedAsmObjectEmitter(target, source, env):
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace ARDOUR {
|
|||
|
||||
static const jack_nframes_t max_frames = JACK_MAX_FRAMES;
|
||||
|
||||
int init (AudioEngine&, bool with_vst, bool try_optimization);
|
||||
int init (AudioEngine& engine, bool with_vst, bool try_optimization);
|
||||
int cleanup ();
|
||||
|
||||
|
||||
|
|
|
@ -21,36 +21,93 @@
|
|||
#ifndef __ardour_audio_unit_h__
|
||||
#define __ardour_audio_unit_h__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <ardour/plugin.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
struct ComponentDescription;
|
||||
class CAComponent;
|
||||
class CAAudioUnit;
|
||||
class CAComponentDescription;
|
||||
struct AudioBufferList;
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class AudioEngine;
|
||||
class Session;
|
||||
|
||||
class AUPlugin : public ARDOUR::Plugin
|
||||
{
|
||||
public:
|
||||
AUPlugin (AudioEngine& engine, Session& session) : Plugin(engine, session) {};
|
||||
virtual ~AUPlugin () {};
|
||||
AUPlugin (AudioEngine& engine, Session& session, CAComponent* comp);
|
||||
virtual ~AUPlugin ();
|
||||
|
||||
uint32_t unique_id () const;
|
||||
const char * label () const;
|
||||
const char * name () const { return _info->name.c_str(); }
|
||||
const char * maker () const;
|
||||
uint32_t parameter_count () const;
|
||||
float default_value (uint32_t port);
|
||||
jack_nframes_t latency () const;
|
||||
void set_parameter (uint32_t which, float val);
|
||||
float get_parameter (uint32_t which) const;
|
||||
|
||||
int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
|
||||
uint32_t nth_parameter (uint32_t which, bool& ok) const;
|
||||
void activate ();
|
||||
void deactivate ();
|
||||
void set_block_size (jack_nframes_t nframes);
|
||||
|
||||
int connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in, int32_t& out, jack_nframes_t nframes, jack_nframes_t offset);
|
||||
std::set<uint32_t> automatable() const;
|
||||
void store_state (ARDOUR::PluginState&);
|
||||
void restore_state (ARDOUR::PluginState&);
|
||||
string describe_parameter (uint32_t);
|
||||
string state_node_name () const { return "audiounit"; }
|
||||
void print_parameter (uint32_t, char*, uint32_t len) const;
|
||||
|
||||
bool parameter_is_audio (uint32_t) const;
|
||||
bool parameter_is_control (uint32_t) const;
|
||||
bool parameter_is_input (uint32_t) const;
|
||||
bool parameter_is_output (uint32_t) const;
|
||||
|
||||
XMLNode& get_state();
|
||||
int set_state(const XMLNode& node);
|
||||
|
||||
bool save_preset (string name);
|
||||
bool load_preset (const string preset_label);
|
||||
std::vector<std::string> get_presets ();
|
||||
|
||||
bool has_editor () const;
|
||||
|
||||
private:
|
||||
CAComponent* comp;
|
||||
CAAudioUnit* unit;
|
||||
|
||||
AudioBufferList* in_list;
|
||||
AudioBufferList* out_list;
|
||||
|
||||
std::vector<std::pair<uint32_t, uint32_t> > parameter_map;
|
||||
};
|
||||
|
||||
class AUPluginInfo : public PluginInfo {
|
||||
public:
|
||||
typedef boost::shared_ptr<ComponentDescription> CompDescPtr;
|
||||
|
||||
public:
|
||||
AUPluginInfo () { };
|
||||
~AUPluginInfo () { };
|
||||
~AUPluginInfo ();
|
||||
|
||||
CompDescPtr desc;
|
||||
CAComponentDescription* desc;
|
||||
|
||||
static PluginInfoList discover ();
|
||||
PluginPtr load (Session& session);
|
||||
|
||||
private:
|
||||
friend class PluginManager;
|
||||
static std::string get_name (CAComponentDescription&);
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
|
||||
|
@ -58,4 +115,3 @@ typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
|
|||
} // namespace ARDOUR
|
||||
|
||||
#endif // __ardour_audio_unit_h__
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ struct ControlEvent {
|
|||
|
||||
};
|
||||
|
||||
class AutomationList : public StateManager
|
||||
class AutomationList : public StateManager, public Stateful
|
||||
{
|
||||
public:
|
||||
typedef std::list<ControlEvent*> AutomationEventList;
|
||||
|
@ -153,6 +153,11 @@ class AutomationList : public StateManager
|
|||
virtual void store_state (XMLNode& node) const;
|
||||
virtual void load_state (const XMLNode&);
|
||||
|
||||
XMLNode &get_state(void);
|
||||
int set_state (const XMLNode &s);
|
||||
|
||||
PBD::ID id() { return _id; }
|
||||
|
||||
void set_max_xval (double);
|
||||
double get_max_xval() const { return max_xval; }
|
||||
|
||||
|
@ -179,6 +184,7 @@ class AutomationList : public StateManager
|
|||
};
|
||||
|
||||
protected:
|
||||
PBD::ID _id;
|
||||
struct State : public ARDOUR::StateManager::State {
|
||||
AutomationEventList events;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -137,6 +137,17 @@ class LadspaPlugin : public ARDOUR::Plugin
|
|||
void run (jack_nframes_t nsamples);
|
||||
void latency_compute_run ();
|
||||
};
|
||||
}
|
||||
|
||||
class LadspaPluginInfo : public PluginInfo {
|
||||
public:
|
||||
LadspaPluginInfo () { };
|
||||
~LadspaPluginInfo () { };
|
||||
|
||||
PluginPtr load (Session& session);
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<LadspaPluginInfo> LadspaPluginInfoPtr;
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_ladspa_plugin_h__ */
|
||||
|
|
|
@ -119,7 +119,10 @@ class Location : public Stateful, public sigc::trackable
|
|||
XMLNode& get_state (void);
|
||||
int set_state (const XMLNode&);
|
||||
|
||||
PBD::ID id() { return _id; }
|
||||
|
||||
private:
|
||||
PBD::ID _id;
|
||||
string _name;
|
||||
jack_nframes_t _start;
|
||||
jack_nframes_t _end;
|
||||
|
@ -145,6 +148,7 @@ class Locations : public Stateful, public StateManager
|
|||
|
||||
XMLNode& get_state (void);
|
||||
int set_state (const XMLNode&);
|
||||
PBD::ID id() { return _id; }
|
||||
|
||||
Location* auto_loop_location () const;
|
||||
Location* auto_punch_location () const;
|
||||
|
@ -197,6 +201,8 @@ class Locations : public Stateful, public StateManager
|
|||
|
||||
Change restore_state (StateManager::State&);
|
||||
StateManager::State* state_factory (std::string why) const;
|
||||
|
||||
PBD::ID _id;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
|
|
@ -76,6 +76,7 @@ class Playlist : public Stateful, public StateManager {
|
|||
EditMode get_edit_mode() const { return _edit_mode; }
|
||||
void set_edit_mode (EditMode);
|
||||
|
||||
PBD::ID id() { return _id; }
|
||||
/* Editing operations */
|
||||
|
||||
void add_region (const Region&, jack_nframes_t position, float times = 1, bool with_save = true);
|
||||
|
@ -273,6 +274,8 @@ class Playlist : public Stateful, public StateManager {
|
|||
void unset_freeze_child (Playlist*);
|
||||
|
||||
void timestamp_layer_op (Region&);
|
||||
|
||||
PBD::ID _id;
|
||||
};
|
||||
|
||||
} /* namespace ARDOUR */
|
||||
|
|
|
@ -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
|
||||
|
@ -18,8 +18,8 @@
|
|||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef __ardour_ladspa_h__
|
||||
#define __ardour_ladspa_h__
|
||||
#ifndef __ardour_plugin_h__
|
||||
#define __ardour_plugin_h__
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <sigc++/signal.h>
|
||||
|
@ -46,6 +46,9 @@ namespace ARDOUR {
|
|||
class AudioEngine;
|
||||
class Session;
|
||||
|
||||
class Plugin;
|
||||
typedef boost::shared_ptr<Plugin> PluginPtr;
|
||||
|
||||
class PluginInfo {
|
||||
public:
|
||||
enum Type {
|
||||
|
@ -54,11 +57,12 @@ class PluginInfo {
|
|||
VST
|
||||
};
|
||||
|
||||
PluginInfo () { };
|
||||
PluginInfo () { }
|
||||
PluginInfo (const PluginInfo &o)
|
||||
: name(o.name), n_inputs(o.n_inputs), n_outputs(o.n_outputs),
|
||||
unique_id(o.unique_id), path (o.path), index(o.index) {}
|
||||
~PluginInfo () { };
|
||||
virtual ~PluginInfo () { }
|
||||
|
||||
string name;
|
||||
string category;
|
||||
uint32_t n_inputs;
|
||||
|
@ -67,7 +71,9 @@ class PluginInfo {
|
|||
|
||||
long unique_id;
|
||||
|
||||
private:
|
||||
virtual PluginPtr load (Session& session) = 0;
|
||||
|
||||
protected:
|
||||
friend class PluginManager;
|
||||
string path;
|
||||
uint32_t index;
|
||||
|
@ -82,7 +88,7 @@ class Plugin : public Stateful, public sigc::trackable
|
|||
public:
|
||||
Plugin (ARDOUR::AudioEngine&, ARDOUR::Session&);
|
||||
Plugin (const Plugin&);
|
||||
~Plugin ();
|
||||
virtual ~Plugin ();
|
||||
|
||||
struct ParameterDescriptor {
|
||||
|
||||
|
@ -143,8 +149,8 @@ class Plugin : public Stateful, public sigc::trackable
|
|||
|
||||
PBD::Controllable *get_nth_control (uint32_t);
|
||||
|
||||
PluginInfo & get_info() { return _info; }
|
||||
void set_info (const PluginInfo &inf) { _info = inf; }
|
||||
PluginInfoPtr get_info() { return _info; }
|
||||
void set_info (const PluginInfoPtr inf) { _info = inf; }
|
||||
|
||||
ARDOUR::AudioEngine& engine() const { return _engine; }
|
||||
ARDOUR::Session& session() const { return _session; }
|
||||
|
@ -155,7 +161,7 @@ class Plugin : public Stateful, public sigc::trackable
|
|||
protected:
|
||||
ARDOUR::AudioEngine& _engine;
|
||||
ARDOUR::Session& _session;
|
||||
PluginInfo _info;
|
||||
PluginInfoPtr _info;
|
||||
uint32_t _cycles;
|
||||
map<string,string> presets;
|
||||
bool save_preset(string name, string domain /* vst, ladspa etc. */);
|
||||
|
@ -181,9 +187,7 @@ class Plugin : public Stateful, public sigc::trackable
|
|||
vector<PortControllable*> controls;
|
||||
};
|
||||
|
||||
/* this is actually defined in plugin_manager.cc */
|
||||
|
||||
boost::shared_ptr<Plugin> find_plugin(ARDOUR::Session&, string name, long unique_id, PluginInfo::Type);
|
||||
PluginPtr find_plugin(ARDOUR::Session&, string name, long unique_id, PluginInfo::Type);
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
|
|
|
@ -5,42 +5,34 @@
|
|||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <ardour/types.h>
|
||||
#include <ardour/plugin.h>
|
||||
#include <ardour/audio_unit.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class PluginInfo;
|
||||
class Plugin;
|
||||
class Session;
|
||||
class AudioEngine;
|
||||
|
||||
class PluginManager {
|
||||
public:
|
||||
PluginManager (ARDOUR::AudioEngine&);
|
||||
PluginManager ();
|
||||
~PluginManager ();
|
||||
|
||||
ARDOUR::PluginInfoList &vst_plugin_info () { return _vst_plugin_info; }
|
||||
ARDOUR::PluginInfoList &ladspa_plugin_info () { return _ladspa_plugin_info; }
|
||||
ARDOUR::PluginInfoList &au_plugin_info () { return _au_plugin_info; }
|
||||
|
||||
void refresh ();
|
||||
|
||||
int add_ladspa_directory (std::string dirpath);
|
||||
int add_vst_directory (std::string dirpath);
|
||||
|
||||
boost::shared_ptr<Plugin> load (ARDOUR::Session& s, PluginInfoPtr info);
|
||||
|
||||
static PluginManager* the_manager() { return _manager; }
|
||||
|
||||
private:
|
||||
ARDOUR::AudioEngine& _engine;
|
||||
ARDOUR::PluginInfoList _vst_plugin_info;
|
||||
ARDOUR::PluginInfoList _ladspa_plugin_info;
|
||||
ARDOUR::PluginInfoList _au_plugin_info;
|
||||
std::map<uint32_t, std::string> rdf_type;
|
||||
|
||||
std::string ladspa_path;
|
||||
|
@ -60,8 +52,6 @@ class PluginManager {
|
|||
int ladspa_discover_from_path (std::string path);
|
||||
int ladspa_discover (std::string path);
|
||||
|
||||
int au_discover ();
|
||||
|
||||
std::string get_ladspa_category (uint32_t id);
|
||||
|
||||
static PluginManager* _manager; // singleton
|
||||
|
|
|
@ -97,7 +97,7 @@ class Route : public IO
|
|||
virtual int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
jack_nframes_t offset, bool can_record, bool rec_monitors_input);
|
||||
virtual void toggle_monitor_input ();
|
||||
virtual bool can_record() const { return false; }
|
||||
virtual bool can_record() { return false; }
|
||||
virtual void set_record_enable (bool yn, void *src) {}
|
||||
virtual bool record_enabled() const { return false; }
|
||||
virtual void handle_transport_stopped (bool abort, bool did_locate, bool flush_redirects);
|
||||
|
|
|
@ -489,6 +489,7 @@ class Session : public sigc::trackable, public Stateful
|
|||
int save_state (string snapshot_name, bool pending = false);
|
||||
int restore_state (string snapshot_name);
|
||||
int save_template (string template_name);
|
||||
int save_history ();
|
||||
|
||||
static int rename_template (string old_name, string new_name);
|
||||
|
||||
|
@ -501,7 +502,7 @@ class Session : public sigc::trackable, public Stateful
|
|||
static vector<string*>* possible_states(string path);
|
||||
|
||||
XMLNode& get_state();
|
||||
int set_state(const XMLNode& node);
|
||||
int set_state(const XMLNode& node); // not idempotent
|
||||
XMLNode& get_template();
|
||||
|
||||
void add_instant_xml (XMLNode&, const std::string& dir);
|
||||
|
@ -844,23 +845,65 @@ class Session : public sigc::trackable, public Stateful
|
|||
string next_undo() const { return history.next_undo(); }
|
||||
string next_redo() const { return history.next_redo(); }
|
||||
|
||||
void begin_reversible_command (string cmd_name, UndoAction *private_undo = 0);
|
||||
void commit_reversible_command (UndoAction* private_redo = 0);
|
||||
void begin_reversible_command (string cmd_name);
|
||||
void commit_reversible_command (Command* cmd = 0);
|
||||
|
||||
void add_undo (const UndoAction& ua) {
|
||||
current_cmd.add_undo (ua);
|
||||
}
|
||||
void add_redo (const UndoAction& ua) {
|
||||
current_cmd.add_redo (ua);
|
||||
}
|
||||
void add_redo_no_execute (const UndoAction& ua) {
|
||||
current_cmd.add_redo_no_execute (ua);
|
||||
void add_command (Command *const cmd) {
|
||||
current_trans.add_command (cmd);
|
||||
}
|
||||
|
||||
UndoAction global_solo_memento (void *src);
|
||||
UndoAction global_mute_memento (void *src);
|
||||
UndoAction global_record_enable_memento (void *src);
|
||||
UndoAction global_metering_memento (void *src);
|
||||
// these commands are implemented in libs/ardour/session_command.cc
|
||||
class GlobalSoloStateCommand : public Command
|
||||
{
|
||||
GlobalRouteBooleanState before, after;
|
||||
Session &sess;
|
||||
void *src;
|
||||
public:
|
||||
GlobalSoloStateCommand(Session &, void *src);
|
||||
void operator()();
|
||||
void undo();
|
||||
XMLNode &get_state();
|
||||
void mark();
|
||||
};
|
||||
|
||||
class GlobalMuteStateCommand : public Command
|
||||
{
|
||||
GlobalRouteBooleanState before, after;
|
||||
Session &sess;
|
||||
void *src;
|
||||
public:
|
||||
GlobalMuteStateCommand(Session &, void *src);
|
||||
void operator()();
|
||||
void undo();
|
||||
XMLNode &get_state();
|
||||
void mark();
|
||||
};
|
||||
|
||||
class GlobalRecordEnableStateCommand : public Command
|
||||
{
|
||||
GlobalRouteBooleanState before, after;
|
||||
Session &sess;
|
||||
void *src;
|
||||
public:
|
||||
GlobalRecordEnableStateCommand(Session &, void *src);
|
||||
void operator()();
|
||||
void undo();
|
||||
XMLNode &get_state();
|
||||
void mark();
|
||||
};
|
||||
|
||||
class GlobalMeteringStateCommand : public Command
|
||||
{
|
||||
GlobalRouteMeterState before, after;
|
||||
Session &sess;
|
||||
void *src;
|
||||
public:
|
||||
GlobalMeteringStateCommand(Session &, void *src);
|
||||
void operator()();
|
||||
void undo();
|
||||
XMLNode &get_state();
|
||||
void mark();
|
||||
};
|
||||
|
||||
/* edit mode */
|
||||
|
||||
|
@ -1635,7 +1678,7 @@ class Session : public sigc::trackable, public Stateful
|
|||
void reverse_diskstream_buffers ();
|
||||
|
||||
UndoHistory history;
|
||||
UndoCommand current_cmd;
|
||||
UndoTransaction current_trans;
|
||||
|
||||
GlobalRouteBooleanState get_global_route_boolean (bool (Route::*method)(void) const);
|
||||
GlobalRouteMeterState get_global_route_metering ();
|
||||
|
|
|
@ -35,6 +35,8 @@ class StateManager : public sigc::trackable
|
|||
|
||||
state_id_t _current_state_id;
|
||||
|
||||
virtual bool should_save_state () const { return true; }
|
||||
|
||||
static void prohibit_save ();
|
||||
static void allow_save (const char* why, bool dosave);
|
||||
|
||||
|
|
|
@ -238,6 +238,7 @@ class TempoMap : public Stateful, public StateManager {
|
|||
|
||||
XMLNode& get_state (void);
|
||||
int set_state (const XMLNode&);
|
||||
PBD::ID id() { return _id; }
|
||||
|
||||
void dump (std::ostream&) const;
|
||||
void clear ();
|
||||
|
@ -315,6 +316,8 @@ class TempoMap : public Stateful, public StateManager {
|
|||
|
||||
void save_state (std::string why);
|
||||
|
||||
PBD::ID _id;
|
||||
|
||||
};
|
||||
|
||||
}; /* namespace ARDOUR */
|
||||
|
|
|
@ -48,7 +48,7 @@ class Track : public Route
|
|||
|
||||
void toggle_monitor_input ();
|
||||
|
||||
bool can_record() const { return true; }
|
||||
virtual bool can_record();
|
||||
|
||||
Diskstream& diskstream() const { return *_diskstream; }
|
||||
|
||||
|
|
|
@ -104,6 +104,15 @@ class VSTPlugin : public ARDOUR::Plugin
|
|||
bool been_resumed;
|
||||
};
|
||||
|
||||
}
|
||||
class VSTPluginInfo : public PluginInfo
|
||||
{
|
||||
public:
|
||||
VSTPluginInfo () {}
|
||||
~VSTPluginInfo () {}
|
||||
|
||||
PluginPtr load (Session& session);
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_vst_plugin_h__ */
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <pbd/basename.h>
|
||||
#include <glibmm/thread.h>
|
||||
#include <pbd/xml++.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include <ardour/ardour.h>
|
||||
#include <ardour/audioengine.h>
|
||||
|
@ -1594,7 +1595,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
|
|||
|
||||
// cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
|
||||
|
||||
_session.add_undo (_playlist->get_memento());
|
||||
XMLNode &before = _playlist->get_state();
|
||||
_playlist->freeze ();
|
||||
|
||||
for (buffer_position = channels[0].write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
|
||||
|
@ -1625,7 +1626,8 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
|
|||
}
|
||||
|
||||
_playlist->thaw ();
|
||||
_session.add_redo_no_execute (_playlist->get_memento());
|
||||
XMLNode &after = _playlist->get_state();
|
||||
_session.add_command (new MementoCommand<Playlist>(*_playlist, before, after));
|
||||
}
|
||||
|
||||
mark_write_completed = true;
|
||||
|
|
|
@ -18,95 +18,361 @@
|
|||
|
||||
*/
|
||||
|
||||
#include <pbd/transmitter.h>
|
||||
#include <pbd/xml++.h>
|
||||
|
||||
#include <ardour/audioengine.h>
|
||||
#include <ardour/audio_unit.h>
|
||||
#include <ardour/session.h>
|
||||
#include <ardour/utils.h>
|
||||
|
||||
#include <appleutility/CAAudioUnit.h>
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
using namespace ARDOUR;
|
||||
|
||||
AUPlugin::AUPlugin (AudioEngine& engine, Session& session, CAComponent* _comp)
|
||||
:
|
||||
Plugin (engine, session),
|
||||
comp (_comp),
|
||||
unit (new CAAudioUnit)
|
||||
{
|
||||
OSErr err = CAAudioUnit::Open (*comp, *unit);
|
||||
if (err != noErr) {
|
||||
error << _("AudioUnit: Could not convert CAComponent to CAAudioUnit") << endmsg;
|
||||
delete unit;
|
||||
delete comp;
|
||||
throw failed_constructor ();
|
||||
}
|
||||
|
||||
unit->Initialize ();
|
||||
}
|
||||
|
||||
AUPlugin::~AUPlugin ()
|
||||
{
|
||||
if (unit) {
|
||||
unit->Uninitialize ();
|
||||
delete unit;
|
||||
}
|
||||
|
||||
if (comp) {
|
||||
delete comp;
|
||||
}
|
||||
|
||||
if (in_list) {
|
||||
delete in_list;
|
||||
}
|
||||
|
||||
if (out_list) {
|
||||
delete out_list;
|
||||
}
|
||||
}
|
||||
|
||||
AUPluginInfo::~AUPluginInfo ()
|
||||
{
|
||||
if (desc) {
|
||||
delete desc;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
AUPlugin::unique_id () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
AUPlugin::label () const
|
||||
{
|
||||
return "AUPlugin label";
|
||||
}
|
||||
|
||||
const char *
|
||||
AUPlugin::maker () const
|
||||
{
|
||||
return "AUplugin maker";
|
||||
}
|
||||
|
||||
uint32_t
|
||||
AUPlugin::parameter_count () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
float
|
||||
AUPlugin::default_value (uint32_t port)
|
||||
{
|
||||
// AudioUnits don't have default values. Maybe presets though?
|
||||
return 0;
|
||||
}
|
||||
|
||||
jack_nframes_t
|
||||
AUPlugin::latency () const
|
||||
{
|
||||
return unit->Latency ();
|
||||
}
|
||||
|
||||
void
|
||||
AUPlugin::set_parameter (uint32_t which, float val)
|
||||
{
|
||||
unit->SetParameter (parameter_map[which].first, parameter_map[which].second, 0, val);
|
||||
}
|
||||
|
||||
float
|
||||
AUPlugin::get_parameter (uint32_t which) const
|
||||
{
|
||||
float outValue = 0.0;
|
||||
|
||||
unit->GetParameter(parameter_map[which].first, parameter_map[which].second, 0, outValue);
|
||||
|
||||
return outValue;
|
||||
}
|
||||
|
||||
int
|
||||
AUPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
AUPlugin::nth_parameter (uint32_t which, bool& ok) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
AUPlugin::activate ()
|
||||
{
|
||||
unit->GlobalReset ();
|
||||
}
|
||||
|
||||
void
|
||||
AUPlugin::deactivate ()
|
||||
{
|
||||
// not needed. GlobalReset () takes care of it.
|
||||
}
|
||||
|
||||
void
|
||||
AUPlugin::set_block_size (jack_nframes_t nframes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
AUPlugin::connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in, int32_t& out, jack_nframes_t nframes, jack_nframes_t offset)
|
||||
{
|
||||
AudioUnitRenderActionFlags flags = 0;
|
||||
AudioTimeStamp ts;
|
||||
|
||||
AudioBufferList abl;
|
||||
abl.mNumberBuffers = 1;
|
||||
abl.mBuffers[0].mNumberChannels = 1;
|
||||
abl.mBuffers[0].mDataByteSize = nframes * sizeof(Sample);
|
||||
abl.mBuffers[0].mData = &bufs[0];
|
||||
|
||||
|
||||
unit->Render (&flags, &ts, 0, 0, &abl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
set<uint32_t>
|
||||
AUPlugin::automatable() const
|
||||
{
|
||||
set<uint32_t> automates;
|
||||
|
||||
return automates;
|
||||
}
|
||||
|
||||
void
|
||||
AUPlugin::store_state (ARDOUR::PluginState&)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
AUPlugin::restore_state (ARDOUR::PluginState&)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
string
|
||||
AUPlugin::describe_parameter (uint32_t)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
void
|
||||
AUPlugin::print_parameter (uint32_t, char*, uint32_t len) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
AUPlugin::parameter_is_audio (uint32_t) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
AUPlugin::parameter_is_control (uint32_t) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
AUPlugin::parameter_is_input (uint32_t) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
AUPlugin::parameter_is_output (uint32_t) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
XMLNode&
|
||||
AUPlugin::get_state()
|
||||
{
|
||||
XMLNode* root = new XMLNode (state_node_name());
|
||||
|
||||
return *root;
|
||||
}
|
||||
|
||||
int
|
||||
AUPlugin::set_state(const XMLNode& node)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool
|
||||
AUPlugin::save_preset (string name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
AUPlugin::load_preset (const string preset_label)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
vector<string>
|
||||
AUPlugin::get_presets ()
|
||||
{
|
||||
vector<string> presets;
|
||||
|
||||
return presets;
|
||||
}
|
||||
|
||||
bool
|
||||
AUPlugin::has_editor () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginPtr
|
||||
AUPluginInfo::load (Session& session)
|
||||
{
|
||||
try {
|
||||
PluginPtr plugin;
|
||||
|
||||
CAComponent* comp = new CAComponent(*desc);
|
||||
|
||||
if (!comp->IsValid()) {
|
||||
error << ("AudioUnit: not a valid Component") << endmsg;
|
||||
} else {
|
||||
plugin.reset (new AUPlugin (session.engine(), session, comp));
|
||||
}
|
||||
|
||||
plugin->set_info(PluginInfoPtr(new AUPluginInfo(*this)));
|
||||
return plugin;
|
||||
}
|
||||
|
||||
catch (failed_constructor &err) {
|
||||
return PluginPtr ((Plugin*) 0);
|
||||
}
|
||||
}
|
||||
|
||||
PluginInfoList
|
||||
AUPluginInfo::discover ()
|
||||
{
|
||||
PluginInfoList plugs;
|
||||
|
||||
int numTypes = 2; // this magic number was retrieved from the apple AUHost example.
|
||||
|
||||
ComponentDescription desc;
|
||||
CAComponentDescription desc;
|
||||
desc.componentFlags = 0;
|
||||
desc.componentFlagsMask = 0;
|
||||
desc.componentSubType = 0;
|
||||
desc.componentManufacturer = 0;
|
||||
desc.componentType = kAudioUnitType_Effect;
|
||||
|
||||
vector<ComponentDescription> vCompDescs;
|
||||
|
||||
for (int i = 0; i < numTypes; ++i) {
|
||||
if (i == 1) {
|
||||
desc.componentType = kAudioUnitType_MusicEffect;
|
||||
} else {
|
||||
desc.componentType = kAudioUnitType_Effect;
|
||||
}
|
||||
|
||||
Component comp = 0;
|
||||
|
||||
comp = FindNextComponent (NULL, &desc);
|
||||
while (comp != NULL) {
|
||||
ComponentDescription temp;
|
||||
GetComponentInfo (comp, &temp, NULL, NULL, NULL);
|
||||
vCompDescs.push_back(temp);
|
||||
comp = FindNextComponent (comp, &desc);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < vCompDescs.size(); ++i) {
|
||||
|
||||
// the following large block is just for determining the name of the plugin.
|
||||
CFStringRef itemName = NULL;
|
||||
// Marc Poirier -style item name
|
||||
Component auComponent = FindNextComponent (0, &(vCompDescs[i]));
|
||||
if (auComponent != NULL) {
|
||||
ComponentDescription dummydesc;
|
||||
Handle nameHandle = NewHandle(sizeof(void*));
|
||||
if (nameHandle != NULL) {
|
||||
OSErr err = GetComponentInfo(auComponent, &dummydesc, nameHandle, NULL, NULL);
|
||||
if (err == noErr) {
|
||||
ConstStr255Param nameString = (ConstStr255Param) (*nameHandle);
|
||||
if (nameString != NULL) {
|
||||
itemName = CFStringCreateWithPascalString(kCFAllocatorDefault, nameString, CFStringGetSystemEncoding());
|
||||
}
|
||||
}
|
||||
DisposeHandle(nameHandle);
|
||||
}
|
||||
}
|
||||
|
||||
// if Marc-style fails, do the original way
|
||||
if (itemName == NULL) {
|
||||
CFStringRef compTypeString = UTCreateStringForOSType(vCompDescs[i].componentType);
|
||||
CFStringRef compSubTypeString = UTCreateStringForOSType(vCompDescs[i].componentSubType);
|
||||
CFStringRef compManufacturerString = UTCreateStringForOSType(vCompDescs[i].componentManufacturer);
|
||||
|
||||
itemName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ - %@ - %@"),
|
||||
compTypeString, compManufacturerString, compSubTypeString);
|
||||
|
||||
if (compTypeString != NULL)
|
||||
CFRelease(compTypeString);
|
||||
if (compSubTypeString != NULL)
|
||||
CFRelease(compSubTypeString);
|
||||
if (compManufacturerString != NULL)
|
||||
CFRelease(compManufacturerString);
|
||||
}
|
||||
string realname = CFStringRefToStdString(itemName);
|
||||
Component comp = 0;
|
||||
|
||||
comp = FindNextComponent (NULL, &desc);
|
||||
while (comp != NULL) {
|
||||
CAComponentDescription temp;
|
||||
GetComponentInfo (comp, &temp, NULL, NULL, NULL);
|
||||
|
||||
AUPluginInfoPtr plug(new AUPluginInfo);
|
||||
plug->name = realname;
|
||||
plug->name = AUPluginInfo::get_name (temp);
|
||||
plug->type = PluginInfo::AudioUnit;
|
||||
plug->n_inputs = 0;
|
||||
plug->n_outputs = 0;
|
||||
plug->category = "AudioUnit";
|
||||
plug->desc = new CAComponentDescription(temp);
|
||||
|
||||
plugs.push_back(plug);
|
||||
|
||||
comp = FindNextComponent (comp, &desc);
|
||||
}
|
||||
|
||||
return plugs;
|
||||
}
|
||||
|
||||
string
|
||||
AUPluginInfo::get_name (CAComponentDescription& comp_desc)
|
||||
{
|
||||
CFStringRef itemName = NULL;
|
||||
// Marc Poirier -style item name
|
||||
CAComponent auComponent (comp_desc);
|
||||
if (auComponent.IsValid()) {
|
||||
CAComponentDescription dummydesc;
|
||||
Handle nameHandle = NewHandle(sizeof(void*));
|
||||
if (nameHandle != NULL) {
|
||||
OSErr err = GetComponentInfo(auComponent.Comp(), &dummydesc, nameHandle, NULL, NULL);
|
||||
if (err == noErr) {
|
||||
ConstStr255Param nameString = (ConstStr255Param) (*nameHandle);
|
||||
if (nameString != NULL) {
|
||||
itemName = CFStringCreateWithPascalString(kCFAllocatorDefault, nameString, CFStringGetSystemEncoding());
|
||||
}
|
||||
}
|
||||
DisposeHandle(nameHandle);
|
||||
}
|
||||
}
|
||||
|
||||
// if Marc-style fails, do the original way
|
||||
if (itemName == NULL) {
|
||||
CFStringRef compTypeString = UTCreateStringForOSType(comp_desc.componentType);
|
||||
CFStringRef compSubTypeString = UTCreateStringForOSType(comp_desc.componentSubType);
|
||||
CFStringRef compManufacturerString = UTCreateStringForOSType(comp_desc.componentManufacturer);
|
||||
|
||||
itemName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ - %@ - %@"),
|
||||
compTypeString, compManufacturerString, compSubTypeString);
|
||||
|
||||
if (compTypeString != NULL)
|
||||
CFRelease(compTypeString);
|
||||
if (compSubTypeString != NULL)
|
||||
CFRelease(compSubTypeString);
|
||||
if (compManufacturerString != NULL)
|
||||
CFRelease(compManufacturerString);
|
||||
}
|
||||
|
||||
return CFStringRefToStdString(itemName);
|
||||
}
|
||||
|
|
|
@ -1246,3 +1246,17 @@ AutomationList::load_state (const XMLNode& node)
|
|||
add (x, y);
|
||||
}
|
||||
}
|
||||
|
||||
XMLNode &AutomationList::get_state ()
|
||||
{
|
||||
XMLNode *node = new XMLNode("AutomationList");
|
||||
store_state(*node);
|
||||
return *node;
|
||||
}
|
||||
|
||||
int AutomationList::set_state(const XMLNode &s)
|
||||
{
|
||||
load_state(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -193,9 +193,9 @@ setup_midi (AudioEngine& engine )
|
|||
}
|
||||
|
||||
int
|
||||
ARDOUR::init (AudioEngine& engine, bool use_vst, bool try_optimization)
|
||||
ARDOUR::init (ARDOUR::AudioEngine& engine, bool use_vst, bool try_optimization)
|
||||
{
|
||||
bool generic_mix_functions = true;
|
||||
bool generic_mix_functions = true;
|
||||
|
||||
(void) bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
|
||||
|
@ -303,7 +303,7 @@ ARDOUR::init (AudioEngine& engine, bool use_vst, bool try_optimization)
|
|||
}
|
||||
|
||||
/* singleton - first object is "it" */
|
||||
new PluginManager (engine);
|
||||
new PluginManager ();
|
||||
|
||||
/* singleton - first object is "it" */
|
||||
new ControlProtocolManager ();
|
||||
|
|
|
@ -186,25 +186,25 @@ PluginInsert::auto_state_changed (uint32_t which)
|
|||
uint32_t
|
||||
PluginInsert::output_streams() const
|
||||
{
|
||||
return _plugins[0]->get_info().n_outputs * _plugins.size();
|
||||
return _plugins[0]->get_info()->n_outputs * _plugins.size();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PluginInsert::input_streams() const
|
||||
{
|
||||
return _plugins[0]->get_info().n_inputs * _plugins.size();
|
||||
return _plugins[0]->get_info()->n_inputs * _plugins.size();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PluginInsert::natural_output_streams() const
|
||||
{
|
||||
return _plugins[0]->get_info().n_outputs;
|
||||
return _plugins[0]->get_info()->n_outputs;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PluginInsert::natural_input_streams() const
|
||||
{
|
||||
return _plugins[0]->get_info().n_inputs;
|
||||
return _plugins[0]->get_info()->n_inputs;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -214,7 +214,7 @@ PluginInsert::is_generator() const
|
|||
a specific "instrument" flag, for example.
|
||||
*/
|
||||
|
||||
return _plugins[0]->get_info().n_inputs == 0;
|
||||
return _plugins[0]->get_info()->n_inputs == 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -350,7 +350,7 @@ PluginInsert::silence (jack_nframes_t nframes, jack_nframes_t offset)
|
|||
|
||||
if (active()) {
|
||||
for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
|
||||
n = (*i) -> get_info().n_inputs;
|
||||
n = (*i) -> get_info()->n_inputs;
|
||||
(*i)->connect_and_run (_session.get_silent_buffers (n), n, in_index, out_index, nframes, offset);
|
||||
}
|
||||
}
|
||||
|
@ -367,8 +367,8 @@ PluginInsert::run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframe
|
|||
connect_and_run (bufs, nbufs, nframes, offset, false);
|
||||
}
|
||||
} else {
|
||||
uint32_t in = _plugins[0]->get_info().n_inputs;
|
||||
uint32_t out = _plugins[0]->get_info().n_outputs;
|
||||
uint32_t in = _plugins[0]->get_info()->n_inputs;
|
||||
uint32_t out = _plugins[0]->get_info()->n_outputs;
|
||||
|
||||
if (out > in) {
|
||||
|
||||
|
@ -524,7 +524,7 @@ PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
|
|||
int32_t
|
||||
PluginInsert::compute_output_streams (int32_t cnt) const
|
||||
{
|
||||
return _plugins[0]->get_info().n_outputs * cnt;
|
||||
return _plugins[0]->get_info()->n_outputs * cnt;
|
||||
}
|
||||
|
||||
int32_t
|
||||
|
@ -536,8 +536,8 @@ PluginInsert::configure_io (int32_t magic, int32_t in, int32_t out)
|
|||
int32_t
|
||||
PluginInsert::can_support_input_configuration (int32_t in) const
|
||||
{
|
||||
int32_t outputs = _plugins[0]->get_info().n_outputs;
|
||||
int32_t inputs = _plugins[0]->get_info().n_inputs;
|
||||
int32_t outputs = _plugins[0]->get_info()->n_outputs;
|
||||
int32_t inputs = _plugins[0]->get_info()->n_inputs;
|
||||
|
||||
if (inputs == 0) {
|
||||
|
||||
|
@ -591,7 +591,7 @@ PluginInsert::state (bool full)
|
|||
node->add_property("id", string(buf));
|
||||
if (_plugins[0]->state_node_name() == "ladspa") {
|
||||
char buf[32];
|
||||
snprintf (buf, sizeof (buf), "%ld", _plugins[0]->get_info().unique_id);
|
||||
snprintf (buf, sizeof (buf), "%ld", _plugins[0]->get_info()->unique_id);
|
||||
node->add_property("unique-id", string(buf));
|
||||
}
|
||||
node->add_property("count", string_compose("%1", _plugins.size()));
|
||||
|
@ -761,7 +761,7 @@ PluginInsert::set_state(const XMLNode& node)
|
|||
}
|
||||
|
||||
// The name of the PluginInsert comes from the plugin, nothing else
|
||||
set_name(plugin->get_info().name,this);
|
||||
set_name(plugin->get_info()->name,this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -170,7 +170,7 @@ IO::silence (jack_nframes_t nframes, jack_nframes_t offset)
|
|||
void
|
||||
IO::apply_declick (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity)
|
||||
{
|
||||
jack_nframes_t declick = min ((jack_nframes_t)4096, nframes);
|
||||
jack_nframes_t declick = min ((jack_nframes_t)128, nframes);
|
||||
gain_t delta;
|
||||
Sample *buffer;
|
||||
double fractional_shift;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2000-2002 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
|
||||
|
@ -641,3 +641,26 @@ LadspaPlugin::latency_compute_run ()
|
|||
run (bufsize);
|
||||
deactivate ();
|
||||
}
|
||||
|
||||
PluginPtr
|
||||
LadspaPluginInfo::load (Session& session)
|
||||
{
|
||||
try {
|
||||
PluginPtr plugin;
|
||||
void *module;
|
||||
|
||||
if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
|
||||
error << string_compose(_("LADSPA: cannot load module from \"%1\""), path) << endmsg;
|
||||
error << dlerror() << endmsg;
|
||||
} else {
|
||||
plugin.reset (new LadspaPlugin (module, session.engine(), session, index, session.frame_rate()));
|
||||
}
|
||||
|
||||
plugin->set_info(PluginInfoPtr(new LadspaPluginInfo(*this)));
|
||||
return plugin;
|
||||
}
|
||||
|
||||
catch (failed_constructor &err) {
|
||||
return PluginPtr ((Plugin*) 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
#include <ardour/session.h>
|
||||
#include <ardour/audioengine.h>
|
||||
#include <ardour/plugin.h>
|
||||
#include <ardour/ladspa_plugin.h>
|
||||
#include <ardour/plugin_manager.h>
|
||||
|
||||
#include <pbd/stl_delete.h>
|
||||
|
||||
|
@ -240,3 +242,43 @@ Plugin::save_preset (string name, string domain)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
PluginPtr
|
||||
ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginInfo::Type type)
|
||||
{
|
||||
PluginManager *mgr = PluginManager::the_manager();
|
||||
PluginInfoList plugs;
|
||||
|
||||
switch (type) {
|
||||
case PluginInfo::LADSPA:
|
||||
plugs = mgr->ladspa_plugin_info();
|
||||
break;
|
||||
|
||||
#ifdef VST_SUPPORT
|
||||
case PluginInfo::VST:
|
||||
plugs = mgr->vst_plugin_info();
|
||||
unique_id = 0; // VST plugins don't have a unique id.
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_COREAUDIO
|
||||
case PluginInfo::AudioUnit:
|
||||
plugs = AUPluginInfo::discover ();
|
||||
unique_id = 0; // Neither do AU.
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return PluginPtr ((Plugin *) 0);
|
||||
}
|
||||
|
||||
PluginInfoList::iterator i;
|
||||
for (i = plugs.begin(); i != plugs.end(); ++i) {
|
||||
if ((name == "" || (*i)->name == name) &&
|
||||
(unique_id == 0 || (*i)->unique_id == unique_id)) {
|
||||
return (*i)->load (session);
|
||||
}
|
||||
}
|
||||
|
||||
return PluginPtr ((Plugin*) 0);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2000-2004 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
|
||||
|
@ -36,8 +36,10 @@
|
|||
#include <ardour/plugin_manager.h>
|
||||
#include <ardour/plugin.h>
|
||||
#include <ardour/ladspa_plugin.h>
|
||||
|
||||
#ifdef VST_SUPPORT
|
||||
#include <ardour/vst_plugin.h>
|
||||
#include <ardour/audio_unit.h>
|
||||
#endif
|
||||
|
||||
#include <pbd/error.h>
|
||||
#include <pbd/stl_delete.h>
|
||||
|
@ -49,8 +51,7 @@ using namespace PBD;
|
|||
|
||||
PluginManager* PluginManager::_manager = 0;
|
||||
|
||||
PluginManager::PluginManager (AudioEngine& e)
|
||||
: _engine (e)
|
||||
PluginManager::PluginManager ()
|
||||
{
|
||||
char* s;
|
||||
string lrdf_path;
|
||||
|
@ -97,10 +98,6 @@ PluginManager::refresh ()
|
|||
vst_refresh ();
|
||||
}
|
||||
#endif // VST_SUPPORT
|
||||
|
||||
#ifdef HAVE_COREAUDIO
|
||||
_au_plugin_info = AUPluginInfo::discover ();
|
||||
#endif // HAVE_COREAUDIO
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -250,7 +247,7 @@ PluginManager::ladspa_discover (string path)
|
|||
break;
|
||||
}
|
||||
|
||||
PluginInfoPtr info(new PluginInfo);
|
||||
PluginInfoPtr info(new LadspaPluginInfo);
|
||||
info->name = descriptor->Name;
|
||||
info->category = get_ladspa_category(descriptor->UniqueID);
|
||||
info->path = path;
|
||||
|
@ -280,85 +277,6 @@ PluginManager::ladspa_discover (string path)
|
|||
return 0;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Plugin>
|
||||
PluginManager::load (Session& session, PluginInfoPtr info)
|
||||
{
|
||||
void *module;
|
||||
|
||||
try {
|
||||
boost::shared_ptr<Plugin> plugin;
|
||||
|
||||
if (info->type == PluginInfo::VST) {
|
||||
|
||||
#ifdef VST_SUPPORT
|
||||
if (Config->get_use_vst()) {
|
||||
FSTHandle* handle;
|
||||
|
||||
if ((handle = fst_load (info->path.c_str())) == 0) {
|
||||
error << string_compose(_("VST: cannot load module from \"%1\""), info->path) << endmsg;
|
||||
} else {
|
||||
plugin.reset (new VSTPlugin (_engine, session, handle));
|
||||
}
|
||||
} else {
|
||||
error << _("You asked ardour to not use any VST plugins") << endmsg;
|
||||
}
|
||||
#else // !VST_SUPPORT
|
||||
error << _("This version of ardour has no support for VST plugins") << endmsg;
|
||||
return boost::shared_ptr<Plugin> ((Plugin*) 0);
|
||||
#endif // !VST_SUPPORT
|
||||
|
||||
} else {
|
||||
|
||||
if ((module = dlopen (info->path.c_str(), RTLD_NOW)) == 0) {
|
||||
error << string_compose(_("LADSPA: cannot load module from \"%1\""), info->path) << endmsg;
|
||||
error << dlerror() << endmsg;
|
||||
} else {
|
||||
plugin.reset (new LadspaPlugin (module, _engine, session, info->index, session.frame_rate()));
|
||||
}
|
||||
}
|
||||
|
||||
plugin->set_info(*info);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
catch (failed_constructor &err) {
|
||||
return boost::shared_ptr<Plugin> ((Plugin*) 0);
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<Plugin>
|
||||
ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginInfo::Type type)
|
||||
{
|
||||
PluginManager *mgr = PluginManager::the_manager();
|
||||
PluginInfoList* plugs = 0;
|
||||
|
||||
switch (type) {
|
||||
case PluginInfo::LADSPA:
|
||||
plugs = &mgr->ladspa_plugin_info();
|
||||
break;
|
||||
case PluginInfo::VST:
|
||||
plugs = &mgr->vst_plugin_info();
|
||||
unique_id = 0; // VST plugins don't have a unique id.
|
||||
break;
|
||||
case PluginInfo::AudioUnit:
|
||||
plugs = &mgr->au_plugin_info();
|
||||
unique_id = 0;
|
||||
break;
|
||||
default:
|
||||
return boost::shared_ptr<Plugin> ((Plugin *) 0);
|
||||
}
|
||||
|
||||
PluginInfoList::iterator i;
|
||||
for (i = plugs->begin(); i != plugs->end(); ++i) {
|
||||
if ((name == "" || (*i)->name == name) &&
|
||||
(unique_id == 0 || (*i)->unique_id == unique_id)) {
|
||||
return mgr->load (session, *i);
|
||||
}
|
||||
}
|
||||
|
||||
return boost::shared_ptr<Plugin> ((Plugin*) 0);
|
||||
}
|
||||
|
||||
string
|
||||
PluginManager::get_ladspa_category (uint32_t plugin_id)
|
||||
{
|
||||
|
@ -464,7 +382,7 @@ PluginManager::vst_discover (string path)
|
|||
<< endl;
|
||||
}
|
||||
|
||||
PluginInfoPtr info(new PluginInfo);
|
||||
PluginInfoPtr info(new VSTPluginInfo);
|
||||
|
||||
/* what a goddam joke freeware VST is */
|
||||
|
||||
|
|
|
@ -1023,6 +1023,7 @@ Session::auto_punch_start_changed (Location* location)
|
|||
if (get_record_enabled() && get_punch_in()) {
|
||||
/* capture start has been changed, so save new pending state */
|
||||
save_state ("", true);
|
||||
save_history();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1344,6 +1345,7 @@ Session::maybe_enable_record ()
|
|||
*/
|
||||
|
||||
save_state ("", true);
|
||||
save_history();
|
||||
|
||||
if (_transport_speed) {
|
||||
if (!punch_in) {
|
||||
|
@ -2131,6 +2133,7 @@ Session::add_diskstream (Diskstream* dstream)
|
|||
|
||||
set_dirty();
|
||||
save_state (_current_snapshot_name);
|
||||
save_history();
|
||||
|
||||
DiskstreamAdded (dstream); /* EMIT SIGNAL */
|
||||
}
|
||||
|
@ -2882,6 +2885,7 @@ Session::remove_source (Source* source)
|
|||
*/
|
||||
|
||||
save_state (_current_snapshot_name);
|
||||
save_history();
|
||||
}
|
||||
|
||||
SourceRemoved(source); /* EMIT SIGNAL */
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
#include <ardour/session.h>
|
||||
#include <ardour/route.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
// solo
|
||||
Session::GlobalSoloStateCommand::GlobalSoloStateCommand(Session &sess, void *src)
|
||||
: sess(sess), src(src)
|
||||
{
|
||||
after = before = sess.get_global_route_boolean(&Route::soloed);
|
||||
}
|
||||
void Session::GlobalSoloStateCommand::mark()
|
||||
{
|
||||
after = sess.get_global_route_boolean(&Route::soloed);
|
||||
}
|
||||
void Session::GlobalSoloStateCommand::operator()()
|
||||
{
|
||||
sess.set_global_solo(after, src);
|
||||
}
|
||||
void Session::GlobalSoloStateCommand::undo()
|
||||
{
|
||||
sess.set_global_solo(before, src);
|
||||
}
|
||||
XMLNode &Session::GlobalSoloStateCommand::get_state()
|
||||
{
|
||||
XMLNode *node = new XMLNode("GlobalSoloStateCommand");
|
||||
return *node;
|
||||
}
|
||||
|
||||
// mute
|
||||
Session::GlobalMuteStateCommand::GlobalMuteStateCommand(Session &sess, void *src)
|
||||
: sess(sess), src(src)
|
||||
{
|
||||
after = before = sess.get_global_route_boolean(&Route::muted);
|
||||
}
|
||||
void Session::GlobalMuteStateCommand::mark()
|
||||
{
|
||||
after = sess.get_global_route_boolean(&Route::muted);
|
||||
}
|
||||
void Session::GlobalMuteStateCommand::operator()()
|
||||
{
|
||||
sess.set_global_mute(after, src);
|
||||
}
|
||||
void Session::GlobalMuteStateCommand::undo()
|
||||
{
|
||||
sess.set_global_mute(before, src);
|
||||
}
|
||||
XMLNode &Session::GlobalMuteStateCommand::get_state()
|
||||
{
|
||||
XMLNode *node = new XMLNode("GlobalMuteStateCommand");
|
||||
return *node;
|
||||
}
|
||||
|
||||
// record enable
|
||||
Session::GlobalRecordEnableStateCommand::GlobalRecordEnableStateCommand(Session &sess, void *src)
|
||||
: sess(sess), src(src)
|
||||
{
|
||||
after = before = sess.get_global_route_boolean(&Route::record_enabled);
|
||||
}
|
||||
void Session::GlobalRecordEnableStateCommand::mark()
|
||||
{
|
||||
after = sess.get_global_route_boolean(&Route::record_enabled);
|
||||
}
|
||||
void Session::GlobalRecordEnableStateCommand::operator()()
|
||||
{
|
||||
sess.set_global_record_enable(after, src);
|
||||
}
|
||||
void Session::GlobalRecordEnableStateCommand::undo()
|
||||
{
|
||||
sess.set_global_record_enable(before, src);
|
||||
}
|
||||
XMLNode &Session::GlobalRecordEnableStateCommand::get_state()
|
||||
{
|
||||
XMLNode *node = new XMLNode("GlobalRecordEnableStateCommand");
|
||||
return *node;
|
||||
}
|
||||
|
||||
// metering
|
||||
Session::GlobalMeteringStateCommand::GlobalMeteringStateCommand(Session &sess, void *src)
|
||||
: sess(sess), src(src)
|
||||
{
|
||||
after = before = sess.get_global_route_metering();
|
||||
}
|
||||
void Session::GlobalMeteringStateCommand::mark()
|
||||
{
|
||||
after = sess.get_global_route_metering();
|
||||
}
|
||||
void Session::GlobalMeteringStateCommand::operator()()
|
||||
{
|
||||
sess.set_global_route_metering(after, src);
|
||||
}
|
||||
void Session::GlobalMeteringStateCommand::undo()
|
||||
{
|
||||
sess.set_global_route_metering(before, src);
|
||||
}
|
||||
XMLNode &Session::GlobalMeteringStateCommand::get_state()
|
||||
{
|
||||
XMLNode *node = new XMLNode("GlobalMeteringStateCommand");
|
||||
return *node;
|
||||
}
|
||||
|
||||
} // namespace ARDOUR
|
|
@ -611,6 +611,7 @@ Session::create (bool& new_session, string* mix_template, jack_nframes_t initial
|
|||
_state_of_the_state = Clean;
|
||||
|
||||
if (save_state (_current_snapshot_name)) {
|
||||
save_history();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1697,6 +1698,7 @@ Session::set_state (const XMLNode& node)
|
|||
|
||||
if (state_was_pending) {
|
||||
save_state (_current_snapshot_name);
|
||||
save_history();
|
||||
remove_pending_capture_state ();
|
||||
state_was_pending = false;
|
||||
}
|
||||
|
@ -2498,6 +2500,7 @@ void
|
|||
Session::auto_save()
|
||||
{
|
||||
save_state (_current_snapshot_name);
|
||||
save_history();
|
||||
}
|
||||
|
||||
RouteGroup *
|
||||
|
@ -2590,29 +2593,25 @@ Session::set_meter_falloff (float val)
|
|||
|
||||
|
||||
void
|
||||
Session::begin_reversible_command (string name, UndoAction* private_undo)
|
||||
Session::begin_reversible_command (string name)
|
||||
{
|
||||
current_cmd.clear ();
|
||||
current_cmd.set_name (name);
|
||||
|
||||
if (private_undo) {
|
||||
current_cmd.add_undo (*private_undo);
|
||||
}
|
||||
current_trans.clear ();
|
||||
current_trans.set_name (name);
|
||||
}
|
||||
|
||||
void
|
||||
Session::commit_reversible_command (UndoAction* private_redo)
|
||||
Session::commit_reversible_command (Command *cmd)
|
||||
{
|
||||
struct timeval now;
|
||||
|
||||
if (private_redo) {
|
||||
current_cmd.add_redo_no_execute (*private_redo);
|
||||
if (cmd) {
|
||||
current_trans.add_command (cmd);
|
||||
}
|
||||
|
||||
gettimeofday (&now, 0);
|
||||
current_cmd.set_timestamp (now);
|
||||
current_trans.set_timestamp (now);
|
||||
|
||||
history.add (current_cmd);
|
||||
history.add (current_trans);
|
||||
}
|
||||
|
||||
Session::GlobalRouteBooleanState
|
||||
|
@ -2691,6 +2690,7 @@ Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
|
|||
set_global_route_boolean (s, &Route::set_record_enable, src);
|
||||
}
|
||||
|
||||
#if 0
|
||||
UndoAction
|
||||
Session::global_mute_memento (void* src)
|
||||
{
|
||||
|
@ -2714,6 +2714,7 @@ Session::global_record_enable_memento (void* src)
|
|||
{
|
||||
return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
template_filter (const string &str, void *arg)
|
||||
|
@ -3301,3 +3302,48 @@ Session::add_instant_xml (XMLNode& node, const std::string& dir)
|
|||
Stateful::add_instant_xml (node, dir);
|
||||
Config->add_instant_xml (node, get_user_ardour_path());
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Session::save_history ()
|
||||
{
|
||||
XMLTree tree;
|
||||
string xml_path;
|
||||
string bak_path;
|
||||
|
||||
tree.set_root (&history.get_state());
|
||||
|
||||
xml_path = _path + _current_snapshot_name + ".history";
|
||||
|
||||
bak_path = xml_path + ".bak";
|
||||
|
||||
if ((access (xml_path.c_str(), F_OK) == 0) &&
|
||||
(rename (xml_path.c_str(), bak_path.c_str())))
|
||||
{
|
||||
error << _("could not backup old history file, current history not saved.") << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!tree.write (xml_path))
|
||||
{
|
||||
error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
|
||||
|
||||
/* don't leave a corrupt file lying around if it is
|
||||
* possible to fix.
|
||||
*/
|
||||
|
||||
if (unlink (xml_path.c_str()))
|
||||
{
|
||||
error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
|
||||
} else {
|
||||
if (rename (bak_path.c_str(), xml_path.c_str()))
|
||||
{
|
||||
error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <pbd/error.h>
|
||||
#include <glibmm/thread.h>
|
||||
#include <pbd/pthread_utils.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include <midi++/mmc.h>
|
||||
#include <midi++/port.h>
|
||||
|
@ -325,8 +326,10 @@ Session::non_realtime_stop (bool abort)
|
|||
}
|
||||
|
||||
if (change_end) {
|
||||
add_undo (sigc::retype_return<void>(sigc::bind (mem_fun (*loc, &Location::set_end), loc->end())));
|
||||
add_redo (sigc::retype_return<void>(sigc::bind (mem_fun (*loc, &Location::set_end), _transport_frame)));
|
||||
XMLNode &before = loc->get_state();
|
||||
loc->set_end(_transport_frame);
|
||||
XMLNode &after = loc->get_state();
|
||||
add_command (new MementoCommand<Location>(*loc, before, after));
|
||||
}
|
||||
|
||||
_end_location_is_free = false;
|
||||
|
@ -410,6 +413,7 @@ Session::non_realtime_stop (bool abort)
|
|||
if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
|
||||
/* capture start has been changed, so save pending state */
|
||||
save_state ("", true);
|
||||
save_history();
|
||||
}
|
||||
|
||||
/* always try to get rid of this */
|
||||
|
|
|
@ -72,6 +72,9 @@ StateManager::use_state (state_id_t id)
|
|||
void
|
||||
StateManager::save_state (std::string why)
|
||||
{
|
||||
if (!should_save_state())
|
||||
return;
|
||||
|
||||
if (!_allow_save) {
|
||||
SaveAllowed.connect (mem_fun (*this, &StateManager::save_state));
|
||||
return;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <ardour/audioplaylist.h>
|
||||
#include <ardour/panner.h>
|
||||
#include <ardour/utils.h>
|
||||
#include <ardour/connection.h>
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
@ -146,6 +147,18 @@ Track::record_enabled () const
|
|||
{
|
||||
return _diskstream->record_enabled ();
|
||||
}
|
||||
|
||||
bool
|
||||
Track::can_record()
|
||||
{
|
||||
bool will_record = true;
|
||||
for (size_t i = 0; i < _inputs.size() && will_record; i++) {
|
||||
if (!_inputs[i]->connected())
|
||||
will_record = false;
|
||||
}
|
||||
|
||||
return will_record;
|
||||
}
|
||||
|
||||
void
|
||||
Track::set_record_enable (bool yn, void *src)
|
||||
|
@ -159,8 +172,13 @@ Track::set_record_enable (bool yn, void *src)
|
|||
return;
|
||||
}
|
||||
|
||||
/* keep track of the meter point as it was before we rec-enabled */
|
||||
// Do not set rec enabled if the track can't record.
|
||||
if (yn && !can_record()) {
|
||||
error << string_compose( _("Can not arm track '%1'. Check the input connections"), name() ) << endmsg;
|
||||
return;
|
||||
}
|
||||
|
||||
/* keep track of the meter point as it was before we rec-enabled */
|
||||
if (!_diskstream->record_enabled()) {
|
||||
_saved_meter_point = _meter_point;
|
||||
}
|
||||
|
@ -206,6 +224,7 @@ Track::set_name (string str, void *src)
|
|||
|
||||
if ((ret = IO::set_name (str, src)) == 0) {
|
||||
_session.save_state ("");
|
||||
_session.save_history();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -479,3 +479,33 @@ VSTPlugin::print_parameter (uint32_t param, char *buf, uint32_t len) const
|
|||
|
||||
memmove (buf, first_nonws, strlen (buf) - (first_nonws - buf) + 1);
|
||||
}
|
||||
|
||||
PluginPtr
|
||||
VSTPluginInfo::load (Session& session)
|
||||
{
|
||||
try {
|
||||
PluginPtr plugin;
|
||||
|
||||
if (Config->get_use_vst()) {
|
||||
FSTHandle* handle;
|
||||
|
||||
handle = fst_load(path.c_str());
|
||||
|
||||
if ( (int)handle == -1) {
|
||||
error << string_compose(_("VST: cannot load module from \"%1\""), path) << endmsg;
|
||||
} else {
|
||||
plugin.reset (new VSTPlugin (session.engine(), session, handle));
|
||||
}
|
||||
} else {
|
||||
error << _("You asked ardour to not use any VST plugins") << endmsg;
|
||||
return PluginPtr ((Plugin*) 0);
|
||||
}
|
||||
|
||||
plugin->set_info(PluginInfoPtr(new VSTPluginInfo(*this)));
|
||||
return plugin;
|
||||
}
|
||||
|
||||
catch (failed_constructor &err) {
|
||||
return PluginPtr ((Plugin*) 0);
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue