AudioProcessorPlayer breaks custom-assigned AudioPlayhead (incl. fix)

During its audioDeviceIOCallbackWithContext() callback, AudioProcessorPlayer recklessly replaces any AudioPlayhead that was already assigned. It should probably remember it and call its getPosition() instead and restore it when deleted.

This issue was introduced with Juce 7.

Here’s a proposed fix (juce_AudioProcessorPlayer.cpp) that works fine with my host.

Rationale: If a specific playhead is already assigned to AudioProcessorPlayer, we can assume it wants full responsibility and should not replace it, even if the replacement might deliver more accurate times. I resisted the temptation to ‘merge’ both infos, because that’s too many assumptions involved.

        class PlayHead : private AudioPlayHead
        {
        public:
            PlayHead (AudioProcessor& proc,
                      Optional<uint64_t> hostTimeIn,
                      uint64_t sampleCountIn,
                      double sampleRateIn)
                : processor (proc),
                  existing (processor.getPlayHead()),
                  hostTimeNs (hostTimeIn),
                  sampleCount (sampleCountIn),
                  seconds ((double) sampleCountIn / sampleRateIn)
            {
                processor.setPlayHead (this);
            }

            ~PlayHead() override
            {
                processor.setPlayHead (existing);
            }

        private:
            Optional<PositionInfo> getPosition() const override
            {
                if (existing != nullptr)
                    if (const auto pos = existing->getPosition())
                        return *pos;

                PositionInfo info;
                info.setHostTimeNs (hostTimeNs);
                info.setTimeInSamples ((int64_t) sampleCount);
                info.setTimeInSeconds (seconds);
                return info;
            }
            
            AudioProcessor& processor;
            AudioPlayHead* existing;
            Optional<uint64_t> hostTimeNs;
            uint64_t sampleCount;
            double seconds;
        };

Context: I’m using a class derived from AudioProcessorPlayer as the driver of a host’s transport. Its audioDeviceIOCallbackWithContext() callback advances the time of an AudioPlayhead that is assigned to it and that also controls Start, Stop, Locate, etc. It’s probably not a common way of doing this, but if an AudioPlayhead was deliberately assigned, it should not silently be replaced no matter what.

Since this problem came up before, it would be great of the proposed change could be considered.

Thanks!