made looping sample-perfect
This commit is contained in:
parent
de325c72b5
commit
f52d6e66e3
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue