diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
new file mode 100644
index 0000000..77431ec
--- /dev/null
+++ b/.github/workflows/maven.yml
@@ -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
diff --git a/README.md b/README.md
index 38cfe62..b41737a 100644
--- a/README.md
+++ b/README.md
@@ -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
@@ -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
@@ -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 ?
@@ -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) |
@@ -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.
diff --git a/build.xml b/build.xml
deleted file mode 100644
index ee70b0f..0000000
--- a/build.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/pom.xml b/pom.xml
index 3b7a6e7..bc2e395 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,12 @@
net.javazoom
mp3spi
- 1.9.6
+ 1.9.7
+
+
+ com.github.umjammer.tritonus
+ 0.3.8
+
@@ -17,14 +22,11 @@
maven-surefire-plugin
- 2.22.0
-
-
- org.junit.platform
- junit-platform-surefire-provider
- 1.1.0
-
-
+ 3.0.0-M4
+
+ -Djava.util.logging.config.file=${project.build.testOutputDirectory}/logging.properties
+ false
+
@@ -38,14 +40,14 @@
- com.github.umjammer.tritonus
+ ${tritonus.groupId}
tritonus-share
- 0.3.7-SNAPSHOT
+ ${tritonus.version}
- com.github.umjammer.tritonus
+ ${tritonus.groupId}
tritonus-remaining
- 0.3.7-SNAPSHOT
+ ${tritonus.version}
com.github.umjammer
diff --git a/src/main/java/javazoom/spi/mpeg/sampled/file/MpegAudioFileReader.java b/src/main/java/javazoom/spi/mpeg/sampled/file/MpegAudioFileReader.java
index 20c4229..339a842 100644
--- a/src/main/java/javazoom/spi/mpeg/sampled/file/MpegAudioFileReader.java
+++ b/src/main/java/javazoom/spi/mpeg/sampled/file/MpegAudioFileReader.java
@@ -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 = {
@@ -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;
@@ -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();
@@ -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)
{
@@ -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
@@ -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);
}
@@ -610,6 +634,7 @@ protected void parseID3v1Frames(byte[] frames, Map props)
* @param end
* @return
*/
+ @SuppressWarnings("unused")
private String chopSubstring(String s, int start, int end)
{
String str = null;
diff --git a/src/test/java/PlayerTest.java b/src/test/java/PlayerTest.java
index e3f2b54..844d3d9 100644
--- a/src/test/java/PlayerTest.java
+++ b/src/test/java/PlayerTest.java
@@ -20,8 +20,8 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.io.PrintStream;
import java.util.Properties;
+import java.util.logging.Logger;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
@@ -34,6 +34,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -52,7 +53,7 @@ public class PlayerTest {
private String filename = null;
private String name = null;
private Properties props = null;
- private PrintStream out = null;
+ private Logger out;
@BeforeEach
protected void setUp() throws Exception {
@@ -62,9 +63,10 @@ protected void setUp() throws Exception {
basefile = props.getProperty("basefile");
name = props.getProperty("filename");
filename = basefile + name;
- out = System.out;
+ out = Logger.getLogger(PlayerTest.class.getName());
}
+ @Test
@Disabled
public void testPlay0() throws Exception {
AudioInputStream in = AudioSystem.getAudioInputStream(new File(filename));
@@ -80,45 +82,38 @@ public void testPlay0() throws Exception {
rawplay(decodedFormat, din);
}
+ @Test
@Disabled
- public void testPlay() {
- try {
+ public void testPlay() throws Exception {
+ out.info("--- Start : " + filename + " ---");
+ File file = new File(filename);
+ //URL file = new URL(props.getProperty("shoutcast"));
+ AudioFileFormat aff = AudioSystem.getAudioFileFormat(file);
+ out.info("Audio Type : " + aff.getType());
+ AudioInputStream in = AudioSystem.getAudioInputStream(file);
+ AudioInputStream din = null;
+ if (in != null) {
+ AudioFormat baseFormat = in.getFormat();
+ out.info("Source Format : " + baseFormat.toString());
+ AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
+ baseFormat.getSampleRate(),
+ 16,
+ baseFormat.getChannels(),
+ baseFormat.getChannels() * 2,
+ baseFormat.getSampleRate(),
+ false);
if (out != null)
- out.println("--- Start : " + filename + " ---");
- File file = new File(filename);
- //URL file = new URL(props.getProperty("shoutcast"));
- AudioFileFormat aff = AudioSystem.getAudioFileFormat(file);
- if (out != null)
- out.println("Audio Type : " + aff.getType());
- AudioInputStream in = AudioSystem.getAudioInputStream(file);
- AudioInputStream din = null;
- if (in != null) {
- AudioFormat baseFormat = in.getFormat();
- if (out != null)
- out.println("Source Format : " + baseFormat.toString());
- AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
- baseFormat.getSampleRate(),
- 16,
- baseFormat.getChannels(),
- baseFormat.getChannels() * 2,
- baseFormat.getSampleRate(),
- false);
- if (out != null)
- out.println("Target Format : " + decodedFormat.toString());
- din = AudioSystem.getAudioInputStream(decodedFormat, in);
- if (din instanceof PropertiesContainer) {
- assertTrue(true, "PropertiesContainer : OK");
- } else {
- assertTrue(false, "Wrong PropertiesContainer instance");
- }
- rawplay(decodedFormat, din);
- in.close();
- if (out != null)
- out.println("--- Stop : " + filename + " ---");
- assertTrue(true, "testPlay : OK");
+ out.info("Target Format : " + decodedFormat.toString());
+ din = AudioSystem.getAudioInputStream(decodedFormat, in);
+ if (din instanceof PropertiesContainer) {
+ assertTrue(true, "PropertiesContainer : OK");
+ } else {
+ assertTrue(false, "Wrong PropertiesContainer instance");
}
- } catch (Exception e) {
- assertTrue(false, "testPlay : " + e.getMessage());
+ rawplay(decodedFormat, din);
+ in.close();
+ out.info("--- Stop : " + filename + " ---");
+ assertTrue(true, "testPlay : OK");
}
}
@@ -140,11 +135,11 @@ private void rawplay(AudioFormat targetFormat, AudioInputStream din) throws IOEx
gainControl.setValue(dB);
// Start
line.start();
- int nBytesRead = 0, nBytesWritten = 0;
+ int nBytesRead = 0;
while (nBytesRead != -1) {
nBytesRead = din.read(data, 0, data.length);
if (nBytesRead != -1)
- nBytesWritten = line.write(data, 0, nBytesRead);
+ line.write(data, 0, nBytesRead);
}
// Stop
line.drain();
diff --git a/src/test/java/Test3.java b/src/test/java/Test3.java
index b80d80b..835e5c4 100644
--- a/src/test/java/Test3.java
+++ b/src/test/java/Test3.java
@@ -5,6 +5,14 @@
*/
import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
@@ -16,6 +24,7 @@
import javax.sound.sampled.SourceDataLine;
import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
/**
@@ -24,11 +33,9 @@
* @author Naohide Sano (umjammer)
* @version 0.00 2012/06/11 umjammer initial version
*/
-@Disabled
-public class Test3 {
+class Test3 {
-// static final String inFile = "/Users/nsano/src/sano-n/vavi-util-tag-mp3spi/src/test/resources/test.mp3";
- static final String inFile = "/Users/nsano/Music/iTunes/iTunes Music/NAMCO/Ace Combat 04 Shattered Skies Original Sound Tracks/1-11 Blockade.mp3";
+ static final String inFile = "src/test/resources/test.mp3";
/**
* @param args
@@ -78,6 +85,35 @@ public static void main(String[] args) throws Exception {
line.drain();
line.close();
}
+
+ @Test
+ @Disabled
+ void test() throws IOException {
+ Path root = Paths.get(System.getProperty("user.home"), "Music", "iTunes", "iTunes Music");
+System.err.println("ROOT: " + Files.exists(root));
+
+ AtomicInteger count = new AtomicInteger();
+ AtomicInteger error = new AtomicInteger();
+ Files.walkFileTree(root, new SimpleFileVisitor() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attr) {
+ if (file.getFileName().toString().toLowerCase().endsWith(".mp3")) {
+//System.err.println(file);
+ count.incrementAndGet();
+ try {
+ AudioSystem.getAudioInputStream(file.toFile());
+ } catch (Exception e) {
+ try {
+System.err.println("ERROR: " + file + ", " + Files.size(file));
+ } catch (Exception f) {}
+ error.incrementAndGet();
+ }
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ });
+System.err.println("RESULT: " + error + "/" + count);
+ }
}
/* */
diff --git a/src/test/java/javazoom/spi/mpeg/sampled/file/PropertiesTest.java b/src/test/java/javazoom/spi/mpeg/sampled/file/PropertiesTest.java
index cea9386..a33eee9 100644
--- a/src/test/java/javazoom/spi/mpeg/sampled/file/PropertiesTest.java
+++ b/src/test/java/javazoom/spi/mpeg/sampled/file/PropertiesTest.java
@@ -2,26 +2,25 @@
package javazoom.spi.mpeg.sampled.file;
import java.io.File;
-import java.io.IOException;
import java.io.InputStream;
-import java.io.PrintStream;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
+import java.util.logging.Logger;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.UnsupportedAudioFileException;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.tritonus.share.sampled.TAudioFormat;
import org.tritonus.share.sampled.file.TAudioFileFormat;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
/**
@@ -30,7 +29,7 @@
* generate your own test.mp3.properties Uncomment out = System.out; in setUp()
* method to generated it on stdout from your own MP3 file.
*/
-public class PropertiesTest {
+class PropertiesTest {
private String basefile = null;
private String baseurl = null;
@@ -38,227 +37,182 @@ public class PropertiesTest {
private String fileurl = null;
private String name = null;
private Properties props = null;
- private PrintStream out = null;
+ private Logger logger;
@BeforeEach
- protected void setUp() throws Exception {
+ void setUp() throws Exception {
props = new Properties();
InputStream pin = getClass().getClassLoader().getResourceAsStream("test.mp3.properties");
props.load(pin);
basefile = props.getProperty("basefile");
- baseurl = props.getProperty("baseurl");
+ baseurl = props.getProperty("baseurl").replaceAll("\\$\\{PWD\\}", System.getProperty("user.dir"));
name = props.getProperty("filename");
filename = basefile + name;
fileurl = baseurl + name;
- out = System.out;
+ logger = Logger.getLogger(PropertiesTest.class.getName());
}
@Test
- public void testPropertiesFile() {
- String[] testPropsAFF = {
+ void testPropertiesFile() throws Exception {
+ final String[] testPropsAFF = {
"duration", "title", "author", "album", "date", "comment", "copyright", "mp3.framerate.fps", "mp3.copyright",
"mp3.padding", "mp3.original", "mp3.length.bytes", "mp3.frequency.hz", "mp3.length.frames", "mp3.mode",
"mp3.channels", "mp3.version.mpeg", "mp3.framesize.bytes", "mp3.vbr.scale", "mp3.version.encoding",
"mp3.header.pos", "mp3.version.layer", "mp3.crc"
};
- String[] testPropsAF = {
+ final String[] testPropsAF = {
"vbr", "bitrate"
};
File file = new File(filename);
- AudioFileFormat baseFileFormat = null;
- AudioFormat baseFormat = null;
- try {
- baseFileFormat = AudioSystem.getAudioFileFormat(file);
- baseFormat = baseFileFormat.getFormat();
- if (out != null)
- out.println("-> Filename : " + filename + " <-");
- if (out != null)
- out.println(baseFileFormat);
- if (baseFileFormat instanceof TAudioFileFormat) {
- Map, ?> properties = ((TAudioFileFormat) baseFileFormat).properties();
- if (out != null)
- out.println(properties);
- for (int i = 0; i < testPropsAFF.length; i++) {
- String key = testPropsAFF[i];
- String val = null;
- if (properties.get(key) != null)
- val = (properties.get(key)).toString();
- if (out != null)
- out.println(key + "='" + val + "'");
- String valexpected = props.getProperty(key);
- assertEquals(key, valexpected, val);
- }
- } else {
- assertTrue(false, "testPropertiesFile : TAudioFileFormat expected");
+ AudioFileFormat baseFileFormat = AudioSystem.getAudioFileFormat(file);
+ AudioFormat baseFormat = baseFileFormat.getFormat();
+ logger.info("-> Filename : " + filename + " <-");
+ logger.info(baseFileFormat.toString());
+ if (baseFileFormat instanceof TAudioFileFormat) {
+ Map, ?> properties = ((TAudioFileFormat) baseFileFormat).properties();
+ logger.info(properties.toString());
+ for (int i = 0; i < testPropsAFF.length; i++) {
+ String key = testPropsAFF[i];
+ String val = null;
+ if (properties.get(key) != null)
+ val = (properties.get(key)).toString();
+ logger.info(key + "='" + val + "'");
+ String valexpected = props.getProperty(key);
+ assertEquals(valexpected, val, key);
}
+ } else {
+ fail("testPropertiesFile : TAudioFileFormat expected");
+ }
- if (baseFormat instanceof TAudioFormat) {
- Map, ?> properties = ((TAudioFormat) baseFormat).properties();
- for (int i = 0; i < testPropsAF.length; i++) {
- String key = testPropsAF[i];
- String val = null;
- if (properties.get(key) != null)
- val = (properties.get(key)).toString();
- if (out != null)
- out.println(key + "='" + val + "'");
- String valexpected = props.getProperty(key);
- assertEquals(key, valexpected, val);
- }
- } else {
- assertTrue(false, "testPropertiesFile : TAudioFormat expected");
+ if (baseFormat instanceof TAudioFormat) {
+ Map, ?> properties = ((TAudioFormat) baseFormat).properties();
+ for (int i = 0; i < testPropsAF.length; i++) {
+ String key = testPropsAF[i];
+ String val = null;
+ if (properties.get(key) != null)
+ val = (properties.get(key)).toString();
+ logger.info(key + "='" + val + "'");
+ String valexpected = props.getProperty(key);
+ assertEquals(valexpected, val, key);
}
- } catch (UnsupportedAudioFileException e) {
- assertTrue(false, "testPropertiesFile : " + e.getMessage());
- } catch (IOException e) {
- assertTrue(false, "testPropertiesFile : " + e.getMessage());
+ } else {
+ fail("testPropertiesFile : TAudioFormat expected");
}
}
@Test
- public void testPropertiesURL() {
- String[] testPropsAFF = { /* "duration", */
+ void testPropertiesURL() throws Exception {
+ final String[] testPropsAFF = { /* "duration", */
"title", "author", "album", "date", "comment", "copyright", "mp3.framerate.fps", "mp3.copyright", "mp3.padding",
"mp3.original", /* "mp3.length.bytes", */"mp3.frequency.hz", /* "mp3.length.frames", */"mp3.mode", "mp3.channels",
"mp3.version.mpeg", "mp3.framesize.bytes", "mp3.vbr.scale", "mp3.version.encoding", "mp3.header.pos",
"mp3.version.layer", "mp3.crc"
};
- String[] testPropsAF = {
+ final String[] testPropsAF = {
"vbr", "bitrate"
};
- AudioFileFormat baseFileFormat = null;
- AudioFormat baseFormat = null;
- try {
- URL url = new URL(fileurl);
- baseFileFormat = AudioSystem.getAudioFileFormat(url);
- baseFormat = baseFileFormat.getFormat();
- if (out != null)
- out.println("-> URL : " + filename + " <-");
- if (out != null)
- out.println(baseFileFormat);
- if (baseFileFormat instanceof TAudioFileFormat) {
- Map, ?> properties = ((TAudioFileFormat) baseFileFormat).properties();
- for (int i = 0; i < testPropsAFF.length; i++) {
- String key = testPropsAFF[i];
- String val = null;
- if (properties.get(key) != null)
- val = (properties.get(key)).toString();
- if (out != null)
- out.println(key + "='" + val + "'");
- String valexpected = props.getProperty(key);
- assertEquals(key, valexpected, val);
- }
- } else {
- assertTrue(false, "testPropertiesURL : TAudioFileFormat expected");
+ URL url = new URL(fileurl);
+ AudioFileFormat baseFileFormat = AudioSystem.getAudioFileFormat(url);
+ AudioFormat baseFormat = baseFileFormat.getFormat();
+ logger.info("-> URL : " + filename + " <-");
+ logger.info(baseFileFormat.toString());
+ if (baseFileFormat instanceof TAudioFileFormat) {
+ Map, ?> properties = ((TAudioFileFormat) baseFileFormat).properties();
+ for (int i = 0; i < testPropsAFF.length; i++) {
+ String key = testPropsAFF[i];
+ String val = null;
+ if (properties.get(key) != null)
+ val = (properties.get(key)).toString();
+ logger.info(key + "='" + val + "'");
+ String valexpected = props.getProperty(key);
+ assertEquals(valexpected, val, key);
}
- if (baseFormat instanceof TAudioFormat) {
- Map, ?> properties = ((TAudioFormat) baseFormat).properties();
- for (int i = 0; i < testPropsAF.length; i++) {
- String key = testPropsAF[i];
- String val = null;
- if (properties.get(key) != null)
- val = (properties.get(key)).toString();
- if (out != null)
- out.println(key + "='" + val + "'");
- String valexpected = props.getProperty(key);
- assertEquals(key, valexpected, val);
- }
- } else {
- assertTrue(false, "testPropertiesURL : TAudioFormat expected");
+ } else {
+ fail("testPropertiesURL : TAudioFileFormat expected");
+ }
+
+ if (baseFormat instanceof TAudioFormat) {
+ Map, ?> properties = ((TAudioFormat) baseFormat).properties();
+ for (int i = 0; i < testPropsAF.length; i++) {
+ String key = testPropsAF[i];
+ String val = null;
+ if (properties.get(key) != null)
+ val = (properties.get(key)).toString();
+ logger.info(key + "='" + val + "'");
+ String valexpected = props.getProperty(key);
+ assertEquals(valexpected, val, key);
}
- } catch (UnsupportedAudioFileException e) {
- assertTrue(false, "testPropertiesURL : " + e.getMessage());
- } catch (IOException e) {
- assertTrue(false, "testPropertiesURL : " + e.getMessage());
+ } else {
+ fail("testPropertiesURL : TAudioFormat expected");
}
}
@Test
- public void testPropertiesShoutcast() {
- AudioFileFormat baseFileFormat = null;
- AudioFormat baseFormat = null;
+ @Disabled
+ void testPropertiesShoutcast() throws Exception {
String shoutURL = props.getProperty("shoutcast");
- try {
- URL url = new URL(shoutURL);
- baseFileFormat = AudioSystem.getAudioFileFormat(url);
- baseFormat = baseFileFormat.getFormat();
- if (out != null)
- out.println("-> URL : " + url.toString() + " <-");
- if (out != null)
- out.println(baseFileFormat);
- if (baseFileFormat instanceof TAudioFileFormat) {
- Map, ?> properties = ((TAudioFileFormat) baseFileFormat).properties();
- Iterator> it = properties.keySet().iterator();
- while (it.hasNext()) {
- String key = (String) it.next();
- String val = null;
- if (properties.get(key) != null)
- val = (properties.get(key)).toString();
- if (out != null)
- out.println(key + "='" + val + "'");
- }
- } else {
- assertTrue(false, "testPropertiesShoutcast : TAudioFileFormat expected");
+ URL url = new URL(shoutURL);
+ AudioFileFormat baseFileFormat = AudioSystem.getAudioFileFormat(url);
+ AudioFormat baseFormat = baseFileFormat.getFormat();
+ logger.info("-> URL : " + url.toString() + " <-");
+ logger.info(baseFileFormat.toString());
+ if (baseFileFormat instanceof TAudioFileFormat) {
+ Map, ?> properties = ((TAudioFileFormat) baseFileFormat).properties();
+ Iterator> it = properties.keySet().iterator();
+ while (it.hasNext()) {
+ String key = (String) it.next();
+ String val = null;
+ if (properties.get(key) != null)
+ val = (properties.get(key)).toString();
+ logger.info(key + "='" + val + "'");
}
- if (baseFormat instanceof TAudioFormat) {
- Map, ?> properties = ((TAudioFormat) baseFormat).properties();
- Iterator> it = properties.keySet().iterator();
- while (it.hasNext()) {
- String key = (String) it.next();
- String val = null;
- if (properties.get(key) != null)
- val = (properties.get(key)).toString();
- if (out != null)
- out.println(key + "='" + val + "'");
- }
- } else {
- assertTrue(false, "testPropertiesShoutcast : TAudioFormat expected");
+ } else {
+ fail("testPropertiesShoutcast : TAudioFileFormat expected");
+ }
+
+ if (baseFormat instanceof TAudioFormat) {
+ Map, ?> properties = ((TAudioFormat) baseFormat).properties();
+ Iterator> it = properties.keySet().iterator();
+ while (it.hasNext()) {
+ String key = (String) it.next();
+ String val = null;
+ if (properties.get(key) != null)
+ val = (properties.get(key)).toString();
+ logger.info(key + "='" + val + "'");
}
- } catch (UnsupportedAudioFileException e) {
- assertTrue(false, "testPropertiesShoutcast : " + e.getMessage());
- } catch (IOException e) {
- assertTrue(false, "testPropertiesShoutcast : " + e.getMessage());
+ } else {
+ fail("testPropertiesShoutcast : TAudioFormat expected");
}
}
- public void _testDumpPropertiesFile() {
- File file = new File(filename);
- AudioFileFormat baseFileFormat = null;
- AudioFormat baseFormat = null;
- try {
- baseFileFormat = AudioSystem.getAudioFileFormat(file);
- baseFormat = baseFileFormat.getFormat();
- if (out != null)
- out.println("-> Filename : " + filename + " <-");
- if (baseFileFormat instanceof TAudioFileFormat) {
- Map, ?> properties = ((TAudioFileFormat) baseFileFormat).properties();
- Iterator> it = properties.keySet().iterator();
- while (it.hasNext()) {
- String key = (String) it.next();
- String val = (properties.get(key)).toString();
- if (out != null)
- out.println(key + "='" + val + "'");
- }
- } else {
- assertTrue(false, "testDumpPropertiesFile : TAudioFileFormat expected");
+ void testDumpPropertiesURL() throws Exception {
+ URL file = new URL(fileurl);
+ AudioFileFormat baseFileFormat = AudioSystem.getAudioFileFormat(file);
+ AudioFormat baseFormat = baseFileFormat.getFormat();
+ logger.info("-> Filename : " + filename + " <-");
+ if (baseFileFormat instanceof TAudioFileFormat) {
+ Map, ?> properties = ((TAudioFileFormat) baseFileFormat).properties();
+ Iterator> it = properties.keySet().iterator();
+ while (it.hasNext()) {
+ String key = (String) it.next();
+ String val = (properties.get(key)).toString();
+ logger.info(key + "='" + val + "'");
}
+ } else {
+ fail("testDumpPropertiesFile : TAudioFileFormat expected");
+ }
- if (baseFormat instanceof TAudioFormat) {
- Map, ?> properties = ((TAudioFormat) baseFormat).properties();
- Iterator> it = properties.keySet().iterator();
- while (it.hasNext()) {
- String key = (String) it.next();
- String val = (properties.get(key)).toString();
- if (out != null)
- out.println(key + "='" + val + "'");
- }
- } else {
- assertTrue(false, "testDumpPropertiesFile : TAudioFormat expected");
+ if (baseFormat instanceof TAudioFormat) {
+ Map, ?> properties = ((TAudioFormat) baseFormat).properties();
+ Iterator> it = properties.keySet().iterator();
+ while (it.hasNext()) {
+ String key = (String) it.next();
+ String val = (properties.get(key)).toString();
+ logger.info(key + "='" + val + "'");
}
- } catch (UnsupportedAudioFileException e) {
- assertTrue(false, "testDumpPropertiesFile : " + e.getMessage());
- } catch (IOException e) {
- assertTrue(false, "testDumpPropertiesFile : " + e.getMessage());
+ } else {
+ fail("testDumpPropertiesFile : TAudioFormat expected");
}
}
}
diff --git a/src/test/java/javazoom/spi/mpeg/sampled/file/SkipTest.java b/src/test/java/javazoom/spi/mpeg/sampled/file/SkipTest.java
index 755ac51..b3d62f0 100644
--- a/src/test/java/javazoom/spi/mpeg/sampled/file/SkipTest.java
+++ b/src/test/java/javazoom/spi/mpeg/sampled/file/SkipTest.java
@@ -22,10 +22,10 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.io.PrintStream;
+import java.net.URL;
import java.util.Properties;
+import java.util.logging.Logger;
-import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
@@ -43,17 +43,17 @@
/**
* Skip bytes before playing.
*/
-public class SkipTest {
+class SkipTest {
private String basefile = null;
private String baseurl = null;
private String filename = null;
private String fileurl = null;
private String name = null;
private Properties props = null;
- private PrintStream out = null;
+ private Logger out;
@BeforeEach
- protected void setUp() throws Exception {
+ void setUp() throws Exception {
props = new Properties();
InputStream pin = getClass().getClassLoader().getResourceAsStream("test.mp3.properties");
props.load(pin);
@@ -62,45 +62,61 @@ protected void setUp() throws Exception {
name = props.getProperty("filename");
filename = basefile + name;
fileurl = baseurl + name;
- out = System.out;
+ out = Logger.getLogger(SkipTest.class.getName());
}
@Test
- public void testSkipFile() {
- if (out != null)
- out.println("-> Filename : " + filename + " <-");
- try {
- File file = new File(filename);
- AudioFileFormat aff = AudioSystem.getAudioFileFormat(file);
- AudioInputStream in = AudioSystem.getAudioInputStream(file);
- AudioInputStream din = null;
- AudioFormat baseFormat = in.getFormat();
- if (out != null)
- out.println("Source Format : " + baseFormat.toString());
- AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
- baseFormat.getSampleRate(),
- 16,
- baseFormat.getChannels(),
- baseFormat.getChannels() * 2,
- baseFormat.getSampleRate(),
- false);
- if (out != null)
- out.println("Target Format : " + decodedFormat.toString());
- din = AudioSystem.getAudioInputStream(decodedFormat, in);
- long toSkip = file.length() / 2;
- long skipped = skip(din, toSkip);
- if (out != null)
- out.println("Skip : " + skipped + "/" + toSkip + " (Total=" + file.length() + ")");
- if (out != null)
- out.println("Start playing");
- rawplay(decodedFormat, din);
- in.close();
- if (out != null)
- out.println("Played");
- assertTrue(true, "testSkip : OK");
- } catch (Exception e) {
- assertTrue(false, e.getMessage());
- }
+ void testSkipFile() throws Exception {
+ out.info("-> Filename : " + filename + " <-");
+ File file = new File(filename);
+ AudioInputStream in = AudioSystem.getAudioInputStream(file);
+ AudioInputStream din = null;
+ AudioFormat baseFormat = in.getFormat();
+ out.info("Source Format : " + baseFormat.toString());
+ AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
+ baseFormat.getSampleRate(),
+ 16,
+ baseFormat.getChannels(),
+ baseFormat.getChannels() * 2,
+ baseFormat.getSampleRate(),
+ false);
+ out.info("Target Format : " + decodedFormat.toString());
+ din = AudioSystem.getAudioInputStream(decodedFormat, in);
+ long toSkip = file.length() * 19 / 20;
+ long skipped = skip(din, toSkip);
+ out.info("Skip : " + skipped + "/" + toSkip + " (Total=" + file.length() + ")");
+ out.info("Start playing");
+ rawplay(decodedFormat, din);
+ in.close();
+ out.info("Played");
+ assertTrue(true, "testSkip : OK");
+ }
+
+ @Test
+ void testSkipUrl() throws Exception {
+ out.info("-> URL : " + fileurl + " <-");
+ URL url = new URL(fileurl);
+ AudioInputStream in = AudioSystem.getAudioInputStream(url);
+ AudioInputStream din = null;
+ AudioFormat baseFormat = in.getFormat();
+ out.info("Source Format : " + baseFormat.toString());
+ AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
+ baseFormat.getSampleRate(),
+ 16,
+ baseFormat.getChannels(),
+ baseFormat.getChannels() * 2,
+ baseFormat.getSampleRate(),
+ false);
+ out.info("Target Format : " + decodedFormat.toString());
+ din = AudioSystem.getAudioInputStream(decodedFormat, in);
+ long toSkip = in.available() * 19 / 20;
+ long skipped = skip(din, toSkip);
+ out.info("Skip : " + skipped + "/" + toSkip + " (Total=" + in.available() + ")");
+ out.info("Start playing");
+ rawplay(decodedFormat, din);
+ in.close();
+ out.info("Played");
+ assertTrue(true, "testSkip : OK");
}
private long skip(AudioInputStream in, long bytes) throws IOException {
@@ -134,11 +150,11 @@ private void rawplay(AudioFormat targetFormat, AudioInputStream din) throws IOEx
gainControl.setValue(dB);
// Start
line.start();
- int nBytesRead = 0, nBytesWritten = 0;
+ int nBytesRead = 0;
while (nBytesRead != -1) {
nBytesRead = din.read(data, 0, data.length);
if (nBytesRead != -1)
- nBytesWritten = line.write(data, 0, nBytesRead);
+ line.write(data, 0, nBytesRead);
}
// Stop
line.drain();
diff --git a/src/test/resources/logging.properties b/src/test/resources/logging.properties
new file mode 100644
index 0000000..8aa6f3e
--- /dev/null
+++ b/src/test/resources/logging.properties
@@ -0,0 +1,14 @@
+handlers=java.util.logging.ConsoleHandler
+.level=INFO
+# Limit the message that are printed on the console to INFO and above.
+java.util.logging.ConsoleHandler.level=INFO
+java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
+# %1:date/time %2:className and methodName %3logName %4:level %5:message %6:errormessage
+java.util.logging.SimpleFormatter.format=%1$tY/%1$tm/%1$td %1$tH:%1$tM:%1$tS.%1$tL [%4$s] %5$s %6$s%n
+
+# HttpUrlConnection
+#java.util.logging.ConsoleHandler.level=ALL
+#sun.net.www.protocol.http.HttpURLConnection.level=ALL
+
+#java.util.logging.ConsoleHandler.formatter=vavi.util.logging.VaviFormatter
+#java.util.logging.ConsoleHandler.formatter=vavi.util.logging.BetterFormatter
diff --git a/src/test/resources/test.mp3 b/src/test/resources/test.mp3
index 5219130..a4e1f47 100644
Binary files a/src/test/resources/test.mp3 and b/src/test/resources/test.mp3 differ
diff --git a/src/test/resources/test.mp3.properties b/src/test/resources/test.mp3.properties
index 8e0ca84..286b5df 100644
--- a/src/test/resources/test.mp3.properties
+++ b/src/test/resources/test.mp3.properties
@@ -7,8 +7,8 @@ shoutcast96=http://64.236.34.97:80/stream/1003
shoutcast128=http://160.79.128.35:7012/
# AudioFileFormat and AudioFormat properties
-ByteLength=8945229
-FrameLength=14289
+ByteLength=8945664
+FrameLength=14290
Type=MP3
SourceFormat=MPEG1L3 44100.0 Hz, unknown bits per sample, stereo, unknown frame size, 38.28125 frames/second,
Channels=2
@@ -19,35 +19,35 @@ SampleSizeInBits=-1
Encoding=MPEG1L3
# AudioInputStream properties
-Available=8945229
+Available=8945664
# Extented Normalized (JDK1.5) AudioFormat properties
-vbr=true
-bitrate=229000
+vbr=false
+bitrate=192000
# Extented Normalized (JDK1.5) AudioFileFormat properties
-duration=212167000
+duration=373290000
title=We
author=Scer
album=The Sta no Expe
date=2003
comment=Test Comments !
-copyright=copy
+#copyright=copy
# Extented MP3 AudioFileFormat properties
mp3.framerate.fps=38.28125
mp3.copyright=false
mp3.padding=false
mp3.original=false
-mp3.length.bytes=8945229
+mp3.length.bytes=8945664
mp3.frequency.hz=44100
-mp3.length.frames=8122
-mp3.mode=1
+mp3.length.frames=14290
+mp3.mode=0
mp3.channels=2
mp3.version.mpeg=1
-mp3.framesize.bytes=413
-mp3.vbr.scale=78
+mp3.framesize.bytes=622
+mp3.vbr.scale=0
mp3.version.encoding=MPEG1L3
-mp3.header.pos=2150
+mp3.header.pos=374
mp3.version.layer=3
-mp3.crc=false
+mp3.crc=true