// Copyright 2014-2025 Jesper Larsson
//
// This file is part of Klipspringer, <https://klipspringer.eavadeaux.net/>
//
// Klipspringer 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.
//
// Klipspringer 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 Klipspringer. If
// not, see <https://www.gnu.org/licenses/>.
package net.avadeaux.klipspringer.codec;
import java.io.*;
import java.nio.ByteBuffer;
/** Representation of an audio device. */
public interface Device extends PcmFormat.Selector {
/** Specification for where bits are placed when the bytes allocated for a sample are not
* completely filled by the sample bits. This can be because the bit depth is not a muliple of
* eight, or because four bytes are allocated for 24-bit samples. See <a
* href="https://klipspringer.avadeaux.net/ten-standard-ways-of-representing-binary-numbers/">blog
* post</a> for explanation of the formats. {@link PcmBuffer} can be used for converting
* between layouts and other sample encoding discrepancies.
*/
enum BitLayout {
/** The lower bits are significant, and insignificant bits are set to zero, This is the
* default, used where no bit layout is specified.
*/
LSB,
/** The higher bits are significant, and insignificant bits are zero. This corresponds to
* scaling up the samples, so that they can be read as if all the bits are
* significant. This is used by LAME and in the WAV format.
*/
MSB,
/** The lower bits are significant, and higher bit equal to the sign, the leftmost
* significant bits. This can only be used when the encoding is signed. Values in this
* format can be read as if all the bits are significant, producing signed values within
* the range dictated by the number of bits per sample. It is used in FLAC encoding.
*/
LSBX
}
/** PCM reader for input (from microphone, ADC, or whatever audio input is available). */
interface Tuner extends PcmReader, Closeable {
/** Tuner factory interface. */
interface Factory extends PcmFormat.Selector {
/** Creates a tuner for the format, or throws exception if not possible. */
Tuner open(PcmFormat format) throws IOException;
}
/** Gets the audio format data read through the tuner. */
PcmFormat format();
/** See {@link Closeable#close()}. */
void close() throws IOException;
}
/** PCM writer with optional methods to control real-time playing where applicanle. */
interface Player extends PcmWriter {
/** Player factory interface. */
interface Factory extends PcmFormat.Selector {
/** Creates a player for the format, or throws exception if not possible. */
Player open(PcmFormat format) throws IOException;
/** Gets the bit layout expected by players from this factory with the given format. If
* the factory is associated with a device, this should match what is returned by
* {@link Device#layout(PcmFormat)}. Default returns {@link BitLayout#LSB}.
*/
default BitLayout layout(PcmFormat format) { return BitLayout.LSB; }
}
/** Gets the audio expected by the player. */
PcmFormat format();
/** Gets the bit layout expected by the player. If the player is produced by a {@link
* Device.Player.Factory Factory}, the layout should match the value returned by {@link
* Factory#layout(PcmFormat)}, and if the player is associated with a device, this should
* match what is returned by {@link Device#layout(PcmFormat)}. Default returns {@link
* BitLayout#LSB}. Default returns {@link BitLayout#LSB}.
*/
default BitLayout layout() { return BitLayout.LSB; }
/** Writes a block of audio data in {@link #layout() the bit layout expected} by the
* player. For most players, it makes sense to always return true, since players do not
* usually have a limit on the stream.
*/
boolean write(ByteBuffer data) throws IOException;
/** Gets an estimate of how many frames are currently buffered, waiting to be
* played. Default returns zero.
*/
default int bufferedFrames() throws IOException { return 0; }
/** Checks if {@link #pause()} is supported. Default returns false. */
default boolean canPause() { return false; }
/** Pauses, if this optional operation is supported, audio playback at the
* destination. Pausing during write may have the effect that write returns false, with the
* buffer position set to where writing stopped. If already in paused state, this method
* does nothing. Default implementation throws {@link UnsupportedOperationException}.
*/
default void pause() throws IOException{ throw new UnsupportedOperationException(); }
/** Resumes paused audio playback at the destination. If already in playback state, or if
* pausing is not supported, this method does nothing (the default).
*/
default void unpause() throws IOException { }
/** Waits for player to send on any data it has buffered up and closes it. Default
* implementation calls {@link #close()} immediately.
*/
default void drain() throws IOException { close(); }
}
/** Gets the bit layout expected by players with the given format associated with this
* device. Default returns {@link BitLayout#LSB}.
*/
default BitLayout layout(PcmFormat format) { return BitLayout.LSB; }
/** Gets the identifying name of the device. */
String name();
/** Gets a descriptive string of the device, which includes the {@link #name()}. */
String toString();
/** Writes a human-readable representation of available formats to the given stream. */
void printAvailableFormats(PrintStream out);
}
Version: v4.3.2.2 (2026-05-16T17:03:34+02:00)
Raw file
Source code overview
Klipspringer home