static void generate_adpcm(ADPCMVoice voice, ShortPtr buffer, int samples) {
        /* if this voice is active */
        if (voice.playing != 0) {
            UBytePtr _base = voice._base;
            int sample = (int) voice.sample;
            int signal = (int) voice.signal;
            int count = (int) voice.count;
            int step = (int) voice.step;
            int val;
            /* loop while we still have samples to generate */
            while (samples != 0) {
                /* compute the new amplitude and update the current step */
                val = _base.read(sample / 2) >> (((sample & 1) << 2) ^ 4);
                signal += diff_lookup[step * 16 + (val & 15)];

                /* clamp to the maximum */
                if (signal > 2047) {
                    signal = 2047;
                } else if (signal < -2048) {
                    signal = -2048;
                }

                /* adjust the step size and clamp */
                step += index_shift[val & 7];
                if (step > 48) {
                    step = 48;
                } else if (step < 0) {
                    step = 0;
                }
                /* output to the buffer, scaling by the volume */
                buffer.write(0, (short) (signal * voice.volume / 16));
                buffer.offset += 2;
                samples--;

                /* next! */
                if (++sample > count) {
                    voice.playing = 0;
                    break;
                }
            }
            /* update the parameters */
            voice.sample = sample;
            voice.signal = signal;
            voice.step = step;
        }

        /* fill the rest with silence */
        while (samples-- != 0) {
            buffer.write(0, (short) 0);
            buffer.offset += 2;
        }
    }