summaryrefslogtreecommitdiff
path: root/songdbj/de
diff options
context:
space:
mode:
Diffstat (limited to 'songdbj/de')
-rw-r--r--songdbj/de/jarnbjo/ogg/BasicStream.java121
-rw-r--r--songdbj/de/jarnbjo/ogg/CachedUrlStream.java252
-rw-r--r--songdbj/de/jarnbjo/ogg/EndOfOggStreamException.java45
-rw-r--r--songdbj/de/jarnbjo/ogg/FileStream.java154
-rw-r--r--songdbj/de/jarnbjo/ogg/LogicalOggStream.java151
-rw-r--r--songdbj/de/jarnbjo/ogg/LogicalOggStreamImpl.java213
-rw-r--r--songdbj/de/jarnbjo/ogg/OggFormatException.java50
-rw-r--r--songdbj/de/jarnbjo/ogg/OggPage.java431
-rw-r--r--songdbj/de/jarnbjo/ogg/OnDemandUrlStream.java127
-rw-r--r--songdbj/de/jarnbjo/ogg/PhysicalOggStream.java124
-rw-r--r--songdbj/de/jarnbjo/ogg/UncachedUrlStream.java207
-rw-r--r--songdbj/de/jarnbjo/util/audio/FadeableAudioInputStream.java62
-rw-r--r--songdbj/de/jarnbjo/util/io/BitInputStream.java185
-rw-r--r--songdbj/de/jarnbjo/util/io/ByteArrayBitInputStream.java352
-rw-r--r--songdbj/de/jarnbjo/util/io/HuffmanNode.java144
-rw-r--r--songdbj/de/jarnbjo/vorbis/AudioPacket.java328
-rw-r--r--songdbj/de/jarnbjo/vorbis/CodeBook.java275
-rw-r--r--songdbj/de/jarnbjo/vorbis/CommentHeader.java244
-rw-r--r--songdbj/de/jarnbjo/vorbis/Floor.java124
-rw-r--r--songdbj/de/jarnbjo/vorbis/Floor0.java74
-rw-r--r--songdbj/de/jarnbjo/vorbis/Floor1.java324
-rw-r--r--songdbj/de/jarnbjo/vorbis/IdentificationHeader.java120
-rw-r--r--songdbj/de/jarnbjo/vorbis/Mapping.java59
-rw-r--r--songdbj/de/jarnbjo/vorbis/Mapping0.java146
-rw-r--r--songdbj/de/jarnbjo/vorbis/MdctFloat.java321
-rw-r--r--songdbj/de/jarnbjo/vorbis/Mode.java75
-rw-r--r--songdbj/de/jarnbjo/vorbis/Residue.java260
-rw-r--r--songdbj/de/jarnbjo/vorbis/Residue0.java53
-rw-r--r--songdbj/de/jarnbjo/vorbis/Residue1.java55
-rw-r--r--songdbj/de/jarnbjo/vorbis/Residue2.java123
-rw-r--r--songdbj/de/jarnbjo/vorbis/SetupHeader.java131
-rw-r--r--songdbj/de/jarnbjo/vorbis/Util.java127
-rw-r--r--songdbj/de/jarnbjo/vorbis/VorbisAudioFileReader.java217
-rw-r--r--songdbj/de/jarnbjo/vorbis/VorbisFormatException.java51
-rw-r--r--songdbj/de/jarnbjo/vorbis/VorbisStream.java247
35 files changed, 0 insertions, 5972 deletions
diff --git a/songdbj/de/jarnbjo/ogg/BasicStream.java b/songdbj/de/jarnbjo/ogg/BasicStream.java
deleted file mode 100644
index 9939524d6c..0000000000
--- a/songdbj/de/jarnbjo/ogg/BasicStream.java
+++ /dev/null
@@ -1,121 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.3 2004/09/21 12:09:45 shred
22 * *** empty log message ***
23 *
24 * Revision 1.2 2004/09/21 06:38:45 shred
25 * Importe reorganisiert, damit Eclipse Ruhe gibt. ;-)
26 *
27 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
28 * First Import
29 *
30 *
31 */
32
33package de.jarnbjo.ogg;
34
35import java.io.IOException;
36import java.io.InputStream;
37import java.util.Collection;
38import java.util.HashMap;
39import java.util.LinkedList;
40
41/**
42 * Implementation of the <code>PhysicalOggStream</code> interface for reading
43 * an Ogg stream from a URL. This class performs
44 * no internal caching, and will not read data from the network before
45 * requested to do so. It is intended to be used in non-realtime applications
46 * like file download managers or similar.
47 */
48
49public class BasicStream implements PhysicalOggStream {
50
51 private boolean closed=false;
52 private InputStream sourceStream;
53 private Object drainLock=new Object();
54 private LinkedList pageCache=new LinkedList();
55 private long numberOfSamples=-1;
56 private int position=0;
57
58 private HashMap logicalStreams=new HashMap();
59 private OggPage firstPage;
60
61 public BasicStream(InputStream sourceStream) throws OggFormatException, IOException {
62 firstPage=OggPage.create(sourceStream);
63 position+=firstPage.getTotalLength();
64 LogicalOggStreamImpl los=new LogicalOggStreamImpl(this, firstPage.getStreamSerialNumber());
65 logicalStreams.put(new Integer(firstPage.getStreamSerialNumber()), los);
66 los.checkFormat(firstPage);
67 }
68
69 public Collection getLogicalStreams() {
70 return logicalStreams.values();
71 }
72
73 public boolean isOpen() {
74 return !closed;
75 }
76
77 public void close() throws IOException {
78 closed=true;
79 sourceStream.close();
80 }
81
82 public int getContentLength() {
83 return -1;
84 }
85
86 public int getPosition() {
87 return position;
88 }
89
90 int pageNumber=2;
91
92 public OggPage getOggPage(int index) throws IOException {
93 if(firstPage!=null) {
94 OggPage tmp=firstPage;
95 firstPage=null;
96 return tmp;
97 }
98 else {
99 OggPage page=OggPage.create(sourceStream);
100 position+=page.getTotalLength();
101 return page;
102 }
103 }
104
105 private LogicalOggStream getLogicalStream(int serialNumber) {
106 return (LogicalOggStream)logicalStreams.get(new Integer(serialNumber));
107 }
108
109 public void setTime(long granulePosition) throws IOException {
110 throw new UnsupportedOperationException("Method not supported by this class");
111 }
112
113 /**
114 * @return always <code>false</code>
115 */
116
117 public boolean isSeekable() {
118 return false;
119 }
120
121} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/ogg/CachedUrlStream.java b/songdbj/de/jarnbjo/ogg/CachedUrlStream.java
deleted file mode 100644
index 86f792e272..0000000000
--- a/songdbj/de/jarnbjo/ogg/CachedUrlStream.java
+++ /dev/null
@@ -1,252 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.1 2003/04/10 19:48:22 jarnbjo
25 * no message
26 *
27 *
28 */
29
30package de.jarnbjo.ogg;
31
32import java.io.*;
33import java.net.*;
34import java.util.*;
35
36/**
37 * Implementation of the <code>PhysicalOggStream</code> interface for reading
38 * and caching an Ogg stream from a URL. This class reads the data as fast as
39 * possible from the URL, caches it locally either in memory or on disk, and
40 * supports seeking within the available data.
41 */
42
43public class CachedUrlStream implements PhysicalOggStream {
44
45 private boolean closed=false;
46 private URLConnection source;
47 private InputStream sourceStream;
48 private Object drainLock=new Object();
49 private RandomAccessFile drain;
50 private byte[] memoryCache;
51 private ArrayList pageOffsets=new ArrayList();
52 private ArrayList pageLengths=new ArrayList();
53 private long numberOfSamples=-1;
54 private long cacheLength;
55
56 private HashMap logicalStreams=new HashMap();
57
58 private LoaderThread loaderThread;
59
60 /**
61 * Creates an instance of this class, using a memory cache.
62 */
63
64 public CachedUrlStream(URL source) throws OggFormatException, IOException {
65 this(source, null);
66 }
67
68 /**
69 * Creates an instance of this class, using the specified file as cache. The
70 * file is not automatically deleted when this class is disposed.
71 */
72
73 public CachedUrlStream(URL source, RandomAccessFile drain) throws OggFormatException, IOException {
74
75 this.source=source.openConnection();
76
77 if(drain==null) {
78 int contentLength=this.source.getContentLength();
79 if(contentLength==-1) {
80 throw new IOException("The URLConncetion's content length must be set when operating with a in-memory cache.");
81 }
82 memoryCache=new byte[contentLength];
83 }
84
85 this.drain=drain;
86 this.sourceStream=this.source.getInputStream();
87
88 loaderThread=new LoaderThread(sourceStream, drain, memoryCache);
89 new Thread(loaderThread).start();
90
91 while(!loaderThread.isBosDone() || pageOffsets.size()<20) {
92 System.out.print("pageOffsets.size(): "+pageOffsets.size()+"\r");
93 try {
94 Thread.sleep(200);
95 }
96 catch (InterruptedException ex) {
97 }
98 }
99 System.out.println();
100 System.out.println("caching "+pageOffsets.size()+"/20 pages\r");
101 }
102
103 public Collection getLogicalStreams() {
104 return logicalStreams.values();
105 }
106
107 public boolean isOpen() {
108 return !closed;
109 }
110
111 public void close() throws IOException {
112 closed=true;
113 sourceStream.close();
114 }
115
116 public long getCacheLength() {
117 return cacheLength;
118 }
119
120 /*
121 private OggPage getNextPage() throws EndOfOggStreamException, IOException, OggFormatException {
122 return getNextPage(false);
123 }
124
125 private OggPage getNextPage(boolean skipData) throws EndOfOggStreamException, IOException, OggFormatException {
126 return OggPage.create(sourceStream, skipData);
127 }
128 */
129
130 public OggPage getOggPage(int index) throws IOException {
131 synchronized(drainLock) {
132 Long offset=(Long)pageOffsets.get(index);
133 Long length=(Long)pageLengths.get(index);
134 if(offset!=null) {
135 if(drain!=null) {
136 drain.seek(offset.longValue());
137 return OggPage.create(drain);
138 }
139 else {
140 byte[] tmpArray=new byte[length.intValue()];
141 System.arraycopy(memoryCache, offset.intValue(), tmpArray, 0, length.intValue());
142 return OggPage.create(tmpArray);
143 }
144 }
145 else {
146 return null;
147 }
148 }
149 }
150
151 private LogicalOggStream getLogicalStream(int serialNumber) {
152 return (LogicalOggStream)logicalStreams.get(new Integer(serialNumber));
153 }
154
155 public void setTime(long granulePosition) throws IOException {
156 for(Iterator iter=logicalStreams.values().iterator(); iter.hasNext(); ) {
157 LogicalOggStream los=(LogicalOggStream)iter.next();
158 los.setTime(granulePosition);
159 }
160 }
161
162 public class LoaderThread implements Runnable {
163
164 private InputStream source;
165 private RandomAccessFile drain;
166 private byte[] memoryCache;
167
168 private boolean bosDone=false;
169
170 private int pageNumber;
171
172 public LoaderThread(InputStream source, RandomAccessFile drain, byte[] memoryCache) {
173 this.source=source;
174 this.drain=drain;
175 this.memoryCache=memoryCache;
176 }
177
178 public void run() {
179 try {
180 boolean eos=false;
181 byte[] buffer=new byte[8192];
182 while(!eos) {
183 OggPage op=OggPage.create(source);
184 synchronized (drainLock) {
185 int listSize=pageOffsets.size();
186
187 long pos=
188 listSize>0?
189 ((Long)pageOffsets.get(listSize-1)).longValue()+
190 ((Long)pageLengths.get(listSize-1)).longValue():
191 0;
192
193 byte[] arr1=op.getHeader();
194 byte[] arr2=op.getSegmentTable();
195 byte[] arr3=op.getData();
196
197 if(drain!=null) {
198 drain.seek(pos);
199 drain.write(arr1);
200 drain.write(arr2);
201 drain.write(arr3);
202 }
203 else {
204 System.arraycopy(arr1, 0, memoryCache, (int)pos, arr1.length);
205 System.arraycopy(arr2, 0, memoryCache, (int)pos+arr1.length, arr2.length);
206 System.arraycopy(arr3, 0, memoryCache, (int)pos+arr1.length+arr2.length, arr3.length);
207 }
208
209 pageOffsets.add(new Long(pos));
210 pageLengths.add(new Long(arr1.length+arr2.length+arr3.length));
211 }
212
213 if(!op.isBos()) {
214 bosDone=true;
215 //System.out.println("bosDone=true;");
216 }
217 if(op.isEos()) {
218 eos=true;
219 }
220
221 LogicalOggStreamImpl los=(LogicalOggStreamImpl)getLogicalStream(op.getStreamSerialNumber());
222 if(los==null) {
223 los=new LogicalOggStreamImpl(CachedUrlStream.this, op.getStreamSerialNumber());
224 logicalStreams.put(new Integer(op.getStreamSerialNumber()), los);
225 los.checkFormat(op);
226 }
227
228 los.addPageNumberMapping(pageNumber);
229 los.addGranulePosition(op.getAbsoluteGranulePosition());
230
231 pageNumber++;
232 cacheLength=op.getAbsoluteGranulePosition();
233 //System.out.println("read page: "+pageNumber);
234 }
235 }
236 catch(EndOfOggStreamException e) {
237 // ok
238 }
239 catch(IOException e) {
240 e.printStackTrace();
241 }
242 }
243
244 public boolean isBosDone() {
245 return bosDone;
246 }
247 }
248
249 public boolean isSeekable() {
250 return true;
251 }
252} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/ogg/EndOfOggStreamException.java b/songdbj/de/jarnbjo/ogg/EndOfOggStreamException.java
deleted file mode 100644
index 4a0c3200f4..0000000000
--- a/songdbj/de/jarnbjo/ogg/EndOfOggStreamException.java
+++ /dev/null
@@ -1,45 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.2 2005/02/09 23:10:47 shred
22 * Serial UID für jarnbjo
23 *
24 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
25 * First Import
26 *
27 * Revision 1.1 2003/03/03 21:02:20 jarnbjo
28 * no message
29 *
30 */
31
32 package de.jarnbjo.ogg;
33
34import java.io.IOException;
35
36/**
37 * Exception thrown when reaching the end of an Ogg stream
38 */
39
40public class EndOfOggStreamException extends IOException {
41 private static final long serialVersionUID = 3907210438109444408L;
42
43 public EndOfOggStreamException() {
44 }
45} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/ogg/FileStream.java b/songdbj/de/jarnbjo/ogg/FileStream.java
deleted file mode 100644
index 5a526300bf..0000000000
--- a/songdbj/de/jarnbjo/ogg/FileStream.java
+++ /dev/null
@@ -1,154 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.1 2003/04/10 19:48:22 jarnbjo
25 * no message
26 *
27 *
28 */
29
30package de.jarnbjo.ogg;
31
32import java.io.*;
33import java.util.*;
34
35/**
36 * Implementation of the <code>PhysicalOggStream</code> interface for accessing
37 * normal disk files.
38 */
39
40public class FileStream implements PhysicalOggStream {
41
42 private boolean closed=false;
43 private RandomAccessFile source;
44 private long[] pageOffsets;
45 private long numberOfSamples=-1;
46
47 private HashMap logicalStreams=new HashMap();
48
49 /**
50 * Creates access to the specified file through the <code>PhysicalOggStream</code> interface.
51 * The specified source file must have been opened for reading.
52 *
53 * @param source the file to read from
54 *
55 * @throws OggFormatException if the stream format is incorrect
56 * @throws IOException if some other IO error occurs when reading the file
57 */
58
59 public FileStream(RandomAccessFile source) throws OggFormatException, IOException {
60 this.source=source;
61
62 ArrayList po=new ArrayList();
63 int pageNumber=0;
64 try {
65 while(true) {
66 po.add(new Long(this.source.getFilePointer()));
67
68 // skip data if pageNumber>0
69 OggPage op=getNextPage(pageNumber>0);
70 if(op==null) {
71 break;
72 }
73
74 LogicalOggStreamImpl los=(LogicalOggStreamImpl)getLogicalStream(op.getStreamSerialNumber());
75 if(los==null) {
76 los=new LogicalOggStreamImpl(this, op.getStreamSerialNumber());
77 logicalStreams.put(new Integer(op.getStreamSerialNumber()), los);
78 }
79
80 if(pageNumber==0) {
81 los.checkFormat(op);
82 }
83
84 los.addPageNumberMapping(pageNumber);
85 los.addGranulePosition(op.getAbsoluteGranulePosition());
86
87 if(pageNumber>0) {
88 this.source.seek(this.source.getFilePointer()+op.getTotalLength());
89 }
90
91 pageNumber++;
92 }
93 }
94 catch(EndOfOggStreamException e) {
95 // ok
96 }
97 catch(IOException e) {
98 throw e;
99 }
100 //System.out.println("pageNumber: "+pageNumber);
101 this.source.seek(0L);
102 pageOffsets=new long[po.size()];
103 int i=0;
104 Iterator iter=po.iterator();
105 while(iter.hasNext()) {
106 pageOffsets[i++]=((Long)iter.next()).longValue();
107 }
108 }
109
110 public Collection getLogicalStreams() {
111 return logicalStreams.values();
112 }
113
114 public boolean isOpen() {
115 return !closed;
116 }
117
118 public void close() throws IOException {
119 closed=true;
120 source.close();
121 }
122
123 private OggPage getNextPage() throws EndOfOggStreamException, IOException, OggFormatException {
124 return getNextPage(false);
125 }
126
127 private OggPage getNextPage(boolean skipData) throws EndOfOggStreamException, IOException, OggFormatException {
128 return OggPage.create(source, skipData);
129 }
130
131 public OggPage getOggPage(int index) throws IOException {
132 source.seek(pageOffsets[index]);
133 return OggPage.create(source);
134 }
135
136 private LogicalOggStream getLogicalStream(int serialNumber) {
137 return (LogicalOggStream)logicalStreams.get(new Integer(serialNumber));
138 }
139
140 public void setTime(long granulePosition) throws IOException {
141 for(Iterator iter=logicalStreams.values().iterator(); iter.hasNext(); ) {
142 LogicalOggStream los=(LogicalOggStream)iter.next();
143 los.setTime(granulePosition);
144 }
145 }
146
147 /**
148 * @return always <code>true</code>
149 */
150
151 public boolean isSeekable() {
152 return true;
153 }
154} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/ogg/LogicalOggStream.java b/songdbj/de/jarnbjo/ogg/LogicalOggStream.java
deleted file mode 100644
index 2f97b2a728..0000000000
--- a/songdbj/de/jarnbjo/ogg/LogicalOggStream.java
+++ /dev/null
@@ -1,151 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.2 2003/04/10 19:48:22 jarnbjo
25 * no message
26 *
27 * Revision 1.1 2003/03/03 21:02:20 jarnbjo
28 * no message
29 *
30 */
31
32package de.jarnbjo.ogg;
33
34import java.io.IOException;
35
36/**
37 * Interface providing access to a logical Ogg stream as part of a
38 * physical Ogg stream.
39 */
40
41
42public interface LogicalOggStream {
43
44 public static final String FORMAT_UNKNOWN = "application/octet-stream";
45
46 public static final String FORMAT_VORBIS = "audio/x-vorbis";
47 public static final String FORMAT_FLAC = "audio/x-flac";
48 public static final String FORMAT_THEORA = "video/x-theora";
49
50 /**
51 * <i>Note:</i> To read from the stream, you must use either
52 * this method or the method <code>getNextOggPacket</code>.
53 * Mixing calls to the two methods will cause data corruption.
54 *
55 * @return the next Ogg page
56 *
57 * @see #getNextOggPacket()
58 *
59 * @throws OggFormatException if the ogg stream is corrupted
60 * @throws IOException if some other IO error occurs
61 */
62
63 public OggPage getNextOggPage() throws OggFormatException, IOException;
64
65 /**
66 * <i>Note:</i> To read from the stream, you must use either
67 * this method or the method <code>getNextOggPage</code>.
68 * Mixing calls to the two methods will cause data corruption.
69 *
70 * @return the next packet as a byte array
71 *
72 * @see #getNextOggPage()
73 *
74 * @throws OggFormatException if the ogg stream is corrupted
75 * @throws IOException if some other IO error occurs
76 */
77
78 public byte[] getNextOggPacket() throws OggFormatException, IOException;
79
80 /**
81 * Checks if this stream is open for reading.
82 *
83 * @return <code>true</code> if this stream is open for reading,
84 * <code>false</code> otherwise
85 */
86
87 public boolean isOpen();
88
89 /**
90 * Closes this stream. After invoking this method, no further access
91 * to the streams data is possible.
92 *
93 * @throws IOException if an IO error occurs
94 */
95
96 public void close() throws IOException;
97
98 /**
99 * Sets the stream's position to the beginning of the stream.
100 * This method does not work if the physical Ogg stream is not
101 * seekable.
102 *
103 * @throws OggFormatException if the ogg stream is corrupted
104 * @throws IOException if some other IO error occurs
105 */
106
107 public void reset() throws OggFormatException, IOException;
108
109 /**
110 * This method does not work if the physical Ogg stream is not
111 * seekable.
112 *
113 * @return the granule position of the last page within
114 * this stream
115 */
116
117 public long getMaximumGranulePosition();
118
119 /**
120 * This method is invoked on all logical streams when
121 * calling the same method on the physical stream. The
122 * same restrictions as mentioned there apply.
123 * This method does not work if the physical Ogg stream is not
124 * seekable.
125 *
126 * @param granulePosition
127 *
128 * @see PhysicalOggStream#setTime(long)
129 *
130 * @throws IOException if an IO error occurs
131 */
132
133 public void setTime(long granulePosition) throws IOException;
134
135 /**
136 * @return the last parsed granule position of this stream
137 */
138
139 public long getTime();
140
141 /**
142 * @return the content type of this stream
143 *
144 * @see #FORMAT_UNKNOWN
145 * @see #FORMAT_VORBIS
146 * @see #FORMAT_FLAC
147 * @see #FORMAT_THEORA
148 */
149
150 public String getFormat();
151} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/ogg/LogicalOggStreamImpl.java b/songdbj/de/jarnbjo/ogg/LogicalOggStreamImpl.java
deleted file mode 100644
index 1a503e91ca..0000000000
--- a/songdbj/de/jarnbjo/ogg/LogicalOggStreamImpl.java
+++ /dev/null
@@ -1,213 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.3 2003/03/31 00:23:04 jarnbjo
25 * no message
26 *
27 * Revision 1.2 2003/03/16 01:11:26 jarnbjo
28 * no message
29 *
30 * Revision 1.1 2003/03/03 21:02:20 jarnbjo
31 * no message
32 *
33 */
34
35package de.jarnbjo.ogg;
36
37import java.io.*;
38import java.util.*;
39
40public class LogicalOggStreamImpl implements LogicalOggStream {
41
42 private PhysicalOggStream source;
43 private int serialNumber;
44
45 private ArrayList pageNumberMapping=new ArrayList();
46 private ArrayList granulePositions=new ArrayList();
47
48 private int pageIndex=0;
49 private OggPage currentPage;
50 private int currentSegmentIndex;
51
52 private boolean open=true;
53
54 private String format=FORMAT_UNKNOWN;
55
56 public LogicalOggStreamImpl(PhysicalOggStream source, int serialNumber) {
57 this.source=source;
58 this.serialNumber=serialNumber;
59 }
60
61 public void addPageNumberMapping(int physicalPageNumber) {
62 pageNumberMapping.add(new Integer(physicalPageNumber));
63 }
64
65 public void addGranulePosition(long granulePosition) {
66 granulePositions.add(new Long(granulePosition));
67 }
68
69 public synchronized void reset() throws OggFormatException, IOException {
70 currentPage=null;
71 currentSegmentIndex=0;
72 pageIndex=0;
73 }
74
75 public synchronized OggPage getNextOggPage() throws EndOfOggStreamException, OggFormatException, IOException {
76 if(source.isSeekable()) {
77 currentPage=source.getOggPage(((Integer)pageNumberMapping.get(pageIndex++)).intValue());
78 }
79 else {
80 currentPage=source.getOggPage(-1);
81 }
82 return currentPage;
83 }
84
85 public synchronized byte[] getNextOggPacket() throws EndOfOggStreamException, OggFormatException, IOException {
86 ByteArrayOutputStream res=new ByteArrayOutputStream();
87 int segmentLength=0;
88
89 if(currentPage==null) {
90 currentPage=getNextOggPage();
91 }
92
93 do {
94 if(currentSegmentIndex>=currentPage.getSegmentOffsets().length) {
95 currentSegmentIndex=0;
96
97 if(!currentPage.isEos()) {
98 if(source.isSeekable() && pageNumberMapping.size()<=pageIndex) {
99 while(pageNumberMapping.size()<=pageIndex+10) {
100 try {
101 Thread.sleep(1000);
102 }
103 catch (InterruptedException ex) {
104 }
105 }
106 }
107 currentPage=getNextOggPage();
108
109 if(res.size()==0 && currentPage.isContinued()) {
110 boolean done=false;
111 while(!done) {
112 if(currentPage.getSegmentLengths()[currentSegmentIndex++]!=255) {
113 done=true;
114 }
115 if(currentSegmentIndex>currentPage.getSegmentTable().length) {
116 currentPage=source.getOggPage(((Integer)pageNumberMapping.get(pageIndex++)).intValue());
117 }
118 }
119 }
120 }
121 else {
122 throw new EndOfOggStreamException();
123 }
124 }
125 segmentLength=currentPage.getSegmentLengths()[currentSegmentIndex];
126 res.write(currentPage.getData(), currentPage.getSegmentOffsets()[currentSegmentIndex], segmentLength);
127 currentSegmentIndex++;
128 } while(segmentLength==255);
129
130 return res.toByteArray();
131 }
132
133 public boolean isOpen() {
134 return open;
135 }
136
137 public void close() throws IOException {
138 open=false;
139 }
140
141 public long getMaximumGranulePosition() {
142 Long mgp=(Long)granulePositions.get(granulePositions.size()-1);
143 return mgp.longValue();
144 }
145
146 public synchronized long getTime() {
147 return currentPage!=null?currentPage.getAbsoluteGranulePosition():-1;
148 }
149
150 public synchronized void setTime(long granulePosition) throws IOException {
151
152 int page=0;
153 for(page=0; page<granulePositions.size(); page++) {
154 Long gp=(Long)granulePositions.get(page);
155 if(gp.longValue()>granulePosition) {
156 break;
157 }
158 }
159
160 pageIndex=page;
161 currentPage=source.getOggPage(((Integer)pageNumberMapping.get(pageIndex++)).intValue());
162 currentSegmentIndex=0;
163 int segmentLength=0;
164 do {
165 if(currentSegmentIndex>=currentPage.getSegmentOffsets().length) {
166 currentSegmentIndex=0;
167 if(pageIndex>=pageNumberMapping.size()) {
168 throw new EndOfOggStreamException();
169 }
170 currentPage=source.getOggPage(((Integer)pageNumberMapping.get(pageIndex++)).intValue());
171 }
172 segmentLength=currentPage.getSegmentLengths()[currentSegmentIndex];
173 currentSegmentIndex++;
174 } while(segmentLength==255);
175 }
176
177 public void checkFormat(OggPage page) {
178 byte[] data=page.getData();
179
180 if(data.length>=7 &&
181 data[1]==0x76 &&
182 data[2]==0x6f &&
183 data[3]==0x72 &&
184 data[4]==0x62 &&
185 data[5]==0x69 &&
186 data[6]==0x73) {
187
188 format=FORMAT_VORBIS;
189 }
190 else if(data.length>=7 &&
191 data[1]==0x74 &&
192 data[2]==0x68 &&
193 data[3]==0x65 &&
194 data[4]==0x6f &&
195 data[5]==0x72 &&
196 data[6]==0x61) {
197
198 format=FORMAT_THEORA;
199 }
200 else if (data.length==4 &&
201 data[0]==0x66 &&
202 data[1]==0x4c &&
203 data[2]==0x61 &&
204 data[3]==0x43) {
205
206 format=FORMAT_FLAC;
207 }
208 }
209
210 public String getFormat() {
211 return format;
212 }
213} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/ogg/OggFormatException.java b/songdbj/de/jarnbjo/ogg/OggFormatException.java
deleted file mode 100644
index a6b2466b92..0000000000
--- a/songdbj/de/jarnbjo/ogg/OggFormatException.java
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.2 2005/02/09 23:10:47 shred
22 * Serial UID für jarnbjo
23 *
24 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
25 * First Import
26 *
27 * Revision 1.1 2003/03/03 21:02:20 jarnbjo
28 * no message
29 *
30 */
31
32package de.jarnbjo.ogg;
33
34import java.io.IOException;
35
36/**
37 * Exception thrown when trying to read a corrupted Ogg stream.
38 */
39
40public class OggFormatException extends IOException {
41 private static final long serialVersionUID = 3544953238333175349L;
42
43 public OggFormatException() {
44 super();
45 }
46
47 public OggFormatException(String message) {
48 super(message);
49 }
50} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/ogg/OggPage.java b/songdbj/de/jarnbjo/ogg/OggPage.java
deleted file mode 100644
index cc965cc7a9..0000000000
--- a/songdbj/de/jarnbjo/ogg/OggPage.java
+++ /dev/null
@@ -1,431 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.3 2003/04/10 19:48:22 jarnbjo
25 * no message
26 *
27 * Revision 1.2 2003/03/31 00:23:04 jarnbjo
28 * no message
29 *
30 * Revision 1.1 2003/03/03 21:02:20 jarnbjo
31 * no message
32 *
33 */
34
35package de.jarnbjo.ogg;
36
37import java.io.*;
38
39import de.jarnbjo.util.io.*;
40
41/**
42 * <p>An instance of this class represents an ogg page read from an ogg file
43 * or network stream. It has no public constructor, but instances can be
44 * created by the <code>create</code> methods, supplying a JMF stream or
45 * a <code>RandomAccessFile</code>
46 * which is positioned at the beginning of an Ogg page.</p>
47 *
48 * <p>Furtheron, the class provides methods for accessing the raw page data,
49 * as well as data attributes like segmenting information, sequence number,
50 * stream serial number, chechsum and wether this page is the beginning or
51 * end of a logical bitstream (BOS, EOS) and if the page data starts with a
52 * continued packet or a fresh data packet.</p>
53 */
54
55public class OggPage {
56
57 private int version;
58 private boolean continued, bos, eos;
59 private long absoluteGranulePosition;
60 private int streamSerialNumber, pageSequenceNumber, pageCheckSum;
61 private int[] segmentOffsets;
62 private int[] segmentLengths;
63 private int totalLength;
64 private byte[] header, segmentTable, data;
65
66 protected OggPage() {
67 }
68
69 private OggPage(
70 int version,
71 boolean continued,
72 boolean bos,
73 boolean eos,
74 long absoluteGranulePosition,
75 int streamSerialNumber,
76 int pageSequenceNumber,
77 int pageCheckSum,
78 int[] segmentOffsets,
79 int[] segmentLengths,
80 int totalLength,
81 byte[] header,
82 byte[] segmentTable,
83 byte[] data) {
84
85 this.version=version;
86 this.continued=continued;
87 this.bos=bos;
88 this.eos=eos;
89 this.absoluteGranulePosition=absoluteGranulePosition;
90 this.streamSerialNumber=streamSerialNumber;
91 this.pageSequenceNumber=pageSequenceNumber;
92 this.pageCheckSum=pageCheckSum;
93 this.segmentOffsets=segmentOffsets;
94 this.segmentLengths=segmentLengths;
95 this.totalLength=totalLength;
96 this.header=header;
97 this.segmentTable=segmentTable;
98 this.data=data;
99 }
100
101 /**
102 * this method equals to create(RandomAccessFile source, false)
103 *
104 * @see #create(RandomAccessFile, boolean)
105 */
106
107 public static OggPage create(RandomAccessFile source) throws IOException, EndOfOggStreamException, OggFormatException {
108 return create(source, false);
109 }
110
111 /**
112 * This method is called to read data from the current position in the
113 * specified RandomAccessFile and create a new OggPage instance based on the data
114 * read. If the parameter <code>skipData</code> is set to <code>true</code>,
115 * the actual page segments (page data) is skipped and not read into
116 * memory. This mode is useful when scanning through an ogg file to build
117 * a seek table.
118 *
119 * @param source the source from which the ogg page is generated
120 * @param skipData if set to <code>true</code>, the actual page data is not read into memory
121 * @return an ogg page created by reading data from the specified source, starting at the current position
122 * @throws FormatException if the data read from the specified source is not matching the specification for an ogg page
123 * @throws EndOfStreamException if it is not possible to read an entire ogg page from the specified source
124 * @throws IOException if some other I/O error is detected when reading from the source
125 *
126 * @see #create(RandomAccessFile)
127 */
128
129 public static OggPage create(RandomAccessFile source, boolean skipData) throws IOException, EndOfOggStreamException, OggFormatException {
130 return create((Object)source, skipData);
131 }
132
133 /**
134 * this method equals to create(InputStream source, false)
135 *
136 * @see #create(InputStream, boolean)
137 */
138
139 public static OggPage create(InputStream source) throws IOException, EndOfOggStreamException, OggFormatException {
140 return create(source, false);
141 }
142
143 /**
144 * This method is called to read data from the current position in the
145 * specified InpuStream and create a new OggPage instance based on the data
146 * read. If the parameter <code>skipData</code> is set to <code>true</code>,
147 * the actual page segments (page data) is skipped and not read into
148 * memory. This mode is useful when scanning through an ogg file to build
149 * a seek table.
150 *
151 * @param source the source from which the ogg page is generated
152 * @param skipData if set to <code>true</code>, the actual page data is not read into memory
153 * @return an ogg page created by reading data from the specified source, starting at the current position
154 * @throws FormatException if the data read from the specified source is not matching the specification for an ogg page
155 * @throws EndOfStreamException if it is not possible to read an entire ogg page from the specified source
156 * @throws IOException if some other I/O error is detected when reading from the source
157 *
158 * @see #create(InputStream)
159 */
160
161 public static OggPage create(InputStream source, boolean skipData) throws IOException, EndOfOggStreamException, OggFormatException {
162 return create((Object)source, skipData);
163 }
164
165 /**
166 * this method equals to create(byte[] source, false)
167 *
168 * @see #create(byte[], boolean)
169 */
170
171 public static OggPage create(byte[] source) throws IOException, EndOfOggStreamException, OggFormatException {
172 return create(source, false);
173 }
174
175 /**
176 * This method is called to
177 * create a new OggPage instance based on the specified byte array.
178 *
179 * @param source the source from which the ogg page is generated
180 * @param skipData if set to <code>true</code>, the actual page data is not read into memory
181 * @return an ogg page created by reading data from the specified source, starting at the current position
182 * @throws FormatException if the data read from the specified source is not matching the specification for an ogg page
183 * @throws EndOfStreamException if it is not possible to read an entire ogg page from the specified source
184 * @throws IOException if some other I/O error is detected when reading from the source
185 *
186 * @see #create(byte[])
187 */
188
189 public static OggPage create(byte[] source, boolean skipData) throws IOException, EndOfOggStreamException, OggFormatException {
190 return create((Object)source, skipData);
191 }
192
193 private static OggPage create(Object source, boolean skipData) throws IOException, EndOfOggStreamException, OggFormatException {
194
195 try {
196 int sourceOffset=27;
197
198 byte[] header=new byte[27];
199 if(source instanceof RandomAccessFile) {
200 RandomAccessFile raf=(RandomAccessFile)source;
201 if(raf.getFilePointer()==raf.length()) {
202 return null;
203 }
204 raf.readFully(header);
205 }
206 else if(source instanceof InputStream) {
207 readFully((InputStream)source, header);
208 }
209 else if(source instanceof byte[]) {
210 System.arraycopy((byte[])source, 0, header, 0, 27);
211 }
212
213 BitInputStream bdSource=new ByteArrayBitInputStream(header);
214
215 int capture=bdSource.getInt(32);
216
217 if(capture!=0x5367674f) {
218 //throw new FormatException("Ogg page does not start with 'OggS' (0x4f676753)");
219
220 /*
221 ** This condition is IMHO an error, but older Ogg files often contain
222 ** pages with a different capture than OggS. I am not sure how to
223 ** manage these pages, but the decoder seems to work properly, if
224 ** the incorrect capture is simply ignored.
225 */
226
227 String cs=Integer.toHexString(capture);
228 while(cs.length()<8) {
229 cs="0"+cs;
230 }
231 cs=cs.substring(6, 8)+cs.substring(4, 6)+cs.substring(2, 4)+cs.substring(0, 2);
232 char c1=(char)(Integer.valueOf(cs.substring(0, 2), 16).intValue());
233 char c2=(char)(Integer.valueOf(cs.substring(2, 4), 16).intValue());
234 char c3=(char)(Integer.valueOf(cs.substring(4, 6), 16).intValue());
235 char c4=(char)(Integer.valueOf(cs.substring(6, 8), 16).intValue());
236 System.out.println("Ogg packet header is 0x"+cs+" ("+c1+c2+c3+c4+"), should be 0x4f676753 (OggS)");
237 }
238
239 int version=bdSource.getInt(8);
240 byte tmp=(byte)bdSource.getInt(8);
241 boolean bf1=(tmp&1)!=0;
242 boolean bos=(tmp&2)!=0;
243 boolean eos=(tmp&4)!=0;
244 long absoluteGranulePosition=bdSource.getLong(64);
245 int streamSerialNumber=bdSource.getInt(32);
246 int pageSequenceNumber=bdSource.getInt(32);
247 int pageCheckSum=bdSource.getInt(32);
248 int pageSegments=bdSource.getInt(8);
249
250 //System.out.println("OggPage: "+streamSerialNumber+" / "+absoluteGranulePosition+" / "+pageSequenceNumber);
251
252 int[] segmentOffsets=new int[pageSegments];
253 int[] segmentLengths=new int[pageSegments];
254 int totalLength=0;
255
256 byte[] segmentTable=new byte[pageSegments];
257 byte[] tmpBuf=new byte[1];
258
259 for(int i=0; i<pageSegments; i++) {
260 int l=0;
261 if(source instanceof RandomAccessFile) {
262 l=((int)((RandomAccessFile)source).readByte()&0xff);
263 }
264 else if(source instanceof InputStream) {
265 l=(int)((InputStream)source).read();
266 }
267 else if(source instanceof byte[]) {
268 l=(int)((byte[])source)[sourceOffset++];
269 l&=255;
270 }
271 segmentTable[i]=(byte)l;
272 segmentLengths[i]=l;
273 segmentOffsets[i]=totalLength;
274 totalLength+=l;
275 }
276
277 byte[] data=null;
278
279 if(!skipData) {
280
281 //System.out.println("createPage: "+absoluteGranulePosition*1000/44100);
282
283 data=new byte[totalLength];
284 //source.read(data, 0, totalLength);
285 if(source instanceof RandomAccessFile) {
286 ((RandomAccessFile)source).readFully(data);
287 }
288 else if(source instanceof InputStream) {
289 readFully((InputStream)source, data);
290 }
291 else if(source instanceof byte[]) {
292 System.arraycopy(source, sourceOffset, data, 0, totalLength);
293 }
294 }
295
296 return new OggPage(version, bf1, bos, eos, absoluteGranulePosition, streamSerialNumber, pageSequenceNumber, pageCheckSum, segmentOffsets, segmentLengths, totalLength, header, segmentTable, data);
297 }
298 catch(EOFException e) {
299 throw new EndOfOggStreamException();
300 }
301 }
302
303 private static void readFully(InputStream source, byte[] buffer) throws IOException {
304 int total=0;
305 while(total<buffer.length) {
306 int read=source.read(buffer, total, buffer.length-total);
307 if(read==-1) {
308 throw new EndOfOggStreamException();
309 }
310 total+=read;
311 }
312 }
313
314 /**
315 * Returns the absolute granule position of the last complete
316 * packet contained in this Ogg page, or -1 if the page contains a single
317 * packet, which is not completed on this page. For pages containing Vorbis
318 * data, this value is the sample index within the Vorbis stream. The Vorbis
319 * stream does not necessarily start with sample index 0.
320 *
321 * @return the absolute granule position of the last packet completed on
322 * this page
323 */
324
325
326 public long getAbsoluteGranulePosition() {
327 return absoluteGranulePosition;
328 }
329
330 /**
331 * Returns the stream serial number of this ogg page.
332 *
333 * @return this page's serial number
334 */
335
336 public int getStreamSerialNumber() {
337 return streamSerialNumber;
338 }
339
340 /**
341 * Return the sequnce number of this ogg page.
342 *
343 * @return this page's sequence number
344 */
345
346 public int getPageSequenceNumber() {
347 return pageSequenceNumber;
348 }
349
350 /**
351 * Return the check sum of this ogg page.
352 *
353 * @return this page's check sum
354 */
355
356 public int getPageCheckSum() {
357 return pageCheckSum;
358 }
359
360 /**
361 * @return the total number of bytes in the page data
362 */
363
364
365 public int getTotalLength() {
366 if(data!=null) {
367 return 27+segmentTable.length+data.length;
368 }
369 else {
370 return totalLength;
371 }
372 }
373
374 /**
375 * @return a ByteBuffer containing the page data
376 */
377
378
379 public byte[] getData() {
380 return data;
381 }
382
383 public byte[] getHeader() {
384 return header;
385 }
386
387 public byte[] getSegmentTable() {
388 return segmentTable;
389 }
390
391 public int[] getSegmentOffsets() {
392 return segmentOffsets;
393 }
394
395 public int[] getSegmentLengths() {
396 return segmentLengths;
397 }
398
399 /**
400 * @return <code>true</code> if this page begins with a continued packet
401 */
402
403 public boolean isContinued() {
404 return continued;
405 }
406
407 /**
408 * @return <code>true</code> if this page begins with a fresh packet
409 */
410
411 public boolean isFresh() {
412 return !continued;
413 }
414
415 /**
416 * @return <code>true</code> if this page is the beginning of a logical stream
417 */
418
419 public boolean isBos() {
420 return bos;
421 }
422
423 /**
424 * @return <code>true</code> if this page is the end of a logical stream
425 */
426
427 public boolean isEos() {
428 return eos;
429 }
430
431} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/ogg/OnDemandUrlStream.java b/songdbj/de/jarnbjo/ogg/OnDemandUrlStream.java
deleted file mode 100644
index 98159c4e7c..0000000000
--- a/songdbj/de/jarnbjo/ogg/OnDemandUrlStream.java
+++ /dev/null
@@ -1,127 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.1 2003/04/10 19:48:22 jarnbjo
25 * no message
26 *
27 * Revision 1.1 2003/03/31 00:23:04 jarnbjo
28 * no message
29 *
30 */
31
32package de.jarnbjo.ogg;
33
34import java.io.*;
35import java.net.*;
36import java.util.*;
37
38/**
39 * Implementation of the <code>PhysicalOggStream</code> interface for reading
40 * an Ogg stream from a URL. This class performs
41 * no internal caching, and will not read data from the network before
42 * requested to do so. It is intended to be used in non-realtime applications
43 * like file download managers or similar.
44 */
45
46public class OnDemandUrlStream implements PhysicalOggStream {
47
48 private boolean closed=false;
49 private URLConnection source;
50 private InputStream sourceStream;
51 private Object drainLock=new Object();
52 private LinkedList pageCache=new LinkedList();
53 private long numberOfSamples=-1;
54 private int contentLength=0;
55 private int position=0;
56
57 private HashMap logicalStreams=new HashMap();
58 private OggPage firstPage;
59
60 private static final int PAGECACHE_SIZE = 20;
61
62 public OnDemandUrlStream(URL source) throws OggFormatException, IOException {
63 this.source=source.openConnection();
64 this.sourceStream=this.source.getInputStream();
65
66 contentLength=this.source.getContentLength();
67
68 firstPage=OggPage.create(sourceStream);
69 position+=firstPage.getTotalLength();
70 LogicalOggStreamImpl los=new LogicalOggStreamImpl(this, firstPage.getStreamSerialNumber());
71 logicalStreams.put(new Integer(firstPage.getStreamSerialNumber()), los);
72 los.checkFormat(firstPage);
73 }
74
75 public Collection getLogicalStreams() {
76 return logicalStreams.values();
77 }
78
79 public boolean isOpen() {
80 return !closed;
81 }
82
83 public void close() throws IOException {
84 closed=true;
85 sourceStream.close();
86 }
87
88 public int getContentLength() {
89 return contentLength;
90 }
91
92 public int getPosition() {
93 return position;
94 }
95
96 int pageNumber=2;
97
98 public OggPage getOggPage(int index) throws IOException {
99 if(firstPage!=null) {
100 OggPage tmp=firstPage;
101 firstPage=null;
102 return tmp;
103 }
104 else {
105 OggPage page=OggPage.create(sourceStream);
106 position+=page.getTotalLength();
107 return page;
108 }
109 }
110
111 private LogicalOggStream getLogicalStream(int serialNumber) {
112 return (LogicalOggStream)logicalStreams.get(new Integer(serialNumber));
113 }
114
115 public void setTime(long granulePosition) throws IOException {
116 throw new UnsupportedOperationException("Method not supported by this class");
117 }
118
119 /**
120 * @return always <code>false</code>
121 */
122
123 public boolean isSeekable() {
124 return false;
125 }
126
127} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/ogg/PhysicalOggStream.java b/songdbj/de/jarnbjo/ogg/PhysicalOggStream.java
deleted file mode 100644
index 5f342a38b7..0000000000
--- a/songdbj/de/jarnbjo/ogg/PhysicalOggStream.java
+++ /dev/null
@@ -1,124 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.3 2003/04/10 19:48:22 jarnbjo
25 * no message
26 *
27 * Revision 1.2 2003/03/31 00:23:04 jarnbjo
28 * no message
29 *
30 * Revision 1.1 2003/03/03 21:02:20 jarnbjo
31 * no message
32 *
33 */
34
35package de.jarnbjo.ogg;
36
37import java.io.IOException;
38import java.util.Collection;
39
40/**
41 * Interface providing access to a physical Ogg stream. Typically this is
42 * a file.
43 */
44
45public interface PhysicalOggStream {
46
47 /**
48 * Returns a collection of objects implementing <code>LogicalOggStream</code>
49 * for accessing the separate logical streams within this physical Ogg stream.
50 *
51 * @return a collection of objects implementing <code>LogicalOggStream</code>
52 * which are representing the logical streams contained within this
53 * physical stream
54 *
55 * @see LogicalOggStream
56 */
57
58 public Collection getLogicalStreams();
59
60 /**
61 * Return the Ogg page with the absolute index <code>index</code>,
62 * independent from the logical structure of this stream or if the
63 * index parameter is -1, the next Ogg page is returned.
64 * This method should only be used by implementations of <code>LogicalOggStream</code>
65 * to access the raw pages.
66 *
67 * @param index the absolute index starting from 0 at the beginning of
68 * the file or stream or -1 to get the next page in a non-seekable
69 * stream
70 *
71 * @return the Ogg page with the physical absolute index <code>index</code>
72 *
73 * @throws OggFormatException if the ogg stream is corrupted
74 * @throws IOException if some other IO error occurs
75 */
76
77 public OggPage getOggPage(int index) throws OggFormatException, IOException;
78
79 /**
80 * Checks if this stream is open for reading.
81 *
82 * @return <code>true</code> if this stream is open for reading,
83 * <code>false</code> otherwise
84 */
85
86 public boolean isOpen();
87
88 /**
89 * Closes this stream. After invoking this method, no further access
90 * to the streams data is possible.
91 *
92 * @throws IOException
93 */
94
95 public void close() throws IOException;
96
97 /**
98 * Sets this stream's (and its logical stream's) position to the granule
99 * position. The next packet read from any logical stream will be the
100 * first packet beginning on the first page with a granule position higher
101 * than the argument.<br><br>
102 *
103 * At the moment, this method only works correctly for Ogg files with
104 * a single logical Vorbis stream, and due to the different interpretations
105 * of the granule position, depending on mixed content, this method will
106 * never be able to work for mixed streams. Chained and interleaved streams are
107 * also not yet supported. Actually, this method is only a hack to support
108 * seeking from JMF, but may of course be abused otherwise too :)
109 *
110 * @param granulePosition
111 *
112 * @throws OggFormatException if the ogg stream is corrupted
113 * @throws IOException if some other IO error occurs
114 */
115
116 public void setTime(long granulePosition) throws OggFormatException, IOException;
117
118 /**
119 * @return <code>true</code> if the stream is seekable, <code>false</code>
120 * otherwise
121 */
122
123 public boolean isSeekable();
124} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/ogg/UncachedUrlStream.java b/songdbj/de/jarnbjo/ogg/UncachedUrlStream.java
deleted file mode 100644
index a07f0ac00e..0000000000
--- a/songdbj/de/jarnbjo/ogg/UncachedUrlStream.java
+++ /dev/null
@@ -1,207 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.1 2003/04/10 19:48:22 jarnbjo
25 * no message
26 *
27 */
28
29package de.jarnbjo.ogg;
30
31import java.io.*;
32import java.net.*;
33import java.util.*;
34
35/**
36 * Implementation of the <code>PhysicalOggStream</code> interface for reading
37 * an Ogg stream from a URL. This class performs only the necessary caching
38 * to provide continous playback. Seeking within the stream is not supported.
39 */
40
41public class UncachedUrlStream implements PhysicalOggStream {
42
43 private boolean closed=false;
44 private URLConnection source;
45 private InputStream sourceStream;
46 private Object drainLock=new Object();
47 private LinkedList pageCache=new LinkedList();
48 private long numberOfSamples=-1;
49
50 private HashMap logicalStreams=new HashMap();
51
52 private LoaderThread loaderThread;
53
54 private static final int PAGECACHE_SIZE = 10;
55
56 /** Creates an instance of the <code>PhysicalOggStream</code> interface
57 * suitable for reading an Ogg stream from a URL.
58 */
59
60 public UncachedUrlStream(URL source) throws OggFormatException, IOException {
61
62 this.source=source.openConnection();
63 this.sourceStream=this.source.getInputStream();
64
65 loaderThread=new LoaderThread(sourceStream, pageCache);
66 new Thread(loaderThread).start();
67
68 while(!loaderThread.isBosDone() || pageCache.size()<PAGECACHE_SIZE) {
69 try {
70 Thread.sleep(200);
71 }
72 catch (InterruptedException ex) {
73 }
74 //System.out.print("caching "+pageCache.size()+"/"+PAGECACHE_SIZE+" pages\r");
75 }
76 //System.out.println();
77 }
78
79 public Collection getLogicalStreams() {
80 return logicalStreams.values();
81 }
82
83 public boolean isOpen() {
84 return !closed;
85 }
86
87 public void close() throws IOException {
88 closed=true;
89 sourceStream.close();
90 }
91
92 /*
93 public long getCacheLength() {
94 return cacheLength;
95 }
96 */
97
98 /*
99 private OggPage getNextPage() throws EndOfOggStreamException, IOException, OggFormatException {
100 return getNextPage(false);
101 }
102
103 private OggPage getNextPage(boolean skipData) throws EndOfOggStreamException, IOException, OggFormatException {
104 return OggPage.create(sourceStream, skipData);
105 }
106 */
107
108 public OggPage getOggPage(int index) throws IOException {
109 while(pageCache.size()==0) {
110 try {
111 Thread.sleep(100);
112 }
113 catch (InterruptedException ex) {
114 }
115 }
116 synchronized(drainLock) {
117 //OggPage page=(OggPage)pageCache.getFirst();
118 //pageCache.removeFirst();
119 //return page;
120 return (OggPage)pageCache.removeFirst();
121 }
122 }
123
124 private LogicalOggStream getLogicalStream(int serialNumber) {
125 return (LogicalOggStream)logicalStreams.get(new Integer(serialNumber));
126 }
127
128 public void setTime(long granulePosition) throws IOException {
129 throw new UnsupportedOperationException("Method not supported by this class");
130 }
131
132 public class LoaderThread implements Runnable {
133
134 private InputStream source;
135 private LinkedList pageCache;
136 private RandomAccessFile drain;
137 private byte[] memoryCache;
138
139 private boolean bosDone=false;
140
141 private int pageNumber;
142
143 public LoaderThread(InputStream source, LinkedList pageCache) {
144 this.source=source;
145 this.pageCache=pageCache;
146 }
147
148 public void run() {
149 try {
150 boolean eos=false;
151 byte[] buffer=new byte[8192];
152 while(!eos) {
153 OggPage op=OggPage.create(source);
154 synchronized (drainLock) {
155 pageCache.add(op);
156 }
157
158 if(!op.isBos()) {
159 bosDone=true;
160 }
161 if(op.isEos()) {
162 eos=true;
163 }
164
165 LogicalOggStreamImpl los=(LogicalOggStreamImpl)getLogicalStream(op.getStreamSerialNumber());
166 if(los==null) {
167 los=new LogicalOggStreamImpl(UncachedUrlStream.this, op.getStreamSerialNumber());
168 logicalStreams.put(new Integer(op.getStreamSerialNumber()), los);
169 los.checkFormat(op);
170 }
171
172 //los.addPageNumberMapping(pageNumber);
173 //los.addGranulePosition(op.getAbsoluteGranulePosition());
174
175 pageNumber++;
176
177 while(pageCache.size()>PAGECACHE_SIZE) {
178 try {
179 Thread.sleep(200);
180 }
181 catch (InterruptedException ex) {
182 }
183 }
184 }
185 }
186 catch(EndOfOggStreamException e) {
187 // ok
188 }
189 catch(IOException e) {
190 e.printStackTrace();
191 }
192 }
193
194 public boolean isBosDone() {
195 return bosDone;
196 }
197 }
198
199 /**
200 * @return always <code>false</code>
201 */
202
203 public boolean isSeekable() {
204 return false;
205 }
206
207} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/util/audio/FadeableAudioInputStream.java b/songdbj/de/jarnbjo/util/audio/FadeableAudioInputStream.java
deleted file mode 100644
index 4916102d4b..0000000000
--- a/songdbj/de/jarnbjo/util/audio/FadeableAudioInputStream.java
+++ /dev/null
@@ -1,62 +0,0 @@
1package de.jarnbjo.util.audio;
2
3import java.io.*;
4import javax.sound.sampled.*;
5
6public class FadeableAudioInputStream extends AudioInputStream {
7
8 private AudioInputStream stream;
9 private boolean fading=false;
10 private double phi=0.0;
11
12 public FadeableAudioInputStream(AudioInputStream stream) throws IOException {
13 super(stream, stream.getFormat(), -1L);
14 }
15
16 public void fadeOut() {
17 fading=true;
18 phi=0.0;
19 }
20
21 public int read(byte[] b) throws IOException {
22 return read(b, 0, b.length);
23 }
24
25 public int read(byte[] b, int offset, int length) throws IOException {
26 int read=super.read(b, offset, length);
27
28 //System.out.println("read "+read);
29
30 if(fading) {
31 int j=0, l=0, r=0;
32 double gain=0.0;
33
34 for(int i=offset; i<offset+read; i+=4) {
35 j=i;
36 l=((int)b[j++])&0xff;
37 l|=((int)b[j++])<<8;
38 r=((int)b[j++])&0xff;
39 r|=((int)b[j])<<8;
40
41 if(phi<Math.PI/2) {
42 phi+=0.000015;
43 }
44
45 gain=Math.cos(phi);
46 //System.out.println("gain "+gain);
47
48 l=(int)(l*gain);
49 r=(int)(r*gain);
50
51 j=i;
52 b[j++]=(byte)(l&0xff);
53 b[j++]=(byte)((l>>8)&0xff);
54 b[j++]=(byte)(r&0xff);
55 b[j++]=(byte)((r>>8)&0xff);
56 }
57 }
58
59 return read;
60 }
61
62} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/util/io/BitInputStream.java b/songdbj/de/jarnbjo/util/io/BitInputStream.java
deleted file mode 100644
index 89cadb8380..0000000000
--- a/songdbj/de/jarnbjo/util/io/BitInputStream.java
+++ /dev/null
@@ -1,185 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.5 2003/04/10 19:48:31 jarnbjo
25 * no message
26 *
27 * Revision 1.4 2003/03/16 20:57:06 jarnbjo
28 * no message
29 *
30 * Revision 1.3 2003/03/16 20:56:56 jarnbjo
31 * no message
32 *
33 * Revision 1.2 2003/03/16 01:11:39 jarnbjo
34 * no message
35 *
36 * Revision 1.1 2003/03/03 21:02:20 jarnbjo
37 * no message
38 *
39 */
40
41package de.jarnbjo.util.io;
42
43import java.io.IOException;
44
45/**
46 * An interface with methods allowing bit-wise reading from
47 * an input stream. All methods in this interface are optional
48 * and an implementation not support a method or a specific state
49 * (e.g. endian) will throw an UnspportedOperationException if
50 * such a method is being called. This should be speicified in
51 * the implementation documentation.
52 */
53
54public interface BitInputStream {
55
56 /**
57 * constant for setting this stream's mode to little endian
58 *
59 * @see #setEndian(int)
60 */
61
62 public static final int LITTLE_ENDIAN = 0;
63
64 /**
65 * constant for setting this stream's mode to big endian
66 *
67 * @see #setEndian(int)
68 */
69
70 public static final int BIG_ENDIAN = 1;
71
72 /**
73 * reads one bit (as a boolean) from the input stream
74 *
75 * @return <code>true</code> if the next bit is 1,
76 * <code>false</code> otherwise
77 *
78 * @throws IOException if an I/O error occurs
79 * @throws UnsupportedOperationException if the method is not supported by the implementation
80 */
81
82 public boolean getBit() throws IOException;
83
84 /**
85 * reads <code>bits</code> number of bits from the input
86 * stream
87 *
88 * @return the unsigned integer value read from the stream
89 *
90 * @throws IOException if an I/O error occurs
91 * @throws UnsupportedOperationException if the method is not supported by the implementation
92 */
93
94 public int getInt(int bits) throws IOException;
95
96 /**
97 * reads <code>bits</code> number of bits from the input
98 * stream
99 *
100 * @return the signed integer value read from the stream
101 *
102 * @throws IOException if an I/O error occurs
103 * @throws UnsupportedOperationException if the method is not supported by the implementation
104 */
105
106 public int getSignedInt(int bits) throws IOException;
107
108 /**
109 * reads a huffman codeword based on the <code>root</code>
110 * parameter and returns the decoded value
111 *
112 * @param root the root of the Huffman tree used to decode the codeword
113 * @return the decoded unsigned integer value read from the stream
114 *
115 * @throws IOException if an I/O error occurs
116 * @throws UnsupportedOperationException if the method is not supported by the implementation
117 */
118
119 public int getInt(HuffmanNode root) throws IOException;
120
121 /**
122 * reads an integer encoded as "signed rice" as described in
123 * the FLAC audio format specification
124 *
125 * @param order
126 * @return the decoded integer value read from the stream
127 *
128 * @throws IOException if an I/O error occurs
129 * @throws UnsupportedOperationException if the method is not supported by the implementation
130 */
131
132 public int readSignedRice(int order) throws IOException;
133
134 /**
135 * fills the array from <code>offset</code> with <code>len</code>
136 * integers encoded as "signed rice" as described in
137 * the FLAC audio format specification
138 *
139 * @param order
140 * @param buffer
141 * @param offset
142 * @param len
143 * @return the decoded integer value read from the stream
144 *
145 * @throws IOException if an I/O error occurs
146 * @throws UnsupportedOperationException if the method is not supported by the implementation
147 */
148
149 public void readSignedRice(int order, int[] buffer, int offset, int len) throws IOException;
150
151 /**
152 * reads <code>bits</code> number of bits from the input
153 * stream
154 *
155 * @return the unsigned long value read from the stream
156 *
157 * @throws IOException if an I/O error occurs
158 * @throws UnsupportedOperationException if the method is not supported by the implementation
159 */
160
161 public long getLong(int bits) throws IOException;
162
163 /**
164 * causes the read pointer to be moved to the beginning
165 * of the next byte, remaining bits in the current byte
166 * are discarded
167 *
168 * @throws UnsupportedOperationException if the method is not supported by the implementation
169 */
170
171 public void align();
172
173 /**
174 * changes the endian mode used when reading bit-wise from
175 * the stream, changing the mode mid-stream will cause the
176 * read cursor to move to the beginning of the next byte
177 * (as if calling the <code>allign</code> method
178 *
179 * @see #align()
180 *
181 * @throws UnsupportedOperationException if the method is not supported by the implementation
182 */
183
184 public void setEndian(int endian);
185} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/util/io/ByteArrayBitInputStream.java b/songdbj/de/jarnbjo/util/io/ByteArrayBitInputStream.java
deleted file mode 100644
index 9c84c7daca..0000000000
--- a/songdbj/de/jarnbjo/util/io/ByteArrayBitInputStream.java
+++ /dev/null
@@ -1,352 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.3 2003/04/10 19:48:31 jarnbjo
25 * no message
26 *
27 * Revision 1.2 2003/03/16 01:11:39 jarnbjo
28 * no message
29 *
30 * Revision 1.1 2003/03/03 21:02:20 jarnbjo
31 * no message
32 *
33 */
34
35package de.jarnbjo.util.io;
36
37import java.io.IOException;
38
39/**
40 * Implementation of the <code>BitInputStream</code> interface,
41 * using a byte array as data source.
42*/
43
44public class ByteArrayBitInputStream implements BitInputStream {
45
46 private byte[] source;
47 private byte currentByte;
48
49 private int endian;
50
51 private int byteIndex=0;
52 private int bitIndex=0;
53
54 public ByteArrayBitInputStream(byte[] source) {
55 this(source, LITTLE_ENDIAN);
56 }
57
58 public ByteArrayBitInputStream(byte[] source, int endian) {
59 this.endian=endian;
60 this.source=source;
61 currentByte=source[0];
62 bitIndex=(endian==LITTLE_ENDIAN)?0:7;
63 }
64
65 public boolean getBit() throws IOException {
66 if(endian==LITTLE_ENDIAN) {
67 if(bitIndex>7) {
68 bitIndex=0;
69 currentByte=source[++byteIndex];
70 }
71 return (currentByte&(1<<(bitIndex++)))!=0;
72 }
73 else {
74 if(bitIndex<0) {
75 bitIndex=7;
76 currentByte=source[++byteIndex];
77 }
78 return (currentByte&(1<<(bitIndex--)))!=0;
79 }
80 }
81
82 public int getInt(int bits) throws IOException {
83 if(bits>32) {
84 throw new IllegalArgumentException("Argument \"bits\" must be <= 32");
85 }
86 int res=0;
87 if(endian==LITTLE_ENDIAN) {
88 for(int i=0; i<bits; i++) {
89 if(getBit()) {
90 res|=(1<<i);
91 }
92 }
93 }
94 else {
95 if(bitIndex<0) {
96 bitIndex=7;
97 currentByte=source[++byteIndex];
98 }
99 if(bits<=bitIndex+1) {
100 int ci=((int)currentByte)&0xff;
101 int offset=1+bitIndex-bits;
102 int mask=((1<<bits)-1)<<offset;
103 res=(ci&mask)>>offset;
104 bitIndex-=bits;
105 }
106 else {
107 res=(((int)currentByte)&0xff&((1<<(bitIndex+1))-1))<<(bits-bitIndex-1);
108 bits-=bitIndex+1;
109 currentByte=source[++byteIndex];
110 while(bits>=8) {
111 bits-=8;
112 res|=(((int)source[byteIndex])&0xff)<<bits;
113 currentByte=source[++byteIndex];
114 }
115 if(bits>0) {
116 int ci=((int)source[byteIndex])&0xff;
117 res|=(ci>>(8-bits))&((1<<bits)-1);
118 bitIndex=7-bits;
119 }
120 else {
121 currentByte=source[--byteIndex];
122 bitIndex=-1;
123 }
124 }
125 }
126
127 return res;
128 }
129
130 public int getSignedInt(int bits) throws IOException {
131 int raw=getInt(bits);
132 if(raw>=1<<(bits-1)) {
133 raw-=1<<bits;
134 }
135 return raw;
136 }
137
138 public int getInt(HuffmanNode root) throws IOException {
139 while(root.value==null) {
140 if(bitIndex>7) {
141 bitIndex=0;
142 currentByte=source[++byteIndex];
143 }
144 root=(currentByte&(1<<(bitIndex++)))!=0?root.o1:root.o0;
145 }
146 return root.value.intValue();
147 }
148
149 public long getLong(int bits) throws IOException {
150 if(bits>64) {
151 throw new IllegalArgumentException("Argument \"bits\" must be <= 64");
152 }
153 long res=0;
154 if(endian==LITTLE_ENDIAN) {
155 for(int i=0; i<bits; i++) {
156 if(getBit()) {
157 res|=(1L<<i);
158 }
159 }
160 }
161 else {
162 for(int i=bits-1; i>=0; i--) {
163 if(getBit()) {
164 res|=(1L<<i);
165 }
166 }
167 }
168 return res;
169 }
170
171 /**
172 * <p>reads an integer encoded as "signed rice" as described in
173 * the FLAC audio format specification</p>
174 *
175 * <p><b>not supported for little endian</b></p>
176 *
177 * @param order
178 * @return the decoded integer value read from the stream
179 *
180 * @throws IOException if an I/O error occurs
181 * @throws UnsupportedOperationException if the method is not supported by the implementation
182 */
183
184 public int readSignedRice(int order) throws IOException {
185
186 int msbs=-1, lsbs=0, res=0;
187
188 if(endian==LITTLE_ENDIAN) {
189 // little endian
190 throw new UnsupportedOperationException("ByteArrayBitInputStream.readSignedRice() is only supported in big endian mode");
191 }
192 else {
193 // big endian
194
195 byte cb=source[byteIndex];
196 do {
197 msbs++;
198 if(bitIndex<0) {
199 bitIndex=7;
200 byteIndex++;
201 cb=source[byteIndex];
202 }
203 } while((cb&(1<<bitIndex--))==0);
204
205 int bits=order;
206
207 if(bitIndex<0) {
208 bitIndex=7;
209 byteIndex++;
210 }
211 if(bits<=bitIndex+1) {
212 int ci=((int)source[byteIndex])&0xff;
213 int offset=1+bitIndex-bits;
214 int mask=((1<<bits)-1)<<offset;
215 lsbs=(ci&mask)>>offset;
216 bitIndex-=bits;
217 }
218 else {
219 lsbs=(((int)source[byteIndex])&0xff&((1<<(bitIndex+1))-1))<<(bits-bitIndex-1);
220 bits-=bitIndex+1;
221 byteIndex++;
222 while(bits>=8) {
223 bits-=8;
224 lsbs|=(((int)source[byteIndex])&0xff)<<bits;
225 byteIndex++;
226 }
227 if(bits>0) {
228 int ci=((int)source[byteIndex])&0xff;
229 lsbs|=(ci>>(8-bits))&((1<<bits)-1);
230 bitIndex=7-bits;
231 }
232 else {
233 byteIndex--;
234 bitIndex=-1;
235 }
236 }
237
238 res=(msbs<<order)|lsbs;
239 }
240
241 return (res&1)==1?-(res>>1)-1:(res>>1);
242 }
243
244 /**
245 * <p>fills the array from <code>offset</code> with <code>len</code>
246 * integers encoded as "signed rice" as described in
247 * the FLAC audio format specification</p>
248 *
249 * <p><b>not supported for little endian</b></p>
250 *
251 * @param order
252 * @param buffer
253 * @param offset
254 * @param len
255 * @return the decoded integer value read from the stream
256 *
257 * @throws IOException if an I/O error occurs
258 * @throws UnsupportedOperationException if the method is not supported by the implementation
259 */
260
261 public void readSignedRice(int order, int[] buffer, int off, int len) throws IOException {
262
263 if(endian==LITTLE_ENDIAN) {
264 // little endian
265 throw new UnsupportedOperationException("ByteArrayBitInputStream.readSignedRice() is only supported in big endian mode");
266 }
267 else {
268 // big endian
269 for(int i=off; i<off+len; i++) {
270
271 int msbs=-1, lsbs=0;
272
273 byte cb=source[byteIndex];
274 do {
275 msbs++;
276 if(bitIndex<0) {
277 bitIndex=7;
278 byteIndex++;
279 cb=source[byteIndex];
280 }
281 } while((cb&(1<<bitIndex--))==0);
282
283 int bits=order;
284
285 if(bitIndex<0) {
286 bitIndex=7;
287 byteIndex++;
288 }
289 if(bits<=bitIndex+1) {
290 int ci=((int)source[byteIndex])&0xff;
291 int offset=1+bitIndex-bits;
292 int mask=((1<<bits)-1)<<offset;
293 lsbs=(ci&mask)>>offset;
294 bitIndex-=bits;
295 }
296 else {
297 lsbs=(((int)source[byteIndex])&0xff&((1<<(bitIndex+1))-1))<<(bits-bitIndex-1);
298 bits-=bitIndex+1;
299 byteIndex++;
300 while(bits>=8) {
301 bits-=8;
302 lsbs|=(((int)source[byteIndex])&0xff)<<bits;
303 byteIndex++;
304 }
305 if(bits>0) {
306 int ci=((int)source[byteIndex])&0xff;
307 lsbs|=(ci>>(8-bits))&((1<<bits)-1);
308 bitIndex=7-bits;
309 }
310 else {
311 byteIndex--;
312 bitIndex=-1;
313 }
314 }
315
316 int res=(msbs<<order)|lsbs;
317 buffer[i]=(res&1)==1?-(res>>1)-1:(res>>1);
318 }
319 }
320 }
321
322 public void align() {
323 if(endian==BIG_ENDIAN && bitIndex>=0) {
324 bitIndex=7;
325 byteIndex++;
326 }
327 else if(endian==LITTLE_ENDIAN && bitIndex<=7) {
328 bitIndex=0;
329 byteIndex++;
330 }
331 }
332
333 public void setEndian(int endian) {
334 if(this.endian==BIG_ENDIAN && endian==LITTLE_ENDIAN) {
335 bitIndex=0;
336 byteIndex++;
337 }
338 else if(this.endian==LITTLE_ENDIAN && endian==BIG_ENDIAN) {
339 bitIndex=7;
340 byteIndex++;
341 }
342 this.endian=endian;
343 }
344
345 /**
346 * @return the byte array used as a source for this instance
347 */
348
349 public byte[] getSource() {
350 return source;
351 }
352} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/util/io/HuffmanNode.java b/songdbj/de/jarnbjo/util/io/HuffmanNode.java
deleted file mode 100644
index 88600a4ddd..0000000000
--- a/songdbj/de/jarnbjo/util/io/HuffmanNode.java
+++ /dev/null
@@ -1,144 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.2 2003/04/10 19:48:31 jarnbjo
25 * no message
26 *
27 */
28
29package de.jarnbjo.util.io;
30
31import java.io.IOException;
32import de.jarnbjo.util.io.BitInputStream;
33
34/**
35 * Representation of a node in a Huffman tree, used to read
36 * Huffman compressed codewords from e.g. a Vorbis stream.
37 */
38
39final public class HuffmanNode {
40
41 private HuffmanNode parent;
42 private int depth=0;
43 protected HuffmanNode o0, o1;
44 protected Integer value;
45 private boolean full=false;
46
47 /**
48 * creates a new Huffman tree root node
49 */
50
51 public HuffmanNode() {
52 this(null);
53 }
54
55 protected HuffmanNode(HuffmanNode parent) {
56 this.parent=parent;
57 if(parent!=null) {
58 depth=parent.getDepth()+1;
59 }
60 }
61
62 protected HuffmanNode(HuffmanNode parent, int value) {
63 this(parent);
64 this.value=new Integer(value);
65 full=true;
66 }
67
68 protected int read(BitInputStream bis) throws IOException {
69 HuffmanNode iter=this;
70 while(iter.value==null) {
71 iter=bis.getBit()?iter.o1:iter.o0;
72 }
73 return iter.value.intValue();
74 }
75
76 protected HuffmanNode get0() {
77 return o0==null?set0(new HuffmanNode(this)):o0;
78 }
79
80 protected HuffmanNode get1() {
81 return o1==null?set1(new HuffmanNode(this)):o1;
82 }
83
84 protected Integer getValue() {
85 return value;
86 }
87
88 private HuffmanNode getParent() {
89 return parent;
90 }
91
92 protected int getDepth() {
93 return depth;
94 }
95
96 private boolean isFull() {
97 return full?true:(full=o0!=null&&o0.isFull()&&o1!=null&&o1.isFull());
98 }
99
100 private HuffmanNode set0(HuffmanNode value) {
101 return o0=value;
102 }
103
104 private HuffmanNode set1(HuffmanNode value) {
105 return o1=value;
106 }
107
108 private void setValue(Integer value) {
109 full=true;
110 this.value=value;
111 }
112
113 /**
114 * creates a new tree node at the first free location at the given
115 * depth, and assigns the value to it
116 *
117 * @param depth the tree depth of the new node (codeword length in bits)
118 * @param value the node's new value
119 */
120
121 public boolean setNewValue(int depth, int value) {
122 if(isFull()) {
123 return false;
124 }
125 if(depth==1) {
126 if(o0==null) {
127 set0(new HuffmanNode(this, value));
128 return true;
129 }
130 else if(o1==null) {
131 set1(new HuffmanNode(this, value));
132 return true;
133 }
134 else {
135 return false;
136 }
137 }
138 else {
139 return get0().setNewValue(depth-1, value)?
140 true:
141 get1().setNewValue(depth-1, value);
142 }
143 }
144}
diff --git a/songdbj/de/jarnbjo/vorbis/AudioPacket.java b/songdbj/de/jarnbjo/vorbis/AudioPacket.java
deleted file mode 100644
index 90a54073c1..0000000000
--- a/songdbj/de/jarnbjo/vorbis/AudioPacket.java
+++ /dev/null
@@ -1,328 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.2 2004/09/21 06:39:06 shred
22 * Importe reorganisiert, damit Eclipse Ruhe gibt. ;-)
23 *
24 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
25 * First Import
26 *
27 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
28 * no message
29 *
30 *
31 */
32
33package de.jarnbjo.vorbis;
34
35import java.io.IOException;
36
37import de.jarnbjo.util.io.BitInputStream;
38
39class AudioPacket {
40
41 private int modeNumber;
42 private Mode mode;
43 private Mapping mapping;
44 private int n; // block size
45 private boolean blockFlag, previousWindowFlag, nextWindowFlag;
46
47 private int windowCenter, leftWindowStart, leftWindowEnd, leftN, rightWindowStart, rightWindowEnd, rightN;
48 private float[] window;
49 private float[][] pcm;
50 private int[][] pcmInt;
51
52 private Floor[] channelFloors;
53 private boolean[] noResidues;
54
55 private final static float[][] windows=new float[8][];
56
57 protected AudioPacket(final VorbisStream vorbis, final BitInputStream source) throws VorbisFormatException, IOException {
58
59 final SetupHeader sHeader=vorbis.getSetupHeader();
60 final IdentificationHeader iHeader=vorbis.getIdentificationHeader();
61 final Mode[] modes=sHeader.getModes();
62 final Mapping[] mappings=sHeader.getMappings();
63 final Residue[] residues=sHeader.getResidues();
64 final int channels=iHeader.getChannels();
65
66 if(source.getInt(1)!=0) {
67 throw new VorbisFormatException("Packet type mismatch when trying to create an audio packet.");
68 }
69
70 modeNumber=source.getInt(Util.ilog(modes.length-1));
71
72 try {
73 mode=modes[modeNumber];
74 }
75 catch(ArrayIndexOutOfBoundsException e) {
76 throw new VorbisFormatException("Reference to invalid mode in audio packet.");
77 }
78
79 mapping=mappings[mode.getMapping()];
80
81 final int[] magnitudes=mapping.getMagnitudes();
82 final int[] angles=mapping.getAngles();
83
84 blockFlag=mode.getBlockFlag();
85
86 final int blockSize0=iHeader.getBlockSize0();
87 final int blockSize1=iHeader.getBlockSize1();
88
89 n=blockFlag?blockSize1:blockSize0;
90
91 if(blockFlag) {
92 previousWindowFlag=source.getBit();
93 nextWindowFlag=source.getBit();
94 }
95
96 windowCenter=n/2;
97
98 if(blockFlag && !previousWindowFlag) {
99 leftWindowStart=n/4-blockSize0/4;
100 leftWindowEnd=n/4+blockSize0/4;
101 leftN=blockSize0/2;
102 }
103 else {
104 leftWindowStart=0;
105 leftWindowEnd=n/2;
106 leftN=windowCenter;
107 }
108
109 if(blockFlag && !nextWindowFlag) {
110 rightWindowStart=n*3/4-blockSize0/4;
111 rightWindowEnd=n*3/4+blockSize0/4;
112 rightN=blockSize0/2;
113 }
114 else {
115 rightWindowStart=windowCenter;
116 rightWindowEnd=n;
117 rightN=n/2;
118 }
119
120 window=getComputedWindow();//new double[n];
121
122 channelFloors=new Floor[channels];
123 noResidues=new boolean[channels];
124
125 pcm=new float[channels][n];
126 pcmInt=new int[channels][n];
127
128 boolean allFloorsEmpty=true;
129
130 for(int i=0; i<channels; i++) {
131 int submapNumber=mapping.getMux()[i];
132 int floorNumber=mapping.getSubmapFloors()[submapNumber];
133 Floor decodedFloor=sHeader.getFloors()[floorNumber].decodeFloor(vorbis, source);
134 channelFloors[i]=decodedFloor;
135 noResidues[i]=decodedFloor==null;
136 if(decodedFloor!=null) {
137 allFloorsEmpty=false;
138 }
139 }
140
141 if(allFloorsEmpty) {
142 return;
143 }
144
145 for(int i=0; i<magnitudes.length; i++) {
146 if(!noResidues[magnitudes[i]] ||
147 !noResidues[angles[i]]) {
148
149 noResidues[magnitudes[i]]=false;
150 noResidues[angles[i]]=false;
151 }
152 }
153
154 Residue[] decodedResidues=new Residue[mapping.getSubmaps()];
155
156 for(int i=0; i<mapping.getSubmaps(); i++) {
157 int ch=0;
158 boolean[] doNotDecodeFlags=new boolean[channels];
159 for(int j=0; j<channels; j++) {
160 if(mapping.getMux()[j]==i) {
161 doNotDecodeFlags[ch++]=noResidues[j];
162 }
163 }
164 int residueNumber=mapping.getSubmapResidues()[i];
165 Residue residue=residues[residueNumber];
166
167 residue.decodeResidue(vorbis, source, mode, ch, doNotDecodeFlags, pcm);
168 }
169
170
171 for(int i=mapping.getCouplingSteps()-1; i>=0; i--) {
172 double newA=0, newM=0;
173 final float[] magnitudeVector=pcm[magnitudes[i]];
174 final float[] angleVector=pcm[angles[i]];
175 for(int j=0; j<magnitudeVector.length; j++) {
176 float a=angleVector[j];
177 float m=magnitudeVector[j];
178 if(a>0) {
179 //magnitudeVector[j]=m;
180 angleVector[j]=m>0?m-a:m+a;
181 }
182 else {
183 magnitudeVector[j]=m>0?m+a:m-a;
184 angleVector[j]=m;
185 }
186 }
187 }
188
189 for(int i=0; i<channels; i++) {
190 if(channelFloors[i]!=null) {
191 channelFloors[i].computeFloor(pcm[i]);
192 }
193 }
194
195 // perform an inverse mdct to all channels
196
197 for(int i=0; i<channels; i++) {
198 MdctFloat mdct=blockFlag?iHeader.getMdct1():iHeader.getMdct0();
199 mdct.imdct(pcm[i], window, pcmInt[i]);
200 }
201
202 }
203
204 private float[] getComputedWindow() {
205 int ix=(blockFlag?4:0)+(previousWindowFlag?2:0)+(nextWindowFlag?1:0);
206 float[] w=windows[ix];
207 if(w==null) {
208 w=new float[n];
209
210 for(int i=0;i<leftN;i++){
211 float x=(float)((i+.5)/leftN*Math.PI/2.);
212 x=(float)Math.sin(x);
213 x*=x;
214 x*=(float)Math.PI/2.;
215 x=(float)Math.sin(x);
216 w[i+leftWindowStart]=x;
217 }
218
219 for(int i=leftWindowEnd; i<rightWindowStart; w[i++]=1.0f);
220
221 for(int i=0;i<rightN;i++){
222 float x=(float)((rightN-i-.5)/rightN*Math.PI/2.);
223 x=(float)Math.sin(x);
224 x*=x;
225 x*=(float)Math.PI/2.;
226 x=(float)Math.sin(x);
227 w[i+rightWindowStart]=x;
228 }
229
230 windows[ix]=w;
231 }
232 return w;
233 }
234
235 protected int getNumberOfSamples() {
236 return rightWindowStart-leftWindowStart;
237 }
238
239 protected int getPcm(final AudioPacket previousPacket, final int[][] buffer) {
240 int channels=pcm.length;
241 int val;
242
243 // copy left window flank and mix with right window flank from
244 // the previous audio packet
245 for(int i=0; i<channels; i++) {
246 int j1=0, j2=previousPacket.rightWindowStart;
247 final int[] ppcm=previousPacket.pcmInt[i];
248 final int[] tpcm=pcmInt[i];
249 final int[] target=buffer[i];
250
251 for(int j=leftWindowStart; j<leftWindowEnd; j++) {
252 val=ppcm[j2++]+tpcm[j];
253 if(val>32767) val=32767;
254 if(val<-32768) val=-32768;
255 target[j1++]=val;
256 }
257 }
258
259 // use System.arraycopy to copy the middle part (if any)
260 // of the window
261 if(leftWindowEnd+1<rightWindowStart) {
262 for(int i=0; i<channels; i++) {
263 System.arraycopy(pcmInt[i], leftWindowEnd, buffer[i], leftWindowEnd-leftWindowStart, rightWindowStart-leftWindowEnd);
264 }
265 }
266
267 return rightWindowStart-leftWindowStart;
268 }
269
270 protected void getPcm(final AudioPacket previousPacket, final byte[] buffer) {
271 int channels=pcm.length;
272 int val;
273
274 // copy left window flank and mix with right window flank from
275 // the previous audio packet
276 for(int i=0; i<channels; i++) {
277 int ix=0, j2=previousPacket.rightWindowStart;
278 final int[] ppcm=previousPacket.pcmInt[i];
279 final int[] tpcm=pcmInt[i];
280 for(int j=leftWindowStart; j<leftWindowEnd; j++) {
281 val=ppcm[j2++]+tpcm[j];
282 if(val>32767) val=32767;
283 if(val<-32768) val=-32768;
284 buffer[ix+(i*2)+1]=(byte)(val&0xff);
285 buffer[ix+(i*2)]=(byte)((val>>8)&0xff);
286 ix+=channels*2;
287 }
288
289 ix=(leftWindowEnd-leftWindowStart)*channels*2;
290 for(int j=leftWindowEnd; j<rightWindowStart; j++) {
291 val=tpcm[j];
292 if(val>32767) val=32767;
293 if(val<-32768) val=-32768;
294 buffer[ix+(i*2)+1]=(byte)(val&0xff);
295 buffer[ix+(i*2)]=(byte)((val>>8)&0xff);
296 ix+=channels*2;
297 }
298 }
299 }
300
301 protected float[] getWindow() {
302 return window;
303 }
304
305 protected int getLeftWindowStart() {
306 return leftWindowStart;
307 }
308
309 protected int getLeftWindowEnd() {
310 return leftWindowEnd;
311 }
312
313 protected int getRightWindowStart() {
314 return rightWindowStart;
315 }
316
317 protected int getRightWindowEnd() {
318 return rightWindowEnd;
319 }
320
321 public int[][] getPcm() {
322 return pcmInt;
323 }
324
325 public float[][] getFreqencyDomain() {
326 return pcm;
327 }
328}
diff --git a/songdbj/de/jarnbjo/vorbis/CodeBook.java b/songdbj/de/jarnbjo/vorbis/CodeBook.java
deleted file mode 100644
index c865b120ca..0000000000
--- a/songdbj/de/jarnbjo/vorbis/CodeBook.java
+++ /dev/null
@@ -1,275 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.2 2004/09/21 06:39:06 shred
22 * Importe reorganisiert, damit Eclipse Ruhe gibt. ;-)
23 *
24 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
25 * First Import
26 *
27 * Revision 1.3 2003/04/10 19:49:04 jarnbjo
28 * no message
29 *
30 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
31 * no message
32 *
33 *
34 */
35
36package de.jarnbjo.vorbis;
37
38import java.io.IOException;
39import java.util.Arrays;
40
41import de.jarnbjo.util.io.BitInputStream;
42import de.jarnbjo.util.io.HuffmanNode;
43
44class CodeBook {
45
46 private HuffmanNode huffmanRoot;
47 private int dimensions, entries;
48
49 private int[] entryLengths;
50 private float[][] valueVector;
51
52 protected CodeBook(BitInputStream source) throws VorbisFormatException, IOException {
53
54 // check sync
55 if(source.getInt(24)!=0x564342) {
56 throw new VorbisFormatException("The code book sync pattern is not correct.");
57 }
58
59 dimensions=source.getInt(16);
60 entries=source.getInt(24);
61
62 entryLengths=new int[entries];
63
64 boolean ordered=source.getBit();
65
66 if(ordered) {
67 int cl=source.getInt(5)+1;
68 for(int i=0; i<entryLengths.length; ) {
69 int num=source.getInt(Util.ilog(entryLengths.length-i));
70 if(i+num>entryLengths.length) {
71 throw new VorbisFormatException("The codebook entry length list is longer than the actual number of entry lengths.");
72 }
73 Arrays.fill(entryLengths, i, i+num, cl);
74 cl++;
75 i+=num;
76 }
77 }
78 else {
79 // !ordered
80 boolean sparse=source.getBit();
81
82 if(sparse) {
83 for(int i=0; i<entryLengths.length; i++) {
84 if(source.getBit()) {
85 entryLengths[i]=source.getInt(5)+1;
86 }
87 else {
88 entryLengths[i]=-1;
89 }
90 }
91 }
92 else {
93 // !sparse
94 for(int i=0; i<entryLengths.length; i++) {
95 entryLengths[i]=source.getInt(5)+1;
96 }
97 }
98 }
99
100 if (!createHuffmanTree(entryLengths)) {
101 throw new VorbisFormatException("An exception was thrown when building the codebook Huffman tree.");
102 }
103
104 int codeBookLookupType=source.getInt(4);
105
106 switch(codeBookLookupType) {
107 case 0:
108 // codebook has no scalar vectors to be calculated
109 break;
110 case 1:
111 case 2:
112 float codeBookMinimumValue=Util.float32unpack(source.getInt(32));
113 float codeBookDeltaValue=Util.float32unpack(source.getInt(32));
114
115 int codeBookValueBits=source.getInt(4)+1;
116 boolean codeBookSequenceP=source.getBit();
117
118 int codeBookLookupValues=0;
119
120 if(codeBookLookupType==1) {
121 codeBookLookupValues=Util.lookup1Values(entries, dimensions);
122 }
123 else {
124 codeBookLookupValues=entries*dimensions;
125 }
126
127 int codeBookMultiplicands[]=new int[codeBookLookupValues];
128
129 for(int i=0; i<codeBookMultiplicands.length; i++) {
130 codeBookMultiplicands[i]=source.getInt(codeBookValueBits);
131 }
132
133 valueVector=new float[entries][dimensions];
134
135 if(codeBookLookupType==1) {
136 for(int i=0; i<entries; i++) {
137 float last=0;
138 int indexDivisor=1;
139 for(int j=0; j<dimensions; j++) {
140 int multiplicandOffset=
141 (i/indexDivisor)%codeBookLookupValues;
142 valueVector[i][j]=
143 codeBookMultiplicands[multiplicandOffset]*codeBookDeltaValue+codeBookMinimumValue+last;
144 if(codeBookSequenceP) {
145 last=valueVector[i][j];
146 }
147 indexDivisor*=codeBookLookupValues;
148 }
149 }
150 }
151 else {
152 throw new UnsupportedOperationException();
153 /** @todo implement */
154 }
155 break;
156 default:
157 throw new VorbisFormatException("Unsupported codebook lookup type: "+codeBookLookupType);
158 }
159 }
160
161 private static long totalTime=0;
162
163 private boolean createHuffmanTree(int[] entryLengths) {
164 huffmanRoot=new HuffmanNode();
165 for(int i=0; i<entryLengths.length; i++) {
166 int el=entryLengths[i];
167 if(el>0) {
168 if(!huffmanRoot.setNewValue(el, i)) {
169 return false;
170 }
171 }
172 }
173 return true;
174 }
175
176 protected int getDimensions() {
177 return dimensions;
178 }
179
180 protected int getEntries() {
181 return entries;
182 }
183
184 protected HuffmanNode getHuffmanRoot() {
185 return huffmanRoot;
186 }
187
188 //public float[] readVQ(ReadableBitChannel source) throws IOException {
189 // return valueVector[readInt(source)];
190 //}
191
192 protected int readInt(final BitInputStream source) throws IOException {
193 return source.getInt(huffmanRoot);
194 /*
195 HuffmanNode node;
196 for(node=huffmanRoot; node.value==null; node=source.getBit()?node.o1:node.o0);
197 return node.value.intValue();
198 */
199 }
200
201 protected void readVvAdd(float[][] a, BitInputStream source, int offset, int length)
202 throws VorbisFormatException, IOException {
203
204 int i,j;//k;//entry;
205 int chptr=0;
206 int ch=a.length;
207
208 if(ch==0) {
209 return;
210 }
211
212 int lim=(offset+length)/ch;
213
214 for(i=offset/ch;i<lim;){
215 final float[] ve=valueVector[source.getInt(huffmanRoot)];
216 for(j=0;j<dimensions;j++){
217 a[chptr++][i]+=ve[j];
218 if(chptr==ch){
219 chptr=0;
220 i++;
221 }
222 }
223 }
224 }
225
226 /*
227 public void readVAdd(double[] a, ReadableBitChannel source, int offset, int length)
228 throws FormatException, IOException {
229
230 int i,j,entry;
231 int t;
232
233 if(dimensions>8){
234 for(i=0;i<length;){
235 entry = readInt(source);
236 //if(entry==-1)return(-1);
237 //t=entry*dimensions;
238 for(j=0;j<dimensions;){
239 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
240 }
241 }
242 }
243 else{
244 for(i=0;i<length;){
245 entry=readInt(source);
246 //if(entry==-1)return(-1);
247 //t=entry*dim;
248 j=0;
249 switch(dimensions){
250 case 8:
251 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
252 case 7:
253 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
254 case 6:
255 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
256 case 5:
257 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
258 case 4:
259 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
260 case 3:
261 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
262 case 2:
263 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
264 case 1:
265 a[offset+(i++)]+=valueVector[entry][j++];//valuelist[t+(j++)];
266 case 0:
267 break;
268 }
269 }
270 }
271 }
272 */
273
274
275} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/CommentHeader.java b/songdbj/de/jarnbjo/vorbis/CommentHeader.java
deleted file mode 100644
index dd00ebca38..0000000000
--- a/songdbj/de/jarnbjo/vorbis/CommentHeader.java
+++ /dev/null
@@ -1,244 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
25 * no message
26 *
27 *
28 */
29
30package de.jarnbjo.vorbis;
31
32import java.io.*;
33
34import java.util.*;
35
36import de.jarnbjo.util.io.BitInputStream;
37
38/**
39 */
40
41public class CommentHeader {
42
43 public static final String TITLE = "TITLE";
44 public static final String ARTIST = "ARTIST";
45 public static final String ALBUM = "ALBUM";
46 public static final String TRACKNUMBER = "TRACKNUMBER";
47 public static final String VERSION = "VERSION";
48 public static final String PERFORMER = "PERFORMER";
49 public static final String COPYRIGHT = "COPYRIGHT";
50 public static final String LICENSE = "LICENSE";
51 public static final String ORGANIZATION = "ORGANIZATION";
52 public static final String DESCRIPTION = "DESCRIPTION";
53 public static final String GENRE = "GENRE";
54 public static final String DATE = "DATE";
55 public static final String LOCATION = "LOCATION";
56 public static final String CONTACT = "CONTACT";
57 public static final String ISRC = "ISRC";
58
59 private String vendor;
60 private HashMap comments=new HashMap();
61 private boolean framingBit;
62
63 private static final long HEADER = 0x736962726f76L; // 'vorbis'
64
65 public CommentHeader(BitInputStream source) throws VorbisFormatException, IOException {
66 if(source.getLong(48)!=HEADER) {
67 throw new VorbisFormatException("The identification header has an illegal leading.");
68 }
69
70 vendor=getString(source);
71
72 int ucLength=source.getInt(32);
73
74 for(int i=0; i<ucLength; i++) {
75 String comment=getString(source);
76 int ix=comment.indexOf('=');
77 String key=comment.substring(0, ix);
78 String value=comment.substring(ix+1);
79 //comments.put(key, value);
80 addComment(key, value);
81 }
82
83 framingBit=source.getInt(8)!=0;
84 }
85
86 private void addComment(String key, String value) {
87 key = key.toUpperCase(); // Comment keys are case insensitive
88 ArrayList al=(ArrayList)comments.get(key);
89 if(al==null) {
90 al=new ArrayList();
91 comments.put(key, al);
92 }
93 al.add(value);
94 }
95
96 public String getVendor() {
97 return vendor;
98 }
99
100 public String getComment(String key) {
101 ArrayList al=(ArrayList)comments.get(key);
102 return al==null?(String)null:(String)al.get(0);
103 }
104
105 public String[] getComments(String key) {
106 ArrayList al=(ArrayList)comments.get(key);
107 return al==null?new String[0]:(String[])al.toArray(new String[al.size()]);
108 }
109
110 public String getTitle() {
111 return getComment(TITLE);
112 }
113
114 public String[] getTitles() {
115 return getComments(TITLE);
116 }
117
118 public String getVersion() {
119 return getComment(VERSION);
120 }
121
122 public String[] getVersions() {
123 return getComments(VERSION);
124 }
125
126 public String getAlbum() {
127 return getComment(ALBUM);
128 }
129
130 public String[] getAlbums() {
131 return getComments(ALBUM);
132 }
133
134 public String getTrackNumber() {
135 return getComment(TRACKNUMBER);
136 }
137
138 public String[] getTrackNumbers() {
139 return getComments(TRACKNUMBER);
140 }
141
142 public String getArtist() {
143 return getComment(ARTIST);
144 }
145
146 public String[] getArtists() {
147 return getComments(ARTIST);
148 }
149
150 public String getPerformer() {
151 return getComment(PERFORMER);
152 }
153
154 public String[] getPerformers() {
155 return getComments(PERFORMER);
156 }
157
158 public String getCopyright() {
159 return getComment(COPYRIGHT);
160 }
161
162 public String[] getCopyrights() {
163 return getComments(COPYRIGHT);
164 }
165
166 public String getLicense() {
167 return getComment(LICENSE);
168 }
169
170 public String[] getLicenses() {
171 return getComments(LICENSE);
172 }
173
174 public String getOrganization() {
175 return getComment(ORGANIZATION);
176 }
177
178 public String[] getOrganizations() {
179 return getComments(ORGANIZATION);
180 }
181
182 public String getDescription() {
183 return getComment(DESCRIPTION);
184 }
185
186 public String[] getDescriptions() {
187 return getComments(DESCRIPTION);
188 }
189
190 public String getGenre() {
191 return getComment(GENRE);
192 }
193
194 public String[] getGenres() {
195 return getComments(GENRE);
196 }
197
198 public String getDate() {
199 return getComment(DATE);
200 }
201
202 public String[] getDates() {
203 return getComments(DATE);
204 }
205
206 public String getLocation() {
207 return getComment(LOCATION);
208 }
209
210 public String[] getLocations() {
211 return getComments(LOCATION);
212 }
213
214 public String getContact() {
215 return getComment(CONTACT);
216 }
217
218 public String[] getContacts() {
219 return getComments(CONTACT);
220 }
221
222 public String getIsrc() {
223 return getComment(ISRC);
224 }
225
226 public String[] getIsrcs() {
227 return getComments(ISRC);
228 }
229
230
231 private String getString(BitInputStream source) throws IOException, VorbisFormatException {
232
233 int length=source.getInt(32);
234
235 byte[] strArray=new byte[length];
236
237 for(int i=0; i<length; i++) {
238 strArray[i]=(byte)source.getInt(8);
239 }
240
241 return new String(strArray, "UTF-8");
242 }
243
244} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/Floor.java b/songdbj/de/jarnbjo/vorbis/Floor.java
deleted file mode 100644
index 5be2798dfb..0000000000
--- a/songdbj/de/jarnbjo/vorbis/Floor.java
+++ /dev/null
@@ -1,124 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.3 2003/04/10 19:49:04 jarnbjo
25 * no message
26 *
27 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
28 * no message
29 *
30 *
31 */
32
33package de.jarnbjo.vorbis;
34
35import java.io.IOException;
36
37import de.jarnbjo.util.io.BitInputStream;
38
39
40public abstract class Floor {
41
42 public final static float[] DB_STATIC_TABLE={
43 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f,
44 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f,
45 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.128753e-07f,
46 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f,
47 2.9163793e-07f, 3.1059021e-07f, 3.3077411e-07f, 3.5226968e-07f,
48 3.7516214e-07f, 3.9954229e-07f, 4.2550680e-07f, 4.5315863e-07f,
49 4.8260743e-07f, 5.1396998e-07f, 5.4737065e-07f, 5.8294187e-07f,
50 6.2082472e-07f, 6.6116941e-07f, 7.0413592e-07f, 7.4989464e-07f,
51 7.9862701e-07f, 8.5052630e-07f, 9.0579828e-07f, 9.6466216e-07f,
52 1.0273513e-06f, 1.0941144e-06f, 1.1652161e-06f, 1.2409384e-06f,
53 1.3215816e-06f, 1.4074654e-06f, 1.4989305e-06f, 1.5963394e-06f,
54 1.7000785e-06f, 1.8105592e-06f, 1.9282195e-06f, 2.0535261e-06f,
55 2.1869758e-06f, 2.3290978e-06f, 2.4804557e-06f, 2.6416497e-06f,
56 2.8133190e-06f, 2.9961443e-06f, 3.1908506e-06f, 3.3982101e-06f,
57 3.6190449e-06f, 3.8542308e-06f, 4.1047004e-06f, 4.3714470e-06f,
58 4.6555282e-06f, 4.9580707e-06f, 5.2802740e-06f, 5.6234160e-06f,
59 5.9888572e-06f, 6.3780469e-06f, 6.7925283e-06f, 7.2339451e-06f,
60 7.7040476e-06f, 8.2047000e-06f, 8.7378876e-06f, 9.3057248e-06f,
61 9.9104632e-06f, 1.0554501e-05f, 1.1240392e-05f, 1.1970856e-05f,
62 1.2748789e-05f, 1.3577278e-05f, 1.4459606e-05f, 1.5399272e-05f,
63 1.6400004e-05f, 1.7465768e-05f, 1.8600792e-05f, 1.9809576e-05f,
64 2.1096914e-05f, 2.2467911e-05f, 2.3928002e-05f, 2.5482978e-05f,
65 2.7139006e-05f, 2.8902651e-05f, 3.0780908e-05f, 3.2781225e-05f,
66 3.4911534e-05f, 3.7180282e-05f, 3.9596466e-05f, 4.2169667e-05f,
67 4.4910090e-05f, 4.7828601e-05f, 5.0936773e-05f, 5.4246931e-05f,
68 5.7772202e-05f, 6.1526565e-05f, 6.5524908e-05f, 6.9783085e-05f,
69 7.4317983e-05f, 7.9147585e-05f, 8.4291040e-05f, 8.9768747e-05f,
70 9.5602426e-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f,
71 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f,
72 0.00015820453f, 0.00016848555f, 0.00017943469f, 0.00019109536f,
73 0.00020351382f, 0.00021673929f, 0.00023082423f, 0.00024582449f,
74 0.00026179955f, 0.00027881276f, 0.00029693158f, 0.00031622787f,
75 0.00033677814f, 0.00035866388f, 0.00038197188f, 0.00040679456f,
76 0.00043323036f, 0.00046138411f, 0.00049136745f, 0.00052329927f,
77 0.00055730621f, 0.00059352311f, 0.00063209358f, 0.00067317058f,
78 0.00071691700f, 0.00076350630f, 0.00081312324f, 0.00086596457f,
79 0.00092223983f, 0.00098217216f, 0.0010459992f, 0.0011139742f,
80 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f,
81 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f,
82 0.0019632195f, 0.0020908006f, 0.0022266726f, 0.0023713743f,
83 0.0025254795f, 0.0026895994f, 0.0028643847f, 0.0030505286f,
84 0.0032487691f, 0.0034598925f, 0.0036847358f, 0.0039241906f,
85 0.0041792066f, 0.0044507950f, 0.0047400328f, 0.0050480668f,
86 0.0053761186f, 0.0057254891f, 0.0060975636f, 0.0064938176f,
87 0.0069158225f, 0.0073652516f, 0.0078438871f, 0.0083536271f,
88 0.0088964928f, 0.009474637f, 0.010090352f, 0.010746080f,
89 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f,
90 0.014722068f, 0.015678791f, 0.016697687f, 0.017782797f,
91 0.018938423f, 0.020169149f, 0.021479854f, 0.022875735f,
92 0.024362330f, 0.025945531f, 0.027631618f, 0.029427276f,
93 0.031339626f, 0.033376252f, 0.035545228f, 0.037855157f,
94 0.040315199f, 0.042935108f, 0.045725273f, 0.048696758f,
95 0.051861348f, 0.055231591f, 0.058820850f, 0.062643361f,
96 0.066714279f, 0.071049749f, 0.075666962f, 0.080584227f,
97 0.085821044f, 0.091398179f, 0.097337747f, 0.10366330f,
98 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f,
99 0.14201813f, 0.15124727f, 0.16107617f, 0.17154380f,
100 0.18269168f, 0.19456402f, 0.20720788f, 0.22067342f,
101 0.23501402f, 0.25028656f, 0.26655159f, 0.28387361f,
102 0.30232132f, 0.32196786f, 0.34289114f, 0.36517414f,
103 0.38890521f, 0.41417847f, 0.44109412f, 0.46975890f,
104 0.50028648f, 0.53279791f, 0.56742212f, 0.60429640f,
105 0.64356699f, 0.68538959f, 0.72993007f, 0.77736504f,
106 0.82788260f, 0.88168307f, 0.9389798f, 1.0f};
107
108 static Floor createInstance(BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException {
109
110 int type=source.getInt(16);
111 switch(type) {
112 case 0:
113 return new Floor0(source, header);
114 case 1:
115 return new Floor1(source, header);
116 default:
117 throw new VorbisFormatException("Floor type "+type+" is not supported.");
118 }
119 }
120
121 abstract int getType();
122 abstract Floor decodeFloor(VorbisStream vorbis, BitInputStream source) throws VorbisFormatException, IOException;
123 abstract void computeFloor(float[] vector);
124} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/Floor0.java b/songdbj/de/jarnbjo/vorbis/Floor0.java
deleted file mode 100644
index 4e94b27b73..0000000000
--- a/songdbj/de/jarnbjo/vorbis/Floor0.java
+++ /dev/null
@@ -1,74 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
25 * no message
26 *
27 *
28 */
29
30package de.jarnbjo.vorbis;
31
32import java.io.IOException;
33
34import de.jarnbjo.util.io.BitInputStream;
35
36class Floor0 extends Floor {
37
38 private int order, rate, barkMapSize, amplitudeBits, amplitudeOffset;
39 private int bookList[];
40
41 protected Floor0(BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException {
42
43 order=source.getInt(8);
44 rate=source.getInt(16);
45 barkMapSize=source.getInt(16);
46 amplitudeBits=source.getInt(6);
47 amplitudeOffset=source.getInt(8);
48
49 int bookCount=source.getInt(4)+1;
50 bookList=new int[bookCount];
51
52 for(int i=0; i<bookList.length; i++) {
53 bookList[i]=source.getInt(8);
54 if(bookList[i]>header.getCodeBooks().length) {
55 throw new VorbisFormatException("A floor0_book_list entry is higher than the code book count.");
56 }
57 }
58 }
59
60 protected int getType() {
61 return 0;
62 }
63
64 protected Floor decodeFloor(VorbisStream vorbis, BitInputStream source) throws VorbisFormatException, IOException {
65 /** @todo implement */
66 throw new UnsupportedOperationException();
67 }
68
69 protected void computeFloor(float[] vector) {
70 /** @todo implement */
71 throw new UnsupportedOperationException();
72 }
73
74} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/Floor1.java b/songdbj/de/jarnbjo/vorbis/Floor1.java
deleted file mode 100644
index 69a118b44e..0000000000
--- a/songdbj/de/jarnbjo/vorbis/Floor1.java
+++ /dev/null
@@ -1,324 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$multip
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
25 * no message
26 *
27 *
28 */
29
30package de.jarnbjo.vorbis;
31
32import java.io.IOException;
33import java.util.*;
34
35import de.jarnbjo.util.io.BitInputStream;
36
37
38class Floor1 extends Floor implements Cloneable {
39
40 private int[] partitionClassList;
41 private int maximumClass, multiplier, rangeBits;
42 private int[] classDimensions;
43 private int[] classSubclasses;
44 private int[] classMasterbooks;
45 private int[][] subclassBooks;
46 private int[] xList;
47 private int[] yList;
48 private int[] lowNeighbours, highNeighbours;
49 //private boolean[] step2Flags;
50
51 private static final int[] RANGES = {256, 128, 86, 64};
52
53 private Floor1() {
54 }
55
56 protected Floor1(BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException {
57
58 maximumClass=-1;
59 int partitions=source.getInt(5);
60 partitionClassList=new int[partitions];
61
62 for(int i=0; i<partitionClassList.length; i++) {
63 partitionClassList[i]=source.getInt(4);
64 if(partitionClassList[i]>maximumClass) {
65 maximumClass=partitionClassList[i];
66 }
67 }
68
69
70 classDimensions=new int[maximumClass+1];
71 classSubclasses=new int[maximumClass+1];
72 classMasterbooks=new int[maximumClass+1];
73 subclassBooks=new int[maximumClass+1][];
74
75 int xListLength=2;
76
77 for(int i=0; i<=maximumClass; i++) {
78 classDimensions[i]=source.getInt(3)+1;
79 xListLength+=classDimensions[i];
80 classSubclasses[i]=source.getInt(2);
81
82 if(classDimensions[i] > header.getCodeBooks().length ||
83 classSubclasses[i] > header.getCodeBooks().length) {
84 throw new VorbisFormatException("There is a class dimension or class subclasses entry higher than the number of codebooks in the setup header.");
85 }
86 if(classSubclasses[i]!=0) {
87 classMasterbooks[i]=source.getInt(8);
88 }
89 subclassBooks[i]=new int[1<<classSubclasses[i]];
90 for(int j=0; j<subclassBooks[i].length; j++) {
91 subclassBooks[i][j]=source.getInt(8)-1;
92 }
93 }
94
95 multiplier=source.getInt(2)+1;
96 rangeBits=source.getInt(4);
97
98 //System.out.println("multiplier: "+multiplier);
99 //System.out.println("rangeBits: "+rangeBits);
100
101 //System.out.println("xListLength: "+xListLength);
102
103 int floorValues=0;
104
105 ArrayList alXList=new ArrayList();
106
107 alXList.add(new Integer(0));
108 alXList.add(new Integer(1<<rangeBits));
109
110 //System.out.println("partitions: "+partitions);
111 //System.out.println("classDimensions.length: "+classDimensions.length);
112
113 for(int i=0; i<partitions; i++) {
114 for(int j=0; j<classDimensions[partitionClassList[i]]; j++) {
115 alXList.add(new Integer(source.getInt(rangeBits)));
116 }
117 }
118
119 xList=new int[alXList.size()];
120 lowNeighbours=new int[xList.length];
121 highNeighbours=new int[xList.length];
122
123 Iterator iter=alXList.iterator();
124 for(int i=0; i<xList.length; i++) {
125 xList[i]=((Integer)iter.next()).intValue();
126 }
127
128 for(int i=0; i<xList.length; i++) {
129 lowNeighbours[i]=Util.lowNeighbour(xList, i);
130 highNeighbours[i]=Util.highNeighbour(xList, i);
131 }
132 }
133
134 protected int getType() {
135 return 1;
136 }
137
138 protected Floor decodeFloor(VorbisStream vorbis, BitInputStream source) throws VorbisFormatException, IOException {
139
140 //System.out.println("decodeFloor");
141 if(!source.getBit()) {
142 //System.out.println("null");
143 return null;
144 }
145
146 Floor1 clone=(Floor1)clone();
147
148 clone.yList=new int[xList.length];
149
150 int range=RANGES[multiplier-1];
151
152 clone.yList[0]=source.getInt(Util.ilog(range-1));
153 clone.yList[1]=source.getInt(Util.ilog(range-1));
154
155 int offset=2;
156
157 for(int i=0; i<partitionClassList.length; i++) {
158 int cls=partitionClassList[i];
159 int cdim=classDimensions[cls];
160 int cbits=classSubclasses[cls];
161 int csub=(1<<cbits)-1;
162 int cval=0;
163 if(cbits>0) {
164 cval=source.getInt(vorbis.getSetupHeader().getCodeBooks()[classMasterbooks[cls]].getHuffmanRoot());
165 //cval=vorbis.getSetupHeader().getCodeBooks()[classMasterbooks[cls]].readInt(source);
166 //System.out.println("cval: "+cval);
167 }
168 //System.out.println("0: "+cls+" "+cdim+" "+cbits+" "+csub+" "+cval);
169 for(int j=0; j<cdim; j++) {
170 //System.out.println("a: "+cls+" "+cval+" "+csub);
171 int book=subclassBooks[cls][cval&csub];
172 cval>>>=cbits;
173 if(book>=0) {
174 clone.yList[j+offset]=source.getInt(vorbis.getSetupHeader().getCodeBooks()[book].getHuffmanRoot());
175 //clone.yList[j+offset]=vorbis.getSetupHeader().getCodeBooks()[book].readInt(source);
176 //System.out.println("b: "+(j+offset)+" "+book+" "+clone.yList[j+offset]);
177 //System.out.println("");
178 }
179 else {
180 clone.yList[j+offset]=0;
181 }
182 }
183 offset+=cdim;
184 }
185
186 //System.out.println("");
187 //for(int i=0; i<clone.xList.length; i++) {
188 // System.out.println(i+" = "+clone.xList[i]);
189 //}
190
191 //System.out.println("");
192 //for(int i=0; i<clone.yList.length; i++) {
193 // System.out.println(i+" = "+clone.yList[i]);
194 //}
195
196 //System.out.println("offset: "+offset);
197 //System.out.println("yList.length: "+clone.yList.length);
198
199 //System.exit(0);
200
201 return clone;
202 }
203
204 protected void computeFloor(final float[] vector) {
205
206 int n=vector.length;
207 final int values=xList.length;
208 final boolean[] step2Flags=new boolean[values];
209
210 final int range=RANGES[multiplier-1];
211
212 for(int i=2; i<values; i++) {
213 final int lowNeighbourOffset=lowNeighbours[i];//Util.lowNeighbour(xList, i);
214 final int highNeighbourOffset=highNeighbours[i];//Util.highNeighbour(xList, i);
215 final int predicted=Util.renderPoint(
216 xList[lowNeighbourOffset], xList[highNeighbourOffset],
217 yList[lowNeighbourOffset], yList[highNeighbourOffset],
218 xList[i]);
219 final int val=yList[i];
220 final int highRoom=range-predicted;
221 final int lowRoom=predicted;
222 final int room=highRoom<lowRoom?highRoom*2:lowRoom*2;
223 if(val!=0) {
224 step2Flags[lowNeighbourOffset]=true;
225 step2Flags[highNeighbourOffset]=true;
226 step2Flags[i]=true;
227 if(val>=room) {
228 yList[i]=highRoom>lowRoom?
229 val-lowRoom+predicted:
230 -val+highRoom+predicted-1;
231 }
232 else {
233 yList[i]=(val&1)==1?
234 predicted-((val+1)>>1):
235 predicted+(val>>1);
236 }
237 }
238 else {
239 step2Flags[i]=false;
240 yList[i]=predicted;
241 }
242 }
243
244 final int[] xList2=new int[values];
245
246 System.arraycopy(xList, 0, xList2, 0, values);
247 sort(xList2, yList, step2Flags);
248
249 int hx=0, hy=0, lx=0, ly=yList[0]*multiplier;
250
251 float[] vector2=new float[vector.length];
252 float[] vector3=new float[vector.length];
253 Arrays.fill(vector2, 1.0f);
254 System.arraycopy(vector, 0, vector3, 0, vector.length);
255
256 for(int i=1; i<values; i++) {
257 if(step2Flags[i]) {
258 hy=yList[i]*multiplier;
259 hx=xList2[i];
260 Util.renderLine(lx, ly, hx, hy, vector);
261 Util.renderLine(lx, ly, hx, hy, vector2);
262 lx=hx;
263 ly=hy;
264 }
265 }
266
267 final float r=DB_STATIC_TABLE[hy];
268 for(; hx<n/2; vector[hx++]=r);
269 }
270
271 public Object clone() {
272 Floor1 clone=new Floor1();
273 clone.classDimensions=classDimensions;
274 clone.classMasterbooks=classMasterbooks;
275 clone.classSubclasses=classSubclasses;
276 clone.maximumClass=maximumClass;
277 clone.multiplier=multiplier;
278 clone.partitionClassList=partitionClassList;
279 clone.rangeBits=rangeBits;
280 clone.subclassBooks=subclassBooks;
281 clone.xList=xList;
282 clone.yList=yList;
283 clone.lowNeighbours=lowNeighbours;
284 clone.highNeighbours=highNeighbours;
285 return clone;
286 }
287
288 private final static void sort(int x[], int y[], boolean b[]) {
289 int off=0;
290 int len=x.length;
291 int lim=len+off;
292 int itmp;
293 boolean btmp;
294 // Insertion sort on smallest arrays
295 for (int i=off; i<lim; i++) {
296 for (int j=i; j>off && x[j-1]>x[j]; j--) {
297 itmp=x[j];
298 x[j]=x[j-1];
299 x[j-1]=itmp;
300 itmp=y[j];
301 y[j]=y[j-1];
302 y[j-1]=itmp;
303 btmp=b[j];
304 b[j]=b[j-1];
305 b[j-1]=btmp;
306 //swap(x, j, j-1);
307 //swap(y, j, j-1);
308 //swap(b, j, j-1);
309 }
310 }
311 }
312
313 private final static void swap(int x[], int a, int b) {
314 int t = x[a];
315 x[a] = x[b];
316 x[b] = t;
317 }
318
319 private final static void swap(boolean x[], int a, int b) {
320 boolean t = x[a];
321 x[a] = x[b];
322 x[b] = t;
323 }
324} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/IdentificationHeader.java b/songdbj/de/jarnbjo/vorbis/IdentificationHeader.java
deleted file mode 100644
index 1e18163385..0000000000
--- a/songdbj/de/jarnbjo/vorbis/IdentificationHeader.java
+++ /dev/null
@@ -1,120 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.2 2004/09/21 06:39:06 shred
22 * Importe reorganisiert, damit Eclipse Ruhe gibt. ;-)
23 *
24 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
25 * First Import
26 *
27 * Revision 1.3 2003/03/31 00:20:16 jarnbjo
28 * no message
29 *
30 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
31 * no message
32 *
33 *
34 */
35
36package de.jarnbjo.vorbis;
37
38import java.io.IOException;
39
40import de.jarnbjo.util.io.BitInputStream;
41
42/**
43 */
44
45public class IdentificationHeader {
46
47 private int version, channels, sampleRate, bitrateMaximum, bitrateNominal, bitrateMinimum, blockSize0, blockSize1;
48 private boolean framingFlag;
49 private MdctFloat[] mdct=new MdctFloat[2];
50 //private MdctLong[] mdctInt=new MdctLong[2];
51
52 private static final long HEADER = 0x736962726f76L; // 'vorbis'
53
54 public IdentificationHeader(BitInputStream source) throws VorbisFormatException, IOException {
55 //equalizer=new Equalizer();
56 //equalizer.pack();
57 //equalizer.show();
58
59 long leading=source.getLong(48);
60 if(leading!=HEADER) {
61 throw new VorbisFormatException("The identification header has an illegal leading.");
62 }
63 version=source.getInt(32);
64 channels=source.getInt(8);
65 sampleRate=source.getInt(32);
66 bitrateMaximum=source.getInt(32);
67 bitrateNominal=source.getInt(32);
68 bitrateMinimum=source.getInt(32);
69 int bs=source.getInt(8);
70 blockSize0=1<<(bs&0xf);
71 blockSize1=1<<(bs>>4);
72
73 mdct[0]=new MdctFloat(blockSize0);
74 mdct[1]=new MdctFloat(blockSize1);
75 //mdctInt[0]=new MdctLong(blockSize0);
76 //mdctInt[1]=new MdctLong(blockSize1);
77
78 framingFlag=source.getInt(8)!=0;
79 }
80
81 public int getSampleRate() {
82 return sampleRate;
83 }
84
85 public int getMaximumBitrate() {
86 return bitrateMaximum;
87 }
88
89 public int getNominalBitrate() {
90 return bitrateNominal;
91 }
92
93 public int getMinimumBitrate() {
94 return bitrateMinimum;
95 }
96
97 public int getChannels() {
98 return channels;
99 }
100
101 public int getBlockSize0() {
102 return blockSize0;
103 }
104
105 public int getBlockSize1() {
106 return blockSize1;
107 }
108
109 protected MdctFloat getMdct0() {
110 return mdct[0];
111 }
112
113 protected MdctFloat getMdct1() {
114 return mdct[1];
115 }
116
117 public int getVersion() {
118 return version;
119 }
120} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/Mapping.java b/songdbj/de/jarnbjo/vorbis/Mapping.java
deleted file mode 100644
index 24a2eaa19a..0000000000
--- a/songdbj/de/jarnbjo/vorbis/Mapping.java
+++ /dev/null
@@ -1,59 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
25 * no message
26 *
27 *
28 */
29
30package de.jarnbjo.vorbis;
31
32import java.io.IOException;
33
34import de.jarnbjo.util.io.BitInputStream;
35
36abstract class Mapping {
37
38 protected static Mapping createInstance(VorbisStream vorbis, BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException {
39
40 int type=source.getInt(16);
41 switch(type) {
42 case 0:
43 //System.out.println("mapping type 0");
44 return new Mapping0(vorbis, source, header);
45 default:
46 throw new VorbisFormatException("Mapping type "+type+" is not supported.");
47 }
48 }
49
50 protected abstract int getType();
51 protected abstract int[] getAngles();
52 protected abstract int[] getMagnitudes() ;
53 protected abstract int[] getMux();
54 protected abstract int[] getSubmapFloors();
55 protected abstract int[] getSubmapResidues();
56 protected abstract int getCouplingSteps();
57 protected abstract int getSubmaps();
58
59} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/Mapping0.java b/songdbj/de/jarnbjo/vorbis/Mapping0.java
deleted file mode 100644
index e8fde4686f..0000000000
--- a/songdbj/de/jarnbjo/vorbis/Mapping0.java
+++ /dev/null
@@ -1,146 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
25 * no message
26 *
27 *
28 */
29
30package de.jarnbjo.vorbis;
31
32import java.io.IOException;
33
34import de.jarnbjo.util.io.BitInputStream;
35
36class Mapping0 extends Mapping {
37
38 private int[] magnitudes, angles, mux, submapFloors, submapResidues;
39
40 protected Mapping0(VorbisStream vorbis, BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException {
41
42 int submaps=1;
43
44 if(source.getBit()) {
45 submaps=source.getInt(4)+1;
46 }
47
48 //System.out.println("submaps: "+submaps);
49
50 int channels=vorbis.getIdentificationHeader().getChannels();
51 int ilogChannels=Util.ilog(channels-1);
52
53 //System.out.println("ilogChannels: "+ilogChannels);
54
55 if(source.getBit()) {
56 int couplingSteps=source.getInt(8)+1;
57 magnitudes=new int[couplingSteps];
58 angles=new int[couplingSteps];
59
60 for(int i=0; i<couplingSteps; i++) {
61 magnitudes[i]=source.getInt(ilogChannels);
62 angles[i]=source.getInt(ilogChannels);
63 if(magnitudes[i]==angles[i] || magnitudes[i]>=channels || angles[i]>=channels) {
64 System.err.println(magnitudes[i]);
65 System.err.println(angles[i]);
66 throw new VorbisFormatException("The channel magnitude and/or angle mismatch.");
67 }
68 }
69 }
70 else {
71 magnitudes=new int[0];
72 angles=new int[0];
73 }
74
75 if(source.getInt(2)!=0) {
76 throw new VorbisFormatException("A reserved mapping field has an invalid value.");
77 }
78
79 mux=new int[channels];
80 if(submaps>1) {
81 for(int i=0; i<channels; i++) {
82 mux[i]=source.getInt(4);
83 if(mux[i]>submaps) {
84 throw new VorbisFormatException("A mapping mux value is higher than the number of submaps");
85 }
86 }
87 }
88 else {
89 for(int i=0; i<channels; i++) {
90 mux[i]=0;
91 }
92 }
93
94 submapFloors=new int[submaps];
95 submapResidues=new int[submaps];
96
97 int floorCount=header.getFloors().length;
98 int residueCount=header.getResidues().length;
99
100 for(int i=0; i<submaps; i++) {
101 source.getInt(8); // discard time placeholder
102 submapFloors[i]=source.getInt(8);
103 submapResidues[i]=source.getInt(8);
104
105 if(submapFloors[i]>floorCount) {
106 throw new VorbisFormatException("A mapping floor value is higher than the number of floors.");
107 }
108
109 if(submapResidues[i]>residueCount) {
110 throw new VorbisFormatException("A mapping residue value is higher than the number of residues.");
111 }
112 }
113 }
114
115 protected int getType() {
116 return 0;
117 }
118
119 protected int[] getAngles() {
120 return angles;
121 }
122
123 protected int[] getMagnitudes() {
124 return magnitudes;
125 }
126
127 protected int[] getMux() {
128 return mux;
129 }
130
131 protected int[] getSubmapFloors() {
132 return submapFloors;
133 }
134
135 protected int[] getSubmapResidues() {
136 return submapResidues;
137 }
138
139 protected int getCouplingSteps() {
140 return angles.length;
141 }
142
143 protected int getSubmaps() {
144 return submapFloors.length;
145 }
146} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/MdctFloat.java b/songdbj/de/jarnbjo/vorbis/MdctFloat.java
deleted file mode 100644
index 4f354b259b..0000000000
--- a/songdbj/de/jarnbjo/vorbis/MdctFloat.java
+++ /dev/null
@@ -1,321 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.2 2004/09/21 12:09:45 shred
22 * *** empty log message ***
23 *
24 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
25 * First Import
26 *
27 * Revision 1.3 2003/04/10 19:49:04 jarnbjo
28 * no message
29 *
30 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
31 * no message
32 *
33 *
34 */
35
36package de.jarnbjo.vorbis;
37
38class MdctFloat {
39 static private final float cPI3_8=0.38268343236508977175f;
40 static private final float cPI2_8=0.70710678118654752441f;
41 static private final float cPI1_8=0.92387953251128675613f;
42
43 private int n;
44 private int log2n;
45
46 private float[] trig;
47 private int[] bitrev;
48
49 private float[] equalizer;
50
51 private float scale;
52
53 private int itmp1, itmp2, itmp3, itmp4, itmp5, itmp6, itmp7, itmp8, itmp9;
54 private float dtmp1, dtmp2, dtmp3, dtmp4, dtmp5, dtmp6, dtmp7, dtmp8, dtmp9;
55
56 protected MdctFloat(int n) {
57 bitrev=new int[n/4];
58 trig=new float[n+n/4];
59
60 int n2=n>>>1;
61 log2n=(int)Math.rint(Math.log(n)/Math.log(2));
62 this.n=n;
63
64 int AE=0;
65 int AO=1;
66 int BE=AE+n/2;
67 int BO=BE+1;
68 int CE=BE+n/2;
69 int CO=CE+1;
70 // trig lookups...
71 for(int i=0;i<n/4;i++){
72 trig[AE+i*2]=(float)Math.cos((Math.PI/n)*(4*i));
73 trig[AO+i*2]=(float)-Math.sin((Math.PI/n)*(4*i));
74 trig[BE+i*2]=(float)Math.cos((Math.PI/(2*n))*(2*i+1));
75 trig[BO+i*2]=(float)Math.sin((Math.PI/(2*n))*(2*i+1));
76 }
77 for(int i=0;i<n/8;i++){
78 trig[CE+i*2]=(float)Math.cos((Math.PI/n)*(4*i+2));
79 trig[CO+i*2]=(float)-Math.sin((Math.PI/n)*(4*i+2));
80 }
81
82 {
83 int mask=(1<<(log2n-1))-1;
84 int msb=1<<(log2n-2);
85 for(int i=0;i<n/8;i++){
86 int acc=0;
87 for(int j=0;msb>>>j!=0;j++)
88 if(((msb>>>j)&i)!=0)acc|=1<<j;
89 bitrev[i*2]=((~acc)&mask);
90// bitrev[i*2]=((~acc)&mask)-1;
91 bitrev[i*2+1]=acc;
92 }
93 }
94 scale=4.f/n;
95 }
96
97 //void clear(){
98 //}
99
100 //void forward(float[] in, float[] out){
101 //}
102
103 private float[] _x=new float[1024];
104 private float[] _w=new float[1024];
105
106 protected void setEqualizer(float[] equalizer) {
107 this.equalizer=equalizer;
108 }
109
110 protected float[] getEqualizer() {
111 return equalizer;
112 }
113
114 protected synchronized void imdct(final float[] frq, final float[] window, final int[] pcm) {//, float[] out){
115
116 float[] in=frq;//, out=buf;
117 if(_x.length<n/2){_x=new float[n/2];}
118 if(_w.length<n/2){_w=new float[n/2];}
119 final float[] x=_x;
120 final float[] w=_w;
121 int n2=n>>1;
122 int n4=n>>2;
123 int n8=n>>3;
124
125 if(equalizer!=null) {
126 for(int i=0; i<n; i++) {
127 frq[i]*=equalizer[i];
128 }
129 }
130
131 // rotate + step 1
132 {
133 int inO=-1;
134 int xO=0;
135 int A=n2;
136
137 int i;
138 for(i=0;i<n8;i++) {
139 dtmp1=in[inO+=2];
140 dtmp2=in[inO+=2];
141 dtmp3=trig[--A];
142 dtmp4=trig[--A];
143 x[xO++]=-dtmp2*dtmp3 - dtmp1*dtmp4;
144 x[xO++]= dtmp1*dtmp3 - dtmp2*dtmp4;
145 //A-=2;
146 //x[xO++]=-in[inO+2]*trig[A+1] - in[inO]*trig[A];
147 //x[xO++]= in[inO]*trig[A+1] - in[inO+2]*trig[A];
148 //inO+=4;
149 }
150
151 inO=n2;//-4;
152
153 for(i=0;i<n8;i++) {
154 dtmp1=in[inO-=2];
155 dtmp2=in[inO-=2];
156 dtmp3=trig[--A];
157 dtmp4=trig[--A];
158 x[xO++]=dtmp2*dtmp3 + dtmp1*dtmp4;
159 x[xO++]=dtmp2*dtmp4 - dtmp1*dtmp3;
160 //A-=2;
161 //x[xO++]=in[inO]*trig[A+1] + in[inO+2]*trig[A];
162 //x[xO++]=in[inO]*trig[A] - in[inO+2]*trig[A+1];
163 //inO-=4;
164 }
165 }
166
167 float[] xxx=kernel(x,w,n,n2,n4,n8);
168 int xx=0;
169
170 // step 8
171
172 {
173 int B=n2;
174 int o1=n4,o2=o1-1;
175 int o3=n4+n2,o4=o3-1;
176
177 for(int i=0;i<n4;i++){
178 dtmp1=xxx[xx++];
179 dtmp2=xxx[xx++];
180 dtmp3=trig[B++];
181 dtmp4=trig[B++];
182
183 float temp1= (dtmp1* dtmp4 - dtmp2 * dtmp3);
184 float temp2=-(dtmp1 * dtmp3 + dtmp2 * dtmp4);
185
186 /*
187 float temp1= (xxx[xx] * trig[B+1] - xxx[xx+1] * trig[B]);//*32767.0f;
188 float temp2=-(xxx[xx] * trig[B] + xxx[xx+1] * trig[B+1]);//*32767.0f;
189 */
190
191 //if(temp1>32767.0f) temp1=32767.0f;
192 //if(temp1<-32768.0f) temp1=-32768.0f;
193 //if(temp2>32767.0f) temp2=32767.0f;
194 //if(temp2<-32768.0f) temp2=-32768.0f;
195
196 pcm[o1]=(int)(-temp1*window[o1]);
197 pcm[o2]=(int)( temp1*window[o2]);
198 pcm[o3]=(int)( temp2*window[o3]);
199 pcm[o4]=(int)( temp2*window[o4]);
200
201 o1++;
202 o2--;
203 o3++;
204 o4--;
205 //xx+=2;
206 //B+=2;
207 }
208 }
209 }
210
211 private float[] kernel(float[] x, float[] w,
212 int n, int n2, int n4, int n8){
213 // step 2
214
215 int xA=n4;
216 int xB=0;
217 int w2=n4;
218 int A=n2;
219
220 for(int i=0;i<n4;){
221 float x0=x[xA] - x[xB];
222 float x1;
223 w[w2+i]=x[xA++]+x[xB++];
224
225 x1=x[xA]-x[xB];
226 A-=4;
227
228 w[i++]= x0 * trig[A] + x1 * trig[A+1];
229 w[i]= x1 * trig[A] - x0 * trig[A+1];
230
231 w[w2+i]=x[xA++]+x[xB++];
232 i++;
233 }
234
235 // step 3
236
237 {
238 for(int i=0;i<log2n-3;i++){
239 int k0=n>>>(i+2);
240 int k1=1<<(i+3);
241 int wbase=n2-2;
242
243 A=0;
244 float[] temp;
245
246 for(int r=0;r<(k0>>>2);r++){
247 int w1=wbase;
248 w2=w1-(k0>>1);
249 float AEv= trig[A],wA;
250 float AOv= trig[A+1],wB;
251 wbase-=2;
252
253 k0++;
254 for(int s=0;s<(2<<i);s++){
255 dtmp1=w[w1];
256 dtmp2=w[w2];
257 wB=dtmp1-dtmp2;
258 x[w1]=dtmp1+dtmp2;
259 dtmp1=w[++w1];
260 dtmp2=w[++w2];
261 wA=dtmp1-dtmp2;
262 x[w1]=dtmp1+dtmp2;
263 x[w2] =wA*AEv - wB*AOv;
264 x[w2-1]=wB*AEv + wA*AOv;
265
266 /*
267 wB =w[w1] -w[w2];
268 x[w1] =w[w1] +w[w2];
269
270 wA =w[++w1] -w[++w2];
271 x[w1] =w[w1] +w[w2];
272
273 x[w2] =wA*AEv - wB*AOv;
274 x[w2-1]=wB*AEv + wA*AOv;
275 */
276
277 w1-=k0;
278 w2-=k0;
279 }
280 k0--;
281 A+=k1;
282 }
283
284 temp=w;
285 w=x;
286 x=temp;
287 }
288 }
289
290 // step 4, 5, 6, 7
291 {
292 int C=n;
293 int bit=0;
294 int x1=0;
295 int x2=n2-1;
296
297 for(int i=0;i<n8;i++) {
298 int t1=bitrev[bit++];
299 int t2=bitrev[bit++];
300
301 float wA=w[t1]-w[t2+1];
302 float wB=w[t1-1]+w[t2];
303 float wC=w[t1]+w[t2+1];
304 float wD=w[t1-1]-w[t2];
305
306 float wACE=wA* trig[C];
307 float wBCE=wB* trig[C++];
308 float wACO=wA* trig[C];
309 float wBCO=wB* trig[C++];
310
311 x[x1++]=( wC+wACO+wBCE)*16383.0f;
312 x[x2--]=(-wD+wBCO-wACE)*16383.0f;
313 x[x1++]=( wD+wBCO-wACE)*16383.0f;
314 x[x2--]=( wC-wACO-wBCE)*16383.0f;
315 }
316 }
317 return x;
318 }
319
320}
321
diff --git a/songdbj/de/jarnbjo/vorbis/Mode.java b/songdbj/de/jarnbjo/vorbis/Mode.java
deleted file mode 100644
index ab88944a25..0000000000
--- a/songdbj/de/jarnbjo/vorbis/Mode.java
+++ /dev/null
@@ -1,75 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
25 * no message
26 *
27 *
28 */
29
30package de.jarnbjo.vorbis;
31
32import java.io.*;
33
34import de.jarnbjo.util.io.*;
35
36class Mode {
37
38 private boolean blockFlag;
39 private int windowType, transformType, mapping;
40
41 protected Mode(BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException {
42 blockFlag=source.getBit();
43 windowType=source.getInt(16);
44 transformType=source.getInt(16);
45 mapping=source.getInt(8);
46
47 if(windowType!=0) {
48 throw new VorbisFormatException("Window type = "+windowType+", != 0");
49 }
50
51 if(transformType!=0) {
52 throw new VorbisFormatException("Transform type = "+transformType+", != 0");
53 }
54
55 if(mapping>header.getMappings().length) {
56 throw new VorbisFormatException("Mode mapping number is higher than total number of mappings.");
57 }
58 }
59
60 protected boolean getBlockFlag() {
61 return blockFlag;
62 }
63
64 protected int getWindowType() {
65 return windowType;
66 }
67
68 protected int getTransformType() {
69 return transformType;
70 }
71
72 protected int getMapping() {
73 return mapping;
74 }
75} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/Residue.java b/songdbj/de/jarnbjo/vorbis/Residue.java
deleted file mode 100644
index 78c28fa5ed..0000000000
--- a/songdbj/de/jarnbjo/vorbis/Residue.java
+++ /dev/null
@@ -1,260 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.3 2003/04/04 08:33:02 jarnbjo
25 * no message
26 *
27 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
28 * no message
29 *
30 *
31 */
32
33package de.jarnbjo.vorbis;
34
35import java.io.IOException;
36import java.util.HashMap;
37
38import de.jarnbjo.util.io.*;
39
40
41abstract class Residue {
42
43 protected int begin, end;
44 protected int partitionSize; // grouping
45 protected int classifications; // partitions
46 protected int classBook; // groupbook
47 protected int[] cascade; // secondstages
48 protected int[][] books;
49 protected HashMap looks=new HashMap();
50
51 protected Residue() {
52 }
53
54 protected Residue(BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException {
55 begin=source.getInt(24);
56 end=source.getInt(24);
57 partitionSize=source.getInt(24)+1;
58 classifications=source.getInt(6)+1;
59 classBook=source.getInt(8);
60
61 cascade=new int[classifications];
62
63 int acc=0;
64
65 for(int i=0; i<classifications; i++) {
66 int highBits=0, lowBits=0;
67 lowBits=source.getInt(3);
68 if(source.getBit()) {
69 highBits=source.getInt(5);
70 }
71 cascade[i]=(highBits<<3)|lowBits;
72 acc+=Util.icount(cascade[i]);
73 }
74
75 books=new int[classifications][8];
76
77 for(int i=0; i<classifications; i++) {
78 for(int j=0; j<8; j++) {
79 if((cascade[i]&(1<<j))!=0) {
80 books[i][j]=source.getInt(8);
81 if(books[i][j]>header.getCodeBooks().length) {
82 throw new VorbisFormatException("Reference to invalid codebook entry in residue header.");
83 }
84 }
85 }
86 }
87 }
88
89
90 protected static Residue createInstance(BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException {
91
92 int type=source.getInt(16);
93 switch(type) {
94 case 0:
95 //System.out.println("residue type 0");
96 return new Residue0(source, header);
97 case 1:
98 //System.out.println("residue type 1");
99 return new Residue2(source, header);
100 case 2:
101 //System.out.println("residue type 2");
102 return new Residue2(source, header);
103 default:
104 throw new VorbisFormatException("Residue type "+type+" is not supported.");
105 }
106 }
107
108 protected abstract int getType();
109 protected abstract void decodeResidue(VorbisStream vorbis, BitInputStream source, Mode mode, int ch, boolean[] doNotDecodeFlags, float[][] vectors) throws VorbisFormatException, IOException;
110 //public abstract double[][] getDecodedVectors();
111
112 protected int getBegin() {
113 return begin;
114 }
115
116 protected int getEnd() {
117 return end;
118 }
119
120 protected int getPartitionSize() {
121 return partitionSize;
122 }
123
124 protected int getClassifications() {
125 return classifications;
126 }
127
128 protected int getClassBook() {
129 return classBook;
130 }
131
132 protected int[] getCascade() {
133 return cascade;
134 }
135
136 protected int[][] getBooks() {
137 return books;
138 }
139
140 protected final void fill(Residue clone) {
141 clone.begin=begin;
142 clone.books=books;
143 clone.cascade=cascade;
144 clone.classBook=classBook;
145 clone.classifications=classifications;
146 clone.end=end;
147 clone.partitionSize=partitionSize;
148 }
149
150 protected Look getLook(VorbisStream source, Mode key) {
151 //return new Look(source, key);
152 Look look=(Look)looks.get(key);
153 if(look==null) {
154 look=new Look(source, key);
155 looks.put(key, look);
156 }
157 return look;
158 }
159
160
161 class Look {
162 int map;
163 int parts;
164 int stages;
165 CodeBook[] fullbooks;
166 CodeBook phrasebook;
167 int[][] partbooks;
168 int partvals;
169 int[][] decodemap;
170 int postbits;
171 int phrasebits;
172 int frames;
173
174 protected Look (VorbisStream source, Mode mode) {
175 int dim=0, acc=0, maxstage=0;
176
177 map=mode.getMapping();
178 parts=Residue.this.getClassifications();
179 fullbooks=source.getSetupHeader().getCodeBooks();
180 phrasebook=fullbooks[Residue.this.getClassBook()];
181 dim=phrasebook.getDimensions();
182
183 partbooks=new int[parts][];
184
185 for(int j=0;j<parts;j++) {
186 int stages=Util.ilog(Residue.this.getCascade()[j]);
187 if(stages!=0) {
188 if(stages>maxstage) {
189 maxstage=stages;
190 }
191 partbooks[j]=new int[stages];
192 for(int k=0; k<stages; k++){
193 if((Residue.this.getCascade()[j]&(1<<k))!=0){
194 partbooks[j][k]=Residue.this.getBooks()[j][k];
195 }
196 }
197 }
198 }
199
200 partvals=(int)Math.rint(Math.pow(parts, dim));
201 stages=maxstage;
202
203 decodemap=new int[partvals][];
204
205 for(int j=0;j<partvals;j++){
206 int val=j;
207 int mult=partvals/parts;
208 decodemap[j]=new int[dim];
209
210 for(int k=0;k<dim;k++){
211 int deco=val/mult;
212 val-=deco*mult;
213 mult/=parts;
214 decodemap[j][k]=deco;
215 }
216 }
217 }
218
219 protected int[][] getDecodeMap() {
220 return decodemap;
221 }
222
223 protected int getFrames() {
224 return frames;
225 }
226
227 protected int getMap() {
228 return map;
229 }
230
231 protected int[][] getPartBooks() {
232 return partbooks;
233 }
234
235 protected int getParts() {
236 return parts;
237 }
238
239 protected int getPartVals() {
240 return partvals;
241 }
242
243 protected int getPhraseBits() {
244 return phrasebits;
245 }
246
247 protected CodeBook getPhraseBook() {
248 return phrasebook;
249 }
250
251 protected int getPostBits() {
252 return postbits;
253 }
254
255 protected int getStages() {
256 return stages;
257 }
258 }
259
260} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/Residue0.java b/songdbj/de/jarnbjo/vorbis/Residue0.java
deleted file mode 100644
index 7dc0dfa765..0000000000
--- a/songdbj/de/jarnbjo/vorbis/Residue0.java
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.2 2004/09/21 06:39:06 shred
22 * Importe reorganisiert, damit Eclipse Ruhe gibt. ;-)
23 *
24 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
25 * First Import
26 *
27 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
28 * no message
29 *
30 *
31 */
32
33package de.jarnbjo.vorbis;
34
35import java.io.IOException;
36
37import de.jarnbjo.util.io.BitInputStream;
38
39class Residue0 extends Residue {
40
41 protected Residue0(BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException {
42 super(source, header);
43 }
44
45 protected int getType() {
46 return 0;
47 }
48
49 protected void decodeResidue(VorbisStream vorbis, BitInputStream source, Mode mode, int ch, boolean[] doNotDecodeFlags, float[][] vectors) throws VorbisFormatException, IOException {
50 /** @todo implement */
51 throw new UnsupportedOperationException();
52 }
53} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/Residue1.java b/songdbj/de/jarnbjo/vorbis/Residue1.java
deleted file mode 100644
index f31147c072..0000000000
--- a/songdbj/de/jarnbjo/vorbis/Residue1.java
+++ /dev/null
@@ -1,55 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.2 2004/09/21 06:39:06 shred
22 * Importe reorganisiert, damit Eclipse Ruhe gibt. ;-)
23 *
24 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
25 * First Import
26 *
27 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
28 * no message
29 *
30 *
31 */
32
33package de.jarnbjo.vorbis;
34
35import java.io.IOException;
36
37import de.jarnbjo.util.io.BitInputStream;
38
39class Residue1 extends Residue {
40
41 protected Residue1(BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException {
42 super(source, header);
43 }
44
45 protected int getType() {
46 return 1;
47 }
48
49 protected void decodeResidue(VorbisStream vorbis, BitInputStream source, Mode mode, int ch, boolean[] doNotDecodeFlags, float[][] vectors) throws VorbisFormatException, IOException {
50 /** @todo implement */
51 throw new UnsupportedOperationException();
52 }
53
54
55} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/Residue2.java b/songdbj/de/jarnbjo/vorbis/Residue2.java
deleted file mode 100644
index 666d2cd017..0000000000
--- a/songdbj/de/jarnbjo/vorbis/Residue2.java
+++ /dev/null
@@ -1,123 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.2 2004/09/21 06:39:06 shred
22 * Importe reorganisiert, damit Eclipse Ruhe gibt. ;-)
23 *
24 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
25 * First Import
26 *
27 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
28 * no message
29 *
30 *
31 */
32
33package de.jarnbjo.vorbis;
34
35import java.io.IOException;
36
37import de.jarnbjo.util.io.BitInputStream;
38
39class Residue2 extends Residue {
40
41 private double[][] decodedVectors;
42
43 private Residue2() {
44 }
45
46 protected Residue2(BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException {
47 super(source, header);
48 }
49
50 protected int getType() {
51 return 2;
52 }
53
54 protected void decodeResidue(VorbisStream vorbis, BitInputStream source, Mode mode, int ch, boolean[] doNotDecodeFlags, float[][] vectors) throws VorbisFormatException, IOException {
55
56 Look look=getLook(vorbis, mode);
57
58 CodeBook codeBook=vorbis.getSetupHeader().getCodeBooks()[getClassBook()];
59
60 int classvalsPerCodeword=codeBook.getDimensions();
61 int nToRead=getEnd()-getBegin();
62 int partitionsToRead=nToRead/getPartitionSize(); // partvals
63
64 int samplesPerPartition=getPartitionSize();
65 int partitionsPerWord=look.getPhraseBook().getDimensions();
66
67 int partWords=(partitionsToRead+partitionsPerWord-1)/partitionsPerWord;
68
69 int realCh=0;
70 for(int i=0; i<doNotDecodeFlags.length; i++) {
71 if(!doNotDecodeFlags[i]) {
72 realCh++;
73 }
74 }
75
76 float[][] realVectors=new float[realCh][];
77
78 realCh=0;
79 for(int i=0; i<doNotDecodeFlags.length; i++) {
80 if(!doNotDecodeFlags[i]) {
81 realVectors[realCh++]=vectors[i];
82 }
83 }
84
85 int[][] partword=new int[partWords][];
86 for(int s=0;s<look.getStages();s++){
87 for(int i=0,l=0;i<partitionsToRead;l++){
88 if(s==0){
89 //int temp=look.getPhraseBook().readInt(source);
90 int temp=source.getInt(look.getPhraseBook().getHuffmanRoot());
91 if(temp==-1){
92 throw new VorbisFormatException("");
93 }
94 partword[l]=look.getDecodeMap()[temp];
95 if(partword[l]==null){
96 throw new VorbisFormatException("");
97 }
98 }
99
100 for(int k=0;k<partitionsPerWord && i<partitionsToRead;k++,i++){
101 int offset=begin+i*samplesPerPartition;
102 if((cascade[partword[l][k]]&(1<<s))!=0){
103 CodeBook stagebook=vorbis.getSetupHeader().getCodeBooks()[look.getPartBooks()[partword[l][k]][s]];
104 if(stagebook!=null){
105 stagebook.readVvAdd(realVectors, source, offset, samplesPerPartition);
106 }
107 }
108 }
109 }
110 }
111 }
112
113
114 public Object clone() {
115 Residue2 clone=new Residue2();
116 fill(clone);
117 return clone;
118 }
119
120 protected double[][] getDecodedVectors() {
121 return decodedVectors;
122 }
123} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/SetupHeader.java b/songdbj/de/jarnbjo/vorbis/SetupHeader.java
deleted file mode 100644
index 56e400f348..0000000000
--- a/songdbj/de/jarnbjo/vorbis/SetupHeader.java
+++ /dev/null
@@ -1,131 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
25 * no message
26 *
27 *
28 */
29
30package de.jarnbjo.vorbis;
31
32import java.io.*;
33
34import de.jarnbjo.util.io.*;
35
36class SetupHeader {
37
38 private static final long HEADER = 0x736962726f76L; // 'vorbis'
39
40 private CodeBook[] codeBooks;
41 private Floor[] floors;
42 private Residue[] residues;
43 private Mapping[] mappings;
44 private Mode[] modes;
45
46 public SetupHeader(VorbisStream vorbis, BitInputStream source) throws VorbisFormatException, IOException {
47
48 if(source.getLong(48)!=HEADER) {
49 throw new VorbisFormatException("The setup header has an illegal leading.");
50 }
51
52 // read code books
53
54 int codeBookCount=source.getInt(8)+1;
55 codeBooks=new CodeBook[codeBookCount];
56
57 for(int i=0; i<codeBooks.length; i++) {
58 codeBooks[i]=new CodeBook(source);
59 }
60
61 // read the time domain transformations,
62 // these should all be 0
63
64 int timeCount=source.getInt(6)+1;
65 for(int i=0; i<timeCount; i++) {
66 if(source.getInt(16)!=0) {
67 throw new VorbisFormatException("Time domain transformation != 0");
68 }
69 }
70
71 // read floor entries
72
73 int floorCount=source.getInt(6)+1;
74 floors=new Floor[floorCount];
75
76 for(int i=0; i<floorCount; i++) {
77 floors[i]=Floor.createInstance(source, this);
78 }
79
80 // read residue entries
81
82 int residueCount=source.getInt(6)+1;
83 residues=new Residue[residueCount];
84
85 for(int i=0; i<residueCount; i++) {
86 residues[i]=Residue.createInstance(source, this);
87 }
88
89 // read mapping entries
90
91 int mappingCount=source.getInt(6)+1;
92 mappings=new Mapping[mappingCount];
93
94 for(int i=0; i<mappingCount; i++) {
95 mappings[i]=Mapping.createInstance(vorbis, source, this);
96 }
97
98 // read mode entries
99
100 int modeCount=source.getInt(6)+1;
101 modes=new Mode[modeCount];
102
103 for(int i=0; i<modeCount; i++) {
104 modes[i]=new Mode(source, this);
105 }
106
107 if(!source.getBit()) {
108 throw new VorbisFormatException("The setup header framing bit is incorrect.");
109 }
110 }
111
112 public CodeBook[] getCodeBooks() {
113 return codeBooks;
114 }
115
116 public Floor[] getFloors() {
117 return floors;
118 }
119
120 public Residue[] getResidues() {
121 return residues;
122 }
123
124 public Mapping[] getMappings() {
125 return mappings;
126 }
127
128 public Mode[] getModes() {
129 return modes;
130 }
131} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/Util.java b/songdbj/de/jarnbjo/vorbis/Util.java
deleted file mode 100644
index 7e31c9495e..0000000000
--- a/songdbj/de/jarnbjo/vorbis/Util.java
+++ /dev/null
@@ -1,127 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.3 2003/04/10 19:49:04 jarnbjo
25 * no message
26 *
27 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
28 * no message
29 *
30 *
31 */
32
33package de.jarnbjo.vorbis;
34
35final public class Util {
36
37 public static final int ilog(int x) {
38 int res=0;
39 for(; x>0; x>>=1, res++);
40 return res;
41 }
42
43 public static final float float32unpack(int x) {
44 float mantissa=x&0x1fffff;
45 float e=(x&0x7fe00000)>>21;
46 if((x&0x80000000)!=0) {
47 mantissa=-mantissa;
48 }
49 return mantissa*(float)Math.pow(2.0, e-788.0);
50 }
51
52 public static final int lookup1Values(int a, int b) {
53 int res=(int)Math.pow(Math.E, Math.log(a)/b);
54 return intPow(res+1, b)<=a?res+1:res;
55 }
56
57 public static final int intPow(int base, int e) {
58 int res=1;
59 for(; e>0; e--, res*=base);
60 return res;
61 }
62
63 public static final boolean isBitSet(int value, int bit) {
64 return (value&(1<<bit))!=0;
65 }
66
67 public static final int icount(int value) {
68 int res=0;
69 while(value>0) {
70 res+=value&1;
71 value>>=1;
72 }
73 return res;
74 }
75
76 public static final int lowNeighbour(int[] v, int x) {
77 int max=-1, n=0;
78 for(int i=0; i<v.length && i<x; i++) {
79 if(v[i]>max && v[i]<v[x]) {
80 max=v[i];
81 n=i;
82 }
83 }
84 return n;
85 }
86
87 public static final int highNeighbour(int[] v, int x) {
88 int min=Integer.MAX_VALUE, n=0;
89 for(int i=0; i<v.length && i<x; i++) {
90 if(v[i]<min && v[i]>v[x]) {
91 min=v[i];
92 n=i;
93 }
94 }
95 return n;
96 }
97
98 public static final int renderPoint(int x0, int x1, int y0, int y1, int x) {
99 int dy=y1-y0;
100 int ady=dy<0?-dy:dy;
101 int off=(ady*(x-x0))/(x1-x0);
102 return dy<0?y0-off:y0+off;
103 }
104
105 public static final void renderLine(final int x0, final int y0, final int x1, final int y1, final float[] v) {
106 final int dy=y1-y0;
107 final int adx=x1-x0;
108 final int base=dy/adx;
109 final int sy=dy<0?base-1:base+1;
110 int x=x0;
111 int y=y0;
112 int err=0;
113 final int ady=(dy<0?-dy:dy)-(base>0?base*adx:-base*adx);
114
115 v[x]*=Floor.DB_STATIC_TABLE[y];
116 for(x=x0+1; x<x1; x++) {
117 err+=ady;
118 if(err>=adx) {
119 err-=adx;
120 v[x]*=Floor.DB_STATIC_TABLE[y+=sy];
121 }
122 else {
123 v[x]*=Floor.DB_STATIC_TABLE[y+=base];
124 }
125 }
126 }
127} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/VorbisAudioFileReader.java b/songdbj/de/jarnbjo/vorbis/VorbisAudioFileReader.java
deleted file mode 100644
index b1bc999947..0000000000
--- a/songdbj/de/jarnbjo/vorbis/VorbisAudioFileReader.java
+++ /dev/null
@@ -1,217 +0,0 @@
1package de.jarnbjo.vorbis;
2
3/*
4 * $ProjectName$
5 * $ProjectRevision$
6 * -----------------------------------------------------------
7 * $Id$
8 * -----------------------------------------------------------
9 *
10 * $Author$
11 *
12 * Description:
13 *
14 * Copyright 2002-2003 Tor-Einar Jarnbjo
15 * -----------------------------------------------------------
16 *
17 * Change History
18 * -----------------------------------------------------------
19 * $Log$
20 * Revision 1.1 2005/07/11 15:42:36 hcl
21 * Songdb java version, source. only 1.5 compatible
22 *
23 * Revision 1.2 2004/09/21 06:39:06 shred
24 * Importe reorganisiert, damit Eclipse Ruhe gibt. ;-)
25 *
26 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
27 * First Import
28 *
29 *
30 */
31
32import java.io.File;
33import java.io.IOException;
34import java.io.InputStream;
35import java.io.RandomAccessFile;
36import java.net.URL;
37import java.util.Collection;
38
39import javax.sound.sampled.AudioFileFormat;
40import javax.sound.sampled.AudioFormat;
41import javax.sound.sampled.AudioInputStream;
42import javax.sound.sampled.AudioSystem;
43import javax.sound.sampled.UnsupportedAudioFileException;
44import javax.sound.sampled.spi.AudioFileReader;
45
46import de.jarnbjo.ogg.BasicStream;
47import de.jarnbjo.ogg.EndOfOggStreamException;
48import de.jarnbjo.ogg.FileStream;
49import de.jarnbjo.ogg.LogicalOggStream;
50import de.jarnbjo.ogg.OggFormatException;
51import de.jarnbjo.ogg.PhysicalOggStream;
52import de.jarnbjo.ogg.UncachedUrlStream;
53
54public class VorbisAudioFileReader extends AudioFileReader {
55
56 public VorbisAudioFileReader() {
57 }
58
59 public AudioFileFormat getAudioFileFormat(File file) throws IOException, UnsupportedAudioFileException {
60 try {
61 return getAudioFileFormat(new FileStream(new RandomAccessFile(file, "r")));
62 }
63 catch(OggFormatException e) {
64 throw new UnsupportedAudioFileException(e.getMessage());
65 }
66 }
67
68 public AudioFileFormat getAudioFileFormat(InputStream stream) throws IOException, UnsupportedAudioFileException {
69 try {
70 return getAudioFileFormat(new BasicStream(stream));
71 }
72 catch(OggFormatException e) {
73 throw new UnsupportedAudioFileException(e.getMessage());
74 }
75 }
76
77 public AudioFileFormat getAudioFileFormat(URL url) throws IOException, UnsupportedAudioFileException {
78 try {
79 return getAudioFileFormat(new UncachedUrlStream(url));
80 }
81 catch(OggFormatException e) {
82 throw new UnsupportedAudioFileException(e.getMessage());
83 }
84 }
85
86 private AudioFileFormat getAudioFileFormat(PhysicalOggStream oggStream) throws IOException, UnsupportedAudioFileException {
87 try {
88 Collection streams=oggStream.getLogicalStreams();
89 if(streams.size()!=1) {
90 throw new UnsupportedAudioFileException("Only Ogg files with one logical Vorbis stream are supported.");
91 }
92
93 LogicalOggStream los=(LogicalOggStream)streams.iterator().next();
94 if(los.getFormat()!=LogicalOggStream.FORMAT_VORBIS) {
95 throw new UnsupportedAudioFileException("Only Ogg files with one logical Vorbis stream are supported.");
96 }
97
98 VorbisStream vs=new VorbisStream(los);
99
100 AudioFormat audioFormat=new AudioFormat(
101 (float)vs.getIdentificationHeader().getSampleRate(),
102 16,
103 vs.getIdentificationHeader().getChannels(),
104 true, true);
105
106 return new AudioFileFormat(VorbisFormatType.getInstance(), audioFormat, AudioSystem.NOT_SPECIFIED);
107 }
108 catch(OggFormatException e) {
109 throw new UnsupportedAudioFileException(e.getMessage());
110 }
111 catch(VorbisFormatException e) {
112 throw new UnsupportedAudioFileException(e.getMessage());
113 }
114 }
115
116
117
118 public AudioInputStream getAudioInputStream(File file) throws IOException, UnsupportedAudioFileException {
119 try {
120 return getAudioInputStream(new FileStream(new RandomAccessFile(file, "r")));
121 }
122 catch(OggFormatException e) {
123 throw new UnsupportedAudioFileException(e.getMessage());
124 }
125 }
126
127 public AudioInputStream getAudioInputStream(InputStream stream) throws IOException, UnsupportedAudioFileException {
128 try {
129 return getAudioInputStream(new BasicStream(stream));
130 }
131 catch(OggFormatException e) {
132 throw new UnsupportedAudioFileException(e.getMessage());
133 }
134 }
135
136 public AudioInputStream getAudioInputStream(URL url) throws IOException, UnsupportedAudioFileException {
137 try {
138 return getAudioInputStream(new UncachedUrlStream(url));
139 }
140 catch(OggFormatException e) {
141 throw new UnsupportedAudioFileException(e.getMessage());
142 }
143 }
144
145 private AudioInputStream getAudioInputStream(PhysicalOggStream oggStream) throws IOException, UnsupportedAudioFileException {
146 try {
147 Collection streams=oggStream.getLogicalStreams();
148 if(streams.size()!=1) {
149 throw new UnsupportedAudioFileException("Only Ogg files with one logical Vorbis stream are supported.");
150 }
151
152 LogicalOggStream los=(LogicalOggStream)streams.iterator().next();
153 if(los.getFormat()!=LogicalOggStream.FORMAT_VORBIS) {
154 throw new UnsupportedAudioFileException("Only Ogg files with one logical Vorbis stream are supported.");
155 }
156
157 VorbisStream vs=new VorbisStream(los);
158
159 AudioFormat audioFormat=new AudioFormat(
160 (float)vs.getIdentificationHeader().getSampleRate(),
161 16,
162 vs.getIdentificationHeader().getChannels(),
163 true, true);
164
165 return new AudioInputStream(new VorbisInputStream(vs), audioFormat, -1);
166 }
167 catch(OggFormatException e) {
168 throw new UnsupportedAudioFileException(e.getMessage());
169 }
170 catch(VorbisFormatException e) {
171 throw new UnsupportedAudioFileException(e.getMessage());
172 }
173 }
174
175
176 public static class VorbisFormatType extends AudioFileFormat.Type {
177
178 private static final VorbisFormatType instance=new VorbisFormatType();
179
180 private VorbisFormatType() {
181 super("VORBIS", "ogg");
182 }
183
184 public static AudioFileFormat.Type getInstance() {
185 return instance;
186 }
187 }
188
189 public static class VorbisInputStream extends InputStream {
190
191 private VorbisStream source;
192 private byte[] buffer=new byte[8192];
193
194 public VorbisInputStream(VorbisStream source) {
195 this.source=source;
196 }
197
198 public int read() throws IOException {
199 return 0;
200 }
201
202 public int read(byte[] buffer) throws IOException {
203 return read(buffer, 0, buffer.length);
204 }
205
206 public int read(byte[] buffer, int offset, int length) throws IOException {
207 try {
208 return source.readPcm(buffer, offset, length);
209 }
210 catch(EndOfOggStreamException e) {
211 return -1;
212 }
213 }
214 }
215
216
217} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/VorbisFormatException.java b/songdbj/de/jarnbjo/vorbis/VorbisFormatException.java
deleted file mode 100644
index 5214298378..0000000000
--- a/songdbj/de/jarnbjo/vorbis/VorbisFormatException.java
+++ /dev/null
@@ -1,51 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.2 2005/02/09 23:10:47 shred
22 * Serial UID für jarnbjo
23 *
24 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
25 * First Import
26 *
27 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
28 * no message
29 *
30 *
31 */
32
33package de.jarnbjo.vorbis;
34
35import java.io.IOException;
36
37/**
38 * Exception thrown when trying to read a corrupted Vorbis stream.
39 */
40
41public class VorbisFormatException extends IOException {
42 private static final long serialVersionUID = 3616453405694834743L;
43
44 public VorbisFormatException() {
45 super();
46 }
47
48 public VorbisFormatException(String message) {
49 super(message);
50 }
51} \ No newline at end of file
diff --git a/songdbj/de/jarnbjo/vorbis/VorbisStream.java b/songdbj/de/jarnbjo/vorbis/VorbisStream.java
deleted file mode 100644
index 36659c7106..0000000000
--- a/songdbj/de/jarnbjo/vorbis/VorbisStream.java
+++ /dev/null
@@ -1,247 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.4 2003/04/10 19:49:04 jarnbjo
25 * no message
26 *
27 * Revision 1.3 2003/03/31 00:20:16 jarnbjo
28 * no message
29 *
30 * Revision 1.2 2003/03/16 01:11:12 jarnbjo
31 * no message
32 *
33 *
34 */
35
36package de.jarnbjo.vorbis;
37
38import java.io.*;
39import java.util.*;
40
41import de.jarnbjo.ogg.*;
42import de.jarnbjo.util.io.*;
43
44/**
45 */
46
47public class VorbisStream {
48
49 private LogicalOggStream oggStream;
50 private IdentificationHeader identificationHeader;
51 private CommentHeader commentHeader;
52 private SetupHeader setupHeader;
53
54 private AudioPacket lastAudioPacket, nextAudioPacket;
55 private LinkedList audioPackets=new LinkedList();
56 private byte[] currentPcm;
57 private int currentPcmIndex;
58 private int currentPcmLimit;
59
60 private static final int IDENTIFICATION_HEADER = 1;
61 private static final int COMMENT_HEADER = 3;
62 private static final int SETUP_HEADER = 5;
63
64 private int bitIndex=0;
65 private byte lastByte=(byte)0;
66 private boolean initialized=false;
67
68 private Object streamLock=new Object();
69 private int pageCounter=0;
70
71 private int currentBitRate=0;
72
73 private long currentGranulePosition;
74
75 public static final int BIG_ENDIAN = 0;
76 public static final int LITTLE_ENDIAN = 1;
77
78 public VorbisStream() {
79 }
80
81 public VorbisStream(LogicalOggStream oggStream) throws VorbisFormatException, IOException {
82 this.oggStream=oggStream;
83
84 for(int i=0; i<3; i++) {
85 BitInputStream source=new ByteArrayBitInputStream(oggStream.getNextOggPacket());
86 int headerType=source.getInt(8);
87 switch(headerType) {
88 case IDENTIFICATION_HEADER:
89 identificationHeader=new IdentificationHeader(source);
90 break;
91 case COMMENT_HEADER:
92 commentHeader=new CommentHeader(source);
93 break;
94 case SETUP_HEADER:
95 setupHeader=new SetupHeader(this, source);
96 break;
97 }
98 }
99
100 if(identificationHeader==null) {
101 throw new VorbisFormatException("The file has no identification header.");
102 }
103
104 if(commentHeader==null) {
105 throw new VorbisFormatException("The file has no commentHeader.");
106 }
107
108 if(setupHeader==null) {
109 throw new VorbisFormatException("The file has no setup header.");
110 }
111
112 //currentPcm=new int[identificationHeader.getChannels()][16384];
113 currentPcm=new byte[identificationHeader.getChannels()*identificationHeader.getBlockSize1()*2];
114 //new BufferThread().start();
115 }
116
117 public IdentificationHeader getIdentificationHeader() {
118 return identificationHeader;
119 }
120
121 public CommentHeader getCommentHeader() {
122 return commentHeader;
123 }
124
125 protected SetupHeader getSetupHeader() {
126 return setupHeader;
127 }
128
129 public boolean isOpen() {
130 return oggStream.isOpen();
131 }
132
133 public void close() throws IOException {
134 oggStream.close();
135 }
136
137
138 public int readPcm(byte[] buffer, int offset, int length) throws IOException {
139 synchronized (streamLock) {
140 final int channels=identificationHeader.getChannels();
141
142 if(lastAudioPacket==null) {
143 lastAudioPacket=getNextAudioPacket();
144 }
145 if(currentPcm==null || currentPcmIndex>=currentPcmLimit) {
146 AudioPacket ap=getNextAudioPacket();
147 try {
148 ap.getPcm(lastAudioPacket, currentPcm);
149 currentPcmLimit=ap.getNumberOfSamples()*identificationHeader.getChannels()*2;
150 }
151 catch(ArrayIndexOutOfBoundsException e) {
152 return 0;
153 }
154 currentPcmIndex=0;
155 lastAudioPacket=ap;
156 }
157 int written=0;
158 int i=0;
159 int arrIx=0;
160 for(i=currentPcmIndex; i<currentPcmLimit && arrIx<length; i++) {
161 buffer[offset+arrIx++]=currentPcm[i];
162 written++;
163 }
164 currentPcmIndex=i;
165 return written;
166 }
167 }
168
169
170 private AudioPacket getNextAudioPacket() throws VorbisFormatException, IOException {
171 pageCounter++;
172 byte[] data=oggStream.getNextOggPacket();
173 AudioPacket res=null;
174 while(res==null) {
175 try {
176 res=new AudioPacket(this, new ByteArrayBitInputStream(data));
177 }
178 catch(ArrayIndexOutOfBoundsException e) {
179 // ignore and continue with next packet
180 }
181 }
182 currentGranulePosition+=res.getNumberOfSamples();
183 currentBitRate=data.length*8*identificationHeader.getSampleRate()/res.getNumberOfSamples();
184 return res;
185 }
186
187 public long getCurrentGranulePosition() {
188 return currentGranulePosition;
189 }
190
191 public int getCurrentBitRate() {
192 return currentBitRate;
193 }
194
195 public byte[] processPacket(byte[] packet) throws VorbisFormatException, IOException {
196 if(packet.length==0) {
197 throw new VorbisFormatException("Cannot decode a vorbis packet with length = 0");
198 }
199 if(((int)packet[0]&1)==1) {
200 // header packet
201 BitInputStream source=new ByteArrayBitInputStream(packet);
202 switch(source.getInt(8)) {
203 case IDENTIFICATION_HEADER:
204 identificationHeader=new IdentificationHeader(source);
205 break;
206 case COMMENT_HEADER:
207 commentHeader=new CommentHeader(source);
208 break;
209 case SETUP_HEADER:
210 setupHeader=new SetupHeader(this, source);
211 break;
212 }
213 return null;
214 }
215 else {
216 // audio packet
217 if(identificationHeader==null ||
218 commentHeader==null ||
219 setupHeader==null) {
220
221 throw new VorbisFormatException("Cannot decode audio packet before all three header packets have been decoded.");
222 }
223
224 AudioPacket ap=new AudioPacket(this, new ByteArrayBitInputStream(packet));
225 currentGranulePosition+=ap.getNumberOfSamples();
226
227 if(lastAudioPacket==null) {
228 lastAudioPacket=ap;
229 return null;
230 }
231
232 byte[] res=new byte[identificationHeader.getChannels()*ap.getNumberOfSamples()*2];
233
234 try {
235 ap.getPcm(lastAudioPacket, res);
236 }
237 catch(IndexOutOfBoundsException e) {
238 java.util.Arrays.fill(res, (byte)0);
239 }
240
241 lastAudioPacket=ap;
242
243 return res;
244 }
245 }
246
247} \ No newline at end of file