diff --git a/Source/JK_MidiClock.cpp b/Source/JK_MidiClock.cpp new file mode 100644 index 0000000..12e7df3 --- /dev/null +++ b/Source/JK_MidiClock.cpp @@ -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); +} diff --git a/Source/JK_MidiClock.h b/Source/JK_MidiClock.h new file mode 100644 index 0000000..def132f --- /dev/null +++ b/Source/JK_MidiClock.h @@ -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 clockMessage; + ScopedPointer continueMessage; + ScopedPointer stopMessage; + ScopedPointer 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 diff --git a/Source/JaySynthMidiCC.cpp b/Source/JaySynthMidiCC.cpp index 65ee093..2ff46a0 100644 --- a/Source/JaySynthMidiCC.cpp +++ b/Source/JaySynthMidiCC.cpp @@ -712,11 +712,11 @@ synth_float_t JaySynthMidiCC::getVelKeyControl(int paramID, synth_float_t vel, s switch (midiCC_containers[paramID].velKeyCombineOP) { case VELKEY_OP_ADD: - result = min(1, max(-1, result_vel + result_key)); + result = jsy_min(1, jsy_max(-1, result_vel + result_key)); break; case VELKEY_OP_SUB: - result = min(1, max(-1, result_vel - result_key)); + result = jsy_min(1, jsy_max(-1, result_vel - result_key)); break; case VELKEY_OP_MUL: diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 7bbc0fc..aae01fd 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -576,7 +576,7 @@ void JaySynthAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer for (i=0; i m_limiter_env) { m_limiter_env = (1.0-limiter_ar)*m_limiter_env + limiter_ar*x; @@ -592,7 +592,7 @@ void JaySynthAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer m_limiter_active = 0; for (i=0; i getAtParamID(m_paramID); paramInfoInit(&m_velKey_constraints, 0, pMidiCC->getConstraints(pMidiCC_container)->pName); paramInfoCopy(&m_velKey_constraints, pMidiCC->getConstraints(pMidiCC_container)); - m_velKey_constraints.pmax = max(fabs(pMidiCC->getConstraints(pMidiCC_container)->pmin), fabs(pMidiCC->getConstraints(pMidiCC_container)->pmax)); + m_velKey_constraints.pmax = jsy_max(fabs(pMidiCC->getConstraints(pMidiCC_container)->pmin), fabs(pMidiCC->getConstraints(pMidiCC_container)->pmax)); m_velKey_constraints.pmin = -m_velKey_constraints.pmax; m_velKey_constraints.scenter = 0.5; m_velKey_constraints.pcenter = -1E18; @@ -580,15 +580,15 @@ VelKey_PopUp::VelKey_PopUp (JaySynthMidiCC *pMidiCC, int paramID, synth_float_t m_label_prec = 3; if (pMidiCC->getConstraints(pMidiCC_container)->pinterval > 0) - m_label_prec = max(1, (int)(-log(pMidiCC->getConstraints(pMidiCC_container)->pinterval)/log(10.0) + 0.5)); + m_label_prec = jsy_max(1, (int)(-log(pMidiCC->getConstraints(pMidiCC_container)->pinterval)/log(10.0) + 0.5)); m_label_shape_prec = 3; if (m_shape_xform.pinterval > 0) - m_label_shape_prec = max(1, (int)(-log(m_shape_xform.pinterval)/log(10.0) + 0.5)); + m_label_shape_prec = jsy_max(1, (int)(-log(m_shape_xform.pinterval)/log(10.0) + 0.5)); m_label_skew_prec = 3; if (m_skew_xform.pinterval > 0) - m_label_skew_prec = max(1, (int)(-log(m_skew_xform.pinterval)/log(10.0) + 0.5)); + m_label_skew_prec = jsy_max(1, (int)(-log(m_skew_xform.pinterval)/log(10.0) + 0.5)); displayUpdate(); //[/Constructor] diff --git a/Source/synth/blit.c b/Source/synth/blit.c index 448f690..4a61c3b 100644 --- a/Source/synth/blit.c +++ b/Source/synth/blit.c @@ -8,7 +8,7 @@ #include "synth_defs.h" #include "blit.h" -#include "fir/fir2.h" +#include #include "vector_utils.h" // -------------------------------------------------------------- @@ -144,8 +144,8 @@ void BLIT_ModInit(blit_common_t *pCom) blep = 0; for (n=0; n < pCom->pTableSizes[m]; n++) { - a = sin(x*pi); - b = sin(m*x*pi); + a = sin(x*jsy_pi); + b = sin(m*x*jsy_pi); if (a == 0) blit = (synth_float_t)m; else @@ -234,7 +234,7 @@ void BLIT_Prepare(blit_t *pObj, UINT32 len) synth_float_t pitch_buf[SYNTH_MAX_BUFSIZE]; synth_float_t out_buf[SYNTH_MAX_BUFSIZE]; - len = min(len, SYNTH_MAX_BUFSIZE); + len = jsy_min(len, SYNTH_MAX_BUFSIZE); // Let Oscillators run with different pitches to randomize phase Add_inplace_VS(pitch_buf, 0, 8*440.0*(1+0.01*(synth_float_t)rand()/RAND_MAX), len); @@ -343,7 +343,7 @@ void BLIT_Process_SQR_Vector(blit_t *pObj, synth_float_t *pPitch, synth_float_t { pObj->pwm = (synth_float_t)pCV_pwm[i]; } - dutycycle = min(1, max(0, pObj->dutycycle + pObj->pwm)); + dutycycle = jsy_min(1, jsy_max(0, pObj->dutycycle + pObj->pwm)); pObj->pulse_offset = 2*(dutycycle-0.5); pObj->sqr_x2 = pObj->sqr_x1 + dutycycle - 1; pObj->sqr_pol2 = pObj->sqr_pol1; diff --git a/Source/synth/env.c b/Source/synth/env.c index 0be8103..a0f945b 100644 --- a/Source/synth/env.c +++ b/Source/synth/env.c @@ -102,13 +102,13 @@ void ENV_Param2Set(envgen_t *pObj, UINT32 type, synth_float_t value) switch(type) { case ENV_PARAM2_A: - pObj->param.Ta = max(ENV_MIN_A, value); + pObj->param.Ta = jsy_max(ENV_MIN_A, value); pObj->a_a = 1.f/(pObj->param.Ta*pObj->fs); pObj->b_a = 1.f - pObj->a_a; break; case ENV_PARAM2_D: - pObj->param.Td = max(ENV_MIN_D, value); + pObj->param.Td = jsy_max(ENV_MIN_D, value); pObj->a_d = 5.f/(pObj->param.Td*pObj->fs); pObj->b_d = 1.f - pObj->a_d; @@ -119,7 +119,7 @@ void ENV_Param2Set(envgen_t *pObj, UINT32 type, synth_float_t value) break; case ENV_PARAM2_R: - pObj->param.Tr = max(ENV_MIN_R, value); + pObj->param.Tr = jsy_max(ENV_MIN_R, value); pObj->a_r = 5.f/(pObj->param.Tr*pObj->fs); pObj->b_r = 1.f - pObj->a_r; break; diff --git a/Source/synth/param_scale.c b/Source/synth/param_scale.c index f6e0478..f74bc49 100644 --- a/Source/synth/param_scale.c +++ b/Source/synth/param_scale.c @@ -736,7 +736,7 @@ synth_float_t quantizeParam(param_info_t *pObj, synth_float_t p) synth_float_t clampParam(param_info_t *pObj, synth_float_t p) { - return (synth_float_t)min(pObj->pmax, max(pObj->pmin, quantizeParam(pObj, p))); + return (synth_float_t)jsy_min(pObj->pmax, jsy_max(pObj->pmin, quantizeParam(pObj, p))); } synth_float_t toParam(param_info_t *pObj, synth_float_t s) @@ -758,7 +758,7 @@ synth_float_t toParam(param_info_t *pObj, synth_float_t s) if ((pcenter < pmin) || (pcenter > pmax)) pcenter = pmax*scenter + pmin*(1-scenter); - s = (synth_float_t)min(1, max(0, s)); + s = (synth_float_t)jsy_min(1, jsy_max(0, s)); if (s < scenter) { if (base == 1) diff --git a/Source/synth/sine.c b/Source/synth/sine.c index afb0586..e6861a1 100644 --- a/Source/synth/sine.c +++ b/Source/synth/sine.c @@ -34,8 +34,8 @@ void Sine_SetFS(sine_gen_t *pObj, synth_float_t fs) void Sine_Reset(sine_gen_t *pObj, synth_float_t phase) { - pObj->y[0] = cos(2*pi*phase); - pObj->y[1] = sin(2*pi*phase); + pObj->y[0] = cos(2*jsy_pi*phase); + pObj->y[1] = sin(2*jsy_pi*phase); pObj->fscale = 1; } @@ -54,7 +54,7 @@ void Sine_Update(sine_gen_t *pObj) { synth_float_t freq; freq = pObj->fscale * pObj->pitch; - pObj->b = 2.0 * sin(freq*pi / pObj->fs); + pObj->b = 2.0 * sin(freq*jsy_pi / pObj->fs); } synth_float_t Sine_Process_Scalar(sine_gen_t *pObj, synth_float_t pitch, synth_float_t CV_fm) diff --git a/Source/synth/synth_debug.c b/Source/synth/synth_debug.c index dc0ce85..93e6f59 100644 --- a/Source/synth/synth_debug.c +++ b/Source/synth/synth_debug.c @@ -1,7 +1,9 @@ // -------------------------------------------------------------- // -------------------------------------------------------------- +#ifdef WIN32 #include +#endif #include #include #include diff --git a/Source/synth/synth_defs.h b/Source/synth/synth_defs.h index 0081e6e..0118a92 100644 --- a/Source/synth/synth_defs.h +++ b/Source/synth/synth_defs.h @@ -3,6 +3,8 @@ #ifndef _SYNTH_DEFS_H_ #define _SYNTH_DEFS_H_ +#include +#include #include "synth_types.h" // -------------------------------------------------------------- @@ -43,10 +45,10 @@ #define SYNTH_MAX_BUFSIZE 8192 -#ifndef pi -#define pi 3.1415926535897932384626433832795 -#define pi_mult_2 (2*pi) -#define pi_div_2 (0.5*pi) +#ifndef jsy_pi +#define jsy_pi 3.1415926535897932384626433832795 +#define pi_mult_2 (2*jsy_pi) +#define pi_div_2 (0.5*jsy_pi) #endif #if defined(__cplusplus) @@ -57,12 +59,12 @@ void SynthDebug(const char *fmtstr, ...); } #endif -#ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) +#ifndef jsy_max +#define jsy_max(a,b) (((a) > (b)) ? (a) : (b)) #endif -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) +#ifndef jsy_min +#define jsy_min(a,b) (((a) < (b)) ? (a) : (b)) #endif diff --git a/Source/synth/synth_types.h b/Source/synth/synth_types.h index ac8043f..79a8ec8 100644 --- a/Source/synth/synth_types.h +++ b/Source/synth/synth_types.h @@ -6,7 +6,9 @@ // -------------------------------------------------------------- // Types // -------------------------------------------------------------- +#ifndef synth_float_t #define synth_float_t double +#endif #ifndef UINT32 #define UINT32 unsigned int diff --git a/Source/synth/vcf.c b/Source/synth/vcf.c index 9013dbd..855091c 100644 --- a/Source/synth/vcf.c +++ b/Source/synth/vcf.c @@ -77,8 +77,8 @@ void VCF_LUT_gen(vcf_t *pObj) { cv = (synth_float_t)i/(FILTER_TABLE_SIZE-1); omega = VCF_cv2omega(pObj, cv); - pCom->pLUT_cos[i] = cos(pi*omega); - pCom->pLUT_sin[i] = sin(pi*omega); + pCom->pLUT_cos[i] = cos(jsy_pi*omega); + pCom->pLUT_sin[i] = sin(jsy_pi*omega); } } @@ -100,10 +100,10 @@ synth_float_t VCF_LUT_get_cos(vcf_t *pObj, synth_float_t cv) synth_float_t n, nf; vcf_common_t *pCom = pObj->pCom; - n = min(1, max(0, cv))*(FILTER_TABLE_SIZE-1); + n = jsy_min(1, jsy_max(0, cv))*(FILTER_TABLE_SIZE-1); ni = (int)n; nf = n - (synth_float_t)ni; - ni_next = min(FILTER_TABLE_SIZE-1, ni+1); + ni_next = jsy_min(FILTER_TABLE_SIZE-1, ni+1); return (pCom->pLUT_cos[ni_next] - pCom->pLUT_cos[ni])*nf + pCom->pLUT_cos[ni]; } @@ -114,10 +114,10 @@ synth_float_t VCF_LUT_get_sin(vcf_t *pObj, synth_float_t cv) synth_float_t n, nf; vcf_common_t *pCom = pObj->pCom; - n = min(1, max(0, cv))*(FILTER_TABLE_SIZE-1); + n = jsy_min(1, jsy_max(0, cv))*(FILTER_TABLE_SIZE-1); ni = (int)n; nf = n - (synth_float_t)ni; - ni_next = min(FILTER_TABLE_SIZE-1, ni+1); + ni_next = jsy_min(FILTER_TABLE_SIZE-1, ni+1); return (pCom->pLUT_sin[ni_next] - pCom->pLUT_sin[ni])*nf + pCom->pLUT_sin[ni]; } @@ -172,7 +172,7 @@ void VCF_SetF(vcf_t *pObj, synth_float_t f) void VCF_SetQ(vcf_t *pObj, synth_float_t q) { - pObj->cv_q_bias = max(FILTER_Q_MIN, q); + pObj->cv_q_bias = jsy_max(FILTER_Q_MIN, q); pObj->req_filter_update = 1; } @@ -186,7 +186,7 @@ void VCF_SetType(vcf_t *pObj, UINT32 type) synth_float_t IIRCalcQp(unsigned p, unsigned N) { - return 1.0f/(synth_float_t)(2*sin(pi*(2*p-1)/(2*N))); + return 1.0f/(synth_float_t)(2*sin(jsy_pi*(2*p-1)/(2*N))); } void VCF_SetOrder(vcf_t *pObj, UINT32 order) @@ -238,14 +238,14 @@ synth_float_t VCF_omega2cv(vcf_t *pObj, synth_float_t omega) synth_float_t cv; cv = log(omega/pObj->omega_min)/(pObj->num_octaves * log(FILTER_SWEEP_BASE)); - return min(1, max(0, cv)); + return jsy_min(1, jsy_max(0, cv)); } synth_float_t VCF_cv2omega(vcf_t *pObj, synth_float_t cv) { synth_float_t omega; - omega = pObj->omega_min*pow(FILTER_SWEEP_BASE, pObj->num_octaves*min(1, max(0, cv))); + omega = pObj->omega_min*pow(FILTER_SWEEP_BASE, pObj->num_octaves*jsy_min(1, jsy_max(0, cv))); return omega; } @@ -275,7 +275,7 @@ void VCF_CalcCoeff_LPF(vcf_t *pObj, vcf_coef_t *pCoeff, synth_float_t *pCV_f, sy cv = pObj->cv_f_bias + pCV_f[n]; ks = VCF_LUT_get_sin(pObj, cv); kc = VCF_LUT_get_cos(pObj, cv); - q = min(FILTER_Q_MAX, max(FILTER_Q_MIN, pObj->cv_q_bias + FILTER_Q_MAX*pCV_q[n])); + q = jsy_min(FILTER_Q_MAX, jsy_max(FILTER_Q_MIN, pObj->cv_q_bias + FILTER_Q_MAX*pCV_q[n])); pObj->cv_q_last = q; if (pObj->order == 2) q *= q; @@ -334,7 +334,7 @@ void VCF_CalcCoeff_HPF(vcf_t *pObj, vcf_coef_t *pCoeff, synth_float_t *pCV_f, sy cv = pObj->cv_f_bias + pCV_f[n]; ks = VCF_LUT_get_sin(pObj, cv); kc = VCF_LUT_get_cos(pObj, cv); - q = min(FILTER_Q_MAX, max(FILTER_Q_MIN, pObj->cv_q_bias + FILTER_Q_MAX*pCV_q[n])); + q = jsy_min(FILTER_Q_MAX, jsy_max(FILTER_Q_MIN, pObj->cv_q_bias + FILTER_Q_MAX*pCV_q[n])); pObj->cv_q_last = q; if (pObj->order == 2) q *= q; @@ -393,7 +393,7 @@ void VCF_CalcCoeff_BPF(vcf_t *pObj, vcf_coef_t *pCoeff, synth_float_t *pCV_f, sy cv = pObj->cv_f_bias + pCV_f[n]; ks = VCF_LUT_get_sin(pObj, cv); kc = VCF_LUT_get_cos(pObj, cv); - q = min(FILTER_Q_MAX, max(FILTER_Q_MIN, pObj->cv_q_bias + FILTER_Q_MAX*pCV_q[n])); + q = jsy_min(FILTER_Q_MAX, jsy_max(FILTER_Q_MIN, pObj->cv_q_bias + FILTER_Q_MAX*pCV_q[n])); pObj->cv_q_last = q; if (pObj->order == 2) q *= q; diff --git a/Source/synth/vector_utils.c b/Source/synth/vector_utils.c index c67f916..8e11440 100644 --- a/Source/synth/vector_utils.c +++ b/Source/synth/vector_utils.c @@ -145,7 +145,7 @@ void Clamp_inplace_V(synth_float_t *pSrcDst, synth_float_t minimum, synth_float_ { while(len--) { - *(pSrcDst) = max(minimum, min(maximum, *(pSrcDst))); + *(pSrcDst) = jsy_max(minimum, jsy_min(maximum, *(pSrcDst))); pSrcDst++; } } @@ -154,7 +154,7 @@ void Clamp_V(synth_float_t *pDst, synth_float_t *pSrc, synth_float_t minimum, sy { while(len--) { - *(pDst++) = max(minimum, min(maximum, *(pSrc++))); + *(pDst++) = jsy_max(minimum, jsy_min(maximum, *(pSrc++))); } } @@ -162,7 +162,7 @@ void uMax_VS(synth_float_t *pDst, synth_float_t *pSrc1, synth_float_t src2, UINT { while(len--) { - *(pDst++) = max(fabs(*(pSrc1++)), src2); + *(pDst++) = jsy_max(fabs(*(pSrc1++)), src2); } } @@ -170,7 +170,7 @@ void uMax_VV(synth_float_t *pDst, synth_float_t *pSrc1, synth_float_t *pSrc2, UI { while(len--) { - *(pDst++) = max(fabs(*(pSrc1++)), *(pSrc2++)); + *(pDst++) = jsy_max(fabs(*(pSrc1++)), *(pSrc2++)); } } @@ -178,7 +178,7 @@ void uMin_VS(synth_float_t *pDst, synth_float_t *pSrc1, synth_float_t src2, UINT { while(len--) { - *(pDst++) = min(fabs(*(pSrc1++)), src2); + *(pDst++) = jsy_min(fabs(*(pSrc1++)), src2); } } @@ -186,6 +186,6 @@ void uMin_VV(synth_float_t *pDst, synth_float_t *pSrc1, synth_float_t *pSrc2, UI { while(len--) { - *(pDst++) = min(fabs(*(pSrc1++)), *(pSrc2++)); + *(pDst++) = jsy_min(fabs(*(pSrc1++)), *(pSrc2++)); } } diff --git a/Source/synth/voice.c b/Source/synth/voice.c index 066f61f..f0a6a94 100644 --- a/Source/synth/voice.c +++ b/Source/synth/voice.c @@ -324,7 +324,7 @@ void VoiceEvent(voice_t *pObj, UINT32 type) synth_float_t getKeyFreq(voice_t *pObj, int key) { - int index = max(0, min(NUM_FREQS-1, key)); + int index = jsy_max(0, jsy_min(NUM_FREQS-1, key)); return pObj->pCom->freqTab[index]; } @@ -349,9 +349,9 @@ void VoiceParam2Set(voice_t *pObj, UINT32 type, synth_float_t value) { case VOICE_PARAM_VOICE_PAN: if (pObj->id % 2) - pObj->param[type] = min(1, max(-1, -value/100)); + pObj->param[type] = jsy_min(1, jsy_max(-1, -value/100)); else - pObj->param[type] = min(1, max(-1, value/100)); + pObj->param[type] = jsy_min(1, jsy_max(-1, value/100)); break; case VOICE_PARAM_PORTAMENTO_TIME: @@ -1222,7 +1222,7 @@ void VoiceProcessDataV(voice_t *pObj, float *pOut1, float *pOut2, UINT32 len) } // Amplifier envelope and voice panning - env_gain = 0.25f*max(0, min(1, pObj->param[VOICE_PARAM_VCA_ENV_GAIN])); + env_gain = 0.25f*jsy_max(0, jsy_min(1, pObj->param[VOICE_PARAM_VCA_ENV_GAIN])); // VCA AM Mul_VS(vca_am, pModSrc[(int)pObj->param[VOICE_PARAM_VCA_AM_SRC_0]], pObj->param[VOICE_PARAM_VCA_AM_AMT_0], len); @@ -1241,7 +1241,7 @@ void VoiceProcessDataV(voice_t *pObj, float *pOut1, float *pOut2, UINT32 len) for (j=0; j < (INT32)len; j++) { -// env_gain = 0.25f*max(0, min(1, pObj->param_smoothed[VOICE_PARAM_VCA_ENV_GAIN][j])); +// env_gain = 0.25f*jsy_max(0, jsy_min(1, pObj->param_smoothed[VOICE_PARAM_VCA_ENV_GAIN][j])); out = pBuf_Postvcf[j] * pBuf_ENV[VOICE_ENV_VCA][j] * env_gain * vca_am[j]; (*pOut1++) += (float)((1+pObj->param[VOICE_PARAM_VOICE_PAN])*(1+vca_pan[j])*out); (*pOut2++) += (float)((1-pObj->param[VOICE_PARAM_VOICE_PAN])*(1-vca_pan[j])*out); diff --git a/Source/synth/wavetable.c b/Source/synth/wavetable.c index b11a97a..e828737 100644 --- a/Source/synth/wavetable.c +++ b/Source/synth/wavetable.c @@ -11,6 +11,8 @@ //#define WAVE_EXPORT_FILE +extern const wt_descr_t _g_wt_descr[WT_NUM_WAVETABLES]; +#if 0 const wt_descr_t _g_wt_descr[WT_NUM_WAVETABLES] = { {8, 0, 101, 8, 69, 16, 70, 24, 71, 32, 72, 40, 73, 48, 74, 60, 75}, @@ -55,6 +57,7 @@ const wt_descr_t _g_wt_descr[WT_NUM_WAVETABLES] = {22, 0, 400, 1, 401, 4, 402, 8, 403, 11, 404, 13, 405, 17, 406, 19, 407, 22, 408, 25, 409, 29, 410, 30, 411, 34, 412, 36, 413, 39, 414, 43, 415, 48, 416, 52, 417, 53, 418, 54, 419, 59, 420, 60, 421} }; +#endif void WT_ModInit(wt_common_t *pCom) { @@ -316,7 +319,7 @@ void WT_ProcessDataV(wt_t *pObj, synth_float_t *pPitch, synth_float_t *pCV_fm, s if (pObj->startup) pObj->x = 0; - pObj->wt_index = (WT_WAVETABLE_SIZE-1)*max(0, min(1, pObj->param[WT_PARAM2_WAVETABLE_ENTRY] + pCV_pwm[i])); + pObj->wt_index = (WT_WAVETABLE_SIZE-1)*jsy_max(0, jsy_min(1, pObj->param[WT_PARAM2_WAVETABLE_ENTRY] + pCV_pwm[i])); pObj->wt_start = (UINT32)pObj->wt_index; if (pCV_fm) @@ -328,7 +331,7 @@ void WT_ProcessDataV(wt_t *pObj, synth_float_t *pPitch, synth_float_t *pCV_fm, s ni = (UINT32)(pObj->x*(WT_WAVE_SIZE)); w1 = pObj->pCom->ppWavetables[wt_table][pObj->wt_start][ni]; - w2 = pObj->pCom->ppWavetables[wt_table][min((WT_WAVETABLE_SIZE-1), pObj->wt_start+1)][ni]; + w2 = pObj->pCom->ppWavetables[wt_table][jsy_min((WT_WAVETABLE_SIZE-1), pObj->wt_start+1)][ni]; kmix = pObj->wt_index - (UINT32)pObj->wt_index; out = w1*(1-kmix) + w2*kmix; @@ -350,7 +353,7 @@ void WT_ProcessDataV(wt_t *pObj, synth_float_t *pPitch, synth_float_t *pCV_fm, s if (pObj->startup) pObj->x = 0; - pObj->wt_index = (WT_WAVETABLE_SIZE-1)*max(0, min(1, pObj->param[WT_PARAM2_WAVETABLE_ENTRY] + pCV_pwm[i])); + pObj->wt_index = (WT_WAVETABLE_SIZE-1)*jsy_max(0, jsy_min(1, pObj->param[WT_PARAM2_WAVETABLE_ENTRY] + pCV_pwm[i])); pObj->wt_start = (UINT32)pObj->wt_index; if (pCV_fm) @@ -365,7 +368,7 @@ void WT_ProcessDataV(wt_t *pObj, synth_float_t *pPitch, synth_float_t *pCV_fm, s ni_next = (ni + 1)&(WT_WAVE_SIZE-1); w1 = (pObj->pCom->ppWavetables[wt_table][pObj->wt_start][ni_next] - pObj->pCom->ppWavetables[wt_table][pObj->wt_start][ni])*nf + pObj->pCom->ppWavetables[wt_table][pObj->wt_start][ni]; - w2 = (pObj->pCom->ppWavetables[wt_table][min((WT_WAVETABLE_SIZE-1), pObj->wt_start+1)][ni_next] - pObj->pCom->ppWavetables[wt_table][min((WT_WAVETABLE_SIZE-1), pObj->wt_start+1)][ni])*nf + pObj->pCom->ppWavetables[wt_table][min((WT_WAVETABLE_SIZE-1), pObj->wt_start+1)][ni]; + w2 = (pObj->pCom->ppWavetables[wt_table][jsy_min((WT_WAVETABLE_SIZE-1), pObj->wt_start+1)][ni_next] - pObj->pCom->ppWavetables[wt_table][jsy_min((WT_WAVETABLE_SIZE-1), pObj->wt_start+1)][ni])*nf + pObj->pCom->ppWavetables[wt_table][jsy_min((WT_WAVETABLE_SIZE-1), pObj->wt_start+1)][ni]; kmix = pObj->wt_index - (UINT32)pObj->wt_index; out = w1*(1-kmix) + w2*kmix;