2 |
* * |
* * |
3 |
* LinuxSampler - modular, streaming capable sampler * |
* LinuxSampler - modular, streaming capable sampler * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003 by Benno Senoner and Christian Schoenebeck * |
* Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * |
6 |
* * |
* * |
7 |
* This program is free software; you can redistribute it and/or modify * |
* This program is free software; you can redistribute it and/or modify * |
8 |
* it under the terms of the GNU General Public License as published by * |
* it under the terms of the GNU General Public License as published by * |
31 |
|
|
32 |
const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff()); |
const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff()); |
33 |
|
|
34 |
|
const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask()); |
35 |
|
|
36 |
float Voice::CalculateFilterCutoffCoeff() { |
float Voice::CalculateFilterCutoffCoeff() { |
37 |
return log(FILTER_CUTOFF_MIN / FILTER_CUTOFF_MAX); |
return log(FILTER_CUTOFF_MIN / FILTER_CUTOFF_MAX); |
38 |
} |
} |
39 |
|
|
40 |
|
int Voice::CalculateFilterUpdateMask() { |
41 |
|
if (FILTER_UPDATE_PERIOD <= 0) return 0; |
42 |
|
int power_of_two; |
43 |
|
for (power_of_two = 0; 1<<power_of_two < FILTER_UPDATE_PERIOD; power_of_two++); |
44 |
|
return (1 << power_of_two) - 1; |
45 |
|
} |
46 |
|
|
47 |
Voice::Voice() { |
Voice::Voice() { |
48 |
pEngine = NULL; |
pEngine = NULL; |
49 |
pDiskThread = NULL; |
pDiskThread = NULL; |
104 |
pLFO3 = new LFO<gig::VCOManipulator>(-1200.0f, 1200.0f, LFO<VCOManipulator>::propagation_middle_balanced, pVCOManipulator, pEngine->pEventPool); // +-1 octave (+-1200 cents) max. |
pLFO3 = new LFO<gig::VCOManipulator>(-1200.0f, 1200.0f, LFO<VCOManipulator>::propagation_middle_balanced, pVCOManipulator, pEngine->pEventPool); // +-1 octave (+-1200 cents) max. |
105 |
|
|
106 |
this->pDiskThread = pEngine->pDiskThread; |
this->pDiskThread = pEngine->pDiskThread; |
107 |
dmsg(1,("Voice::SetEngine()\n")); |
dmsg(6,("Voice::SetEngine()\n")); |
108 |
} |
} |
109 |
|
|
110 |
/** |
/** |
352 |
pDimRgn->LFO2ControlDepth, |
pDimRgn->LFO2ControlDepth, |
353 |
pEngine->ControllerTable[pLFO2->ExtController], |
pEngine->ControllerTable[pLFO2->ExtController], |
354 |
pDimRgn->LFO2FlipPhase, |
pDimRgn->LFO2FlipPhase, |
355 |
|
this->SampleRate, |
356 |
Delay); |
Delay); |
357 |
} |
} |
358 |
#endif // ENABLE_FILTER |
#endif // ENABLE_FILTER |
545 |
pLFO3->Process(Samples); |
pLFO3->Process(Samples); |
546 |
|
|
547 |
|
|
548 |
|
#if ENABLE_FILTER |
549 |
|
CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters |
550 |
|
#endif // ENABLE_FILTER |
551 |
|
|
552 |
|
|
553 |
switch (this->PlaybackState) { |
switch (this->PlaybackState) { |
554 |
|
|
555 |
case playback_state_ram: { |
case playback_state_ram: { |
763 |
#endif // ENABLE_FILTER |
#endif // ENABLE_FILTER |
764 |
} |
} |
765 |
|
|
766 |
|
#if ENABLE_FILTER |
767 |
|
/** |
768 |
|
* Calculate all necessary, final biquad filter parameters. |
769 |
|
* |
770 |
|
* @param Samples - number of samples to be rendered in this audio fragment cycle |
771 |
|
*/ |
772 |
|
void Voice::CalculateBiquadParameters(uint Samples) { |
773 |
|
if (!FilterLeft.Enabled) return; |
774 |
|
|
775 |
|
biquad_param_t bqbase; |
776 |
|
biquad_param_t bqmain; |
777 |
|
float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0]; |
778 |
|
float prev_res = pEngine->pSynthesisParameters[Event::destination_vcfr][0]; |
779 |
|
FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, SampleRate); |
780 |
|
pEngine->pBasicFilterParameters[0] = bqbase; |
781 |
|
pEngine->pMainFilterParameters[0] = bqmain; |
782 |
|
|
783 |
|
float* bq; |
784 |
|
for (int i = 1; i < Samples; i++) { |
785 |
|
// recalculate biquad parameters if cutoff or resonance differ from previous sample point |
786 |
|
if (!(i & FILTER_UPDATE_MASK)) if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res || |
787 |
|
pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff) { |
788 |
|
prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i]; |
789 |
|
prev_res = pEngine->pSynthesisParameters[Event::destination_vcfr][i]; |
790 |
|
FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, SampleRate); |
791 |
|
} |
792 |
|
|
793 |
|
//same as 'pEngine->pBasicFilterParameters[i] = bqbase;' |
794 |
|
bq = (float*) &pEngine->pBasicFilterParameters[i]; |
795 |
|
bq[0] = bqbase.a1; |
796 |
|
bq[1] = bqbase.a2; |
797 |
|
bq[2] = bqbase.b0; |
798 |
|
bq[3] = bqbase.b1; |
799 |
|
bq[4] = bqbase.b2; |
800 |
|
|
801 |
|
// same as 'pEngine->pMainFilterParameters[i] = bqmain;' |
802 |
|
bq = (float*) &pEngine->pMainFilterParameters[i]; |
803 |
|
bq[0] = bqmain.a1; |
804 |
|
bq[1] = bqmain.a2; |
805 |
|
bq[2] = bqmain.b0; |
806 |
|
bq[3] = bqmain.b1; |
807 |
|
bq[4] = bqmain.b2; |
808 |
|
} |
809 |
|
} |
810 |
|
#endif // ENABLE_FILTER |
811 |
|
|
812 |
/** |
/** |
813 |
* Interpolates the input audio data (no loop). |
* Interpolates the input audio data (no loop). |
814 |
* |
* |
826 |
InterpolateOneStep_Stereo(pSrc, i, |
InterpolateOneStep_Stereo(pSrc, i, |
827 |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
828 |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
829 |
pEngine->pSynthesisParameters[Event::destination_vcfc][i], |
pEngine->pBasicFilterParameters[i], |
830 |
pEngine->pSynthesisParameters[Event::destination_vcfr][i]); |
pEngine->pMainFilterParameters[i]); |
831 |
} |
} |
832 |
} |
} |
833 |
else { // Mono Sample |
else { // Mono Sample |
835 |
InterpolateOneStep_Mono(pSrc, i, |
InterpolateOneStep_Mono(pSrc, i, |
836 |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
837 |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
838 |
pEngine->pSynthesisParameters[Event::destination_vcfc][i], |
pEngine->pBasicFilterParameters[i], |
839 |
pEngine->pSynthesisParameters[Event::destination_vcfr][i]); |
pEngine->pMainFilterParameters[i]); |
840 |
} |
} |
841 |
} |
} |
842 |
} |
} |
860 |
InterpolateOneStep_Stereo(pSrc, i, |
InterpolateOneStep_Stereo(pSrc, i, |
861 |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
862 |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
863 |
pEngine->pSynthesisParameters[Event::destination_vcfc][i], |
pEngine->pBasicFilterParameters[i], |
864 |
pEngine->pSynthesisParameters[Event::destination_vcfr][i]); |
pEngine->pMainFilterParameters[i]); |
865 |
if (Pos > pSample->LoopEnd) { |
if (Pos > pSample->LoopEnd) { |
866 |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
867 |
LoopCyclesLeft--; |
LoopCyclesLeft--; |
872 |
InterpolateOneStep_Stereo(pSrc, i, |
InterpolateOneStep_Stereo(pSrc, i, |
873 |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
874 |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
875 |
pEngine->pSynthesisParameters[Event::destination_vcfc][i], |
pEngine->pBasicFilterParameters[i], |
876 |
pEngine->pSynthesisParameters[Event::destination_vcfr][i]); |
pEngine->pMainFilterParameters[i]); |
877 |
} |
} |
878 |
} |
} |
879 |
else { // render loop (endless loop) |
else { // render loop (endless loop) |
881 |
InterpolateOneStep_Stereo(pSrc, i, |
InterpolateOneStep_Stereo(pSrc, i, |
882 |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
883 |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
884 |
pEngine->pSynthesisParameters[Event::destination_vcfc][i], |
pEngine->pBasicFilterParameters[i], |
885 |
pEngine->pSynthesisParameters[Event::destination_vcfr][i]); |
pEngine->pMainFilterParameters[i]); |
886 |
if (Pos > pSample->LoopEnd) { |
if (Pos > pSample->LoopEnd) { |
887 |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize); |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize); |
888 |
} |
} |
896 |
InterpolateOneStep_Mono(pSrc, i, |
InterpolateOneStep_Mono(pSrc, i, |
897 |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
898 |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
899 |
pEngine->pSynthesisParameters[Event::destination_vcfc][i], |
pEngine->pBasicFilterParameters[i], |
900 |
pEngine->pSynthesisParameters[Event::destination_vcfr][i]); |
pEngine->pMainFilterParameters[i]); |
901 |
if (Pos > pSample->LoopEnd) { |
if (Pos > pSample->LoopEnd) { |
902 |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
903 |
LoopCyclesLeft--; |
LoopCyclesLeft--; |
908 |
InterpolateOneStep_Mono(pSrc, i, |
InterpolateOneStep_Mono(pSrc, i, |
909 |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
910 |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
911 |
pEngine->pSynthesisParameters[Event::destination_vcfc][i], |
pEngine->pBasicFilterParameters[i], |
912 |
pEngine->pSynthesisParameters[Event::destination_vcfr][i]); |
pEngine->pMainFilterParameters[i]); |
913 |
} |
} |
914 |
} |
} |
915 |
else { // render loop (endless loop) |
else { // render loop (endless loop) |
917 |
InterpolateOneStep_Mono(pSrc, i, |
InterpolateOneStep_Mono(pSrc, i, |
918 |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
pEngine->pSynthesisParameters[Event::destination_vca][i], |
919 |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
pEngine->pSynthesisParameters[Event::destination_vco][i], |
920 |
pEngine->pSynthesisParameters[Event::destination_vcfc][i], |
pEngine->pBasicFilterParameters[i], |
921 |
pEngine->pSynthesisParameters[Event::destination_vcfr][i]); |
pEngine->pMainFilterParameters[i]); |
922 |
if (Pos > pSample->LoopEnd) { |
if (Pos > pSample->LoopEnd) { |
923 |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
924 |
} |
} |