2
0
Fork 0

Delete leaking params that cause JUCE assertions to fail.

Fix bad MidiMessage construction (JUCE assertion failure).
Workaround for Cubase 7.5 invoking setCurrentProgram after setStateInformation and overwriting saved state with hardcoded preset.
Add rudimentary versioning to get-/setStateInformation.
This commit is contained in:
Frits Talbot 2014-08-25 23:09:39 +02:00
parent 27c7f3f2a5
commit 446486da6b
2 changed files with 64 additions and 8 deletions

View file

@ -6,6 +6,7 @@
//==============================================================================
JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor()
: i_program(-1)
{
// Initalize OPL
velocity = false;
@ -380,6 +381,8 @@ void JuceOplvstiAudioProcessor::applyPitchBend()
JuceOplvstiAudioProcessor::~JuceOplvstiAudioProcessor()
{
for (int i = 0; i < params.size(); ++i)
delete params[i];
}
//==============================================================================
@ -598,6 +601,9 @@ void JuceOplvstiAudioProcessor::updateGuiIfPresent()
void JuceOplvstiAudioProcessor::setCurrentProgram (int index)
{
if (i_program==index)
return;
i_program = index;
std::vector<float> &v_params = programs[getProgramName(index)];
for (unsigned int i = 0; i < params.size() && i < v_params.size(); i++) {
@ -634,7 +640,7 @@ void JuceOplvstiAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuf
buffer.clear(0, 0, buffer.getNumSamples());
MidiBuffer::Iterator midi_buffer_iterator(midiMessages);
MidiMessage midi_message(0);
MidiMessage midi_message;
int sample_number;
while (midi_buffer_iterator.getNextEvent(midi_message,sample_number)) {
if (midi_message.isNoteOn()) {
@ -679,7 +685,7 @@ void JuceOplvstiAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuf
ch += 1;
}
Opl->KeyOff(ch);
active_notes[ch] = NO_NOTE;
active_notes[ch]=NO_NOTE;
}
else if (midi_message.isPitchWheel()) {
int bend = midi_message.getPitchWheelValue() - 0x2000; // range -8192 to 8191
@ -704,20 +710,69 @@ AudioProcessorEditor* JuceOplvstiAudioProcessor::createEditor()
return gui;
}
// FIXME: these two funcs and get-/setStateInformation should be replaced by a proper cross-platform archiving API, e.g. eos portable archive or boost text archive
template<class T>
void push(char *&cursor, T value)
{
*reinterpret_cast<T *>(cursor) = value;
cursor+=sizeof(T);
}
template<class T>
void pop(const char *&cursor, T &value)
{
value=*reinterpret_cast<const T *>(cursor);
cursor+=sizeof(T);
}
//==============================================================================
void JuceOplvstiAudioProcessor::getStateInformation (MemoryBlock& destData)
{
destData.ensureSize(sizeof(float) * getNumParameters());
destData.ensureSize(sizeof(CURRENT_VERSION)+sizeof(i_program)+sizeof(float) * getNumParameters());
char *cursor = static_cast<char *>(destData.getData());
push(cursor, CURRENT_VERSION);
push(cursor, i_program);
for (int i = 0; i < getNumParameters(); i++) {
float p = getParameter(i);
destData.copyFrom((void*)&p, i*sizeof(float), sizeof(float));
push(cursor, p);
}
}
void JuceOplvstiAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
if (sizeInBytes < sizeof(CURRENT_VERSION))
return;
const char *cursor = static_cast<const char *>(data);
const char *end = cursor+sizeInBytes;
int version;
pop(cursor, version);
if (version == CURRENT_VERSION)
{
pop(cursor, i_program);
const int parametersToLoad = std::min<int>(static_cast<int>(std::distance(cursor, end)) / sizeof(float), getNumParameters());
for (int i = 0; i < parametersToLoad; i++)
{
float p;
pop(cursor, p);
setParameter(i, p);
}
return;
}
float* fdata = (float*)data;
for (unsigned int i = 0; i < sizeInBytes / sizeof(float); i++) {
const int parametersToLoad = std::min<int>(sizeInBytes / sizeof(float), getNumParameters());
for (int i = 0; i < parametersToLoad; i++) {
setParameter(i, fdata[i]);
}
}

View file

@ -88,6 +88,7 @@ private:
int i_program;
bool velocity;
static const int NO_NOTE=-1;
static const int CURRENT_VERSION = 0x09720100; // OPL2 v01.00 magic
int active_notes[Hiopl::CHANNELS+1]; // keyed by channel
float currentScaledBend;