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

javazoom.jl.decoder.OutputBuffer Maven / Gradle / Ivy

/*
 * 11/19/04 1.0 moved to LGPL. 12/12/99 Added appendSamples() method for efficiency. MDM. 15/02/99 ,Java Conversion by E.B
 * ,[email protected], JavaLayer
 * 
 * Declarations for output buffer, includes operating system implementation of the virtual Obuffer. Optional routines enabling
 * seeks and stops added by Jeff Tsay.
 * 
 * @(#) obuffer.h 1.8, last edit: 6/15/94 16:51:56
 * 
 * @(#) Copyright (C) 1993, 1994 Tobias Bading ([email protected])
 * 
 * @(#) Berlin University of Technology
 * 
 * Idea and first implementation for u-law output with fast downsampling by Jim Boucher ([email protected])
 * 
 * LinuxObuffer class written by Louis P. Kruger ([email protected])
 * ----------------------------------------------------------------------- This program is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.
 * 
 * You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * ----------------------------------------------------------------------
 */

package javazoom.jl.decoder;

/**
 * Base Class for audio output.
 */
public class OutputBuffer {
	public static final int BUFFERSIZE = 2 * 1152; // max. 2 * 1152 samples per frame
	private static final int MAXCHANNELS = 2; // max. number of channels

	private Float replayGainScale;
	private int channels;
	private byte[] buffer;
	private int[] channelPointer;
	private boolean isBigEndian;

	public OutputBuffer (int channels, boolean isBigEndian) {
		this.channels = channels;
		this.isBigEndian = isBigEndian;
		buffer = new byte[BUFFERSIZE * channels];
		channelPointer = new int[channels];
		reset();
	}

	/**
	 * Takes a 16 Bit PCM sample.
	 */
	private void append (int channel, short value) {
		byte firstByte;
		byte secondByte;
		if (isBigEndian) {
			firstByte = (byte)(value >>> 8 & 0xFF);
			secondByte = (byte)(value & 0xFF);
		} else {
			firstByte = (byte)(value & 0xFF);
			secondByte = (byte)(value >>> 8 & 0xFF);
		}
		buffer[channelPointer[channel]] = firstByte;
		buffer[channelPointer[channel] + 1] = secondByte;
		channelPointer[channel] += channels * 2;
	}

	/**
	 * Takes 32 PCM samples.
	 */
	public void appendSamples (int channel, float[] f) {
		short s;
		if (replayGainScale != null) {
			for (int i = 0; i < 32;) {
				s = clip(f[i++] * replayGainScale);
				append(channel, s);
			}
		} else {
			for (int i = 0; i < 32;) {
				s = clip(f[i++]);
				append(channel, s);
			}
		}
	}

	public byte[] getBuffer () {
		return buffer;
	}

	public int reset () {
		try {
			int index = channels - 1;
			return channelPointer[index] - index * 2;
		} finally {
			// Points to byte location, implicitely assuming 16 bit samples.
			for (int i = 0; i < channels; i++)
				channelPointer[i] = i * 2;
		}
	}

	public void setReplayGainScale (Float replayGainScale) {
		this.replayGainScale = replayGainScale;
	}

	public boolean isStereo () {
		return channelPointer[1] == 2;
	}

	// Clip to 16 bits.
	private final short clip (float sample) {
		return sample > 32767.0f ? 32767 : sample < -32768.0f ? -32768 : (short)sample;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy