AU: install latency listener
authorRobin Gareus <robin@gareus.org>
Sat, 16 Jul 2016 03:05:52 +0000 (05:05 +0200)
committerRobin Gareus <robin@gareus.org>
Sat, 16 Jul 2016 03:05:52 +0000 (05:05 +0200)
Don't query after every cycle, some plugins inject license checks
when a host queries latency (!)

libs/ardour/ardour/audio_unit.h
libs/ardour/audio_unit.cc

index 7914dce0ab2e19cd4fdb23828591db62eab3d6e9..24f427b1247ac4144b71b8badf513b2238f278ee 100644 (file)
@@ -171,6 +171,7 @@ class LIBARDOUR_API AUPlugin : public ARDOUR::Plugin
        int32_t output_channels;
        std::vector<std::pair<int,int> > io_configs;
        framecnt_t _last_nframes;
+       mutable framecnt_t _current_latency;
        bool _requires_fixed_size_buffers;
        AudioBufferList* buffers;
        bool _has_midi_input;
index 74b7ce656633e75a8ae890969ee3631248bbda50..3e6bdfb69118f8fbaa3eb29b21aa1cfa7e3f9486 100644 (file)
@@ -955,7 +955,10 @@ AUPlugin::default_value (uint32_t port)
 framecnt_t
 AUPlugin::signal_latency () const
 {
-       return unit->Latency() * _session.frame_rate();
+       if (_current_latency < 0) {
+               _current_latency = unit->Latency() * _session.frame_rate();
+       }
+       return _current_latency;
 }
 
 void
@@ -1082,8 +1085,6 @@ AUPlugin::set_block_size (pframes_t nframes)
                activate ();
        }
 
-       _current_block_size = nframes;
-
        return 0;
 }
 
@@ -3362,6 +3363,19 @@ AUPlugin::create_parameter_listener (AUEventListenerProc cb, void* arg, float in
 
        _parameter_listener_arg = arg;
 
+       // listen for latency changes
+       AudioUnitEvent event;
+       event.mEventType = kAudioUnitEvent_PropertyChange;
+       event.mArgument.mProperty.mAudioUnit = unit->AU();
+       event.mArgument.mProperty.mPropertyID = kAudioUnitProperty_Latency;
+       event.mArgument.mProperty.mScope = kAudioUnitScope_Global;
+       event.mArgument.mProperty.mElement = 0;
+
+       if (AUEventListenerAddEventType (_parameter_listener, _parameter_listener_arg, &event) != noErr) {
+               PBD::error << "Failed to create latency event listener\n";
+               // TODO don't cache _current_latency
+       }
+
        return 0;
 }
 
@@ -3458,6 +3472,15 @@ AUPlugin::_parameter_change_listener (void* arg, void* src, const AudioUnitEvent
 void
 AUPlugin::parameter_change_listener (void* /*arg*/, void* src, const AudioUnitEvent* event, UInt64 /*host_time*/, Float32 new_value)
 {
+       if (event->mEventType == kAudioUnitEvent_PropertyChange) {
+               if (event->mArgument.mProperty.mPropertyID == kAudioUnitProperty_Latency) {
+                       DEBUG_TRACE (DEBUG::AudioUnits, string_compose("AU Latency Change Event %1 <> %1\n", new_value, unit->Latency()));
+                       // TODO atomically set //_current_latency = -1;
+                       _current_latency = unit->Latency() * _session.frame_rate(); // TODO: check: new_value
+               }
+               return;
+       }
+
         ParameterMap::iterator i;
 
         if ((i = parameter_map.find (event->mArgument.mParameter.mParameterID)) == parameter_map.end()) {