Skip to content

Commit

Permalink
Merge pull request #7 from umjammer/0.8.10
Browse files Browse the repository at this point in the history
0.8.10
  • Loading branch information
umjammer authored Jun 2, 2023
2 parents 9116064 + 39abad2 commit 2f2d248
Show file tree
Hide file tree
Showing 172 changed files with 4,380 additions and 4,171 deletions.
47 changes: 34 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,42 @@
[![Release](https://jitpack.io/v/umjammer/JAADec.svg)](https://jitpack.io/#umjammer/JAADec)
[![Java CI with Maven](https://github.com/umjammer/JAADec/actions/workflows/maven.yml/badge.svg)](https://github.com/umjammer/JAADec/actions/workflows/maven.yml)
[![CodeQL](https://github.com/umjammer/JAADec/actions/workflows/codeql.yml/badge.svg)](https://github.com/umjammer/JAADec/actions/workflows/codeql.yml)
[![Release](https://jitpack.io/v/umjammer/vavi-sound-aac.svg)](https://jitpack.io/#umjammer/vavi-sound-aac)
[![Java CI with Maven](https://github.com/umjammer/vavi-sound-aac/actions/workflows/maven.yml/badge.svg)](https://github.com/umjammer/vavi-sound-aac/actions/workflows/maven.yml)
[![CodeQL](https://github.com/umjammer/vavi-sound-aac/actions/workflows/codeql.yml/badge.svg)](https://github.com/umjammer/vavi-sound-aac/actions/workflows/codeql.yml)
![Java](https://img.shields.io/badge/Java-8-b07219)
[![Parent](https://img.shields.io/badge/Parent-vavi--sound--sandbox-pink)](https://github.com/umjammer/vavi-sound-sandbox)

# vavi-sound-aac

Pure Java AAC decoder (Java Sound SPI)

<img src="https://github.com/umjammer/vavi-image-avif/assets/493908/58a132fd-ba3d-4309-9481-2b86fc885f14" width="160" alt="AAC logo"/><sub><a href="https://www.dolby.com/">© Dolby Laboratories, Inc.</a></sub>

## Install

* https://jitpack.io/#/umjammer/vavi-sound-aac

## Usage

```java
AudioInputStream ais = AudioSystem.getAudioInputStream(Files.newInputStream(Paths.get(m4a)));
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new AudioFormat(44100, 16, 2, true, false), ais));
clip.loop(Clip.LOOP_CONTINUOUSLY);
```

## TODO

* ~~rename project into vavi-sound-aac~~
* patches
* ~~https://github.com/Tianscar/jaac/commit/cf9b24f55fcd8f77ae76c42cac87602fdb0382a8~~
* ~~https://github.com/Tianscar/jaac/commit/bbaaec277d6620e0233561d02185f2e901970480~~

---

## Original

# JAADec

**This is a fork of https://sourceforge.net/projects/jaadec/
**This is a fork of https://sourceforge.net/projects/vavi-sound-aac/
containing fixes to make it play nice with other Java Sound Providers.**

The original project was licensed under Public Domain
Expand All @@ -16,12 +46,3 @@ JAAD is an AAC decoder and MP4 demultiplexer library written completely in Java.
It uses no native libraries, is platform-independent and portable.
It can read MP4 container from almost every input-stream (files, network sockets etc.)
and decode AAC-LC (Low Complexity) and HE-AAC (High Efficiency/AAC+).

## Install

* https://jitpack.io/#/umjammer/JAADec

## Applied Patches

* https://github.com/Tianscar/jaac/commit/cf9b24f55fcd8f77ae76c42cac87602fdb0382a8
* https://github.com/Tianscar/jaac/commit/bbaaec277d6620e0233561d02185f2e901970480
19 changes: 9 additions & 10 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<groupId>net.sourceforge.jaadec</groupId>
<artifactId>jaad</artifactId>
<version>0.8.9</version>
<groupId>vavi</groupId>
<artifactId>vavi-sound-aac</artifactId>
<version>0.8.10</version>

<description>JAAD is an AAC decoder and MP4 demultiplexer library written completely in Java. It uses no native libraries, is platform-independent and portable. It can read MP4 container from almost every input-stream (files, network sockets etc.) and decode AAC-LC (Low Complexity) and HE-AAC (High Efficiency/AAC+).</description>
<url>https://github.com/umjammer/JAADec</url>
<description>vavi-sound-aac is an AAC decoder and MP4 demultiplexer library written completely in Java. It uses no native libraries, is platform-independent and portable. It can read MP4 container from almost every input-stream (files, network sockets etc.) and decode AAC-LC (Low Complexity) and HE-AAC (High Efficiency/AAC+).</description>
<url>https://github.com/umjammer/vavi-sound-aac</url>
<licenses>
<license>
<name>Public Domain</name>
Expand All @@ -33,9 +33,9 @@
</developer>
</developers>
<scm>
<connection>scm:git:[email protected]:umjammer/JAADec.git</connection>
<developerConnection>scm:git:[email protected]:umjammer/JAADec.git</developerConnection>
<url>scm:git:[email protected]:umjammer/JAADec.git</url>
<connection>scm:git:[email protected]:umjammer/vavi-sound-aac.git</connection>
<developerConnection>scm:git:[email protected]:umjammer/vavi-sound-aac.git</developerConnection>
<url>scm:git:[email protected]:umjammer/vavi-sound-aac.git</url>
</scm>

<build>
Expand Down Expand Up @@ -77,7 +77,7 @@
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.9.2</version>
<version>5.9.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand All @@ -89,7 +89,6 @@
<groupId>com.github.umjammer</groupId>
<artifactId>vavi-sound</artifactId>
<version>1.0.15</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>commons-beanutils</groupId>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/sourceforge/jaad/MP4Info.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public static void main(String[] args) {
}
}

//print all boxes
// print all boxes
if (boxes) {
System.out.println("================================");
for (Box box : cont.getBoxes()) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/sourceforge/jaad/Play.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ private static void decodeMP4(MP4Input in) throws Exception {
DecoderConfig conf = dec.getConfig();
AudioFormat aufmt = new AudioFormat(conf.getOutputFrequency().getFrequency(), 16, conf.getChannelCount(), true, true);

try (SourceDataLine line = AudioSystem.getSourceDataLine(aufmt)) {
try (SourceDataLine line = AudioSystem.getSourceDataLine(aufmt)) {
line.open();
line.start();

Expand Down
3 changes: 1 addition & 2 deletions src/main/java/net/sourceforge/jaad/Radio.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ private static void decode(String arg) throws Exception {
String x;
do {
x = in.readLine();
}
while (x != null && !x.trim().equals(""));
} while (x != null && !x.trim().equals(""));

ADTSDemultiplexer adts = new ADTSDemultiplexer(in);
AudioFormat aufmt = new AudioFormat(adts.getSampleFrequency(), 16, adts.getChannelCount(), true, true);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/net/sourceforge/jaad/SampleBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ public void setData(byte[] data, int sampleRate, int channels, int bitsPerSample
length = 0;
bitrate = 0;
} else {
int bytesPerSample = bitsPerSample / 8; //usually 2
int samplesPerChannel = data.length / (bytesPerSample * channels); //=1024
int bytesPerSample = bitsPerSample / 8; // usually 2
int samplesPerChannel = data.length / (bytesPerSample * channels); // =1024
length = (double) samplesPerChannel / (double) sampleRate;
bitrate = (double) (samplesPerChannel * bitsPerSample * channels) / length;
}
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/net/sourceforge/jaad/aac/Decoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class Decoder {

private final DecoderConfig config;
private final SyntacticElements syntacticElements;
public int frames=0;
public int frames = 0;
private ADIFHeader adifHeader;

/**
Expand Down Expand Up @@ -52,7 +52,7 @@ public static Decoder create(AudioDecoderInfo info) {
}

public static Decoder create(DecoderConfig config) {
if(config==null)
if (config == null)
throw new IllegalArgumentException("illegal MP4 decoder specific info");
return new Decoder(config);
}
Expand All @@ -73,9 +73,9 @@ public Decoder(DecoderConfig config) {

syntacticElements = new SyntacticElements(config);

LOGGER.log(Level.FINE, "profile: {0}", config.getProfile());
LOGGER.log(Level.FINE, "sf: {0}", config.getSampleFrequency().getFrequency());
LOGGER.log(Level.FINE, "channels: {0}", config.getChannelConfiguration().getDescription());
LOGGER.log(Level.FINER, "profile: {0}", config.getProfile());
LOGGER.log(Level.FINER, "sf: {0}", config.getSampleFrequency() != null ? config.getSampleFrequency().getFrequency() : null);
LOGGER.log(Level.FINER, "channels: {0}", config.getChannelConfiguration().getDescription());
}

public DecoderConfig getConfig() {
Expand All @@ -95,11 +95,11 @@ public void decodeFrame(byte[] frame, SampleBuffer buffer) throws AACException {
BitStream in = BitStream.open(frame);

try {
LOGGER.log(Level.FINE, () -> String.format("frame %d @%d", frames, 8 * frame.length));
LOGGER.log(Level.FINER, () -> String.format("frame %d @%d", frames, 8 * frame.length));
decode(in, buffer);
LOGGER.log(Level.FINEST, () -> String.format("left %d", in.getBitsLeft()));
} catch (EOSException e) {
LOGGER.log(Level.WARNING,"unexpected end of frame",e);
LOGGER.log(Level.WARNING, "unexpected end of frame", e);
} finally {
++frames;
}
Expand Down
35 changes: 19 additions & 16 deletions src/main/java/net/sourceforge/jaad/aac/DecoderConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ public class DecoderConfig {
// extension: SBR
private final boolean sbrEnabled;
private boolean sbrPresent = false;
// in case of SBR this may be twice the SampleFrequency.
// it remains null without SBR
/**
* in case of SBR this may be twice the SampleFrequency.
* it remains null without SBR
*/
private SampleRate outputFrequency;

private boolean psEnabled = true;
Expand All @@ -43,6 +45,7 @@ public PS openPS(SBR sbr) {
}

// extension: error resilience

private boolean sectionDataResilience = false, scalefactorResilience = false, spectralDataResilience = false;

DecoderConfig(boolean sbrEnabled) {
Expand All @@ -53,7 +56,8 @@ public PS openPS(SBR sbr) {
this(true);
}

/* ========== gets/sets ========== */
// gets/sets

public ChannelConfiguration getChannelConfiguration() {
return channelConfiguration;
}
Expand Down Expand Up @@ -94,7 +98,7 @@ public int getFrameLength() {
}

public int getSampleLength() {
int upsampled = outputFrequency!= null && sampleFrequency != outputFrequency ? 2 : 1;
int upsampled = outputFrequency != null && sampleFrequency != outputFrequency ? 2 : 1;
return upsampled * getFrameLength();
}

Expand Down Expand Up @@ -131,7 +135,7 @@ public int getChannelCount() {
return channelConfiguration.getChannelCount();
}

//=========== SBR =============
// SBR ----

/**
* Setup SBR and try to duplicate the output frequency if possible.
Expand Down Expand Up @@ -163,7 +167,7 @@ public boolean isPSEnabled() {
return psEnabled;
}

//=========== ER =============
// ER ----

public boolean isScalefactorResilienceUsed() {
return scalefactorResilience;
Expand All @@ -177,8 +181,7 @@ public boolean isSpectralDataResilienceUsed() {
return spectralDataResilience;
}

/* ======== static builder ========= */

/** static builder */
public static DecoderConfig create(AudioDecoderInfo info) {
return new DecoderConfig().setAudioDecoderInfo(info);
}
Expand Down Expand Up @@ -223,10 +226,10 @@ public DecoderConfig decode(BitStream in) {
case ER_AAC_LC:
case ER_AAC_LTP:
case ER_AAC_LD:
//ga-specific info:
// ga-specific info:
frameLengthFlag = in.readBool();
if (frameLengthFlag)
throw new AACException("config uses 960-sample frames, not yet supported"); //TODO: are 960-frames working yet?
throw new AACException("config uses 960-sample frames, not yet supported"); // TODO: are 960-frames working yet?

dependsOnCoreCoder = in.readBool();

Expand All @@ -243,13 +246,13 @@ public DecoderConfig decode(BitStream in) {
scalefactorResilience = in.readBool();
spectralDataResilience = in.readBool();
}
//extensionFlag3
// extensionFlag3
in.skipBit();
}

if (channelConfiguration == ChannelConfiguration.NONE) {
//TODO: is this working correct? -> ISO 14496-3 part 1: 1.A.4.3
//in.skipBits(3); //PCE
// TODO: is this working correct? -> ISO 14496-3 part 1: 1.A.4.3
// in.skipBits(3); // PCE
PCE pce = PCE.read(in);
setAudioDecoderInfo(pce);
}
Expand All @@ -265,9 +268,9 @@ public DecoderConfig decode(BitStream in) {

// expect implicit SBR for low frequencies
// see 4.6.18.2.6
// if(sbrEnabled && !sbrPresent && sampleFrequency.duplicated() != SF_NONE) {
// setSBRPresent();
// }
// if (sbrEnabled && !sbrPresent && sampleFrequency.duplicated() != SF_NONE) {
// setSBRPresent();
// }

return this;
}
Expand Down
1 change: 1 addition & 0 deletions src/main/java/net/sourceforge/jaad/aac/Profile.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public enum Profile {
/**
* Returns a profile instance for the given index. If the index is not
* between 1 and 23 inclusive, UNKNOWN is returned.
*
* @return a profile with the given index
*/
public static Profile forInt(int i) {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/net/sourceforge/jaad/aac/Receiver.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.List;


/**
* Created by IntelliJ IDEA.
* User: stueken
Expand Down
18 changes: 11 additions & 7 deletions src/main/java/net/sourceforge/jaad/aac/SampleFrequency.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public SampleFrequency getNominal() {
return SampleFrequency.this;
}

@Override
public SampleRate duplicated() {
SampleFrequency duplicate = SampleFrequency.this.duplicated();
return duplicate == SF_NONE ? SF_NONE : duplicate.forFrequency(2 * frequency);
Expand All @@ -80,17 +81,17 @@ public static SampleFrequency nominalFrequency(int freq) {
float d = sf.getDeviationTo(freq);

// direct match
if(d==0)
if (d == 0)
return sf;

// better match
if(d<dev) {
if (d < dev) {
result = sf;
dev = d;
}

// no better match to be expected as in decreasing order
if(sf.frequency<freq)
if (sf.frequency < freq)
break;
}

Expand All @@ -100,13 +101,14 @@ public static SampleFrequency nominalFrequency(int freq) {
private final int index, frequency;
private final int[] prediction, maxTNS_SFB;

SampleFrequency(int index, int freqency, int[] prediction, int[] maxTNS_SFB) {
SampleFrequency(int index, int frequency, int[] prediction, int[] maxTNS_SFB) {
this.index = index;
this.frequency = freqency;
this.frequency = frequency;
this.prediction = prediction;
this.maxTNS_SFB = maxTNS_SFB;
}

@Override
public SampleFrequency getNominal() {
return this;
}
Expand All @@ -132,22 +134,24 @@ public int getIndex() {
*
* @return the sample frequency
*/
@Override
public int getFrequency() {
return frequency;
}

@Override
public SampleFrequency duplicated() {
return index<3 ? SF_NONE : TABLE.get(index-3);
return index < 3 ? SF_NONE : TABLE.get(index - 3);
}

/**
* Return the relative deviation of a given frequency compared to this nominal frequency.
*
* @param frequency to compare.
* @return relative deviation.
*/
public float getDeviationTo(int frequency) {
return ((float)frequency - this.frequency) / this.frequency;
return ((float) frequency - this.frequency) / this.frequency;
}

/**
Expand Down
Loading

0 comments on commit 2f2d248

Please sign in to comment.