From: David Robillard Date: Thu, 31 Aug 2006 19:17:00 +0000 (+0000) Subject: Merged with trunk R879 X-Git-Tag: 3.0-alpha5~4938^2~39 X-Git-Url: https://main.carlh.net/gitweb/?p=ardour.git;a=commitdiff_plain;h=017e16c530bb1a9f186aa81893089dc79b4ddc24 Merged with trunk R879 git-svn-id: svn://localhost/ardour2/branches/midi@880 d708f5d6-7413-0410-9779-e7cbd77b26cf --- diff --git a/SConstruct b/SConstruct index b6a2ed64c5..be4b6ce0b8 100644 --- a/SConstruct +++ b/SConstruct @@ -26,6 +26,7 @@ subst_dict = { } opts = Options('scache.conf') opts.AddOptions( ('ARCH', 'Set architecture-specific compilation flags by hand (all flags as 1 argument)',''), + BoolOption('AUDIOUNITS', 'Compile with Apple\'s AudioUnit library. (experimental)', 0), BoolOption('COREAUDIO', 'Compile with Apple\'s CoreAudio library', 0), BoolOption('DEBUG', 'Set to build with debugging information and no optimizations', 0), PathOption('DESTDIR', 'Set the intermediate install "prefix"', '/'), @@ -467,6 +468,17 @@ if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == 0: libraries['boost'] = conf.Finish () +conf = env.Configure () + +# jack_port_ensure_monitor available + +if conf.CheckFunc('jack_port_ensure_monitor'): + env.Append(CCFLAGS='-DWITH_JACK_PORT_ENSURE_MONITOR') +else: + print '\nWARNING: You need at least svn revision 985 of jack for hardware monitoring to work correctly.\n' + +env = conf.Finish() + # # Check for liblo @@ -497,8 +509,6 @@ else: libraries['dmalloc'] = conf.Finish () -# - # # Audio/MIDI library (needed for MIDI, since audio is all handled via JACK) # diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index aaa686d246..8a1fd22ff2 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -61,7 +61,7 @@ skipped_files=Split(""" connection_editor.cc """) -coreaudio_files=Split(""" +audiounit_files=Split(""" au_pluginui.cc """) @@ -224,9 +224,9 @@ if env['VST']: extra_sources += vst_files gtkardour.Append (CCFLAGS="-DVST_SUPPORT", CPPPATH="#libs/fst") -if gtkardour['COREAUDIO']: - extra_sources += coreaudio_files - gtkardour.Append(CCFLAGS='-DHAVE_COREAUDIO') +if gtkardour['AUDIOUNITS']: + extra_sources += audiounit_files + gtkardour.Append(CCFLAGS='-DHAVE_AUDIOUNITS') gtkardour.Append(LINKFLAGS='-framework Carbon') gtkardour.Merge([libraries['appleutility']]) diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus index ab87fbb3ef..0f1f741c30 100644 --- a/gtk2_ardour/ardour.menus +++ b/gtk2_ardour/ardour.menus @@ -71,6 +71,7 @@ + diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index d0e90c42be..fdaa2d74ca 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -377,6 +377,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI void sync_option_changed (); void toggle_time_master (); + void toggle_video_sync (); enum ShuttleBehaviour { Sprung, diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 2fe34127dc..5af62db99f 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -287,7 +287,8 @@ ARDOUR_UI::install_actions () ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); - act = ActionManager::register_toggle_action (transport_actions, X_("ToggleTimeMaster"), _("Master"), mem_fun(*this, &ARDOUR_UI::toggle_time_master)); + ActionManager::register_toggle_action (transport_actions, X_("ToggleVideoSync"), _("Sync startup to video"), mem_fun(*this, &ARDOUR_UI::toggle_video_sync)); + act = ActionManager::register_toggle_action (transport_actions, X_("ToggleTimeMaster"), _("Time master"), mem_fun(*this, &ARDOUR_UI::toggle_time_master)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (common_actions, X_("ToggleRecordEnableTrack1"), _("Toggle Record Enable Track1"), bind (mem_fun(*this, &ARDOUR_UI::toggle_record_enable), 0U)); diff --git a/gtk2_ardour/ardour_ui_options.cc b/gtk2_ardour/ardour_ui_options.cc index 665c92d264..205180a344 100644 --- a/gtk2_ardour/ardour_ui_options.cc +++ b/gtk2_ardour/ardour_ui_options.cc @@ -43,7 +43,8 @@ ARDOUR_UI::setup_config_options () std::vector groups; groups.push_back("options"); groups.push_back("Editor"); - + groups.push_back("Transport"); + struct { char* name; bool (Configuration::*method)(void) const; @@ -69,6 +70,7 @@ ARDOUR_UI::setup_config_options () { "MeterHoldShort", &Configuration::get_meter_hold_short, 'r' }, { "MeterHoldMedium", &Configuration::get_meter_hold_medium, 'r' }, { "MeterHoldLong", &Configuration::get_meter_hold_long, 'r' }, + { "ToggleVideoSync", &Configuration::get_use_video_sync, 't' }, { 0, 0, 0 } }; @@ -77,8 +79,13 @@ ARDOUR_UI::setup_config_options () Glib::RefPtr act = ActionManager::get_action (i->c_str(), options[n].name); if (act) { Glib::RefPtr tact = Glib::RefPtr::cast_dynamic(act); - if (options[n].act_type == 't' || (options[n].act_type == 'r' && (Config->*(options[n].method))())) - tact->set_active ((Config->*(options[n].method))()); + if (options[n].act_type == 't' || options[n].act_type == 'r') { + if ((Config->*(options[n].method))()) { + tact->set_active (true); + } else { + tact->set_active (false); + } + } continue; } } @@ -237,6 +244,16 @@ ARDOUR_UI::toggle_punch_out () toggle_session_state ("Transport", "TogglePunchOut", &Session::set_punch_out, &Session::get_punch_out); } + void +ARDOUR_UI::toggle_video_sync() +{ + Glib::RefPtr act = ActionManager::get_action ("Transport", "ToggleVideoSync"); + if (act) { + Glib::RefPtr tact = Glib::RefPtr::cast_dynamic(act); + Config->set_use_video_sync (tact->get_active()); + } +} + void ARDOUR_UI::toggle_editing_space() { diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc index 8efdca2dd4..fdd680beb2 100644 --- a/gtk2_ardour/editor_audio_import.cc +++ b/gtk2_ardour/editor_audio_import.cc @@ -82,11 +82,11 @@ Editor::bring_in_external_audio (ImportMode mode, AudioTrack* track, jack_nframe switch (sfdb.run()) { case SoundFileOmega::ResponseImport: - do_import (sfdb.get_paths(), sfdb.get_split(), mode, track, pos, prompt); + do_import (sfdb.get_paths(), sfdb.get_split(), sfdb.get_mode(), track, pos, prompt); break; case SoundFileOmega::ResponseEmbed: - do_embed (sfdb.get_paths(), sfdb.get_split(), mode, track, pos, prompt); + do_embed (sfdb.get_paths(), sfdb.get_split(), sfdb.get_mode(), track, pos, prompt); break; default: @@ -274,12 +274,12 @@ Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool sources.push_back(source); } - catch (failed_constructor& err) { - error << string_compose(_("could not open %1"), path) << endmsg; - goto out; - } + catch (failed_constructor& err) { + error << string_compose(_("could not open %1"), path) << endmsg; + goto out; + } - ARDOUR_UI::instance()->flush_pending (); + ARDOUR_UI::instance()->flush_pending (); } if (sources.empty()) { diff --git a/gtk2_ardour/plugin_selector.cc b/gtk2_ardour/plugin_selector.cc index 69f6f56690..8a52e8587f 100644 --- a/gtk2_ardour/plugin_selector.cc +++ b/gtk2_ardour/plugin_selector.cc @@ -92,7 +92,7 @@ PluginSelector::PluginSelector (PluginManager *mgr) } #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNIT aumodel = ListStore::create(aucols); au_display.set_model (aumodel); au_display.append_column (_("Available plugins"), aucols.name); @@ -151,7 +151,7 @@ PluginSelector::PluginSelector (PluginManager *mgr) } #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNIT notebook.pages().push_back (TabElem (auscroller, _("AudioUnit"))); #endif @@ -171,7 +171,7 @@ PluginSelector::PluginSelector (PluginManager *mgr) } #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNIT au_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked)); au_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::au_display_selection_changed)); #endif @@ -187,7 +187,7 @@ PluginSelector::PluginSelector (PluginManager *mgr) vst_refiller (); #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNIT au_refiller (); #endif @@ -219,7 +219,7 @@ PluginSelector::set_correct_focus() } #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNIT cp--; if (cp == 0) { @@ -330,7 +330,7 @@ PluginSelector::vst_display_selection_changed() #endif //VST_SUPPORT -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNIT void PluginSelector::_au_refiller (void *arg) @@ -374,7 +374,7 @@ PluginSelector::au_display_selection_changed() current_selection = ARDOUR::AudioUnit; } -#endif //HAVE_COREAUDIO +#endif //HAVE_AUDIOUNIT void PluginSelector::use_plugin (PluginInfoPtr pi) @@ -413,7 +413,7 @@ PluginSelector::btn_add_clicked() #endif break; case ARDOUR::AudioUnit: -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNIT row = *(au_display.get_selection()->get_selected()); name = row[aucols.name]; pi = row[aucols.plugin]; @@ -451,7 +451,7 @@ PluginSelector::btn_update_clicked() #ifdef VST_SUPPORT vst_refiller (); #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNIT au_refiller (); #endif } diff --git a/gtk2_ardour/plugin_selector.h b/gtk2_ardour/plugin_selector.h index d71203131c..73c3008e64 100644 --- a/gtk2_ardour/plugin_selector.h +++ b/gtk2_ardour/plugin_selector.h @@ -110,7 +110,7 @@ class PluginSelector : public ArdourDialog void vst_display_selection_changed(); #endif // VST_SUPPORT -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNIT // page 3 struct AUColumns : public Gtk::TreeModel::ColumnRecord { AUColumns () { @@ -131,7 +131,7 @@ class PluginSelector : public ArdourDialog static void _au_refiller (void *); void au_refiller (); void au_display_selection_changed(); -#endif //HAVE_COREAUDIO +#endif //HAVE_AUDIOUNIT ARDOUR::PluginManager *manager; diff --git a/gtk2_ardour/redirect_box.cc b/gtk2_ardour/redirect_box.cc index 642e863ddb..a7b7096829 100644 --- a/gtk2_ardour/redirect_box.cc +++ b/gtk2_ardour/redirect_box.cc @@ -62,7 +62,7 @@ #include "i18n.h" -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNIT #include "au_pluginui.h" #endif @@ -1001,7 +1001,7 @@ RedirectBox::edit_redirect (boost::shared_ptr redirect) } else { plugin_ui->show_all (); } -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNIT } else if (type == ARDOUR::AudioUnit) { AUPluginUI* plugin_ui; if (plugin_insert->get_gui() == 0) { diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc index 6858b8442d..b0601704c8 100644 --- a/gtk2_ardour/sfdb_ui.cc +++ b/gtk2_ardour/sfdb_ui.cc @@ -269,7 +269,11 @@ SoundFileBox::remove_field_clicked () void SoundFileBox::field_edited (const Glib::ustring& str1, const Glib::ustring& str2) { - cout << "field_edited" << endl; + Gtk::TreeModel::Children rows(fields->children()); + Gtk::TreeModel::Row row(rows[atoi(str1.c_str())]); + + Library->set_field (path, row[label_columns.field], str2); + Library->save_changes (); } diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript index 254f5a0560..c15897d8be 100644 --- a/libs/ardour/SConscript +++ b/libs/ardour/SConscript @@ -116,7 +116,8 @@ arch_specific_objects = [ ] osc_files = [ 'osc.cc' ] vst_files = [ 'vst_plugin.cc', 'session_vst.cc' ] -coreaudio_files = [ 'audio_unit.cc', 'coreaudiosource.cc' ] +audiounit_files = [ 'audio_unit.cc' ] +coreaudio_files = [ 'coreaudiosource.cc' ] extra_sources = [ ] if ardour['VST']: @@ -194,11 +195,15 @@ if conf.CheckCHeader('sys/vfs.h'): if conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'): ardour.Append(LINKFLAGS="-framework CoreMIDI") -if conf.CheckCHeader('/System/Library/Frameworks/AudioToolbox.framework/Headers/ExtendedAudioFile.h') and ardour['COREAUDIO'] == 1: +if conf.CheckCHeader('/System/Library/Frameworks/AudioUnit.framework/Headers/AudioUnit.h') and ardour['AUDIOUNITS']: + ardour.Append(CXXFLAGS="-DHAVE_AUDIOUNITS") + ardour.Append(LINKFLAGS="-framework AudioUnit") + extra_sources += audiounit_files + +if conf.CheckCHeader('/System/Library/Frameworks/AudioToolbox.framework/Headers/ExtendedAudioFile.h') and ardour['COREAUDIO']: ardour.Append(CXXFLAGS="-DHAVE_COREAUDIO") ardour.Append(LINKFLAGS="-framework AudioToolbox") extra_sources += coreaudio_files - if env['CONFIG_ARCH'] == 'apple': # this next line avoids issues with circular dependencies between libardour and libardour_cp. @@ -226,7 +231,7 @@ ardour.Merge ([ if ardour['LIBLO']: ardour.Merge ([ libraries['lo'] ]) -if ardour['COREAUDIO']: +if ardour['COREAUDIO'] or ardour['AUDIOUNITS']: ardour.Merge ([ libraries['appleutility'] ]) ardour.VersionBuild(['version.cc', 'ardour/version.h'], 'SConscript') @@ -256,12 +261,12 @@ libardour = ardour.SharedLibrary('ardour', ardour_files + extra_sources + arch_s Default(libardour) if env['NLS']: - i18n (ardour, ardour_files + vst_files + coreaudio_files, env) + i18n (ardour, ardour_files + vst_files + coreaudio_files + audiounit_files, env) env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libardour)) env.Alias('tarball', env.Distribute (env['DISTTREE'], [ 'SConscript', 'i18n.h', 'gettext.h', 'sse_functions.s', 'sse_functions_64bit.s' ] + - ardour_files + vst_files + coreaudio_files + + ardour_files + vst_files + coreaudio_files + audiounit_files + glob.glob('po/*.po') + glob.glob('ardour/*.h'))) diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index db814bbb5f..5f9e53380f 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -72,6 +72,8 @@ class AudioEngine : public sigc::trackable int usecs_per_cycle () const { return _usecs_per_cycle; } + bool get_sync_offset (jack_nframes_t& offset) const; + jack_nframes_t frames_since_cycle_start () { if (!_running || !_jack) return 0; return jack_frames_since_cycle_start (_jack); diff --git a/libs/ardour/ardour/configuration.h b/libs/ardour/ardour/configuration.h index dd689e9a2d..8d51343ffb 100644 --- a/libs/ardour/ardour/configuration.h +++ b/libs/ardour/ardour/configuration.h @@ -63,16 +63,18 @@ class Configuration : public Stateful XMLNode* control_protocol_state () { return _control_protocol_state; } + sigc::signal ParameterChanged; + /* define accessor methods */ #undef CONFIG_VARIABLE #undef CONFIG_VARIABLE_SPECIAL #define CONFIG_VARIABLE(Type,var,name,value) \ Type get_##var () const { return var.get(); } \ - void set_##var (Type val) { var.set (val); var.set_is_user (user_configuration); } + void set_##var (Type val) { var.set (val); var.set_is_user (user_configuration); ParameterChanged (name); } #define CONFIG_VARIABLE_SPECIAL(Type,var,name,value,mutator) \ Type get_##var () const { return var.get(); } \ - void set_##var (Type val) { var.set (val); var.set_is_user (user_configuration); } + void set_##var (Type val) { var.set (val); var.set_is_user (user_configuration); ParameterChanged (name); } #include "ardour/configuration_vars.h" #undef CONFIG_VARIABLE #undef CONFIG_VARIABLE_SPECIAL diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h index 85c7897026..5222eefb0a 100644 --- a/libs/ardour/ardour/configuration_vars.h +++ b/libs/ardour/ardour/configuration_vars.h @@ -21,6 +21,7 @@ CONFIG_VARIABLE(bool, use_hardware_monitoring, "use-hardware-monitoring", false) CONFIG_VARIABLE(bool, use_sw_monitoring, "use-sw-monitoring", false) CONFIG_VARIABLE(bool, use_external_monitoring, "use-external-monitoring", true) CONFIG_VARIABLE(bool, jack_time_master, "jack-time-master", true) +CONFIG_VARIABLE(bool, use_video_sync, "use-video-sync", false) CONFIG_VARIABLE(bool, trace_midi_input, "trace-midi-input", false) CONFIG_VARIABLE(bool, trace_midi_output, "trace-midi-output", false) CONFIG_VARIABLE(bool, plugins_stop_with_transport, "plugins-stop-with-transport", false) diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h index 5da254b6df..a436722cb0 100644 --- a/libs/ardour/ardour/port.h +++ b/libs/ardour/ardour/port.h @@ -106,7 +106,13 @@ class Port : public sigc::trackable { } void ensure_monitor_input (bool yn) { + +#ifdef WITH_JACK_PORT_ENSURE_MONITOR jack_port_ensure_monitor (_port, yn); +#else + jack_port_request_monitor(_port, yn); +#endif + } /*XXX completely bloody useless imho*/ diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index 1abba574f1..c3e93fc7ae 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -58,7 +59,7 @@ struct RegionState : public StateManager::State mutable RegionEditState _first_edit; }; -class Region : public PBD::StatefulDestructible, public StateManager +class Region : public PBD::StatefulDestructible, public StateManager, public boost::enable_shared_from_this { public: typedef std::vector > SourceList; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 47b6c163ef..09fd01baec 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -374,6 +374,8 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible jack_nframes_t last_transport_start() const { return _last_roll_location; } void goto_end () { request_locate (end_location->start(), false);} void goto_start () { request_locate (start_location->start(), false); } + void set_session_start (jack_nframes_t start) { start_location->set_start(start); } + void set_session_end (jack_nframes_t end) { end_location->set_start(end); _end_location_is_free = false; } void use_rf_shuttle_speed (); void request_transport_speed (float speed); void request_overwrite_buffer (Diskstream*); @@ -392,8 +394,9 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible jack_nframes_t current_end_frame() const { return end_location->start(); } jack_nframes_t current_start_frame() const { return start_location->start(); } jack_nframes_t frame_rate() const { return _current_frame_rate; } - double frames_per_smpte_frame() const { return _frames_per_smpte_frame; } jack_nframes_t frames_per_hour() const { return _frames_per_hour; } + + double frames_per_smpte_frame() const { return _frames_per_smpte_frame; } jack_nframes_t smpte_frames_per_hour() const { return _smpte_frames_per_hour; } /* Locations */ @@ -432,7 +435,8 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible MidiFeedback, MidiControl, TranzportControl, - Feedback + Feedback, + SmpteMode, }; sigc::signal ControlChanged; @@ -593,6 +597,7 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible float shuttle_speed_threshold; float rf_speed; float smpte_frames_per_second; + float video_pullup; bool smpte_drop_frames; AnyTime preroll; AnyTime postroll; @@ -602,7 +607,35 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible jack_nframes_t transport_frame () const {return _transport_frame; } jack_nframes_t audible_frame () const; + enum SmpteFormat { + smpte_23976, + smpte_24, + smpte_24976, + smpte_25, + smpte_2997, + smpte_2997drop, + smpte_30, + smpte_30drop, + smpte_5994, + smpte_60, + }; + + enum PullupFormat { + pullup_Plus4Plus1, + pullup_Plus4, + pullup_Plus4Minus1, + pullup_Plus1, + pullup_None, + pullup_Minus1, + pullup_Minus4Plus1, + pullup_Minus4, + pullup_Minus4Minus1, + }; + int set_smpte_type (float fps, bool drop_frames); + int set_video_pullup (float pullup); + + void sync_time_vars(); void bbt_time (jack_nframes_t when, BBT_Time&); void smpte_to_sample( SMPTE::Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes ) const; @@ -621,8 +654,11 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible jack_nframes_t convert_to_frames_at (jack_nframes_t position, AnyTime&); + static sigc::signal StartTimeChanged; + static sigc::signal EndTimeChanged; static sigc::signal SMPTEOffsetChanged; - sigc::signal SMPTETypeChanged; + static sigc::signal SMPTETypeChanged; + static sigc::signal PullupChanged; void request_slave_source (SlaveSource, jack_nframes_t pos = 0); SlaveSource slave_source() const { return _slave_type; } @@ -1074,7 +1110,9 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible mutable gint processing_prohibited; process_function_type process_function; process_function_type last_process_function; - jack_nframes_t _current_frame_rate; + bool waiting_for_sync_offset; + jack_nframes_t _base_frame_rate; + jack_nframes_t _current_frame_rate; //this includes video pullup offset int transport_sub_state; mutable gint _record_status; jack_nframes_t _transport_frame; @@ -1176,6 +1214,8 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible return false; } + bool maybe_sync_start (jack_nframes_t&, jack_nframes_t&); + void check_declick_out (); MIDI::MachineControl* mmc; @@ -1817,6 +1857,8 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible void add_controllable (PBD::Controllable*); void remove_controllable (PBD::Controllable*); + + void handle_configuration_change (const char*); }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h index 1728cdb477..a18250fff2 100644 --- a/libs/ardour/ardour/source.h +++ b/libs/ardour/ardour/source.h @@ -24,7 +24,6 @@ #include #include -#include #include @@ -33,7 +32,7 @@ namespace ARDOUR { -class Source : public PBD::StatefulDestructible, public sigc::trackable, public boost::enable_shared_from_this +class Source : public PBD::StatefulDestructible, public sigc::trackable { public: Source (std::string name, DataType type); diff --git a/libs/ardour/ardour/utils.h b/libs/ardour/ardour/utils.h index ee4482d260..214e74156c 100644 --- a/libs/ardour/ardour/utils.h +++ b/libs/ardour/ardour/utils.h @@ -25,7 +25,7 @@ #include #include -#ifdef HAVE_COREAUDIO +#if defined(HAVE_COREAUDIO) || defined(HAVE_AUDIOUNITS) #include #endif @@ -57,8 +57,11 @@ int touch_file(std::string path); std::string region_name_from_path (std::string path); std::string path_expand (std::string); -#ifdef HAVE_COREAUDIO +void compute_equal_power_fades (jack_nframes_t nframes, float* in, float* out); + +#if defined(HAVE_COREAUDIO) || defined(HAVE_AUDIOUNITS) std::string CFStringRefToStdString(CFStringRef stringRef); #endif // HAVE_COREAUDIO #endif /* __ardour_utils_h__ */ + diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 7f062880b2..7b77aad8f5 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -251,8 +251,7 @@ AudioDiskstream::non_realtime_input_change () if (speed() != 1.0f || speed() != -1.0f) { seek ((jack_nframes_t) (_session.transport_frame() * (double) speed())); - } - else { + } else { seek (_session.transport_frame()); } } @@ -386,8 +385,12 @@ AudioDiskstream::setup_destructive_playlist () void AudioDiskstream::use_destructive_playlist () { - /* use the sources associated with the single full-extent region */ - + /* this is called from the XML-based constructor. when its done, + we already have a playlist and a region, but we need to + set up our sources for write. we use the sources associated + with the (presumed single, full-extent) region. + */ + Playlist::RegionList* rl = _playlist->regions_at (0); if (rl->empty()) { diff --git a/libs/ardour/audio_library.cc b/libs/ardour/audio_library.cc index ad008f6312..3aa6d05be1 100644 --- a/libs/ardour/audio_library.cc +++ b/libs/ardour/audio_library.cc @@ -432,9 +432,9 @@ AudioLibrary::safe_file_extension(string file) file.rfind(".vwe") == string::npos && file.rfind(".paf") == string::npos && #ifdef HAVE_COREAUDIO - file.rfind(".mp3") == string::npos && - file.rfind(".aac") == string::npos && - file.rfind(".mp4") == string::npos && + file.rfind(".mp3") == string::npos && + file.rfind(".aac") == string::npos && + file.rfind(".mp4") == string::npos && #endif // HAVE_COREAUDIO file.rfind(".voc") == string::npos); } diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc index ad98621814..57d5505a0f 100644 --- a/libs/ardour/audio_unit.cc +++ b/libs/ardour/audio_unit.cc @@ -394,3 +394,4 @@ AUPluginInfo::setup_nchannels (CAComponentDescription& comp_desc) 0, &cinfo, &info_size); } } + diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index fe29037cb7..027a623301 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -163,18 +163,32 @@ AudioEngine::stop () } + +bool +AudioEngine::get_sync_offset (jack_nframes_t& offset) const +{ + jack_position_t pos; + + (void) jack_transport_query (_jack, &pos); + + if (pos.valid & JackVideoFrameOffset) { + offset = pos.video_offset; + return true; + } + + return false; +} + void AudioEngine::_jack_timebase_callback (jack_transport_state_t state, jack_nframes_t nframes, - - jack_position_t* pos, int new_position, void *arg) + jack_position_t* pos, int new_position, void *arg) { static_cast (arg)->jack_timebase_callback (state, nframes, pos, new_position); } void AudioEngine::jack_timebase_callback (jack_transport_state_t state, jack_nframes_t nframes, - - jack_position_t* pos, int new_position) + jack_position_t* pos, int new_position) { if (session && session->synced_to_jack()) { session->jack_timebase_callback (state, nframes, pos, new_position); diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index b9d21223e3..d74a38097c 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -66,7 +66,6 @@ AudioSource::AudioSource (string name) AudioSource::AudioSource (const XMLNode& node) : Source (node) { - cerr << "audiosource from XML\n"; if (pending_peak_sources_lock == 0) { pending_peak_sources_lock = new Glib::Mutex; } diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc index 652ca1e4f2..0d7e690a25 100644 --- a/libs/ardour/coreaudiosource.cc +++ b/libs/ardour/coreaudiosource.cc @@ -31,16 +31,12 @@ CoreAudioSource::CoreAudioSource (const XMLNode& node) : AudioFileSource (node) { init (_name); - - SourceCreated (this); /* EMIT SIGNAL */ } CoreAudioSource::CoreAudioSource (const string& idstr, Flag flags) : AudioFileSource(idstr, flags) { init (idstr); - - SourceCreated (this); /* EMIT SIGNAL */ } void diff --git a/libs/ardour/destructive_filesource.cc b/libs/ardour/destructive_filesource.cc index 7bf47e84a0..bf16b40005 100644 --- a/libs/ardour/destructive_filesource.cc +++ b/libs/ardour/destructive_filesource.cc @@ -56,6 +56,7 @@ typedef off_t off64_t; #include #include +#include #include "i18n.h" @@ -124,13 +125,7 @@ DestructiveFileSource::setup_standard_crossfades (jack_nframes_t rate) out_coefficient = new gain_t[xfade_frames]; in_coefficient = new gain_t[xfade_frames]; - for (jack_nframes_t n = 0; n < xfade_frames; ++n) { - - /* XXXX THIS IS NOT THE RIGHT XFADE CURVE: USE A PROPER VOLUMETRIC EQUAL POWER CURVE */ - - in_coefficient[n] = n/(gain_t) (xfade_frames-1); /* 0 .. 1 */ - out_coefficient[n] = 1.0 - in_coefficient[n]; /* 1 .. 0 */ - } + compute_equal_power_fades (xfade_frames, in_coefficient, out_coefficient); } void @@ -195,7 +190,7 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in) } if (file_cnt) { - if ((retval = write_float (xfade_buf, fade_position, file_cnt)) != (ssize_t) file_cnt) { + if ((retval = read_unlocked (xfade_buf, fade_position, file_cnt)) != (ssize_t) file_cnt) { if (retval >= 0 && errno == EAGAIN) { /* XXX - can we really trust that errno is meaningful here? yes POSIX, i'm talking to you. * short or no data there */ @@ -213,7 +208,7 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in) } if (nofade && !fade_in) { - if (write_float (data, file_pos, nofade) != nofade) { + if (write_float (data, file_pos - timeline_position, nofade) != nofade) { error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; return 0; } @@ -245,24 +240,27 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in) } else if (xfade) { + gain_t in[xfade]; + gain_t out[xfade]; + /* short xfade, compute custom curve */ - /* XXX COMPUTE THE CURVE, DAMMIT! */ + compute_equal_power_fades (xfade, in, out); for (jack_nframes_t n = 0; n < xfade; ++n) { - xfade_buf[n] = (xfade_buf[n] * out_coefficient[n]) + (fade_data[n] * in_coefficient[n]); + xfade_buf[n] = (xfade_buf[n] * out[n]) + (fade_data[n] * in[n]); } } if (xfade) { - if (write_float (xfade_buf, fade_position, xfade) != xfade) { + if (write_float (xfade_buf, fade_position - timeline_position, xfade) != xfade) { error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; return 0; } } if (fade_in && nofade) { - if (write_float (data + xfade, file_pos + xfade, nofade) != nofade) { + if (write_float (data + xfade, file_pos + xfade - timeline_position, nofade) != nofade) { error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; return 0; } @@ -345,7 +343,7 @@ DestructiveFileSource::write_unlocked (Sample* data, jack_nframes_t cnt) /* in the middle of recording */ - if (write_float (data, file_pos, cnt) != cnt) { + if (write_float (data, file_pos - timeline_position, cnt) != cnt) { return 0; } } diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index 14f67245fd..01c7182e14 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -306,14 +306,18 @@ Session::sample_rate_convert (import_status& status, string infile, string& outf sf_count_t input_count = 0; SNDFILE* in = sf_open(infile.c_str(), SFM_READ, &sf_info); + if (!in) { + error << string_compose(_("Import/SRC: could not open input file: %1"), outfile) << endmsg; + return false; + } sf_count_t total_input_frames = sf_info.frames; outfile = build_tmp_convert_name(infile); SNDFILE* out = sf_open(outfile.c_str(), SFM_RDWR, &sf_info); - if(!out) { - error << string_compose(_("Import: could not open temp file: %1"), outfile) << endmsg; - return false; - } + if (!out) { + error << string_compose(_("Import/SRC: could not open output file: %1"), outfile) << endmsg; + return false; + } sf_seek (in, 0, SEEK_SET) ; sf_seek (out, 0, SEEK_SET) ; @@ -372,8 +376,6 @@ Session::sample_rate_convert (import_status& status, string infile, string& outf sf_close(in); sf_close(out); - status.done = true; - if (status.cancel) { return false; } else { diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc index 55938ab240..c74c81f7e3 100644 --- a/libs/ardour/insert.cc +++ b/libs/ardour/insert.cc @@ -36,7 +36,7 @@ #include #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNITS #include #endif @@ -523,7 +523,7 @@ PluginInsert::plugin_factory (boost::shared_ptr other) #ifdef VST_SUPPORT boost::shared_ptr vp; #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNITS boost::shared_ptr ap; #endif @@ -533,7 +533,7 @@ PluginInsert::plugin_factory (boost::shared_ptr other) } else if ((vp = boost::dynamic_pointer_cast (other)) != 0) { return boost::shared_ptr (new VSTPlugin (*vp)); #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNITS } else if ((ap = boost::dynamic_pointer_cast (other)) != 0) { return boost::shared_ptr (new AUPlugin (*ap)); #endif @@ -839,7 +839,7 @@ PluginInsert::type () #ifdef VST_SUPPORT boost::shared_ptr vp; #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNITS boost::shared_ptr ap; #endif @@ -851,7 +851,7 @@ PluginInsert::type () } else if ((vp = boost::dynamic_pointer_cast (other)) != 0) { return ARDOUR::VST; #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNITS } else if ((ap = boost::dynamic_pointer_cast (other)) != 0) { return ARDOUR::AudioUnit; #endif diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc index 58ef812d2e..30b28c6abe 100644 --- a/libs/ardour/location.cc +++ b/libs/ardour/location.cc @@ -30,6 +30,7 @@ #include #include +#include #include #include "i18n.h" @@ -84,8 +85,12 @@ Location::set_start (jack_nframes_t s) _end = s; start_changed(this); /* EMIT SIGNAL */ if ( is_start() ) { + Session::StartTimeChanged (); /* EMIT SIGNAL */ AudioFileSource::set_header_position_offset ( s ); } + if ( is_end() ) { + Session::EndTimeChanged (); /* EMIT SIGNAL */ + } } return 0; } diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc index bedc32a0b3..8d200b0ee4 100644 --- a/libs/ardour/plugin.cc +++ b/libs/ardour/plugin.cc @@ -261,7 +261,7 @@ ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginType ty break; #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNITS case ARDOUR::AudioUnit: plugs = AUPluginInfo::discover (); unique_id = 0; // Neither do AU. @@ -282,3 +282,4 @@ ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginType ty return PluginPtr ((Plugin*) 0); } + diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 48431087ae..c420649ef2 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -33,6 +33,7 @@ #include #include #include +#include #include "i18n.h" @@ -400,7 +401,7 @@ Region::first_edit () _first_edit = EditChangesNothing; send_change (NameChanged); - /// XXX CheckNewRegion (boost::shared_ptr(this)); + RegionFactory::CheckNewRegion (shared_from_this()); } } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 3c325ee538..ebdbea1fc4 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -98,9 +98,13 @@ Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0; Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0; sigc::signal Session::AskAboutPendingState; -sigc::signal Session::SMPTEOffsetChanged; sigc::signal Session::SendFeedback; +sigc::signal Session::SMPTEOffsetChanged; +sigc::signal Session::SMPTETypeChanged; +sigc::signal Session::PullupChanged; +sigc::signal Session::StartTimeChanged; +sigc::signal Session::EndTimeChanged; int Session::find_session (string str, string& path, string& snapshot, bool& isnew) @@ -298,6 +302,8 @@ Session::Session (AudioEngine &eng, _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty); + Config->ParameterChanged.connect (mem_fun (*this, &Session::handle_configuration_change)); + if (was_dirty) { DirtyChanged (); /* EMIT SIGNAL */ } @@ -1435,8 +1441,9 @@ Session::set_frame_rate (jack_nframes_t frames_per_second) here. */ - _current_frame_rate = frames_per_second; - _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second; + _base_frame_rate = frames_per_second; + + sync_time_vars(); Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25)); @@ -2759,8 +2766,6 @@ Session::remove_region_from_region_list (boost::shared_ptr r) void Session::add_source (boost::shared_ptr source) { - cerr << "add new source " << source->name() << endl; - pair entry; pair result; @@ -4083,6 +4088,16 @@ Session::set_xfade_model (CrossfadeModel xm) } } +void +Session::handle_configuration_change (const char* parameter) +{ + if (!strcmp (parameter, "use-video-sync")) { + if (_transport_speed == 0.0f) { + waiting_for_sync_offset = true; + } + } +} + void Session::add_curve(Curve *curve) { diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index e99478e0b4..8379b93e83 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -742,7 +742,8 @@ Session::process_without_events (jack_nframes_t nframes) bool session_needs_butler = false; jack_nframes_t stop_limit; long frames_moved; - + jack_nframes_t offset = 0; + { if (post_transport_work & (PostTransportLocate|PostTransportStop)) { no_roll (nframes, 0); @@ -777,16 +778,20 @@ Session::process_without_events (jack_nframes_t nframes) return; } - click (_transport_frame, nframes, 0); + if (maybe_sync_start (nframes, offset)) { + return; + } + + click (_transport_frame, nframes, offset); prepare_diskstreams (); frames_moved = (long) floor (_transport_speed * nframes); - if (process_routes (nframes, 0)) { - no_roll (nframes, 0); - return; - } + if (process_routes (nframes, offset)) { + no_roll (nframes, offset); + return; + } commit_diskstreams (nframes, session_needs_butler); @@ -845,3 +850,31 @@ Session::process_audition (jack_nframes_t nframes) } } +bool +Session::maybe_sync_start (jack_nframes_t& nframes, jack_nframes_t& offset) +{ + jack_nframes_t sync_offset; + + if (!waiting_for_sync_offset) { + return false; + } + + if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) { + + no_roll (sync_offset, 0); + nframes -= sync_offset; + offset += sync_offset; + waiting_for_sync_offset = false; + + if (nframes == 0) { + return true; // done + } + + } else { + no_roll (nframes, 0); + return true; // done + } + + return false; +} + diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index c3eee04de4..eaaa723a0c 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -229,6 +229,18 @@ Session::first_stage_init (string fullpath, string snapshot_name) process_function = &Session::process_with_events; + if (Config->get_use_video_sync()) { + waiting_for_sync_offset = true; + } else { + waiting_for_sync_offset = false; + } + + _current_frame_rate = 48000; + _base_frame_rate = 48000; + + smpte_frames_per_second = 30; + video_pullup = 0.0; + smpte_drop_frames = false; last_smpte_when = 0; _smpte_offset = 0; _smpte_offset_negative = true; @@ -264,6 +276,7 @@ Session::first_stage_init (string fullpath, string snapshot_name) /* default SMPTE type is 30 FPS, non-drop */ set_smpte_type (30.0, false); + set_video_pullup (0.0); _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered)); @@ -926,6 +939,11 @@ Session::load_options (const XMLNode& node) rf_speed = atof (prop->value().c_str()); } } + if ((child = find_named_node (node, "video-pullup")) != 0) { + if ((prop = child->property ("val")) != 0) { + set_video_pullup( atof (prop->value().c_str()) ); + } + } if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) { if ((prop = child->property ("val")) != 0) { set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames ); @@ -1180,6 +1198,10 @@ Session::get_options () const child = opthead->add_child ("rf-speed"); child->add_property ("val", buf); + snprintf (buf, sizeof(buf)-1, "%.4f", video_pullup); + child = opthead->add_child ("video-pullup"); + child->add_property ("val", buf); + snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second); child = opthead->add_child ("smpte-frames-per-second"); child->add_property ("val", buf); diff --git a/libs/ardour/session_time.cc b/libs/ardour/session_time.cc index 945dfbe48b..c74d3021cb 100644 --- a/libs/ardour/session_time.cc +++ b/libs/ardour/session_time.cc @@ -48,15 +48,20 @@ Session::bbt_time (jack_nframes_t when, BBT_Time& bbt) /* SMPTE TIME */ +void +Session::sync_time_vars () +{ + _current_frame_rate = _base_frame_rate * (1.0 + (video_pullup/100.0) ); + _frames_per_hour = _current_frame_rate * 3600; + _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second; + _smpte_frames_per_hour = (unsigned long) (smpte_frames_per_second * 3600.0); +} + int Session::set_smpte_type (float fps, bool drop_frames) { smpte_frames_per_second = fps; smpte_drop_frames = drop_frames; - _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second; - _frames_per_hour = _current_frame_rate * 3600; - _smpte_frames_per_hour = (unsigned long) (smpte_frames_per_second * 3600.0); - last_smpte_valid = false; // smpte type bits are the middle two in the upper nibble @@ -83,6 +88,8 @@ Session::set_smpte_type (float fps, bool drop_frames) break; }; + sync_time_vars(); + SMPTETypeChanged (); /* EMIT SIGNAL */ set_dirty(); @@ -90,6 +97,20 @@ Session::set_smpte_type (float fps, bool drop_frames) return 0; } +int +Session::set_video_pullup (float pull) +{ + video_pullup = pull; + + sync_time_vars(); + + PullupChanged (); /* EMIT SIGNAL */ + + set_dirty(); + + return 0; +} + void Session::set_smpte_offset (jack_nframes_t off) { @@ -411,6 +432,10 @@ Session::jack_timebase_callback (jack_transport_state_t state, pos->valid = jack_position_bits_t (pos->valid | JackPositionBBT); } + //poke audio video ratio so Ardour can track Video Sync + pos->audio_frames_per_video_frame = frame_rate() / smpte_frames_per_second; + pos->valid = jack_position_bits_t (pos->valid | JackAudioVideoRatio); + #if 0 /* SMPTE info */ diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 85e2dd391f..561d63fe78 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -191,6 +191,10 @@ Session::realtime_stop (bool abort) _transport_speed = 0; + if (Config->get_use_video_sync()) { + waiting_for_sync_offset = true; + } + transport_sub_state = (auto_return ? AutoReturning : 0); } diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index 2bdcdc5a02..b6ded6d617 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -292,6 +292,11 @@ SndFileSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t uint32_t real_cnt; jack_nframes_t file_cnt; + //destructive (tape) tracks need to offset reads and writes by the timeline position + if (_flags && ARDOUR::Destructive == ARDOUR::Destructive) { + start -= timeline_position; + } + if (start > _length) { /* read starts beyond end of data, just memset to zero */ diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc index 2fcdd29033..61a7659a5e 100644 --- a/libs/ardour/source_factory.cc +++ b/libs/ardour/source_factory.cc @@ -24,6 +24,10 @@ #include #include +#ifdef HAVE_COREAUDIO +#include +#endif + #include "i18n.h" using namespace ARDOUR; @@ -32,8 +36,6 @@ using namespace std; sigc::signal > SourceFactory::SourceCreated; #ifdef HAVE_COREAUDIO - - boost::shared_ptr SourceFactory::create (const XMLNode& node) { diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc index 26b5966086..8d9d799a44 100644 --- a/libs/ardour/utils.cc +++ b/libs/ardour/utils.cc @@ -259,7 +259,7 @@ path_expand (string path) #endif } -#ifdef HAVE_COREAUDIO +#if defined(HAVE_COREAUDIO) || defined(HAVE_AUDIOUNITS) string CFStringRefToStdString(CFStringRef stringRef) { @@ -277,3 +277,29 @@ CFStringRefToStdString(CFStringRef stringRef) return result; } #endif // HAVE_COREAUDIO + +void +compute_equal_power_fades (jack_nframes_t nframes, float* in, float* out) +{ + double step; + + step = 1.0/nframes; + + in[0] = 0.0f; + + for (int i = 1; i < nframes - 1; ++i) { + in[i] = in[i-1] + step; + } + + in[nframes-1] = 1.0; + + const float pan_law_attenuation = -3.0f; + const float scale = 2.0f - 4.0f * powf (10.0f,pan_law_attenuation/20.0f); + + for (unsigned long n = 0; n < nframes; ++n) { + float inVal = in[n]; + float outVal = 1 - inVal; + out[n] = outVal * (scale * outVal + 1.0f - scale); + in[n] = inVal * (scale * inVal + 1.0f - scale); + } +}