I’m by no means an expert, and haven’t used them outside of software like Labview and Matlab which does most of the heavy-lifting behind the scenes. Also, like @Apenz1 said, I doubt you’d need to use a proper Fuzzy controller to produce something like this when you can simply “hard-code” it using ratios of rpm range and limits.
To give a brief explanation, you were along the right lines with “uses a range of values”. Fuzzy logic takes a ‘boolean’ type comparison (e.g. Hot, or Warm, or Cold) and converts it to a ratio-type comparison (e.g. 60% Cold, 40% Warm) which can be more representative of the actual thing you’re trying to represent. To use the same example:
You can then apply ‘generic’ rules, such as:
- If “Hot”, turn on A/C, turn off Heating
- If “Warm”, turn off A/C, turn off Heating
- If “Cold”, turn off A/C, turn on Heating
Then after the logic determines the ratios, it might then (based on our previous example), turn off the A/C and turn the Heating on to ~40% (as a guess).
From my understanding, it’s basically a means of producing a representative output based on a set of varying inputs. In your example, they’re (presumably) taking inputs of RPM and load, and using rules such as: "If RPM < 2000 AND load < 10000, Play ‘Idle’ "
Once the Fuzzy logic takes into account the weightings of all of the rules, it will produce variables that can then be applied to pitch/volume of each audio.
I’m not sure if there are any open-source lua libraries that you could utilise, and either way I’d probably just recommend considering each audio file and writing your own methods for each individually, such as:
local function getRatio(value, min, max)
value = math.clamp(value, min, max); -- Clamps the value so you don't accidentally get ratios <0 or >1
return (value - min) / (max - min);
end
local rpm = 1250; -- Example value within the range
local IdleStartPitch = 0.7; -- "minimum" pitch of the Idle sound
local MaximumIdleSoundIncrease = 0.2; -- "maximum" amount of pitch increase for the Idle sound
if (rpm > 500 and rpm < 2000) then
local ratio = getRatio(rpm, 500, 2000) -- Returns 0.5 (as 1250 is half-way between 500 and 2000)
IdleSound.Pitch = IdleStartPitch +(MaximumIdleSoundIncrease *ratio); -- Gradually increases pitch as rpm increases up to 2000
end