Filter long audio data using cascading biquad filter
You are not storing the filter states between buffers.

In this case, each filter is a 2nd order filter, which has 2 state variables (the values stored in the 2 delays implementing each filter).

So for each new frame, you are starting with state 0, introducing a glitch between frames.

You must store the resulting state for each filter, and apply it for each next frame.

Built-in Function: [Y, SF] = filter (B, A, X, SI)

 If the fourth argument SI is provided, it is taken as the initial
 state of the system and the final state is returned as SF.  The
 state vector is a column vector whose length is equal to the
 length of the longest coefficient vector minus one.  If SI is not
 supplied, the initial state vector is set to all zeros.


So for each filter, you must store the corresponding SF, and provide as SI on the next frame.