Structured OpenAl
- Now it is possible to: - read files as mono or stereo - create and play more than one sound
This commit is contained in:
parent
03f9b90239
commit
aec9301b6b
@ -0,0 +1,38 @@
|
||||
package ru.windcorp.progressia.client.audio;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import ru.windcorp.progressia.common.resource.*;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import static org.lwjgl.stb.STBVorbis.*;
|
||||
import static org.lwjgl.openal.AL10.*;
|
||||
|
||||
public class AudioReader {
|
||||
private AudioReader() {};
|
||||
|
||||
//TODO fix converting from mono-stereo
|
||||
|
||||
public static SoundType readAsMono(String AudioFile) {
|
||||
IntBuffer channelBuffer = BufferUtils.createIntBuffer(1);
|
||||
IntBuffer rateBuffer = BufferUtils.createIntBuffer(1);
|
||||
Resource res = ResourceManager.getResource(AudioFile);
|
||||
ShortBuffer rawMonoAudio = decodeVorbis(res, channelBuffer, rateBuffer);
|
||||
|
||||
return new SoundType(rawMonoAudio, AL_FORMAT_MONO16, rateBuffer.get(0));
|
||||
}
|
||||
|
||||
public static SoundType readAsStereo(String AudioFile) {
|
||||
IntBuffer channelsBuffer = BufferUtils.createIntBuffer(2);
|
||||
IntBuffer rateBuffer = BufferUtils.createIntBuffer(1);
|
||||
Resource res = ResourceManager.getResource(AudioFile);
|
||||
ShortBuffer rawStereoAudio = decodeVorbis(res, channelsBuffer, rateBuffer);
|
||||
|
||||
return new SoundType(rawStereoAudio, AL_FORMAT_STEREO16, rateBuffer.get(0));
|
||||
}
|
||||
|
||||
private static ShortBuffer decodeVorbis(Resource dataToDecode, IntBuffer channelsBuffer, IntBuffer rateBuffer) {
|
||||
return stb_vorbis_decode_memory(dataToDecode.readAsBytes(), channelsBuffer, rateBuffer);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package ru.windcorp.progressia.client.audio;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import static org.lwjgl.openal.AL10.*;
|
||||
|
||||
//TODO add getters and setters
|
||||
|
||||
public class Listener {
|
||||
private static FloatBuffer position =
|
||||
(FloatBuffer) BufferUtils.createFloatBuffer(3).put(new float[]{0.0f, 0.0f, 0.0f}).flip();
|
||||
private static FloatBuffer velocity =
|
||||
(FloatBuffer) BufferUtils.createFloatBuffer(3).put(new float[]{0.0f, 0.0f, 0.0f}).flip();
|
||||
private static FloatBuffer orientation =
|
||||
(FloatBuffer) BufferUtils.createFloatBuffer(6).put(new float[]{0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f}).flip();
|
||||
|
||||
public static void update() {
|
||||
alListenerfv(AL_POSITION, position);
|
||||
alListenerfv(AL_VELOCITY, velocity);
|
||||
alListenerfv(AL_ORIENTATION, orientation);
|
||||
}
|
||||
}
|
141
src/main/java/ru/windcorp/progressia/client/audio/Sound.java
Normal file
141
src/main/java/ru/windcorp/progressia/client/audio/Sound.java
Normal file
@ -0,0 +1,141 @@
|
||||
package ru.windcorp.progressia.client.audio;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import static org.lwjgl.openal.AL10.*;
|
||||
|
||||
public class Sound {
|
||||
//Buffers
|
||||
private int audio;
|
||||
private int source;
|
||||
//Characteristics
|
||||
private FloatBuffer position =
|
||||
(FloatBuffer) BufferUtils.createFloatBuffer(3)
|
||||
.put(new float[]{0.0f, 0.0f, 0.0f}).flip();
|
||||
private FloatBuffer velocity =
|
||||
(FloatBuffer) BufferUtils.createFloatBuffer(3)
|
||||
.put(new float[]{0.0f, 0.0f, 0.0f}).flip();
|
||||
private float pitch = 1.0f;
|
||||
private float gain = 1.0f;
|
||||
|
||||
public Sound() {
|
||||
}
|
||||
|
||||
public Sound(int audio, int source) {
|
||||
setAudio(audio);
|
||||
setSource(source);
|
||||
}
|
||||
|
||||
public Sound(int audio, FloatBuffer position, FloatBuffer velocity, float pitch, float gain)
|
||||
{
|
||||
setAudio(audio);
|
||||
setPosition(position);
|
||||
setVelocity(velocity);
|
||||
setPitch(pitch);
|
||||
setGain(gain);
|
||||
}
|
||||
|
||||
public Sound(FloatBuffer position, FloatBuffer velocity, float pitch, float gain) {
|
||||
setPosition(position);
|
||||
setVelocity(velocity);
|
||||
setPitch(pitch);
|
||||
setGain(gain);
|
||||
}
|
||||
|
||||
public void forcePlay() {
|
||||
alSourcePlay(source);
|
||||
}
|
||||
|
||||
public boolean playOnce() {
|
||||
if(isEmpty()) {
|
||||
alSourcePlay(source);
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
public boolean playLoop() {
|
||||
alSourcei(source, AL_LOOPING, AL_TRUE);
|
||||
boolean isPlaying = playOnce();
|
||||
alSourcei(source, AL_LOOPING, AL_FALSE);
|
||||
return isPlaying;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
alSourceStop(source);
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
alSourcePause(source);
|
||||
}
|
||||
|
||||
public boolean isPlaying() {
|
||||
final int state = alGetSourcei(source, AL_PLAYING);
|
||||
return state == AL_TRUE;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return source == 0;
|
||||
}
|
||||
|
||||
public int getAudio() {
|
||||
return audio;
|
||||
}
|
||||
|
||||
public void setAudio(int audio) {
|
||||
this.audio = audio;
|
||||
}
|
||||
|
||||
public void setSource(int source) {
|
||||
this.source = source;
|
||||
alSourcei(this.source, AL_BUFFER, audio);
|
||||
}
|
||||
|
||||
public int getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
//OTHER
|
||||
|
||||
public void setPosition(FloatBuffer position) {
|
||||
this.position = position;
|
||||
alSourcefv(source, AL_POSITION, position);
|
||||
}
|
||||
|
||||
public FloatBuffer getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
public void setVelocity(FloatBuffer velocity) {
|
||||
alSourcefv(source, AL_VELOCITY, velocity);
|
||||
this.velocity = velocity;
|
||||
}
|
||||
|
||||
public FloatBuffer getVelocity() {
|
||||
return velocity;
|
||||
}
|
||||
|
||||
|
||||
public void setPitch(float pitch) {
|
||||
alSourcef(source, AL_PITCH, pitch);
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
public float getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
|
||||
public void setGain(float gain) {
|
||||
alSourcef(source, AL_GAIN, gain);
|
||||
this.gain = gain;
|
||||
}
|
||||
|
||||
public float getGain() {
|
||||
return gain;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package ru.windcorp.progressia.client.audio;
|
||||
|
||||
import java.nio.ShortBuffer;
|
||||
import static org.lwjgl.openal.AL10.*;
|
||||
|
||||
public class SoundType {
|
||||
private ShortBuffer rawAudio;
|
||||
private int sampleRate;
|
||||
private int format;
|
||||
|
||||
public SoundType(ShortBuffer rawAudio, int format, int sampleRate) {
|
||||
this.rawAudio = rawAudio;
|
||||
this.sampleRate = sampleRate;
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public Sound genSound() {
|
||||
int audio = alGenBuffers();
|
||||
alBufferData(audio, format, rawAudio, sampleRate);
|
||||
return new Sound(audio, alGenSources());
|
||||
}
|
||||
}
|
@ -2,27 +2,16 @@ package ru.windcorp.progressia.client.audio.backend;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.openal.*;
|
||||
import ru.windcorp.progressia.common.resource.Resource;
|
||||
import ru.windcorp.progressia.common.resource.ResourceManager;
|
||||
import ru.windcorp.progressia.client.audio.AudioReader;
|
||||
import ru.windcorp.progressia.client.audio.Listener;
|
||||
import ru.windcorp.progressia.client.audio.Sound;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import static org.lwjgl.openal.AL10.*;
|
||||
import static org.lwjgl.openal.ALC10.*;
|
||||
import static org.lwjgl.stb.STBVorbis.stb_vorbis_decode_memory;
|
||||
|
||||
public class ALTest {
|
||||
|
||||
// Buffers hold sound data
|
||||
private IntBuffer buffer = BufferUtils.createIntBuffer(1);
|
||||
// Sources are points emitting sound
|
||||
private IntBuffer source = BufferUtils.createIntBuffer(1);
|
||||
// Position of the source sound
|
||||
private FloatBuffer sourcePos = (FloatBuffer) BufferUtils.createFloatBuffer(3).put(new float[]{0.0f, 0.0f, 0.0f}).flip();
|
||||
// Velocity of the source sound
|
||||
private FloatBuffer sourceVel = (FloatBuffer) BufferUtils.createFloatBuffer(3).put(new float[]{0.0f, 0.0f, 0.0f}).flip();
|
||||
// Position of the listener
|
||||
private FloatBuffer listenerPos = (FloatBuffer) BufferUtils.createFloatBuffer(3).put(new float[]{0.0f, 0.0f, 0.0f}).flip();
|
||||
// Velocity of the listener
|
||||
@ -32,8 +21,6 @@ public class ALTest {
|
||||
private FloatBuffer listenerOri =
|
||||
(FloatBuffer) BufferUtils.createFloatBuffer(6).put(new float[]{0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f}).flip();
|
||||
|
||||
private ShortBuffer rawDataBuffer;
|
||||
|
||||
private void initializeAL() {
|
||||
|
||||
String defaultDeviceName = alcGetString(0, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||
@ -47,57 +34,8 @@ public class ALTest {
|
||||
}
|
||||
|
||||
void loadALData() {
|
||||
checkALError();
|
||||
int thebuffer = AL10.alGenBuffers();
|
||||
checkALError();
|
||||
|
||||
IntBuffer channelsBuffer = BufferUtils.createIntBuffer(1);
|
||||
IntBuffer sampleRateBuffer = BufferUtils.createIntBuffer(1);
|
||||
|
||||
|
||||
ShortBuffer rawAudioBuffer =
|
||||
readVorbis("assets/sounds/sample.ogg", channelsBuffer, sampleRateBuffer);
|
||||
int channels = channelsBuffer.get();
|
||||
int sampleRate = sampleRateBuffer.get();
|
||||
|
||||
int format = -1;
|
||||
if (channels == 1) {
|
||||
format = AL_FORMAT_MONO16;
|
||||
} else if (channels == 2) {
|
||||
format = AL_FORMAT_STEREO16;
|
||||
}
|
||||
|
||||
System.out.println(rawAudioBuffer);
|
||||
//Send the data to OpenAL
|
||||
alBufferData(thebuffer, AL_FORMAT_STEREO16, rawAudioBuffer, sampleRate);
|
||||
//Free the memory allocated by STB
|
||||
//free(rawAudioBuffer);
|
||||
|
||||
alGenSources(source);
|
||||
|
||||
//Assign our buffer to the source
|
||||
alSourcei(source.get(0), AL_BUFFER, thebuffer);
|
||||
|
||||
// Bind the buffer with the source
|
||||
//AL10.alGenBuffers(source);
|
||||
checkALError();
|
||||
|
||||
/*alSourcei(source.get(0), AL_BUFFER, buffer.get(0) );
|
||||
alSourcef(source.get(0), AL_PITCH, 1.0f );
|
||||
alSourcef(source.get(0), AL_GAIN, 1.0f );
|
||||
alSourcefv(source.get(0), AL_POSITION, sourcePos );
|
||||
alSourcefv(source.get(0), AL_VELOCITY, sourceVel );*/
|
||||
|
||||
int error = alGetError();
|
||||
|
||||
checkALError();
|
||||
}
|
||||
|
||||
//Tells OpenAL to use the data we have created
|
||||
void setListenerValues() {
|
||||
alListenerfv(AL_POSITION, listenerPos);
|
||||
alListenerfv(AL_VELOCITY, listenerVel);
|
||||
alListenerfv(AL_ORIENTATION, listenerOri);
|
||||
Sound music = AudioReader.readAsMono("assets/sounds/sample_mono.ogg").genSound();
|
||||
music.forcePlay();
|
||||
}
|
||||
|
||||
void killALData() {
|
||||
@ -107,26 +45,14 @@ public class ALTest {
|
||||
|
||||
public void execute() {
|
||||
initializeAL();
|
||||
|
||||
checkALError();
|
||||
|
||||
Listener.update();
|
||||
loadALData();
|
||||
|
||||
|
||||
setListenerValues();
|
||||
checkALError();
|
||||
AL10.alSourcePlay(source.get(0));
|
||||
checkALError();
|
||||
}
|
||||
|
||||
private static ShortBuffer readVorbis(String fileName, IntBuffer channelsBuffer, IntBuffer sampleRateBuffer) {
|
||||
Resource res = ResourceManager.getResource(fileName);
|
||||
System.out.println();
|
||||
System.out.println(res.readAsBytes().remaining());
|
||||
System.out.println();
|
||||
return stb_vorbis_decode_memory(res.readAsBytes(), channelsBuffer, sampleRateBuffer);
|
||||
}
|
||||
|
||||
public void checkALError() {
|
||||
int i = alGetError();
|
||||
if(alGetError() != AL_NO_ERROR) {
|
||||
|
@ -1,4 +0,0 @@
|
||||
package ru.windcorp.progressia.client.audio;
|
||||
|
||||
public class deletetheclass {
|
||||
}
|
Binary file not shown.
BIN
src/main/resources/assets/sounds/sample_mono.ogg
Normal file
BIN
src/main/resources/assets/sounds/sample_mono.ogg
Normal file
Binary file not shown.
BIN
src/main/resources/assets/sounds/sample_stereo.ogg
Normal file
BIN
src/main/resources/assets/sounds/sample_stereo.ogg
Normal file
Binary file not shown.
Reference in New Issue
Block a user