Merged with trunk R776

git-svn-id: svn://localhost/ardour2/branches/midi@777 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2006-08-10 01:22:45 +00:00
parent 38c7d34d8c
commit ab6f1ed9ba
110 changed files with 7360 additions and 785 deletions

View File

@ -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',

View File

@ -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.

45
au_pluginui.cc Normal file
View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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;
}
}

View File

@ -156,6 +156,7 @@ ARDOUR_UI::unload_session ()
case 1:
session->save_state ("");
session->save_history();
break;
}
}

View File

@ -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 ();
}

View File

@ -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>

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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()));
}
}

View File

@ -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 ();

View File

@ -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();

View File

@ -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();
}
}

View File

@ -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 ();

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 ();
}

View File

@ -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 ();
}
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -182,6 +182,8 @@ protected:
void master_bus_button_clicked ();
void monitor_bus_button_clicked ();
bool on_new_session_page;
};

View File

@ -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;
}

View File

@ -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();
}

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2000 Paul Davis
Copyright (C) 2000-2006 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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);

View File

@ -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 *);

View File

@ -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);

View File

@ -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__ */

View File

@ -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 ();
}

View File

@ -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));

View File

@ -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__

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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();

View File

@ -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;
}

View File

@ -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);

View File

@ -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 ();

View File

@ -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;
}

View File

@ -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

View File

@ -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__

View File

@ -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]);
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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__

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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);
}

View 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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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__

View File

@ -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.);
}

View File

@ -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__

View File

@ -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') ))

View File

@ -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):

View File

@ -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 ();

View File

@ -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__

View File

@ -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;

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2000 Paul Davis
Copyright (C) 2000-2006 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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__ */

View File

@ -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

View File

@ -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 */

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2000 Paul Davis
Copyright (C) 2000-2006 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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

View File

@ -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

View File

@ -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);

View File

@ -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 ();

View File

@ -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);

View File

@ -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 */

View File

@ -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; }

View File

@ -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__ */

View File

@ -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;

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 ();

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}

View File

@ -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