diff options
Diffstat (limited to 'libs')
29 files changed, 291 insertions, 78 deletions
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<void,const char*> 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 <vector> #include <boost/shared_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> #include <pbd/undo.h> #include <pbd/statefuldestructible.h> @@ -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<Region> { public: typedef std::vector<boost::shared_ptr<Source> > 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<void,ControlType> 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<void> StartTimeChanged; + static sigc::signal<void> EndTimeChanged; static sigc::signal<void> SMPTEOffsetChanged; - sigc::signal<void> SMPTETypeChanged; + static sigc::signal<void> SMPTETypeChanged; + static sigc::signal<void> 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 <string> #include <sigc++/signal.h> -#include <boost/enable_shared_from_this.hpp> #include <pbd/statefuldestructible.h> @@ -33,7 +32,7 @@ namespace ARDOUR { -class Source : public PBD::StatefulDestructible, public sigc::trackable, public boost::enable_shared_from_this<Source> +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 <string> #include <cmath> -#ifdef HAVE_COREAUDIO +#if defined(HAVE_COREAUDIO) || defined(HAVE_AUDIOUNITS) #include <CoreFoundation/CoreFoundation.h> #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<AudioEngine*> (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 <pbd/error.h> #include <ardour/destructive_filesource.h> +#include <ardour/utils.h> #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 <ardour/vst_plugin.h> #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNITS #include <ardour/audio_unit.h> #endif @@ -523,7 +523,7 @@ PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other) #ifdef VST_SUPPORT boost::shared_ptr<VSTPlugin> vp; #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNITS boost::shared_ptr<AUPlugin> ap; #endif @@ -533,7 +533,7 @@ PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other) } else if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (other)) != 0) { return boost::shared_ptr<Plugin> (new VSTPlugin (*vp)); #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNITS } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) { return boost::shared_ptr<Plugin> (new AUPlugin (*ap)); #endif @@ -839,7 +839,7 @@ PluginInsert::type () #ifdef VST_SUPPORT boost::shared_ptr<VSTPlugin> vp; #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNITS boost::shared_ptr<AUPlugin> ap; #endif @@ -851,7 +851,7 @@ PluginInsert::type () } else if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (other)) != 0) { return ARDOUR::VST; #endif -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNITS } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (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 <pbd/xml++.h> #include <ardour/location.h> +#include <ardour/session.h> #include <ardour/audiofilesource.h> #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 <ardour/playlist.h> #include <ardour/session.h> #include <ardour/source.h> +#include <ardour/region_factory.h> #include "i18n.h" @@ -400,7 +401,7 @@ Region::first_edit () _first_edit = EditChangesNothing; send_change (NameChanged); - /// XXX CheckNewRegion (boost::shared_ptr<Region>(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<int> Session::AskAboutPendingState; -sigc::signal<void> Session::SMPTEOffsetChanged; sigc::signal<void> Session::SendFeedback; +sigc::signal<void> Session::SMPTEOffsetChanged; +sigc::signal<void> Session::SMPTETypeChanged; +sigc::signal<void> Session::PullupChanged; +sigc::signal<void> Session::StartTimeChanged; +sigc::signal<void> 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<Region> r) void Session::add_source (boost::shared_ptr<Source> source) { - cerr << "add new source " << source->name() << endl; - pair<SourceMap::key_type, SourceMap::mapped_type> entry; pair<SourceMap::iterator,bool> result; @@ -4084,6 +4089,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) { curves[curve->id()] = 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 <ardour/destructive_filesource.h> #include <ardour/configuration.h> +#ifdef HAVE_COREAUDIO +#include <ardour/coreaudiosource.h> +#endif + #include "i18n.h" using namespace ARDOUR; @@ -32,8 +36,6 @@ using namespace std; sigc::signal<void,boost::shared_ptr<Source> > SourceFactory::SourceCreated; #ifdef HAVE_COREAUDIO - - boost::shared_ptr<Source> 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); + } +} |