Skip to content

Commit

Permalink
Merge pull request #1 from umjammer/1.9.7
Browse files Browse the repository at this point in the history
1.9.7
  • Loading branch information
umjammer authored Jun 25, 2020
2 parents 8802cb3 + 0ce2d27 commit 420da24
Show file tree
Hide file tree
Showing 12 changed files with 390 additions and 433 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven

name: Java CI with Maven

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
build:

runs-on: macos-latest

steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Maven
run: mvn -B package --file pom.xml
24 changes: 14 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[![Release](https://jitpack.io/v/umjammer/mp3spi.svg)](https://jitpack.io/#umjammer/mp3spi) [![Parent](https://img.shields.io/badge/Parent-vavi--sound--sandbox-pink)](https://github.com/umjammer/vavi-sound-sandbox)
[![Release](https://jitpack.io/v/umjammer/mp3spi.svg)](https://jitpack.io/#umjammer/mp3spi) [![Java CI with Maven](https://github.com/umjammer/mp3spi/workflows/Java%20CI%20with%20Maven/badge.svg)](https://github.com/umjammer/mp3spi/actions) [![Parent](https://img.shields.io/badge/Parent-vavi--sound--sandbox-pink)](https://github.com/umjammer/vavi-sound-sandbox)

# MP3SPI

Expand All @@ -16,8 +16,8 @@

MP3SPI is a SPI (Service Provider Interface) that adds MP3 support for JavaSound.
It allows to play MPEG 1/2/2.5 Layer 1/2/3 files thanks to underlying JLayer
and Tritonus libraries. This is a non-commercial project and anyone can add his
contribution. MP3SPI is licensed under LGPL (see LICENSE.txt).
and Tritonus libraries. This is a non-commercial project and anyone can add his
contribution. MP3SPI is licensed under LGPL (see [LICENSE.txt](LICENSE.txt)).


## FAQ
Expand All @@ -42,7 +42,7 @@ contribution. MP3SPI is licensed under LGPL (see LICENSE.txt).

### Does MP3SPI support VBR ?

Yes, It supports XING and VBRI VBR header too.
Yes, It supports XING and VBRI VBR header too.

### How to get ID3v2 tags from MP3SPI API ?

Expand All @@ -64,17 +64,19 @@ contribution. MP3SPI is licensed under LGPL (see LICENSE.txt).

Here are our benchmark notes :

* Heap use range : 1380KB to 1900KB - 370 classes loaded.
* Heap use range : 1380KB to 1900KB - 370 classes loaded.
* Footprint :

| ~8MB |under WinNT4/Win2K + J2SE 1.3 (Hotspot) |
|memory|environment|
|---|---|
| ~8MB |under WinNT4/Win2K + J2SE 1.3 (Hotspot) |
| ~10MB |under WinNT4/Win2K + J2SE 1.4.1 (Hotspot) |

* CPU usage :

| ~12%| under PIII 800Mhz/WinNT4+J2SE 1.3 (Hotspot) |
|cpu|environment|
|---|---|
| ~12%| under PIII 800Mhz/WinNT4+J2SE 1.3 (Hotspot) |
| ~8% | under PIII 1Ghz/Win2K+J2SE 1.3.1 (Hotspot) |
| ~12% | under PIII 1Ghz/Win2K+J2SE 1.4.1 (Hotspot) |
| ~1% | under PIII 1Ghz/Win2K+J2SE 1.5.0 (Hotspot) |
Expand All @@ -91,10 +93,12 @@ contribution. MP3SPI is licensed under LGPL (see LICENSE.txt).

## KNOWN PROBLEMS

99% of MP3 plays well with JLayer but some (1%) return an `ArrayIndexOutOfBoundsException`
while playing. It might come from invalid audio frames.
99% of MP3 plays well with JLayer but some (1%) return an `ArrayIndexOutOfBoundsException`
while playing. It might come from invalid audio frames.

When source is not a file, this cannot deal id3v1 tag which file size is larger than 20M bytes.

### Workaround

Just `try`/`catch` `ArrayIndexOutOfBoundsException` in your code to skip
Just `try`/`catch` `ArrayIndexOutOfBoundsException` in your code to skip
non-detected invalid frames.
113 changes: 0 additions & 113 deletions build.xml

This file was deleted.

28 changes: 15 additions & 13 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@

<groupId>net.javazoom</groupId>
<artifactId>mp3spi</artifactId>
<version>1.9.6</version>
<version>1.9.7</version>

<properties>
<tritonus.groupId>com.github.umjammer.tritonus</tritonus.groupId>
<tritonus.version>0.3.8</tritonus.version>
</properties>

<build>
<plugins>
Expand All @@ -17,14 +22,11 @@
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
<version>3.0.0-M4</version>
<configuration>
<argLine>-Djava.util.logging.config.file=${project.build.testOutputDirectory}/logging.properties</argLine>
<trimStackTrace>false</trimStackTrace>
</configuration>
</plugin>
</plugins>
</build>
Expand All @@ -38,14 +40,14 @@

<dependencies>
<dependency>
<groupId>com.github.umjammer.tritonus</groupId>
<groupId>${tritonus.groupId}</groupId>
<artifactId>tritonus-share</artifactId>
<version>0.3.7-SNAPSHOT</version>
<version>${tritonus.version}</version>
</dependency>
<dependency>
<groupId>com.github.umjammer.tritonus</groupId>
<groupId>${tritonus.groupId}</groupId>
<artifactId>tritonus-remaining</artifactId>
<version>0.3.7-SNAPSHOT</version>
<version>${tritonus.version}</version>
</dependency>
<dependency>
<groupId>com.github.umjammer</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public class MpegAudioFileReader extends TAudioFileReader
{ MpegEncoding.MPEG2L1, MpegEncoding.MPEG2L2, MpegEncoding.MPEG2L3 },
{ MpegEncoding.MPEG1L1, MpegEncoding.MPEG1L2, MpegEncoding.MPEG1L3 },
{ MpegEncoding.MPEG2DOT5L1, MpegEncoding.MPEG2DOT5L2, MpegEncoding.MPEG2DOT5L3 }, };
public static final int INITAL_READ_LENGTH = 128000 * 4; // TODO a tag larger than this length causes an exception
public static final int INITAL_READ_LENGTH = 1024 * 1024 * 20; // TODO limitation
private static final int MARK_LIMIT = INITAL_READ_LENGTH + 1;

private static final String[] id3v1genres = {
Expand Down Expand Up @@ -357,6 +357,7 @@ else if (((head[0] == 'O') | (head[0] == 'o')) && ((head[1] == 'G') | (head[1] =
// MPEG header info.
int nVersion = AudioSystem.NOT_SPECIFIED;
int nLayer = AudioSystem.NOT_SPECIFIED;
@SuppressWarnings("unused")
int nSFIndex = AudioSystem.NOT_SPECIFIED;
int nMode = AudioSystem.NOT_SPECIFIED;
int FrameSize = AudioSystem.NOT_SPECIFIED;
Expand All @@ -373,7 +374,7 @@ else if (((head[0] == 'O') | (head[0] == 'o')) && ((head[1] == 'G') | (head[1] =
try
{
Bitstream m_bitstream = new Bitstream(pis);
aff_properties.put("mp3.header.pos", new Integer(m_bitstream.header_pos()));
aff_properties.put("mp3.header.pos", m_bitstream.header_pos());
Header m_header = m_bitstream.readFrame();
// nVersion = 0 => MPEG2-LSF (Including MPEG2.5), nVersion = 1 => MPEG1
nVersion = m_header.version();
Expand All @@ -384,42 +385,42 @@ else if (((head[0] == 'O') | (head[0] == 'o')) && ((head[1] == 'G') | (head[1] =
aff_properties.put("mp3.version.layer", Integer.toString(nLayer));
nSFIndex = m_header.sample_frequency();
nMode = m_header.mode();
aff_properties.put("mp3.mode", new Integer(nMode));
aff_properties.put("mp3.mode", nMode);
nChannels = nMode == 3 ? 1 : 2;
aff_properties.put("mp3.channels", new Integer(nChannels));
aff_properties.put("mp3.channels", nChannels);
nVBR = m_header.vbr();
af_properties.put("vbr", new Boolean(nVBR));
aff_properties.put("mp3.vbr", new Boolean(nVBR));
aff_properties.put("mp3.vbr.scale", new Integer(m_header.vbr_scale()));
af_properties.put("vbr", nVBR);
aff_properties.put("mp3.vbr", nVBR);
aff_properties.put("mp3.vbr.scale", m_header.vbr_scale());
FrameSize = m_header.calculate_framesize();
aff_properties.put("mp3.framesize.bytes", new Integer(FrameSize));
aff_properties.put("mp3.framesize.bytes", FrameSize);
if (FrameSize < 0) throw new UnsupportedAudioFileException("Invalid FrameSize : " + FrameSize);
nFrequency = m_header.frequency();
aff_properties.put("mp3.frequency.hz", new Integer(nFrequency));
aff_properties.put("mp3.frequency.hz", nFrequency);
FrameRate = (float) ((1.0 / (m_header.ms_per_frame())) * 1000.0);
aff_properties.put("mp3.framerate.fps", new Float(FrameRate));
aff_properties.put("mp3.framerate.fps", FrameRate);
if (FrameRate < 0) throw new UnsupportedAudioFileException("Invalid FrameRate : " + FrameRate);
if (mLength != AudioSystem.NOT_SPECIFIED)
{
aff_properties.put("mp3.length.bytes", new Integer(mLength));
aff_properties.put("mp3.length.bytes", mLength);
nTotalFrames = m_header.max_number_of_frames(mLength);
aff_properties.put("mp3.length.frames", new Integer(nTotalFrames));
aff_properties.put("mp3.length.frames", nTotalFrames);
}
BitRate = m_header.bitrate();
af_properties.put("bitrate", new Integer(BitRate));
aff_properties.put("mp3.bitrate.nominal.bps", new Integer(BitRate));
af_properties.put("bitrate", BitRate);
aff_properties.put("mp3.bitrate.nominal.bps", BitRate);
nHeader = m_header.getSyncHeader();
encoding = sm_aEncodings[nVersion][nLayer - 1];
aff_properties.put("mp3.version.encoding", encoding.toString());
if (mLength != AudioSystem.NOT_SPECIFIED)
{
nTotalMS = Math.round(m_header.total_ms(mLength));
aff_properties.put("duration", new Long(nTotalMS * 1000L));
aff_properties.put("duration", nTotalMS * 1000L);
}
aff_properties.put("mp3.copyright", new Boolean(m_header.copyright()));
aff_properties.put("mp3.original", new Boolean(m_header.original()));
aff_properties.put("mp3.crc", new Boolean(m_header.checksums()));
aff_properties.put("mp3.padding", new Boolean(m_header.padding()));
aff_properties.put("mp3.copyright", m_header.copyright());
aff_properties.put("mp3.original", m_header.original());
aff_properties.put("mp3.crc", m_header.checksums());
aff_properties.put("mp3.padding", m_header.padding());
InputStream id3v2 = m_bitstream.getRawID3v2();
if (id3v2 != null)
{
Expand Down Expand Up @@ -451,12 +452,33 @@ else if (((head[0] == 'O') | (head[0] == 'o')) && ((head[1] == 'G') | (head[1] =
{
FileInputStream fis = (FileInputStream) inputStream;
byte[] id3v1 = new byte[128];
@SuppressWarnings("unused")
long bytesSkipped = fis.skip(inputStream.available() - id3v1.length);
@SuppressWarnings("unused")
int read = fis.read(id3v1, 0, id3v1.length);
if ((id3v1[0] == 'T') && (id3v1[1] == 'A') && (id3v1[2] == 'G'))
{
parseID3v1Frames(id3v1, aff_properties);
}
} else {
if (TDebug.TraceAudioFileReader) TDebug.out("unknown size, maybe not a file: " + inputStream.available());
if (inputStream.available() <= INITAL_READ_LENGTH) {
InputStream is = new BufferedInputStream(inputStream, inputStream.available());
byte[] id3v1 = new byte[128];
is.mark(inputStream.available());
@SuppressWarnings("unused")
long bytesSkipped = is.skip(inputStream.available() - id3v1.length);
@SuppressWarnings("unused")
int read = is.read(id3v1, 0, id3v1.length);
// is.reset();
if (TDebug.TraceAudioFileReader) TDebug.out((char) id3v1[0] + ", " + (char) id3v1[1] + ", " + (char) id3v1[2]);
if ((id3v1[0] == 'T') && (id3v1[1] == 'A') && (id3v1[2] == 'G'))
{
parseID3v1Frames(id3v1, aff_properties);
}
} else {
if (TDebug.TraceAudioFileReader) TDebug.out("larger than limit 20MB, skip id3v1");
}
}
AudioFormat format = new MpegAudioFormat(encoding, nFrequency, AudioSystem.NOT_SPECIFIED // SampleSizeInBits - The size of a sample
, nChannels // Channels - The number of channels
Expand Down Expand Up @@ -565,6 +587,8 @@ public AudioInputStream getAudioInputStream(InputStream inputStream) throws Unsu
{
if (TDebug.TraceAudioFileReader) TDebug.out("MpegAudioFileReader.getAudioInputStream(InputStream inputStream)");
if (!inputStream.markSupported()) inputStream = new BufferedInputStream(inputStream);
if (TDebug.TraceAudioFileReader) TDebug.out("available/limit: " + inputStream.available() + ", " + getMarkLimit());
setMarkLimit(Math.min(inputStream.available(), getMarkLimit()));
return super.getAudioInputStream(inputStream);
}

Expand Down Expand Up @@ -610,6 +634,7 @@ protected void parseID3v1Frames(byte[] frames, Map<String, Object> props)
* @param end
* @return
*/
@SuppressWarnings("unused")
private String chopSubstring(String s, int start, int end)
{
String str = null;
Expand Down
Loading

0 comments on commit 420da24

Please sign in to comment.