<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def read_blocks(file_path, start=0.0, end=float('inf'), buffer_size=5760000):
 """ Read an audio file block after block. The blocks are yielded one by one. Args: file_path (str):
 Path to the file to read. start (float):
 Start in seconds to read from. end (float):
 End in seconds to read to. ``inf`` means to the end of the file. buffer_size (int):
 Number of samples to load into memory at once and return as a single block. The exact number of loaded samples depends on the block-size of the audioread library. So it can be of x higher, where the x is typically 1024 or 4096. Returns: Generator: A generator yielding the samples for every block. """

    buffer = []
    n_buffer = 0
    n_samples = 0

    with audioread.audio_open(file_path) as input_file:
        n_channels = input_file.channels
        sr_native = input_file.samplerate

        start_sample = int(np.round(sr_native * start)) * n_channels
        end_sample = end

        if end_sample != np.inf:
            end_sample = int(np.round(sr_native * end)) * n_channels

        for block in input_file:
            block = librosa.util.buf_to_float(block)
            n_prev = n_samples
            n_samples += len(block)

            if n_samples < start_sample:
                continue

            if n_prev > end_sample:
                break

            if n_samples > end_sample:
                block = block[:end_sample - n_prev]

            if n_prev <= start_sample <= n_samples:
                block = block[start_sample - n_prev:]

            n_buffer += len(block)
            buffer.append(block)

            if n_buffer >= buffer_size:
                yield process_buffer(buffer, n_channels)

                buffer = []
                n_buffer = 0

        if len(buffer) > 0:
            yield process_buffer(buffer, n_channels)