[SOLVED] Juce with Oboe - not calling next getNextAudioBlock

I have a library (which works as DLL on PC) but on Android (with Oboe) but it doesn’t appear to call the getNextAudioBlock

Oboe seems to be set up OK

2019-07-22 12:27:14.738 21333-21364/com.blah.droid_test I/JUCE: Requested Oboe stream start with result: OK
2019-07-22 12:27:14.738 21333-21364/com.blah.droid_test I/JUCE: Starting Oboe stream with result: OK

On initilisation I’m setting up a MixerAudioSource for the callback

mixer = new MixerAudioSource();
player.setSource(mixer);
deviceManager.addAudioCallback(&player);

then I’m getting a float[] of samples from the game engine (verified this is happening) which is being added to my own positionableMemoryAudioSource (see class code below)

AudioBuffer<float> myBuffer(&audioFileToLoad->audioFile.samples, 1, audioFileToLoad->audioFile.numOfSamples);
	positionableMemoryAudioSource *myPosMemAudioSource = new positionableMemoryAudioSource(myBuffer, true, true);
myPosMemAudioSource ->setLooping(true);

this is then added to a AudioTransportSource

AudioTransportSource* transportSource = new AudioTransportSource();
transportSource->setSource(myPosMemAudioSource , 0, nullptr, sRate, 1);

this is then added to mixerAudioSource and then calling Start() on the TransportSource

auto* device = deviceManager.getCurrentAudioDevice();
mymixerAudioSource->addInputSource(transportSource, false);
transportSource->prepareToPlay(device->getCurrentBufferSizeSamples(), device->getCurrentSampleRate());
transportSource->start();

I’m not getting any exceptions, and I can debug fine. Breakpoints to the
MixerAudioSource::getNextAudioBlock, AudioTransportSource::getNextAudioBlock or positionableMemoryAudioSource::getNextAudioBlock never get hit although their respective PrepareToPlay() all do

my gut feeling is that the start() isn’t getting broadcast, but its instinct - so what would be a good test of this?

adding my positionableMemoryAudioSource code but I don’t think that’s the issue, as it does work on windows but who knows!

/*
  ==============================================================================

    positionableMemoryAudioSource.h
    Created: 10 Jul 2019 10:42:42am
    Author:  me

  ==============================================================================
*/

#pragma once
#include "../JuceLibraryCode/JuceHeader.h"
namespace juce
{

	//==============================================================================
	/**
		An AudioSource which takes some float audio data as an input.

		@tags{Audio}
	*/
	class JUCE_API positionableMemoryAudioSource : public PositionableAudioSource
	{
	public:
		//==============================================================================
		/**  Creates a MemoryAudioSource by providing an audio buffer.

			 If copyMemory is true then the buffer will be copied into an internal
			 buffer which will be owned by the MemoryAudioSource. If copyMemory is
			 false, then you must ensure that the lifetime of the audio buffer is
			 at least as long as the MemoryAudioSource.
		*/
		positionableMemoryAudioSource(AudioBuffer<float>& audioBuffer, bool copyMemory, bool shouldLoop = false);

		~positionableMemoryAudioSource() override;

		//==============================================================================
		/** Implementation of the AudioSource method. */
		void prepareToPlay(int samplesPerBlockExpected, double sampleRate) override;

		/** Implementation of the AudioSource method. */
		void releaseResources() override;

		/** Implementation of the AudioSource method. */
		void getNextAudioBlock(const AudioSourceChannelInfo& bufferToFill) override;

		//==============================================================================

		void setLooping(bool shouldLoop) override;

		/** Returns whether loop-mode is turned on or not. */
		bool isLooping() const override { return looping; }

		//==============================================================================
/** Implements the PositionableAudioSource method. */
		void setNextReadPosition(int64 newPosition) override;

		/** Implements the PositionableAudioSource method. */
		int64 getNextReadPosition() const override;

		/** Implements the PositionableAudioSource method. */
		int64 getTotalLength() const override;

	private:
		//==============================================================================
		AudioBuffer<float> buffer;
		int position = 0;
		//bool isLooping;

		int64 nextPlayPos;
		bool looping;

		//==============================================================================
		JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(positionableMemoryAudioSource)
	};

} // namespace juce
/*
  ==============================================================================

    positionableMemoryAudioSource.cpp
    Created: 10 Jul 2019 10:42:42am
    Author:  me

  ==============================================================================
*/

#include "positionableMemoryAudioSource.h"

namespace juce
{

	positionableMemoryAudioSource::positionableMemoryAudioSource(AudioBuffer<float>& bufferToUse, bool copyMemory, bool shouldLoop)
		: looping(shouldLoop)
	{
		if (copyMemory)
			buffer.makeCopyOf(bufferToUse);
		else
			buffer.setDataToReferTo(bufferToUse.getArrayOfWritePointers(),
				bufferToUse.getNumChannels(),
				bufferToUse.getNumSamples());
	}


	positionableMemoryAudioSource::~positionableMemoryAudioSource() {}

	int64 positionableMemoryAudioSource::getTotalLength() const { return buffer.getNumSamples(); }
	void positionableMemoryAudioSource::setNextReadPosition(int64 newPosition) { nextPlayPos = newPosition; }
	void positionableMemoryAudioSource::setLooping(bool shouldLoop) { looping = shouldLoop; }

	int64 positionableMemoryAudioSource::getNextReadPosition() const
	{
		return looping ? nextPlayPos % buffer.getNumSamples()
			: nextPlayPos;
	}
	//==============================================================================
	void positionableMemoryAudioSource::prepareToPlay(int /*samplesPerBlockExpected*/, double /*sampleRate*/)
	{
		position = 0;
	}

	void positionableMemoryAudioSource::releaseResources() {}

	void positionableMemoryAudioSource::getNextAudioBlock(const AudioSourceChannelInfo& bufferToFill)
	{
		auto& dst = *bufferToFill.buffer;
		auto channels = jmin(dst.getNumChannels(), buffer.getNumChannels());
		auto max = 0, pos = 0;
		auto n = buffer.getNumSamples(), m = bufferToFill.numSamples;

		int i;
		for (i = position; (i < n || looping) && (pos < m); i += max)
		{
			max = jmin(m - pos, n - (i % n));

			int ch = 0;
			for (; ch < channels; ++ch)
				dst.copyFrom(ch, bufferToFill.startSample + pos, buffer, ch, i % n, max);

			for (; ch < dst.getNumChannels(); ++ch)
				dst.clear(ch, bufferToFill.startSample + pos, max);

			pos += max;
		}

		if (pos < m)
			dst.clear(bufferToFill.startSample + pos, m - pos);

		position = (i % n);
	}

} // namespace juce

This was my error.

Something about the way I was setting the breakpoints. And also in part of the code, that I had a conditional that wasn’t being passed.

you know the story!