All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.badlogic.gdx.backends.lwjgl.audio.OpenALSound Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright 2011 See AUTHORS file.
 *
 * 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 com.badlogic.gdx.backends.lwjgl.audio;

import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import com.badlogic.gdx.audio.Sound;

import static org.lwjgl.openal.AL10.*;

/** @author Nathan Sweet */
public class OpenALSound implements Sound {
	private int bufferID = -1;
	private final OpenALLwjglAudio audio;
	private float duration;
	private int sampleRate, channels;
	private String type;

	public OpenALSound (OpenALLwjglAudio audio) {
		this.audio = audio;
	}

	/** Prepare our sound for playback!
	 * @param pcm Byte array of raw PCM data to be played.
	 * @param channels The number of channels for the sound. Most commonly 1 (for mono) or 2 (for stereo).
	 * @param bitDepth The number of bits in each sample. Normally 16. Can also be 8, 32 or sometimes 64.
	 * @param sampleRate The number of samples to be played each second. Commonly 44100; can be anything within reason. */
	void setup (byte[] pcm, int channels, int bitDepth, int sampleRate) {
		this.channels = channels;
		this.sampleRate = sampleRate;
		int format = channels > 1 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
		if (bitDepth == 8) format--; // Use 8-bit AL_FORMAT instead.
		int samples = pcm.length / (bitDepth / 8 * channels);
		duration = samples / (float)sampleRate;

		ByteBuffer buffer = ByteBuffer.allocateDirect(pcm.length);
		buffer.order(ByteOrder.nativeOrder());
		buffer.put(pcm);
		((Buffer)buffer).flip();

		if (bufferID == -1) {
			bufferID = alGenBuffers();
			alBufferData(bufferID, format, buffer.asShortBuffer(), sampleRate);
		}
	}

	public long play () {
		return play(1);
	}

	public long play (float volume) {
		if (audio.noDevice) return 0;
		int sourceID = audio.obtainSource(false);
		if (sourceID == -1) {
			// Attempt to recover by stopping the least recently played sound
			audio.retain(this, true);
			sourceID = audio.obtainSource(false);
		} else
			audio.retain(this, false);
		// In case it still didn't work
		if (sourceID == -1) return -1;
		long soundId = audio.getSoundId(sourceID);
		alSourcei(sourceID, AL_BUFFER, bufferID);
		alSourcei(sourceID, AL_LOOPING, AL_FALSE);
		alSourcef(sourceID, AL_GAIN, volume);
		alSourcePlay(sourceID);
		return soundId;
	}

	public long loop () {
		return loop(1);
	}

	@Override
	public long loop (float volume) {
		if (audio.noDevice) return 0;
		int sourceID = audio.obtainSource(false);
		if (sourceID == -1) return -1;
		long soundId = audio.getSoundId(sourceID);
		alSourcei(sourceID, AL_BUFFER, bufferID);
		alSourcei(sourceID, AL_LOOPING, AL_TRUE);
		alSourcef(sourceID, AL_GAIN, volume);
		alSourcePlay(sourceID);
		return soundId;
	}

	public void stop () {
		if (audio.noDevice) return;
		audio.stopSourcesWithBuffer(bufferID);
	}

	public void dispose () {
		if (audio.noDevice) return;
		if (bufferID == -1) return;
		audio.freeBuffer(bufferID);
		alDeleteBuffers(bufferID);
		bufferID = -1;
		audio.forget(this);
	}

	@Override
	public void stop (long soundId) {
		if (audio.noDevice) return;
		audio.stopSound(soundId);
	}

	@Override
	public void pause () {
		if (audio.noDevice) return;
		audio.pauseSourcesWithBuffer(bufferID);
	}

	@Override
	public void pause (long soundId) {
		if (audio.noDevice) return;
		audio.pauseSound(soundId);
	}

	@Override
	public void resume () {
		if (audio.noDevice) return;
		audio.resumeSourcesWithBuffer(bufferID);
	}

	@Override
	public void resume (long soundId) {
		if (audio.noDevice) return;
		audio.resumeSound(soundId);
	}

	@Override
	public void setPitch (long soundId, float pitch) {
		if (audio.noDevice) return;
		audio.setSoundPitch(soundId, pitch);
	}

	@Override
	public void setVolume (long soundId, float volume) {
		if (audio.noDevice) return;
		audio.setSoundGain(soundId, volume);
	}

	@Override
	public void setLooping (long soundId, boolean looping) {
		if (audio.noDevice) return;
		audio.setSoundLooping(soundId, looping);
	}

	@Override
	public void setPan (long soundId, float pan, float volume) {
		if (audio.noDevice) return;
		audio.setSoundPan(soundId, pan, volume);
	}

	@Override
	public long play (float volume, float pitch, float pan) {
		long id = play();
		setPitch(id, pitch);
		setPan(id, pan, volume);
		return id;
	}

	@Override
	public long loop (float volume, float pitch, float pan) {
		long id = loop();
		setPitch(id, pitch);
		setPan(id, pan, volume);
		return id;
	}

	/** Returns the length of the sound in seconds. */
	public float duration () {
		return duration;
	}

	/** Returns the original sample rate of the sound in Hz. */
	public int getRate () {
		return sampleRate;
	}

	/** Returns the number of channels of the sound (1 for mono, 2 for stereo). */
	public int getChannels () {
		return channels;
	}

	/** @param type The type of audio, such as mp3, ogg or wav. */
	public void setType (String type) {
		this.type = type;
	}

	public String getType () {
		return type;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy