started implementing AudioEngine
This commit is contained in:
parent
4486bb67a9
commit
87b3faaa81
|
@ -1,5 +1,6 @@
|
|||
package com.danitheskunk.skunkworks;
|
||||
|
||||
import com.danitheskunk.skunkworks.audio.AudioEngine;
|
||||
import org.lwjgl.openal.AL;
|
||||
import org.lwjgl.openal.ALC;
|
||||
|
||||
|
@ -14,63 +15,11 @@ import static org.lwjgl.openal.AL10.*;
|
|||
import static org.lwjgl.openal.ALC10.*;
|
||||
|
||||
public class TestSound {
|
||||
public static void main(String args[]) {
|
||||
var device = alcOpenDevice((ByteBuffer) null);
|
||||
if(device == 0) {
|
||||
throw new RuntimeException("couldn't init openal device");
|
||||
}
|
||||
var deviceCaps = ALC.createCapabilities(device);
|
||||
var context = alcCreateContext(device, (IntBuffer) null);
|
||||
if(context == 0) {
|
||||
throw new RuntimeException("couldn't create openal context");
|
||||
}
|
||||
alcMakeContextCurrent(context);
|
||||
AL.createCapabilities(deviceCaps);
|
||||
|
||||
var buf = alGenBuffers();
|
||||
int sampleRate = 44100;
|
||||
var samples = new short[sampleRate * 2];
|
||||
for(int i = 0; i < samples.length; ++i) {
|
||||
var s = Math.sin(2 * Math.PI * 220 * i / (double) sampleRate);
|
||||
var s2 = Math.sin(2 * Math.PI * 440 * i / (double) sampleRate +
|
||||
s * 10 * (88200 - i) / 88200);
|
||||
//s = s * s2 * i / 88200;
|
||||
s = s2 * (88200 - i) / 88200;
|
||||
samples[i] = (short) (s * 32760);
|
||||
}
|
||||
|
||||
var bb = ByteBuffer.allocate(samples.length * 2);
|
||||
for(int i = 0; i < samples.length; ++i) {
|
||||
bb.putShort(samples[i]);
|
||||
}
|
||||
|
||||
var bytes = bb.array();
|
||||
|
||||
AudioInputStream audio;
|
||||
var format = new AudioFormat(sampleRate, 16, 1, true, true);
|
||||
audio = new AudioInputStream(
|
||||
new ByteArrayInputStream(bytes),
|
||||
format,
|
||||
bytes.length
|
||||
);
|
||||
try {
|
||||
AudioSystem.write(audio,
|
||||
AudioFileFormat.Type.WAVE,
|
||||
new File("meow.wav")
|
||||
);
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
alBufferData(buf, AL_FORMAT_MONO16, samples, sampleRate);
|
||||
|
||||
var src = alGenSources();
|
||||
alSourcei(src, AL_BUFFER, buf);
|
||||
alSourcePlay(src);
|
||||
try {
|
||||
Thread.sleep(3000);
|
||||
} catch(InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
public static void main(String args[]) throws InterruptedException {
|
||||
var engine = new AudioEngine(44100, 256, 8);
|
||||
for(int i = 0; i < 120; ++i) {
|
||||
engine.refill();
|
||||
Thread.sleep(20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
package com.danitheskunk.skunkworks.audio;
|
||||
|
||||
import org.lwjgl.openal.AL;
|
||||
import org.lwjgl.openal.ALC;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.lwjgl.openal.AL10.*;
|
||||
import static org.lwjgl.openal.ALC10.*;
|
||||
|
||||
public class AudioEngine {
|
||||
private int sampleRate;
|
||||
private int bufferSize;
|
||||
private int bufferCount;
|
||||
private long device;
|
||||
private long context;
|
||||
private int source;
|
||||
private int tick = 0;
|
||||
|
||||
public AudioEngine(int sampleRate, int bufferSize, int bufferCount) {
|
||||
this.sampleRate = sampleRate;
|
||||
this.bufferSize = bufferSize;
|
||||
this.bufferCount = bufferCount;
|
||||
|
||||
device = alcOpenDevice((ByteBuffer) null);
|
||||
if(device == 0) {
|
||||
throw new RuntimeException("couldn't init openal device");
|
||||
}
|
||||
var deviceCaps = ALC.createCapabilities(device);
|
||||
context = alcCreateContext(device, (IntBuffer) null);
|
||||
if(context == 0) {
|
||||
throw new RuntimeException("couldn't create openal context");
|
||||
}
|
||||
alcMakeContextCurrent(context);
|
||||
AL.createCapabilities(deviceCaps);
|
||||
|
||||
this.source = alGenSources();
|
||||
|
||||
for(int i = 0; i < bufferCount; ++i) {
|
||||
addEmptyBuffer();
|
||||
}
|
||||
alSourcePlay(source);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
alcDestroyContext(context);
|
||||
alcCloseDevice(device);
|
||||
}
|
||||
|
||||
private void fillBuffer(int buffer) {
|
||||
var buf = new double[bufferSize * 2];
|
||||
for(int i = 0; i < bufferSize; ++i) {
|
||||
double time = (double) tick / (double) sampleRate;
|
||||
var s = Math.sin(2 * Math.PI * 440 * time);
|
||||
buf[i * 2] = s;
|
||||
buf[i * 2 + 1] = s;
|
||||
++tick;
|
||||
}
|
||||
|
||||
var shortBuffer = new short[bufferSize * 2];
|
||||
for(int i = 0; i < bufferSize * 2; ++i) {
|
||||
shortBuffer[i] = (short) (buf[i] * 32760);
|
||||
}
|
||||
|
||||
alBufferData(buffer, AL_FORMAT_STEREO16, shortBuffer, sampleRate);
|
||||
}
|
||||
|
||||
private void addEmptyBuffer() {
|
||||
var buf = alGenBuffers();
|
||||
fillBuffer(buf);
|
||||
alSourceQueueBuffers(source, buf);
|
||||
}
|
||||
|
||||
public void refill() {
|
||||
var bufCount = alGetSourcei(source, AL_BUFFERS_PROCESSED);
|
||||
var bufs = new int[bufCount];
|
||||
alSourceUnqueueBuffers(source, bufs);
|
||||
for(int i = 0; i < bufCount; ++i) {
|
||||
fillBuffer(bufs[i]);
|
||||
alSourceQueueBuffers(source, bufs[i]);
|
||||
}
|
||||
if(alGetSourcei(source, AL_SOURCE_STATE) != AL_PLAYING) {
|
||||
System.out.println("buffer underrun, addng buffer");
|
||||
addEmptyBuffer();
|
||||
alSourcePlay(source);
|
||||
}
|
||||
}
|
||||
|
||||
public int getSampleRate() {
|
||||
return sampleRate;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue