Visualizer Thing

This is just a proof of concept, nothing fancy or good here


local render = render;
local Lerp = Lerp;
local math = math;
local cam = cam;
local HSVToColor = HSVToColor;
local unpack = unpack;
local map = game.GetMap();

local vis_rainbow = CreateClientConVar("vis_rainbow", "0");
local vis_rainbow_speed_scale = CreateClientConVar("vis_rainbow_speed_scale", "1");
local vis_rainbow_use_volume = CreateClientConVar("vis_rainbow_use_volume", "1");
local vis_bars = CreateClientConVar("vis_bars", "128");
local vis_height = CreateClientConVar("vis_height", "160");
local vis_style = CreateClientConVar("vis_style", "0");
local vis_rainbow_direction = CreateClientConVar("vis_rainbow_direction", "0");
local vis_rainbow_style = CreateClientConVar("vis_rainbow_style", "0");

local tbPos = {
	["gm_flatgrass"] = Vector(161.235580, 41.361214, -12287),
};

local function GetAverage(...)
	local args = {...};
	local ret = 0;

	for k,v in next, args do
		ret = ret + v;
	end

	return (ret / #args);
end

local flVisHeight = vis_height:GetFloat();

local function CalculateColor(valLerped)
	local g = math.abs(((valLerped / flVisHeight) * 255) - 255);
	local r = (valLerped / flVisHeight) * 255;

	return r, g, 0;
end

local function GetAudioLevelScale(level_left, level_right)
	return (level_left + level_right) / 2;
end

local function GetScale()
	return (128 / vis_bars:GetInt());
end

local function GetScaleFloor()
	return math.floor(128 / vis_bars:GetInt());
end

local function LerpAmount(flScale, flFrom, flTo, min, max)
	local lerped = Lerp(flScale, flFrom || 0, flTo || 0);
	return math.Clamp(lerped, min || 0, max || 160);
end

local function GetMins()
	return Vector(-2, -2, 0) * GetScale();
end

local function GetMaxs(z)
	return (Vector(2, 2, 0) * GetScale()) + Vector(0, 0, z);
end

local function GetOrigin()
	return (tbPos[map] || Vector());
end

local _FrameTime = FrameTime;

local function FrameTime()
	return _FrameTime() / 2; // changing from renderscreenspaceffects broke this somehow
end

function DoVisualizer(snd)
	RunConsoleCommand("stopsound");

	sound.PlayFile(snd, "", function(chan)

		if(IsValid(chan)) then
			local tbLerped = {};
			local fft = {};
			local flStartTime = SysTime();
			chan:Play();

			hook.Add("PostDrawTranslucentRenderables", "DrawingShit", function()
				vis_bars:SetInt(math.Clamp(vis_bars:GetInt(), 1, 128));
				local boxes = {};
				local mins = GetMins();
				local origin = GetOrigin();
				local scale = GetScale();
				local scalefloor = GetScaleFloor();
				local style = vis_style:GetInt();
				local dir = vis_rainbow_direction:GetBool();
				flVisHeight = vis_height:GetFloat();

				if(!IsValid(chan) || chan:GetState() == GMOD_CHANNEL_STOPPED) then
					hook.Remove("PostDrawTranslucentRenderables", "DrawingShit");
					return;
				end

				chan:FFT(fft, FFT_256);

				local _all = 0;

				if(vis_rainbow_style:GetBool()) then
					for i = 1, 10 do
						_all = _all + fft*;
					end
					_all = _all / 2;
				else
					_all = GetAudioLevelScale(chan:GetLevel());
				end

				flStartTime = flStartTime + FrameTime() * (vis_rainbow_use_volume:GetBool() && _all || 1) * (150 * vis_rainbow_speed_scale:GetFloat());

				for i = 1, 128 - 18, scale do
					local vals = {};

					for _i = 1, scalefloor do
						vals[#vals + 1] = fft[i + (_i - 1)] || 0; // just in case
					end

					boxes[#boxes + 1] = GetAverage(unpack(vals));
				end

				render.SetColorMaterial();

				for k,v in next, boxes do
					tbLerped[k] = LerpAmount(FrameTime() * 18, tbLerped[k], (v || 0) * 3000 * (flVisHeight / 160), 0, flVisHeight);

					local col = (!vis_rainbow:GetBool()) && Color(CalculateColor(tbLerped[k])) || HSVToColor((flStartTime + ((k * scale * 4) * (dir && -1 || 1))) % 360, 1, .85);
					local maxs = GetMaxs(tbLerped[k]);

					if(style < 3) then
						render.DrawBox(origin + Vector(5 * scale, 0, 0) * k, Angle(0, 0, 0), mins, maxs, col, false);

						if(style == 0) then
							render.DrawBox(origin - Vector(5 * scale, 0, 0) * (k - 1), Angle(0, 0, 0), mins, maxs, col, false);
						elseif(style == 1) then
							local maxs = GetMaxs(tbLerped[k] / 2);
							render.DrawBox(origin + Vector(5 * scale, 0, 0) * k + Vector(0, 0, flVisHeight), Angle(180, 0, 0), mins, maxs, col, false);
						elseif(style == 2) then
							render.DrawBox(origin + Vector(5 * scale, 0, 0) * (-(k - 1) + #boxes) + Vector(0, 0, flVisHeight), Angle(180, 0, 0), mins, maxs, col, false);
						end
					elseif(style == 3) then
						render.DrawBox(origin - Vector(5 * scale, 0, 0) * (#boxes - k), Angle(0, 0, 0), mins, maxs, col, false);
						render.DrawBox(origin + Vector(5 * scale, 0, 0) * (#boxes - k), Angle(0, 0, 0), mins, maxs, col, false);
					elseif(style == 4) then
						local val = maxs.z;
						maxs.z = 0;
						maxs = maxs * 2;
						maxs.z = val / 2;
						render.DrawBox(origin + Vector(10 * scale, 0, 0) * (-#boxes / 2 + k) + Vector(0, 0, flVisHeight / 2), Angle(180, 0, 0), mins * 2, maxs, col, false);
						render.DrawBox(origin + Vector(10 * scale, 0, 0) * (-#boxes / 2 + k) + Vector(0, 0, flVisHeight / 2), Angle(0, 0, 0), mins * 2, maxs, col, false);
					elseif(style == 5) then
						local val = maxs.z;
						maxs.z = 0;
						maxs = maxs * 2;
						maxs.z = val / 2;
						render.DrawBox(origin + Vector(10 * scale, 0, 0) * (#boxes / 2 - k) + Vector(0, 0, flVisHeight / 2), Angle(180, 0, 0), mins * 2, maxs, col, false);
						render.DrawBox(origin + Vector(10 * scale, 0, 0) * (#boxes / 2 - k) + Vector(0, 0, flVisHeight / 2), Angle(0, 0, 0), mins * 2, maxs, col, false);
					elseif(style == 6) then
						local maxs = GetMaxs(tbLerped[k] / 2);

						render.DrawBox(origin + Vector(5 * scale, 0, 0) * (k) + Vector(0, 0, flVisHeight / 2), Angle(180, 0, 0), mins, maxs, col, false);
						render.DrawBox(origin + Vector(5 * scale, 0, 0) * (k) + Vector(0, 0, flVisHeight / 2), Angle(0, 0, 0), mins, maxs, col, false);

						render.DrawBox(origin + Vector(5 * scale, 0, 0) * (-k + 1) + Vector(0, 0, flVisHeight / 2), Angle(180, 0, 0), mins, maxs, col, false);
						render.DrawBox(origin + Vector(5 * scale, 0, 0) * (-k + 1) + Vector(0, 0, flVisHeight / 2), Angle(0, 0, 0), mins, maxs, col, false);
					end
				end
			end);

		end
	end);
end

DoVisualizer("sound/test33.mp3");

EDIT:

Cleaned up code and added new stuff

EDIT2:

Added different styles

EDIT3:

Changed rendering hook

[video]https://youtu.be/rBRy2iB1_mg[/video]

[video]https://youtu.be/ZhkSTLiKMOk[/video]

I love FFT!

This is cool as fuck.

nice work

good shit man

Cool stuff dude

Wow this looks cool

liar

no lie