void FM4Op_keyOff(FM4OP *p) { ADSR_keyOff(&p->adsr[0]); ADSR_keyOff(&p->adsr[1]); ADSR_keyOff(&p->adsr[2]); ADSR_keyOff(&p->adsr[3]); }
void sequencer_newStep_action(void) // User callback function called by sequencer_process() { if ((noteG.automaticON || noteG.chRequested)) { seq_sequence_new(); noteG.chRequested = false; AdditiveGen_newWaveform(); } if ( (noteG.someNotesMuted) && (rintf(frand_a_b(0.4f , 1)) == 0) ) ADSR_keyOff(&adsr); else ADSR_keyOn(&adsr); if (autoFilterON) SVF_directSetFilterValue(&SVFilter, Ts * 600.f * powf(5000.f / 600.f, frand_a_b(0 , 1))); if (noteG.transpose != 0) { noteG.rootNote += noteG.transpose ; seq_transpose(); } if (autoSound == 1) { switch(rand() % 4) // 4 random timbers { case 0 : sound = CHORD15; break; case 1 : AdditiveGen_newWaveform(); sound = ADDITIVE; break; case 2 : sound = CHORD13min5; break; case 3 : sound = VOICES3; break; } } if (autoSound == 2) { sound = rand() % LAST_SOUND; if ((sound == CHORD13min5) || (sound == CHORD135)) sound = VOICES3; if ( sound == ADDITIVE) AdditiveGen_newWaveform(); } f0 = notesFreq[seq.track1.note[seq.step_idx]]; // Main "melody" frequency vol = frand_a_b(0.4f , .8f); // slightly random volume for each note }
void make_sound(uint16_t *buf , uint16_t length) // To be used with the Sequencer { uint16_t pos; uint16_t *outp; float y = 0; float yL, yR ; float f1; uint16_t valueL, valueR; outp = buf; for (pos = 0; pos < length; pos++) { /*--- Sequencer actions and update ---*/ sequencer_process(); //computes f0 and calls sequencer_newStep_action() and sequencer_newSequence_action() /*--- compute vibrato modulation ---*/ f1 = f0 * (1 + Osc_WT_SINE_SampleCompute(&vibr_lfo)); /*--- Generate waveform ---*/ y = waveCompute(sound, f1); /*--- Apply envelop and tremolo ---*/ env = ADSR_computeSample(&adsr) * (1 + Osc_WT_SINE_SampleCompute(&_lfo)); y *= vol * env; // apply volume and envelop if (adsr.cnt_ >= seq.gateTime) ADSR_keyOff(&adsr); /*--- Apply filter effect ---*/ /* Update the filters cutoff frequencies */ if ((! autoFilterON)&&(filt_lfo.amp != 0)) SVF_directSetFilterValue(&SVFilter, filterFreq * (1 + OpSampleCompute7bis(&filt_lfo))); if (filt2_lfo.amp != 0) SVF_directSetFilterValue(&SVFilter2, filterFreq2 * (1 + OpSampleCompute7bis(&filt2_lfo))); y = 0.5f * (SVF_calcSample(&SVFilter, y) + SVF_calcSample(&SVFilter2, y)); // Two filters in parallel /*--- Apply delay effect ----*/ if (delayON) y = Delay_compute(y); /*--- Apply phaser effect ----*/ if (phaserON) y = Phaser_compute(y); /*--- Apply chorus/flanger effect ---*/ if (chorusON) stereoChorus_compute (&yL, &yR, y) ; else yL = yR = y; /*--- clipping ---*/ yL = (yL > 1.0f) ? 1.0f : yL; //clip too loud left samples yL = (yL < -1.0f) ? -1.0f : yL; yR = (yR > 1.0f) ? 1.0f : yR; //clip too loud right samples yR = (yR < -1.0f) ? -1.0f : yR; /****** let's hear the new sample *******/ valueL = (uint16_t)((int16_t)((32767.0f) * yL)); // conversion float -> int valueR = (uint16_t)((int16_t)((32767.0f) * yR)); *outp++ = valueL; // left channel sample *outp++ = valueR; // right channel sample } }
int brass(CSOUND *csound, BRASS *p) { MYFLT *ar = p->ar; uint32_t offset = p->h.insdshead->ksmps_offset; uint32_t early = p->h.insdshead->ksmps_no_end; uint32_t n, nsmps = CS_KSMPS; MYFLT amp = (*p->amp)*AMP_RSCALE; /* Normalise */ MYFLT maxPressure = p->maxPressure = amp; int v_len = (int)p->vibr->flen; MYFLT *v_data = p->vibr->ftable; MYFLT vibGain = *p->vibAmt; MYFLT vTime = p->v_time; p->v_rate = *p->vibFreq * v_len * csound->onedsr; /* vibr->setFreq(6.137); */ /* vibrGain = 0.05; */ /* breath periodic vibrato component */ if (p->kloop>0 && p->h.insdshead->relesing) p->kloop=1; if ((--p->kloop) == 0) { ADSR_setReleaseRate(csound, &p->adsr, amp * FL(0.005)); ADSR_keyOff(&p->adsr); } if (p->frq != *p->frequency) { /* Set frequency if changed */ p->frq = *p->frequency; if (p->limit > p->frq) { p->frq =p->limit; csound->Warning(csound, Str("frequency too low, set to minimum")); } p->slideTarget = (CS_ESR / p->frq * FL(2.0)) + FL(3.0); /* fudge correction for filter delays */ /* we'll play a harmonic */ if (DLineA_setDelay(csound, &p->delayLine, p->slideTarget)) return OK; p->lipTarget = p->frq; p->lipT = FL(0.0); /* So other part is set */ } /* End of set frequency */ if (*p->liptension != p->lipT) { p->lipT = *p->liptension; LipFilt_setFreq(csound, &p->lipFilter, p->lipTarget * (MYFLT)pow(4.0,(2.0* p->lipT) -1.0)); } if (UNLIKELY(offset)) memset(ar, '\0', offset*sizeof(MYFLT)); if (UNLIKELY(early)) { nsmps -= early; memset(&ar[nsmps], '\0', early*sizeof(MYFLT)); } for (n=offset;n<nsmps;n++) { MYFLT breathPressure; MYFLT lastOutput; int temp; MYFLT temp_time, alpha; MYFLT v_lastOutput; MYFLT ans; breathPressure = maxPressure * ADSR_tick(&p->adsr); /* Tick on vibrato table */ vTime += p->v_rate; /* Update current time */ while (vTime >= v_len) /* Check for end of sound */ vTime -= v_len; /* loop back to beginning */ while (vTime < FL(0.0)) /* Check for end of sound */ vTime += v_len; /* loop back to beginning */ temp_time = vTime; #ifdef phase_offset if (p->v_phaseOffset != FL(0.0)) { temp_time += p->v_phaseOffset; /* Add phase offset */ while (temp_time >= v_len) /* Check for end of sound */ temp_time -= v_len; /* loop back to beginning */ while (temp_time < FL(0.0)) /* Check for end of sound */ temp_time += v_len; /* loop back to beginning */ } #endif temp = (int) temp_time; /* Integer part of time address */ /* fractional part of time address */ alpha = temp_time - (MYFLT)temp; v_lastOutput = v_data[temp]; /* Do linear interpolation, same as */ v_lastOutput += /*alpha*data[temp+1]+(1-alpha)data[temp] */ (alpha * (v_data[temp+1] - v_lastOutput)); /* End of vibrato tick */ breathPressure += vibGain * v_lastOutput; lastOutput = DLineA_tick(&p->delayLine, /* bore delay */ DCBlock_tick(&p->dcBlock, /* block DC */ LipFilt_tick(&p->lipFilter, FL(0.3) * breathPressure, /* mouth input */ /* and bore reflection */ FL(0.85) * p->delayLine.lastOutput))); ans = lastOutput*AMP_SCALE*FL(3.5); ar[n] = ans; } p->v_time = vTime; return OK; }