- evaluate MidiClock

git-svn-id: http://moon:8086/svn/software/trunk/projects/JaySynth@269 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
2015-03-20 16:35:58 +00:00
parent 13adfc4ddd
commit 210833df74
18 changed files with 1826 additions and 1640 deletions
Binary file not shown.
Binary file not shown.
+6 -1
View File
@@ -10,7 +10,12 @@
pluginAUExportPrefix="JaySynthAU" pluginRTASCategory="" aaxIdentifier="com.yourcompany.JaySynth"
pluginAAXCategory="AAX_ePlugInCategory_Dynamics" jucerVersion="3.1.0">
<MAINGROUP id="JZYYhB" name="JaySynth">
<GROUP id="{0DB5BC0B-0430-BEF4-A718-904ED25AF98F}" name="Source"/>
<GROUP id="{0DB5BC0B-0430-BEF4-A718-904ED25AF98F}" name="Source">
<FILE id="GSnFml" name="JaySynthAudioProcessorEditor.cpp" compile="1"
resource="0" file="Source/JaySynthAudioProcessorEditor.cpp"/>
<FILE id="ImntJQ" name="JaySynthAudioProcessorEditor.h" compile="0"
resource="0" file="Source/JaySynthAudioProcessorEditor.h"/>
</GROUP>
</MAINGROUP>
<EXPORTFORMATS>
<LINUX_MAKE targetFolder="Builds/Linux">
+1 -1
View File
@@ -227,7 +227,7 @@
#define JucePlugin_WantsMidiInput 1
#endif
#ifndef JucePlugin_ProducesMidiOutput
#define JucePlugin_ProducesMidiOutput 0
#define JucePlugin_ProducesMidiOutput 1
#endif
#ifndef JucePlugin_SilenceInProducesSilenceOut
#define JucePlugin_SilenceInProducesSilenceOut 0
Binary file not shown.
+13 -2
View File
@@ -30,7 +30,7 @@
//==============================================================================
ButtonLED::ButtonLED (const String& name)
: Button (L"Button LED"),
: Button (name),
cachedImage_led_23_red_png (0),
cachedImage_led_23_red1_png (0),
triggeredOnMouseDown(0),
@@ -50,7 +50,6 @@ ButtonLED::ButtonLED (const String& name)
//[Constructor] You can add your own custom stuff here..
setName(name);
//[/Constructor]
}
@@ -197,6 +196,18 @@ void ButtonLED::paintButton (Graphics& g, bool /*isMouseOverButton*/, bool /*isB
false);
}
}
void ButtonLED::flash(uint32_t duration_ms)
{
setToggleState(true, juce::NotificationType::dontSendNotification);
startTimer((uint32_t)duration_ms);
}
void ButtonLED::timerCallback()
{
setToggleState(false, juce::NotificationType::dontSendNotification);
}
//[/MiscUserCode]
+3 -1
View File
@@ -36,7 +36,7 @@
Describe your class and how it works here!
//[/Comments]
*/
class ButtonLED : public Button
class ButtonLED : public Button, public Timer
{
public:
//==============================================================================
@@ -48,6 +48,8 @@ public:
void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown);
void clicked(const ModifierKeys &modifiers);
void mouseWheelMove(const MouseEvent &event, const MouseWheelDetails &wheel);
void timerCallback();
void flash(uint32_t duration_ms);
void setTriggeredOnMouseDown (bool triggeredOnMouseDown);
bool getClickingTogglesState (void);
void setClickingTogglesState (bool clickingTogglesState);
+189
View File
@@ -0,0 +1,189 @@
/*
//#######################################################################################
//Class to insert Midiclock messages into a given MidiBuffer, suitable for block
//based audio callbacks. The class can act on position jumps e.g. "Loops" by sending a
//positioning message.
//NOTE: No ballistik came in to play so I wouldn't recommend using it to drive a mechanical
//tape deck!!!
//
//solar3d-software, April- 10- 2012
//#######################################################################################
*/
#include "JK_MidiClock.h"
JK_MidiClock::JK_MidiClock()
:wasPlaying(false),
syncPpqPosition(-999.0),
posChangeThreshold(0.001),
ppqToStartSyncAt(0.0),
followSongPosition(true),
syncFlag(0),
ppqOffset(0)
{
//Prepare Midi messages to avoid blocking the caller of generateMidiclock()!
continueMessage = new MidiMessage(MidiMessage::midiContinue());
stopMessage = new MidiMessage(MidiMessage::midiStop());
clockMessage = new MidiMessage(MidiMessage::midiClock());
songPositionMessage = new MidiMessage(MidiMessage::songPositionPointer(0));
}
//=================================================================================================
void JK_MidiClock::generateMidiclock(AudioPlayHead::CurrentPositionInfo &lastPosInfo,
MidiBuffer* midiBuffer, const int bufferSize, const double sampleRate)
{
//###################################Some explanation about musical tempo #################
//A Time Signature, is two numbers, one on top of the other. The numerator describes the #
//number of Beats in a Bar, while the denominator describes of what note value a Beat is. #
//So 4/4 would be four quarter-notes per Bar, while 4/2 would be four half-notes per Bar, #
//4/8 would be four eighth-notes per Bar, and 2/4 would be two quarter-notes per Bar. #
//#########################################################################################
if (midiBuffer != nullptr)
{
//PPQ value of one sample
const double ppqPerSample = (lastPosInfo.bpm / 60.0) / sampleRate;
//PPQ offset to compensate Midi interface latency
double hostPpqPosition = lastPosInfo.ppqPosition + ppqOffset * ppqPerSample;;
if (lastPosInfo.isPlaying || lastPosInfo.isRecording)
{
if (! wasPlaying)
{
//set the point where to start the slave
ppqToStartSyncAt = getNearestSixteenthInPPQ(hostPpqPosition);
//Special case: Master is set to always start playback from the previous start position...
if (positionJumped(syncPpqPosition, hostPpqPosition, sampleRate, ppqPerSample))
{
//Cue Midiclock slave to the nearest sixteenth note to new start position
//because the one calculated in stop mode isn't valid anymore.
sendSongPositionPointerMessage(ppqToStartSyncAt, 0, midiBuffer);
}
}
else
{
//Position jump (loop or manually position change while playing)
if (positionJumped(syncPpqPosition, hostPpqPosition, sampleRate, ppqPerSample))
{
//set the point where to start the slave
ppqToStartSyncAt = getNearestSixteenthInPPQ(hostPpqPosition);
//User has changed position manually while playing
if (syncFlag == 0)
{
midiBuffer->addEvent(*stopMessage, 0);
sendSongPositionPointerMessage(hostPpqPosition, 0, midiBuffer);
syncFlag = startSlave_;
}
else
{
if (followSongPosition)
{
sendSongPositionPointerMessage(hostPpqPosition, 0, midiBuffer);
syncFlag = startSlave_;
}
else
syncFlag = 0;
}
}
}
for (int posInBuffer = 0; posInBuffer < bufferSize; ++posInBuffer)
{
syncPpqPosition = hostPpqPosition + (posInBuffer * ppqPerSample);
const int clockDistanceInSamples = roundToInt((60.0 * sampleRate) / (lastPosInfo.bpm * 24.0));
const int64 hostSamplePos = roundToInt64((hostPpqPosition * (60.0 / lastPosInfo.bpm)) * sampleRate);
const int64 syncSamplePos = hostSamplePos + posInBuffer;
//Some hosts like Cubase come up with a wacky ppqPosition
//that could break the timing! Best is to "wait"
//here for the right ppqPosition to jump on.
if (syncPpqPosition >= ppqToStartSyncAt)
{
if ((syncFlag & startSlave_) == startSlave_)
{
midiBuffer->addEvent(*continueMessage, posInBuffer);
syncFlag &= cycleEnd_;
}
//Cycle mode on
if (lastPosInfo.isLooping && lastPosInfo.ppqLoopStart != lastPosInfo.ppqLoopEnd)
{
const double ppqToCycleEnd = fabs(lastPosInfo.ppqLoopEnd - syncPpqPosition);
const int64 samplesToCycleEnd = roundToInt64(ppqToCycleEnd * (60.0 / lastPosInfo.bpm) * sampleRate);
if ((syncFlag & cycleEnd_) == 0)
{
if (samplesToCycleEnd <= clockDistanceInSamples) //For fine tuning tweak here
{
//We have reached the cycle- end position
//and must stop the Midiclock slave here
if (followSongPosition)
midiBuffer->addEvent(*stopMessage, posInBuffer);
syncFlag |= cycleEnd_;
}
}
}
}
//For best timing we should never interupt Midiclock messages!
//Seems that some slaves constantly adjusting their internal clock
//to Midiclock even if they are in stop mode.
if (syncSamplePos % clockDistanceInSamples == 0)
midiBuffer->addEvent(*clockMessage, posInBuffer);
}
wasPlaying = true;
}
else
{
//Send positioning message if the user has stopped or if he changed the playhead position
//manually in stop mode! This will also initially cue slave after loading plugin instance.
if (wasPlaying || positionJumped(syncPpqPosition, hostPpqPosition, sampleRate, ppqPerSample))
{
midiBuffer->addEvent(*stopMessage, 0);
sendSongPositionPointerMessage(hostPpqPosition, 0, midiBuffer);
}
syncPpqPosition = hostPpqPosition;
syncFlag = startSlave_;
wasPlaying = false;
}
}
}
//=================================================================================================
bool JK_MidiClock::positionJumped(const double lastPosInPPQ, const double currentPosInPPQ,
const double sampleRate, const double ppqPerSample)
{
//This returns true if the user has changed the playhead position manually or if
//a jump has occured! The comperator's default threshold is lastPosInPPQ +- 10ms.
if (currentPosInPPQ < lastPosInPPQ - ((posChangeThreshold * sampleRate) * ppqPerSample) ||
currentPosInPPQ > lastPosInPPQ + ((posChangeThreshold * sampleRate) * ppqPerSample))
return true;
return false;
}
//=================================================================================================
void JK_MidiClock::sendSongPositionPointerMessage(const double ppqPosition, const int posInBuffer, MidiBuffer* buffer)
{
//This will cue the slave to the NEAREST
//16th note to the given ppqPosition.
int intBeat = int(ceil(ppqPosition * 4));
uint8* pSongPositionTime((uint8*)(songPositionMessage->getRawData()));
*(pSongPositionTime + 1) = (uint8)(intBeat & 0x7f);
*(pSongPositionTime + 2) = (uint8)((intBeat & 0x3f80)>>7);
buffer->addEvent(*songPositionMessage, posInBuffer);
}
+73
View File
@@ -0,0 +1,73 @@
/*
//#######################################################################################
//Class to insert Midiclock messages into a given MidiBuffer, suitable for block
//based audio callbacks. The class can act on position jumps e.g. "Loops" by sending a
//positioning message.
//NOTE: No ballistik came in to play so I wouldn't recommend using it to drive a mechanical
//tape deck!!!
//
//solar3d-software, April- 10- 2012
//#######################################################################################
*/
#ifndef __JK_MIDICLOCK
#define __JK_MIDICLOCK
#include "../JuceLibraryCode/JuceHeader.h"
//#include "Includes.h"
class JK_MidiClock
{
public:
JK_MidiClock();
void setPositionJumpThreshold(const double ms) {posChangeThreshold = ms / 1000.0;}
double getPositionJumpThreshold() {return posChangeThreshold;}
void setFollowSongPosition(const bool shouldFollow) {followSongPosition = shouldFollow;}
bool getFollowSongPosition() {return followSongPosition;}
void setOffset(const int offset) {ppqOffset = offset;}
int getOffset() {return ppqOffset;}
void generateMidiclock(AudioPlayHead::CurrentPositionInfo &lastPosInfo,
MidiBuffer* midiBuffer,
const int bufferSize,
const double sampleRate);
//=================================================================================================
juce_UseDebuggingNewOperator
private:
inline int64 roundToInt64 (const double val) noexcept
{
return (val - floor(val) >= 0.5) ? (int64)(ceil(val)) : (int64)(floor(val));
}
bool wasPlaying;
double syncPpqPosition;
double posChangeThreshold;
double ppqToStartSyncAt;
bool followSongPosition;
uint8 syncFlag;
int ppqOffset;
static const int cycleEnd_ = 1;
static const int startSlave_ = 2;
ScopedPointer <MidiMessage> clockMessage;
ScopedPointer <MidiMessage> continueMessage;
ScopedPointer <MidiMessage> stopMessage;
ScopedPointer <MidiMessage> songPositionMessage;
void sendSongPositionPointerMessage(const double ppqPosition, const int posInBuffer, MidiBuffer* buffer);
bool positionJumped(const double lastPosInPPQ, const double currentPosInPPQ,
const double sampleRate, const double ppqPerSample);
double getNearestSixteenthInPPQ(const double ppqPosition) {return ceil(ppqPosition * 4.0) / 4.0;}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JK_MidiClock);
};
#endif
+36 -3
View File
@@ -113,6 +113,11 @@ JaySynth::JaySynth (int num_voices, String pathToWaves)
for (i=0; i < m_num_audiothreads; i++)
m_ppAudioThread[i] = new JaySynthThread(&m_pEventAudioThreadRdy[i], m_pVoices, num_voices, i, m_num_audiothreads);
m_clockdiv = 0;
m_lastTime_ms = 0;
m_lastTimeError_ms = 0;
m_estimatedTime_ms = 0;
}
JaySynth::~JaySynth()
@@ -1047,19 +1052,47 @@ void JaySynth::handleMidiEvent (const MidiMessage& m)
}
else if (m.isMidiClock())
{
const double alpha_1 = 1.0;
const double alpha_2 = 1.0/48;
const double currTime_ms = juce::Time::getMillisecondCounterHiRes();
double deltaTime_ms = currTime_ms - m_lastTime_ms;
if (m_lastTime_ms)
{
double timeError_ms = deltaTime_ms - m_estimatedTime_ms;
m_lastTimeError_ms = (1-alpha_1)*m_lastTimeError_ms + alpha_1*timeError_ms;
if (std::abs(timeError_ms) > 5.0)
{
m_estimatedTime_ms = deltaTime_ms;
}
else
{
m_estimatedTime_ms = m_estimatedTime_ms + alpha_2*(m_lastTimeError_ms);
}
}
m_lastTime_ms = currTime_ms;
if (!m_clockdiv)
{
uint32_t dT = (uint32_t)(24*m_estimatedTime_ms + 0.5);
listeners.call (&JaySynthListener::synthChanged, SYNTH_CHANGED_MIDICLOCK, &dT);
m_clockdiv = 24;
}
m_clockdiv--;
}
else if (m.isSongPositionPointer())
{
SynthDebug("SongPositionPointer\n");
m_clockdiv = (6 * m.getSongPositionPointerMidiBeat()) % 24;
}
else if (m.isQuarterFrame())
{
SynthDebug("QuarterFrame\n");
}
else if (m.isFullFrame())
{
SynthDebug("FullFrame\n");
}
else
{
+8 -2
View File
@@ -37,8 +37,8 @@ private:
int m_num_voices;
int m_voice_offset, m_voice_step;
int m_sample_len;
WaitableEvent *m_pEventRun;
WaitableEvent *m_pEventRdy;
ScopedPointer<WaitableEvent> m_pEventRun;
ScopedPointer<WaitableEvent> m_pEventRdy;
};
@@ -158,6 +158,7 @@ public:
SYNTH_CHANGED_NUM_VOICES_PLAYING,
SYNTH_CHANGED_NOTE_PRESSED,
SYNTH_CHANGED_NOTE_RELEASED,
SYNTH_CHANGED_MIDICLOCK,
SYNTH_CHANGED_SIZE
};
@@ -246,6 +247,11 @@ private:
JaySynthThread **m_ppAudioThread;
ScopedPointer <WaitableEvent> m_pEventAudioThreadRdy;
JaySynthMonophonicMGR m_monoMGR;
uint32_t m_clockdiv;
double m_lastTime_ms;
double m_lastTimeError_ms;
double m_estimatedTime_ms;
};
File diff suppressed because it is too large Load Diff
+220 -223
View File
@@ -1,26 +1,24 @@
/*
==============================================================================
This is an automatically generated file created by the Jucer!
Creation date: 31 Mar 2014 12:38:24pm
This is an automatically generated GUI class created by the Introjucer!
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Jucer version: 1.12
Created with Introjucer version: 3.1.0
------------------------------------------------------------------------------
The Jucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-6 by Raw Material Software ltd.
The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-13 by Raw Material Software Ltd.
==============================================================================
*/
#ifndef __JUCER_HEADER_JAYSYNTHAUDIOPROCESSOREDITOR_JAYSYNTHAUDIOPROCESSOREDITOR_1F0BC626__
#define __JUCER_HEADER_JAYSYNTHAUDIOPROCESSOREDITOR_JAYSYNTHAUDIOPROCESSOREDITOR_1F0BC626__
#ifndef __JUCE_HEADER_AD3FF14AD0EF4DBE__
#define __JUCE_HEADER_AD3FF14AD0EF4DBE__
//[Headers] -- You can add your own extra header files here --
#include "../JuceLibraryCode/JuceHeader.h"
@@ -90,9 +88,6 @@ public:
static const int led_23_red1_pngSize;
//==============================================================================
juce_UseDebuggingNewOperator
private:
//[UserVariables] -- You can add your own custom variables in this section.
JaySynthAudioProcessor* getProcessor() const
@@ -110,221 +105,223 @@ private:
//[/UserVariables]
//==============================================================================
Label* m_label_colon;
Slider* m_slider_master_volume;
Slider* m_slider_vcf_f;
Slider* m_slider_vcf_q;
Slider* m_slider_osc0_det;
Slider* m_slider_osc1_det;
Slider* m_slider_osc0_transpose;
Slider* m_slider_osc1_transpose;
Slider* m_slider_vca_env_attack;
Slider* m_slider_vca_env_decay;
Slider* m_slider_vca_env_release;
Slider* m_slider_vca_env_sustain;
Slider* m_slider_vcf_env_attack;
Slider* m_slider_vcf_env_decay;
Slider* m_slider_vcf_env_release;
Slider* m_slider_vcf_env_sustain;
Slider* m_slider_vcf_env_amount;
Label* m_label_vcf_env_attack;
Label* m_label_vcf_f;
Label* m_label_vca_env_attack;
Label* m_label_vca_env_decay;
Label* m_label_vca_env_sustain;
Label* m_label_vca_env_release;
Label* m_label_vcf_env_decay;
Label* m_label_vcf_env_sustain;
Label* m_label_vcf_env_release;
Label* m_label_vcf_q;
Label* m_label_vcf_env_amount;
Label* m_label_master_volume;
Label* m_label_osc0_transpose;
Label* m_label_osc1_transpose;
Label* m_label_osc0_det;
Label* m_label_osc1_det;
Slider* m_slider_vca_env_amount;
Label* m_label_vca_env_amount;
Slider* m_slider_osc0_dutycycle;
Slider* m_slider_osc1_dutycycle;
Label* m_label_osc0_dutycycle;
Label* m_label_osc1_dutycycle;
Slider* m_slider_lfo0_speed;
Slider* m_slider_osc1_fm_amt0;
Slider* m_slider_osc0_fm_amt0;
Label* m_label_lfo0_speed;
Label* m_label_osc0_fm_amt0;
Label* m_label_osc1_fm_amt0;
Slider* m_slider_vcf_f_amt0;
Label* m_label_vcf_f_amt0;
Slider* m_slider_lfo1_speed;
Label* m_label_lfo1_speed;
ComboBox* m_comboBox_osc0_shape;
ComboBox* m_comboBox_osc1_shape;
ComboBox* m_comboBox_lfo0_shape;
ComboBox* m_comboBox_lfo1_shape;
Slider* m_slider_lfo2_speed;
Slider* m_slider_lfo3_speed;
ComboBox* m_comboBox_lfo2_shape;
ComboBox* m_comboBox_lfo3_shape;
Label* m_label_lfo2_speed;
Label* m_label_lfo3_speed;
ComboBox* m_comboBox_vcf_f_src0;
ComboBox* m_comboBox_osc0_fm_src0;
ComboBox* m_comboBox_osc1_fm_src0;
Slider* m_slider_vca_am_amt0;
Label* m_label_vca_am_amt0;
ComboBox* m_comboBox_vca_am_src0;
Slider* m_slider_vca_pan_amt0;
Label* m_label_vca_pan_amt0;
ComboBox* m_comboBox_vca_pan_src0;
Label* m_label_synth_name;
Label* m_label_synth_version;
ComboBox* m_comboBox_vcf_type;
Slider* m_slider_lfo1_smooth;
Label* m_label_lfo1_smooth;
Slider* m_slider_lfo0_smooth;
Label* m_label_lfo0_smooth;
Slider* m_slider_lfo2_smooth;
Label* m_label_lfo2_smooth;
Slider* m_slider_lfo3_smooth;
Label* m_label_lfo3_smooth;
Slider* m_slider_osc0_pwm_amt0;
Label* m_label_osc0_pwm_amt0;
Slider* m_slider_osc1_pwm_amt0;
Label* m_label_osc1_pwm_amt0;
ComboBox* m_comboBox_osc0_pwm_src0;
ComboBox* m_comboBox_osc1_pwm_src0;
Slider* m_slider_osc0_level;
Label* m_label_osc0_level;
Slider* m_slider_osc1_level;
Label* m_label_osc1_level;
Slider* m_slider_noise_level;
Label* m_label_noise_level;
ComboBox* m_comboBox_noise_shape;
ButtonLED* m_btn_noise_enable_led;
ButtonLED* m_btn_osc0_enable;
ButtonLED* m_btn_osc1_enable;
Label* m_label_patch_name;
TextButton* m_button_patch_incr;
TextButton* m_button_patch_decr;
Label* m_label_patch_number;
Label* m_label_osc1_pb_min;
Label* m_label_osc1_pb_max;
Label* m_label_osc0_pb_max;
Label* m_label_osc0_pb_min;
Slider* m_slider_master_tune;
Label* m_label_master_tune;
ToggleButton* m_button_humanize_enable;
ComboBox* m_comboBox_vcf_order;
Slider* m_slider_portamento_time;
Label* m_label_portamento_time;
ToggleButton* m_button_unisono_enable;
Slider* m_slider_humanize_var_vco;
Slider* m_slider_voice_pan_spread;
Label* m_label_voice_pan_spread;
Slider* m_slider_humanize_var_vcf;
Slider* m_slider_humanize_var_env;
Label* m_label_unisono_num_voices;
ToggleButton* m_button_osc0_restart_enable;
ToggleButton* m_button_osc1_restart_enable;
ToggleButton* m_button_mono_enable;
ComboBox* m_comboBox_osc1_fm_src1;
ComboBox* m_comboBox_osc1_pwm_src1;
ComboBox* m_comboBox_osc0_fm_src1;
ComboBox* m_comboBox_osc0_pwm_src1;
ComboBox* m_comboBox_osc1_am_src0;
ComboBox* m_comboBox_osc1_am_src1;
Slider* m_slider_osc1_am_amt0;
Label* m_label_osc1_am_amt0;
ComboBox* m_comboBox_osc0_am_src0;
ComboBox* m_comboBox_osc0_am_src1;
Slider* m_slider_osc0_am_amt0;
Label* m_label_osc0_am_amt0;
Slider* m_slider_env2_attack;
Slider* m_slider_env2_decay;
Slider* m_slider_env2_release;
Slider* m_slider_env2_sustain;
Label* m_label_env2_attack;
Label* m_label_env2_decay;
Label* m_label_env2_sustain;
Label* m_label_env2_release;
Slider* m_slider_env3_attack;
Slider* m_slider_env3_decay;
Slider* m_slider_env3_release;
Slider* m_slider_env3_sustain;
Label* m_label_env3_attack;
Label* m_label_env3_decay;
Label* m_label_env3_sustain;
Label* m_label_env3_release;
ComboBox* m_comboBox_vcf_f_src1;
Slider* m_slider_vcf_q_amt0;
Label* m_label_vcf_q_amt0;
ComboBox* m_comboBox_vcf_q_src0;
ComboBox* m_comboBox_vcf_q_src1;
Label* m_label_humanize_var_vco;
Label* m_label_humanize_var_vcf;
Label* m_label_humanize_var_env;
ButtonLED* m_btn_limiter_led;
Label* m_label_limiter_led;
Slider* m_slider_lfo0_delay;
Label* m_label_lfo0_delay;
Slider* m_slider_lfo0_attack;
Label* m_label_lfo0_attack;
Slider* m_slider_lfo1_delay;
Label* m_label_lfo1_delay;
Slider* m_slider_lfo1_attack;
Label* m_label_lfo1_attack;
Slider* m_slider_lfo2_delay;
Label* m_label_lfo2_delay;
Slider* m_slider_lfo2_attack;
Label* m_label_lfo2_attack;
Slider* m_slider_lfo3_delay;
Label* m_label_lfo3_delay;
Slider* m_slider_lfo3_attack;
Label* m_label_lfo3_attack;
ToggleButton* m_button_lfo0_restart_enable;
ToggleButton* m_button_lfo0_individual_enable;
Slider* m_slider_lfo0_symmetry;
Label* m_label_lfo0_symmetry;
Slider* m_slider_lfo1_symmetry;
Label* m_label_lfo1_symmetry;
ToggleButton* m_button_lfo1_restart_enable;
ToggleButton* m_button_lfo1_individual_enable;
ToggleButton* m_button_lfo2_restart_enable;
ToggleButton* m_button_lfo2_individual_enable;
Slider* m_slider_lfo2_symmetry;
Label* m_label_lfo2_symmetry;
Slider* m_slider_lfo3_symmetry;
Label* m_label_lfo3_symmetry;
ToggleButton* m_button_lfo3_restart_enable;
ToggleButton* m_button_lfo3_individual_enable;
Slider* m_slider_osc0_fm_amt1;
Label* m_label_osc0_fm_amt1;
Slider* m_slider_osc0_pwm_amt1;
Label* m_label_osc0_pwm_amt1;
Slider* m_slider_osc0_am_amt1;
Label* m_label_osc0_am_amt1;
Slider* m_slider_osc1_fm_amt1;
Label* m_label_osc1_fm_amt1;
Slider* m_slider_osc1_pwm_amt1;
Label* m_label_osc1_pwm_amt1;
Slider* m_slider_osc1_am_amt1;
Label* m_label_osc1_am_amt1;
Slider* m_slider_vcf_f_amt1;
Label* m_label_vcf_f_amt1;
Slider* m_slider_vcf_q_amt1;
Label* m_label_vcf_q_amt1;
ToggleButton* m_button_mono_retrigger;
Label* m_label_max_num_voices;
Label* m_label_num_voices_playing;
ScopedPointer<Label> m_label_colon;
ScopedPointer<Slider> m_slider_master_volume;
ScopedPointer<Slider> m_slider_vcf_f;
ScopedPointer<Slider> m_slider_vcf_q;
ScopedPointer<Slider> m_slider_osc0_det;
ScopedPointer<Slider> m_slider_osc1_det;
ScopedPointer<Slider> m_slider_osc0_transpose;
ScopedPointer<Slider> m_slider_osc1_transpose;
ScopedPointer<Slider> m_slider_vca_env_attack;
ScopedPointer<Slider> m_slider_vca_env_decay;
ScopedPointer<Slider> m_slider_vca_env_release;
ScopedPointer<Slider> m_slider_vca_env_sustain;
ScopedPointer<Slider> m_slider_vcf_env_attack;
ScopedPointer<Slider> m_slider_vcf_env_decay;
ScopedPointer<Slider> m_slider_vcf_env_release;
ScopedPointer<Slider> m_slider_vcf_env_sustain;
ScopedPointer<Slider> m_slider_vcf_env_amount;
ScopedPointer<Label> m_label_vcf_env_attack;
ScopedPointer<Label> m_label_vcf_f;
ScopedPointer<Label> m_label_vca_env_attack;
ScopedPointer<Label> m_label_vca_env_decay;
ScopedPointer<Label> m_label_vca_env_sustain;
ScopedPointer<Label> m_label_vca_env_release;
ScopedPointer<Label> m_label_vcf_env_decay;
ScopedPointer<Label> m_label_vcf_env_sustain;
ScopedPointer<Label> m_label_vcf_env_release;
ScopedPointer<Label> m_label_vcf_q;
ScopedPointer<Label> m_label_vcf_env_amount;
ScopedPointer<Label> m_label_master_volume;
ScopedPointer<Label> m_label_osc0_transpose;
ScopedPointer<Label> m_label_osc1_transpose;
ScopedPointer<Label> m_label_osc0_det;
ScopedPointer<Label> m_label_osc1_det;
ScopedPointer<Slider> m_slider_vca_env_amount;
ScopedPointer<Label> m_label_vca_env_amount;
ScopedPointer<Slider> m_slider_osc0_dutycycle;
ScopedPointer<Slider> m_slider_osc1_dutycycle;
ScopedPointer<Label> m_label_osc0_dutycycle;
ScopedPointer<Label> m_label_osc1_dutycycle;
ScopedPointer<Slider> m_slider_lfo0_speed;
ScopedPointer<Slider> m_slider_osc1_fm_amt0;
ScopedPointer<Slider> m_slider_osc0_fm_amt0;
ScopedPointer<Label> m_label_lfo0_speed;
ScopedPointer<Label> m_label_osc0_fm_amt0;
ScopedPointer<Label> m_label_osc1_fm_amt0;
ScopedPointer<Slider> m_slider_vcf_f_amt0;
ScopedPointer<Label> m_label_vcf_f_amt0;
ScopedPointer<Slider> m_slider_lfo1_speed;
ScopedPointer<Label> m_label_lfo1_speed;
ScopedPointer<ComboBox> m_comboBox_osc0_shape;
ScopedPointer<ComboBox> m_comboBox_osc1_shape;
ScopedPointer<ComboBox> m_comboBox_lfo0_shape;
ScopedPointer<ComboBox> m_comboBox_lfo1_shape;
ScopedPointer<Slider> m_slider_lfo2_speed;
ScopedPointer<Slider> m_slider_lfo3_speed;
ScopedPointer<ComboBox> m_comboBox_lfo2_shape;
ScopedPointer<ComboBox> m_comboBox_lfo3_shape;
ScopedPointer<Label> m_label_lfo2_speed;
ScopedPointer<Label> m_label_lfo3_speed;
ScopedPointer<ComboBox> m_comboBox_vcf_f_src0;
ScopedPointer<ComboBox> m_comboBox_osc0_fm_src0;
ScopedPointer<ComboBox> m_comboBox_osc1_fm_src0;
ScopedPointer<Slider> m_slider_vca_am_amt0;
ScopedPointer<Label> m_label_vca_am_amt0;
ScopedPointer<ComboBox> m_comboBox_vca_am_src0;
ScopedPointer<Slider> m_slider_vca_pan_amt0;
ScopedPointer<Label> m_label_vca_pan_amt0;
ScopedPointer<ComboBox> m_comboBox_vca_pan_src0;
ScopedPointer<Label> m_label_synth_name;
ScopedPointer<Label> m_label_synth_version;
ScopedPointer<ComboBox> m_comboBox_vcf_type;
ScopedPointer<Slider> m_slider_lfo1_smooth;
ScopedPointer<Label> m_label_lfo1_smooth;
ScopedPointer<Slider> m_slider_lfo0_smooth;
ScopedPointer<Label> m_label_lfo0_smooth;
ScopedPointer<Slider> m_slider_lfo2_smooth;
ScopedPointer<Label> m_label_lfo2_smooth;
ScopedPointer<Slider> m_slider_lfo3_smooth;
ScopedPointer<Label> m_label_lfo3_smooth;
ScopedPointer<Slider> m_slider_osc0_pwm_amt0;
ScopedPointer<Label> m_label_osc0_pwm_amt0;
ScopedPointer<Slider> m_slider_osc1_pwm_amt0;
ScopedPointer<Label> m_label_osc1_pwm_amt0;
ScopedPointer<ComboBox> m_comboBox_osc0_pwm_src0;
ScopedPointer<ComboBox> m_comboBox_osc1_pwm_src0;
ScopedPointer<Slider> m_slider_osc0_level;
ScopedPointer<Label> m_label_osc0_level;
ScopedPointer<Slider> m_slider_osc1_level;
ScopedPointer<Label> m_label_osc1_level;
ScopedPointer<Slider> m_slider_noise_level;
ScopedPointer<Label> m_label_noise_level;
ScopedPointer<ComboBox> m_comboBox_noise_shape;
ScopedPointer<ButtonLED> m_btn_noise_enable_led;
ScopedPointer<ButtonLED> m_btn_osc0_enable;
ScopedPointer<ButtonLED> m_btn_osc1_enable;
ScopedPointer<Label> m_label_patch_name;
ScopedPointer<TextButton> m_button_patch_incr;
ScopedPointer<TextButton> m_button_patch_decr;
ScopedPointer<Label> m_label_patch_number;
ScopedPointer<Label> m_label_osc1_pb_min;
ScopedPointer<Label> m_label_osc1_pb_max;
ScopedPointer<Label> m_label_osc0_pb_max;
ScopedPointer<Label> m_label_osc0_pb_min;
ScopedPointer<Slider> m_slider_master_tune;
ScopedPointer<Label> m_label_master_tune;
ScopedPointer<ToggleButton> m_button_humanize_enable;
ScopedPointer<ComboBox> m_comboBox_vcf_order;
ScopedPointer<Slider> m_slider_portamento_time;
ScopedPointer<Label> m_label_portamento_time;
ScopedPointer<ToggleButton> m_button_unisono_enable;
ScopedPointer<Slider> m_slider_humanize_var_vco;
ScopedPointer<Slider> m_slider_voice_pan_spread;
ScopedPointer<Label> m_label_voice_pan_spread;
ScopedPointer<Slider> m_slider_humanize_var_vcf;
ScopedPointer<Slider> m_slider_humanize_var_env;
ScopedPointer<Label> m_label_unisono_num_voices;
ScopedPointer<ToggleButton> m_button_osc0_restart_enable;
ScopedPointer<ToggleButton> m_button_osc1_restart_enable;
ScopedPointer<ToggleButton> m_button_mono_enable;
ScopedPointer<ComboBox> m_comboBox_osc1_fm_src1;
ScopedPointer<ComboBox> m_comboBox_osc1_pwm_src1;
ScopedPointer<ComboBox> m_comboBox_osc0_fm_src1;
ScopedPointer<ComboBox> m_comboBox_osc0_pwm_src1;
ScopedPointer<ComboBox> m_comboBox_osc1_am_src0;
ScopedPointer<ComboBox> m_comboBox_osc1_am_src1;
ScopedPointer<Slider> m_slider_osc1_am_amt0;
ScopedPointer<Label> m_label_osc1_am_amt0;
ScopedPointer<ComboBox> m_comboBox_osc0_am_src0;
ScopedPointer<ComboBox> m_comboBox_osc0_am_src1;
ScopedPointer<Slider> m_slider_osc0_am_amt0;
ScopedPointer<Label> m_label_osc0_am_amt0;
ScopedPointer<Slider> m_slider_env2_attack;
ScopedPointer<Slider> m_slider_env2_decay;
ScopedPointer<Slider> m_slider_env2_release;
ScopedPointer<Slider> m_slider_env2_sustain;
ScopedPointer<Label> m_label_env2_attack;
ScopedPointer<Label> m_label_env2_decay;
ScopedPointer<Label> m_label_env2_sustain;
ScopedPointer<Label> m_label_env2_release;
ScopedPointer<Slider> m_slider_env3_attack;
ScopedPointer<Slider> m_slider_env3_decay;
ScopedPointer<Slider> m_slider_env3_release;
ScopedPointer<Slider> m_slider_env3_sustain;
ScopedPointer<Label> m_label_env3_attack;
ScopedPointer<Label> m_label_env3_decay;
ScopedPointer<Label> m_label_env3_sustain;
ScopedPointer<Label> m_label_env3_release;
ScopedPointer<ComboBox> m_comboBox_vcf_f_src1;
ScopedPointer<Slider> m_slider_vcf_q_amt0;
ScopedPointer<Label> m_label_vcf_q_amt0;
ScopedPointer<ComboBox> m_comboBox_vcf_q_src0;
ScopedPointer<ComboBox> m_comboBox_vcf_q_src1;
ScopedPointer<Label> m_label_humanize_var_vco;
ScopedPointer<Label> m_label_humanize_var_vcf;
ScopedPointer<Label> m_label_humanize_var_env;
ScopedPointer<ButtonLED> m_btn_limiter_led;
ScopedPointer<Label> m_label_limiter_led;
ScopedPointer<Slider> m_slider_lfo0_delay;
ScopedPointer<Label> m_label_lfo0_delay;
ScopedPointer<Slider> m_slider_lfo0_attack;
ScopedPointer<Label> m_label_lfo0_attack;
ScopedPointer<Slider> m_slider_lfo1_delay;
ScopedPointer<Label> m_label_lfo1_delay;
ScopedPointer<Slider> m_slider_lfo1_attack;
ScopedPointer<Label> m_label_lfo1_attack;
ScopedPointer<Slider> m_slider_lfo2_delay;
ScopedPointer<Label> m_label_lfo2_delay;
ScopedPointer<Slider> m_slider_lfo2_attack;
ScopedPointer<Label> m_label_lfo2_attack;
ScopedPointer<Slider> m_slider_lfo3_delay;
ScopedPointer<Label> m_label_lfo3_delay;
ScopedPointer<Slider> m_slider_lfo3_attack;
ScopedPointer<Label> m_label_lfo3_attack;
ScopedPointer<ToggleButton> m_button_lfo0_restart_enable;
ScopedPointer<ToggleButton> m_button_lfo0_individual_enable;
ScopedPointer<Slider> m_slider_lfo0_symmetry;
ScopedPointer<Label> m_label_lfo0_symmetry;
ScopedPointer<Slider> m_slider_lfo1_symmetry;
ScopedPointer<Label> m_label_lfo1_symmetry;
ScopedPointer<ToggleButton> m_button_lfo1_restart_enable;
ScopedPointer<ToggleButton> m_button_lfo1_individual_enable;
ScopedPointer<ToggleButton> m_button_lfo2_restart_enable;
ScopedPointer<ToggleButton> m_button_lfo2_individual_enable;
ScopedPointer<Slider> m_slider_lfo2_symmetry;
ScopedPointer<Label> m_label_lfo2_symmetry;
ScopedPointer<Slider> m_slider_lfo3_symmetry;
ScopedPointer<Label> m_label_lfo3_symmetry;
ScopedPointer<ToggleButton> m_button_lfo3_restart_enable;
ScopedPointer<ToggleButton> m_button_lfo3_individual_enable;
ScopedPointer<Slider> m_slider_osc0_fm_amt1;
ScopedPointer<Label> m_label_osc0_fm_amt1;
ScopedPointer<Slider> m_slider_osc0_pwm_amt1;
ScopedPointer<Label> m_label_osc0_pwm_amt1;
ScopedPointer<Slider> m_slider_osc0_am_amt1;
ScopedPointer<Label> m_label_osc0_am_amt1;
ScopedPointer<Slider> m_slider_osc1_fm_amt1;
ScopedPointer<Label> m_label_osc1_fm_amt1;
ScopedPointer<Slider> m_slider_osc1_pwm_amt1;
ScopedPointer<Label> m_label_osc1_pwm_amt1;
ScopedPointer<Slider> m_slider_osc1_am_amt1;
ScopedPointer<Label> m_label_osc1_am_amt1;
ScopedPointer<Slider> m_slider_vcf_f_amt1;
ScopedPointer<Label> m_label_vcf_f_amt1;
ScopedPointer<Slider> m_slider_vcf_q_amt1;
ScopedPointer<Label> m_label_vcf_q_amt1;
ScopedPointer<ToggleButton> m_button_mono_retrigger;
ScopedPointer<Label> m_label_max_num_voices;
ScopedPointer<Label> m_label_num_voices_playing;
ScopedPointer<Label> m_labelDebug;
ScopedPointer<ButtonLED> m_btn_midiClockLed;
//==============================================================================
// (prevent copy constructor and operator= being generated..)
JaySynthAudioProcessorEditor (const JaySynthAudioProcessorEditor&);
const JaySynthAudioProcessorEditor& operator= (const JaySynthAudioProcessorEditor&);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JaySynthAudioProcessorEditor)
};
//[EndFile] You can add extra defines here...
//[/EndFile]
#endif // __JUCER_HEADER_JAYSYNTHAUDIOPROCESSOREDITOR_JAYSYNTHAUDIOPROCESSOREDITOR_1F0BC626__
#endif // __JUCE_HEADER_AD3FF14AD0EF4DBE__
+10
View File
@@ -166,6 +166,11 @@ void JaySynthAudioProcessor::synthChanged(int type, void *pData)
actionListener.callNumVoicesPlaying(*((int*)pData));
break;
case JaySynth::SYNTH_CHANGED_MIDICLOCK:
if (getEditor(this) != NULL)
actionListener.callMidiClock(*((uint32_t*)pData));
break;
default:
break;
}
@@ -518,6 +523,11 @@ void JaySynthAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer
synth_float_t x, limiter_ar, limiter_af, limiter_threshold;
float synth_gain;
AudioPlayHead::CurrentPositionInfo pos;
getPlayHead()->getCurrentPosition(pos);
m_JK_MidiClock.generateMidiclock(pos, &midiMessages, numSamples, getSampleRate());
// 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
keyboardState.processNextMidiBuffer (midiMessages, 0, numSamples, true);
+14
View File
@@ -15,6 +15,7 @@
#include "synth/synth_defs.h"
#include "JaySynthSound.h"
#include "JaySynth.h"
#include "JK_MidiClock.h"
//==============================================================================
/**
@@ -30,6 +31,7 @@ public:
JAYSYNTH_CHANGED_NOTE_PRESSED,
JAYSYNTH_CHANGED_NOTE_RELEASED,
JAYSYNTH_CHANGED_NUM_VOICES_PLAYING,
JAYSYNTH_CHANGED_MIDICLOCK,
JAYSYNTH_CHANGED_PROGRAM,
JAYSYNTH_CHANGED_LIMITER,
JAYSYNTH_CHANGED_SIZE
@@ -111,6 +113,16 @@ public:
sendActionMessage(s);
}
void callMidiClock (uint32_t deltaTime_ms)
{
String s;
s = String("type=") + String(JAYSYNTH_CHANGED_MIDICLOCK);
s = s + String(" ");
s = s + String("value=") + String(deltaTime_ms);
s = s + String(" ");
sendActionMessage(s);
}
void callBinary(void *pData, int size)
{
String s;
@@ -340,6 +352,8 @@ private:
JaySynthMidiCC midCC_editBuffer;
int m_limiter_active;
synth_float_t m_limiter_env;
JK_MidiClock m_JK_MidiClock;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JaySynthAudioProcessor);
};
+6
View File
@@ -46,6 +46,7 @@ OBJECTFILES= \
${OBJECTDIR}/JuceLibraryCode/modules/juce_graphics/juce_graphics.o \
${OBJECTDIR}/JuceLibraryCode/modules/juce_gui_basics/juce_gui_basics.o \
${OBJECTDIR}/Source/ButtonLED.o \
${OBJECTDIR}/Source/JK_MidiClock.o \
${OBJECTDIR}/Source/JaySynth.o \
${OBJECTDIR}/Source/JaySynthAudioProcessorEditor.o \
${OBJECTDIR}/Source/JaySynthMidiCC.o \
@@ -150,6 +151,11 @@ ${OBJECTDIR}/Source/ButtonLED.o: Source/ButtonLED.cpp
${RM} "$@.d"
$(COMPILE.cc) -g -DDEBUG -DSYNTH_DEBUG -DWIN32 -D_DEBUG -D_WINDOWS -Dfir_float_t=double -I../../libsrc -IJuceLibraryCode -I../../../extLib/vst2/vstsdk2.4 -std=c++11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/Source/ButtonLED.o Source/ButtonLED.cpp
${OBJECTDIR}/Source/JK_MidiClock.o: Source/JK_MidiClock.cpp
${MKDIR} -p ${OBJECTDIR}/Source
${RM} "$@.d"
$(COMPILE.cc) -g -DDEBUG -DSYNTH_DEBUG -DWIN32 -D_DEBUG -D_WINDOWS -Dfir_float_t=double -I../../libsrc -IJuceLibraryCode -I../../../extLib/vst2/vstsdk2.4 -std=c++11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/Source/JK_MidiClock.o Source/JK_MidiClock.cpp
${OBJECTDIR}/Source/JaySynth.o: Source/JaySynth.cpp
${MKDIR} -p ${OBJECTDIR}/Source
${RM} "$@.d"
+6
View File
@@ -46,6 +46,7 @@ OBJECTFILES= \
${OBJECTDIR}/JuceLibraryCode/modules/juce_graphics/juce_graphics.o \
${OBJECTDIR}/JuceLibraryCode/modules/juce_gui_basics/juce_gui_basics.o \
${OBJECTDIR}/Source/ButtonLED.o \
${OBJECTDIR}/Source/JK_MidiClock.o \
${OBJECTDIR}/Source/JaySynth.o \
${OBJECTDIR}/Source/JaySynthAudioProcessorEditor.o \
${OBJECTDIR}/Source/JaySynthMidiCC.o \
@@ -150,6 +151,11 @@ ${OBJECTDIR}/Source/ButtonLED.o: Source/ButtonLED.cpp
${RM} "$@.d"
$(COMPILE.cc) -O3 -s -DWIN32 -D_WINDOWS -Dfir_float_t=double -I../../libsrc -IJuceLibraryCode -I../../../extLib/vst2/vstsdk2.4 -std=c++11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/Source/ButtonLED.o Source/ButtonLED.cpp
${OBJECTDIR}/Source/JK_MidiClock.o: Source/JK_MidiClock.cpp
${MKDIR} -p ${OBJECTDIR}/Source
${RM} "$@.d"
$(COMPILE.cc) -O3 -s -DWIN32 -D_WINDOWS -Dfir_float_t=double -I../../libsrc -IJuceLibraryCode -I../../../extLib/vst2/vstsdk2.4 -std=c++11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/Source/JK_MidiClock.o Source/JK_MidiClock.cpp
${OBJECTDIR}/Source/JaySynth.o: Source/JaySynth.cpp
${MKDIR} -p ${OBJECTDIR}/Source
${RM} "$@.d"
+10
View File
@@ -6,6 +6,7 @@
projectFiles="true">
<itemPath>JuceLibraryCode/AppConfig.h</itemPath>
<itemPath>Source/ButtonLED.h</itemPath>
<itemPath>Source/JK_MidiClock.h</itemPath>
<itemPath>Source/JaySynth.h</itemPath>
<itemPath>Source/JaySynthAudioProcessorEditor.h</itemPath>
<itemPath>Source/JaySynthMidiCC.h</itemPath>
@@ -70,6 +71,7 @@
<itemPath>Source/synth/wavetable.h</itemPath>
</logicalFolder>
<itemPath>Source/ButtonLED.cpp</itemPath>
<itemPath>Source/JK_MidiClock.cpp</itemPath>
<itemPath>Source/JaySynth.cpp</itemPath>
<itemPath>Source/JaySynthAudioProcessorEditor.cpp</itemPath>
<itemPath>Source/JaySynthMidiCC.cpp</itemPath>
@@ -200,6 +202,10 @@
</item>
<item path="Source/ButtonLED.h" ex="false" tool="3" flavor2="0">
</item>
<item path="Source/JK_MidiClock.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="Source/JK_MidiClock.h" ex="false" tool="3" flavor2="0">
</item>
<item path="Source/JaySynth.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="Source/JaySynth.h" ex="false" tool="3" flavor2="0">
@@ -409,6 +415,10 @@
</item>
<item path="Source/ButtonLED.h" ex="false" tool="3" flavor2="0">
</item>
<item path="Source/JK_MidiClock.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="Source/JK_MidiClock.h" ex="false" tool="3" flavor2="0">
</item>
<item path="Source/JaySynth.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="Source/JaySynth.h" ex="false" tool="3" flavor2="0">