Hello,
I am creating a plugin project, setting up debugging with PluginHost.app and Xcode successfully breaks debugging in the constructors of my processor and editor classes, but only on the first run (when I search for the plugin from PluginHost.app and once I open the view of the plugin for the first time). After this, with or without any changes made to processor and editor - Xcode never stops on these breakpoints.
I wasn't sure if I messed the project somehow, so I recreated the exact same project again. The same thing reproduced - debug works on initial run and then I can't break anymore (on consequitive runs).
There should be something wrong with my specific case, so here it is - I am using one of the examples from the Demo app (AudioSynthesizerDemo). I am learning how to build a sampler and what I did is - I removed the sine wave part and left just the SamplerSound adding, but using a custom sample.
So my project is pretty much the default plugin project + 1 file (SamplerAudioSource.cpp), looking like this:
// SamplerAudioSource.cpp
struct SamplerAudioSource : public AudioSource
{
SamplerAudioSource (MidiKeyboardState& keyState) : keyboardState (keyState)
{
// Breakpoint: Xcode would allways stop here
for (int i = 4; --i >= 0;)
{
synth.addVoice (new SamplerVoice());
}
setUsingSampledSound();
}
void setUsingSampledSound()
{
const String path = "path/to/sample.wav";
const File file ( path );
AudioFormatManager formatManager;
formatManager.registerBasicFormats();
ScopedPointer<AudioFormatReader> reader (formatManager.createReaderFor (file));
BigInteger allNotes;
allNotes.setRange (0, 128, true);
synth.clearSounds();
synth.addSound (new SamplerSound ("demo sound",
*reader,
allNotes,
74, // root midi note
0.1, // attack time
0.1, // release time
10.0 // maximum sample length
));
}
void prepareToPlay (int /*samplesPerBlockExpected*/, double sampleRate) override
{
midiCollector.reset (sampleRate);
synth.setCurrentPlaybackSampleRate (sampleRate);
}
void releaseResources() override
{
}
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override
{
MidiBuffer incomingMidi;
bufferToFill.clearActiveBufferRegion();
midiCollector.removeNextBlockOfMessages (incomingMidi, bufferToFill.numSamples);
keyboardState.processNextMidiBuffer (incomingMidi, 0, bufferToFill.numSamples, true);
synth.renderNextBlock (*bufferToFill.buffer, incomingMidi, 0, bufferToFill.numSamples);
}
MidiMessageCollector midiCollector;
MidiKeyboardState& keyboardState;
AudioSampleBuffer fileBuffer;
Synthesiser synth;
};
In the editor I only add the midi keyboard component. Here is the header:
// PluginEditor.h
class FirstSamplerAudioProcessorEditor : public AudioProcessorEditor
{
...
private:
MidiKeyboardComponent keyboardComponent;
...
};
// PluginEditor.cpp
FirstSamplerAudioProcessorEditor::FirstSamplerAudioProcessorEditor (FirstSamplerAudioProcessor& p)
: AudioProcessorEditor (&p),
processor (p),
keyboardComponent (p.keyboardState, MidiKeyboardComponent::horizontalKeyboard)
{
// Breakpoint: This one is hit only the first run
setSize (400, 300);
addAndMakeVisible ( keyboardComponent );
}
...
void FirstSamplerAudioProcessorEditor::resized()
{
keyboardComponent.setBounds (8, 96, getWidth() - 16, 64);
}
And this is what the Processor looks like. This is the header:
// PluginProcessor.h
class FirstSamplerAudioProcessor : public AudioProcessor
{
public:
...
// public fields
MidiKeyboardState keyboardState;
private:
AudioDeviceManager deviceManager;
AudioSourcePlayer sourcePlayer;
SamplerAudioSource audioSource;
...
};
And the changes (from the default) implementation:
// PluginProcessor.cpp
FirstSamplerAudioProcessor::FirstSamplerAudioProcessor()
: audioSource( keyboardState )
{
// Breakpoint: This one is hit only the first run
sourcePlayer.setSource ( &audioSource );
deviceManager.addAudioCallback ( &sourcePlayer );
deviceManager.addMidiInputCallback ( String::empty, &( audioSource.midiCollector ) );
}
FirstSamplerAudioProcessor::~FirstSamplerAudioProcessor()
{
sourcePlayer.setSource (nullptr);
deviceManager.removeMidiInputCallback ( String::empty, &( audioSource.midiCollector ) );
deviceManager.removeAudioCallback ( &sourcePlayer );
}
...
One final clue - breaking in the constructor of the SamplerAudioSource is always possible.
I would appreciate any help.
Thank you.
Regards,
Nikolay Tsenkov
