public static void sample_start(int channel, int samplenum, int loop) {
        if (Machine.sample_rate == 0) {
            return;
        }
        if (Machine.samples == null) {
            return;
        }
        if (Machine.samples.sample[samplenum] == null) {
            return;
        }
        if (channel >= numchannels) {
            if (errorlog != null) {
                fprintf(errorlog, "error: sample_start() called with channel = %d, but only %d channels allocated\n", channel, numchannels);
            }
            return;
        }
        if (samplenum >= Machine.samples.total) {
            if (errorlog != null) {
                fprintf(errorlog, "error: sample_start() called with samplenum = %d, but only %d samples available\n", samplenum, Machine.samples.total);
            }
            return;
        }

        if (Machine.samples.sample[samplenum].resolution == 8) {
            if (errorlog != null) {
                fprintf(errorlog, "play 8 bit sample %d, channel %d\n", samplenum, channel);
            }
            mixer_play_sample(firstchannel + channel,
                    new BytePtr(Machine.samples.sample[samplenum].data),
                    Machine.samples.sample[samplenum].length,
                    Machine.samples.sample[samplenum].smpfreq,
                    loop != 0);
        } else {
            if (errorlog != null) {
                fprintf(errorlog, "play 16 bit sample %d, channel %d\n", samplenum, channel);
            }
            mixer_play_sample_16(firstchannel + channel,
                    new ShortPtr(Machine.samples.sample[samplenum].data),
                    Machine.samples.sample[samplenum].length,
                    Machine.samples.sample[samplenum].smpfreq,
                    loop != 0);
        }
    }