made looping sample-perfect

This commit is contained in:
DaniTheSkunk 2022-10-15 05:40:21 +00:00
parent de325c72b5
commit f52d6e66e3
3 changed files with 61 additions and 18 deletions

View File

@ -30,14 +30,22 @@ public class TestSound {
//Node.connect(sin3, 0, mix, 1); //Node.connect(sin3, 0, mix, 1);
//Node.connect(sin2, 0, mix, 2); //Node.connect(sin2, 0, mix, 2);
var loop = engine.loadSample("C:\\Users\\dani\\Downloads\\AKWF" +
"\\AKWF_bw_sin\\AKWF_sin_0001.wav");
var sample = engine.loadSample("C:\\Users\\dani\\Downloads\\Untitled" + var sample = engine.loadSample("C:\\Users\\dani\\Downloads\\Untitled" +
".wav"); ".wav");
var player = new SamplePlayer(engine, sample); var kick = engine.loadSample("C:\\samples\\drum\\legowelt\\BASEDRUMS" +
"\\Legowelt Basedrum 007.wav");
var player = new SamplePlayer(engine);
Node.connect(player, 0, mix, 0); Node.connect(player, 0, mix, 0);
for(int i = 0; i < 500; ++i) { player.play(loop, true);
engine.refill(); for(int j = 0; j < 10; ++j) {
Thread.sleep(20); //player.play(kick);
for(int i = 0; i < 50; ++i) {
engine.refill();
Thread.sleep(20);
}
} }
/* /*
for(int i = 0; i < 60; ++i) { for(int i = 0; i < 60; ++i) {

View File

@ -142,11 +142,11 @@ public class AudioEngine {
} }
var sample = new Samplei(bytes.length / 2 / channels, channels == 2); var sample = new Samplei(bytes.length / 2 / channels, channels == 2);
for(int i = 0; i < bytes.length / 2 / channels; ++i) { for(int i = 0; i < bytes.length / 2 / channels; ++i) {
var l = var l = (bytes[i * 2 * channels] & 0xFF) +
bytes[i * 2 * channels] + bytes[i * 2 * channels + 1] * 256; (bytes[i * 2 * channels + 1] & 0xFF) * 256;
if(channels == 2) { if(channels == 2) {
var r = bytes[i * 2 * channels + 2] + var r = (bytes[i * 2 * channels + 2] & 0xFF) +
bytes[i * 2 * channels + 3] * 256; (bytes[i * 2 * channels + 3] & 0xFF) * 256;
sample.setSamplei(i, (short) l, (short) r); sample.setSamplei(i, (short) l, (short) r);
} else { } else {
sample.setSamplei(i, (short) l); sample.setSamplei(i, (short) l);

View File

@ -4,26 +4,61 @@ import com.danitheskunk.skunkworks.audio.AudioBuffer;
import com.danitheskunk.skunkworks.audio.AudioEngine; import com.danitheskunk.skunkworks.audio.AudioEngine;
import com.danitheskunk.skunkworks.audio.ISample; import com.danitheskunk.skunkworks.audio.ISample;
public class SamplePlayer extends Node { import java.util.ArrayList;
private ISample sample; import java.util.List;
private int tick;
public SamplePlayer(AudioEngine engine, ISample sample) { public class SamplePlayer extends Node {
private List<PlayingSample> samples;
public SamplePlayer(AudioEngine engine) {
super(engine, 0, 1); super(engine, 0, 1);
this.sample = sample; samples = new ArrayList<>();
this.tick = 0;
} }
@Override @Override
public AudioBuffer getBuffer(int slot) { public AudioBuffer getBuffer(int slot) {
var bufsize = getEngine().getBufferSize(); var bufsize = getEngine().getBufferSize();
var buf = new AudioBuffer(bufsize); var buf = new AudioBuffer(bufsize);
for(int i = 0; i < bufsize && tick < sample.getLength(); ++i) { var toRemove = new ArrayList<PlayingSample>();
var l = sample.getSampleLeft(tick); for(int i = 0; i < bufsize; ++i) {
var r = sample.getSampleRight(tick); double l = 0;
double r = 0;
for(var sample : samples) {
if(sample.loop) {
sample.tick %= sample.sample.getLength();
}
if(sample.tick < sample.sample.getLength()) {
l += sample.sample.getSampleLeft(sample.tick);
r += sample.sample.getSampleRight(sample.tick);
++sample.tick;
} else {
toRemove.add(sample);
}
}
for(var sample : toRemove) {
samples.remove(sample);
}
toRemove.clear();
buf.setSample(i, l, r); buf.setSample(i, l, r);
++tick;
} }
return buf; return buf;
} }
public void play(ISample sample) {
play(sample, false);
}
public void play(ISample sample, boolean looping) {
var s = new PlayingSample();
s.sample = sample;
s.loop = looping;
s.tick = 0;
samples.add(s);
}
private static class PlayingSample {
ISample sample;
int tick;
boolean loop;
}
} }