protected int clock_resample_fast(CycleCount delta_t, short buf[], int n,
			int interleave) {
		int s = 0;

		for (;;) {
			int /* cycle_count */next_sample_offset = sample_offset
					+ cycles_per_sample;
			int /* cycle_count */delta_t_sample = next_sample_offset >> FIXP_SHIFT;
			if (delta_t_sample > delta_t.delta_t) {
				break;
			}
			if (s >= n) {
				return s;
			}
			for (int i = 0; i < delta_t_sample; i++) {
				clock();
				sample[sample_index] = sample[sample_index + RINGSIZE] = (short) output();
				++sample_index;
				sample_index &= 0x3fff;
			}
			delta_t.delta_t -= delta_t_sample;
			sample_offset = next_sample_offset & FIXP_MASK;

			int fir_offset = sample_offset * fir_RES >> FIXP_SHIFT;
			int fir_start = (fir_offset * fir_N);
			int sample_start = (sample_index - fir_N + RINGSIZE);

			// Convolution with filter impulse response.
			int v = 0;
			for (int j = 0; j < fir_N; j++) {
				v += sample[sample_start + j] * fir[fir_start + j];
			}

			v >>= FIR_SHIFT;

			// Saturated arithmetics to guard against 16 bit sample overflow.
			final int half = 1 << 15;
			if (v >= half) {
				v = half - 1;
			} else if (v < -half) {
				v = -half;
			}

			buf[s++ * interleave] = (short) v;
		}

		for (int i = 0; i < delta_t.delta_t; i++) {
			clock();
			sample[sample_index] = sample[sample_index + RINGSIZE] = (short) output();
			++sample_index;
			sample_index &= 0x3fff;
		}
		sample_offset -= delta_t.delta_t << FIXP_SHIFT;
		delta_t.delta_t = 0;
		return s;
	}