org.refcodes.audio.AbstractLineOutSampleWriter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of refcodes-audio Show documentation
Show all versions of refcodes-audio Show documentation
Artifact providing audio provessing functionality such as generating
sine waves or writing raw audio samples to WAV files.
// /////////////////////////////////////////////////////////////////////////////
// REFCODES.ORG
// /////////////////////////////////////////////////////////////////////////////
// This code is copyright (c) by Siegfried Steiner, Munich, Germany, distributed
// on an "AS IS" BASIS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, and licen-
// sed under the following (see "http://en.wikipedia.org/wiki/Multi-licensing")
// licenses:
// -----------------------------------------------------------------------------
// GNU General Public License, v3.0 ("http://www.gnu.org/licenses/gpl-3.0.html")
// -----------------------------------------------------------------------------
// Apache License, v2.0 ("http://www.apache.org/licenses/TEXT-2.0")
// -----------------------------------------------------------------------------
// Please contact the copyright holding author(s) of the software artifacts in
// question for licensing issues not being covered by the above listed licenses,
// also regarding commercial licensing models or regarding the compatibility
// with other open source licenses.
// /////////////////////////////////////////////////////////////////////////////
package org.refcodes.audio;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
/**
* The {@link AbstractLineOutSampleWriter} provides a foundation means to write
* sound samples to a line-out device.
*
* @param The {@link SoundSample} (sub-)type on which the
* {@link SampleWriter} implementation is to operate on.
* @param The {@link SampleWriter} implementing this
* {@link AbstractLineOutSampleWriter}.
*/
public abstract class AbstractLineOutSampleWriter> implements LineOutSampleWriter {
// /////////////////////////////////////////////////////////////////////////
// CONSTANTS:
// /////////////////////////////////////////////////////////////////////////
protected static final long MAX_16_BIT = 65535;
protected static final long MAX_8_BIT = 255;
// /////////////////////////////////////////////////////////////////////////
// VARIABLES:
// /////////////////////////////////////////////////////////////////////////
protected BitsPerSample _bitsPerSample = BitsPerSample.HIGH_RES;
// /////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS:
// /////////////////////////////////////////////////////////////////////////
/**
* Constructs an {@link AbstractLineOutSampleWriter}.
*/
public AbstractLineOutSampleWriter() {}
/**
* Constructs an {@link AbstractLineOutSampleWriter} with the given
* {@link BitsPerSample} to use.
*
* @param aBitsPerSample The bits/sample to use when doing audio playback.
*/
public AbstractLineOutSampleWriter( BitsPerSample aBitsPerSample ) {
_bitsPerSample = aBitsPerSample;
}
// /////////////////////////////////////////////////////////////////////////
// METHODS:
// /////////////////////////////////////////////////////////////////////////
/**
* {@inheritDoc}
*/
@Override
public void setBitsPerSample( BitsPerSample aBitsPerSample ) {
_bitsPerSample = aBitsPerSample;
}
/**
* {@inheritDoc}
*/
@Override
public BitsPerSample getBitsPerSample() {
return _bitsPerSample;
}
// /////////////////////////////////////////////////////////////////////////
// HOOKS:
// /////////////////////////////////////////////////////////////////////////
protected long toWavSample( double eSampleData ) {
return switch ( _bitsPerSample ) {
case HIGH_RES -> (long) ( eSampleData * ( MAX_16_BIT / 2 ) ); // PCM SIGNED
case LOW_RES -> (long) ( eSampleData * ( MAX_8_BIT / 2 ) ); // PCM SIGNED
};
}
// /////////////////////////////////////////////////////////////////////////
// HELPER:
// /////////////////////////////////////////////////////////////////////////
/**
* Produces a line-out {@link SourceDataLine} instance for writing samples
* to.
*
* @param aSoundSample The {@link SoundSample} from which to get the
* according metrics.
* @param aBitsPerSample The preferred bits/sample.
*
* @return An instance of the {@link SourceDataLine} to which to write data.
*
* @throws LineUnavailableException thrown in case the audio-line cannot be
* acquired.
*/
protected static SourceDataLine toLineOut( SoundSample aSoundSample, BitsPerSample aBitsPerSample ) throws LineUnavailableException {
AudioSystem.getMixerInfo(); // Init the syound system...?!?
// @formatter:off
final AudioFormat format = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED, // Encoding
aSoundSample.getSamplingRate(), // Sample Rate
aBitsPerSample.getBitCount() * aSoundSample.getChannelCount(), // Sample size in Bits
aSoundSample.getChannelCount(), // Channels
aBitsPerSample.getByteCount() * aSoundSample.getChannelCount(), // Number of bytes in each frame
aSoundSample.getSamplingRate(), // Number of frames per second
true // True = big endian, false = little endian
);
// @formatter:on
final DataLine.Info info = new DataLine.Info( SourceDataLine.class, format );
final SourceDataLine theLine = (SourceDataLine) AudioSystem.getLine( info );
theLine.open();
theLine.start();
return theLine;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy