/* * Copyright 2013 MovingBlocks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.terasology.audio.openAL.staticSound; import org.lwjgl.openal.AL10; import org.lwjgl.openal.AL11; import org.terasology.audio.openAL.BaseSoundSource; import org.terasology.audio.openAL.OpenALException; import org.terasology.audio.openAL.SoundPool; import static org.lwjgl.openal.AL10.AL_FALSE; import static org.lwjgl.openal.AL10.AL_LOOPING; import static org.lwjgl.openal.AL10.AL_TRUE; import static org.lwjgl.openal.AL10.alGetSourcei; import static org.lwjgl.openal.AL10.alSourcei; /** * */ public class OpenALSoundSource extends BaseSoundSource<OpenALSound> { private OpenALSound audio; public OpenALSoundSource(SoundPool<OpenALSound, OpenALSoundSource> pool) { super(pool); } public float getLength() { return audio.getLength(); } /** * @return the playback position in second */ public float getPlaybackPositionSeconds() { return (float) AL10.alGetSourcei(getSourceId(), AL11.AL_BYTE_OFFSET) / audio.getBufferSize(); } // TODO: Work out what this method returns and rename it to fit public float getPlaybackPosition() { return (float) AL10.alGetSourcei(getSourceId(), AL11.AL_SAMPLE_OFFSET) / audio.getSamplingRate(); } /** * Set playback position in seconds * * @param position */ public OpenALSoundSource setPlaybackPositionInSeconds(float position) { boolean isPlaying = isPlaying(); if (isPlaying) { AL10.alSourceStop(getSourceId()); } AL10.alSourceRewind(getSourceId()); AL10.alSourcei(getSourceId(), AL11.AL_SAMPLE_OFFSET, (int) (audio.getSamplingRate() * position)); OpenALException.checkState("Setting sound playback absolute position"); if (isPlaying) { play(); } return this; } /** * Set relative playback position (0.0f - start, 1.0f - end) * * @param position */ // TODO: This is broken for compressed streams - is this something that we need to worry about? public OpenALSoundSource setPlaybackPosition(float position) { boolean isPlaying = isPlaying(); if (isPlaying()) { AL10.alSourceStop(getSourceId()); } AL10.alSourceRewind(getSourceId()); AL10.alSourcei(getSourceId(), AL11.AL_BYTE_OFFSET, (int) (audio.getBufferSize() * position)); OpenALException.checkState("Setting sound playback relaive position"); if (isPlaying) { play(); } return this; } @Override public OpenALSound getAudio() { return audio; } @Override public boolean isLooping() { return alGetSourcei(getSourceId(), AL_LOOPING) == AL_TRUE; } @Override public OpenALSoundSource setLooping(boolean looping) { alSourcei(getSourceId(), AL_LOOPING, looping ? AL_TRUE : AL_FALSE); OpenALException.checkState("Setting sound looping"); return this; } @Override public OpenALSoundSource setAudio(OpenALSound sound) { boolean isPlaying = isPlaying(); if (isPlaying) { stop(); } reset(); audio = sound; AL10.alSourcei(getSourceId(), AL10.AL_BUFFER, audio.getBufferId()); OpenALException.checkState("Assigning buffer to source"); if (isPlaying) { play(); } return this; } @Override public void purge() { boolean isPlaying = isPlaying(); if (isPlaying) { stop(); } reset(); audio = null; AL10.alSourcei(getSourceId(), AL10.AL_BUFFER, 0); OpenALException.checkState("Clearing source"); } }