DAW block size

pull/1/head
asb2m10 11 years ago
parent e6f6ce0de1
commit ad1f4196f4
  1. BIN
      Builds/MacOSX/Dexed.xcodeproj/project.xcworkspace/xcuserdata/asb2m10.xcuserdatad/UserInterfaceState.xcuserstate
  2. 10
      README.md
  3. 152
      Source/PluginProcessor.cpp
  4. 2
      Source/PluginProcessor.h

@ -5,10 +5,10 @@ Dexed is a multi platform, multi format plugin synth that is closely modeled on
Under the hood it uses [music-synthesizer-for-android](https://code.google.com/p/music-synthesizer-for-android) Under the hood it uses [music-synthesizer-for-android](https://code.google.com/p/music-synthesizer-for-android)
for the synth engine and [JUCE](http://wwww.juce.com) as a plugin wrapper. for the synth engine and [JUCE](http://wwww.juce.com) as a plugin wrapper.
The goal of this project is to be a great tool/companion for the original DX7. Sound engine The goal of this project is to be a tool/companion for the original DX7. Sound engine
with 'float' value parameters, different waveform à la TX81z would be great but anything that with 'float' value parameters, different waveform à la TX81z would be great but anything that
goes beyond the DX7 should and will be a fork of this project. This is to keep the compatiblity with goes beyond the DX7 should and will be a fork of this project. This is to keep the compatiblity with
the original DX7. the original machine.
Dexed is licensed on the GPL v2. The msfa component (acronym for music synthesizer for android, see msfa Dexed is licensed on the GPL v2. The msfa component (acronym for music synthesizer for android, see msfa
in the source folder) stays on the Apache 2.0 license to able to collaborate between projects. in the source folder) stays on the Apache 2.0 license to able to collaborate between projects.
@ -24,6 +24,10 @@ Features
Changelog Changelog
--------- ---------
#### Version 0.5.0
* Linux support
* Fix large DAW blocksize with midi events
#### Version 0.4.0 #### Version 0.4.0
* Modulation wheel support * Modulation wheel support
* Now using the [Obxd](https://obxd.wordpress.com) 4-pole lowpass filter implementation * Now using the [Obxd](https://obxd.wordpress.com) 4-pole lowpass filter implementation
@ -35,6 +39,7 @@ Binary downloads
Dexed is not a finished product but it is stable enough to be used in a DAW environment: Dexed is not a finished product but it is stable enough to be used in a DAW environment:
in normal operation it shouldn't crash and the VST state saving works. in normal operation it shouldn't crash and the VST state saving works.
* Version 0.5.0 [vst win32](http://le-son666.com/software/dexed/dexed-0.5.0-win32.zip) - [vst win64](http://le-son666.com/software/dexed/dexed-0.5.0-win64.zip) - [vst os x](http://le-son666.com/software/dexed/dexed-0.5.0-osx.vst.zip)
* Version 0.4.0 [vst win32](http://le-son666.com/software/dexed/dexed-0.4.0-win32.zip) - [vst win64](http://le-son666.com/software/dexed/dexed-0.4.0-win64.zip) - [vst os x](http://le-son666.com/software/dexed/dexed-0.4.0-osx.vst.zip) * Version 0.4.0 [vst win32](http://le-son666.com/software/dexed/dexed-0.4.0-win32.zip) - [vst win64](http://le-son666.com/software/dexed/dexed-0.4.0-win64.zip) - [vst os x](http://le-son666.com/software/dexed/dexed-0.4.0-osx.vst.zip)
* Version 0.3.0 [vst win32](http://le-son666.com/software/dexed/dexed-0.3.0-win32.zip) - [vst win64](http://le-son666.com/software/dexed/dexed-0.3.0-win64.zip) - [vst os x](http://le-son666.com/software/dexed/dexed-0.3.0-osx.vst.zip) * Version 0.3.0 [vst win32](http://le-son666.com/software/dexed/dexed-0.3.0-win32.zip) - [vst win64](http://le-son666.com/software/dexed/dexed-0.3.0-win64.zip) - [vst os x](http://le-son666.com/software/dexed/dexed-0.3.0-osx.vst.zip)
@ -77,7 +82,6 @@ TODO - Dexed
* Implement a better DX look and feel (amp, pitch, algo) * Implement a better DX look and feel (amp, pitch, algo)
* Various code cleanup * Various code cleanup
* Standalone executable (for full support of the sysex editor) * Standalone executable (for full support of the sysex editor)
* Midi sample resolution on DAW block size
TODO - msfa TODO - msfa
----------- -----------

@ -46,7 +46,6 @@ DexedAudioProcessor::DexedAudioProcessor() {
lastStateSave = 0; lastStateSave = 0;
currentNote = -1; currentNote = -1;
workBlock = NULL;
vuSignal = 0; vuSignal = 0;
initCtrl(); initCtrl();
setCurrentProgram(0); setCurrentProgram(0);
@ -90,9 +89,6 @@ void DexedAudioProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
sustain = false; sustain = false;
extra_buf_size = 0; extra_buf_size = 0;
workBlockSize = samplesPerBlock;
workBlock = new float[samplesPerBlock];
keyboardState.reset(); keyboardState.reset();
nextMidi = new MidiMessage(0xF0); nextMidi = new MidiMessage(0xF0);
@ -109,10 +105,6 @@ void DexedAudioProcessor::releaseResources() {
voices[note].live = false; voices[note].live = false;
} }
if ( workBlock != NULL ) {
delete workBlock;
}
keyboardState.reset(); keyboardState.reset();
delete nextMidi; delete nextMidi;
@ -121,6 +113,7 @@ void DexedAudioProcessor::releaseResources() {
void DexedAudioProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { void DexedAudioProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& midiMessages) {
int numSamples = buffer.getNumSamples(); int numSamples = buffer.getNumSamples();
int i = 0;
if ( refreshVoice ) { if ( refreshVoice ) {
for(int i=0;i<MAX_ACTIVE_NOTES;i++) { for(int i=0;i<MAX_ACTIVE_NOTES;i++) {
@ -131,13 +124,6 @@ void DexedAudioProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& mi
refreshVoice = false; refreshVoice = false;
} }
// check buffer size
if ( numSamples > workBlockSize ) {
delete workBlock;
workBlockSize = numSamples;
workBlock = new float[workBlockSize];
}
// Now pass any incoming midi messages to our keyboard state object, and let it // Now pass any incoming midi messages to our keyboard state object, and let it
// add messages to the buffer if the user is clicking on the on-screen keys // add messages to the buffer if the user is clicking on the on-screen keys
keyboardState.processNextMidiBuffer (midiMessages, 0, numSamples, true); keyboardState.processNextMidiBuffer (midiMessages, 0, numSamples, true);
@ -146,38 +132,67 @@ void DexedAudioProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& mi
hasMidiMessage = it.getNextEvent(*nextMidi,midiEventPos); hasMidiMessage = it.getNextEvent(*nextMidi,midiEventPos);
float *channelData = buffer.getSampleData(0); float *channelData = buffer.getSampleData(0);
int samplePos = 0;
while(getNextEvent(&it, numSamples)) { // flush first events
processMidiMessage(midiMsg); for (i = 0; i < numSamples && i < extra_buf_size; i++) {
channelData[i] = extra_buf[i];
} }
while ( samplePos < numSamples ) { // remaining buffer is still to be processed
int block = numSamples; if (extra_buf_size > numSamples) {
for (int j = 0; j < extra_buf_size - numSamples; j++) {
/* extra_buf[j] = extra_buf[j + numSamples];
* MIDI message needs to be bound to }
* the sample. When a rendering occurs extra_buf_size -= numSamples;
* very large blocks can be passed and
* without this code, the plugin will be
* out of sync... TODO!
while(getNextEvent(&it, samplePos)) { // flush the event, they will be process in next cycle
while(getNextEvent(&it, numSamples)) {
processMidiMessage(midiMsg); processMidiMessage(midiMsg);
} }
} else {
for (; i < numSamples; i += N) {
AlignedBuf<int32_t, N> audiobuf;
float sumbuf[N];
if ( hasMidiMessage ) { while(getNextEvent(&it, i)) {
block = midiEventPos - samplePos; processMidiMessage(midiMsg);
} else { }
block = numSamples - samplePos;
} for (int j = 0; j < N; ++j) {
*/ audiobuf.get()[j] = 0;
sumbuf[j] = 0;
}
int32_t lfovalue = lfo.getsample();
int32_t lfodelay = lfo.getdelay();
for (int note = 0; note < MAX_ACTIVE_NOTES; ++note) {
if (voices[note].live) {
voices[note].dx7_note->compute(audiobuf.get(), lfovalue, lfodelay, &controllers);
for (int j=0; j < N; ++j) {
int32_t val = audiobuf.get()[j] >> 4;
int clip_val = val < -(1 << 24) ? 0x8000 : val >= (1 << 24) ? 0x7fff : val >> 9;
float f = ((float) clip_val) / (float) 32768;
if( f > 1 ) f = 1;
if( f < -1 ) f = -1;
sumbuf[j] += f;
audiobuf.get()[j] = 0;
}
}
}
processSamples(block, workBlock); int jmax = numSamples - i;
for(int i = 0; i < block; i++ ) for (int j = 0; j < N; ++j) {
channelData[i+samplePos] = workBlock[i]; if (j < jmax) {
channelData[i + j] = sumbuf[j];
} else {
extra_buf[j - jmax] = sumbuf[j];
}
}
}
}
samplePos += block; while(getNextEvent(&it, numSamples)) {
processMidiMessage(midiMsg);
} }
fx.process(channelData, numSamples); fx.process(channelData, numSamples);
@ -211,6 +226,14 @@ void DexedAudioProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& mi
} }
} }
void DexedAudioProcessor::processSamples(int n_samples, float *buffer) {
int i;
extra_buf_size = i - n_samples;
}
//============================================================================== //==============================================================================
// This creates new instances of the plugin.. // This creates new instances of the plugin..
@ -359,59 +382,6 @@ void DexedAudioProcessor::keyup(uint8_t pitch) {
} }
} }
void DexedAudioProcessor::processSamples(int n_samples, float *buffer) {
int i;
for (i = 0; i < n_samples && i < extra_buf_size; i++) {
buffer[i] = extra_buf[i];
}
if (extra_buf_size > n_samples) {
for (int j = 0; j < extra_buf_size - n_samples; j++) {
extra_buf[j] = extra_buf[j + n_samples];
}
extra_buf_size -= n_samples;
return;
}
for (; i < n_samples; i += N) {
AlignedBuf<int32_t, N> audiobuf;
float sumbuf[N];
for (int j = 0; j < N; ++j) {
audiobuf.get()[j] = 0;
sumbuf[j] = 0;
}
int32_t lfovalue = lfo.getsample();
int32_t lfodelay = lfo.getdelay();
for (int note = 0; note < MAX_ACTIVE_NOTES; ++note) {
if (voices[note].live) {
voices[note].dx7_note->compute(audiobuf.get(), lfovalue, lfodelay, &controllers);
for (int j=0; j < N; ++j) {
int32_t val = audiobuf.get()[j] >> 4;
int clip_val = val < -(1 << 24) ? 0x8000 : val >= (1 << 24) ? 0x7fff : val >> 9;
float f = ((float) clip_val) / (float) 32768;
if( f > 1 ) f = 1;
if( f < -1 ) f = -1;
sumbuf[j] += f;
audiobuf.get()[j] = 0;
}
}
}
int jmax = n_samples - i;
for (int j = 0; j < N; ++j) {
if (j < jmax) {
buffer[i + j] = sumbuf[j];
} else {
extra_buf[j - jmax] = sumbuf[j];
}
}
}
extra_buf_size = i - n_samples;
}
// ==================================================================== // ====================================================================
bool DexedAudioProcessor::peekVoiceStatus() { bool DexedAudioProcessor::peekVoiceStatus() {
if ( currentNote == -1 ) if ( currentNote == -1 )

@ -57,8 +57,6 @@ class DexedAudioProcessor : public AudioProcessor, public AsyncUpdater
float extra_buf[N]; float extra_buf[N];
int extra_buf_size; int extra_buf_size;
float *workBlock;
int workBlockSize;
int currentProgram; int currentProgram;
/** /**

Loading…
Cancel
Save