Skip to content

Commit

Permalink
Add javadoc for Opus packet classes.
Browse files Browse the repository at this point in the history
  • Loading branch information
leonfancy committed Jul 11, 2020
1 parent 3c5b39a commit 810c64d
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 15 deletions.
7 changes: 7 additions & 0 deletions src/main/java/org/chenliang/oggus/opus/Channel.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package org.chenliang.oggus.opus;

/**
* Opus packet only has two types of channel:
* <ul>
* <li>stereo: left and right channels</li>
* <li>mono: only a single channel</li>
* </ul>
*/
public enum Channel {
MONO, STEREO
}
46 changes: 46 additions & 0 deletions src/main/java/org/chenliang/oggus/opus/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,36 @@
import static org.chenliang.oggus.opus.Config.EncodeMode.HYBRID;
import static org.chenliang.oggus.opus.Config.EncodeMode.SILK;

/**
* Get the configuration of Opus packet that represent the encoding mode, bandwidth, and frame size. The first 5 bits
* of the TOC byte gives the ID of configuration. {@code Config.of(int id)} method is used to get the Config instance
* of a given ID.
*
* <p>Below are the table of configurations:
* <pre>
* +-----------------------+-----------+-----------+-------------------+
* | Configuration ID | Mode | Bandwidth | Frame Sizes |
* +-----------------------+-----------+-----------+-------------------+
* | 0...3 | SILK-only | NB | 10, 20, 40, 60 ms |
* | | | | |
* | 4...7 | SILK-only | MB | 10, 20, 40, 60 ms |
* | | | | |
* | 8...11 | SILK-only | WB | 10, 20, 40, 60 ms |
* | | | | |
* | 12...13 | Hybrid | SWB | 10, 20 ms |
* | | | | |
* | 14...15 | Hybrid | FB | 10, 20 ms |
* | | | | |
* | 16...19 | CELT-only | NB | 2.5, 5, 10, 20 ms |
* | | | | |
* | 20...23 | CELT-only | WB | 2.5, 5, 10, 20 ms |
* | | | | |
* | 24...27 | CELT-only | SWB | 2.5, 5, 10, 20 ms |
* | | | | |
* | 28...31 | CELT-only | FB | 2.5, 5, 10, 20 ms |
* +-----------------------+-----------+-----------+-------------------+
* </pre>
*/
public class Config {
private final int id;
private final EncodeMode encodeMode;
Expand Down Expand Up @@ -57,6 +87,10 @@ public class Config {
new Config(31, CELT, FB, 20),
};

/**
* @param id configuration id, should be between [0, 32)
* @return Config object
*/
public static Config of(int id) {
if (id > 32 || id < 0) {
throw new IllegalArgumentException("Invalid Config ID: " + id);
Expand Down Expand Up @@ -87,10 +121,16 @@ public int getId() {
return id;
}

/**
* Opus encoding mode.
*/
public enum EncodeMode {
SILK, HYBRID, CELT
}

/**
* Opus supported audio bandwidth and sample rate.
*/
public enum Bandwidth {
NB(4000, 8000), MB(6000, 12000), WB(8000, 16000),
SWB(12000, 24000), FB(20000, 48000);
Expand All @@ -103,10 +143,16 @@ public enum Bandwidth {
this.sampleRate = sampleRate;
}

/**
* @return audio bandwidth
*/
public int getHz() {
return hz;
}

/**
* @return sample rate for that bandwidth
*/
public int getSampleRate() {
return sampleRate;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import java.io.ByteArrayOutputStream;

/**
* This is the parent class of {@link CodeZeroPacket}, {@link CodeOnePacket} and {@link CodeTwoPacket}.
* These Opus packets contains a fixed number of frames.
*/
abstract class FixedFrameCountPacket extends OpusPacket {
public void setVbr(boolean isVbr) {
throw new IllegalStateException("Code 0 to 2 Opus packet doesn't support setting Vbr flag");
Expand Down
64 changes: 52 additions & 12 deletions src/main/java/org/chenliang/oggus/opus/OpusPacket.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,38 @@
import java.util.List;

/**
* An Opus packet that described in <a href=https://tools.ietf.org/html/rfc6716>RFC6716</a>.
* An Opus packet that described in <a href=https://tools.ietf.org/html/rfc6716>RFC6716</a>. An Opus packet binary
* always begins with a TOC byte as follows:
*
* <pre>
* 0 1 2 3 4 5 6 7
* +-+-+-+-+-+-+-+-+
* | config |s| c |
* +-+-+-+-+-+-+-+-+
* </pre>
* <p>
* This Class is the abstract class to represent a Opus packet. Based on the frame count defined in the TOC byte,
* 4 concrete classes are defined:
* <ul>
* <li>{@link CodeZeroPacket}</li>
* <li>{@link CodeOnePacket}</li>
* <li>{@link CodeTwoPacket}</li>
* <li>{@link CodeThreePacket}</li>
* </ul>
* <p>
* Users don't care these concrete classes, they just use {@link OpusPackets} factory methods to create OpusPacket
* objects.
*/
public abstract class OpusPacket {
protected Config config;
protected Channel channel;
protected final List<byte[]> frames = new LinkedList<>();

/**
* Add one frame to this Opus packet.
* Add a frame to this Opus packet.
*
* <p>It will throw exception if the number of frames is over the allowed frame count, or a different length of
* frameData is added to a CBR Opus packet.</p>
*
* @param frameData the binary data byte array of a frame
*/
Expand Down Expand Up @@ -61,33 +84,50 @@ public List<byte[]> getFrames() {
*/
public abstract int getCode();

public abstract boolean isVbr();

public abstract boolean hasPadding();

/**
* @return the allowed frame count in this Opus packet
*/
public abstract int getFrameCount();

public abstract int getPadLenBytesSum();
public abstract void setFrameCount(int frameCount);

public int getPadDataLen() {
return (getPadLenBytesSum() / 255) * 254 + getPadLenBytesSum() % 255;
}
/**
* @return {@code true} if this packet is variable bitrate
*/
public abstract boolean isVbr();

public abstract void setVbr(boolean isVbr);

/**
* Only {@link CodeThreePacket} may have padding.
*
* @return {@code true} if packet has padding
*/
public abstract boolean hasPadding();

public abstract void setHasPadding(boolean hasPadding);

public abstract void setFrameCount(int frameCount);
public abstract int getPadLenBytesSum();

/**
* @param padLenBytesSum the sum of bytes that represent the padding length
*/
public abstract void setPadLenBytesSum(int padLenBytesSum);

/**
* @return the length of binary bytes that are padded at the last of this Opus packet
*/
public int getPadDataLen() {
return (getPadLenBytesSum() / 255) * 254 + getPadLenBytesSum() % 255;
}

/**
* Dump Opus packet to standard binary.
*/
public abstract byte[] dumpToStandardFormat();

/**
* Dump Opus packet to self delimited binary.
* Dump Opus packet to self delimiting binary.
*/
public abstract byte[] dumpToSelfDelimitingFormat();

Expand Down
11 changes: 8 additions & 3 deletions src/main/java/org/chenliang/oggus/opus/OpusPackets.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
import java.util.ArrayList;
import java.util.List;

/**
* Factory methods for creating {@link OpusPacket}, or parsing {@link OpusPacket} from binary data.
*/
public class OpusPackets {
/**
* Create a {@code OpusPacket} with given {@code config}, {@code channel} and {@code code}, see
* Create an empty {@code OpusPacket} with given {@code config}, {@code channel} and {@code code}, see
* <a href=https://tools.ietf.org/html/rfc6716#section-3.2>RFC6716 Section-3.2</a>.
*
* @param config the config from 0 ~ 31
Expand All @@ -23,9 +26,10 @@ public static OpusPacket newPacket(Config config, Channel channel, int code) {
}

/**
* Create empty {@code OpusPacket} from TOC byte.
* Create an empty {@code OpusPacket} from TOC byte.
*
* @param toc the TOC byte
* @return the OpusPacket object
*/
public static OpusPacket newPacketOfToc(int toc) {
int code = toc & 0x03;
Expand All @@ -35,7 +39,8 @@ public static OpusPacket newPacketOfToc(int toc) {
}

/**
* Parse Opus packets from the binary data. The first {@code (streamCount - 1)} packets must be in
* Parse Opus packets from the binary data that contains {@code streamCount} packets. The first
* {@code (streamCount - 1)} packets must be in
* <a href="https://tools.ietf.org/html/rfc6716#appendix-B">self-delimiting format</a> format. The last packet
* must be in <a href=https://tools.ietf.org/html/rfc6716#section-3.2>standard Opus packet format</a>.
*
Expand Down

0 comments on commit 810c64d

Please sign in to comment.