with Ada.Unchecked_Conversion; with Tresses.DSP; with Tresses.Filters.SVF; use Tresses.Filters.SVF; package body Tresses.FX.Bitcrusher is ------------- -- Process -- ------------- procedure Process (This : in out Instance; Buffer : in out Mono_Buffer; Depth : Bitdepth; DS : Downsampling; Amount : Param_Range; Cutoff : Param_Range) is Down_Factor : constant U32 := U32 (DS); Shift : constant Natural := 16 - Natural (Depth); Mask : constant U16 := Shift_Left (U16'Last, Shift); function To_U16 is new Ada.Unchecked_Conversion (S16, U16); function To_S16 is new Ada.Unchecked_Conversion (U16, S16); function "and" (A : S16; B : U16) return S16 is (To_S16 (To_U16 (A) and B)); Filtered : S16; Masked : S16; begin if This.Do_Init then This.Do_Init := False; Init (This.Filter); Set_Mode (This.Filter, Low_Pass); end if; Set_Frequency (This.Filter, Cutoff); for Elt of Buffer loop -- Take one sample every X input sample if This.Sample_Count mod Down_Factor = 0 then This.Last_Sample := This.Sample; This.Sample := Elt; -- Prepare for linear interpolation This.Acc := This.Last_Sample; This.Step := S16 ((S32 (This.Sample) - S32 (This.Last_Sample)) / S32 (Down_Factor)); else -- Next sample interpolation This.Acc := This.Acc + This.Step; end if; -- Apply bit reduction mask Masked := This.Acc and Mask; -- Filter output Filtered := S16 (Process (This.Filter, S32 (Masked))); -- Wet/Dry mix Elt := DSP.Mix (Elt, Filtered, Amount); This.Sample_Count := This.Sample_Count + 1; end loop; end Process; end Tresses.FX.Bitcrusher;