+ * encoder.exe は little endian
+ * PCM_SIGNED の場合はちゃんと 16Bit Signed な数値を渡してやる
-
-
PCM_SIGNED の場合はちゃんと 16Bit Signed な数値を渡してやる
-
-
+## TODO
-
これから実装すること
+ * 3, 5bit
-
-
3, 5bit
-
-
+## License
-
一次ライセンス
-
+```
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
@@ -70,8 +39,4 @@
-/*
- * adpcm.c codex functions for MS_ADPCM data
- * (hopefully) provides interoperability with
- * Microsoft's ADPCM format, but, as usual,
- * see LACK-OF-WARRANTY information below.
- *
- * Copyright (C) 1999 Stanley J. Brooks <stabro@megsinet.net>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-
-
-
-
diff --git a/src/main/java/vavi/sound/adpcm/ms/readme.md b/src/main/java/vavi/sound/adpcm/ms/readme.md
new file mode 100644
index 0000000..ddfef1b
--- /dev/null
+++ b/src/main/java/vavi/sound/adpcm/ms/readme.md
@@ -0,0 +1,45 @@
+vavi.sound.adpcm.ms
+
+MS ADPCM フォーマット関連のクラスを提供します.
+
+## Status
+
+sox と同じ結果になったので完成とみなす。
+
+## Tech-know
+
+ * ACM の M$ ADPCM とは結果が違う
+
+## TODO
+
+ * ~~datetime="111016">一括読み込みを止める~~
+ * ~~datetime="111016">↑もしくは EngineeringIO を使う~~
+ * ~~datetime="060124">音が汚い~~
+ * ~~最後のフラグメントが切れている~~ → #drain()
+
+## TODO
+```
+/*
+ * adpcm.c codex functions for MS_ADPCM data
+ * (hopefully) provides interoperability with
+ * Microsoft's ADPCM format, but, as usual,
+ * see LACK-OF-WARRANTY information below.
+ *
+ * Copyright (C) 1999 Stanley J. Brooks <stabro@megsinet.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+```
\ No newline at end of file
diff --git a/src/main/java/vavi/sound/adpcm/package.html b/src/main/java/vavi/sound/adpcm/package.html
deleted file mode 100644
index afdca31..0000000
--- a/src/main/java/vavi/sound/adpcm/package.html
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-vavi.sound.adpcm
-
-
-
-
-
-
-/* File: adpcm.c
- Description: Routines to convert 12 bit linear samples to the
- Dialogic or Oki ADPCM coding format.
- I copied the algorithms out of the book "PC Telephony - The
- complete guide to designing, building and programming systems
- using Dialogic and Related Hardware" by Bob Edgar. pg 272-276.
-
-*/
-
-
-
-
-
diff --git a/src/main/java/vavi/sound/adpcm/vox/readme.md b/src/main/java/vavi/sound/adpcm/vox/readme.md
new file mode 100644
index 0000000..5869bee
--- /dev/null
+++ b/src/main/java/vavi/sound/adpcm/vox/readme.md
@@ -0,0 +1,24 @@
+# vavi.sound.adpcm.vox
+
+VOX ADPCM フォーマット関連のクラスを提供します.
+
+# Status
+
+完成
+
+## TODO
+
+ * ~~decode x16~~???
+
+## License
+
+```
+/* File: adpcm.c
+ Description: Routines to convert 12 bit linear samples to the
+ Dialogic or Oki ADPCM coding format.
+ I copied the algorithms out of the book "PC Telephony - The
+ complete guide to designing, building and programming systems
+ using Dialogic and Related Hardware" by Bob Edgar. pg 272-276.
+
+*/
+```
\ No newline at end of file
diff --git a/src/main/java/vavi/sound/adpcm/yamaha/package.html b/src/main/java/vavi/sound/adpcm/yamaha/package.html
deleted file mode 100644
index ee0dea0..0000000
--- a/src/main/java/vavi/sound/adpcm/yamaha/package.html
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
-
-
-
-
-vavi.sound.adpcm.yamaha
-
-
-
-
-
-
-YAMAHA MA Chip ADPCM フォーマット関連のクラスを提供します.
-
-
-完成
-
-
わかったこと
-
-
-
よう見たら YM2608 のコードと一緒やん、何が2年の研究やねん
-
-
-
-
一次ライセンス
-
-
記載なし
-
-
-
-
-
diff --git a/src/main/java/vavi/sound/adpcm/yamaha/readme.md b/src/main/java/vavi/sound/adpcm/yamaha/readme.md
new file mode 100644
index 0000000..4d7a335
--- /dev/null
+++ b/src/main/java/vavi/sound/adpcm/yamaha/readme.md
@@ -0,0 +1,14 @@
+# vavi.sound.adpcm.yamaha
+
+YAMAHA MA Chip ADPCM フォーマット関連のクラスを提供します.
+
+# Status
+
+完成
+
+
+よう見たら YM2608 のコードと一緒やん、何が2年の研究やねん
+
+## License
+
+記載なし
diff --git a/src/main/java/vavi/sound/adpcm/ym2608/package.html b/src/main/java/vavi/sound/adpcm/ym2608/readme.md
similarity index 54%
rename from src/main/java/vavi/sound/adpcm/ym2608/package.html
rename to src/main/java/vavi/sound/adpcm/ym2608/readme.md
index 1701e0b..e776d86 100644
--- a/src/main/java/vavi/sound/adpcm/ym2608/package.html
+++ b/src/main/java/vavi/sound/adpcm/ym2608/readme.md
@@ -1,165 +1,105 @@
-
-
-
-
- * 今のところ実装クラスは bean でなければならない.
- * (引数なしのコンストラクタがあること)
+ * Currently, an implementation class of this interface should be an bean.
+ * (means having a contractor without argument)
*
*
* @author Naohide Sano (nsano)
* @version 0.00 070119 nsano initial version
diff --git a/src/main/java/vavi/sound/mfi/vavi/sequencer/MachineDependentFunction.java b/src/main/java/vavi/sound/mfi/vavi/sequencer/MachineDependentFunction.java
index 09460ff..b99693e 100644
--- a/src/main/java/vavi/sound/mfi/vavi/sequencer/MachineDependentFunction.java
+++ b/src/main/java/vavi/sound/mfi/vavi/sequencer/MachineDependentFunction.java
@@ -15,10 +15,14 @@
/**
* Sub sequencer for machine dependent system exclusive message.
*
- * 今のところ実装クラスは bean でなければならない。
- * (引数なしのコンストラクタがあること)
- * {@link #process(MachineDependentMessage)} 関連はステートレスでなければならない。
+ * Currently, an implementation class of this interface should be an bean.
+ * (means having a contractor without argument)
+ * {@link #process(MachineDependentMessage)} related should be state less.
*
+ *
+ * properties file ... any
+ * name prefix ... "function."
+ *
* @author Naohide Sano (nsano)
* @version 0.00 030822 nsano initial version
*/
@@ -41,7 +45,7 @@ public interface MachineDependentFunction {
void process(MachineDependentMessage message)
throws InvalidMfiDataException;
- /** */
+ /** factory */
class Factory extends PrefixedClassPropertiesFactory {
/** */
@@ -56,7 +60,7 @@ public MachineDependentFunction getFunction(String key) {
} catch (IllegalArgumentException e) {
Debug.println(key);
Debug.printStackTrace(e);
- return new UndefinedFunction(); // TODO should throw exception
+ return new UndefinedFunction(); // TODO should throw exception or not?
}
}
}
diff --git a/src/main/java/vavi/sound/mfi/vavi/sequencer/MachineDependentSequencer.java b/src/main/java/vavi/sound/mfi/vavi/sequencer/MachineDependentSequencer.java
index c0662e1..e78df4c 100644
--- a/src/main/java/vavi/sound/mfi/vavi/sequencer/MachineDependentSequencer.java
+++ b/src/main/java/vavi/sound/mfi/vavi/sequencer/MachineDependentSequencer.java
@@ -14,6 +14,10 @@
/**
* Sub sequencer for machine dependent system exclusive message.
+ *
+ * Currently, an implementation class of this interface should be an bean.
+ * (means having a contractor without argument)
+ * {@link #encode(int, int, byte[])} related should be stateless.
*
* @author Naohide Sano (nsano)
* @version 0.00 051116 nsano initial version
@@ -77,15 +79,15 @@ class Data {
public boolean continued = false;
}
- /** */
+ /** monaural stereo conversion */
class Util {
- /** */
+ /** left */
private static final int L = 0;
- /** */
+ /** right */
private static final int R = 1;
/**
- * インターリーブされた PCM を L R 順に分離
+ * separates interleaved PCM to an array L R order.
* @param stereo PCM stereo, currently 16bit only
* @param bits PCM bits, TODO currently unused
* @param byteOrder PCM 16 bit byte order, TODO currently unused
@@ -116,7 +118,7 @@ public static byte[][] toMono(byte[] stereo, int bits, ByteOrder byteOrder) {
}
/**
- * インターリーブするというらしい。
+ * this seems to say interleave.
* @param monoL ADPCM monaural L, currently 4bit only
* @param monoR ADPCM monaural R, currently 4bit only
* @param bits ADPCM bits, TODO currently unused
@@ -137,7 +139,7 @@ public static byte[] toStereo(byte[] monoL, byte[] monoR, int bits, ByteOrder by
}
/**
- * インターリーブしない。
+ * not interleaved.
* @param monoL adpcm data L
* @param monoR adpcm data R
* @return L, R concatenated adpcm data
diff --git a/src/main/java/vavi/sound/mobile/BasicAudioEngine.java b/src/main/java/vavi/sound/mobile/BasicAudioEngine.java
index 2a948fb..bfddc6b 100644
--- a/src/main/java/vavi/sound/mobile/BasicAudioEngine.java
+++ b/src/main/java/vavi/sound/mobile/BasicAudioEngine.java
@@ -16,12 +16,13 @@
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
-import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import vavi.util.Debug;
+import static vavi.sound.SoundUtil.volume;
+
/**
* Abstract AudioEngine.
@@ -34,7 +35,7 @@ public abstract class BasicAudioEngine implements AudioEngine {
/** */
protected Data[] data;
- /* */
+ @Override
public void setData(int streamNumber,
int channel,
int sampleRate,
@@ -64,7 +65,7 @@ public void setData(int streamNumber,
// debug1();
}
- /** */
+ @Override
public void stop(int streamNumber) {
}
@@ -74,7 +75,7 @@ public void stop(int streamNumber) {
/** */
protected abstract InputStream[] getInputStreams(int streamNumber, int channels);
- /** */
+ @Override
public void start(int streamNumber) {
int channels = getChannels(streamNumber);
@@ -105,10 +106,7 @@ public void start(int streamNumber) {
SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
line.open(audioFormat);
line.start();
-FloatControl gainControl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
-double gain = .2d; // number between 0 and 1 (loudest)
-float dB = (float) (Math.log(gain) / Math.log(10.0) * 20.0);
-gainControl.setValue(dB);
+ volume(line, .2d);
byte[] buf = new byte[1024];
while (iss[0].available() > 0) {
if (channels == 1) {
@@ -146,7 +144,7 @@ public void start(int streamNumber) {
/** */
protected abstract OutputStream getOutputStream(OutputStream os);
- /* */
+ @Override
public byte[] encode(int bits, int channels, byte[] pcm) {
try {
if (channels == 1) {
diff --git a/src/main/java/vavi/sound/mobile/FuetrekAudioEngine.java b/src/main/java/vavi/sound/mobile/FuetrekAudioEngine.java
index 119d63b..cae3c17 100644
--- a/src/main/java/vavi/sound/mobile/FuetrekAudioEngine.java
+++ b/src/main/java/vavi/sound/mobile/FuetrekAudioEngine.java
@@ -42,7 +42,7 @@ public FuetrekAudioEngine() {
data = new Data[MAX_ID];
}
- /** */
+ @Override
protected int getChannels(int streamNumber) {
int channels = 1;
if (data[streamNumber].channel != -1) {
@@ -64,7 +64,7 @@ protected int getChannels(int streamNumber) {
return channels;
}
- /** */
+ @Override
protected InputStream[] getInputStreams(int streamNumber, int channels) {
InputStream[] iss = new InputStream[2];
if (data[streamNumber].channels == 1) {
@@ -101,7 +101,7 @@ protected InputStream[] getInputStreams(int streamNumber, int channels) {
//-------------------------------------------------------------------------
- /** */
+ @Override
protected OutputStream getOutputStream(OutputStream os) {
return new G721OutputStream(os, ByteOrder.LITTLE_ENDIAN);
}
diff --git a/src/main/java/vavi/sound/mobile/PcmAudioEngine.java b/src/main/java/vavi/sound/mobile/PcmAudioEngine.java
index 676e8d3..73592f2 100644
--- a/src/main/java/vavi/sound/mobile/PcmAudioEngine.java
+++ b/src/main/java/vavi/sound/mobile/PcmAudioEngine.java
@@ -14,27 +14,29 @@
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
-import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import vavi.util.Debug;
+import static vavi.sound.SoundUtil.volume;
+
/**
* PCM AudioEngine.
- *
-WSC-MAX_DLL
-DLL
- Input File Output File
-wscma2_dll File Format Bit Sampling Frequency Form Conversion Format File Format
-wscma3_dll WAVE 16bit 4kHz or 8kHz mono 4bit ADPCM SMAF/MA-2
- WAVE 16bit 4kHz~16kHz mono 4bit ADPCM SMAF/MA-3
-wscma5_dll WAVE 16bit or 8bit 4kHz~ 8kHz mono 8bit PCM SMAF/MA-3
- WAVE or AIFF 16bit 4kHz~24kHz mono 4bit ADPCM SMAF/MA-5
- WAVE or AIFF 16bit or 8bit 4kHz~12kHz mono 8bit PCM SMAF/MA-5
- WAVE or AIFF 16bit 4kHz~12kHz stereo 4bit ADPCM SMAF/MA-5
- WAVE or AIFF 16bit or 8bit 4kHz~6kHz stereo 8bit PCM SMAF/MA-5
+ *
+ * WSC-MAX_DLL
+ * DLL
+ * Input File Output File
+ * wscma2_dll File Format Bit Sampling Frequency Form Conversion Format File Format
+ * wscma3_dll WAVE 16bit 4kHz or 8kHz mono 4bit ADPCM SMAF/MA-2
+ * WAVE 16bit 4kHz~16kHz mono 4bit ADPCM SMAF/MA-3
+ * wscma5_dll WAVE 16bit or 8bit 4kHz~ 8kHz mono 8bit PCM SMAF/MA-3
+ * WAVE or AIFF 16bit 4kHz~24kHz mono 4bit ADPCM SMAF/MA-5
+ * WAVE or AIFF 16bit or 8bit 4kHz~12kHz mono 8bit PCM SMAF/MA-5
+ * WAVE or AIFF 16bit 4kHz~12kHz stereo 4bit ADPCM SMAF/MA-5
+ * WAVE or AIFF 16bit or 8bit 4kHz~6kHz stereo 8bit PCM SMAF/MA-5
+ *
*
* @author Naohide Sano (nsano)
* @version 0.00 020829 nsano initial version
@@ -52,7 +54,7 @@ public PcmAudioEngine() {
data = new Data[32];
}
- /** */
+ @Override
protected int getChannels(int streamNumber) {
int channels = 1;
if (data[streamNumber].channel == -1) {
@@ -84,7 +86,7 @@ protected int getChannels(int streamNumber) {
return channels;
}
- /** */
+ @Override
protected InputStream[] getInputStreams(int streamNumber, int channels) {
InputStream[] iss = new InputStream[2];
if (data[streamNumber].channels == 1) {
@@ -105,11 +107,12 @@ protected InputStream[] getInputStreams(int streamNumber, int channels) {
//-------------------------------------------------------------------------
- /** */
+ @Override
protected OutputStream getOutputStream(OutputStream os) {
return os;
}
+ @Override
public void start(int streamNumber) {
int channels = getChannels(streamNumber);
@@ -140,10 +143,7 @@ public void start(int streamNumber) {
SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
line.open(audioFormat);
line.start();
-FloatControl gainControl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
-double gain = .2d; // number between 0 and 1 (loudest)
-float dB = (float) (Math.log(gain) / Math.log(10.0) * 20.0);
-gainControl.setValue(dB);
+ volume(line, .2d);
byte[] buf = new byte[1024];
while (iss[0].available() > 0) {
if (channels == 1) {
@@ -169,9 +169,7 @@ public void start(int streamNumber) {
line.stop();
line.close();
// debug4(os);
- } catch (IOException e) {
- throw new IllegalStateException(e);
- } catch (LineUnavailableException e) {
+ } catch (IOException | LineUnavailableException e) {
throw new IllegalStateException(e);
}
}
diff --git a/src/main/java/vavi/sound/mobile/RohmAudioEngine.java b/src/main/java/vavi/sound/mobile/RohmAudioEngine.java
index da66309..2c47390 100644
--- a/src/main/java/vavi/sound/mobile/RohmAudioEngine.java
+++ b/src/main/java/vavi/sound/mobile/RohmAudioEngine.java
@@ -40,7 +40,7 @@ public RohmAudioEngine() {
data = new Data[MAX_ID];
}
- /** */
+ @Override
protected int getChannels(int streamNumber) {
int channels = 1;
if (data[streamNumber].channel != -1) {
@@ -61,7 +61,7 @@ protected int getChannels(int streamNumber) {
return channels;
}
- /** */
+ @Override
protected InputStream[] getInputStreams(int streamNumber, int channels) {
InputStream[] iss = new InputStream[2];
if (data[streamNumber].channels == 1) {
@@ -82,7 +82,7 @@ protected InputStream[] getInputStreams(int streamNumber, int channels) {
//-------------------------------------------------------------------------
- /** */
+ @Override
protected OutputStream getOutputStream(OutputStream os) {
return new RohmOutputStream(os, ByteOrder.LITTLE_ENDIAN);
}
diff --git a/src/main/java/vavi/sound/mobile/YamahaAudioEngine.java b/src/main/java/vavi/sound/mobile/YamahaAudioEngine.java
index 63fc34d..e0ffcc1 100644
--- a/src/main/java/vavi/sound/mobile/YamahaAudioEngine.java
+++ b/src/main/java/vavi/sound/mobile/YamahaAudioEngine.java
@@ -34,7 +34,7 @@ public YamahaAudioEngine() {
data = new Data[32];
}
- /** */
+ @Override
protected int getChannels(int streamNumber) {
int channels = 1;
if (data[streamNumber].channel == -1) {
@@ -66,7 +66,7 @@ protected int getChannels(int streamNumber) {
return channels;
}
- /** */
+ @Override
protected InputStream[] getInputStreams(int streamNumber, int channels) {
InputStream[] iss = new InputStream[2];
if (data[streamNumber].channels == 1) {
@@ -87,7 +87,7 @@ protected InputStream[] getInputStreams(int streamNumber, int channels) {
//-------------------------------------------------------------------------
- /** */
+ @Override
protected OutputStream getOutputStream(OutputStream os) {
return new MaOutputStream(os, ByteOrder.LITTLE_ENDIAN);
}
diff --git a/src/main/java/vavi/sound/mobile/package.html b/src/main/java/vavi/sound/mobile/package.html
deleted file mode 100644
index e469e09..0000000
--- a/src/main/java/vavi/sound/mobile/package.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-vavi.sound.mobile
-
-
-
-
-
-
- * {@link javax.sound.midi.MidiSystem#getSequencer()} を
- * 使用しているため javax.sound.midi SPI のプログラム内で使用してはいけません。
+ * don't use {@link javax.sound.midi.MidiSystem#getSequencer()},
+ * {@link javax.sound.midi.MidiSystem#getSequencer(boolean)} in this program,
+ * because this is the {@link javax.sound.midi.Sequencer}.
*
* @author Naohide Sano (nsano)
* @version 0.00 071010 nsano initial version
@@ -53,12 +48,12 @@ class SmafSequencer implements Sequencer, Synthesizer {
/** the sequence of SMAF */
private Sequence sequence;
- /** */
+ @Override
public SmafDevice.Info getDeviceInfo() {
return info;
}
- /* */
+ @Override
public void close() {
if (midiSequencer == null) {
throw new IllegalStateException("not opend");
@@ -67,7 +62,7 @@ public void close() {
midiSynthesizer.close();
}
- /* */
+ @Override
public boolean isOpen() {
if (midiSequencer == null) {
return false;
@@ -75,10 +70,10 @@ public boolean isOpen() {
return midiSequencer.isOpen();
}
- /** ADPCM sequencer */
+ /** ADPCM sequencer, TODO should be {@link javax.sound.midi.Transmitter} */
private javax.sound.midi.MetaEventListener mea = new MetaEventAdapter();
- /* */
+ @Override
public void open() throws SmafUnavailableException {
try {
if (midiSequencer == null) {
@@ -94,7 +89,7 @@ public void open() throws SmafUnavailableException {
}
}
- /* */
+ @Override
public void setSequence(Sequence sequence)
throws InvalidSmafDataException {
@@ -111,7 +106,7 @@ public void setSequence(Sequence sequence)
}
}
- /* */
+ @Override
public void setSequence(InputStream stream)
throws IOException,
InvalidSmafDataException {
@@ -119,12 +114,12 @@ public void setSequence(InputStream stream)
this.setSequence(SmafSystem.getSequence(stream));
}
- /* */
+ @Override
public Sequence getSequence() {
return sequence;
}
- /* */
+ @Override
public void start() {
if (midiSequencer == null) {
throw new IllegalStateException("not opend");
@@ -133,7 +128,7 @@ public void start() {
midiSequencer.start();
}
- /* */
+ @Override
public void stop() {
if (midiSequencer == null) {
throw new IllegalStateException("not opend");
@@ -142,7 +137,7 @@ public void stop() {
off();
}
- /* */
+ @Override
public boolean isRunning() {
if (midiSequencer == null) {
throw new IllegalStateException("not opend");
@@ -186,7 +181,7 @@ protected void fireMeta(MetaMessage meta) {
public void meta(javax.sound.midi.MetaMessage message) {
//Debug.println("type: " + message.getType());
switch (message.getType()) {
- case 0x2f: // 自動的に最後につけてくれる
+ case 0x2f: // added automatically at the end of the sequence
try {
MetaMessage metaMessage = new MetaMessage();
metaMessage.setMessage(0x2f, null);
diff --git a/src/main/java/vavi/sound/smaf/chunk/AudioSequenceDataChunk.java b/src/main/java/vavi/sound/smaf/chunk/AudioSequenceDataChunk.java
index 5148dd2..0ef722e 100644
--- a/src/main/java/vavi/sound/smaf/chunk/AudioSequenceDataChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/AudioSequenceDataChunk.java
@@ -7,7 +7,6 @@
package vavi.sound.smaf.chunk;
import java.io.IOException;
-import java.io.InputStream;
import vavi.sound.smaf.InvalidSmafDataException;
import vavi.sound.smaf.SmafMessage;
@@ -39,14 +38,14 @@ public AudioSequenceDataChunk() {
}
/** TODO how to get formatType from parent chunk ??? */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
//Debug.println("available: " + is.available() + ", " + available());
//skip(is, size); // TODO
FormatType formatType = ((TrackChunk) parent).getFormatType();
switch (formatType) {
case HandyPhoneStandard:
- readHandyPhoneStandard(is);
+ readHandyPhoneStandard(dis);
break;
default:
throw new InvalidSmafDataException("FormatType: " + formatType);
diff --git a/src/main/java/vavi/sound/smaf/chunk/BitmapChunk.java b/src/main/java/vavi/sound/smaf/chunk/BitmapChunk.java
index 33a6cfb..9027bb0 100644
--- a/src/main/java/vavi/sound/smaf/chunk/BitmapChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/BitmapChunk.java
@@ -7,7 +7,6 @@
package vavi.sound.smaf.chunk;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import vavi.sound.smaf.InvalidSmafDataException;
@@ -37,9 +36,9 @@ public BitmapChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
-skip(is, size); // TODO
+dis.skipBytes((int) (long) size); // TODO
}
/** TODO */
diff --git a/src/main/java/vavi/sound/smaf/chunk/Chunk.java b/src/main/java/vavi/sound/smaf/chunk/Chunk.java
index fc22085..27f3b1f 100644
--- a/src/main/java/vavi/sound/smaf/chunk/Chunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/Chunk.java
@@ -6,8 +6,8 @@
package vavi.sound.smaf.chunk;
+import java.io.DataInput;
import java.io.DataInputStream;
-import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -16,6 +16,7 @@
import java.util.logging.Level;
import vavi.sound.smaf.InvalidSmafDataException;
+import vavi.util.ByteUtil;
import vavi.util.Debug;
import vavi.util.properties.PrefixedPropertiesFactory;
@@ -35,17 +36,6 @@ public abstract class Chunk {
/** Chunk size */
protected int size;
- /**
- * 親でカウントダウンしないで済むように。
- * (結局ややこしいだけちゃうん?)
- * @see #Chunk(byte[], int)
- * @see #available()
- * @see #read(InputStream)
- * @see #skip(InputStream,long)
- * @see #read(InputStream,byte[])
- */
- private int readSize;
-
/** */
public Chunk() {
}
@@ -55,18 +45,16 @@ protected Chunk(byte[] id, int size) {
this.id = id;
this.size = size;
-
- this.readSize = size;
}
/**
- * @param is Chunk Header は読み込み済みであること
+ * @param dis Chunk Header は読み込み済みであること
* @throws IOException
* @throws InvalidSmafDataException
* TODO Chunk -> constructor ???
* TODO parent を渡したいが為。
*/
- protected abstract void init(InputStream is, Chunk parent)
+ protected abstract void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException;
/** Chunk ID */
@@ -79,91 +67,6 @@ public int getSize() {
return size;
}
- /**
- * カウントダウンした結果
- * @see #readSize
- */
- protected int available() {
- return readSize;
- }
-
- /**
- * 勝手にカウントダウンしない InputStream から直接読み込んだ場合の補正用
- * @see #readSize
- */
- private void consume(int size) {
- readSize -= size;
- }
-
- /**
- * EOF チェック付きのユーティリティ
- * @see #readSize カウントダウンされます
- */
- protected void skip(InputStream is, long bytes) throws IOException {
- skipInternal(is, bytes);
- readSize -= bytes;
- }
-
- /**
- * EOF チェック付きのユーティリティ
- */
- private static void skipInternal(InputStream is, long bytes) throws IOException {
- long l = 0;
- while (bytes - l > 0) {
- long r = is.skip(bytes - l);
- if (r < 0) {
- throw new EOFException();
- }
- l += r;
- }
- }
-
- /**
- * EOF チェック付きのユーティリティ
- * @see #readSize カウントダウンされます
- * @return unsigned byte
- */
- protected int read(InputStream is) throws IOException {
- DataInputStream dis = new DataInputStream(is);
- consume(1);
- return dis.readUnsignedByte();
- }
-
- /**
- * EOF チェック付きのユーティリティ
- * @see #readSize カウントダウンされます
- * @return unsigned short
- */
- protected int readShort(InputStream is) throws IOException {
- DataInputStream dis = new DataInputStream(is);
- consume(2);
- return dis.readUnsignedShort();
- }
-
- /**
- * EOF チェック付きのユーティリティ
- * buffer.length サイズ読み込まれます。
- * @see #readSize カウントダウンされます
- */
- protected void read(InputStream is, byte[] buffer) throws IOException {
- readInternal(is, buffer);
- consume(buffer.length);
- }
-
- /**
- * EOF チェック付きのユーティリティ
- */
- private static void readInternal(InputStream is, byte[] buffer) throws IOException {
- int l = 0;
- while (buffer.length - l > 0) {
- int r = is.read(buffer, l, buffer.length - l);
- if (r < 0) {
- throw new EOFException();
- }
- l += r;
- }
- }
-
/**
* 最初でない親の読み込み用(マーク無し)
* @param is
@@ -172,62 +75,54 @@ private static void readInternal(InputStream is, byte[] buffer) throws IOExcepti
protected Chunk readFrom(InputStream is)
throws InvalidSmafDataException, IOException {
- return readFrom(is, this, false);
+ return readFrom(is, this);
}
/**
* @param is should support marking
* @param parent 親のデータが欲しい時があるので
- * @param mark Chunk Header を読み込んだあと破棄するかどうか(最初だけ使う)
* @return 読み込んだ Chunk オブジェクト
- * @see #readSize parent != null ならカウントダウンされます
- * @throws IOException when is does not support marking
*/
- public static Chunk readFrom(InputStream is, Chunk parent, boolean mark)
+ public static Chunk readFrom(InputStream is, Chunk parent)
throws InvalidSmafDataException, IOException {
- if (mark && !is.markSupported()) {
- throw new IOException("cannot mark to stream");
- }
-
- if (mark) {
- is.mark(8);
+ DataInputStream dis;
+ if (is instanceof MyDataInputStream) {
+ MyDataInputStream mdis = MyDataInputStream.class.cast(is);
+ dis = new DataInputStream(mdis.is);
+ } else {
+ dis = new DataInputStream(is);
}
byte[] id = new byte[4];
- readInternal(is, id);
+ dis.readFully(id); // not want to count down
- DataInputStream dis = new DataInputStream(is);
int size = dis.readInt();
-Debug.printf(Level.FINE, "size: %1$08x (%1$d)", size);
-
- if (mark) {
- is.reset();
- is.mark(8 + size);
- skipInternal(is, 8);
- }
+Debug.printf(Level.FINE, "size: 0x%1$08x (%1$d)", size);
Chunk chunk = newInstance(id, size);
- chunk.init(is, parent);
-
- if (mark) {
- is.reset();
-
- is.mark(8 + size);
- int crcLength = size + 8 - 2;
- byte[] buffer = new byte[crcLength];
- readInternal(is, buffer);
-
- CRC16 crc = new CRC16();
- crc.update(buffer);
-Debug.printf(Level.FINE, "crc (calc): %04x", (int) ~crc.getValue());
-
- is.reset();
- }
+//Debug.println(chunk.getClass().getName() + "\n" + StringUtil.getDump(is, 0, 128));
+//Debug.printf(Level.FINE, "is: " + is + " / " + chunk.getClass().getName());
+ MyDataInputStream mdis = new MyDataInputStream(is, id, size);
+//Debug.printf(Level.FINE, "mdis: " + mdis + " / " + chunk.getClass().getName());
+ chunk.init(mdis, parent);
if (parent != null) {
// 親のループ内での読み込みの場合
- parent.consume(8 + chunk.getSize());
+ if (is instanceof MyDataInputStream) {
+ mdis = MyDataInputStream.class.cast(is);
+ mdis.readSize -= 8 + chunk.getSize();
+ } else {
+ assert false : "is: " + is.getClass().getName();
+ }
+ } else {
+//Debug.printf(Level.FINE, "crc (calc): %04x, avail: %d, %s, %s", mdis.crc(), mdis.available(), mdis, chunk.getClass().getName());
+ if (chunk instanceof FileChunk) {
+ FileChunk fc = FileChunk.class.cast(chunk);
+ if (fc.getCrc() != mdis.crc()) {
+Debug.printf(Level.WARNING, "crc not match expected: %04x, actural: %04x", fc.getCrc(), mdis.crc());
+ }
+ }
}
return chunk;
@@ -238,6 +133,124 @@ public static Chunk readFrom(InputStream is, Chunk parent, boolean mark)
//----
+ /** input stream with count down, crc */
+ protected static class MyDataInputStream extends InputStream implements DataInput {
+ InputStream is;
+ DataInputStream dis;
+ int readSize;
+ static ThreadLocal crc = new ThreadLocal<>();
+
+ protected MyDataInputStream(InputStream is, byte[] id, int size) {
+ if (is instanceof MyDataInputStream) {
+ MyDataInputStream mdis = MyDataInputStream.class.cast(is);
+ this.is = mdis.is;
+ } else {
+ this.is = is;
+ }
+//Debug.printf(Level.FINE, "is: " + this.is);
+ this.dis = new DataInputStream(this.is);
+ this.readSize = size;
+
+ if (crc.get() == null) {
+ crc.set(new CRC16());
+ }
+ crc.get().update(id);
+ crc.get().update(ByteUtil.getBeBytes(size));
+ }
+ public int crc() {
+//Debug.println("crc len: " + crc.get().getCount());
+ return (int) crc.get().getValue();
+ }
+ @Override
+ public long skip(long n) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public int available() throws IOException {
+ return readSize;
+ }
+ @Override
+ public int readUnsignedByte() throws IOException {
+ int r = dis.readUnsignedByte();
+ crc.get().update((byte) r);
+ readSize--;
+ return r;
+ }
+ @Override
+ public void readFully(byte[] b) throws IOException {
+ dis.readFully(b, 0, b.length);
+ crc.get().update(b);
+ readSize -= b.length;
+ }
+ @Override
+ public int read() throws IOException {
+ return is.read();
+ }
+ @Override
+ public void readFully(byte[] b, int off, int len) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public int skipBytes(int n) throws IOException {
+ byte[] b = new byte[n];
+ dis.readFully(b);
+ crc.get().update(b);
+ readSize -= n;
+ return n;
+ }
+ @Override
+ public boolean readBoolean() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public byte readByte() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public short readShort() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public int readUnsignedShort() throws IOException {
+ int r = dis.readUnsignedShort();
+ if (available() > 2) {
+ // crc is located at last of the file
+ // and this condition assumed to get crc uses this method.
+ crc.get().update(ByteUtil.getBeBytes((short) r));
+ }
+ readSize -= 2;
+ return r;
+ }
+ @Override
+ public char readChar() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public int readInt() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public long readLong() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public float readFloat() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public double readDouble() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public String readLine() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public String readUTF() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ }
+
/** CCITT X.25 */
static class CRC16 {
/** number of bits in a char */
@@ -264,6 +277,7 @@ static class CRC16 {
/** */
int crc = 0xffff;
+ int count;
/**
* 16 ビットの CRC を方法 1 で求めます。
* @param c データを与えます。
@@ -272,6 +286,7 @@ static class CRC16 {
public int update(byte[] c) {
for (int n = 0; n < c.length; n++) {
crc = (crc << BYTE_BIT) ^ crcTable[((crc >> (16 - BYTE_BIT)) & 0xff) ^ (c[n] & 0xff)];
+ count++;
}
return ~crc & 0xffff;
}
@@ -279,73 +294,25 @@ public int update(byte[] c) {
/** */
public int update(byte c) {
crc = (crc << BYTE_BIT) ^ crcTable[((crc >> (16 - BYTE_BIT)) & 0xff) ^ (c & 0xff)];
+ count++;
return ~crc & 0xffff;
}
/** */
- public long getValue() {
- return crc;
- }
- }
-
- //----
-
- /**
- * read 1 ~ 2 bytes
- * @return 0〜127, 128〜16511 (0x407f)
- */
- protected int readOneToTwo(InputStream is)
- throws IOException {
-
- int value;
- int d1 = read(is);
-//Debug.println("d1: " + d1 + "(" + StringUtil.toHex2(d1) + ")");
- if ((0x80 & d1) != 0) { // ---- 0x80 ~ 0xff, ----
- int d2 = read(is);
-//Debug.println("d2: " + d2 + "(" + StringUtil.toHex2(d2) + ")");
- value = (((d1 & 0x7f) + 1) << 7) | (d2 & 0x7f);
- } else { // ---- 0x01 ~ 0x7f, ----
- value = d1 & 0x7f;
+ public int getValue() {
+ return ~crc & 0xffff;
}
-//Debug.println("value: " + value);
- return value;
- }
- /**
- * read 1 ~ 4 bytes
- * @return 0 ~ 268435455 (0x0fffffff)
- */
- protected int readOneToFour(InputStream is)
- throws IOException {
-
- int value;
- int d1 = read(is);
- if ((0x80 & d1) != 0) {
- int d2 = read(is);
- if ((0x80 & d2) != 0) {
- int d3 = read(is);
- if ((0x80 & d3) != 0) {
- int d4 = read(is);
- value = ((d1 & 0x7f) << 21) | ((d2 & 0x7f) << 14) | ((d3 & 0x7f) << 7) | (d4 & 0x7f);
-//Debug.println("1-4(4): " + value);
- } else {
- value = ((d1 & 0x7f) << 14) | ((d2 & 0x7f) << 7) | (d3 & 0x7f);
-//Debug.println("1-4(3): " + value);
- }
- } else {
- value = ((d1 & 0x7f) << 7) | (d2 & 0x7f); // 128 ~
-//Debug.println("1-4(2): " + value);
- }
- } else {
- value = d1 & 0x7f; // 0 ~ 127
-//Debug.println("1-4(1): " + value);
+ /** */
+ public int getCount() {
+ return count;
}
- return value;
- }
+}
//----
/**
+ * factory
* @param id a chunk id read
* @param size
* @return chunk
@@ -356,29 +323,30 @@ private static Chunk newInstance(byte[] id, int size)
try {
return chunkFactory.get(id).newInstance(id, size);
} catch (IllegalArgumentException e) {
+Debug.println(Level.FINE, e);
return new UndefinedChunk(id, size); // TODO out source
// throw new InvalidSmafDataException("unsupported chunk id: " + StringUtil.getDump(id));
} catch (Exception e) {
if (e instanceof InvocationTargetException) {
-Debug.printStackTrace(e.getCause());
+Debug.printStackTrace(Level.SEVERE, e.getCause());
} else {
-Debug.printStackTrace(e);
+Debug.printStackTrace(Level.SEVERE, e);
}
throw new IllegalStateException(e);
}
}
- /** */
+ /** prefix for property file */
private static final String keyBase = "chunk.";
- /** */
+ /** constructors for factory */
private static final PrefixedPropertiesFactory> chunkFactory =
new PrefixedPropertiesFactory>("/vavi/sound/smaf/smaf.properties", keyBase) {
@Override
public Constructor extends Chunk> get(byte[] id) {
String type = new String(id);
-Debug.printf(Level.FINE, "Chunk ID(read): %s+0x%02x", (Character.isLetterOrDigit(type.charAt(3)) ? type : new String(id, 0, 3)), type.charAt(3));
+Debug.printf(Level.FINE, "Chunk ID(read): %s+0x%02x", (Character.isLetterOrDigit(type.charAt(3)) ? type : new String(id, 0, 3)), (int) type.charAt(3));
for (String key : instances.keySet()) {
if (key.charAt(3) == '*' && key.substring(0, 3).equals(type.substring(0, 3))) {
diff --git a/src/main/java/vavi/sound/smaf/chunk/ColorPaletteDefinitionChunk.java b/src/main/java/vavi/sound/smaf/chunk/ColorPaletteDefinitionChunk.java
index 3ba382f..e4a1c1f 100644
--- a/src/main/java/vavi/sound/smaf/chunk/ColorPaletteDefinitionChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/ColorPaletteDefinitionChunk.java
@@ -8,7 +8,6 @@
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import vavi.sound.smaf.InvalidSmafDataException;
@@ -37,9 +36,9 @@ public ColorPaletteDefinitionChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
-skip(is, size);
+dis.skipBytes((int) (long) size);
}
/** */
diff --git a/src/main/java/vavi/sound/smaf/chunk/ContentsInfoChunk.java b/src/main/java/vavi/sound/smaf/chunk/ContentsInfoChunk.java
index 3c39fd5..4cd978a 100644
--- a/src/main/java/vavi/sound/smaf/chunk/ContentsInfoChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/ContentsInfoChunk.java
@@ -8,11 +8,11 @@
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.TreeMap;
+import java.util.logging.Level;
import vavi.sound.smaf.InvalidSmafDataException;
import vavi.util.Debug;
@@ -49,30 +49,30 @@ public ContentsInfoChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
- this.contentsClass = read(is);
-Debug.println("contentsClass: " + (contentsClass == 0 ? "YAMAHA" : "Vender ID(" + contentsClass + ")"));
- this.contentsType = read(is);
-Debug.printf("contentsType: 0x02x\n", contentsType);
- this.contentsCodeType = read(is);
-Debug.printf("contentsCodeType: 0x02x\n", contentsCodeType);
- this.copyStatus = read(is);
-Debug.println("copyStatus: " + StringUtil.toBits(copyStatus, 8));
- this.copyCounts = read(is);
-Debug.println("copyCounts: " + copyCounts);
+ this.contentsClass = dis.readUnsignedByte();
+Debug.println(Level.FINE, "contentsClass: " + (contentsClass == 0 ? "YAMAHA" : "Vender ID(" + contentsClass + ")"));
+ this.contentsType = dis.readUnsignedByte();
+Debug.printf(Level.FINE, "contentsType: 0x%02x\n", contentsType);
+ this.contentsCodeType = dis.readUnsignedByte();
+Debug.printf(Level.FINE, "contentsCodeType: 0x%02x\n", contentsCodeType);
+ this.copyStatus = dis.readUnsignedByte();
+Debug.println(Level.FINE, "copyStatus: " + StringUtil.toBits(copyStatus, 8));
+ this.copyCounts = dis.readUnsignedByte();
+Debug.println(Level.FINE, "copyCounts: " + copyCounts);
byte[] option = new byte[size - 5];
- read(is, option);
-Debug.println("option: " + option.length + " bytes (subData)");
+ dis.readFully(option);
+Debug.println(Level.FINE, "option: " + option.length + " bytes (subData)");
int i = 0;
while (i < option.length) {
-//Debug.println(i + " / " + option.length + "\n" + StringUtil.getDump(option, i, option.length - i));
+Debug.println(Level.FINER, i + " / " + option.length + "\n" + StringUtil.getDump(option, i, option.length - i));
SubData subDatum = new SubData(option, i, contentsCodeType);
subData.put(subDatum.getTag(), subDatum);
-Debug.println("ContentsInfo: subDatum: " + subDatum);
+Debug.println(Level.FINE, "ContentsInfo: subDatum: " + subDatum);
i += 2 + 1 + subDatum.getData().length + 1; // tag ':' data ','
-//Debug.println(i + " / " + option.length + "\n" + StringUtil.getDump(option, i, option.length - i));
+Debug.println(Level.FINER, i + " / " + option.length + "\n" + StringUtil.getDump(option, i, option.length - i));
}
}
diff --git a/src/main/java/vavi/sound/smaf/chunk/DataChunk.java b/src/main/java/vavi/sound/smaf/chunk/DataChunk.java
index 7e1b980..fac4588 100644
--- a/src/main/java/vavi/sound/smaf/chunk/DataChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/DataChunk.java
@@ -6,13 +6,14 @@
package vavi.sound.smaf.chunk;
+import java.io.DataInput;
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.TreeMap;
+import java.util.logging.Level;
import vavi.sound.smaf.InvalidSmafDataException;
import vavi.util.Debug;
@@ -34,7 +35,7 @@ public DataChunk(byte[] id, int size) {
super(id, size);
this.languageCode = id[3] & 0xff;
-Debug.println("Data: lang: " + languageCode + ", size: " + size);
+Debug.println(Level.FINE, "Data: lang: " + languageCode + ", size: " + size);
}
/** */
@@ -44,17 +45,17 @@ public DataChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
-//Debug.println("available: " + available());
- while (available() > 4) { // TODO 正常ファイルは 0 でいい
- SubData subDatum = new SubData(is);
-Debug.println(subDatum);
+Debug.println(Level.FINER, "available: " + dis.available());
+ while (dis.available() > 4) { // TODO 正常ファイルは 0 でいい
+ SubData subDatum = new SubData(dis);
+Debug.println(Level.FINE, subDatum);
subData.put(subDatum.tag, subDatum);
-//Debug.println("SubData: " + subDatum.tag + ", " + subDatum.data.length + ", " + available());
+Debug.println(Level.FINER, "SubData: " + subDatum.tag + ", " + subDatum.data.length + ", " + dis.available());
}
- skip(is, available()); // TODO 正常ファイルなら必要なし
+ dis.skipBytes(dis.available()); // TODO 正常ファイルなら必要なし
}
/** */
@@ -128,15 +129,15 @@ boolean isUnicode(int languageCode) {
class SubData {
/** */
- SubData(InputStream is) throws IOException {
+ SubData(DataInput di) throws IOException {
byte[] temp = new byte[2];
- read(is, temp);
+ di.readFully(temp);
this.tag = new String(temp);
- int size = readShort(is);
+ int size = di.readUnsignedShort();
this.data = new byte[size];
- read(is, this.data);
+ di.readFully(this.data);
}
/** */
@@ -181,7 +182,7 @@ public String toString() {
if (printable) {
return "SubData(" + new String(tag) + ", lang: " + getLanguageCode() + ", size: " + data.length + "): " + string;
} else {
- return "SubData(" + new String(tag) + ", lang: " + getLanguageCode() + ", size: " + data.length + ")\n" + StringUtil.getDump(data);
+ return "SubData(" + new String(tag) + ", lang: " + getLanguageCode() + ", size: " + data.length + ")\n" + StringUtil.getDump(data, 128);
}
} catch (UnsupportedEncodingException e) {
assert false;
diff --git a/src/main/java/vavi/sound/smaf/chunk/DisplayParameterDefinitionChunk.java b/src/main/java/vavi/sound/smaf/chunk/DisplayParameterDefinitionChunk.java
index 10ff027..fd7d2d6 100644
--- a/src/main/java/vavi/sound/smaf/chunk/DisplayParameterDefinitionChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/DisplayParameterDefinitionChunk.java
@@ -8,11 +8,11 @@
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
+import vavi.sound.midi.MidiUtil;
import vavi.sound.smaf.InvalidSmafDataException;
import vavi.util.Debug;
@@ -40,19 +40,19 @@ public DisplayParameterDefinitionChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
int i = 0;
while (i < size) {
- int eventSize = readOneToTwo(is);
- int eventType = read(is);
+ int eventSize = MidiUtil.readVariableLength(dis);
+ int eventType = dis.readUnsignedByte();
Event event = new Event();
event.eventType = eventType;
Debug.println("event: " + eventType);
for (int j = 0; j < ((eventSize - 1) / 2); j++) {
- int parameterId = read(is);
- int parameterValue = read(is);
+ int parameterId = dis.readUnsignedByte();
+ int parameterValue = dis.readUnsignedByte();
Event.Parameter parameter = new Event.Parameter();
parameter.parameterID = ParameterID.valueOf(parameterId);
parameter.value = parameterValue;
diff --git a/src/main/java/vavi/sound/smaf/chunk/FileChunk.java b/src/main/java/vavi/sound/smaf/chunk/FileChunk.java
index 74559d9..85812d2 100644
--- a/src/main/java/vavi/sound/smaf/chunk/FileChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/FileChunk.java
@@ -9,7 +9,6 @@
import java.io.DataOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
@@ -41,11 +40,11 @@ public FileChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
- while (available() > 2) {
- Chunk chunk = readFrom(is);
+ while (dis.available() > 2) {
+ Chunk chunk = readFrom(dis);
if (chunk instanceof ContentsInfoChunk) {
contentsInfoChunk = chunk;
} else if (chunk instanceof OptionalDataChunk) {
@@ -64,11 +63,11 @@ protected void init(InputStream is, Chunk parent)
}
}
//Debug.println("available: " + is.available());
- this.crc = readShort(is);
+ this.crc = dis.readUnsignedShort();
Debug.printf("crc (orig): %04x\n", crc);
- if (is.available() > 4) {
- int kddiCrc = readShort(is);
- int kddiMark = readShort(is);
+ if (dis.available() > 4) {
+ int kddiCrc = dis.readUnsignedShort();
+ int kddiMark = dis.readUnsignedShort();
Debug.printf("has kddi crc: %04x, %04x\n", kddiCrc, kddiMark);
}
}
diff --git a/src/main/java/vavi/sound/smaf/chunk/GraphicsSetupDataChunk.java b/src/main/java/vavi/sound/smaf/chunk/GraphicsSetupDataChunk.java
index cdfa2d8..104c452 100644
--- a/src/main/java/vavi/sound/smaf/chunk/GraphicsSetupDataChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/GraphicsSetupDataChunk.java
@@ -8,7 +8,6 @@
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Level;
@@ -39,9 +38,9 @@ public GraphicsSetupDataChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent) throws InvalidSmafDataException, IOException {
- while (available() > 0) {
- Chunk chunk = readFrom(is);
+ protected void init(MyDataInputStream dis, Chunk parent) throws InvalidSmafDataException, IOException {
+ while (dis.available() > 0) {
+ Chunk chunk = readFrom(dis);
if (chunk instanceof DisplayParameterDefinitionChunk) {
displayParameterDefinitionChunk = chunk;
} else if (chunk instanceof ColorPaletteDefinitionChunk) {
diff --git a/src/main/java/vavi/sound/smaf/chunk/GraphicsTrackChunk.java b/src/main/java/vavi/sound/smaf/chunk/GraphicsTrackChunk.java
index 445d96f..d1256f3 100644
--- a/src/main/java/vavi/sound/smaf/chunk/GraphicsTrackChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/GraphicsTrackChunk.java
@@ -8,7 +8,6 @@
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
@@ -16,7 +15,7 @@
import java.util.Map;
import java.util.logging.Level;
-import vavi.sound.midi.MidiConstants;
+import vavi.sound.midi.MidiConstants.MetaEvent;
import vavi.sound.smaf.InvalidSmafDataException;
import vavi.sound.smaf.MetaMessage;
import vavi.sound.smaf.SmafEvent;
@@ -55,23 +54,23 @@ public GraphicsTrackChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
//skip(is, size);
- this.formatType = FormatType.values()[read(is)];
+ this.formatType = FormatType.values()[dis.readUnsignedByte()];
- this.playerType = read(is);
- this.textEncodeType = read(is);
- this.colorType = read(is);
- this.durationTimeBase = read(is);
+ this.playerType = dis.readUnsignedByte();
+ this.textEncodeType = dis.readUnsignedByte();
+ this.colorType = dis.readUnsignedByte();
+ this.durationTimeBase = dis.readUnsignedByte();
- int optionSize = read(is);
+ int optionSize = dis.readUnsignedByte();
this.optionData = new byte[optionSize];
- read(is, optionData);
+ dis.readFully(optionData);
- while (available() > 0) {
- Chunk chunk = readFrom(is);
+ while (dis.available() > 0) {
+ Chunk chunk = readFrom(dis);
if (chunk instanceof GraphicsSetupDataChunk) {
setupDataChunk = chunk;
} else if (chunk instanceof GraphicsTrackSequenceDataChunk) {
@@ -161,7 +160,7 @@ public List getSmafEvents() throws InvalidSmafDataException {
props.put("timeBase", durationTimeBase);
MetaMessage metaMessage = new MetaMessage();
- metaMessage.setMessage(MidiConstants.META_MACHINE_DEPEND, props);
+ metaMessage.setMessage(MetaEvent.META_MACHINE_DEPEND.number(), props);
events.add(new SmafEvent(metaMessage, 0l));
return null; // TODO
@@ -172,9 +171,9 @@ public static class FontDataChunk extends Chunk {
// "Ge**” :Font Chunk
// "Gu**” :Unicode Font Chunk
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
-skip(is, size); // TODO
+dis.skipBytes((int) (long) size); // TODO
}
/** TODO */
diff --git a/src/main/java/vavi/sound/smaf/chunk/GraphicsTrackSequenceDataChunk.java b/src/main/java/vavi/sound/smaf/chunk/GraphicsTrackSequenceDataChunk.java
index ec55e75..e9ca304 100644
--- a/src/main/java/vavi/sound/smaf/chunk/GraphicsTrackSequenceDataChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/GraphicsTrackSequenceDataChunk.java
@@ -6,9 +6,10 @@
package vavi.sound.smaf.chunk;
+import java.io.DataInputStream;
import java.io.IOException;
-import java.io.InputStream;
+import vavi.sound.midi.MidiUtil;
import vavi.sound.smaf.InvalidSmafDataException;
import vavi.sound.smaf.SmafMessage;
import vavi.sound.smaf.chunk.TrackChunk.FormatType;
@@ -50,13 +51,13 @@ public GraphicsTrackSequenceDataChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
FormatType formatType = ((TrackChunk) parent).getFormatType();
switch (formatType) {
case HandyPhoneStandard:
- readHandyPhoneStandard(is);
+ readHandyPhoneStandard(dis);
break;
default:
throw new InvalidSmafDataException("FormatType: " + formatType);
@@ -65,17 +66,17 @@ protected void init(InputStream is, Chunk parent)
}
/** formatType 0 */
- protected void readHandyPhoneStandard(InputStream is)
+ protected void readHandyPhoneStandard(DataInputStream dis)
throws InvalidSmafDataException, IOException {
SmafMessage smafMessage = null;
- while (available() > 0) {
+ while (dis.available() > 0) {
// -------- duration --------
- int duration = readOneToTwo(is);
+ int duration = MidiUtil.readVariableLength(dis);
//Debug.println("duration: " + duration + ", 0x" + StringUtil.toHex4(duration));
// -------- event --------
- int e1 = read(is);
+ int e1 = dis.readUnsignedByte();
switch (e1) {
case 0x00: // short event
smafMessage = new NopMessage(duration);
@@ -84,33 +85,33 @@ protected void readHandyPhoneStandard(InputStream is)
smafMessage = new ResetOrigneMessage(duration);
break;
case 0x20: { // control event
- int size = readOneToTwo(is);
+ int size = MidiUtil.readVariableLength(dis);
byte[] data = new byte[size];
- read(is, data);
+ dis.readFully(data);
smafMessage = new BackDropColorDefinitionMessage(duration, data);
} break;
case 0x21: { // control event
- int size = readOneToTwo(is);
+ int size = MidiUtil.readVariableLength(dis);
byte[] data = new byte[size];
- read(is, data);
+ dis.readFully(data);
smafMessage = new OffsetOriginMessage(duration, data);
} break;
case 0x22: { // control event
- int size = readOneToTwo(is);
+ int size = MidiUtil.readVariableLength(dis);
byte[] data = new byte[size];
- read(is, data);
+ dis.readFully(data);
smafMessage = new UserMessage(duration, data);
} break;
case 0x40: { // display object event
- int size = readOneToTwo(is);
+ int size = MidiUtil.readVariableLength(dis);
byte[] data = new byte[size];
- read(is, data);
+ dis.readFully(data);
smafMessage = new GeneralPurposeDisplayMessage(duration, e1, data);
} break;
default: {
- int size = readOneToTwo(is);
+ int size = MidiUtil.readVariableLength(dis);
byte[] data = new byte[size];
- read(is, data);
+ dis.readFully(data);
smafMessage = new UndefinedMessage(duration);
Debug.printf("reserved: %02x\n", e1);
} break;
diff --git a/src/main/java/vavi/sound/smaf/chunk/ImageChunk.java b/src/main/java/vavi/sound/smaf/chunk/ImageChunk.java
index b18c6cc..7950ad0 100644
--- a/src/main/java/vavi/sound/smaf/chunk/ImageChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/ImageChunk.java
@@ -9,7 +9,6 @@
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
@@ -46,11 +45,11 @@ public ImageChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
this.imageData = new byte[size];
- read(is, imageData);
+ dis.readFully(imageData);
Debug.println("image: " + getImage());
}
diff --git a/src/main/java/vavi/sound/smaf/chunk/ImageDataChunk.java b/src/main/java/vavi/sound/smaf/chunk/ImageDataChunk.java
index 5c933d8..4fdac79 100644
--- a/src/main/java/vavi/sound/smaf/chunk/ImageDataChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/ImageDataChunk.java
@@ -7,7 +7,6 @@
package vavi.sound.smaf.chunk;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
@@ -40,11 +39,11 @@ public ImageDataChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
- while (available() > 0) {
- Chunk chunk = readFrom(is);
+ while (dis.available() > 0) {
+ Chunk chunk = readFrom(dis);
if (chunk instanceof ImageChunk) { // "Gig*"
imageDataChunks.add(chunk);
} else if (chunk instanceof BitmapChunk) { // ""
diff --git a/src/main/java/vavi/sound/smaf/chunk/LinkChunk.java b/src/main/java/vavi/sound/smaf/chunk/LinkChunk.java
index 3a32a00..586dd9f 100644
--- a/src/main/java/vavi/sound/smaf/chunk/LinkChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/LinkChunk.java
@@ -7,7 +7,6 @@
package vavi.sound.smaf.chunk;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import vavi.sound.smaf.InvalidSmafDataException;
@@ -37,9 +36,9 @@ public LinkChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
-skip(is, size); // TODO
+dis.skipBytes((int) (long) size); // TODO
}
/** TODO */
diff --git a/src/main/java/vavi/sound/smaf/chunk/MasterTrackChunk.java b/src/main/java/vavi/sound/smaf/chunk/MasterTrackChunk.java
index 8d3bb7b..9db2794 100644
--- a/src/main/java/vavi/sound/smaf/chunk/MasterTrackChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/MasterTrackChunk.java
@@ -7,7 +7,6 @@
package vavi.sound.smaf.chunk;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.logging.Level;
@@ -34,21 +33,21 @@ public MasterTrackChunk(byte[] id, int size) {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
- this.formatType = FormatType.values()[read(is)];
- this.sequenceType = SequenceType.values()[read(is)];
+ this.formatType = FormatType.values()[dis.readUnsignedByte()];
+ this.sequenceType = SequenceType.values()[dis.readUnsignedByte()];
Debug.println("sequenceType: " + sequenceType);
- this.durationTimeBase = read(is);
+ this.durationTimeBase = dis.readUnsignedByte();
//Debug.println("durationTimeBase: " + StringUtil.toHex2(durationTimeBase));
- int optionSize = read(is);
+ int optionSize = dis.readUnsignedByte();
this.optionData = new byte[optionSize];
- read(is, optionData);
+ dis.readFully(optionData);
- while (available() > 0) {
+ while (dis.available() > 0) {
//Debug.println("available: " + is.available() + ", " + available());
- Chunk chunk = readFrom(is);
+ Chunk chunk = readFrom(dis);
if (chunk instanceof MasterTrackSequenceDataChunk) { // "Mssq"
sequenceDataChunk = chunk;
} else {
diff --git a/src/main/java/vavi/sound/smaf/chunk/MasterTrackSequenceDataChunk.java b/src/main/java/vavi/sound/smaf/chunk/MasterTrackSequenceDataChunk.java
index 6546eb7..ee270dd 100644
--- a/src/main/java/vavi/sound/smaf/chunk/MasterTrackSequenceDataChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/MasterTrackSequenceDataChunk.java
@@ -7,7 +7,6 @@
package vavi.sound.smaf.chunk;
import java.io.IOException;
-import java.io.InputStream;
import vavi.sound.smaf.InvalidSmafDataException;
import vavi.util.Debug;
@@ -30,9 +29,9 @@ public MasterTrackSequenceDataChunk(byte[] id, int size) {
}
/** TODO how to get formatType from parent chunk ??? */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
-skip(is, size); // TODO
+dis.skipBytes((int) (long) size); // TODO
}
}
diff --git a/src/main/java/vavi/sound/smaf/chunk/OptionalDataChunk.java b/src/main/java/vavi/sound/smaf/chunk/OptionalDataChunk.java
index fa02e8d..548c83c 100644
--- a/src/main/java/vavi/sound/smaf/chunk/OptionalDataChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/OptionalDataChunk.java
@@ -8,7 +8,6 @@
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
@@ -40,11 +39,11 @@ public OptionalDataChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
- while (available() > 0) {
- Chunk data = readFrom(is);
+ while (dis.available() > 0) {
+ Chunk data = readFrom(dis);
// TODO "Pro*"
dataChunks.add(data);
}
diff --git a/src/main/java/vavi/sound/smaf/chunk/PcmAudioTrackChunk.java b/src/main/java/vavi/sound/smaf/chunk/PcmAudioTrackChunk.java
index de707d1..dfb64b1 100644
--- a/src/main/java/vavi/sound/smaf/chunk/PcmAudioTrackChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/PcmAudioTrackChunk.java
@@ -8,7 +8,6 @@
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
@@ -16,7 +15,7 @@
import java.util.Map;
import java.util.logging.Level;
-import vavi.sound.midi.MidiConstants;
+import vavi.sound.midi.MidiConstants.MetaEvent;
import vavi.sound.smaf.InvalidSmafDataException;
import vavi.sound.smaf.MetaMessage;
import vavi.sound.smaf.SmafEvent;
@@ -49,25 +48,25 @@ public PcmAudioTrackChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
//skip(is, size);
- this.formatType = FormatType.values()[read(is)];
+ this.formatType = FormatType.values()[dis.readUnsignedByte()];
Debug.println("formatType: " + formatType);
- this.sequenceType = SequenceType.values()[read(is)];
+ this.sequenceType = SequenceType.values()[dis.readUnsignedByte()];
Debug.println("sequenceType: " + sequenceType);
- this.waveType = new WaveType(readShort(is));
+ this.waveType = new WaveType(dis.readUnsignedShort());
Debug.println("waveType: " + waveType);
- this.durationTimeBase = read(is);
+ this.durationTimeBase = dis.readUnsignedByte();
Debug.println("durationTimeBase: " + durationTimeBase + ", " + getDurationTimeBase() + " ms");
- this.gateTimeTimeBase = read(is);
+ this.gateTimeTimeBase = dis.readUnsignedByte();
Debug.println("gateTimeTimeBase: " + gateTimeTimeBase + ", " + getGateTimeTimeBase() + " ms");
- while (available() > 0) {
- Chunk chunk = readFrom(is);
+ while (dis.available() > 0) {
+ Chunk chunk = readFrom(dis);
if (chunk instanceof SeekAndPhraseInfoChunk) {
seekAndPhraseInfoChunk = chunk;
} else if (chunk instanceof AudioSequenceDataChunk) {
@@ -164,7 +163,7 @@ public List getSmafEvents() throws InvalidSmafDataException {
props.put("gateTimeTimeBase", timeBaseTable[gateTimeTimeBase]);
MetaMessage metaMessage = new MetaMessage();
- metaMessage.setMessage(MidiConstants.META_MACHINE_DEPEND, props);
+ metaMessage.setMessage(MetaEvent.META_MACHINE_DEPEND.number(), props);
events.add(new SmafEvent(metaMessage, 0l));
//
diff --git a/src/main/java/vavi/sound/smaf/chunk/ScoreTrackChunk.java b/src/main/java/vavi/sound/smaf/chunk/ScoreTrackChunk.java
index 30bcdf0..fb4f216 100644
--- a/src/main/java/vavi/sound/smaf/chunk/ScoreTrackChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/ScoreTrackChunk.java
@@ -8,7 +8,6 @@
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
@@ -16,7 +15,7 @@
import java.util.Map;
import java.util.logging.Level;
-import vavi.sound.midi.MidiConstants;
+import vavi.sound.midi.MidiConstants.MetaEvent;
import vavi.sound.smaf.InvalidSmafDataException;
import vavi.sound.smaf.MetaMessage;
import vavi.sound.smaf.SmafEvent;
@@ -57,21 +56,21 @@ public ScoreTrackChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
- this.formatType = FormatType.values()[read(is)];
- this.sequenceType = SequenceType.values()[read(is)];
+ this.formatType = FormatType.values()[dis.readUnsignedByte()];
+ this.sequenceType = SequenceType.values()[dis.readUnsignedByte()];
Debug.println("sequenceType: " + sequenceType);
- this.durationTimeBase = read(is);
+ this.durationTimeBase = dis.readUnsignedByte();
Debug.println("durationTimeBase: " + durationTimeBase + ", " + getDurationTimeBase() + " ms");
- this.gateTimeTimeBase = read(is);
+ this.gateTimeTimeBase = dis.readUnsignedByte();
Debug.println("gateTimeTimeBase: " + gateTimeTimeBase + ", " + getGateTimeTimeBase() + " ms");
switch (formatType) {
case HandyPhoneStandard: {
byte[] buffer = new byte[2];
- read(is, buffer);
+ dis.readFully(buffer);
//Debug.println(StringUtil.getDump(channelStatus));
this.channelStatuses = new ChannelStatus[4];
for (int i = 0; i < 4; i++) {
@@ -82,7 +81,7 @@ protected void init(InputStream is, Chunk parent)
case MobileStandard_Compress:
case MobileStandard_NoCompress: {
byte[] buffer = new byte[16];
- read(is, buffer);
+ dis.readFully(buffer);
this.channelStatuses = new ChannelStatus[16];
for (int i = 0; i < 16; i++) {
channelStatuses[i] = new ChannelStatus(i, (int) buffer[i]);
@@ -91,15 +90,15 @@ protected void init(InputStream is, Chunk parent)
} break;
case Unknown3: {
byte[] buffer = new byte[32];
- read(is, buffer);
+ dis.readFully(buffer);
// TODO implement
} break;
}
Debug.println("formatType: " + formatType);
- while (available() > 0) {
+ while (dis.available() > 0) {
//Debug.println("available: " + is.available() + ", " + available());
- Chunk chunk = readFrom(is);
+ Chunk chunk = readFrom(dis);
if (chunk instanceof SeekAndPhraseInfoChunk) {
seekAndPhraseInfoChunk = chunk;
} else if (chunk instanceof SequenceDataChunk) {
@@ -195,7 +194,7 @@ public List getSmafEvents() throws InvalidSmafDataException {
props.put("gateTimeTimeBase", timeBaseTable[gateTimeTimeBase]);
MetaMessage metaMessage = new MetaMessage();
- metaMessage.setMessage(MidiConstants.META_MACHINE_DEPEND, props);
+ metaMessage.setMessage(MetaEvent.META_MACHINE_DEPEND.number(), props);
events.add(new SmafEvent(metaMessage, 0l));
//
diff --git a/src/main/java/vavi/sound/smaf/chunk/SeekAndPhraseInfoChunk.java b/src/main/java/vavi/sound/smaf/chunk/SeekAndPhraseInfoChunk.java
index 4ce95a9..9131c8e 100644
--- a/src/main/java/vavi/sound/smaf/chunk/SeekAndPhraseInfoChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/SeekAndPhraseInfoChunk.java
@@ -8,7 +8,6 @@
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.List;
@@ -42,12 +41,12 @@ public SeekAndPhraseInfoChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
byte[] data = new byte[size];
Debug.println("SeekAndPhraseInfo: " + size + " bytes (subData)");
- read(is, data);
+ dis.readFully(data);
int i = 0;
while (i < size) {
diff --git a/src/main/java/vavi/sound/smaf/chunk/SequenceDataChunk.java b/src/main/java/vavi/sound/smaf/chunk/SequenceDataChunk.java
index 08d1a62..541cc82 100644
--- a/src/main/java/vavi/sound/smaf/chunk/SequenceDataChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/SequenceDataChunk.java
@@ -10,7 +10,6 @@
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
@@ -18,6 +17,7 @@
import java.util.Set;
import java.util.logging.Level;
+import vavi.sound.midi.MidiUtil;
import vavi.sound.smaf.InvalidSmafDataException;
import vavi.sound.smaf.SmafMessage;
import vavi.sound.smaf.SysexMessage;
@@ -62,19 +62,19 @@ public SequenceDataChunk() {
}
/** TODO how to get formatType from parent chunk ??? */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
//Debug.println("available: " + is.available() + ", " + available());
//skip(is, size);
ScoreTrackChunk.FormatType formatType = ((TrackChunk) parent).getFormatType();
switch (formatType) {
case HandyPhoneStandard:
- readHandyPhoneStandard(is);
+ readHandyPhoneStandard(dis);
break;
case MobileStandard_Compress:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for (int i = 0; i < size; i++) {
- baos.write(is.read());
+ baos.write(dis.read());
}
//OutputStream os1 = new FileOutputStream("/tmp/data.enc");
//os1.write(baos.toByteArray());
@@ -89,11 +89,11 @@ protected void init(InputStream is, Chunk parent)
//Debug.println("data.dec created");
Debug.println("decode: " + size + " -> " + decoded.length);
size = decoded.length;
- readMobileStandard(new ByteArrayInputStream(decoded));
+ readMobileStandard(new MyDataInputStream(new ByteArrayInputStream(decoded), id, decoded.length));
break;
case MobileStandard_NoCompress:
case Unknown3: // TODO
- readMobileStandard(is);
+ readMobileStandard(dis);
break;
}
Debug.println("messages: " + messages.size());
@@ -109,24 +109,24 @@ protected SmafMessage getHandyPhoneStandardMessage(int duration, int data, int g
}
/** formatType 0 */
- protected void readHandyPhoneStandard(InputStream is)
+ protected void readHandyPhoneStandard(MyDataInputStream dis)
throws InvalidSmafDataException, IOException {
SmafMessage smafMessage = null;
- while (available() > 0) {
+ while (dis.available() > 0) {
// -------- duration --------
- int duration = readOneToTwo(is);
+ int duration = MidiUtil.readVariableLength(dis);
//Debug.println("duration: " + duration + ", 0x" + StringUtil.toHex4(duration));
// -------- event --------
- int e1 = read(is);
+ int e1 = dis.readUnsignedByte();
if (e1 == 0xff) { // exclusive, nop
- int e2 = read(is);
+ int e2 = dis.readUnsignedByte();
switch (e2) {
case 0xf0: // exclusive
- int messageSize = read(is);
+ int messageSize = dis.readUnsignedByte();
byte[] data = new byte[messageSize];
- read(is, data);
+ dis.readFully(data);
// TODO end check 0xf7
smafMessage = SysexMessage.Factory.getSysexMessage(duration, data);
break;
@@ -139,13 +139,13 @@ protected void readHandyPhoneStandard(InputStream is)
break;
}
} else if (e1 != 0x00) { // note
- int gateTime = readOneToTwo(is);
+ int gateTime = MidiUtil.readVariableLength(dis);
//Debug.println("gateTime: " + gateTime + ", 0x" + StringUtil.toHex4(gateTime));
smafMessage = getHandyPhoneStandardMessage(duration, e1, gateTime);
} else { // e1 == 0x00 other event
- int e2 = read(is);
+ int e2 = dis.readUnsignedByte();
if (e2 == 0x00) {
- int e3 = read(is);
+ int e3 = dis.readUnsignedByte();
if (e3 == 0x00) {
smafMessage = new EndOfSequenceMessage(duration);
} else {
@@ -158,7 +158,7 @@ protected void readHandyPhoneStandard(InputStream is)
int data = e2 & 0x0f;
switch (event) {
case 3:
- int value = read(is);
+ int value = dis.readUnsignedByte();
switch (data) {
case 0: // program change - 0x00 ~ 0x7f
smafMessage = new ProgramChangeMessage(duration, channel, value);
@@ -224,37 +224,37 @@ protected void readHandyPhoneStandard(InputStream is)
private int cc = 0;
/** formatType 1, 2 */
- private void readMobileStandard(InputStream is)
+ private void readMobileStandard(MyDataInputStream dis)
throws InvalidSmafDataException, IOException {
SmafMessage smafMessage = null;
- while (available() > 0) {
+ while (dis.available() > 0) {
// duration
- int duration = readOneToFour(is);
+ int duration = MidiUtil.readVariableLength(dis);
//Debug.println("duration: " + duration);
// event
- int status = read(is);
+ int status = dis.readUnsignedByte();
if (status >= 0x80 && status <= 0x8f) { // note w/o velocity
int channel = status & 0x0f;
- int note = read(is);
- int gateTime = readOneToFour(is);
+ int note = dis.readUnsignedByte();
+ int gateTime = MidiUtil.readVariableLength(dis);
smafMessage = new NoteMessage(duration, channel, note, gateTime);
} else if (status >= 0x90 && status <= 0x9f) { // note w/ velocity
int channel = status & 0x0f;
- int note = read(is);
- int velocity = read(is);
- int gateTime = readOneToFour(is);
+ int note = dis.readUnsignedByte();
+ int velocity = dis.readUnsignedByte();
+ int gateTime = MidiUtil.readVariableLength(dis);
smafMessage = new NoteMessage(duration, channel, note, gateTime, velocity);
} else if (status >= 0xa0 && status <= 0xaf) { // reserved
- int d1 = read(is);
- int d2 = read(is);
+ int d1 = dis.readUnsignedByte();
+ int d2 = dis.readUnsignedByte();
smafMessage = null;
Debug.printf(Level.WARNING, "reserved: 0xa_: %02x%02x\n", d1, d2);
} else if (status >= 0xb0 && status <= 0xbf) { // control change
int channel = status & 0x0f;
- int control = read(is);
- int value = read(is);
+ int control = dis.readUnsignedByte();
+ int value = dis.readUnsignedByte();
switch (control) { // TODO no specification
case 0x00: // バンクセレクト MSB
smafMessage = new BankSelectMessage(duration, channel, value, BankSelectMessage.Significant.Least);
@@ -297,25 +297,25 @@ private void readMobileStandard(InputStream is)
}
} else if (status >= 0xc0 && status <= 0xcf) { // program change
int channel = status & 0x0f;
- int program = read(is);
+ int program = dis.readUnsignedByte();
smafMessage = new ProgramChangeMessage(duration, channel, program);
} else if (status >= 0xd0 && status <= 0xdf) { // reserved
- int d1 = read(is);
+ int d1 = dis.readUnsignedByte();
smafMessage = new UndefinedMessage(duration);
Debug.printf(Level.WARNING, "reserved: 0xd_: %02x\n", d1);
} else if (status >= 0xe0 && status <= 0xef) { // pitch vend message
int channel = status & 0x0f;
- int lsb = read(is);
- int msb = read(is);
+ int lsb = dis.readUnsignedByte();
+ int msb = dis.readUnsignedByte();
smafMessage = new PitchBendMessage(duration, channel, (msb << 7) | lsb);
} else if (status == 0xff) { // eos, nop
- int d1 = read(is);
+ int d1 = dis.readUnsignedByte();
switch (d1) {
case 0x00:
smafMessage = new NopMessage(duration);
break;
case 0x2f:
- int d2 = read(is); // must be 0
+ int d2 = dis.readUnsignedByte(); // must be 0
if (d2 != 0) {
Debug.printf(Level.WARNING, "illegal state: %02x\n", d2);
}
@@ -327,9 +327,9 @@ private void readMobileStandard(InputStream is)
break;
}
} else if (status == 0xf0) { // exclusive
- int messageSize = readOneToFour(is);
+ int messageSize = MidiUtil.readVariableLength(dis);
byte[] data = new byte[messageSize];
- read(is, data);
+ dis.readFully(data);
// TODO end check 0xf7
smafMessage = SysexMessage.Factory.getSysexMessage(duration, data);
} else if (status < 0x80) { // data
diff --git a/src/main/java/vavi/sound/smaf/chunk/SetupDataChunk.java b/src/main/java/vavi/sound/smaf/chunk/SetupDataChunk.java
index 2bd2361..5660f82 100644
--- a/src/main/java/vavi/sound/smaf/chunk/SetupDataChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/SetupDataChunk.java
@@ -8,12 +8,12 @@
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
+import vavi.sound.midi.MidiUtil;
import vavi.sound.smaf.InvalidSmafDataException;
import vavi.sound.smaf.SmafMessage;
import vavi.sound.smaf.SysexMessage;
@@ -44,19 +44,19 @@ public SetupDataChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent) throws InvalidSmafDataException, IOException {
+ protected void init(MyDataInputStream dis, Chunk parent) throws InvalidSmafDataException, IOException {
ScoreTrackChunk.FormatType formatType = ((ScoreTrackChunk) parent).getFormatType();
switch (formatType) {
case HandyPhoneStandard:
- readHandyPhoneStandard(is);
+ readHandyPhoneStandard(dis);
break;
case MobileStandard_Compress:
- readMobileStandard(is); // TODO Huffman
+ readMobileStandard(dis); // TODO Huffman
break;
case MobileStandard_NoCompress:
case Unknown3:
- readMobileStandard(is);
+ readMobileStandard(dis);
break;
}
Debug.println("messages: " + messages.size());
@@ -73,20 +73,20 @@ protected void init(InputStream is, Chunk parent) throws InvalidSmafDataExceptio
*
*
*/
- private void readHandyPhoneStandard(InputStream is) throws InvalidSmafDataException, IOException {
+ private void readHandyPhoneStandard(MyDataInputStream dis) throws InvalidSmafDataException, IOException {
SmafMessage smafMessage = null;
- while (available() > 0) {
+ while (dis.available() > 0) {
// -------- event --------
- int e1 = read(is);
+ int e1 = dis.readUnsignedByte();
if (e1 == 0xff) { // exclusive
- int e2 = read(is);
+ int e2 = dis.readUnsignedByte();
switch (e2) {
case 0xf0:
- int messageSize = read(is);
+ int messageSize = dis.readUnsignedByte();
byte[] data = new byte[messageSize];
- read(is, data);
+ dis.readFully(data);
// TODO end check 0xf7
smafMessage = SysexMessage.Factory.getSysexMessage(0, data);
break;
@@ -109,17 +109,17 @@ private void readHandyPhoneStandard(InputStream is) throws InvalidSmafDataExcept
}
/** formatType 1, 2 */
- private void readMobileStandard(InputStream is) throws InvalidSmafDataException, IOException {
+ private void readMobileStandard(MyDataInputStream dis) throws InvalidSmafDataException, IOException {
SmafMessage smafMessage = null;
- while (available() > 0) {
+ while (dis.available() > 0) {
// event
- int status = read(is);
+ int status = dis.readUnsignedByte();
if (status == 0xf0) { // exclusive
- int messageSize = readOneToFour(is);
+ int messageSize = MidiUtil.readVariableLength(dis);
byte[] data = new byte[messageSize];
- read(is, data);
+ dis.readFully(data);
// TODO end check 0xf7
smafMessage = SysexMessage.Factory.getSysexMessage(0, data);
} else {
diff --git a/src/main/java/vavi/sound/smaf/chunk/StreamPcmDataChunk.java b/src/main/java/vavi/sound/smaf/chunk/StreamPcmDataChunk.java
index bee7337..2402112 100644
--- a/src/main/java/vavi/sound/smaf/chunk/StreamPcmDataChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/StreamPcmDataChunk.java
@@ -8,7 +8,6 @@
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
@@ -43,9 +42,9 @@ public StreamPcmDataChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent) throws InvalidSmafDataException, IOException {
- while (available() > 0) {
- Chunk chunk = readFrom(is);
+ protected void init(MyDataInputStream dis, Chunk parent) throws InvalidSmafDataException, IOException {
+ while (dis.available() > 0) {
+ Chunk chunk = readFrom(dis);
if (chunk instanceof StreamWaveDataChunk) {
streamWaveDataChunks.add(chunk);
} else {
diff --git a/src/main/java/vavi/sound/smaf/chunk/StreamWaveDataChunk.java b/src/main/java/vavi/sound/smaf/chunk/StreamWaveDataChunk.java
index ad534e1..35a76cd 100644
--- a/src/main/java/vavi/sound/smaf/chunk/StreamWaveDataChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/StreamWaveDataChunk.java
@@ -7,7 +7,6 @@
package vavi.sound.smaf.chunk;
import java.io.IOException;
-import java.io.InputStream;
import vavi.sound.smaf.InvalidSmafDataException;
import vavi.sound.smaf.SmafMessage;
@@ -38,13 +37,13 @@ public StreamWaveDataChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent) throws InvalidSmafDataException, IOException {
+ protected void init(MyDataInputStream dis, Chunk parent) throws InvalidSmafDataException, IOException {
byte[] weveTypeBytes = new byte[3];
- read(is, weveTypeBytes);
+ dis.readFully(weveTypeBytes);
this.waveType = new WaveType(weveTypeBytes);
- data = new byte[available()];
- read(is, data);
+ data = new byte[dis.available()];
+ dis.readFully(data);
}
/** */
diff --git a/src/main/java/vavi/sound/smaf/chunk/UndefinedChunk.java b/src/main/java/vavi/sound/smaf/chunk/UndefinedChunk.java
index dd10974..22c275e 100644
--- a/src/main/java/vavi/sound/smaf/chunk/UndefinedChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/UndefinedChunk.java
@@ -7,7 +7,6 @@
package vavi.sound.smaf.chunk;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Level;
@@ -31,17 +30,23 @@ public UndefinedChunk(byte[] id, int size) {
}
/** */
- protected void init(InputStream is, Chunk parent)
+ protected void init(MyDataInputStream dis, Chunk parent)
throws InvalidSmafDataException, IOException {
+ if (size > dis.available()) {
+Debug.println(Level.WARNING, "read size is larger than available stream");
+//new Exception("*** DUMMY ***").printStackTrace(System.err);
+ throw new InvalidSmafDataException("read size is larger than available stream");
+ }
byte[] data = new byte[size];
- read(is, data);
+ dis.readFully(data);
Debug.println(Level.WARNING, "Undefined: size: " + size + "\n" + StringUtil.getDump(data, 64));
}
/** */
public void writeTo(OutputStream os) throws IOException {
// TODO
+Debug.println(Level.WARNING, "not implemented skip");
}
}
diff --git a/src/main/java/vavi/sound/smaf/chunk/WaveDataChunk.java b/src/main/java/vavi/sound/smaf/chunk/WaveDataChunk.java
index d84ddea..4721235 100644
--- a/src/main/java/vavi/sound/smaf/chunk/WaveDataChunk.java
+++ b/src/main/java/vavi/sound/smaf/chunk/WaveDataChunk.java
@@ -8,7 +8,6 @@
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import vavi.sound.smaf.InvalidSmafDataException;
@@ -42,9 +41,9 @@ public WaveDataChunk() {
}
/** */
- protected void init(InputStream is, Chunk parent) throws InvalidSmafDataException, IOException {
+ protected void init(MyDataInputStream dis, Chunk parent) throws InvalidSmafDataException, IOException {
data = new byte[size];
- read(is, data);
+ dis.readFully(data);
}
/** */
diff --git a/src/main/java/vavi/sound/smaf/chunk/package.html b/src/main/java/vavi/sound/smaf/chunk/readme.md
similarity index 64%
rename from src/main/java/vavi/sound/smaf/chunk/package.html
rename to src/main/java/vavi/sound/smaf/chunk/readme.md
index 79b25d8..a053586 100644
--- a/src/main/java/vavi/sound/smaf/chunk/package.html
+++ b/src/main/java/vavi/sound/smaf/chunk/readme.md
@@ -1,36 +1,14 @@
-
-
+# vavi.sound.smaf.chunk
-
-
-
-
-
-
-vavi.sound.smaf.chunk
-
-
-
-
-
-
- Copyright(C) 1996-2001 Takuya OOURA
- email: ooura@mmm.t.u-tokyo.ac.jp
- download: http://momonga.t.u-tokyo.ac.jp/~ooura/fft.html
- You may use, copy, modify this code for any purpose and
- without fee. You may distribute this ORIGINAL package.
-
-
-
I0Bessel
-
-
- Copyright(C) 1996 Takuya OOURA (email: ooura@mmm.t.u-tokyo.ac.jp).
- You may use, copy, modify this code for any purpose and
- without fee. You may distribute this ORIGINAL package.
-