started implementing AudioEngine
This commit is contained in:
parent
4486bb67a9
commit
87b3faaa81
|
@ -1,5 +1,6 @@
|
||||||
package com.danitheskunk.skunkworks;
|
package com.danitheskunk.skunkworks;
|
||||||
|
|
||||||
|
import com.danitheskunk.skunkworks.audio.AudioEngine;
|
||||||
import org.lwjgl.openal.AL;
|
import org.lwjgl.openal.AL;
|
||||||
import org.lwjgl.openal.ALC;
|
import org.lwjgl.openal.ALC;
|
||||||
|
|
||||||
|
@ -14,63 +15,11 @@ import static org.lwjgl.openal.AL10.*;
|
||||||
import static org.lwjgl.openal.ALC10.*;
|
import static org.lwjgl.openal.ALC10.*;
|
||||||
|
|
||||||
public class TestSound {
|
public class TestSound {
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) throws InterruptedException {
|
||||||
var device = alcOpenDevice((ByteBuffer) null);
|
var engine = new AudioEngine(44100, 256, 8);
|
||||||
if(device == 0) {
|
for(int i = 0; i < 120; ++i) {
|
||||||
throw new RuntimeException("couldn't init openal device");
|
engine.refill();
|
||||||
}
|
Thread.sleep(20);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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