def scaling_round(val, factor=16, max_value=0):
    """
    Round the given value to the nearest multiple of `factor`.

    If the optional `max_value` is given, the nearest multiple
    not above that `max_value` is returned.

    :param val: The value to round.
    :param factor: Rounding multiple.
    :param max_value: Maximum return value.
    :return: Rounded int
    :rtype: int
    """
    vsc = int(val / factor)
    vmin = vsc * factor
    vmax = (vsc + 1) * factor
    if (max_value and vmax > max_value) or abs(val - vmin) < abs(val - vmax):
        return vmin
    return vmax