X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Faudio_unit.cc;h=13bc57973191282895464cb76b483378ed099b4d;hb=47ba20143e06445a9977f4757d816439ea8042d0;hp=74b7ce656633e75a8ae890969ee3631248bbda50;hpb=8219fdee073ae20bf05bdb435bc1a7fb7cf0f089;p=ardour.git diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc index 74b7ce6566..13bc579731 100644 --- a/libs/ardour/audio_unit.cc +++ b/libs/ardour/audio_unit.cc @@ -431,7 +431,7 @@ AUPlugin::AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptrLatency() * _session.frame_rate(); + guint lat = g_atomic_int_get (&_current_latency);; + if (lat == UINT_MAX) { + lat = unit->Latency() * _session.frame_rate(); + g_atomic_int_set (&_current_latency, lat); + } + return lat; } void @@ -1082,8 +1087,6 @@ AUPlugin::set_block_size (pframes_t nframes) activate (); } - _current_block_size = nframes; - return 0; } @@ -1648,7 +1651,9 @@ AUPlugin::connect_and_run (BufferSet& bufs, bool inplace = true; // TODO check plugin-insert in-place ? ChanMapping::Mappings inmap (in_map.mappings ()); ChanMapping::Mappings outmap (out_map.mappings ()); - assert (outmap[DataType::AUDIO].size () > 0); + if (outmap[DataType::AUDIO].size () == 0) { + inplace = false; + } if (inmap[DataType::AUDIO].size() > 0 && inmap != outmap) { inplace = false; } @@ -1798,29 +1803,12 @@ AUPlugin::get_beat_and_tempo_callback (Float64* outCurrentBeat, DEBUG_TRACE (DEBUG::AudioUnits, "AU calls ardour beat&tempo callback\n"); - /* more than 1 meter or more than 1 tempo means that a simplistic computation - (and interpretation) of a beat position will be incorrect. So refuse to - offer the value. - */ - - if (tmap.n_tempos() > 1 || tmap.n_meters() > 1) { - return kAudioUnitErr_CannotDoInCurrentContext; - } - - TempoMetric metric = tmap.metric_at (transport_frame + input_offset); - Timecode::BBT_Time bbt = _session.tempo_map().bbt_at_frame (transport_frame + input_offset); - if (outCurrentBeat) { - const double ppq_scaling = metric.meter().note_divisor() / 4.0; - float beat; - beat = metric.meter().divisions_per_bar() * (bbt.bars - 1); - beat += (bbt.beats - 1); - beat += bbt.ticks / Timecode::BBT_Time::ticks_per_beat; - *outCurrentBeat = beat * ppq_scaling; + *outCurrentBeat = tmap.quarter_note_at_frame (transport_frame + input_offset); } if (outCurrentTempo) { - *outCurrentTempo = floor (metric.tempo().beats_per_minute()); + *outCurrentTempo = tmap.tempo_at_frame (transport_frame + input_offset).beats_per_minute(); } return noErr; @@ -1837,15 +1825,6 @@ AUPlugin::get_musical_time_location_callback (UInt32* outDeltaSampleOffsetToNe DEBUG_TRACE (DEBUG::AudioUnits, "AU calls ardour music time location callback\n"); - /* more than 1 meter or more than 1 tempo means that a simplistic computation - (and interpretation) of a beat position will be incorrect. So refuse to - offer the value. - */ - - if (tmap.n_tempos() > 1 || tmap.n_meters() > 1) { - return kAudioUnitErr_CannotDoInCurrentContext; - } - TempoMetric metric = tmap.metric_at (transport_frame + input_offset); Timecode::BBT_Time bbt = _session.tempo_map().bbt_at_frame (transport_frame + input_offset); @@ -1854,8 +1833,10 @@ AUPlugin::get_musical_time_location_callback (UInt32* outDeltaSampleOffsetToNe /* on the beat */ *outDeltaSampleOffsetToNextBeat = 0; } else { - double const beat_frac_to_next = (Timecode::BBT_Time::ticks_per_beat - bbt.ticks) / Timecode::BBT_Time::ticks_per_beat; - *outDeltaSampleOffsetToNextBeat = tmap.frame_at_beat (tmap.beat_at_frame (transport_frame + input_offset) + beat_frac_to_next); + double const next_beat = ceil (tmap.quarter_note_at_frame (transport_frame + input_offset)); + framepos_t const next_beat_frame = tmap.frame_at_quarter_note (next_beat); + + *outDeltaSampleOffsetToNextBeat = next_beat_frame - (transport_frame + input_offset); } } @@ -1874,8 +1855,10 @@ AUPlugin::get_musical_time_location_callback (UInt32* outDeltaSampleOffsetToNe 3|1|0 -> 1 + (2 * divisions_per_bar) etc. */ + bbt.beats = 1; + bbt.ticks = 0; - *outCurrentMeasureDownBeat = 1 + metric.meter().divisions_per_bar() * (bbt.bars - 1); + *outCurrentMeasureDownBeat = tmap.pulse_at_bbt (bbt) * 4.0; } return noErr; @@ -1928,38 +1911,14 @@ AUPlugin::get_transport_state_callback (Boolean* outIsPlaying, TempoMap& tmap (_session.tempo_map()); - /* more than 1 meter means that a simplistic computation (and interpretation) of - a beat position will be incorrect. so refuse to offer the value. - */ - - if (tmap.n_meters() > 1) { - return kAudioUnitErr_CannotDoInCurrentContext; - } - Timecode::BBT_Time bbt; if (outCycleStartBeat) { - TempoMetric metric = tmap.metric_at (loc->start() + input_offset); - bbt = _session.tempo_map().bbt_at_frame (loc->start() + input_offset); - - float beat; - beat = metric.meter().divisions_per_bar() * bbt.bars; - beat += bbt.beats; - beat += bbt.ticks / Timecode::BBT_Time::ticks_per_beat; - - *outCycleStartBeat = beat; + *outCycleStartBeat = tmap.quarter_note_at_frame (loc->start() + input_offset); } if (outCycleEndBeat) { - TempoMetric metric = tmap.metric_at (loc->end() + input_offset); - bbt = _session.tempo_map().bbt_at_frame (loc->end() + input_offset); - - float beat; - beat = metric.meter().divisions_per_bar() * bbt.bars; - beat += bbt.beats; - beat += bbt.ticks / Timecode::BBT_Time::ticks_per_beat; - - *outCycleEndBeat = beat; + *outCycleEndBeat = tmap.quarter_note_at_frame (loc->end() + input_offset); } } } @@ -3362,6 +3321,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 +3430,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 <> %2\n", new_value, unit->Latency())); + guint lat = unit->Latency() * _session.frame_rate(); + g_atomic_int_set (&_current_latency, lat); + } + return; + } + ParameterMap::iterator i; if ((i = parameter_map.find (event->mArgument.mParameter.mParameterID)) == parameter_map.end()) {