98 lines
3.4 KiB
Java
98 lines
3.4 KiB
Java
/*
|
|
* Copyright (C) 2013 Darth Affe <http://wyrez.org> and contributors
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*
|
|
* This Code is based on the source provided with a tutorial by
|
|
* http://www.badlogicgames.com (as of 16.05.2013).
|
|
* The original source can be found here:
|
|
* http://code.google.com/p/audio-analysis/source/browse/trunk/src/com/badlogic/audio/io/AudioDevice.java
|
|
*/
|
|
package org.wyrez.audio;
|
|
|
|
import javax.sound.sampled.AudioFormat;
|
|
import javax.sound.sampled.AudioSystem;
|
|
import javax.sound.sampled.SourceDataLine;
|
|
|
|
/**
|
|
* Class that allows directly passing PCM float data to the sound card for
|
|
* playback.
|
|
*
|
|
* @author Darth Affe
|
|
*/
|
|
public class AudioDevice {
|
|
|
|
private final SourceDataLine out;
|
|
private byte[] buffer;
|
|
|
|
/**
|
|
* Constructor, initializes the audio system for 16-bit signed stereo output
|
|
* with a sampling rate of 44100 and a buffer size of 2048.
|
|
*
|
|
* @throws Exception in case the audio system could not be initialized
|
|
*/
|
|
public AudioDevice() throws Exception {
|
|
this(44100, 2);
|
|
}
|
|
|
|
/**
|
|
* Constructor, initializes the audio system for 16-bit signed output. Sets
|
|
* the buffer size to 1024*channels
|
|
*
|
|
* @param samplingRate The sampling rate
|
|
* @param channels The number of channels
|
|
* @throws Exception in case the audio system could not be initialized
|
|
*/
|
|
public AudioDevice(float samplingRate, int channels) throws Exception {
|
|
this(samplingRate, channels, 1024 * channels);
|
|
}
|
|
|
|
/**
|
|
* Constructor, initializes the audio system for 16-bit signed output.
|
|
*
|
|
* @param samplingRate The sampling rate
|
|
* @param channels The number of channels
|
|
* @param bufferSize The buffer size (have to be a even number)
|
|
* @throws Exception in case the audio system could not be initialized
|
|
*/
|
|
public AudioDevice(float samplingRate, int channels, int bufferSize) throws Exception {
|
|
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
|
|
samplingRate, 16, channels, channels * 2, samplingRate, false);
|
|
buffer = new byte[bufferSize * 2];
|
|
out = AudioSystem.getSourceDataLine(format);
|
|
out.open(format);
|
|
out.start();
|
|
}
|
|
|
|
/**
|
|
* Writes the given samples to the audio device. The samples have to be in
|
|
* the range [-1,1].
|
|
*
|
|
* @param samples The samples.
|
|
*/
|
|
public void writeSamples(float[] samples) {
|
|
fillBuffer(samples);
|
|
out.write(buffer, 0, buffer.length);
|
|
}
|
|
|
|
private void fillBuffer(float[] samples) {
|
|
for (int i = 0, j = 0; i < samples.length; i++, j += 2) {
|
|
short value = (short) (samples[i] * Short.MAX_VALUE);
|
|
buffer[j] = (byte) (value | 0xff);
|
|
buffer[j + 1] = (byte) (value >> 8);
|
|
}
|
|
}
|
|
}
|