diff --git a/.gitignore b/.gitignore index 780cda6bc..385609fd7 100644 --- a/.gitignore +++ b/.gitignore @@ -82,3 +82,4 @@ exported1.all.bin /libsrc/flamingo/nbproject/private/ /libsrc/flamingo/build/ /libsrc/flamingo/dist/ +/libsrc/jlayer-1.0.2/target/ diff --git a/lib/jl1.0.1.jar b/lib/jl1.0.1.jar deleted file mode 100644 index caaf140d4..000000000 Binary files a/lib/jl1.0.1.jar and /dev/null differ diff --git a/lib/jlayer-1.0.2.jar b/lib/jlayer-1.0.2.jar new file mode 100644 index 000000000..743579271 Binary files /dev/null and b/lib/jlayer-1.0.2.jar differ diff --git a/lib/jl.license.txt b/lib/jlayer.license.txt similarity index 100% rename from lib/jl.license.txt rename to lib/jlayer.license.txt diff --git a/libsrc/ffdec_lib/nbproject/project.xml b/libsrc/ffdec_lib/nbproject/project.xml index 2ccabf827..8068673cf 100644 --- a/libsrc/ffdec_lib/nbproject/project.xml +++ b/libsrc/ffdec_lib/nbproject/project.xml @@ -239,7 +239,7 @@ auxiliary.show.customizer.message= src - ../../lib/LZMA.jar;../../lib/avi.jar;../../lib/gif.jar;../../lib/gnujpdf.jar;../../lib/jl1.0.1.jar;../../lib/jpacker.jar;../../lib/nellymoser.jar;../../lib/sfntly.jar;../../lib/ttf.jar;../../lib/cmykjpeg.jar;../../src;../../lib/flashdebugger.jar;../../lib/graphs.jar;../../lib/ddsreader.jar;../../lib/vlcj-4.7.3.jar;../../lib/jna-3.5.1.jar;../../lib/jna-platform-3.5.1.jar + ../../lib/LZMA.jar;../../lib/avi.jar;../../lib/gif.jar;../../lib/gnujpdf.jar;../../lib/jpacker.jar;../../lib/nellymoser.jar;../../lib/sfntly.jar;../../lib/ttf.jar;../../lib/cmykjpeg.jar;../../src;../../lib/flashdebugger.jar;../../lib/graphs.jar;../../lib/ddsreader.jar;../../lib/vlcj-4.7.3.jar;../../lib/jna-3.5.1.jar;../../lib/jna-platform-3.5.1.jar;../../lib/jlayer-1.0.2.jar build reports dist diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/SoundStreamHeadTypeTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/SoundStreamHeadTypeTag.java index 00d52261e..a0cd3f0a5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/SoundStreamHeadTypeTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/SoundStreamHeadTypeTag.java @@ -70,7 +70,7 @@ public abstract class SoundStreamHeadTypeTag extends Tag implements CharacterIdT protected abstract void setSoundType(boolean soundType); protected abstract void setSoundSampleCount(int soundSampleCount); - + protected abstract void setSoundCompression(int soundCompression); protected abstract void setSoundRate(int soundRate); @@ -99,7 +99,7 @@ public abstract class SoundStreamHeadTypeTag extends Tag implements CharacterIdT sampleLen = (newSoundType ? 2 : 1) * (newSoundSize ? 2 : 1); soundRateHz = (int) Math.round(fmt.getSampleRate()); newSoundSampleCount = (int) Math.ceil(soundRateHz / swf.frameRate); - + bytesPerSwfFrame = (int) Math.ceil(soundRateHz / swf.frameRate) * sampleLen; switch (soundRateHz) { case 5512: @@ -207,27 +207,26 @@ public abstract class SoundStreamHeadTypeTag extends Tag implements CharacterIdT int frame = 0; long lastNumSamplesLong = 0; try { - while (dais.available() > 0) { - + while (dais.available() > 0) { + float timeAfterFrame = (frame + 1) / swf.frameRate; float numSamplesAfterFrame = (frame + 1) * soundRateHz / swf.frameRate; - + long numSamplesAfterFrameLong = (long) Math.ceil(numSamplesAfterFrame); - - long deltaNumSamples = numSamplesAfterFrameLong - lastNumSamplesLong; - - + + long deltaNumSamples = numSamplesAfterFrameLong - lastNumSamplesLong; + lastNumSamplesLong = numSamplesAfterFrameLong; - + if (deltaNumSamples > 0) { - byte buf[] = new byte[(int)deltaNumSamples * sampleLen]; + byte buf[] = new byte[(int) deltaNumSamples * sampleLen]; dais.readFully(buf); SoundStreamBlockTag block = new SoundStreamBlockTag(swf); block.streamSoundData = new ByteArrayRange(buf); blocks.add(block); } else { SoundStreamBlockTag block = new SoundStreamBlockTag(swf); - block.streamSoundData = new ByteArrayRange(new byte[0]); + block.streamSoundData = new ByteArrayRange(new byte[0]); blocks.add(block); } frame++; @@ -236,6 +235,39 @@ public abstract class SoundStreamHeadTypeTag extends Tag implements CharacterIdT //ignore } } + if (mp3Frames != null) { + + /*int frame = 0; + + int mp3FrameNum = 0; + long lastNumSamplesLong = 0; + while (mp3FrameNum < mp3Frames.size()) { + float timeAfterFrame = (frame + 1) / swf.frameRate; + float numSamplesAfterFrame = (frame + 1) * soundRateHz / swf.frameRate; + long numSamplesBeforeFrameLong = Math.round(frame * soundRateHz / swf.frameRate); + + int seekSamples = (int) (lastNumSamplesLong - numSamplesBeforeFrameLong); + + SoundStreamBlockTag block = new SoundStreamBlockTag(swf); + + List blockMp3Frames = new ArrayList<>(); + int blockSamples = 0; + while(lastNumSamplesLong < numSamplesAfterFrame) { + MP3FRAME mp3Frame = mp3Frames.get(mp3FrameNum); + lastNumSamplesLong += mp3Frame.getSampleCount(); + blockSamples += mp3Frame.getSampleCount(); + blockMp3Frames.add(mp3Frame); + } + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + SWFOutputStream sos = new SWFOutputStream(baos, SWF.DEFAULT_VERSION, null); + try { + sos.writeUI16(blockSamples); + sos.writeSI16(seekSamples); + } catch (IOException ex) { + Logger.getLogger(SoundStreamHeadTypeTag.class.getName()).log(Level.SEVERE, null, ex); + } + } */ + } ReadOnlyTagList tags = timelined.getTags(); int frame = -1; @@ -246,18 +278,18 @@ public abstract class SoundStreamHeadTypeTag extends Tag implements CharacterIdT if (frame >= startFrame && !blocks.isEmpty()) { SoundStreamBlockTag block = blocks.remove(0); block.setTimelined(timelined); - timelined.addTag(i, block); + timelined.addTag(i, block); tags = timelined.getTags(); i++; } } } setSoundCompression(newSoundFormat); - setSoundSampleCount((int)newSoundSampleCount); - setSoundSize(newSoundSize); + setSoundSampleCount((int) newSoundSampleCount); + setSoundSize(newSoundSize); setSoundType(newSoundType); setSoundRate(newSoundRate); - + setModified(true); timelined.resetTimeline(); swf.resetTimeline(); //to reload blocks diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/MP3FRAME.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/MP3FRAME.java index 4ad62a040..b0bfadbf9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/MP3FRAME.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/MP3FRAME.java @@ -55,9 +55,33 @@ public class MP3FRAME { } catch (DecoderException ex) { Logger.getLogger(MP3FRAME.class.getName()).log(Level.SEVERE, null, ex); } - bitstream.closeFrame(); + bitstream.closeFrame(); return ret; } + + public int getSampleCount() { + if (h.version() == 3) { + switch(h.layer()) { + case 1: + return 1152; + case 2: + return 1152; + case 3: + return 384; + } + } + if (h.version() == 2 || h.version() == 0) { + switch(h.layer()) { + case 1: + return 576; + case 2: + return 1152; + case 3: + return 384; + } + } + return 0; + } public boolean isStereo() { return h.mode() != Header.SINGLE_CHANNEL; diff --git a/libsrc/jlayer-1.0.2/.github/workflows/codeql-analysis.yml b/libsrc/jlayer-1.0.2/.github/workflows/codeql-analysis.yml new file mode 100644 index 000000000..84a170317 --- /dev/null +++ b/libsrc/jlayer-1.0.2/.github/workflows/codeql-analysis.yml @@ -0,0 +1,71 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +name: "CodeQL" + +on: + push: + branches: [master] + pull_request: + # The branches below must be a subset of the branches above + branches: [master] +# schedule: +# - cron: '0 8 * * 1' + +jobs: + analyze: + name: Analyze + runs-on: macos-latest + + strategy: + fail-fast: false + matrix: + # Override automatic language detection by changing the below list + # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] + language: ['java'] + # Learn more... + # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + # We must fetch at least the immediate parents so that if this is + # a pull request then we can checkout the head. + fetch-depth: 2 + + # If this run was triggered by a pull request event, then checkout + # the head of the pull request instead of the merge commit. + - run: git checkout HEAD^2 + if: ${{ github.event_name == 'pull_request' }} + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # â„šī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/libsrc/jlayer-1.0.2/.github/workflows/maven.yml b/libsrc/jlayer-1.0.2/.github/workflows/maven.yml new file mode 100644 index 000000000..69a449b64 --- /dev/null +++ b/libsrc/jlayer-1.0.2/.github/workflows/maven.yml @@ -0,0 +1,18 @@ +name: Java CI + +on: [push] + +jobs: + build: + + runs-on: macos-latest + + steps: + - uses: actions/checkout@v1 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Build with Maven + run: | + mvn -B package --file pom.xml diff --git a/libsrc/jlayer-1.0.2/.gitignore b/libsrc/jlayer-1.0.2/.gitignore new file mode 100644 index 000000000..d0697fab2 --- /dev/null +++ b/libsrc/jlayer-1.0.2/.gitignore @@ -0,0 +1,8 @@ +/bin/ +jl1.0.1.jar +build-unix.sh +build-win32.bat +playerapplet.html +setEnvAnt.bat +doc +tmp/ diff --git a/libsrc/jlayer-1.0.2/CHANGES.txt b/libsrc/jlayer-1.0.2/CHANGES.txt new file mode 100644 index 000000000..9605c9fb7 --- /dev/null +++ b/libsrc/jlayer-1.0.2/CHANGES.txt @@ -0,0 +1,122 @@ + JLayer 1.0.1 + JavaZOOM 1999-2008 + + Project Homepage : + http://www.javazoom.net/javalayer/javalayer.html + + JAVA and MP3 online Forums : + http://www.javazoom.net/services/forums/index.jsp +----------------------------------------------------- + +11/16/2008: JLayer 1.0.1 +------------------------ +- Subband allocation bug fix. + + +11/28/2004: JLayer 1.0 +---------------------- +- VBRI frame header (Fraunhofer VBR) support added in Header.java. +- Frame controls improved. It fixes the following bugs : + + ArrayIndexOutOfBound Exception in t_43[] array. + + ArrayIndexOutOfBound Exception in huffman_decode() method. +- Licensing moved from GPL to LGPL : It means that you can use JLayer in + your own application without being restricted by GPL license issues. + It's more business friendly. +- JavaLayer renamed into JLayer to be compliant to SUN trademark rules. +- Tested under JRE 1.5.0. CPU usage < 1%, RAM usage < 12MB under P4/2Ghz. + + +01/02/2004: JavaLayer 0.4 +------------------------- +- XING VBR header frame support improved in Header.java : + + public boolean vbr() added. + + public int vbr_scale() added. + + public byte[] vbr_toc() added. + total_ms(), ms_per_frame(), min_number_of_frames(int), max_number_of_frames(int), + bitrate_string(), bitrate() methods check for VBR status. + +- ID3v2 frames support improved : + + public InputStream getRawID3v2() added in Bitstream.java + +- Misc : + Bug fixed in the decoder for some +320kbps stream. + Bug fixed : SYNC conflict with some ID3v2 frames. + + public int bitrate() added. + + public int bitrate_instant() added. + jUnit tests added (see srctest/ folder) + + +08/04/2003: JavaLayer 0.3.0 +--------------------------- +- Advanced threaded player classes added. + + +04/01/2002: JavaLayer 0.2.0 +--------------------------- + - MPEG 2.5 support added. + Encoded files with LAME are supported. + - Bug fixes for ms time computation with free format. + + Bench notes : + + Heap use range : 1380KB to 1900KB - 370 classes loaded. + + Footprint : ~8MB under WinNT4 + J2SE 1.3 (Hotspot). + + CPU usage : ~12% under PIII 800Mhz/WinNT4+J2SE 1.3 (Hotspot). + + CPU usage : ~11% under PIII 1Ghz/Win2K+J2SE 1.4 (Hotspot). + + +03/04/2002: JavaLayer 0.1.2 +--------------------------- + - API improved to let developers get MP3 bitrate, framelength and total time features. + - Additionnal files added (CHANGES.txt and LICENSE.txt). + + +10/01/2001: JavaLayer 0.1.1 +--------------------------- + - Bugs fixes in the decoder (Layer III). + + +07/02/2001: JavaLayer 0.1.0 +--------------------------- + - Streaming support added to the simple player (jlp). + - Bugs fixes in the simple player (too fast playback for low rate files). + + +06/04/2001: JavaLayer 0.0.9 +--------------------------- + - Bugs fixes in Layer I and Layer II decoder. + - ANT build script added. + - HTML page added to play MP3 through PlayerApplet in a JavaSound 1.0 (JDK 1.3) + compliant browser. + + +04/16/2000: JavaLayer 0.0.8 +--------------------------- +A simple player have been added and you can now play MP3 in real time with JVM +that supports JavaSound 1.0 (i.e JDK 1.3). + + - Bug fixes. + - Decoder improvements. + - Build Scripts have been added for Win32 and Unix platforms. + + +12/16/1999: JavaLayer 0.0.7 +--------------------------- +JavaLayer 0.0.7 contains significant improvements over version 0.0 : + + - API and documentation added. + - The decoder is much more faster. Fast enough for real-time decoding. + - Huffman/Layer3 tables serialization added. + - New buffers management. + - Exceptions + Utils added. + - Bugs fixes. + + +02/28/1999: JavaLayer 0.0 +------------------------- +JavaLayer V0.0 does not play any MP3 but it allows the MP3toWAV conversion. +This is the first step in this project. We do it thanks to free mp3 ressources +available on the net: + + - MAPlay for the OO MP3 decoder (C++). + - WAV format description from Microsoft. + +The MP3 decoder works now but it is too slow to allow real time implementation. diff --git a/libsrc/jlayer-1.0.2/LICENSE.txt b/libsrc/jlayer-1.0.2/LICENSE.txt new file mode 100644 index 000000000..b1e3f5a26 --- /dev/null +++ b/libsrc/jlayer-1.0.2/LICENSE.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/libsrc/jlayer-1.0.2/README.md b/libsrc/jlayer-1.0.2/README.md new file mode 100644 index 000000000..be8504144 --- /dev/null +++ b/libsrc/jlayer-1.0.2/README.md @@ -0,0 +1,90 @@ +[![Release](https://jitpack.io/v/umjammer/jlayer.svg)](https://jitpack.io/#umjammer/jlayer) +[![Java CI](https://github.com/umjammer/jlayer/actions/workflows/maven.yml/badge.svg)](https://github.com/umjammer/jlayer/actions/workflows/maven.yml) +[![CodeQL](https://github.com/umjammer/jlayer/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/umjammer/jlayer/actions/workflows/codeql-analysis.yml) +![Java](https://img.shields.io/badge/Java-8-b07219) +[![Parent](https://img.shields.io/badge/Parent-mp3spi-pink)](https://github.com/umjammer/mp3spi) + +# JLayer + + JavaZOOM 1999-2008 + + Project Homepage :
+ [http://www.javazoom.net/javalayer/javalayer.html](https://web.archive.org/web/20210108055829/http://www.javazoom.net/javalayer/javalayer.html) + + JAVA and MP3 online Forums :
+ [http://www.javazoom.net/services/forums/index.jsp](https://web.archive.org/web/20041010053627/http://www.javazoom.net/services/forums/index.jsp) + +---- + +## DESCRIPTION + +JLayer is a library that decodes/plays/converts MPEG 1/2/2.5 Layer 1/2/3 +(i.e. MP3) in real time for the JAVA(tm) platform. This is a non-commercial project +and anyone can add his contribution. JLayer is licensed under LGPL (see [LICENSE](LICENSE.txt)). + + +## FAQ + +### How to install JLayer ? + + * https://jitpack.io/#umjammer/jlayer + +### Do I need JMF to run JLayer player ? + + No, JMF is not required. You just need a JVM JavaSound 1.0 compliant. + (i.e. JVM1.3 or higher). + +### How to run the MP3TOWAV converter ? + +``` + java javazoom.jl.converter.jlc -v -p output.wav yourfile.mp3 +``` + + (Note : MP3TOWAV converter should work under jdk1.1.x or higher) + +### How to run the simple MP3 player ? + +``` + java javazoom.jl.player.jlp localfile.mp3 +``` + + or + +``` + java javazoom.jl.player.jlp -url http://www.aserver.com/remotefile.mp3 +``` + + Note : MP3 simple player only works under JVM that supports JavaSound 1.0 (i.e JDK1.3.x+) + +### How to run the advanced (threaded) MP3 player ? + +``` + java javazoom.jl.player.advanced.jlap localfile.mp3 +``` + +### Does simple MP3 player support streaming ? + + Yes, use the following command to play music from stream : + +``` + java javazoom.jl.player.jlp -url http://www.shoutcastserver.com:8000 +``` + + (If JLayer returns without playing SHOUTcast stream then it might mean + that the server expect a winamp like `"User-Agent"` in HTTP request). + +### Does JLayer support MPEG 2.5 ? + + Yes, it works fine for all files generated with LAME. + +### Does JLayer support VBR ? + + Yes, It supports VBRI and XING VBR header too. + +### How to get ID3v1 or ID3v2 tags from JLayer API ? + + The API provides a `getRawID3v2()` method to get an `InputStream` on ID3v2 frames. + +### How to skip frames to have a seek feature ? + + See `javazoom.jl.player.advanced.jlap` source to learn how to skip frames. diff --git a/libsrc/jlayer-1.0.2/pom.xml b/libsrc/jlayer-1.0.2/pom.xml new file mode 100644 index 000000000..dbff5e082 --- /dev/null +++ b/libsrc/jlayer-1.0.2/pom.xml @@ -0,0 +1,77 @@ + + 4.0.0 + + net.javazoom + jlayer + 1.0.2 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 8 + 8 + UTF-8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M7 + + + -Djava.util.logging.config.file=${project.build.testOutputDirectory}/logging.properties + + false + + + + + + + + jitpack.io + https://jitpack.io + + + + + + + org.junit + junit-bom + 5.8.2 + pom + import + + + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.platform + junit-platform-commons + test + + + + com.github.umjammer + vavi-commons + 1.1.6 + test + + + \ No newline at end of file diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/Converter.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/Converter.java new file mode 100644 index 000000000..3e2e815a1 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/Converter.java @@ -0,0 +1,354 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Original verion. mdm@techie.com. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.converter; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.nio.file.Files; + +import javazoom.jl.decoder.Bitstream; +import javazoom.jl.decoder.Decoder; +import javazoom.jl.decoder.Header; +import javazoom.jl.decoder.JavaLayerException; +import javazoom.jl.decoder.Obuffer; + + +/** + * The Converter class implements the conversion of + * an MPEG audio file to a .WAV file. To convert an MPEG audio stream, + * just create an instance of this class and call the convert() + * method, passing in the names of the input and output files. You can + * pass in optional ProgressListener and + * Decoder.Params objects also to customize the conversion. + * + * @author MDM 12/12/99 + * @since 0.0.7 + */ +public class Converter { + + /** + * Creates a new converter instance. + */ + public Converter() { + } + + public synchronized void convert(String sourceName, String destName) throws JavaLayerException { + convert(sourceName, destName, null, null); + } + + public synchronized void convert(String sourceName, + String destName, + ProgressListener progressListener) throws JavaLayerException { + convert(sourceName, destName, progressListener, null); + } + + public void convert(String sourceName, + String destName, + ProgressListener progressListener, + Decoder.Params decoderParams) throws JavaLayerException { + if (destName.length() == 0) + destName = null; + try { + InputStream in = openInput(sourceName); + convert(in, destName, progressListener, decoderParams); + in.close(); + } catch (IOException ioe) { + throw new JavaLayerException(ioe.getLocalizedMessage(), ioe); + } + } + + public synchronized void convert(InputStream sourceStream, + String destName, + ProgressListener progressListener, + Decoder.Params decoderParams) throws JavaLayerException { + if (progressListener == null) + progressListener = PrintWriterProgressListener.newStdOut(PrintWriterProgressListener.NO_DETAIL); + try { + if (!(sourceStream instanceof BufferedInputStream)) + sourceStream = new BufferedInputStream(sourceStream); + int frameCount = -1; + if (sourceStream.markSupported()) { + sourceStream.mark(-1); + frameCount = countFrames(sourceStream); + sourceStream.reset(); + } + progressListener.converterUpdate(ProgressListener.UPDATE_FRAME_COUNT, frameCount, 0); + + Obuffer output = null; + Decoder decoder = new Decoder(decoderParams); + Bitstream stream = new Bitstream(sourceStream); + + if (frameCount == -1) + frameCount = Integer.MAX_VALUE; + + int frame = 0; + long startTime = System.currentTimeMillis(); + + try { + for (; frame < frameCount; frame++) { + try { + Header header = stream.readFrame(); + if (header == null) + break; + + progressListener.readFrame(frame, header); + + if (output == null) { + // REVIEW: Incorrect functionality. + // the decoder should provide decoded + // frequency and channels output as it may differ from + // the source (e.g. when downmixing stereo to mono.) + int channels = (header.mode() == Header.SINGLE_CHANNEL) ? 1 : 2; + int freq = header.frequency(); + output = new WaveFileObuffer(channels, freq, destName); + decoder.setOutputBuffer(output); + } + + Obuffer decoderOutput = decoder.decodeFrame(header, stream); + + // REVIEW: the way the output buffer is set + // on the decoder is a bit dodgy. Even though + // this exception should never happen, we test to be sure. + if (decoderOutput != output) + throw new InternalError("Output buffers are different."); + + progressListener.decodedFrame(frame, header, output); + + stream.closeFrame(); + + } catch (Exception ex) { + boolean stop = !progressListener.converterException(ex); + + if (stop) { + throw new JavaLayerException(ex.getLocalizedMessage(), ex); + } + } + } + + } finally { + + if (output != null) + output.close(); + } + + int time = (int) (System.currentTimeMillis() - startTime); + progressListener.converterUpdate(ProgressListener.UPDATE_CONVERT_COMPLETE, time, frame); + } catch (IOException ex) { + throw new JavaLayerException(ex.getLocalizedMessage(), ex); + } + } + + protected int countFrames(InputStream in) { + return -1; + } + + protected InputStream openInput(String fileName) throws IOException { + // ensure name is abstract path name + File file = new File(fileName); + InputStream fileIn = Files.newInputStream(file.toPath()); + BufferedInputStream bufIn = new BufferedInputStream(fileIn); + + return bufIn; + } + + /** + * This interface is used by the Converter to provide + * notification of tasks being carried out by the converter, + * and to provide new information as it becomes available. + */ + public interface ProgressListener { + int UPDATE_FRAME_COUNT = 1; + + /** + * Conversion is complete. Param1 contains the time + * to convert in milliseconds. Param2 contains the number + * of MPEG audio frames converted. + */ + int UPDATE_CONVERT_COMPLETE = 2; + + /** + * Notifies the listener that new information is available. + * + * @param updateID Code indicating the information that has been + * updated. + * @param param1 Parameter whose value depends upon the update code. + * @param param2 Parameter whose value depends upon the update code. + *

+ * The updateID parameter can take these values: + *

+ * UPDATE_FRAME_COUNT: param1 is the frame count, or -1 if + * not known. + * UPDATE_CONVERT_COMPLETE: param1 is the conversion time, + * param2 + * is the number of frames converted. + */ + void converterUpdate(int updateID, int param1, int param2); + + /** + * If the converter wishes to make a first pass over the + * audio frames, this is called as each frame is parsed. + */ + void parsedFrame(int frameNo, Header header); + + /** + * This method is called after each frame has been read, + * but before it has been decoded. + * + * @param frameNo The 0-based sequence number of the frame. + * @param header The Header rerpesenting the frame just read. + */ + void readFrame(int frameNo, Header header); + + /** + * This method is called after a frame has been decoded. + * + * @param frameNo The 0-based sequence number of the frame. + * @param header The Header rerpesenting the frame just read. + * @param o The Obuffer the deocded data was written to. + */ + void decodedFrame(int frameNo, Header header, Obuffer o); + + /** + * Called when an exception is thrown during while converting + * a frame. + * + * @param t The Throwable instance that + * was thrown. + * @return true to continue processing, or false + * to abort conversion. + *

+ * If this method returns false, the exception + * is propagated to the caller of the convert() method. If + * true is returned, the exception is silently + * ignored and the converter moves onto the next frame. + */ + boolean converterException(Throwable t); + } + + /** + * Implementation of ProgressListener that writes + * notification text to a PrintWriter. + *

+ * REVIEW: i18n of text and order required. + */ + static public class PrintWriterProgressListener implements ProgressListener { + static public final int NO_DETAIL = 0; + + /** + * Level of detail typically expected of expert + * users. + */ + static public final int EXPERT_DETAIL = 1; + + /** + * Verbose detail. + */ + static public final int VERBOSE_DETAIL = 2; + + /** + * Debug detail. All frame read notifications are shown. + */ + static public final int DEBUG_DETAIL = 7; + + static public final int MAX_DETAIL = 10; + + private PrintWriter pw; + + private int detailLevel; + + static public PrintWriterProgressListener newStdOut(int detail) { + return new PrintWriterProgressListener(new PrintWriter(System.out, true), detail); + } + + public PrintWriterProgressListener(PrintWriter writer, int detailLevel) { + this.pw = writer; + this.detailLevel = detailLevel; + } + + public boolean isDetail(int detail) { + return (this.detailLevel >= detail); + } + + public void converterUpdate(int updateID, int param1, int param2) { + if (isDetail(VERBOSE_DETAIL)) { + switch (updateID) { + case UPDATE_CONVERT_COMPLETE: + // catch divide by zero errors. + if (param2 == 0) + param2 = 1; + + pw.println(); + pw.println("Converted " + param2 + " frames in " + param1 + " ms (" + (param1 / param2) + + " ms per frame.)"); + } + } + } + + public void parsedFrame(int frameNo, Header header) { + if ((frameNo == 0) && isDetail(VERBOSE_DETAIL)) { + String headerString = header.toString(); + pw.println("File is a " + headerString); + } else if (isDetail(MAX_DETAIL)) { + String headerString = header.toString(); + pw.println("Prased frame " + frameNo + ": " + headerString); + } + } + + public void readFrame(int frameNo, Header header) { + if ((frameNo == 0) && isDetail(VERBOSE_DETAIL)) { + String headerString = header.toString(); + pw.println("File is a " + headerString); + } else if (isDetail(MAX_DETAIL)) { + String headerString = header.toString(); + pw.println("Read frame " + frameNo + ": " + headerString); + } + } + + public void decodedFrame(int frameNo, Header header, Obuffer o) { + if (isDetail(MAX_DETAIL)) { + String headerString = header.toString(); + pw.println("Decoded frame " + frameNo + ": " + headerString); + pw.println("Output: " + o); + } else if (isDetail(VERBOSE_DETAIL)) { + if (frameNo == 0) { + pw.print("Converting."); + pw.flush(); + } + + if ((frameNo % 10) == 0) { + pw.print('.'); + pw.flush(); + } + } + } + + public boolean converterException(Throwable t) { + if (this.detailLevel > NO_DETAIL) { + t.printStackTrace(pw); + pw.flush(); + } + return false; + } + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/RiffFile.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/RiffFile.java new file mode 100644 index 000000000..2a819a62b --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/RiffFile.java @@ -0,0 +1,447 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 02/23/99 JavaConversion by E.B + * Don Cross, April 1993. + * RIFF file format classes. + * See Chapter 8 of "Multimedia Programmer's Reference" in + * the Microsoft Windows SDK. + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.converter; + +import java.io.IOException; +import java.io.RandomAccessFile; + + +/** + * Class to manage RIFF files + */ +public class RiffFile { + + static class RiffChunkHeader { + /** Four-character chunk ID */ + public int ckID = 0; + /** Length of data in chunk */ + public int ckSize = 0; + } + + // DDCRET + + /** The operation succeeded */ + public static final int DDC_SUCCESS = 0; + /** The operation failed for unspecified reasons */ + public static final int DDC_FAILURE = 1; + /** Operation failed due to running out of memory */ + public static final int DDC_OUT_OF_MEMORY = 2; + /** Operation encountered file I/O error */ + public static final int DDC_FILE_ERROR = 3; + /** Operation was called with invalid parameters */ + public static final int DDC_INVALID_CALL = 4; + /** Operation was aborted by the user */ + public static final int DDC_USER_ABORT = 5; + /** File format does not match */ + public static final int DDC_INVALID_FILE = 6; + + // RiffFileMode + + /** undefined type (can use to mean "N/A" or "not open") */ + public static final int RFM_UNKNOWN = 0; + /** open for write */ + public static final int RFM_WRITE = 1; + /** open for read */ + public static final int RFM_READ = 2; + + /** header for whole file */ + private RiffChunkHeader riff_header; + /** current file I/O mode */ + protected int fmode; + /** I/O stream to use */ + protected RandomAccessFile file; + + /** + * Dummy Constructor + */ + public RiffFile() { + file = null; + fmode = RFM_UNKNOWN; + riff_header = new RiffChunkHeader(); + + riff_header.ckID = FourCC("RIFF"); + riff_header.ckSize = 0; + } + + /** + * Return File Mode. + */ + public int CurrentFileMode() { + return fmode; + } + + /** + * Open a RIFF file. + */ + public int Open(String Filename, int NewMode) { + int retcode = DDC_SUCCESS; + + if (fmode != RFM_UNKNOWN) { + retcode = Close(); + } + + if (retcode == DDC_SUCCESS) { + switch (NewMode) { + case RFM_WRITE: + try { + file = new RandomAccessFile(Filename, "rw"); + + try { + // Write the RIFF header... + // We will have to come back later and patch it! + byte[] br = new byte[8]; + br[0] = (byte) ((riff_header.ckID >>> 24) & 0x000000FF); + br[1] = (byte) ((riff_header.ckID >>> 16) & 0x000000FF); + br[2] = (byte) ((riff_header.ckID >>> 8) & 0x000000FF); + br[3] = (byte) (riff_header.ckID & 0x000000FF); + + byte br4 = (byte) ((riff_header.ckSize >>> 24) & 0x000000FF); + byte br5 = (byte) ((riff_header.ckSize >>> 16) & 0x000000FF); + byte br6 = (byte) ((riff_header.ckSize >>> 8) & 0x000000FF); + byte br7 = (byte) (riff_header.ckSize & 0x000000FF); + + br[4] = br7; + br[5] = br6; + br[6] = br5; + br[7] = br4; + + file.write(br, 0, 8); + fmode = RFM_WRITE; + } catch (IOException ioe) { + file.close(); + fmode = RFM_UNKNOWN; + } + } catch (IOException ioe) { + fmode = RFM_UNKNOWN; + retcode = DDC_FILE_ERROR; + } + break; + + case RFM_READ: + try { + file = new RandomAccessFile(Filename, "r"); + try { + // Try to read the RIFF header... + byte[] br = new byte[8]; + file.read(br, 0, 8); + fmode = RFM_READ; + riff_header.ckID = ((br[0] << 24) & 0xFF000000) | ((br[1] << 16) & 0x00FF0000) | ((br[2] << 8) & 0x0000FF00) | (br[3] & 0x000000FF); + riff_header.ckSize = ((br[4] << 24) & 0xFF000000) | ((br[5] << 16) & 0x00FF0000) | ((br[6] << 8) & 0x0000FF00) | (br[7] & 0x000000FF); + } catch (IOException ioe) { + file.close(); + fmode = RFM_UNKNOWN; + } + } catch (IOException ioe) { + fmode = RFM_UNKNOWN; + retcode = DDC_FILE_ERROR; + } + break; + default: + retcode = DDC_INVALID_CALL; + } + } + return retcode; + } + + /** + * Write NumBytes data. + */ + public int Write(byte[] Data, int NumBytes) { + if (fmode != RFM_WRITE) { + return DDC_INVALID_CALL; + } + try { + file.write(Data, 0, NumBytes); + fmode = RFM_WRITE; + } catch (IOException ioe) { + return DDC_FILE_ERROR; + } + riff_header.ckSize += NumBytes; + return DDC_SUCCESS; + } + + + /** + * Write NumBytes data. + */ + public int Write(short[] Data, int NumBytes) { + byte[] theData = new byte[NumBytes]; + int yc = 0; + for (int y = 0; y < NumBytes; y = y + 2) { + theData[y] = (byte) (Data[yc] & 0x00FF); + theData[y + 1] = (byte) ((Data[yc++] >>> 8) & 0x00FF); + } + if (fmode != RFM_WRITE) { + return DDC_INVALID_CALL; + } + try { + file.write(theData, 0, NumBytes); + fmode = RFM_WRITE; + } catch (IOException ioe) { + return DDC_FILE_ERROR; + } + riff_header.ckSize += NumBytes; + return DDC_SUCCESS; + } + + /** + * Write NumBytes data. + */ + public int Write(RiffChunkHeader Triff_header, int NumBytes) { + byte[] br = new byte[8]; + br[0] = (byte) ((Triff_header.ckID >>> 24) & 0x000000FF); + br[1] = (byte) ((Triff_header.ckID >>> 16) & 0x000000FF); + br[2] = (byte) ((Triff_header.ckID >>> 8) & 0x000000FF); + br[3] = (byte) (Triff_header.ckID & 0x000000FF); + + byte br4 = (byte) ((Triff_header.ckSize >>> 24) & 0x000000FF); + byte br5 = (byte) ((Triff_header.ckSize >>> 16) & 0x000000FF); + byte br6 = (byte) ((Triff_header.ckSize >>> 8) & 0x000000FF); + byte br7 = (byte) (Triff_header.ckSize & 0x000000FF); + + br[4] = br7; + br[5] = br6; + br[6] = br5; + br[7] = br4; + + if (fmode != RFM_WRITE) { + return DDC_INVALID_CALL; + } + try { + file.write(br, 0, NumBytes); + fmode = RFM_WRITE; + } catch (IOException ioe) { + return DDC_FILE_ERROR; + } + riff_header.ckSize += NumBytes; + return DDC_SUCCESS; + } + + /** + * Write NumBytes data. + */ + public int Write(short Data, int NumBytes) { + short theData = (short) (((Data >>> 8) & 0x00FF) | ((Data << 8) & 0xFF00)); + if (fmode != RFM_WRITE) { + return DDC_INVALID_CALL; + } + try { + file.writeShort(theData); + fmode = RFM_WRITE; + } catch (IOException ioe) { + return DDC_FILE_ERROR; + } + riff_header.ckSize += NumBytes; + return DDC_SUCCESS; + } + + /** + * Write NumBytes data. + */ + public int Write(int Data, int NumBytes) { + short theDataL = (short) ((Data >>> 16) & 0x0000FFFF); + short theDataR = (short) (Data & 0x0000FFFF); + short theDataLI = (short) (((theDataL >>> 8) & 0x00FF) | ((theDataL << 8) & 0xFF00)); + short theDataRI = (short) (((theDataR >>> 8) & 0x00FF) | ((theDataR << 8) & 0xFF00)); + int theData = ((theDataRI << 16) & 0xFFFF0000) | (theDataLI & 0x0000FFFF); + if (fmode != RFM_WRITE) { + return DDC_INVALID_CALL; + } + try { + file.writeInt(theData); + fmode = RFM_WRITE; + } catch (IOException ioe) { + return DDC_FILE_ERROR; + } + riff_header.ckSize += NumBytes; + return DDC_SUCCESS; + } + + + /** + * Read NumBytes data. + */ + public int Read(byte[] Data, int NumBytes) { + int retcode = DDC_SUCCESS; + try { + file.read(Data, 0, NumBytes); + } catch (IOException ioe) { + retcode = DDC_FILE_ERROR; + } + return retcode; + } + + /** + * Expect NumBytes data. + */ + public int Expect(String Data, int NumBytes) { + byte target = 0; + int cnt = 0; + try { + while ((NumBytes--) != 0) { + target = file.readByte(); + if (target != Data.charAt(cnt++)) return DDC_FILE_ERROR; + } + } catch (IOException ioe) { + return DDC_FILE_ERROR; + } + return DDC_SUCCESS; + } + + /** + * Close Riff File. + * Length is written too. + */ + public int Close() { + int retcode = DDC_SUCCESS; + + switch (fmode) { + case RFM_WRITE: + try { + file.seek(0); + try { + byte[] br = new byte[8]; + br[0] = (byte) ((riff_header.ckID >>> 24) & 0x000000FF); + br[1] = (byte) ((riff_header.ckID >>> 16) & 0x000000FF); + br[2] = (byte) ((riff_header.ckID >>> 8) & 0x000000FF); + br[3] = (byte) (riff_header.ckID & 0x000000FF); + + br[7] = (byte) ((riff_header.ckSize >>> 24) & 0x000000FF); + br[6] = (byte) ((riff_header.ckSize >>> 16) & 0x000000FF); + br[5] = (byte) ((riff_header.ckSize >>> 8) & 0x000000FF); + br[4] = (byte) (riff_header.ckSize & 0x000000FF); + file.write(br, 0, 8); + file.close(); + } catch (IOException ioe) { + retcode = DDC_FILE_ERROR; + } + } catch (IOException ioe) { + retcode = DDC_FILE_ERROR; + } + break; + + case RFM_READ: + try { + file.close(); + } catch (IOException ioe) { + retcode = DDC_FILE_ERROR; + } + break; + } + file = null; + fmode = RFM_UNKNOWN; + return retcode; + } + + /** + * Return File Position. + */ + public long CurrentFilePosition() { + long position; + try { + position = file.getFilePointer(); + } catch (IOException ioe) { + position = -1; + } + return position; + } + + /** + * Write Data to specified offset. + */ + public int Backpatch(long FileOffset, RiffChunkHeader Data, int NumBytes) { + if (file == null) { + return DDC_INVALID_CALL; + } + try { + file.seek(FileOffset); + } catch (IOException ioe) { + return DDC_FILE_ERROR; + } + return Write(Data, NumBytes); + } + + public int Backpatch(long FileOffset, byte[] Data, int NumBytes) { + if (file == null) { + return DDC_INVALID_CALL; + } + try { + file.seek(FileOffset); + } catch (IOException ioe) { + return DDC_FILE_ERROR; + } + return Write(Data, NumBytes); + } + + + /** + * Seek in the File. + */ + protected int Seek(long offset) { + int rc; + try { + file.seek(offset); + rc = DDC_SUCCESS; + } catch (IOException ioe) { + rc = DDC_FILE_ERROR; + } + return rc; + } + + /** + * Error Messages. + */ + private String DDCRET_String(int retcode) { + switch (retcode) { + case DDC_SUCCESS: + return "DDC_SUCCESS"; + case DDC_FAILURE: + return "DDC_FAILURE"; + case DDC_OUT_OF_MEMORY: + return "DDC_OUT_OF_MEMORY"; + case DDC_FILE_ERROR: + return "DDC_FILE_ERROR"; + case DDC_INVALID_CALL: + return "DDC_INVALID_CALL"; + case DDC_USER_ABORT: + return "DDC_USER_ABORT"; + case DDC_INVALID_FILE: + return "DDC_INVALID_FILE"; + } + return "Unknown Error"; + } + + /** + * Fill the header. + */ + public static int FourCC(String ChunkName) { + byte[] p = {0x20, 0x20, 0x20, 0x20}; + ChunkName.getBytes(0, 4, p, 0); + int ret = (((p[0] << 24) & 0xFF000000) | ((p[1] << 16) & 0x00FF0000) | ((p[2] << 8) & 0x0000FF00) | (p[3] & 0x000000FF)); + return ret; + } + +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/WaveFile.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/WaveFile.java new file mode 100644 index 000000000..625779d35 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/WaveFile.java @@ -0,0 +1,206 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 02/23/99 JavaConversion by E.B + * Don Cross, April 1993. + * RIFF file format classes. + * See Chapter 8 of "Multimedia Programmer's Reference" in + * the Microsoft Windows SDK. + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.converter; + +/** + * Class allowing WaveFormat Access + */ +public class WaveFile extends RiffFile { + public static final int MAX_WAVE_CHANNELS = 2; + + static class WaveFormat_ChunkData { + public short wFormatTag = 0; // Format category (PCM=1) + public short nChannels = 0; // Number of channels (mono=1, stereo=2) + public int nSamplesPerSec = 0; // Sampling rate [Hz] + public int nAvgBytesPerSec = 0; + public short nBlockAlign = 0; + public short nBitsPerSample = 0; + + public WaveFormat_ChunkData() { + wFormatTag = 1; // PCM + Config(44100, (short) 16, (short) 1); + } + + public void Config(int NewSamplingRate, short NewBitsPerSample, short NewNumChannels) { + nSamplesPerSec = NewSamplingRate; + nChannels = NewNumChannels; + nBitsPerSample = NewBitsPerSample; + nAvgBytesPerSec = (nChannels * nSamplesPerSec * nBitsPerSample) / 8; + nBlockAlign = (short) ((nChannels * nBitsPerSample) / 8); + } + } + + + class WaveFormat_Chunk { + public RiffChunkHeader header; + public WaveFormat_ChunkData data; + + public WaveFormat_Chunk() { + header = new RiffChunkHeader(); + data = new WaveFormat_ChunkData(); + header.ckID = FourCC("fmt "); + header.ckSize = 16; + } + + public int VerifyValidity() { + boolean ret = header.ckID == FourCC("fmt ") && + + (data.nChannels == 1 || data.nChannels == 2) && + + data.nAvgBytesPerSec == (data.nChannels * + data.nSamplesPerSec * + data.nBitsPerSample) / 8 && + + data.nBlockAlign == (data.nChannels * + data.nBitsPerSample) / 8; + if (ret) return 1; + else return 0; + } + } + + public static class WaveFileSample { + public short[] chan; + + public WaveFileSample() { + chan = new short[WaveFile.MAX_WAVE_CHANNELS]; + } + } + + private WaveFormat_Chunk wave_format; + private RiffChunkHeader pcm_data; + private long pcm_data_offset = 0; // offset of 'pcm_data' in output file + private int num_samples = 0; + + + /** + * Constructs a new WaveFile instance. + */ + public WaveFile() { + pcm_data = new RiffChunkHeader(); + wave_format = new WaveFormat_Chunk(); + pcm_data.ckID = FourCC("data"); + pcm_data.ckSize = 0; + num_samples = 0; + } + + /** + * + */ + public int OpenForWrite(String Filename, int SamplingRate, short BitsPerSample, short NumChannels) { + // Verify parameters... + if ((Filename == null) || + (BitsPerSample != 8 && BitsPerSample != 16) || + NumChannels < 1 || NumChannels > 2) { + return DDC_INVALID_CALL; + } + + wave_format.data.Config(SamplingRate, BitsPerSample, NumChannels); + + int retcode = Open(Filename, RFM_WRITE); + + if (retcode == DDC_SUCCESS) { + byte[] theWave = {(byte) 'W', (byte) 'A', (byte) 'V', (byte) 'E'}; + retcode = Write(theWave, 4); + + if (retcode == DDC_SUCCESS) { + // Ecriture de wave_format + retcode = Write(wave_format.header, 8); + retcode = Write(wave_format.data.wFormatTag, 2); + retcode = Write(wave_format.data.nChannels, 2); + retcode = Write(wave_format.data.nSamplesPerSec, 4); + retcode = Write(wave_format.data.nAvgBytesPerSec, 4); + retcode = Write(wave_format.data.nBlockAlign, 2); + retcode = Write(wave_format.data.nBitsPerSample, 2); + + + if (retcode == DDC_SUCCESS) { + pcm_data_offset = CurrentFilePosition(); + retcode = Write(pcm_data, 8); + } + } + } + + return retcode; + } + + /** + * Write 16-bit audio + */ + public int WriteData(short[] data, int numData) { + int extraBytes = numData * 2; + pcm_data.ckSize += extraBytes; + return super.Write(data, extraBytes); + } + + /** + * + */ + public int Close() { + int rc = DDC_SUCCESS; + + if (fmode == RFM_WRITE) + rc = Backpatch(pcm_data_offset, pcm_data, 8); + if (rc == DDC_SUCCESS) + rc = super.Close(); + return rc; + } + + // [Hz] + public int SamplingRate() { + return wave_format.data.nSamplesPerSec; + } + + public short BitsPerSample() { + return wave_format.data.nBitsPerSample; + } + + public short NumChannels() { + return wave_format.data.nChannels; + } + + public int NumSamples() { + return num_samples; + } + + + /** + * Open for write using another wave file's parameters... + */ + public int OpenForWrite(String Filename, WaveFile OtherWave) { + return OpenForWrite(Filename, + OtherWave.SamplingRate(), + OtherWave.BitsPerSample(), + OtherWave.NumChannels()); + } + + /** + * + */ + public long CurrentFilePosition() { + return super.CurrentFilePosition(); + } + +} \ No newline at end of file diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/WaveFileObuffer.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/WaveFileObuffer.java new file mode 100644 index 000000000..b4d8d5f6a --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/WaveFileObuffer.java @@ -0,0 +1,124 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 12/12/99 0.0.7 Renamed class, additional constructor arguments + * and larger write buffers. mdm@techie.com. + * + * 15/02/99 Java Conversion by E.B ,javalayer@javazoom.net + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.converter; + +import javazoom.jl.decoder.Obuffer; + + +/** + * Implements an Obuffer by writing the data to + * a file in RIFF WAVE format. + * + * @since 0.0 + */ + + +public class WaveFileObuffer extends Obuffer { + private short[] buffer; + private short[] bufferp; + private int channels; + private WaveFile outWave; + + /** + * Creates a new WareFileObuffer instance. + * + * @param number_of_channels The number of channels of audio data + * this buffer will receive. + * @param freq The sample frequency of the samples in the buffer. + * @param fileName The filename to write the data to. + */ + public WaveFileObuffer(int number_of_channels, int freq, String fileName) { + if (fileName == null) + throw new NullPointerException("fileName"); + + buffer = new short[OBUFFERSIZE]; + bufferp = new short[MAXCHANNELS]; + channels = number_of_channels; + + for (int i = 0; i < number_of_channels; ++i) + bufferp[i] = (short) i; + + outWave = new WaveFile(); + + int rc = outWave.OpenForWrite(fileName, freq, (short) 16, (short) channels); + } + + /** + * Takes a 16 Bit PCM sample. + */ + public void append(int channel, short value) { + buffer[bufferp[channel]] = value; + bufferp[channel] += (short) channels; + } + + /** + * Write the samples to the file (Random Acces). + */ + short[] myBuffer = new short[2]; + + public void write_buffer(int val) { + + int k = 0; + int rc = 0; + + rc = outWave.WriteData(buffer, bufferp[0]); + // REVIEW: handle RiffFile errors. + for (int i = 0; i < channels; ++i) bufferp[i] = (short) i; + } + + public void close() { + outWave.Close(); + } + + /** + * + */ + public void clear_buffer() { + } + + /** + * + */ + public void set_stop_flag() { + } + + /* + * Create STDOUT buffer + * + * + public static Obuffer create_stdout_obuffer(MPEG_Args maplay_args) + { + Obuffer thebuffer = null; + int mode = maplay_args.MPEGheader.mode(); + int which_channels = maplay_args.which_c; + if (mode == Header.single_channel || which_channels != MPEG_Args.both) + thebuffer = new FileObuffer(1,maplay_args.output_filename); + else + thebuffer = new FileObuffer(2,maplay_args.output_filename); + return(thebuffer); + } + */ +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/jlc.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/jlc.java new file mode 100644 index 000000000..267bc6973 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/converter/jlc.java @@ -0,0 +1,181 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 29/01/00 Initial version. mdm@techie.com + * + * 12/12/99 JavaLayer 0.0.7 mdm@techie.com + * + * 14/02/99 MPEG_Args Based Class - E.B + * Adapted from javalayer and MPEG_Args. + * Doc'ed and integerated with JL converter. Removed + * Win32 specifics from original Maplay code. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.converter; + +import java.io.PrintWriter; +import java.util.logging.Logger; + +import javazoom.jl.decoder.Crc16; +import javazoom.jl.decoder.JavaLayerException; +import javazoom.jl.decoder.OutputChannels; + + +/** + * The jlc class presents the JavaLayer + * Conversion functionality as a command-line program. + * + * @since 0.0.7 + */ +public class jlc { + + private static final Logger logger = Logger.getLogger(jlc.class.getName()); + + static public void main(String[] args) { + String[] argv; + long start = System.currentTimeMillis(); + int argc = args.length + 1; + argv = new String[argc]; + argv[0] = "jlc"; + System.arraycopy(args, 0, argv, 1, args.length); + + jlcArgs ma = new jlcArgs(); + if (!ma.processArgs(argv)) + System.exit(1); + + Converter conv = new Converter(); + + int detail = (ma.verbose_mode ? ma.verbose_level : Converter.PrintWriterProgressListener.NO_DETAIL); + + Converter.ProgressListener listener = new Converter.PrintWriterProgressListener(new PrintWriter(System.out, true), + detail); + + try { + conv.convert(ma.filename, ma.output_filename, listener); + } catch (JavaLayerException ex) { + logger.warning("Conversion failure: " + ex); + } + + System.exit(0); + } + + /** + * Class to contain arguments for maplay. + */ + static class jlcArgs { + // channel constants moved into OutputChannels class. + + public int which_c; + + public int output_mode; + + public boolean use_own_scalefactor; + + public float scalefactor; + + public String output_filename; + + public String filename; + + public boolean verbose_mode; + + public int verbose_level = 3; + + public jlcArgs() { + which_c = OutputChannels.BOTH_CHANNELS; + use_own_scalefactor = false; + scalefactor = (float) 32768.0; + verbose_mode = false; + } + + /** + * Process user arguments. + *

+ * Returns true if successful. + */ + public boolean processArgs(String[] argv) { + filename = null; + Crc16[] crc; + crc = new Crc16[1]; + int i; + int argc = argv.length; + + verbose_mode = false; + output_mode = OutputChannels.BOTH_CHANNELS; + output_filename = ""; + if (argc < 2 || argv[1].equals("-h")) + return Usage(); + + i = 1; + while (i < argc) { +logger.finer("Option = " + argv[i]); + if (argv[i].charAt(0) == '-') { + if (argv[i].startsWith("-v")) { + verbose_mode = true; + if (argv[i].length() > 2) { + try { + String level = argv[i].substring(2); + verbose_level = Integer.parseInt(level); + } catch (NumberFormatException ex) { + System.err.println("Invalid verbose level. Using default."); + } + } + System.out.println("Verbose Activated (level " + verbose_level + ")"); + } else if (argv[i].equals("-p")) { + if (++i == argc) { + System.out.println("Please specify an output filename after the -p option!"); + System.exit(1); + } + output_filename = argv[i]; + } else + return Usage(); + } else { + filename = argv[i]; + System.out.println("FileName = " + argv[i]); + if (filename == null) + return Usage(); + } + i++; + } + if (filename == null) + return Usage(); + + return true; + } + + /** + * Usage of JavaLayer. + */ + public boolean Usage() { + System.out.println("JavaLayer Converter :"); + System.out.println(" -v[x] verbose mode. "); + System.out.println(" default = 2"); +// System.out.println(" -s write u-law samples at 8 kHz rate to stdout"); +// System.out.println(" -l decode only the left channel"); +// System.out.println(" -r decode only the right channel"); +// System.out.println(" -d downmix mode (layer III only)"); +// System.out.println(" -s write pcm samples to stdout"); +// System.out.println(" -d downmix mode (layer III only)"); + System.out.println(" -p name output as a PCM wave file"); + System.out.println(); + System.out.println(" More info on http://www.javazoom.net"); +// System.out.println(" -f ushort use this scalefactor instead of the default value 32768"); + return false; + } + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/BitReserve.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/BitReserve.java new file mode 100644 index 000000000..2716658bb --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/BitReserve.java @@ -0,0 +1,154 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 12/12/99 0.0.7 Implementation stores single bits + * as ints for better performance. mdm@techie.com. + * + * 02/28/99 0.0 Java Conversion by E.B, javalayer@javazoom.net + * + * Adapted from the public c code by Jeff Tsay. + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Implementation of Bit Reservoir for Layer III. + *

+ * The implementation stores single bits as a word in the buffer. If + * a bit is set, the corresponding word in the buffer will be non-zero. + * If a bit is clear, the corresponding word is zero. Although this + * may seem waseful, this can be a factor of two quicker than + * packing 8 bits to a byte and extracting. + *

+ * REVIEW: there is no range checking, so buffer underflow or overflow + * can silently occur. + */ +final class BitReserve { + + /** + * Size of the internal buffer to store the reserved bits. + * Must be a power of 2. And x8, as each bit is stored as a single + * entry. + */ + private static final int BUFSIZE = 4096 * 8; + + /** + * Mask that can be used to quickly implement the + * modulus operation on BUFSIZE. + */ + private static final int BUFSIZE_MASK = BUFSIZE - 1; + + private int offset, totbit, buf_byte_idx; + private final int[] buf = new int[BUFSIZE]; + @SuppressWarnings("unused") + private int buf_bit_idx; + + BitReserve() { + offset = 0; + totbit = 0; + buf_byte_idx = 0; + } + + /** + * Return totbit Field. + */ + public int hsstell() { + return (totbit); + } + + /** + * Read a number bits from the bit stream. + * + * @param N the number of + */ + public int hgetbits(int N) { + totbit += N; + + int val = 0; + + int pos = buf_byte_idx; + if (pos + N < BUFSIZE) { + while (N-- > 0) { + val <<= 1; + val |= ((buf[pos++] != 0) ? 1 : 0); + } + } else { + while (N-- > 0) { + val <<= 1; + val |= ((buf[pos] != 0) ? 1 : 0); + pos = (pos + 1) & BUFSIZE_MASK; + } + } + buf_byte_idx = pos; + return val; + } + + /** + * Returns next bit from reserve. + * + * @return 0 if next bit is reset, or 1 if next bit is set. + */ + public int hget1bit() { + totbit++; + int val = buf[buf_byte_idx]; + buf_byte_idx = (buf_byte_idx + 1) & BUFSIZE_MASK; + return val; + } + + /** + * Write 8 bits into the bit stream. + */ + public void hputbuf(int val) { + int ofs = offset; + buf[ofs++] = val & 0x80; + buf[ofs++] = val & 0x40; + buf[ofs++] = val & 0x20; + buf[ofs++] = val & 0x10; + buf[ofs++] = val & 0x08; + buf[ofs++] = val & 0x04; + buf[ofs++] = val & 0x02; + buf[ofs++] = val & 0x01; + + if (ofs == BUFSIZE) + offset = 0; + else + offset = ofs; + } + + /** + * Rewind N bits in Stream. + */ + public void rewindNbits(int N) { + totbit -= N; + buf_byte_idx -= N; + if (buf_byte_idx < 0) + buf_byte_idx += BUFSIZE; + } + + /** + * Rewind N bytes in Stream. + */ + public void rewindNbytes(int N) { + int bits = (N << 3); + totbit -= bits; + buf_byte_idx -= bits; + if (buf_byte_idx < 0) + buf_byte_idx += BUFSIZE; + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Bitstream.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Bitstream.java new file mode 100644 index 000000000..9f884c59b --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Bitstream.java @@ -0,0 +1,572 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 11/17/04 Uncomplete frames discarded. E.B, javalayer@javazoom.net + * + * 12/05/03 ID3v2 tag returned. E.B, javalayer@javazoom.net + * + * 12/12/99 Based on Ibitstream. Exceptions thrown on errors, + * Temporary removed seek functionality. mdm@techie.com + * + * 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net + * + * 04/14/97 : Added function prototypes for new syncing and seeking + * mechanisms. Also made this file portable. Changes made by Jeff Tsay + * + * @(#) ibitstream.h 1.5, last edit: 6/15/94 16:55:34 + * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de) + * @(#) Berlin University of Technology + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PushbackInputStream; + + +/** + * The Bistream class is responsible for parsing + * an MPEG audio bitstream. + * + * REVIEW: much of the parsing currently occurs in the + * various decoders. This should be moved into this class and associated + * inner classes. + */ +public final class Bitstream implements BitstreamErrors { + + /** + * Synchronization control constant for the initial + * synchronization to the start of a frame. + */ + static byte INITIAL_SYNC = 0; + + /** + * Synchronization control constant for non-initial frame + * synchronizations. + */ + static byte STRICT_SYNC = 1; + + /** + * Maximum size of the frame buffer. + *

+ * max. 1730 bytes per frame: 144 * 384kbit/s / 32000 Hz + 2 Bytes CRC + */ + private static final int BUFFER_INT_SIZE = 433; + + /** + * The frame buffer that holds the data for the current frame. + */ + private final int[] framebuffer = new int[BUFFER_INT_SIZE]; + + /** + * Number of valid bytes in the frame buffer. + */ + private int framesize; + + /** + * The bytes read from the stream. + */ + private byte[] frame_bytes = new byte[BUFFER_INT_SIZE * 4]; + + /** + * Index into framebuffer where the next bits are + * retrieved. + */ + private int wordpointer; + + /** + * Number (0-31, from MSB to LSB) of next bit for get_bits() + */ + private int bitindex; + + /** + * The current specified syncword + */ + private int syncword; + + /** + * Audio header position in stream. + */ + private int header_pos = 0; + + /** + * + */ + private boolean single_ch_mode; + + private final int[] bitmask = { + 0, // dummy + 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, + 0x000007FF, 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF + }; + + private final PushbackInputStream source; + + private final Header header = new Header(); + + private final byte[] syncBuf = new byte[4]; + + private Crc16[] crc = new Crc16[1]; + + private byte[] rawid3v2 = null; + + private boolean firstframe = true; + + /** + * Construct a IBitstream that reads data from a + * given InputStream. + * + * @param in The InputStream to read from. + */ + public Bitstream(InputStream in) { + if (in == null) + throw new NullPointerException("in"); + in = new BufferedInputStream(in); + loadID3v2(in); + firstframe = true; + source = new PushbackInputStream(in, BUFFER_INT_SIZE * 4); + + closeFrame(); + } + + /** + * Return position of the first audio header. + * + * @return size of ID3v2 tag frames. + */ + public int header_pos() { + return header_pos; + } + + /** + * Load ID3v2 frames. + * + * @param in MP3 InputStream. + * @author JavaZOOM + */ + private void loadID3v2(InputStream in) { + int size = -1; + try { + // Read ID3v2 header (10 bytes). + in.mark(10); + size = readID3v2Header(in); + header_pos = size; + } catch (IOException e) { + } finally { + try { + // Unread ID3v2 header (10 bytes). + in.reset(); + } catch (IOException e) { + } + } + // Load ID3v2 tags. + try { + if (size > 0) { + rawid3v2 = new byte[size]; + in.read(rawid3v2, 0, rawid3v2.length); + } + } catch (IOException e) { + } + } + + /** + * Parse ID3v2 tag header to find out size of ID3v2 frames. + * + * @param in MP3 InputStream + * @return size of ID3v2 frames + header + * @throws IOException + * @author JavaZOOM + */ + private int readID3v2Header(InputStream in) throws IOException { + byte[] id3header = new byte[4]; + int size = -10; + in.read(id3header, 0, 3); + // Look for ID3v2 + if ((id3header[0] == 'I') && (id3header[1] == 'D') && (id3header[2] == '3')) { + in.read(id3header, 0, 3); + @SuppressWarnings("unused") + int majorVersion = id3header[0]; + @SuppressWarnings("unused") + int revision = id3header[1]; + in.read(id3header, 0, 4); + size = (id3header[0] << 21) + (id3header[1] << 14) + (id3header[2] << 7) + (id3header[3]); + } + return (size + 10); + } + + /** + * Return raw ID3v2 frames + header. + * + * @return ID3v2 InputStream or null if ID3v2 frames are not available. + */ + public InputStream getRawID3v2() { + if (rawid3v2 == null) + return null; + else { + ByteArrayInputStream bain = new ByteArrayInputStream(rawid3v2); + return bain; + } + } + + /** + * Close the Bitstream. + * + * @throws BitstreamException + */ + public void close() throws BitstreamException { + try { + source.close(); + } catch (IOException ex) { + throw newBitstreamException(STREAM_ERROR, ex); + } + } + + /** + * Reads and parses the next frame from the input source. + * + * @return the Header describing details of the frame read, + * or null if the end of the stream has been reached. + */ + public Header readFrame() throws BitstreamException { + Header result = null; + try { + result = readNextFrame(); + // E.B, Parse VBR (if any) first frame. + if (firstframe) { + result.parseVBR(frame_bytes); + firstframe = false; + } + } catch (BitstreamException ex) { + if ((ex.getErrorCode() == INVALIDFRAME)) { + // Try to skip this frame. + //System.out.println("INVALIDFRAME"); + try { + closeFrame(); + result = readNextFrame(); + } catch (BitstreamException e) { + if ((e.getErrorCode() != STREAM_EOF)) { + // wrap original exception so stack trace is maintained. + throw newBitstreamException(e.getErrorCode(), e); + } + } + } else if ((ex.getErrorCode() != STREAM_EOF)) { + // wrap original exception so stack trace is maintained. + throw newBitstreamException(ex.getErrorCode(), ex); + } + } + return result; + } + + /** + * Read next MP3 frame. + * + * @return MP3 frame header. + * @throws BitstreamException + */ + private Header readNextFrame() throws BitstreamException { + if (framesize == -1) { + nextFrame(); + } + return header; + } + + /** + * Read next MP3 frame. + * + * @throws BitstreamException + */ + private void nextFrame() throws BitstreamException { + // entire frame is read by the header class. + header.read_header(this, crc); + } + + /** + * Unreads the bytes read from the frame. + * + * @throws BitstreamException + */ + // REVIEW: add new error codes for this. + public void unreadFrame() throws BitstreamException { + if (wordpointer == -1 && bitindex == -1 && (framesize > 0)) { + try { + source.unread(frame_bytes, 0, framesize); + } catch (IOException ex) { + throw newBitstreamException(STREAM_ERROR); + } + } + } + + /** + * Close MP3 frame. + */ + public void closeFrame() { + framesize = -1; + wordpointer = -1; + bitindex = -1; + } + + /** + * Determines if the next 4 bytes of the stream represent a + * frame header. + */ + public boolean isSyncCurrentPosition(int syncmode) throws BitstreamException { + int read = readBytes(syncBuf, 0, 4); + int headerString = ((syncBuf[0] << 24) & 0xFF000000) | ((syncBuf[1] << 16) & 0x00FF0000) + | ((syncBuf[2] << 8) & 0x0000FF00) | ((syncBuf[3] << 0) & 0x000000FF); + + try { + source.unread(syncBuf, 0, read); + } catch (IOException ex) { + } + + boolean sync = false; + switch (read) { + case 0: + sync = true; + break; + case 4: + sync = isSyncMark(headerString, syncmode, syncword); + break; + } + + return sync; + } + + // REVIEW: this class should provide inner classes to + // parse the frame contents. Eventually, readBits will + // be removed. + public int readBits(int n) { + return get_bits(n); + } + + public int readCheckedBits(int n) { + // REVIEW: implement CRC check. + return get_bits(n); + } + + BitstreamException newBitstreamException(int errorcode) { + return new BitstreamException(errorcode, null); + } + + BitstreamException newBitstreamException(int errorcode, Throwable throwable) { + return new BitstreamException(errorcode, throwable); + } + + /** + * Get next 32 bits from bitstream. + * They are stored in the headerString. + * syncMode allows Synchro flag ID + * The returned value is False at the end of stream. + */ + int syncHeader(byte syncMode) throws BitstreamException { + boolean sync; + int headerString; + // read additional 2 bytes + int bytesRead = readBytes(syncBuf, 0, 3); + + if (bytesRead != 3) + throw newBitstreamException(STREAM_EOF, null); + + headerString = ((syncBuf[0] << 16) & 0x00FF0000) | ((syncBuf[1] << 8) & 0x0000FF00) | ((syncBuf[2] << 0) & 0x000000FF); + + do { + headerString <<= 8; + + if (readBytes(syncBuf, 3, 1) != 1) + throw newBitstreamException(STREAM_EOF, null); + + headerString |= (syncBuf[3] & 0x000000FF); + + sync = isSyncMark(headerString, syncMode, syncword); + } while (!sync); + + return headerString; + } + + public boolean isSyncMark(int headerstring, int syncmode, int word) { + boolean sync = false; + + if (syncmode == INITIAL_SYNC) { + //sync = ((headerstring & 0xFFF00000) == 0xFFF00000); + sync = ((headerstring & 0xFFE00000) == 0xFFE00000); // SZD: MPEG 2.5 + } else { + sync = ((headerstring & 0xFFF80C00) == word) && (((headerstring & 0x000000C0) == 0x000000C0) == single_ch_mode); + } + + // filter out invalid sample rate + if (sync) + sync = (((headerstring >>> 10) & 3) != 3); + // filter out invalid layer + if (sync) + sync = (((headerstring >>> 17) & 3) != 0); + // filter out invalid version + if (sync) + sync = (((headerstring >>> 19) & 3) != 1); + + return sync; + } + + /** + * Reads the data for the next frame. The frame is not parsed + * until parse frame is called. + */ + int read_frame_data(int bytesize) throws BitstreamException { + int numread = 0; + numread = readFully(frame_bytes, 0, bytesize); + framesize = bytesize; + wordpointer = -1; + bitindex = -1; + return numread; + } + + /** + * Parses the data previously read with read_frame_data(). + */ + void parse_frame() throws BitstreamException { + // Convert Bytes read to int + int b = 0; + byte[] byteread = frame_bytes; + int bytesize = framesize; + + // Check ID3v1 TAG (True only if last frame). + + for (int k = 0; k < bytesize; k = k + 4) { + @SuppressWarnings("unused") + int convert = 0; + byte b0 = 0; + byte b1 = 0; + byte b2 = 0; + byte b3 = 0; + b0 = byteread[k]; + if (k + 1 < bytesize) + b1 = byteread[k + 1]; + if (k + 2 < bytesize) + b2 = byteread[k + 2]; + if (k + 3 < bytesize) + b3 = byteread[k + 3]; + framebuffer[b++] = ((b0 << 24) & 0xFF000000) | ((b1 << 16) & 0x00FF0000) | ((b2 << 8) & 0x0000FF00) + | (b3 & 0x000000FF); + } + wordpointer = 0; + bitindex = 0; + } + + /** + * Read bits from buffer into the lower bits of an unsigned int. + * The LSB contains the latest read bit of the stream. + * (1 <= number_of_bits <= 16) + */ + public int get_bits(int number_of_bits) { + int returnvalue = 0; + int sum = bitindex + number_of_bits; + + // E.B + // There is a problem here, wordpointer could be -1 ?! + if (wordpointer < 0) + wordpointer = 0; + // E.B : End. + + if (sum <= 32) { + // all bits contained in *wordpointer + returnvalue = (framebuffer[wordpointer] >>> (32 - sum)) & bitmask[number_of_bits]; + if ((bitindex += number_of_bits) == 32) { + bitindex = 0; + wordpointer++; // added by me! + } + return returnvalue; + } + + int Right = (framebuffer[wordpointer] & 0x0000FFFF); + wordpointer++; + int Left = (framebuffer[wordpointer] & 0xFFFF0000); + returnvalue = ((Right << 16) & 0xFFFF0000) | ((Left >>> 16) & 0x0000FFFF); + + returnvalue >>>= 48 - sum; + returnvalue &= bitmask[number_of_bits]; + bitindex = sum - 32; + return returnvalue; + } + + /** + * Set the word we want to sync the header to. + * In Big-Endian byte order + */ + void set_syncword(int syncword0) { + syncword = syncword0 & 0xFFFFFF3F; + single_ch_mode = ((syncword0 & 0x000000C0) == 0x000000C0); + } + + /** + * Reads the exact number of bytes from the source + * input stream into a byte array. + * + * @param b The byte array to read the specified number + * of bytes into. + * @param offs The index in the array where the first byte + * read should be stored. + * @param len the number of bytes to read. + * @throws BitstreamException is thrown if the specified + * number of bytes could not be read from the stream. + */ + private int readFully(byte[] b, int offs, int len) throws BitstreamException { + int nRead = 0; + try { + while (len > 0) { + int bytesread = source.read(b, offs, len); + if (bytesread == -1) { + while (len-- > 0) { + b[offs++] = 0; + } + break; + //throw newBitstreamException(UNEXPECTED_EOF, new EOFException()); + } + nRead = nRead + bytesread; + offs += bytesread; + len -= bytesread; + } + } catch (IOException ex) { + throw newBitstreamException(STREAM_ERROR, ex); + } + return nRead; + } + + /** + * Similar to readFully, but doesn't throw exception when + * EOF is reached. + */ + private int readBytes(byte[] b, int offs, int len) throws BitstreamException { + int totalBytesRead = 0; + try { + while (len > 0) { + int bytesread = source.read(b, offs, len); + if (bytesread == -1) { + break; + } + totalBytesRead += bytesread; + offs += bytesread; + len -= bytesread; + } + } catch (IOException ex) { + throw newBitstreamException(STREAM_ERROR, ex); + } + return totalBytesRead; + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/BitstreamErrors.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/BitstreamErrors.java new file mode 100644 index 000000000..f13bbc59b --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/BitstreamErrors.java @@ -0,0 +1,68 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 11/17/04 INVALIDFRAME code added. javalayer@javazoom.net + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * This interface describes all error codes that can be thrown + * in BistreamExceptions. + * + * @author MDM 12/12/99 + * @see BitstreamException + * @since 0.0.6 + */ +public interface BitstreamErrors extends JavaLayerErrors { + + /** + * An undeterminable error occurred. + */ + int UNKNOWN_ERROR = BITSTREAM_ERROR + 0; + + /** + * The header describes an unknown sample rate. + */ + int UNKNOWN_SAMPLE_RATE = BITSTREAM_ERROR + 1; + + /** + * A problem occurred reading from the stream. + */ + int STREAM_ERROR = BITSTREAM_ERROR + 2; + + /** + * The end of the stream was reached prematurely. + */ + int UNEXPECTED_EOF = BITSTREAM_ERROR + 3; + + /** + * The end of the stream was reached. + */ + int STREAM_EOF = BITSTREAM_ERROR + 4; + + /** + * Frame data are missing. + */ + int INVALIDFRAME = BITSTREAM_ERROR + 5; + + /** + * + */ + int BITSTREAM_LAST = 0x1ff; +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/BitstreamException.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/BitstreamException.java new file mode 100644 index 000000000..992c2ce03 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/BitstreamException.java @@ -0,0 +1,62 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Instances of BitstreamException are thrown + * when operations on a Bitstream fail. + *

+ * The exception provides details of the exception condition + * in two ways: + *

  1. + * as an error-code describing the nature of the error + *


  2. + * as the Throwable instance, if any, that was thrown + * indicating that an exceptional condition has occurred. + *

+ * + * @author MDM 12/12/99 + * @since 0.0.6 + */ +public class BitstreamException extends JavaLayerException + implements BitstreamErrors { + private int errorCode = UNKNOWN_ERROR; + + public BitstreamException(String msg, Throwable t) { + super(msg, t); + } + + public BitstreamException(int errorCode, Throwable t) { + this(getErrorString(errorCode), t); + this.errorCode = errorCode; + } + + public int getErrorCode() { + return errorCode; + } + + static public String getErrorString(int errorcode) { + // REVIEW: use resource bundle to map error codes + // to locale-sensitive strings. + + return "Bitstream errorCode " + Integer.toHexString(errorcode); + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Control.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Control.java new file mode 100644 index 000000000..b0ecaf802 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Control.java @@ -0,0 +1,54 @@ +/* + * 11/19/04 1.0 moved to LGPL. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Work in progress. + */ +public interface Control { + + /** + * Starts playback of the media presented by this control. + */ + void start(); + + /** + * Stops playback of the media presented by this control. + */ + void stop(); + + boolean isPlaying(); + + void pause(); + + boolean isRandomAccess(); + + /** + * Retrieves the current position. + */ + double getPosition(); + + /** + * + */ + void setPosition(double d); + + +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Crc16.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Crc16.java new file mode 100644 index 000000000..bbddf3875 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Crc16.java @@ -0,0 +1,66 @@ +/* + * 11/19/04 : 1.0 moved to LGPL. + * + * 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net + * + * @(#) crc.h 1.5, last edit: 6/15/94 16:55:32 + * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de) + * @(#) Berlin University of Technology + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * 16-Bit CRC checksum + */ +public final class Crc16 { + + private static final short polynomial = (short) 0x8005; + private short crc; + + /** + * Dummy Constructor + */ + public Crc16() { + crc = (short) 0xFFFF; + } + + /** + * Feed a bitstring to the crc calculation (0 < length <= 32). + */ + public void add_bits(int bitstring, int length) { + int bitmask = 1 << (length - 1); + do + if (((crc & 0x8000) == 0) ^ ((bitstring & bitmask) == 0)) { + crc <<= 1; + crc ^= polynomial; + } else + crc <<= 1; + while ((bitmask >>>= 1) != 0); + } + + /** + * Return the calculated checksum. + * Erase it for next calls to add_bits(). + */ + public short checksum() { + short sum = crc; + crc = (short) 0xFFFF; + return sum; + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Decoder.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Decoder.java new file mode 100644 index 000000000..556d8aa40 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Decoder.java @@ -0,0 +1,317 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 01/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * The Decoder class encapsulates the details of + * decoding an MPEG audio frame. + * + * @author MDM + * @version 0.0.7 12/12/99 + * @since 0.0.5 + */ +public class Decoder implements DecoderErrors { + static private final Params DEFAULT_PARAMS = new Params(); + + /** + * The Obuffer instance that will receive the decoded + * PCM samples. + */ + private Obuffer output; + + /** + * Synthesis filter for the left channel. + */ + private SynthesisFilter filter1; + + /** + * Sythesis filter for the right channel. + */ + private SynthesisFilter filter2; + + /** + * The decoder used to decode layer III frames. + */ + private LayerIIIDecoder l3decoder; + private LayerIIDecoder l2decoder; + private LayerIDecoder l1decoder; + + private int outputFrequency; + private int outputChannels; + + private Equalizer equalizer = new Equalizer(); + + private Params params; + + private boolean initialized; + + /** + * Creates a new Decoder instance with default + * parameters. + */ + public Decoder() { + this(null); + } + + /** + * Creates a new Decoder instance with default + * parameters. + * + * @param params The Params instance that describes + * the customizable aspects of the decoder. + */ + public Decoder(Params params) { + if (params == null) + params = DEFAULT_PARAMS; + + this.params = params; + + Equalizer eq = this.params.getInitialEqualizerSettings(); + if (eq != null) { + equalizer.setFrom(eq); + } + } + + static public Params getDefaultParams() { + return (Params) DEFAULT_PARAMS.clone(); + } + + public void setEqualizer(Equalizer eq) { + if (eq == null) + eq = Equalizer.PASS_THRU_EQ; + + equalizer.setFrom(eq); + + float[] factors = equalizer.getBandFactors(); + + if (filter1 != null) + filter1.setEQ(factors); + + if (filter2 != null) + filter2.setEQ(factors); + } + + /** + * Decodes one frame from an MPEG audio bitstream. + * + * @param header The header describing the frame to decode. + * @param stream The bit stream that provides the bits for te body of the frame. + * @return A SampleBuffer containing the decoded samples. + */ + public Obuffer decodeFrame(Header header, Bitstream stream) + throws DecoderException { + if (!initialized) { + initialize(header); + } + + int layer = header.layer(); + + output.clear_buffer(); + + FrameDecoder decoder = retrieveDecoder(header, stream, layer); + + decoder.decodeFrame(); + + output.write_buffer(1); + + return output; + } + + /** + * Changes the output buffer. This will take effect the next time + * decodeFrame() is called. + */ + public void setOutputBuffer(Obuffer out) { + output = out; + } + + /** + * Retrieves the sample frequency of the PCM samples output + * by this decoder. This typically corresponds to the sample + * rate encoded in the MPEG audio stream. + * + * @return the sample rate (in Hz) of the samples written to the + * output buffer when decoding. + */ + public int getOutputFrequency() { + return outputFrequency; + } + + /** + * Retrieves the number of channels of PCM samples output by + * this decoder. This usually corresponds to the number of + * channels in the MPEG audio stream, although it may differ. + * + * @return The number of output channels in the decoded samples: 1 + * for mono, or 2 for stereo. + */ + public int getOutputChannels() { + return outputChannels; + } + + /** + * Retrieves the maximum number of samples that will be written to + * the output buffer when one frame is decoded. This can be used to + * help calculate the size of other buffers whose size is based upon + * the number of samples written to the output buffer. NB: this is + * an upper bound and fewer samples may actually be written, depending + * upon the sample rate and number of channels. + * + * @return The maximum number of samples that are written to the + * output buffer when decoding a single frame of MPEG audio. + */ + public int getOutputBlockSize() { + return Obuffer.OBUFFERSIZE; + } + + protected DecoderException newDecoderException(int errorCode) { + return new DecoderException(errorCode, null); + } + + protected DecoderException newDecoderException(int errorCode, Throwable throwable) { + return new DecoderException(errorCode, throwable); + } + + protected FrameDecoder retrieveDecoder(Header header, Bitstream stream, int layer) + throws DecoderException { + FrameDecoder decoder = null; + + // REVIEW: allow channel output selection type + // (LEFT, RIGHT, BOTH, DOWNMIX) + switch (layer) { + case 3: + if (l3decoder == null) { + l3decoder = new LayerIIIDecoder(stream, + header, filter1, filter2, + output, OutputChannels.BOTH_CHANNELS); + } + + decoder = l3decoder; + break; + case 2: + if (l2decoder == null) { + l2decoder = new LayerIIDecoder(); + l2decoder.create(stream, + header, filter1, filter2, + output, OutputChannels.BOTH_CHANNELS); + } + decoder = l2decoder; + break; + case 1: + if (l1decoder == null) { + l1decoder = new LayerIDecoder(); + l1decoder.create(stream, + header, filter1, filter2, + output, OutputChannels.BOTH_CHANNELS); + } + decoder = l1decoder; + break; + } + + if (decoder == null) { + throw newDecoderException(UNSUPPORTED_LAYER, null); + } + + return decoder; + } + + private void initialize(Header header) + throws DecoderException { + + // REVIEW: allow customizable scale factor + float scalefactor = 32700.0f; + + int mode = header.mode(); + @SuppressWarnings("unused") + int layer = header.layer(); + int channels = mode == Header.SINGLE_CHANNEL ? 1 : 2; + + + // set up output buffer if not set up by client. + if (output == null) + output = new SampleBuffer(header.frequency(), channels); + + float[] factors = equalizer.getBandFactors(); + filter1 = new SynthesisFilter(0, scalefactor, factors); + + // REVIEW: allow mono output for stereo + if (channels == 2) + filter2 = new SynthesisFilter(1, scalefactor, factors); + + outputChannels = channels; + outputFrequency = header.frequency(); + + initialized = true; + } + + /** + * The Params class presents the customizable + * aspects of the decoder. + *

+ * Instances of this class are not thread safe. + */ + public static class Params implements Cloneable { + private OutputChannels outputChannels = OutputChannels.BOTH; + + private Equalizer equalizer = new Equalizer(); + + public Params() { + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException ex) { + throw new InternalError(this + ": " + ex); + } + } + + public void setOutputChannels(OutputChannels out) { + if (out == null) + throw new NullPointerException("out"); + + outputChannels = out; + } + + public OutputChannels getOutputChannels() { + return outputChannels; + } + + /** + * Retrieves the equalizer settings that the decoder's equalizer + * will be initialized from. + *

+ * The Equalizer instance returned + * cannot be changed in real time to affect the + * decoder output as it is used only to initialize the decoders + * EQ settings. To affect the decoder's output in realtime, + * use the Equalizer returned from the getEqualizer() method on + * the decoder. + * + * @return The Equalizer used to initialize the + * EQ settings of the decoder. + */ + public Equalizer getInitialEqualizerSettings() { + return equalizer; + } + } +} + diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/DecoderErrors.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/DecoderErrors.java new file mode 100644 index 000000000..866bb80c3 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/DecoderErrors.java @@ -0,0 +1,43 @@ +/* + * 09/26/08 throw exception on subbband alloc error: Christopher G. Jennings (cjennings@acm.org) + * 11/19/04 1.0 moved to LGPL. + * 01/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * This interface provides constants describing the error + * codes used by the Decoder to indicate errors. + * + * @author MDM + */ +public interface DecoderErrors extends JavaLayerErrors { + + int UNKNOWN_ERROR = DECODER_ERROR + 0; + + /** + * Layer not supported by the decoder. + */ + int UNSUPPORTED_LAYER = DECODER_ERROR + 1; + + /** + * Illegal allocation in subband layer. Indicates a corrupt stream. + */ + int ILLEGAL_SUBBAND_ALLOCATION = DECODER_ERROR + 2; +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/DecoderException.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/DecoderException.java new file mode 100644 index 000000000..411d3c4f8 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/DecoderException.java @@ -0,0 +1,54 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 01/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * The DecoderException represents the class of + * errors that can occur when decoding MPEG audio. + * + * @author MDM + */ +public class DecoderException extends JavaLayerException + implements DecoderErrors { + + private int errorCode = UNKNOWN_ERROR; + + public DecoderException(String msg, Throwable t) { + super(msg, t); + } + + public DecoderException(int errorCode, Throwable t) { + this(getErrorString(errorCode), t); + this.errorCode = errorCode; + } + + public int getErrorCode() { + return errorCode; + } + + static public String getErrorString(int errorcode) { + // REVIEW: use resource file to map error codes + // to locale-sensitive strings. + + return "Decoder errorCode " + Integer.toHexString(errorcode); + } +} + diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Equalizer.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Equalizer.java new file mode 100644 index 000000000..ab691a451 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Equalizer.java @@ -0,0 +1,184 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * The Equalizer class can be used to specify + * equalization settings for the MPEG audio decoder. + *

+ * The equalizer consists of 32 band-pass filters. + * Each band of the equalizer can take on a fractional value between + * -1.0 and +1.0. + * At -1.0, the input signal is attenuated by 6dB, at +1.0 the signal is + * amplified by 6dB. + * + * @author MDM + * @see Decoder + */ +public final class Equalizer { + + /** + * Equalizer setting to denote that a given band will not be + * present in the output signal. + */ + static public final float BAND_NOT_PRESENT = Float.NEGATIVE_INFINITY; + + static public final Equalizer PASS_THRU_EQ = new Equalizer(); + + private static final int BANDS = 32; + + private final float[] settings = new float[BANDS]; + + /** + * Creates a new Equalizer instance. + */ + public Equalizer() { + } + + public Equalizer(float[] settings) { + setFrom(settings); + } + + public Equalizer(EQFunction eq) { + setFrom(eq); + } + + public void setFrom(float[] eq) { + reset(); + int max = Math.min(eq.length, BANDS); + + for (int i = 0; i < max; i++) { + settings[i] = limit(eq[i]); + } + } + + public void setFrom(EQFunction eq) { + reset(); + int max = BANDS; + + for (int i = 0; i < max; i++) { + settings[i] = limit(eq.getBand(i)); + } + } + + /** + * Sets the bands of this equalizer to the value the bands of + * another equalizer. Bands that are not present in both equalizers are ignored. + */ + public void setFrom(Equalizer eq) { + if (eq != this) { + setFrom(eq.settings); + } + } + + /** + * Sets all bands to 0.0 + */ + public void reset() { + for (int i = 0; i < BANDS; i++) { + settings[i] = 0.0f; + } + } + + /** + * Retrieves the number of bands present in this equalizer. + */ + public int getBandCount() { + return settings.length; + } + + public float setBand(int band, float neweq) { + float eq = 0.0f; + + if ((band >= 0) && (band < BANDS)) { + eq = settings[band]; + settings[band] = limit(neweq); + } + + return eq; + } + + /** + * Retrieves the eq setting for a given band. + */ + public float getBand(int band) { + float eq = 0.0f; + + if ((band >= 0) && (band < BANDS)) { + eq = settings[band]; + } + + return eq; + } + + private float limit(float eq) { + if (eq == BAND_NOT_PRESENT) + return eq; + if (eq > 1.0f) + return 1.0f; + return Math.max(eq, -1.0f); + } + + /** + * Retrieves an array of floats whose values represent a + * scaling factor that can be applied to linear samples + * in each band to provide the equalization represented by + * this instance. + * + * @return an array of factors that can be applied to the + * subbands. + */ + float[] getBandFactors() { + float[] factors = new float[BANDS]; + for (int i = 0, maxCount = BANDS; i < maxCount; i++) { + factors[i] = getBandFactor(settings[i]); + } + + return factors; + } + + /** + * Converts an equalizer band setting to a sample factor. + * The factor is determined by the function f = 2^n where + * n is the equalizer band setting in the range [-1.0,1.0]. + */ + float getBandFactor(float eq) { + if (eq == BAND_NOT_PRESENT) + return 0.0f; + + float f = (float) Math.pow(2.0, eq); + return f; + } + + static abstract public class EQFunction { + /** + * Returns the setting of a band in the equalizer. + * + * @param band The index of the band to retrieve the setting + * for. + * @return the setting of the specified band. This is a value between + * -1 and +1. + */ + public float getBand(int band) { + return 0.0f; + } + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/FrameDecoder.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/FrameDecoder.java new file mode 100644 index 000000000..62423f174 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/FrameDecoder.java @@ -0,0 +1,38 @@ +/* + * 09/26/08 throw exception on subbband alloc error: Christopher G. Jennings (cjennings@acm.org) + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Implementations of FrameDecoder are responsible for decoding + * an MPEG audio frame. + *

+ * REVIEW: the interface currently is too thin. There should be + * methods to specify the output buffer, the synthesis filters and + * possibly other objects used by the decoder. + */ +public interface FrameDecoder { + + /** + * Decodes one frame of MPEG audio. + */ + void decodeFrame() throws DecoderException; +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Header.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Header.java new file mode 100644 index 000000000..a2fd9d8d4 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Header.java @@ -0,0 +1,727 @@ +/* + * 11/19/04 : 1.0 moved to LGPL. + * VBRI header support added, E.B javalayer@javazoom.net + * + * 12/04/03 : VBR (XING) header support added, E.B javalayer@javazoom.net + * + * 02/13/99 : Java Conversion by JavaZOOM , E.B javalayer@javazoom.net + * + * Declarations for MPEG header class + * A few layer III, MPEG-2 LSF, and seeking modifications made by Jeff Tsay. + * Last modified : 04/19/97 + * + * @(#) header.h 1.7, last edit: 6/15/94 16:55:33 + * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de) + * @(#) Berlin University of Technology + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Class for extracting information from a frame header. + */ +public final class Header { + + public static final int[][] frequencies ={ + {22050, 24000, 16000, 1}, + {44100, 48000, 32000, 1}, + {11025, 12000, 8000, 1} // SZD: MPEG25 + }; + + /** + * Constant for MPEG-2 LSF version + */ + public static final int MPEG2_LSF = 0; + public static final int MPEG25_LSF = 2; // SZD + + /** + * Constant for MPEG-1 version + */ + public static final int MPEG1 = 1; + + public static final int STEREO = 0; + public static final int JOINT_STEREO = 1; + public static final int DUAL_CHANNEL = 2; + public static final int SINGLE_CHANNEL = 3; + public static final int FOURTYFOUR_POINT_ONE = 0; + public static final int FOURTYEIGHT = 1; + public static final int THIRTYTWO = 2; + + private int h_layer, h_protection_bit, h_bitrate_index, + h_padding_bit, h_mode_extension; + private int h_version; + private int h_mode; + private int h_sample_frequency; + private int h_number_of_subbands, h_intensity_stereo_bound; + private boolean h_copyright, h_original; + // VBR support added by E.B + private static final double[] h_vbr_time_per_frame = {-1, 384, 1152, 1152}; + private boolean h_vbr; + private int h_vbr_frames; + private int h_vbr_scale; + private int h_vbr_bytes; + private byte[] h_vbr_toc; + + private byte syncmode = Bitstream.INITIAL_SYNC; + private Crc16 crc; + + public short checksum; + public int framesize; + public int nSlots; + + private int _headerstring = -1; // E.B + + Header() { + } + + public String toString() { + StringBuilder buffer = new StringBuilder(200); + buffer.append("Layer "); + buffer.append(layer_string()); + buffer.append(" frame "); + buffer.append(mode_string()); + buffer.append(' '); + buffer.append(version_string()); + if (!checksums()) + buffer.append(" no"); + buffer.append(" checksums"); + buffer.append(' '); + buffer.append(sample_frequency_string()); + buffer.append(','); + buffer.append(' '); + buffer.append(bitrate_string()); + + return buffer.toString(); + } + + /** + * Read a 32-bit header from the bitstream. + */ + void read_header(Bitstream stream, Crc16[] crcp) throws BitstreamException { + int headerString; + int channelBitrate; + boolean sync = false; + do { + headerString = stream.syncHeader(syncmode); + _headerstring = headerString; // E.B + if (syncmode == Bitstream.INITIAL_SYNC) { + h_version = ((headerString >>> 19) & 1); + if (((headerString >>> 20) & 1) == 0) // SZD: MPEG2.5 detection + if (h_version == MPEG2_LSF) + h_version = MPEG25_LSF; + else + throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR); + if ((h_sample_frequency = ((headerString >>> 10) & 3)) == 3) { + throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR); + } + } + h_layer = 4 - (headerString >>> 17) & 3; + h_protection_bit = (headerString >>> 16) & 1; + h_bitrate_index = (headerString >>> 12) & 0xF; + h_padding_bit = (headerString >>> 9) & 1; + h_mode = ((headerString >>> 6) & 3); + h_mode_extension = (headerString >>> 4) & 3; + if (h_mode == JOINT_STEREO) + h_intensity_stereo_bound = (h_mode_extension << 2) + 4; + else + h_intensity_stereo_bound = 0; // should never be used + if (((headerString >>> 3) & 1) == 1) + h_copyright = true; + if (((headerString >>> 2) & 1) == 1) + h_original = true; + // calculate number of subbands: + if (h_layer == 1) + h_number_of_subbands = 32; + else { + channelBitrate = h_bitrate_index; + // calculate bitrate per channel: + if (h_mode != SINGLE_CHANNEL) + if (channelBitrate == 4) + channelBitrate = 1; + else + channelBitrate -= 4; + if ((channelBitrate == 1) || (channelBitrate == 2)) + if (h_sample_frequency == THIRTYTWO) + h_number_of_subbands = 12; + else + h_number_of_subbands = 8; + else if ((h_sample_frequency == FOURTYEIGHT) || ((channelBitrate >= 3) && (channelBitrate <= 5))) + h_number_of_subbands = 27; + else + h_number_of_subbands = 30; + } + if (h_intensity_stereo_bound > h_number_of_subbands) + h_intensity_stereo_bound = h_number_of_subbands; + // calculate framesize and nSlots + calculate_framesize(); + // read framedata: + int framesizeloaded = stream.read_frame_data(framesize); + if ((framesize >= 0) && (framesizeloaded != framesize)) { + // Data loaded does not match to expected framesize, + // it might be an ID3v1 TAG. (Fix 11/17/04). + throw stream.newBitstreamException(Bitstream.INVALIDFRAME); + } + if (stream.isSyncCurrentPosition(syncmode)) { + if (syncmode == Bitstream.INITIAL_SYNC) { + syncmode = Bitstream.STRICT_SYNC; + stream.set_syncword(headerString & 0xFFF80CC0); + } + sync = true; + } else { + stream.unreadFrame(); + } + } + while (!sync); + stream.parse_frame(); + if (h_protection_bit == 0) { + // frame contains a crc checksum + checksum = (short) stream.get_bits(16); + if (crc == null) + crc = new Crc16(); + crc.add_bits(headerString, 16); + crcp[0] = crc; + } else + crcp[0] = null; + if (h_sample_frequency == FOURTYFOUR_POINT_ONE) { + } + } + + /** + * Parse frame to extract optionnal VBR frame. + * + * @param firstFrame + * @author E.B (javalayer@javazoom.net) + */ + void parseVBR(byte[] firstFrame) throws BitstreamException { + // Trying Xing header. + String xing = "Xing"; + byte[] tmp = new byte[4]; + int offset = 0; + // Compute "Xing" offset depending on MPEG version and channels. + if (h_version == MPEG1) { + if (h_mode == SINGLE_CHANNEL) offset = 21 - 4; + else offset = 36 - 4; + } else { + if (h_mode == SINGLE_CHANNEL) offset = 13 - 4; + else offset = 21 - 4; + } + try { + System.arraycopy(firstFrame, offset, tmp, 0, 4); + // Is "Xing" ? + if (xing.equals(new String(tmp))) { + //Yes. + h_vbr = true; + h_vbr_frames = -1; + h_vbr_bytes = -1; + h_vbr_scale = -1; + h_vbr_toc = new byte[100]; + + int length = 4; + // Read flags. + byte[] flags = new byte[4]; + System.arraycopy(firstFrame, offset + length, flags, 0, flags.length); + length += flags.length; + // Read number of frames (if available). + if ((flags[3] & (byte) (1 << 0)) != 0) { + System.arraycopy(firstFrame, offset + length, tmp, 0, tmp.length); + h_vbr_frames = (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00 | tmp[3] & 0x000000FF; + length += 4; + } + // Read size (if available). + if ((flags[3] & (byte) (1 << 1)) != 0) { + System.arraycopy(firstFrame, offset + length, tmp, 0, tmp.length); + h_vbr_bytes = (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00 | tmp[3] & 0x000000FF; + length += 4; + } + // Read TOC (if available). + if ((flags[3] & (byte) (1 << 2)) != 0) { + System.arraycopy(firstFrame, offset + length, h_vbr_toc, 0, h_vbr_toc.length); + length += h_vbr_toc.length; + } + // Read scale (if available). + if ((flags[3] & (byte) (1 << 3)) != 0) { + System.arraycopy(firstFrame, offset + length, tmp, 0, tmp.length); + h_vbr_scale = (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00 | tmp[3] & 0x000000FF; + length += 4; + } + //System.out.println("VBR:"+xing+" Frames:"+ h_vbr_frames +" Size:"+h_vbr_bytes); + } + } catch (ArrayIndexOutOfBoundsException e) { + throw new BitstreamException("XingVBRHeader Corrupted", e); + } + + // Trying VBRI header. + String vbri = "VBRI"; + offset = 36 - 4; + try { + System.arraycopy(firstFrame, offset, tmp, 0, 4); + // Is "VBRI" ? + if (vbri.equals(new String(tmp))) { + //Yes. + h_vbr = true; + h_vbr_frames = -1; + h_vbr_bytes = -1; + h_vbr_scale = -1; + h_vbr_toc = new byte[100]; + // Bytes. + int length = 4 + 6; + System.arraycopy(firstFrame, offset + length, tmp, 0, tmp.length); + h_vbr_bytes = (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00 | tmp[3] & 0x000000FF; + length += 4; + // Frames. + System.arraycopy(firstFrame, offset + length, tmp, 0, tmp.length); + h_vbr_frames = (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00 | tmp[3] & 0x000000FF; + length += 4; + //System.out.println("VBR:"+vbri+" Frames:"+ h_vbr_frames +" Size:"+h_vbr_bytes); + // TOC + // TODO + } + } catch (ArrayIndexOutOfBoundsException e) { + throw new BitstreamException("VBRIVBRHeader Corrupted", e); + } + } + + // Functions to query header contents: + + /** + * Returns version. + */ + public int version() { + return h_version; + } + + /** + * Returns Layer ID. + */ + public int layer() { + return h_layer; + } + + /** + * Returns bitrate index. + */ + public int bitrate_index() { + return h_bitrate_index; + } + + /** + * Returns Sample Frequency. + */ + public int sample_frequency() { + return h_sample_frequency; + } + + /** + * Returns Frequency. + */ + public int frequency() { + return frequencies[h_version][h_sample_frequency]; + } + + /** + * Returns Mode. + */ + public int mode() { + return h_mode; + } + + /** + * Returns Protection bit. + */ + public boolean checksums() { + return h_protection_bit == 0; + } + + /** + * Returns Copyright. + */ + public boolean copyright() { + return h_copyright; + } + + /** + * Returns Original. + */ + public boolean original() { + return h_original; + } + + /** + * Return VBR. + * + * @return true if VBR header is found + */ + public boolean vbr() { + return h_vbr; + } + + /** + * Return VBR scale. + * + * @return scale of -1 if not available + */ + public int vbr_scale() { + return h_vbr_scale; + } + + /** + * Return VBR TOC. + * + * @return vbr toc ot null if not available + */ + public byte[] vbr_toc() { + return h_vbr_toc; + } + + /** + * Returns Checksum flag. + * Compares computed checksum with stream checksum. + */ + public boolean checksum_ok() { + return (checksum == crc.checksum()); + } + + // Seeking and layer III stuff + + /** + * Returns Layer III Padding bit. + */ + public boolean padding() { + return h_padding_bit != 0; + } + + /** + * Returns Slots. + */ + public int slots() { + return nSlots; + } + + /** + * Returns Mode Extension. + */ + public int mode_extension() { + return h_mode_extension; + } + + // E.B -> private to public + public static final int[][][] bitrates = { + {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000, + 112000, 128000, 144000, 160000, 176000, 192000, 224000, 256000, 0}, + {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, + 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}, + {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, + 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}}, + + {{0 /*free format*/, 32000, 64000, 96000, 128000, 160000, 192000, + 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000, 0}, + {0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000, + 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0}, + {0 /*free format*/, 32000, 40000, 48000, 56000, 64000, 80000, + 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0}}, + // SZD: MPEG2.5 + {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000, + 112000, 128000, 144000, 160000, 176000, 192000, 224000, 256000, 0}, + {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, + 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}, + {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, + 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}}, + }; + + + /** + * Calculate Frame size. + * Calculates framesize in bytes excluding header size. + *

+ * E.B -> private to public + */ + public int calculate_framesize() { + + if (h_layer == 1) { + framesize = (12 * bitrates[h_version][0][h_bitrate_index]) / + frequencies[h_version][h_sample_frequency]; + if (h_padding_bit != 0) framesize++; + framesize <<= 2; // one slot is 4 bytes long + nSlots = 0; + } else { + framesize = (144 * bitrates[h_version][h_layer - 1][h_bitrate_index]) / + frequencies[h_version][h_sample_frequency]; + if (h_version == MPEG2_LSF || h_version == MPEG25_LSF) framesize >>= 1; // SZD + if (h_padding_bit != 0) framesize++; + // Layer III slots + if (h_layer == 3) { + if (h_version == MPEG1) { + nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 17 : 32) // side info size + - ((h_protection_bit != 0) ? 0 : 2) // CRC size + - 4; // header size + } else { // MPEG-2 LSF, SZD: MPEG-2.5 LSF + nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 9 : 17) // side info size + - ((h_protection_bit != 0) ? 0 : 2) // CRC size + - 4; // header size + } + } else { + nSlots = 0; + } + } + framesize -= 4; // subtract header size + return framesize; + } + + /** + * Returns the maximum number of frames in the stream. + * + * @param streamSize stream size + * @return number of frames + */ + public int max_number_of_frames(int streamSize) { // E.B + if (h_vbr) return h_vbr_frames; + else { + if ((framesize + 4 - h_padding_bit) == 0) return 0; + else return (streamSize / (framesize + 4 - h_padding_bit)); + } + } + + /** + * Returns the maximum number of frames in the stream. + * + * @param streamSize stream size + * @return number of frames + */ + public int min_number_of_frames(int streamSize) { // E.B + if (h_vbr) return h_vbr_frames; + else { + if ((framesize + 5 - h_padding_bit) == 0) return 0; + else return (streamSize / (framesize + 5 - h_padding_bit)); + } + } + + /** + * Returns ms/frame. + * + * @return milliseconds per frame + */ + public float ms_per_frame() { // E.B + if (h_vbr) { + double tpf = h_vbr_time_per_frame[layer()] / frequency(); + if ((h_version == MPEG2_LSF) || (h_version == MPEG25_LSF)) tpf /= 2; + return ((float) (tpf * 1000)); + } else { + final float[][] ms_per_frame_array = { + {8.707483f, 8.0f, 12.0f}, + {26.12245f, 24.0f, 36.0f}, + {26.12245f, 24.0f, 36.0f} + }; + return (ms_per_frame_array[h_layer - 1][h_sample_frequency]); + } + } + + /** + * Returns total ms. + * + * @param streamSize stream size + * @return total milliseconds + */ + public float total_ms(int streamSize) { // E.B + return (max_number_of_frames(streamSize) * ms_per_frame()); + } + + /** + * Returns synchronized header. + */ + public int getSyncHeader() { // E.B + return _headerstring; + } + + // functions which return header information as strings: + + /** + * Return Layer version. + */ + public String layer_string() { + switch (h_layer) { + case 1: + return "I"; + case 2: + return "II"; + case 3: + return "III"; + } + return null; + } + + // E.B -> private to public + public static final String[][][] bitrate_str = { + {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", + "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", + "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", + "forbidden"}, + {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", + "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", + "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", + "forbidden"}, + {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", + "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", + "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", + "forbidden"}}, + + {{"free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s", + "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s", + "320 kbit/s", "352 kbit/s", "384 kbit/s", "416 kbit/s", "448 kbit/s", + "forbidden"}, + {"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", + "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", + "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", "384 kbit/s", + "forbidden"}, + {"free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s", + "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", + "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", + "forbidden"}}, + // SZD: MPEG2.5 + {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", + "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", + "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", + "forbidden"}, + {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", + "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", + "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", + "forbidden"}, + {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", + "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", + "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", + "forbidden"}}, + }; + + /** + * Return Bitrate. + * + * @return bitrate in bps + */ + public String bitrate_string() { + if (h_vbr) { + return bitrate() / 1000 + " kb/s"; + } else return bitrate_str[h_version][h_layer - 1][h_bitrate_index]; + } + + /** + * Return Bitrate. + * + * @return bitrate in bps and average bitrate for VBR header + */ + public int bitrate() { + if (h_vbr) { + return ((int) ((h_vbr_bytes * 8) / (ms_per_frame() * h_vbr_frames))) * 1000; + } else return bitrates[h_version][h_layer - 1][h_bitrate_index]; + } + + /** + * Return Instant Bitrate. + * Bitrate for VBR is not constant. + * + * @return bitrate in bps + */ + public int bitrate_instant() { + return bitrates[h_version][h_layer - 1][h_bitrate_index]; + } + + /** + * Returns Frequency + * + * @return frequency string in kHz + */ + public String sample_frequency_string() { + switch (h_sample_frequency) { + case THIRTYTWO: + if (h_version == MPEG1) + return "32 kHz"; + else if (h_version == MPEG2_LSF) + return "16 kHz"; + else // SZD + return "8 kHz"; + case FOURTYFOUR_POINT_ONE: + if (h_version == MPEG1) + return "44.1 kHz"; + else if (h_version == MPEG2_LSF) + return "22.05 kHz"; + else // SZD + return "11.025 kHz"; + case FOURTYEIGHT: + if (h_version == MPEG1) + return "48 kHz"; + else if (h_version == MPEG2_LSF) + return "24 kHz"; + else // SZD + return "12 kHz"; + } + return null; + } + + /** + * Returns Mode. + */ + public String mode_string() { + switch (h_mode) { + case STEREO: + return "Stereo"; + case JOINT_STEREO: + return "Joint stereo"; + case DUAL_CHANNEL: + return "Dual channel"; + case SINGLE_CHANNEL: + return "Single channel"; + } + return null; + } + + /** + * Returns Version. + * + * @return MPEG-1 or MPEG-2 LSF or MPEG-2.5 LSF + */ + public String version_string() { + switch (h_version) { + case MPEG1: + return "MPEG-1"; + case MPEG2_LSF: + return "MPEG-2 LSF"; + case MPEG25_LSF: // SZD + return "MPEG-2.5 LSF"; + } + return null; + } + + /** + * Returns the number of subbands in the current frame. + * + * @return number of subbands + */ + public int number_of_subbands() { + return h_number_of_subbands; + } + + /** + * Returns Intensity Stereo. + * (Layer II joint stereo only). + * Returns the number of subbands which are in stereo mode, + * subbands above that limit are in intensity stereo mode. + * + * @return intensity + */ + public int intensity_stereo_bound() { + return h_intensity_stereo_bound; + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/InputStreamSource.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/InputStreamSource.java new file mode 100644 index 000000000..dae0ce20a --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/InputStreamSource.java @@ -0,0 +1,72 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.IOException; +import java.io.InputStream; + + +/** + * Work In Progress. + *

+ * An instance of InputStreamSource implements a + * Source that provides data from an InputStream + * . Seeking functionality is not supported. + * + * @author MDM + */ +public class InputStreamSource implements Source { + + private final InputStream in; + + public InputStreamSource(InputStream in) { + if (in == null) + throw new NullPointerException("in"); + + this.in = in; + } + + public int read(byte[] b, int offs, int len) + throws IOException { + int read = in.read(b, offs, len); + return read; + } + + public boolean willReadBlock() { + return true; + } + + public boolean isSeekable() { + return false; + } + + public long tell() { + return -1; + } + + public long seek(long to) { + return -1; + } + + public long length() { + return -1; + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerError.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerError.java new file mode 100644 index 000000000..c72e6b64a --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerError.java @@ -0,0 +1,30 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Work in progress. + *

+ * API usage errors may be handled by throwing an instance of this + * class, as per JMF 2.0. + */ +public class JavaLayerError extends Error { +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerErrors.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerErrors.java new file mode 100644 index 000000000..35eae6114 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerErrors.java @@ -0,0 +1,39 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Exception erorr codes for components of the JavaLayer API. + */ +public interface JavaLayerErrors { + + /** + * The first bitstream error code. See the {@link DecoderErrors DecoderErrors} + * interface for other bitstream error codes. + */ + int BITSTREAM_ERROR = 0x100; + + /** + * The first decoder error code. See the {@link DecoderErrors DecoderErrors} + * interface for other decoder error codes. + */ + int DECODER_ERROR = 0x200; +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerException.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerException.java new file mode 100644 index 000000000..28fddeada --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerException.java @@ -0,0 +1,66 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.PrintStream; + + +/** + * The JavaLayerException is the base class for all API-level + * exceptions thrown by JavaLayer. To facilitate conversion and + * common handling of exceptions from other domains, the class + * can delegate some functionality to a contained Throwable instance. + *

+ * + * @author MDM + */ +public class JavaLayerException extends Exception { + + private Throwable exception; + + public JavaLayerException() { + } + + public JavaLayerException(String msg) { + super(msg); + } + + public JavaLayerException(String msg, Throwable t) { + super(msg); + exception = t; + } + + public Throwable getException() { + return exception; + } + + public void printStackTrace() { + printStackTrace(System.err); + } + + public void printStackTrace(PrintStream ps) { + if (this.exception == null) { + super.printStackTrace(ps); + } else { + exception.printStackTrace(); + } + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerHook.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerHook.java new file mode 100644 index 000000000..3033c21e8 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerHook.java @@ -0,0 +1,37 @@ +/* + * 11/19/04 1.0 moved to LGPL. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.InputStream; + + +/** + * The JavaLayerHooks class allows developers to change + * the way the JavaLayer library uses Resources. + */ + +public interface JavaLayerHook { + + /** + * Retrieves the named resource. This allows resources to be + * obtained without specifying how they are retrieved. + */ + InputStream getResourceAsStream(String name); +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerUtils.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerUtils.java new file mode 100644 index 000000000..390794493 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/JavaLayerUtils.java @@ -0,0 +1,187 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.lang.reflect.Array; + + +/** + * The JavaLayerUtils class is not strictly part of the JavaLayer API. + * It serves to provide useful methods and system-wide hooks. + * + * @author MDM + */ +public class JavaLayerUtils { + static private JavaLayerHook hook = null; + + /** + * Deserializes the object contained in the given input stream. + * + * @param in The input stream to deserialize an object from. + * @param cls The expected class of the deserialized object. + */ + static public Object deserialize(InputStream in, Class cls) + throws IOException { + if (cls == null) + throw new NullPointerException("cls"); + + Object obj = deserialize(in, cls); + if (!cls.isInstance(obj)) { + throw new InvalidObjectException("type of deserialized instance not of required class."); + } + + return obj; + } + + /** + * Deserializes an object from the given InputStream. + * The deserialization is delegated to an + * ObjectInputStream instance. + * + * @param in The InputStream to deserialize an object + * from. + * @return The object deserialized from the stream. + * @throws IOException is thrown if there was a problem reading + * the underlying stream, or an object could not be deserialized + * from the stream. + * @see java.io.ObjectInputStream + */ + static public Object deserialize(InputStream in) + throws IOException { + if (in == null) + throw new NullPointerException("in"); + + ObjectInputStream objIn = new ObjectInputStream(in); + + Object obj; + + try { + obj = objIn.readObject(); + } catch (ClassNotFoundException ex) { + throw new InvalidClassException(ex.toString()); + } + + return obj; + } + + /** + * Deserializes an array from a given InputStream. + * + * @param in The InputStream to + * deserialize an object from. + * @param elemType The class denoting the type of the array + * elements. + * @param length The expected length of the array, or -1 if + * any length is expected. + */ + static public Object deserializeArray(InputStream in, Class elemType, int length) + throws IOException { + if (elemType == null) + throw new NullPointerException("elemType"); + + if (length < -1) + throw new IllegalArgumentException("length"); + + Object obj = deserialize(in); + + Class cls = obj.getClass(); + + + if (!cls.isArray()) + throw new InvalidObjectException("object is not an array"); + + Class arrayElemType = cls.getComponentType(); + if (arrayElemType != elemType) + throw new InvalidObjectException("unexpected array component type"); + + if (length != -1) { + int arrayLength = Array.getLength(obj); + if (arrayLength != length) + throw new InvalidObjectException("array length mismatch"); + } + + return obj; + } + + static public Object deserializeArrayResource(String name, Class elemType, int length) + throws IOException { + InputStream str = getResourceAsStream(name); + if (str == null) + throw new IOException("unable to load resource '" + name + "'"); + + Object obj = deserializeArray(str, elemType, length); + + return obj; + } + + static public void serialize(OutputStream out, Object obj) + throws IOException { + if (out == null) + throw new NullPointerException("out"); + + if (obj == null) + throw new NullPointerException("obj"); + + ObjectOutputStream objOut = new ObjectOutputStream(out); + objOut.writeObject(obj); + } + + /** + * Sets the system-wide JavaLayer hook. + */ + static synchronized public void setHook(JavaLayerHook hook0) { + hook = hook0; + } + + static synchronized public JavaLayerHook getHook() { + return hook; + } + + /** + * Retrieves an InputStream for a named resource. + * + * @param name The name of the resource. This must be a simple + * name, and not a qualified package name. + * @return The InputStream for the named resource, or null if + * the resource has not been found. If a hook has been + * provided, its getResourceAsStream() method is called + * to retrieve the resource. + */ + static synchronized public InputStream getResourceAsStream(String name) { + InputStream is = null; + + if (hook != null) { + is = hook.getResourceAsStream(name); + } else { + Class cls = JavaLayerUtils.class; + is = cls.getResourceAsStream(name); + } + + return is; + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/LayerIDecoder.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/LayerIDecoder.java new file mode 100644 index 000000000..8b1bd3190 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/LayerIDecoder.java @@ -0,0 +1,396 @@ +/* + * 09/26/08 throw exception on subbband alloc error: Christopher G. Jennings (cjennings@acm.org) + * + * 11/19/04 1.0 moved to LGPL. + * + * 12/12/99 Initial version. Adapted from javalayer.java + * and Subband*.java. mdm@techie.com + * + * 02/28/99 Initial version : javalayer.java by E.B + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Implements decoding of MPEG Audio Layer I frames. + */ +class LayerIDecoder implements FrameDecoder { + + protected Bitstream stream; + protected Header header; + protected SynthesisFilter filter1, filter2; + protected Obuffer buffer; + protected int which_channels; + protected int mode; + + protected int num_subbands; + protected Subband[] subbands; + protected Crc16 crc; // new Crc16[1] to enable CRC checking. + + public LayerIDecoder() { + crc = new Crc16(); + } + + public void create(Bitstream stream0, Header header0, + SynthesisFilter filtera, SynthesisFilter filterb, + Obuffer buffer0, int which_ch0) { + stream = stream0; + header = header0; + filter1 = filtera; + filter2 = filterb; + buffer = buffer0; + which_channels = which_ch0; + } + + public void decodeFrame() throws DecoderException { + + num_subbands = header.number_of_subbands(); + subbands = new Subband[32]; + mode = header.mode(); + + createSubbands(); + + readAllocation(); + readScaleFactorSelection(); + + if ((crc != null) || header.checksum_ok()) { + readScaleFactors(); + + readSampleData(); + } + } + + protected void createSubbands() { + int i; + if (mode == Header.SINGLE_CHANNEL) + for (i = 0; i < num_subbands; ++i) + subbands[i] = new SubbandLayer1(i); + else if (mode == Header.JOINT_STEREO) { + for (i = 0; i < header.intensity_stereo_bound(); ++i) + subbands[i] = new SubbandLayer1Stereo(i); + for (; i < num_subbands; ++i) + subbands[i] = new SubbandLayer1IntensityStereo(i); + } else { + for (i = 0; i < num_subbands; ++i) + subbands[i] = new SubbandLayer1Stereo(i); + } + } + + protected void readAllocation() throws DecoderException { + // start to read audio data: + for (int i = 0; i < num_subbands; ++i) + subbands[i].read_allocation(stream, header, crc); + } + + protected void readScaleFactorSelection() { + // scale factor selection not present for layer I. + } + + protected void readScaleFactors() { + for (int i = 0; i < num_subbands; ++i) + subbands[i].read_scalefactor(stream, header); + } + + protected void readSampleData() { + boolean read_ready = false; + boolean write_ready = false; + int mode = header.mode(); + int i; + do { + for (i = 0; i < num_subbands; ++i) + read_ready = subbands[i].read_sampledata(stream); + do { + for (i = 0; i < num_subbands; ++i) + write_ready = subbands[i].put_next_sample(which_channels, filter1, filter2); + + filter1.calculate_pcm_samples(buffer); + if ((which_channels == OutputChannels.BOTH_CHANNELS) && (mode != Header.SINGLE_CHANNEL)) + filter2.calculate_pcm_samples(buffer); + } while (!write_ready); + } while (!read_ready); + + } + + /** + * Abstract base class for subband classes of layer I and II + */ + static abstract class Subband { + /* + * ScaleFactors for layer I and II, Annex 3-B.1 in ISO/IEC DIS 11172: + * + * Changes from version 1.1 to 1.2: + * - array size increased by one, although a scalefactor with index 63 + * is illegal (to prevent segmentation faults) + */ + public static final float[] scaleFactors = { + 2.00000000000000f, 1.58740105196820f, 1.25992104989487f, 1.00000000000000f, + 0.79370052598410f, 0.62996052494744f, 0.50000000000000f, 0.39685026299205f, + 0.31498026247372f, 0.25000000000000f, 0.19842513149602f, 0.15749013123686f, + 0.12500000000000f, 0.09921256574801f, 0.07874506561843f, 0.06250000000000f, + 0.04960628287401f, 0.03937253280921f, 0.03125000000000f, 0.02480314143700f, + 0.01968626640461f, 0.01562500000000f, 0.01240157071850f, 0.00984313320230f, + 0.00781250000000f, 0.00620078535925f, 0.00492156660115f, 0.00390625000000f, + 0.00310039267963f, 0.00246078330058f, 0.00195312500000f, 0.00155019633981f, + 0.00123039165029f, 0.00097656250000f, 0.00077509816991f, 0.00061519582514f, + 0.00048828125000f, 0.00038754908495f, 0.00030759791257f, 0.00024414062500f, + 0.00019377454248f, 0.00015379895629f, 0.00012207031250f, 0.00009688727124f, + 0.00007689947814f, 0.00006103515625f, 0.00004844363562f, 0.00003844973907f, + 0.00003051757813f, 0.00002422181781f, 0.00001922486954f, 0.00001525878906f, + 0.00001211090890f, 0.00000961243477f, 0.00000762939453f, 0.00000605545445f, + 0.00000480621738f, 0.00000381469727f, 0.00000302772723f, 0.00000240310869f, + 0.00000190734863f, 0.00000151386361f, 0.00000120155435f, 0.00000000000000f // illegal scaleFactor + }; + + public abstract void read_allocation(Bitstream stream, Header header, Crc16 crc) throws DecoderException; + + public abstract void read_scalefactor(Bitstream stream, Header header); + + public abstract boolean read_sampledata(Bitstream stream); + + public abstract boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2); + } + + /** + * Class for layer I subbands in single channel mode. + * Used for single channel mode + * and in derived class for intensity stereo mode + */ + static class SubbandLayer1 extends Subband { + + // Factors and offsets for sample requantization + public static final float[] table_factor = { + 0.0f, (1.0f / 2.0f) * (4.0f / 3.0f), (1.0f / 4.0f) * (8.0f / 7.0f), (1.0f / 8.0f) * (16.0f / 15.0f), + (1.0f / 16.0f) * (32.0f / 31.0f), (1.0f / 32.0f) * (64.0f / 63.0f), (1.0f / 64.0f) * (128.0f / 127.0f), + (1.0f / 128.0f) * (256.0f / 255.0f), (1.0f / 256.0f) * (512.0f / 511.0f), + (1.0f / 512.0f) * (1024.0f / 1023.0f), (1.0f / 1024.0f) * (2048.0f / 2047.0f), + (1.0f / 2048.0f) * (4096.0f / 4095.0f), (1.0f / 4096.0f) * (8192.0f / 8191.0f), + (1.0f / 8192.0f) * (16384.0f / 16383.0f), (1.0f / 16384.0f) * (32768.0f / 32767.0f) + }; + + public static final float[] table_offset = { + 0.0f, ((1.0f / 2.0f) - 1.0f) * (4.0f / 3.0f), ((1.0f / 4.0f) - 1.0f) * (8.0f / 7.0f), ((1.0f / 8.0f) - 1.0f) * (16.0f / 15.0f), + ((1.0f / 16.0f) - 1.0f) * (32.0f / 31.0f), ((1.0f / 32.0f) - 1.0f) * (64.0f / 63.0f), ((1.0f / 64.0f) - 1.0f) * (128.0f / 127.0f), + ((1.0f / 128.0f) - 1.0f) * (256.0f / 255.0f), ((1.0f / 256.0f) - 1.0f) * (512.0f / 511.0f), + ((1.0f / 512.0f) - 1.0f) * (1024.0f / 1023.0f), ((1.0f / 1024.0f) - 1.0f) * (2048.0f / 2047.0f), + ((1.0f / 2048.0f) - 1.0f) * (4096.0f / 4095.0f), ((1.0f / 4096.0f) - 1.0f) * (8192.0f / 8191.0f), + ((1.0f / 8192.0f) - 1.0f) * (16384.0f / 16383.0f), ((1.0f / 16384.0f) - 1.0f) * (32768.0f / 32767.0f) + }; + + protected int subbandnumber; + protected int samplenumber; + protected int allocation; + protected float scalefactor; + protected int samplelength; + protected float sample; + protected float factor, offset; + + /** + * Constructor. + */ + public SubbandLayer1(int subbandnumber) { + this.subbandnumber = subbandnumber; + samplenumber = 0; + } + + /** + * + */ + public void read_allocation(Bitstream stream, Header header, Crc16 crc) throws DecoderException { + if ((allocation = stream.get_bits(4)) == 15) { + // CGJ: catch this condition and throw appropriate exception + throw new DecoderException(DecoderErrors.ILLEGAL_SUBBAND_ALLOCATION, null); + // MPEG-stream is corrupted! + } + + if (crc != null) crc.add_bits(allocation, 4); + if (allocation != 0) { + samplelength = allocation + 1; + factor = table_factor[allocation]; + offset = table_offset[allocation]; + } + } + + /** + * + */ + public void read_scalefactor(Bitstream stream, Header header) { + if (allocation != 0) scalefactor = scaleFactors[stream.get_bits(6)]; + } + + /** + * + */ + public boolean read_sampledata(Bitstream stream) { + if (allocation != 0) { + sample = (stream.get_bits(samplelength)); + } + if (++samplenumber == 12) { + samplenumber = 0; + return true; + } + return false; + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) { + if ((allocation != 0) && (channels != OutputChannels.RIGHT_CHANNEL)) { + float scaled_sample = (sample * factor + offset) * scalefactor; + filter1.input_sample(scaled_sample, subbandnumber); + } + return true; + } + } + + /** + * Class for layer I subbands in joint stereo mode. + */ + static class SubbandLayer1IntensityStereo extends SubbandLayer1 { + protected float channel2_scalefactor; + + /** + * Constructor + */ + public SubbandLayer1IntensityStereo(int subbandnumber) { + super(subbandnumber); + } + + /** + * + */ + public void read_allocation(Bitstream stream, Header header, Crc16 crc) throws DecoderException { + super.read_allocation(stream, header, crc); + } + + /** + * + */ + public void read_scalefactor(Bitstream stream, Header header) { + if (allocation != 0) { + scalefactor = scaleFactors[stream.get_bits(6)]; + channel2_scalefactor = scaleFactors[stream.get_bits(6)]; + } + } + + /** + * + */ + public boolean read_sampledata(Bitstream stream) { + return super.read_sampledata(stream); + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) { + if (allocation != 0) { + sample = sample * factor + offset; // requantization + if (channels == OutputChannels.BOTH_CHANNELS) { + float sample1 = sample * scalefactor, + sample2 = sample * channel2_scalefactor; + filter1.input_sample(sample1, subbandnumber); + filter2.input_sample(sample2, subbandnumber); + } else if (channels == OutputChannels.LEFT_CHANNEL) { + float sample1 = sample * scalefactor; + filter1.input_sample(sample1, subbandnumber); + } else { + float sample2 = sample * channel2_scalefactor; + filter1.input_sample(sample2, subbandnumber); + } + } + return true; + } + } + + /** + * Class for layer I subbands in stereo mode. + */ + static class SubbandLayer1Stereo extends SubbandLayer1 { + + protected int channel2_allocation; + protected float channel2_scalefactor; + protected int channel2_samplelength; + protected float channel2_sample; + protected float channel2_factor, channel2_offset; + + /** + * Constructor + */ + public SubbandLayer1Stereo(int subbandnumber) { + super(subbandnumber); + } + + /** + * + */ + public void read_allocation(Bitstream stream, Header header, Crc16 crc) throws DecoderException { + allocation = stream.get_bits(4); + channel2_allocation = stream.get_bits(4); + if (crc != null) { + crc.add_bits(allocation, 4); + crc.add_bits(channel2_allocation, 4); + } + if (allocation != 0) { + samplelength = allocation + 1; + factor = table_factor[allocation]; + offset = table_offset[allocation]; + } + if (channel2_allocation != 0) { + channel2_samplelength = channel2_allocation + 1; + channel2_factor = table_factor[channel2_allocation]; + channel2_offset = table_offset[channel2_allocation]; + } + } + + /** + * + */ + public void read_scalefactor(Bitstream stream, Header header) { + if (allocation != 0) scalefactor = scaleFactors[stream.get_bits(6)]; + if (channel2_allocation != 0) channel2_scalefactor = scaleFactors[stream.get_bits(6)]; + } + + /** + * + */ + public boolean read_sampledata(Bitstream stream) { + boolean returnvalue = super.read_sampledata(stream); + if (channel2_allocation != 0) { + channel2_sample = (stream.get_bits(channel2_samplelength)); + } + return (returnvalue); + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) { + super.put_next_sample(channels, filter1, filter2); + if ((channel2_allocation != 0) && (channels != OutputChannels.LEFT_CHANNEL)) { + float sample2 = (channel2_sample * channel2_factor + channel2_offset) * + channel2_scalefactor; + if (channels == OutputChannels.BOTH_CHANNELS) + filter2.input_sample(sample2, subbandnumber); + else + filter1.input_sample(sample2, subbandnumber); + } + return true; + } + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/LayerIIDecoder.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/LayerIIDecoder.java new file mode 100644 index 000000000..489de35de --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/LayerIIDecoder.java @@ -0,0 +1,968 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 29/05/01 Michael Scheerer, Fixed some C++ to Java porting bugs. + * + * 16/07/01 Michael Scheerer, Catched a bug in method + * read_sampledata, which causes an outOfIndexException. + * + * 12/12/99 Initial version. Adapted from javalayer.java + * and Subband*.java. mdm@techie.com + * + * 02/28/99 Initial version : javalayer.java by E.B + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Implements decoding of MPEG Audio Layer II frames. + */ +class LayerIIDecoder extends LayerIDecoder implements FrameDecoder { + + protected void createSubbands() { + int i; + if (mode == Header.SINGLE_CHANNEL) + for (i = 0; i < num_subbands; ++i) + subbands[i] = new SubbandLayer2(i); + else if (mode == Header.JOINT_STEREO) { + for (i = 0; i < header.intensity_stereo_bound(); ++i) + subbands[i] = new SubbandLayer2Stereo(i); + for (; i < num_subbands; ++i) + subbands[i] = new SubbandLayer2IntensityStereo(i); + } else { + for (i = 0; i < num_subbands; ++i) + subbands[i] = new SubbandLayer2Stereo(i); + } + } + + protected void readScaleFactorSelection() { + for (int i = 0; i < num_subbands; ++i) + ((SubbandLayer2) subbands[i]).read_scalefactor_selection(stream, crc); + } + + /** + * Class for layer II subbands in single channel mode. + */ + static class SubbandLayer2 extends Subband { + // this table contains 3 requantized samples for each legal codeword + // when grouped in 5 bits, i.e. 3 quantizationsteps per sample + public static final float[] grouping_5bits = new float[] { + -2.0f / 3.0f, -2.0f / 3.0f, -2.0f / 3.0f, + 0.0f, -2.0f / 3.0f, -2.0f / 3.0f, + 2.0f / 3.0f, -2.0f / 3.0f, -2.0f / 3.0f, + -2.0f / 3.0f, 0.0f, -2.0f / 3.0f, + 0.0f, 0.0f, -2.0f / 3.0f, + 2.0f / 3.0f, 0.0f, -2.0f / 3.0f, + -2.0f / 3.0f, 2.0f / 3.0f, -2.0f / 3.0f, + 0.0f, 2.0f / 3.0f, -2.0f / 3.0f, + 2.0f / 3.0f, 2.0f / 3.0f, -2.0f / 3.0f, + -2.0f / 3.0f, -2.0f / 3.0f, 0.0f, + 0.0f, -2.0f / 3.0f, 0.0f, + 2.0f / 3.0f, -2.0f / 3.0f, 0.0f, + -2.0f / 3.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 2.0f / 3.0f, 0.0f, 0.0f, + -2.0f / 3.0f, 2.0f / 3.0f, 0.0f, + 0.0f, 2.0f / 3.0f, 0.0f, + 2.0f / 3.0f, 2.0f / 3.0f, 0.0f, + -2.0f / 3.0f, -2.0f / 3.0f, 2.0f / 3.0f, + 0.0f, -2.0f / 3.0f, 2.0f / 3.0f, + 2.0f / 3.0f, -2.0f / 3.0f, 2.0f / 3.0f, + -2.0f / 3.0f, 0.0f, 2.0f / 3.0f, + 0.0f, 0.0f, 2.0f / 3.0f, + 2.0f / 3.0f, 0.0f, 2.0f / 3.0f, + -2.0f / 3.0f, 2.0f / 3.0f, 2.0f / 3.0f, + 0.0f, 2.0f / 3.0f, 2.0f / 3.0f, + 2.0f / 3.0f, 2.0f / 3.0f, 2.0f / 3.0f + }; + + // this table contains 3 requantized samples for each legal codeword + // when grouped in 7 bits, i.e. 5 quantizationsteps per sample + public static final float[] grouping_7bits = new float[] { + -0.8f, -0.8f, -0.8f, -0.4f, -0.8f, -0.8f, 0.0f, -0.8f, -0.8f, 0.4f, -0.8f, -0.8f, 0.8f, -0.8f, -0.8f, + -0.8f, -0.4f, -0.8f, -0.4f, -0.4f, -0.8f, 0.0f, -0.4f, -0.8f, 0.4f, -0.4f, -0.8f, 0.8f, -0.4f, -0.8f, + -0.8f, 0.0f, -0.8f, -0.4f, 0.0f, -0.8f, 0.0f, 0.0f, -0.8f, 0.4f, 0.0f, -0.8f, 0.8f, 0.0f, -0.8f, + -0.8f, 0.4f, -0.8f, -0.4f, 0.4f, -0.8f, 0.0f, 0.4f, -0.8f, 0.4f, 0.4f, -0.8f, 0.8f, 0.4f, -0.8f, + -0.8f, 0.8f, -0.8f, -0.4f, 0.8f, -0.8f, 0.0f, 0.8f, -0.8f, 0.4f, 0.8f, -0.8f, 0.8f, 0.8f, -0.8f, + -0.8f, -0.8f, -0.4f, -0.4f, -0.8f, -0.4f, 0.0f, -0.8f, -0.4f, 0.4f, -0.8f, -0.4f, 0.8f, -0.8f, -0.4f, + -0.8f, -0.4f, -0.4f, -0.4f, -0.4f, -0.4f, 0.0f, -0.4f, -0.4f, 0.4f, -0.4f, -0.4f, 0.8f, -0.4f, -0.4f, + -0.8f, 0.0f, -0.4f, -0.4f, 0.0f, -0.4f, 0.0f, 0.0f, -0.4f, 0.4f, 0.0f, -0.4f, 0.8f, 0.0f, -0.4f, + -0.8f, 0.4f, -0.4f, -0.4f, 0.4f, -0.4f, 0.0f, 0.4f, -0.4f, 0.4f, 0.4f, -0.4f, 0.8f, 0.4f, -0.4f, + -0.8f, 0.8f, -0.4f, -0.4f, 0.8f, -0.4f, 0.0f, 0.8f, -0.4f, 0.4f, 0.8f, -0.4f, 0.8f, 0.8f, -0.4f, + -0.8f, -0.8f, 0.0f, -0.4f, -0.8f, 0.0f, 0.0f, -0.8f, 0.0f, 0.4f, -0.8f, 0.0f, 0.8f, -0.8f, 0.0f, + -0.8f, -0.4f, 0.0f, -0.4f, -0.4f, 0.0f, 0.0f, -0.4f, 0.0f, 0.4f, -0.4f, 0.0f, 0.8f, -0.4f, 0.0f, + -0.8f, 0.0f, 0.0f, -0.4f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.4f, 0.0f, 0.0f, 0.8f, 0.0f, 0.0f, + -0.8f, 0.4f, 0.0f, -0.4f, 0.4f, 0.0f, 0.0f, 0.4f, 0.0f, 0.4f, 0.4f, 0.0f, 0.8f, 0.4f, 0.0f, + -0.8f, 0.8f, 0.0f, -0.4f, 0.8f, 0.0f, 0.0f, 0.8f, 0.0f, 0.4f, 0.8f, 0.0f, 0.8f, 0.8f, 0.0f, + -0.8f, -0.8f, 0.4f, -0.4f, -0.8f, 0.4f, 0.0f, -0.8f, 0.4f, 0.4f, -0.8f, 0.4f, 0.8f, -0.8f, 0.4f, + -0.8f, -0.4f, 0.4f, -0.4f, -0.4f, 0.4f, 0.0f, -0.4f, 0.4f, 0.4f, -0.4f, 0.4f, 0.8f, -0.4f, 0.4f, + -0.8f, 0.0f, 0.4f, -0.4f, 0.0f, 0.4f, 0.0f, 0.0f, 0.4f, 0.4f, 0.0f, 0.4f, 0.8f, 0.0f, 0.4f, + -0.8f, 0.4f, 0.4f, -0.4f, 0.4f, 0.4f, 0.0f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.8f, 0.4f, 0.4f, + -0.8f, 0.8f, 0.4f, -0.4f, 0.8f, 0.4f, 0.0f, 0.8f, 0.4f, 0.4f, 0.8f, 0.4f, 0.8f, 0.8f, 0.4f, + -0.8f, -0.8f, 0.8f, -0.4f, -0.8f, 0.8f, 0.0f, -0.8f, 0.8f, 0.4f, -0.8f, 0.8f, 0.8f, -0.8f, 0.8f, + -0.8f, -0.4f, 0.8f, -0.4f, -0.4f, 0.8f, 0.0f, -0.4f, 0.8f, 0.4f, -0.4f, 0.8f, 0.8f, -0.4f, 0.8f, + -0.8f, 0.0f, 0.8f, -0.4f, 0.0f, 0.8f, 0.0f, 0.0f, 0.8f, 0.4f, 0.0f, 0.8f, 0.8f, 0.0f, 0.8f, + -0.8f, 0.4f, 0.8f, -0.4f, 0.4f, 0.8f, 0.0f, 0.4f, 0.8f, 0.4f, 0.4f, 0.8f, 0.8f, 0.4f, 0.8f, + -0.8f, 0.8f, 0.8f, -0.4f, 0.8f, 0.8f, 0.0f, 0.8f, 0.8f, 0.4f, 0.8f, 0.8f, 0.8f, 0.8f, 0.8f + }; + + // this table contains 3 requantized samples for each legal codeword + // when grouped in 10 bits, i.e. 9 quantizationsteps per sample + public static final float[] grouping_10bits = { + -8.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, + -2.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, 0.0f, -8.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, + 4.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, + -8.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, + -2.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, 0.0f, -6.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, + 4.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, + -8.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, + -2.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 0.0f, -4.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, + 4.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, + -8.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, + -2.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, 0.0f, -2.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, + 4.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, + -8.0f / 9.0f, 0.0f, -8.0f / 9.0f, -6.0f / 9.0f, 0.0f, -8.0f / 9.0f, -4.0f / 9.0f, 0.0f, -8.0f / 9.0f, + -2.0f / 9.0f, 0.0f, -8.0f / 9.0f, 0.0f, 0.0f, -8.0f / 9.0f, 2.0f / 9.0f, 0.0f, -8.0f / 9.0f, + 4.0f / 9.0f, 0.0f, -8.0f / 9.0f, 6.0f / 9.0f, 0.0f, -8.0f / 9.0f, 8.0f / 9.0f, 0.0f, -8.0f / 9.0f, + -8.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, + -2.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 0.0f, 2.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, + 4.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, + -8.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, + -2.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, 0.0f, 4.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, + 4.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, + -8.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, + -2.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 0.0f, 6.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, + 4.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, + -8.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, + -2.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 0.0f, 8.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, + 4.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, + -8.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, + -2.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 0.0f, -8.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, + 4.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, + -8.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, + -2.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 0.0f, -6.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, + 4.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, + -8.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, + -2.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 0.0f, -4.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, + 4.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, + -8.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, + -2.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, 0.0f, -2.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, + 4.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, + -8.0f / 9.0f, 0.0f, -6.0f / 9.0f, -6.0f / 9.0f, 0.0f, -6.0f / 9.0f, -4.0f / 9.0f, 0.0f, -6.0f / 9.0f, + -2.0f / 9.0f, 0.0f, -6.0f / 9.0f, 0.0f, 0.0f, -6.0f / 9.0f, 2.0f / 9.0f, 0.0f, -6.0f / 9.0f, + 4.0f / 9.0f, 0.0f, -6.0f / 9.0f, 6.0f / 9.0f, 0.0f, -6.0f / 9.0f, 8.0f / 9.0f, 0.0f, -6.0f / 9.0f, + -8.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, + -2.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 0.0f, 2.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, + 4.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, + -8.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, + -2.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, 0.0f, 4.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, + 4.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, + -8.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, + -2.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 0.0f, 6.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, + 4.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, + -8.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, + -2.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 0.0f, 8.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, + 4.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, + -8.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, + -2.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, 0.0f, -8.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, + 4.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, + -8.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, + -2.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 0.0f, -6.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, + 4.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, + -8.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, + -2.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 0.0f, -4.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, + 4.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, + -8.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, + -2.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, 0.0f, -2.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, + 4.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, + -8.0f / 9.0f, 0.0f, -4.0f / 9.0f, -6.0f / 9.0f, 0.0f, -4.0f / 9.0f, -4.0f / 9.0f, 0.0f, -4.0f / 9.0f, + -2.0f / 9.0f, 0.0f, -4.0f / 9.0f, 0.0f, 0.0f, -4.0f / 9.0f, 2.0f / 9.0f, 0.0f, -4.0f / 9.0f, + 4.0f / 9.0f, 0.0f, -4.0f / 9.0f, 6.0f / 9.0f, 0.0f, -4.0f / 9.0f, 8.0f / 9.0f, 0.0f, -4.0f / 9.0f, + -8.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, + -2.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 0.0f, 2.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, + 4.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, + -8.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, + -2.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 0.0f, 4.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, + 4.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, + -8.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, + -2.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 0.0f, 6.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, + 4.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, + -8.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, + -2.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 0.0f, 8.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, + 4.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, + -8.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, + -2.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, 0.0f, -8.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, + 4.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, + -8.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, + -2.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, 0.0f, -6.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, + 4.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, + -8.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, + -2.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, 0.0f, -4.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, + 4.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, + -8.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, + -2.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, 0.0f, -2.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, + 4.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, + -8.0f / 9.0f, 0.0f, -2.0f / 9.0f, -6.0f / 9.0f, 0.0f, -2.0f / 9.0f, -4.0f / 9.0f, 0.0f, -2.0f / 9.0f, + -2.0f / 9.0f, 0.0f, -2.0f / 9.0f, 0.0f, 0.0f, -2.0f / 9.0f, 2.0f / 9.0f, 0.0f, -2.0f / 9.0f, + 4.0f / 9.0f, 0.0f, -2.0f / 9.0f, 6.0f / 9.0f, 0.0f, -2.0f / 9.0f, 8.0f / 9.0f, 0.0f, -2.0f / 9.0f, + -8.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, + -2.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, 0.0f, 2.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, + 4.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, + -8.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, + -2.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, 0.0f, 4.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, + 4.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, + -8.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, + -2.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 0.0f, 6.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, + 4.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, + -8.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, + -2.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 0.0f, 8.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, + 4.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, + -8.0f / 9.0f, -8.0f / 9.0f, 0.0f, -6.0f / 9.0f, -8.0f / 9.0f, 0.0f, -4.0f / 9.0f, -8.0f / 9.0f, 0.0f, + -2.0f / 9.0f, -8.0f / 9.0f, 0.0f, 0.0f, -8.0f / 9.0f, 0.0f, 2.0f / 9.0f, -8.0f / 9.0f, 0.0f, + 4.0f / 9.0f, -8.0f / 9.0f, 0.0f, 6.0f / 9.0f, -8.0f / 9.0f, 0.0f, 8.0f / 9.0f, -8.0f / 9.0f, 0.0f, + -8.0f / 9.0f, -6.0f / 9.0f, 0.0f, -6.0f / 9.0f, -6.0f / 9.0f, 0.0f, -4.0f / 9.0f, -6.0f / 9.0f, 0.0f, + -2.0f / 9.0f, -6.0f / 9.0f, 0.0f, 0.0f, -6.0f / 9.0f, 0.0f, 2.0f / 9.0f, -6.0f / 9.0f, 0.0f, + 4.0f / 9.0f, -6.0f / 9.0f, 0.0f, 6.0f / 9.0f, -6.0f / 9.0f, 0.0f, 8.0f / 9.0f, -6.0f / 9.0f, 0.0f, + -8.0f / 9.0f, -4.0f / 9.0f, 0.0f, -6.0f / 9.0f, -4.0f / 9.0f, 0.0f, -4.0f / 9.0f, -4.0f / 9.0f, 0.0f, + -2.0f / 9.0f, -4.0f / 9.0f, 0.0f, 0.0f, -4.0f / 9.0f, 0.0f, 2.0f / 9.0f, -4.0f / 9.0f, 0.0f, + 4.0f / 9.0f, -4.0f / 9.0f, 0.0f, 6.0f / 9.0f, -4.0f / 9.0f, 0.0f, 8.0f / 9.0f, -4.0f / 9.0f, 0.0f, + -8.0f / 9.0f, -2.0f / 9.0f, 0.0f, -6.0f / 9.0f, -2.0f / 9.0f, 0.0f, -4.0f / 9.0f, -2.0f / 9.0f, 0.0f, + -2.0f / 9.0f, -2.0f / 9.0f, 0.0f, 0.0f, -2.0f / 9.0f, 0.0f, 2.0f / 9.0f, -2.0f / 9.0f, 0.0f, + 4.0f / 9.0f, -2.0f / 9.0f, 0.0f, 6.0f / 9.0f, -2.0f / 9.0f, 0.0f, 8.0f / 9.0f, -2.0f / 9.0f, 0.0f, + -8.0f / 9.0f, 0.0f, 0.0f, -6.0f / 9.0f, 0.0f, 0.0f, -4.0f / 9.0f, 0.0f, 0.0f, + -2.0f / 9.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f / 9.0f, 0.0f, 0.0f, + 4.0f / 9.0f, 0.0f, 0.0f, 6.0f / 9.0f, 0.0f, 0.0f, 8.0f / 9.0f, 0.0f, 0.0f, + -8.0f / 9.0f, 2.0f / 9.0f, 0.0f, -6.0f / 9.0f, 2.0f / 9.0f, 0.0f, -4.0f / 9.0f, 2.0f / 9.0f, 0.0f, + -2.0f / 9.0f, 2.0f / 9.0f, 0.0f, 0.0f, 2.0f / 9.0f, 0.0f, 2.0f / 9.0f, 2.0f / 9.0f, 0.0f, + 4.0f / 9.0f, 2.0f / 9.0f, 0.0f, 6.0f / 9.0f, 2.0f / 9.0f, 0.0f, 8.0f / 9.0f, 2.0f / 9.0f, 0.0f, + -8.0f / 9.0f, 4.0f / 9.0f, 0.0f, -6.0f / 9.0f, 4.0f / 9.0f, 0.0f, -4.0f / 9.0f, 4.0f / 9.0f, 0.0f, + -2.0f / 9.0f, 4.0f / 9.0f, 0.0f, 0.0f, 4.0f / 9.0f, 0.0f, 2.0f / 9.0f, 4.0f / 9.0f, 0.0f, + 4.0f / 9.0f, 4.0f / 9.0f, 0.0f, 6.0f / 9.0f, 4.0f / 9.0f, 0.0f, 8.0f / 9.0f, 4.0f / 9.0f, 0.0f, + -8.0f / 9.0f, 6.0f / 9.0f, 0.0f, -6.0f / 9.0f, 6.0f / 9.0f, 0.0f, -4.0f / 9.0f, 6.0f / 9.0f, 0.0f, + -2.0f / 9.0f, 6.0f / 9.0f, 0.0f, 0.0f, 6.0f / 9.0f, 0.0f, 2.0f / 9.0f, 6.0f / 9.0f, 0.0f, + 4.0f / 9.0f, 6.0f / 9.0f, 0.0f, 6.0f / 9.0f, 6.0f / 9.0f, 0.0f, 8.0f / 9.0f, 6.0f / 9.0f, 0.0f, + -8.0f / 9.0f, 8.0f / 9.0f, 0.0f, -6.0f / 9.0f, 8.0f / 9.0f, 0.0f, -4.0f / 9.0f, 8.0f / 9.0f, 0.0f, + -2.0f / 9.0f, 8.0f / 9.0f, 0.0f, 0.0f, 8.0f / 9.0f, 0.0f, 2.0f / 9.0f, 8.0f / 9.0f, 0.0f, + 4.0f / 9.0f, 8.0f / 9.0f, 0.0f, 6.0f / 9.0f, 8.0f / 9.0f, 0.0f, 8.0f / 9.0f, 8.0f / 9.0f, 0.0f, + -8.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, + -2.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, 0.0f, -8.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, + 4.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, + -8.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, + -2.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 0.0f, -6.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, + 4.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, + -8.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, + -2.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 0.0f, -4.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, + 4.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, + -8.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, + -2.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, 0.0f, -2.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, + 4.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, + -8.0f / 9.0f, 0.0f, 2.0f / 9.0f, -6.0f / 9.0f, 0.0f, 2.0f / 9.0f, -4.0f / 9.0f, 0.0f, 2.0f / 9.0f, + -2.0f / 9.0f, 0.0f, 2.0f / 9.0f, 0.0f, 0.0f, 2.0f / 9.0f, 2.0f / 9.0f, 0.0f, 2.0f / 9.0f, + 4.0f / 9.0f, 0.0f, 2.0f / 9.0f, 6.0f / 9.0f, 0.0f, 2.0f / 9.0f, 8.0f / 9.0f, 0.0f, 2.0f / 9.0f, + -8.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, + -2.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 0.0f, 2.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, + 4.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, + -8.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, + -2.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 0.0f, 4.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, + 4.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, + -8.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, + -2.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 0.0f, 6.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, + 4.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, + -8.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, + -2.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 0.0f, 8.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, + 4.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, + -8.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, + -2.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, 0.0f, -8.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, + 4.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, + -8.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, + -2.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, 0.0f, -6.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, + 4.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, + -8.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, + -2.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, 0.0f, -4.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, + 4.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, + -8.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, + -2.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, 0.0f, -2.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, + 4.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, + -8.0f / 9.0f, 0.0f, 4.0f / 9.0f, -6.0f / 9.0f, 0.0f, 4.0f / 9.0f, -4.0f / 9.0f, 0.0f, 4.0f / 9.0f, + -2.0f / 9.0f, 0.0f, 4.0f / 9.0f, 0.0f, 0.0f, 4.0f / 9.0f, 2.0f / 9.0f, 0.0f, 4.0f / 9.0f, + 4.0f / 9.0f, 0.0f, 4.0f / 9.0f, 6.0f / 9.0f, 0.0f, 4.0f / 9.0f, 8.0f / 9.0f, 0.0f, 4.0f / 9.0f, + -8.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, + -2.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, 0.0f, 2.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, + 4.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, + -8.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, + -2.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, 0.0f, 4.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, + 4.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, + -8.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, + -2.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 0.0f, 6.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, + 4.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, + -8.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, + -2.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, 0.0f, 8.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, + 4.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, + -8.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, + -2.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 0.0f, -8.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, + 4.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, + -8.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, + -2.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 0.0f, -6.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, + 4.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, + -8.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, + -2.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 0.0f, -4.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, + 4.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, + -8.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, + -2.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 0.0f, -2.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, + 4.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, + -8.0f / 9.0f, 0.0f, 6.0f / 9.0f, -6.0f / 9.0f, 0.0f, 6.0f / 9.0f, -4.0f / 9.0f, 0.0f, 6.0f / 9.0f, + -2.0f / 9.0f, 0.0f, 6.0f / 9.0f, 0.0f, 0.0f, 6.0f / 9.0f, 2.0f / 9.0f, 0.0f, 6.0f / 9.0f, + 4.0f / 9.0f, 0.0f, 6.0f / 9.0f, 6.0f / 9.0f, 0.0f, 6.0f / 9.0f, 8.0f / 9.0f, 0.0f, 6.0f / 9.0f, + -8.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, + -2.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 0.0f, 2.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, + 4.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, + -8.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, + -2.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, 0.0f, 4.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, + 4.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, + -8.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, + -2.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, 0.0f, 6.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, + 4.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, + -8.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, + -2.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 0.0f, 8.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, + 4.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, + -8.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, + -2.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, 0.0f, -8.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, + 4.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, + -8.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, + -2.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 0.0f, -6.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, + 4.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, + -8.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, + -2.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 0.0f, -4.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, + 4.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, + -8.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, + -2.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, 0.0f, -2.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, + 4.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, + -8.0f / 9.0f, 0.0f, 8.0f / 9.0f, -6.0f / 9.0f, 0.0f, 8.0f / 9.0f, -4.0f / 9.0f, 0.0f, 8.0f / 9.0f, + -2.0f / 9.0f, 0.0f, 8.0f / 9.0f, 0.0f, 0.0f, 8.0f / 9.0f, 2.0f / 9.0f, 0.0f, 8.0f / 9.0f, + 4.0f / 9.0f, 0.0f, 8.0f / 9.0f, 6.0f / 9.0f, 0.0f, 8.0f / 9.0f, 8.0f / 9.0f, 0.0f, 8.0f / 9.0f, + -8.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, + -2.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 0.0f, 2.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, + 4.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, + -8.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, + -2.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 0.0f, 4.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, + 4.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, + -8.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, + -2.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 0.0f, 6.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, + 4.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, + -8.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, + -2.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 0.0f, 8.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, + 4.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f + }; + + // data taken from ISO/IEC DIS 11172, Annexes 3-B.2[abcd] and 3-B.4: + + // subbands 0-2 in tables 3-B.2a and 2b: (index is allocation) + public static final int[] table_ab1_codelength = { + // bits per codeword + 0, 5, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + }; + + public static final float[][] table_ab1_groupingtables = { + // pointer to sample grouping table, or NULL-pointer if ungrouped + null, grouping_5bits, null, null, null, null, null, null, null, null, null, null, null, null, null, null + }; + + public static final float[] table_ab1_factor = { + // factor for requantization: (real)sample * factor - 1.0 gives requantized sample + 0.0f, 1.0f / 2.0f, 1.0f / 4.0f, 1.0f / 8.0f, 1.0f / 16.0f, 1.0f / 32.0f, 1.0f / 64.0f, + 1.0f / 128.0f, 1.0f / 256.0f, 1.0f / 512.0f, 1.0f / 1024.0f, 1.0f / 2048.0f, + 1.0f / 4096.0f, 1.0f / 8192.0f, 1.0f / 16384.0f, 1.0f / 32768.0f + }; + + public static final float[] table_ab1_c = + // factor c for requantization from table 3-B.4 + {0.0f, 1.33333333333f, 1.14285714286f, 1.06666666666f, 1.03225806452f, + 1.01587301587f, 1.00787401575f, 1.00392156863f, 1.00195694716f, 1.00097751711f, + 1.00048851979f, 1.00024420024f, 1.00012208522f, 1.00006103888f, 1.00003051851f, + 1.00001525902f}; + + public static final float[] table_ab1_d = + // addend d for requantization from table 3-B.4 + {0.0f, 0.50000000000f, 0.25000000000f, 0.12500000000f, 0.06250000000f, + 0.03125000000f, 0.01562500000f, 0.00781250000f, 0.00390625000f, 0.00195312500f, + 0.00097656250f, 0.00048828125f, 0.00024414063f, 0.00012207031f, 0.00006103516f, + 0.00003051758f}; + + // subbands 3-... tables 3-B.2a and 2b: + public static final float[][] table_ab234_groupingtables = { + null, grouping_5bits, grouping_7bits, null, grouping_10bits, null, null, null, + null, null, null, null, null, null, null, null + }; + + // subbands 3-10 in tables 3-B.2a and 2b: + public static final int[] table_ab2_codelength = { + 0, 5, 7, 3, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 + }; + public static final float[] table_ab2_factor = { + 0.0f, 1.0f / 2.0f, 1.0f / 4.0f, 1.0f / 4.0f, 1.0f / 8.0f, 1.0f / 8.0f, 1.0f / 16.0f, + 1.0f / 32.0f, 1.0f / 64.0f, 1.0f / 128.0f, 1.0f / 256.0f, 1.0f / 512.0f, + 1.0f / 1024.0f, 1.0f / 2048.0f, 1.0f / 4096.0f, 1.0f / 32768.0f + }; + public static final float[] table_ab2_c = { + 0.0f, 1.33333333333f, 1.60000000000f, 1.14285714286f, 1.77777777777f, + 1.06666666666f, 1.03225806452f, 1.01587301587f, 1.00787401575f, 1.00392156863f, + 1.00195694716f, 1.00097751711f, 1.00048851979f, 1.00024420024f, 1.00012208522f, + 1.00001525902f + }; + public static final float[] table_ab2_d = { + 0.0f, 0.50000000000f, 0.50000000000f, 0.25000000000f, 0.50000000000f, + 0.12500000000f, 0.06250000000f, 0.03125000000f, 0.01562500000f, 0.00781250000f, + 0.00390625000f, 0.00195312500f, 0.00097656250f, 0.00048828125f, 0.00024414063f, + 0.00003051758f + }; + + // subbands 11-22 in tables 3-B.2a and 2b: + public static final int[] table_ab3_codelength = { + 0, 5, 7, 3, 10, 4, 5, 16 + }; + public static final float[] table_ab3_factor = { + 0.0f, 1.0f / 2.0f, 1.0f / 4.0f, 1.0f / 4.0f, 1.0f / 8.0f, 1.0f / 8.0f, 1.0f / 16.0f, 1.0f / 32768.0f + }; + public static final float[] table_ab3_c = { + 0.0f, 1.33333333333f, 1.60000000000f, 1.14285714286f, 1.77777777777f, + 1.06666666666f, 1.03225806452f, 1.00001525902f + }; + public static final float[] table_ab3_d = { + 0.0f, 0.50000000000f, 0.50000000000f, 0.25000000000f, 0.50000000000f, + 0.12500000000f, 0.06250000000f, 0.00003051758f + }; + + // subbands 23-... in tables 3-B.2a and 2b: + public static final int[] table_ab4_codelength = {0, 5, 7, 16}; + public static final float[] table_ab4_factor = {0.0f, 1.0f / 2.0f, 1.0f / 4.0f, 1.0f / 32768.0f}; + public static final float[] table_ab4_c = {0.0f, 1.33333333333f, 1.60000000000f, 1.00001525902f}; + public static final float[] table_ab4_d = {0.0f, 0.50000000000f, 0.50000000000f, 0.00003051758f}; + + // subbands in tables 3-B.2c and 2d: + public static final int[] table_cd_codelength = { + 0, 5, 7, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + }; + public static final float[][] table_cd_groupingtables = { + null, grouping_5bits, grouping_7bits, grouping_10bits, null, null, null, null, + null, null, null, null, null, null, null, null + }; + public static final float[] table_cd_factor = { + 0.0f, 1.0f / 2.0f, 1.0f / 4.0f, 1.0f / 8.0f, 1.0f / 8.0f, 1.0f / 16.0f, 1.0f / 32.0f, 1.0f / 64.0f, + 1.0f / 128.0f, 1.0f / 256.0f, 1.0f / 512.0f, 1.0f / 1024.0f, 1.0f / 2048.0f, 1.0f / 4096.0f, + 1.0f / 8192.0f, 1.0f / 16384.0f + }; + public static final float[] table_cd_c = { + 0.0f, 1.33333333333f, 1.60000000000f, 1.77777777777f, 1.06666666666f, + 1.03225806452f, 1.01587301587f, 1.00787401575f, 1.00392156863f, 1.00195694716f, + 1.00097751711f, 1.00048851979f, 1.00024420024f, 1.00012208522f, 1.00006103888f, + 1.00003051851f + }; + public static final float[] table_cd_d = { + 0.0f, 0.50000000000f, 0.50000000000f, 0.50000000000f, 0.12500000000f, + 0.06250000000f, 0.03125000000f, 0.01562500000f, 0.00781250000f, 0.00390625000f, + 0.00195312500f, 0.00097656250f, 0.00048828125f, 0.00024414063f, 0.00012207031f, + 0.00006103516f + }; + + protected int subbandNumber; + protected int allocation; + protected int scfsi; + protected float scaleFactor1, scaleFactor2, scaleFactor3; + protected int[] codeLength = {0}; + protected float[][] groupingtable = new float[2][]; + protected float[] factor = {0.0f}; + protected int groupNumber; + protected int sampleNumber; + protected float[] samples = new float[3]; + protected float[] c = {0}; + protected float[] d = {0}; + + /** + * Constructor + */ + public SubbandLayer2(int subbandNumber) { + this.subbandNumber = subbandNumber; + groupNumber = sampleNumber = 0; + } + + /** + * + */ + protected int get_allocationlength(Header header) { + if (header.version() == Header.MPEG1) { + int channel_bitrate = header.bitrate_index(); + + // calculate bitrate per channel: + if (header.mode() != Header.SINGLE_CHANNEL) + if (channel_bitrate == 4) + channel_bitrate = 1; + else + channel_bitrate -= 4; + + if (channel_bitrate == 1 || channel_bitrate == 2) + // table 3-B.2c or 3-B.2d + if (subbandNumber <= 1) + return 4; + else + return 3; + else + // tables 3-B.2a or 3-B.2b + if (subbandNumber <= 10) + return 4; + else if (subbandNumber <= 22) + return 3; + else + return 2; + } else { // MPEG-2 LSF -- Jeff + + // table B.1 of ISO/IEC 13818-3 + if (subbandNumber <= 3) + return 4; + else if (subbandNumber <= 10) + return 3; + else + return 2; + } + } + + /** + * + */ + protected void prepare_sample_reading(Header header, int allocation, + //float[][] groupingtable, + int channel, + float[] factor, int[] codeLength, + float[] c, float[] d) { + int channelBitrate = header.bitrate_index(); + // calculate bitrate per channel: + if (header.mode() != Header.SINGLE_CHANNEL) + if (channelBitrate == 4) + channelBitrate = 1; + else + channelBitrate -= 4; + + if (channelBitrate == 1 || channelBitrate == 2) { + // table 3-B.2c or 3-B.2d + groupingtable[channel] = table_cd_groupingtables[allocation]; + factor[0] = table_cd_factor[allocation]; + codeLength[0] = table_cd_codelength[allocation]; + c[0] = table_cd_c[allocation]; + d[0] = table_cd_d[allocation]; + } else { + // tables 3-B.2a or 3-B.2b + if (subbandNumber <= 2) { + groupingtable[channel] = table_ab1_groupingtables[allocation]; + factor[0] = table_ab1_factor[allocation]; + codeLength[0] = table_ab1_codelength[allocation]; + c[0] = table_ab1_c[allocation]; + d[0] = table_ab1_d[allocation]; + } else { + groupingtable[channel] = table_ab234_groupingtables[allocation]; + if (subbandNumber <= 10) { + factor[0] = table_ab2_factor[allocation]; + codeLength[0] = table_ab2_codelength[allocation]; + c[0] = table_ab2_c[allocation]; + d[0] = table_ab2_d[allocation]; + } else if (subbandNumber <= 22) { + factor[0] = table_ab3_factor[allocation]; + codeLength[0] = table_ab3_codelength[allocation]; + c[0] = table_ab3_c[allocation]; + d[0] = table_ab3_d[allocation]; + } else { + factor[0] = table_ab4_factor[allocation]; + codeLength[0] = table_ab4_codelength[allocation]; + c[0] = table_ab4_c[allocation]; + d[0] = table_ab4_d[allocation]; + } + } + } + } + + /** + * + */ + public void read_allocation(Bitstream stream, Header header, Crc16 crc) { + int length = get_allocationlength(header); + allocation = stream.get_bits(length); + if (crc != null) + crc.add_bits(allocation, length); + } + + /** + * + */ + public void read_scalefactor_selection(Bitstream stream, Crc16 crc) { + if (allocation != 0) { + scfsi = stream.get_bits(2); + if (crc != null) crc.add_bits(scfsi, 2); + } + } + + /** + * + */ + public void read_scalefactor(Bitstream stream, Header header) { + if (allocation != 0) { + switch (scfsi) { + case 0: + scaleFactor1 = scaleFactors[stream.get_bits(6)]; + scaleFactor2 = scaleFactors[stream.get_bits(6)]; + scaleFactor3 = scaleFactors[stream.get_bits(6)]; + break; + case 1: + scaleFactor1 = scaleFactor2 = scaleFactors[stream.get_bits(6)]; + scaleFactor3 = scaleFactors[stream.get_bits(6)]; + break; + case 2: + scaleFactor1 = scaleFactor2 = scaleFactor3 = scaleFactors[stream.get_bits(6)]; + break; + case 3: + scaleFactor1 = scaleFactors[stream.get_bits(6)]; + scaleFactor2 = scaleFactor3 = scaleFactors[stream.get_bits(6)]; + break; + } + prepare_sample_reading(header, allocation, 0, + factor, codeLength, c, d); + } + } + + /** + * + */ + public boolean read_sampledata(Bitstream stream) { + if (allocation != 0) + if (groupingtable[0] != null) { + int samplecode = stream.get_bits(codeLength[0]); + // create requantized samples: + samplecode += samplecode << 1; + float[] target = samples; + float[] source = groupingtable[0]; + //Bugfix: + int tmp = 0; + int temp = samplecode; + + if (temp > source.length - 3) temp = source.length - 3; + + target[tmp] = source[temp]; + temp++; + tmp++; + target[tmp] = source[temp]; + temp++; + tmp++; + target[tmp] = source[temp]; + + // memcpy (samples, groupingtable + samplecode, 3 * sizeof (real)); + } else { + samples[0] = (float) ((stream.get_bits(codeLength[0])) * factor[0] - 1.0); + samples[1] = (float) ((stream.get_bits(codeLength[0])) * factor[0] - 1.0); + samples[2] = (float) ((stream.get_bits(codeLength[0])) * factor[0] - 1.0); + } + + sampleNumber = 0; + return ++groupNumber == 12; + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) { + if ((allocation != 0) && (channels != OutputChannels.RIGHT_CHANNEL)) { + float sample = samples[sampleNumber]; + + if (groupingtable[0] == null) + sample = (sample + d[0]) * c[0]; + if (groupNumber <= 4) + sample *= scaleFactor1; + else if (groupNumber <= 8) + sample *= scaleFactor2; + else + sample *= scaleFactor3; + filter1.input_sample(sample, subbandNumber); + } + + return ++sampleNumber == 3; + } + } + + /** + * Class for layer II subbands in joint stereo mode. + */ + static class SubbandLayer2IntensityStereo extends SubbandLayer2 { + protected int channel2_scfsi; + protected float channel2_scalefactor1, channel2_scalefactor2, channel2_scalefactor3; + + /** + * Constructor + */ + public SubbandLayer2IntensityStereo(int subbandnumber) { + super(subbandnumber); + } + + /** + * + */ + public void read_allocation(Bitstream stream, Header header, Crc16 crc) { + super.read_allocation(stream, header, crc); + } + + /** + * + */ + public void read_scalefactor_selection(Bitstream stream, Crc16 crc) { + if (allocation != 0) { + scfsi = stream.get_bits(2); + channel2_scfsi = stream.get_bits(2); + if (crc != null) { + crc.add_bits(scfsi, 2); + crc.add_bits(channel2_scfsi, 2); + } + } + } + + /** + * + */ + public void read_scalefactor(Bitstream stream, Header header) { + if (allocation != 0) { + super.read_scalefactor(stream, header); + switch (channel2_scfsi) { + case 0: + channel2_scalefactor1 = scaleFactors[stream.get_bits(6)]; + channel2_scalefactor2 = scaleFactors[stream.get_bits(6)]; + channel2_scalefactor3 = scaleFactors[stream.get_bits(6)]; + break; + + case 1: + channel2_scalefactor1 = channel2_scalefactor2 = scaleFactors[stream.get_bits(6)]; + channel2_scalefactor3 = scaleFactors[stream.get_bits(6)]; + break; + + case 2: + channel2_scalefactor1 = channel2_scalefactor2 = + channel2_scalefactor3 = scaleFactors[stream.get_bits(6)]; + break; + + case 3: + channel2_scalefactor1 = scaleFactors[stream.get_bits(6)]; + channel2_scalefactor2 = channel2_scalefactor3 = scaleFactors[stream.get_bits(6)]; + break; + } + } + } + + /** + * + */ + public boolean read_sampledata(Bitstream stream) { + return super.read_sampledata(stream); + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) { + if (allocation != 0) { + float sample = samples[sampleNumber]; + + if (groupingtable[0] == null) + sample = (sample + d[0]) * c[0]; + if (channels == OutputChannels.BOTH_CHANNELS) { + float sample2 = sample; + if (groupNumber <= 4) { + sample *= scaleFactor1; + sample2 *= channel2_scalefactor1; + } else if (groupNumber <= 8) { + sample *= scaleFactor2; + sample2 *= channel2_scalefactor2; + } else { + sample *= scaleFactor3; + sample2 *= channel2_scalefactor3; + } + filter1.input_sample(sample, subbandNumber); + filter2.input_sample(sample2, subbandNumber); + } else if (channels == OutputChannels.LEFT_CHANNEL) { + if (groupNumber <= 4) + sample *= scaleFactor1; + else if (groupNumber <= 8) + sample *= scaleFactor2; + else + sample *= scaleFactor3; + filter1.input_sample(sample, subbandNumber); + } else { + if (groupNumber <= 4) + sample *= channel2_scalefactor1; + else if (groupNumber <= 8) + sample *= channel2_scalefactor2; + else + sample *= channel2_scalefactor3; + filter1.input_sample(sample, subbandNumber); + } + } + + return ++sampleNumber == 3; + } + } + + /** + * Class for layer II subbands in stereo mode. + */ + static class SubbandLayer2Stereo extends SubbandLayer2 { + protected int channel2Allocation; + protected int channel2_scfsi; + protected float channel2ScaleFactor1, channel2ScaleFactor2, channel2_scalefactor3; + //protected boolean channel2_grouping; ???? Never used! + protected int[] channel2_codelength = {0}; + //protected float[][] channel2_groupingtable = {{0},{0}}; + protected float[] channel2_factor = {0}; + protected float[] channel2_samples; + protected float[] channel2_c = {0}; + protected float[] channel2_d = {0}; + + /** + * Constructor + */ + public SubbandLayer2Stereo(int subbandnumber) { + super(subbandnumber); + channel2_samples = new float[3]; + } + + /** + * + */ + public void read_allocation(Bitstream stream, Header header, Crc16 crc) { + int length = get_allocationlength(header); + allocation = stream.get_bits(length); + channel2Allocation = stream.get_bits(length); + if (crc != null) { + crc.add_bits(allocation, length); + crc.add_bits(channel2Allocation, length); + } + } + + /** + * + */ + public void read_scalefactor_selection(Bitstream stream, Crc16 crc) { + if (allocation != 0) { + scfsi = stream.get_bits(2); + if (crc != null) + crc.add_bits(scfsi, 2); + } + if (channel2Allocation != 0) { + channel2_scfsi = stream.get_bits(2); + if (crc != null) + crc.add_bits(channel2_scfsi, 2); + } + } + + /** + * + */ + public void read_scalefactor(Bitstream stream, Header header) { + super.read_scalefactor(stream, header); + if (channel2Allocation != 0) { + switch (channel2_scfsi) { + case 0: + channel2ScaleFactor1 = scaleFactors[stream.get_bits(6)]; + channel2ScaleFactor2 = scaleFactors[stream.get_bits(6)]; + channel2_scalefactor3 = scaleFactors[stream.get_bits(6)]; + break; + + case 1: + channel2ScaleFactor1 = channel2ScaleFactor2 = + scaleFactors[stream.get_bits(6)]; + channel2_scalefactor3 = scaleFactors[stream.get_bits(6)]; + break; + + case 2: + channel2ScaleFactor1 = channel2ScaleFactor2 = + channel2_scalefactor3 = scaleFactors[stream.get_bits(6)]; + break; + + case 3: + channel2ScaleFactor1 = scaleFactors[stream.get_bits(6)]; + channel2ScaleFactor2 = channel2_scalefactor3 = + scaleFactors[stream.get_bits(6)]; + break; + } + prepare_sample_reading(header, channel2Allocation, 1, + channel2_factor, channel2_codelength, channel2_c, + channel2_d); + } + } + + /** + * + */ + public boolean read_sampledata(Bitstream stream) { + boolean returnValue = super.read_sampledata(stream); + + if (channel2Allocation != 0) + if (groupingtable[1] != null) { + int sampleCode = stream.get_bits(channel2_codelength[0]); + // create requantized samples: + sampleCode += sampleCode << 1; + float[] target = channel2_samples; + float[] source = groupingtable[1]; + int tmp = 0; + int temp = sampleCode; + target[tmp] = source[temp]; + temp++; + tmp++; + target[tmp] = source[temp]; + temp++; + tmp++; + target[tmp] = source[temp]; + + } else { + channel2_samples[0] = (float) ((stream.get_bits(channel2_codelength[0])) * + channel2_factor[0] - 1.0); + channel2_samples[1] = (float) ((stream.get_bits(channel2_codelength[0])) * + channel2_factor[0] - 1.0); + channel2_samples[2] = (float) ((stream.get_bits(channel2_codelength[0])) * + channel2_factor[0] - 1.0); + } + return returnValue; + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) { + boolean returnValue = super.put_next_sample(channels, filter1, filter2); + if ((channel2Allocation != 0) && (channels != OutputChannels.LEFT_CHANNEL)) { + float sample = channel2_samples[sampleNumber - 1]; + + if (groupingtable[1] == null) + sample = (sample + channel2_d[0]) * channel2_c[0]; + + if (groupNumber <= 4) + sample *= channel2ScaleFactor1; + else if (groupNumber <= 8) + sample *= channel2ScaleFactor2; + else + sample *= channel2_scalefactor3; + if (channels == OutputChannels.BOTH_CHANNELS) + filter2.input_sample(sample, subbandNumber); + else + filter1.input_sample(sample, subbandNumber); + } + return returnValue; + } + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/LayerIIIDecoder.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/LayerIIIDecoder.java new file mode 100644 index 000000000..1f3be7eb6 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/LayerIIIDecoder.java @@ -0,0 +1,2013 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 18/06/01 Michael Scheerer, Fixed bugs which causes + * negative indexes in method huffmann_decode and in method + * dequanisize_sample. + * + * 16/07/01 Michael Scheerer, Catched a bug in method + * huffmann_decode, which causes an outOfIndexException. + * Cause : Indexnumber of 24 at SfBandIndex, + * which has only a length of 22. I have simply and dirty + * fixed the index to <= 22, because I'm not really be able + * to fix the bug. The Indexnumber is taken from the MP3 + * file and the origin Ma-Player with the same code works + * well. + * + * 02/19/99 Java Conversion by E.B, javalayer@javazoom.net + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Class Implementing Layer 3 Decoder. + * + * @since 0.0 + */ +final class LayerIIIDecoder implements FrameDecoder { + + static final double d43 = (4.0 / 3.0); + + public int[] scalefac_buffer; + + private int checkSumHuff = 0; + private int[] is_1d; + private float[][][] ro; + private float[][][] lr; + private float[] out_1d; + private float[][] prevblck; + private float[][] k; + private int[] nonzero; + private Bitstream stream; + private Header header; + private SynthesisFilter filter1, filter2; + private Obuffer buffer; + private int which_channels; + private BitReserve br; + private III_side_info_t si; + + private temporaire2[] III_scalefac_t; + private temporaire2[] scalefac; + + private int max_gr; + private int frame_start; + private int part2_start; + private int channels; + private int first_channel; + private int last_channel; + private int sfreq; + + /** + * Constructor. + *

+ * REVIEW: these constructor arguments should be moved to the + * decodeFrame() method, where possible, so that one + */ + public LayerIIIDecoder(Bitstream stream0, Header header0, + SynthesisFilter filtera, SynthesisFilter filterb, + Obuffer buffer0, int which_ch0) { + huffcodetab.initHuff(); + is_1d = new int[SBLIMIT * SSLIMIT + 4]; + ro = new float[2][SBLIMIT][SSLIMIT]; + lr = new float[2][SBLIMIT][SSLIMIT]; + out_1d = new float[SBLIMIT * SSLIMIT]; + prevblck = new float[2][SBLIMIT * SSLIMIT]; + k = new float[2][SBLIMIT * SSLIMIT]; + nonzero = new int[2]; + + // III_scalefact_t + III_scalefac_t = new temporaire2[2]; + III_scalefac_t[0] = new temporaire2(); + III_scalefac_t[1] = new temporaire2(); + scalefac = III_scalefac_t; + + // L3TABLE INIT + + sfBandIndex = new SBI[9]; // SZD: MPEG2.5 +3 indices + int[] l0 = {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576}; + int[] s0 = {0, 4, 8, 12, 18, 24, 32, 42, 56, 74, 100, 132, 174, 192}; + int[] l1 = {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 114, 136, 162, 194, 232, 278, 330, 394, 464, 540, 576}; + int[] s1 = {0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 136, 180, 192}; + int[] l2 = {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576}; + int[] s2 = {0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192}; + + int[] l3 = {0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418, 576}; + int[] s3 = {0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192}; + int[] l4 = {0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384, 576}; + int[] s4 = {0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192}; + int[] l5 = {0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550, 576}; + int[] s5 = {0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192}; + // SZD: MPEG2.5 + int[] l6 = {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576}; + int[] s6 = {0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192}; + int[] l7 = {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576}; + int[] s7 = {0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192}; + int[] l8 = {0, 12, 24, 36, 48, 60, 72, 88, 108, 132, 160, 192, 232, 280, 336, 400, 476, 566, 568, 570, 572, 574, 576}; + int[] s8 = {0, 8, 16, 24, 36, 52, 72, 96, 124, 160, 162, 164, 166, 192}; + + sfBandIndex[0] = new SBI(l0, s0); + sfBandIndex[1] = new SBI(l1, s1); + sfBandIndex[2] = new SBI(l2, s2); + + sfBandIndex[3] = new SBI(l3, s3); + sfBandIndex[4] = new SBI(l4, s4); + sfBandIndex[5] = new SBI(l5, s5); + // SZD: MPEG2.5 + sfBandIndex[6] = new SBI(l6, s6); + sfBandIndex[7] = new SBI(l7, s7); + sfBandIndex[8] = new SBI(l8, s8); + + // END OF L3TABLE INIT + + if (reorder_table == null) { // SZD: generate LUT + reorder_table = new int[9][]; + for (int i = 0; i < 9; i++) + reorder_table[i] = reorder(sfBandIndex[i].s); + } + + // Sftable + int[] ll0 = {0, 6, 11, 16, 21}; + int[] ss0 = {0, 6, 12}; + sftable = new Sftable(ll0, ss0); + // END OF Sftable + + // scalefac_buffer + scalefac_buffer = new int[54]; + // END OF scalefac_buffer + + stream = stream0; + header = header0; + filter1 = filtera; + filter2 = filterb; + buffer = buffer0; + which_channels = which_ch0; + + frame_start = 0; + channels = (header.mode() == Header.SINGLE_CHANNEL) ? 1 : 2; + max_gr = (header.version() == Header.MPEG1) ? 2 : 1; + + sfreq = header.sample_frequency() + + ((header.version() == Header.MPEG1) ? 3 : + (header.version() == Header.MPEG25_LSF) ? 6 : 0); // SZD + + if (channels == 2) { + switch (which_channels) { + case OutputChannels.LEFT_CHANNEL: + case OutputChannels.DOWNMIX_CHANNELS: + first_channel = last_channel = 0; + break; + + case OutputChannels.RIGHT_CHANNEL: + first_channel = last_channel = 1; + break; + + case OutputChannels.BOTH_CHANNELS: + default: + first_channel = 0; + last_channel = 1; + break; + } + } else { + first_channel = last_channel = 0; + } + + for (int ch = 0; ch < 2; ch++) + for (int j = 0; j < 576; j++) + prevblck[ch][j] = 0.0f; + + nonzero[0] = nonzero[1] = 576; + + br = new BitReserve(); + si = new III_side_info_t(); + } + + /** + * Notify decoder that a seek is being made. + */ + public void seek_notify() { + frame_start = 0; + for (int ch = 0; ch < 2; ch++) + for (int j = 0; j < 576; j++) + prevblck[ch][j] = 0.0f; + br = new BitReserve(); + } + + public void decodeFrame() { + decode(); + } + + // subband samples are buffered and passed to the + // SynthesisFilter in one go. + private float[] samples1 = new float[32]; + private float[] samples2 = new float[32]; + + /** + * Decode one frame, filling the buffer with the output samples. + */ + public void decode() { + int nSlots = header.slots(); + int flush_main; + int gr, ch, ss, sb, sb18; + int main_data_end; + int bytes_to_discard; + int i; + + get_side_info(); + + for (i = 0; i < nSlots; i++) + br.hputbuf(stream.get_bits(8)); + + main_data_end = br.hsstell() >>> 3; // of previous frame + + if ((flush_main = (br.hsstell() & 7)) != 0) { + br.hgetbits(8 - flush_main); + main_data_end++; + } + + bytes_to_discard = frame_start - main_data_end + - si.main_data_begin; + + frame_start += nSlots; + + if (bytes_to_discard < 0) + return; + + if (main_data_end > 4096) { + frame_start -= 4096; + br.rewindNbytes(4096); + } + + for (; bytes_to_discard > 0; bytes_to_discard--) + br.hgetbits(8); + + for (gr = 0; gr < max_gr; gr++) { + + for (ch = 0; ch < channels; ch++) { + part2_start = br.hsstell(); + + if (header.version() == Header.MPEG1) + get_scale_factors(ch, gr); + else // MPEG-2 LSF, SZD: MPEG-2.5 LSF + get_LSF_scale_factors(ch, gr); + + huffman_decode(ch, gr); + dequantize_sample(ro[ch], ch, gr); + } + + stereo(gr); + + if ((which_channels == OutputChannels.DOWNMIX_CHANNELS) && (channels > 1)) + do_downmix(); + + for (ch = first_channel; ch <= last_channel; ch++) { + + reorder(lr[ch], ch, gr); + antialias(ch, gr); + + hybrid(ch, gr); + + for (sb18 = 18; sb18 < 576; sb18 += 36) // Frequency inversion + for (ss = 1; ss < SSLIMIT; ss += 2) + out_1d[sb18 + ss] = -out_1d[sb18 + ss]; + + if ((ch == 0) || (which_channels == OutputChannels.RIGHT_CHANNEL)) { + for (ss = 0; ss < SSLIMIT; ss++) { // Polyphase synthesis + sb = 0; + for (sb18 = 0; sb18 < 576; sb18 += 18) { + samples1[sb] = out_1d[sb18 + ss]; + sb++; + } + filter1.input_samples(samples1); + filter1.calculate_pcm_samples(buffer); + } + } else { + for (ss = 0; ss < SSLIMIT; ss++) { // Polyphase synthesis + sb = 0; + for (sb18 = 0; sb18 < 576; sb18 += 18) { + samples2[sb] = out_1d[sb18 + ss]; + sb++; + } + filter2.input_samples(samples2); + filter2.calculate_pcm_samples(buffer); + } + + } + } + } + + counter++; + buffer.write_buffer(1); + } + + /** + * Reads the side info from the stream, assuming the entire. + * frame has been read already. + * Mono : 136 bits (= 17 bytes) + * Stereo : 256 bits (= 32 bytes) + */ + private boolean get_side_info() { + int ch, gr; + if (header.version() == Header.MPEG1) { + + si.main_data_begin = stream.get_bits(9); + if (channels == 1) + si.private_bits = stream.get_bits(5); + else si.private_bits = stream.get_bits(3); + + for (ch = 0; ch < channels; ch++) { + si.ch[ch].scfsi[0] = stream.get_bits(1); + si.ch[ch].scfsi[1] = stream.get_bits(1); + si.ch[ch].scfsi[2] = stream.get_bits(1); + si.ch[ch].scfsi[3] = stream.get_bits(1); + } + + for (gr = 0; gr < 2; gr++) { + for (ch = 0; ch < channels; ch++) { + si.ch[ch].gr[gr].part2_3_length = stream.get_bits(12); + si.ch[ch].gr[gr].big_values = stream.get_bits(9); + si.ch[ch].gr[gr].global_gain = stream.get_bits(8); + si.ch[ch].gr[gr].scalefac_compress = stream.get_bits(4); + si.ch[ch].gr[gr].window_switching_flag = stream.get_bits(1); + if ((si.ch[ch].gr[gr].window_switching_flag) != 0) { + si.ch[ch].gr[gr].block_type = stream.get_bits(2); + si.ch[ch].gr[gr].mixed_block_flag = stream.get_bits(1); + + si.ch[ch].gr[gr].table_select[0] = stream.get_bits(5); + si.ch[ch].gr[gr].table_select[1] = stream.get_bits(5); + + si.ch[ch].gr[gr].subblock_gain[0] = stream.get_bits(3); + si.ch[ch].gr[gr].subblock_gain[1] = stream.get_bits(3); + si.ch[ch].gr[gr].subblock_gain[2] = stream.get_bits(3); + + // Set region_count parameters since they are implicit in this case. + + if (si.ch[ch].gr[gr].block_type == 0) { + // Side info bad: block_type == 0 in split block + return false; + } else if (si.ch[ch].gr[gr].block_type == 2 + && si.ch[ch].gr[gr].mixed_block_flag == 0) { + si.ch[ch].gr[gr].region0_count = 8; + } else { + si.ch[ch].gr[gr].region0_count = 7; + } + si.ch[ch].gr[gr].region1_count = 20 - + si.ch[ch].gr[gr].region0_count; + } else { + si.ch[ch].gr[gr].table_select[0] = stream.get_bits(5); + si.ch[ch].gr[gr].table_select[1] = stream.get_bits(5); + si.ch[ch].gr[gr].table_select[2] = stream.get_bits(5); + si.ch[ch].gr[gr].region0_count = stream.get_bits(4); + si.ch[ch].gr[gr].region1_count = stream.get_bits(3); + si.ch[ch].gr[gr].block_type = 0; + } + si.ch[ch].gr[gr].preflag = stream.get_bits(1); + si.ch[ch].gr[gr].scalefac_scale = stream.get_bits(1); + si.ch[ch].gr[gr].count1table_select = stream.get_bits(1); + } + } + } else { // MPEG-2 LSF, SZD: MPEG-2.5 LSF + + si.main_data_begin = stream.get_bits(8); + if (channels == 1) + si.private_bits = stream.get_bits(1); + else si.private_bits = stream.get_bits(2); + + for (ch = 0; ch < channels; ch++) { + + si.ch[ch].gr[0].part2_3_length = stream.get_bits(12); + si.ch[ch].gr[0].big_values = stream.get_bits(9); + si.ch[ch].gr[0].global_gain = stream.get_bits(8); + si.ch[ch].gr[0].scalefac_compress = stream.get_bits(9); + si.ch[ch].gr[0].window_switching_flag = stream.get_bits(1); + + if ((si.ch[ch].gr[0].window_switching_flag) != 0) { + + si.ch[ch].gr[0].block_type = stream.get_bits(2); + si.ch[ch].gr[0].mixed_block_flag = stream.get_bits(1); + si.ch[ch].gr[0].table_select[0] = stream.get_bits(5); + si.ch[ch].gr[0].table_select[1] = stream.get_bits(5); + + si.ch[ch].gr[0].subblock_gain[0] = stream.get_bits(3); + si.ch[ch].gr[0].subblock_gain[1] = stream.get_bits(3); + si.ch[ch].gr[0].subblock_gain[2] = stream.get_bits(3); + + // Set region_count parameters since they are implicit in this case. + + if (si.ch[ch].gr[0].block_type == 0) { + // Side info bad: block_type == 0 in split block + return false; + } else if (si.ch[ch].gr[0].block_type == 2 + && si.ch[ch].gr[0].mixed_block_flag == 0) { + si.ch[ch].gr[0].region0_count = 8; + } else { + si.ch[ch].gr[0].region0_count = 7; + si.ch[ch].gr[0].region1_count = 20 - + si.ch[ch].gr[0].region0_count; + } + + } else { + si.ch[ch].gr[0].table_select[0] = stream.get_bits(5); + si.ch[ch].gr[0].table_select[1] = stream.get_bits(5); + si.ch[ch].gr[0].table_select[2] = stream.get_bits(5); + si.ch[ch].gr[0].region0_count = stream.get_bits(4); + si.ch[ch].gr[0].region1_count = stream.get_bits(3); + si.ch[ch].gr[0].block_type = 0; + } + + si.ch[ch].gr[0].scalefac_scale = stream.get_bits(1); + si.ch[ch].gr[0].count1table_select = stream.get_bits(1); + } + } + return true; + } + + /** + * + */ + private void get_scale_factors(int ch, int gr) { + int sfb, window; + gr_info_s gr_info = (si.ch[ch].gr[gr]); + int scale_comp = gr_info.scalefac_compress; + int length0 = slen[0][scale_comp]; + int length1 = slen[1][scale_comp]; + + if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) { + if ((gr_info.mixed_block_flag) != 0) { // MIXED + for (sfb = 0; sfb < 8; sfb++) + scalefac[ch].l[sfb] = br.hgetbits( + slen[0][gr_info.scalefac_compress]); + for (sfb = 3; sfb < 6; sfb++) + for (window = 0; window < 3; window++) + scalefac[ch].s[window][sfb] = br.hgetbits( + slen[0][gr_info.scalefac_compress]); + for (sfb = 6; sfb < 12; sfb++) + for (window = 0; window < 3; window++) + scalefac[ch].s[window][sfb] = br.hgetbits( + slen[1][gr_info.scalefac_compress]); + for (sfb = 12, window = 0; window < 3; window++) + scalefac[ch].s[window][sfb] = 0; + + } else { // SHORT + + scalefac[ch].s[0][0] = br.hgetbits(length0); + scalefac[ch].s[1][0] = br.hgetbits(length0); + scalefac[ch].s[2][0] = br.hgetbits(length0); + scalefac[ch].s[0][1] = br.hgetbits(length0); + scalefac[ch].s[1][1] = br.hgetbits(length0); + scalefac[ch].s[2][1] = br.hgetbits(length0); + scalefac[ch].s[0][2] = br.hgetbits(length0); + scalefac[ch].s[1][2] = br.hgetbits(length0); + scalefac[ch].s[2][2] = br.hgetbits(length0); + scalefac[ch].s[0][3] = br.hgetbits(length0); + scalefac[ch].s[1][3] = br.hgetbits(length0); + scalefac[ch].s[2][3] = br.hgetbits(length0); + scalefac[ch].s[0][4] = br.hgetbits(length0); + scalefac[ch].s[1][4] = br.hgetbits(length0); + scalefac[ch].s[2][4] = br.hgetbits(length0); + scalefac[ch].s[0][5] = br.hgetbits(length0); + scalefac[ch].s[1][5] = br.hgetbits(length0); + scalefac[ch].s[2][5] = br.hgetbits(length0); + scalefac[ch].s[0][6] = br.hgetbits(length1); + scalefac[ch].s[1][6] = br.hgetbits(length1); + scalefac[ch].s[2][6] = br.hgetbits(length1); + scalefac[ch].s[0][7] = br.hgetbits(length1); + scalefac[ch].s[1][7] = br.hgetbits(length1); + scalefac[ch].s[2][7] = br.hgetbits(length1); + scalefac[ch].s[0][8] = br.hgetbits(length1); + scalefac[ch].s[1][8] = br.hgetbits(length1); + scalefac[ch].s[2][8] = br.hgetbits(length1); + scalefac[ch].s[0][9] = br.hgetbits(length1); + scalefac[ch].s[1][9] = br.hgetbits(length1); + scalefac[ch].s[2][9] = br.hgetbits(length1); + scalefac[ch].s[0][10] = br.hgetbits(length1); + scalefac[ch].s[1][10] = br.hgetbits(length1); + scalefac[ch].s[2][10] = br.hgetbits(length1); + scalefac[ch].s[0][11] = br.hgetbits(length1); + scalefac[ch].s[1][11] = br.hgetbits(length1); + scalefac[ch].s[2][11] = br.hgetbits(length1); + scalefac[ch].s[0][12] = 0; + scalefac[ch].s[1][12] = 0; + scalefac[ch].s[2][12] = 0; + } // SHORT + + } else { // LONG types 0,1,3 + + if ((si.ch[ch].scfsi[0] == 0) || (gr == 0)) { + scalefac[ch].l[0] = br.hgetbits(length0); + scalefac[ch].l[1] = br.hgetbits(length0); + scalefac[ch].l[2] = br.hgetbits(length0); + scalefac[ch].l[3] = br.hgetbits(length0); + scalefac[ch].l[4] = br.hgetbits(length0); + scalefac[ch].l[5] = br.hgetbits(length0); + } + if ((si.ch[ch].scfsi[1] == 0) || (gr == 0)) { + scalefac[ch].l[6] = br.hgetbits(length0); + scalefac[ch].l[7] = br.hgetbits(length0); + scalefac[ch].l[8] = br.hgetbits(length0); + scalefac[ch].l[9] = br.hgetbits(length0); + scalefac[ch].l[10] = br.hgetbits(length0); + } + if ((si.ch[ch].scfsi[2] == 0) || (gr == 0)) { + scalefac[ch].l[11] = br.hgetbits(length1); + scalefac[ch].l[12] = br.hgetbits(length1); + scalefac[ch].l[13] = br.hgetbits(length1); + scalefac[ch].l[14] = br.hgetbits(length1); + scalefac[ch].l[15] = br.hgetbits(length1); + } + if ((si.ch[ch].scfsi[3] == 0) || (gr == 0)) { + scalefac[ch].l[16] = br.hgetbits(length1); + scalefac[ch].l[17] = br.hgetbits(length1); + scalefac[ch].l[18] = br.hgetbits(length1); + scalefac[ch].l[19] = br.hgetbits(length1); + scalefac[ch].l[20] = br.hgetbits(length1); + } + + scalefac[ch].l[21] = 0; + scalefac[ch].l[22] = 0; + } + } + + // MDM: new_slen is fully initialized before use, no need + // to reallocate array. + private final int[] new_slen = new int[4]; + + /** + * + */ + private void get_LSF_scale_data(int ch, int gr) { + + int scalefac_comp, int_scalefac_comp; + int mode_ext = header.mode_extension(); + int m; + int blocktypenumber; + int blocknumber = 0; + + gr_info_s gr_info = (si.ch[ch].gr[gr]); + + scalefac_comp = gr_info.scalefac_compress; + + if (gr_info.block_type == 2) { + if (gr_info.mixed_block_flag == 0) + blocktypenumber = 1; + else if (gr_info.mixed_block_flag == 1) + blocktypenumber = 2; + else + blocktypenumber = 0; + } else { + blocktypenumber = 0; + } + + if (!(((mode_ext == 1) || (mode_ext == 3)) && (ch == 1))) { + + if (scalefac_comp < 400) { + + new_slen[0] = (scalefac_comp >>> 4) / 5; + new_slen[1] = (scalefac_comp >>> 4) % 5; + new_slen[2] = (scalefac_comp & 0xF) >>> 2; + new_slen[3] = (scalefac_comp & 3); + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 0; + + } else if (scalefac_comp < 500) { + + new_slen[0] = ((scalefac_comp - 400) >>> 2) / 5; + new_slen[1] = ((scalefac_comp - 400) >>> 2) % 5; + new_slen[2] = (scalefac_comp - 400) & 3; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 1; + + } else if (scalefac_comp < 512) { + + new_slen[0] = (scalefac_comp - 500) / 3; + new_slen[1] = (scalefac_comp - 500) % 3; + new_slen[2] = 0; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 1; + blocknumber = 2; + } + } + + if ((((mode_ext == 1) || (mode_ext == 3)) && (ch == 1))) { + int_scalefac_comp = scalefac_comp >>> 1; + + if (int_scalefac_comp < 180) { + new_slen[0] = int_scalefac_comp / 36; + new_slen[1] = (int_scalefac_comp % 36) / 6; + new_slen[2] = (int_scalefac_comp % 36) % 6; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 3; + } else if (int_scalefac_comp < 244) { + new_slen[0] = ((int_scalefac_comp - 180) & 0x3F) >>> 4; + new_slen[1] = ((int_scalefac_comp - 180) & 0xF) >>> 2; + new_slen[2] = (int_scalefac_comp - 180) & 3; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 4; + } else if (int_scalefac_comp < 255) { + new_slen[0] = (int_scalefac_comp - 244) / 3; + new_slen[1] = (int_scalefac_comp - 244) % 3; + new_slen[2] = 0; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 5; + } + } + + for (int x = 0; x < 45; x++) // why 45, not 54? + scalefac_buffer[x] = 0; + + m = 0; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < nr_of_sfb_block[blocknumber][blocktypenumber][i]; + j++) { + scalefac_buffer[m] = (new_slen[i] == 0) ? 0 : + br.hgetbits(new_slen[i]); + m++; + + } + } + } + + /** + * + */ + private void get_LSF_scale_factors(int ch, int gr) { + int m = 0; + int sfb, window; + gr_info_s gr_info = (si.ch[ch].gr[gr]); + + get_LSF_scale_data(ch, gr); + + if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) { + if (gr_info.mixed_block_flag != 0) { // MIXED + for (sfb = 0; sfb < 8; sfb++) { + scalefac[ch].l[sfb] = scalefac_buffer[m]; + m++; + } + for (sfb = 3; sfb < 12; sfb++) { + for (window = 0; window < 3; window++) { + scalefac[ch].s[window][sfb] = scalefac_buffer[m]; + m++; + } + } + for (window = 0; window < 3; window++) + scalefac[ch].s[window][12] = 0; + + } else { // SHORT + + for (sfb = 0; sfb < 12; sfb++) { + for (window = 0; window < 3; window++) { + scalefac[ch].s[window][sfb] = scalefac_buffer[m]; + m++; + } + } + + for (window = 0; window < 3; window++) + scalefac[ch].s[window][12] = 0; + } + } else { // LONG types 0,1,3 + + for (sfb = 0; sfb < 21; sfb++) { + scalefac[ch].l[sfb] = scalefac_buffer[m]; + m++; + } + scalefac[ch].l[21] = 0; // Jeff + scalefac[ch].l[22] = 0; + } + } + + /** + * + */ + int[] x = {0}; + int[] y = {0}; + int[] v = {0}; + int[] w = {0}; + + private void huffman_decode(int ch, int gr) { + x[0] = 0; + y[0] = 0; + v[0] = 0; + w[0] = 0; + + int part2_3_end = part2_start + si.ch[ch].gr[gr].part2_3_length; + int num_bits; + int region1Start; + int region2Start; + int index; + + int buf, buf1; + + huffcodetab h; + + // Find region boundary for short block case + + if (((si.ch[ch].gr[gr].window_switching_flag) != 0) && + (si.ch[ch].gr[gr].block_type == 2)) { + + // Region2. + //MS: Extrahandling for 8KHZ + region1Start = (sfreq == 8) ? 72 : 36; // sfb[9/3]*3=36 or in case 8KHZ = 72 + region2Start = 576; // No Region2 for short block case + + } else { // Find region boundary for long block case + + buf = si.ch[ch].gr[gr].region0_count + 1; + buf1 = buf + si.ch[ch].gr[gr].region1_count + 1; + + if (buf1 > sfBandIndex[sfreq].l.length - 1) buf1 = sfBandIndex[sfreq].l.length - 1; + + region1Start = sfBandIndex[sfreq].l[buf]; + region2Start = sfBandIndex[sfreq].l[buf1]; /* MI */ + } + + index = 0; + // Read big values area + for (int i = 0; i < (si.ch[ch].gr[gr].big_values << 1); i += 2) { + if (i < region1Start) h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[0]]; + else if (i < region2Start) h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[1]]; + else h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[2]]; + + huffcodetab.huffman_decoder(h, x, y, v, w, br); + + is_1d[index++] = x[0]; + is_1d[index++] = y[0]; + + checkSumHuff = checkSumHuff + x[0] + y[0]; + } + + // Read count1 area + h = huffcodetab.ht[si.ch[ch].gr[gr].count1table_select + 32]; + num_bits = br.hsstell(); + + while ((num_bits < part2_3_end) && (index < 576)) { + + huffcodetab.huffman_decoder(h, x, y, v, w, br); + + is_1d[index++] = v[0]; + is_1d[index++] = w[0]; + is_1d[index++] = x[0]; + is_1d[index++] = y[0]; + checkSumHuff = checkSumHuff + v[0] + w[0] + x[0] + y[0]; + num_bits = br.hsstell(); + } + + if (num_bits > part2_3_end) { + br.rewindNbits(num_bits - part2_3_end); + index -= 4; + } + + num_bits = br.hsstell(); + + // Dismiss stuffing bits + if (num_bits < part2_3_end) + br.hgetbits(part2_3_end - num_bits); + + // Zero out rest + + nonzero[ch] = Math.min(index, 576); + + if (index < 0) index = 0; + + // may not be necessary + for (; index < 576; index++) + is_1d[index] = 0; + } + + /** + * + */ + private void i_stereo_k_values(int is_pos, int io_type, int i) { + if (is_pos == 0) { + k[0][i] = 1.0f; + k[1][i] = 1.0f; + } else if ((is_pos & 1) != 0) { + k[0][i] = io[io_type][(is_pos + 1) >>> 1]; + k[1][i] = 1.0f; + } else { + k[0][i] = 1.0f; + k[1][i] = io[io_type][is_pos >>> 1]; + } + } + + /** + * + */ + private void dequantize_sample(float[][] xr, int ch, int gr) { + gr_info_s gr_info = (si.ch[ch].gr[gr]); + int cb = 0; + int next_cb_boundary; + int cb_begin = 0; + int cb_width = 0; + int index = 0, t_index, j; + float g_gain; + float[][] xr_1d = xr; + + // choose correct scalefactor band per block type, initalize boundary + + if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) { + if (gr_info.mixed_block_flag != 0) + next_cb_boundary = sfBandIndex[sfreq].l[1]; // LONG blocks: 0,1,3 + else { + cb_width = sfBandIndex[sfreq].s[1]; + next_cb_boundary = (cb_width << 2) - cb_width; + cb_begin = 0; + } + } else { + next_cb_boundary = sfBandIndex[sfreq].l[1]; // LONG blocks: 0,1,3 + } + + // Compute overall (global) scaling. + + g_gain = (float) Math.pow(2.0, (0.25 * (gr_info.global_gain - 210.0))); + + for (j = 0; j < nonzero[ch]; j++) { + // Modif E.B 02/22/99 + int reste = j % SSLIMIT; + int quotien = (j - reste) / SSLIMIT; + if (is_1d[j] == 0) xr_1d[quotien][reste] = 0.0f; + else { + int abv = is_1d[j]; + // Pow Array fix (11/17/04) + if (abv < t_43.length) { + if (is_1d[j] > 0) xr_1d[quotien][reste] = g_gain * t_43[abv]; + else { + if (-abv < t_43.length) xr_1d[quotien][reste] = -g_gain * t_43[-abv]; + else xr_1d[quotien][reste] = -g_gain * (float) Math.pow(-abv, d43); + } + } else { + if (is_1d[j] > 0) xr_1d[quotien][reste] = g_gain * (float) Math.pow(abv, d43); + else xr_1d[quotien][reste] = -g_gain * (float) Math.pow(-abv, d43); + } + } + } + + // apply formula per block type + for (j = 0; j < nonzero[ch]; j++) { + // Modif E.B 02/22/99 + int reste = j % SSLIMIT; + int quotien = (j - reste) / SSLIMIT; + + if (index == next_cb_boundary) { /* Adjust critical band boundary */ + if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) { + if (gr_info.mixed_block_flag != 0) { + + if (index == sfBandIndex[sfreq].l[8]) { + next_cb_boundary = sfBandIndex[sfreq].s[4]; + next_cb_boundary = (next_cb_boundary << 2) - + next_cb_boundary; + cb = 3; + cb_width = sfBandIndex[sfreq].s[4] - + sfBandIndex[sfreq].s[3]; + + cb_begin = sfBandIndex[sfreq].s[3]; + cb_begin = (cb_begin << 2) - cb_begin; + + } else if (index < sfBandIndex[sfreq].l[8]) { + + next_cb_boundary = sfBandIndex[sfreq].l[(++cb) + 1]; + + } else { + + next_cb_boundary = sfBandIndex[sfreq].s[(++cb) + 1]; + next_cb_boundary = (next_cb_boundary << 2) - + next_cb_boundary; + + cb_begin = sfBandIndex[sfreq].s[cb]; + cb_width = sfBandIndex[sfreq].s[cb + 1] - + cb_begin; + cb_begin = (cb_begin << 2) - cb_begin; + } + + } else { + + next_cb_boundary = sfBandIndex[sfreq].s[(++cb) + 1]; + next_cb_boundary = (next_cb_boundary << 2) - + next_cb_boundary; + + cb_begin = sfBandIndex[sfreq].s[cb]; + cb_width = sfBandIndex[sfreq].s[cb + 1] - + cb_begin; + cb_begin = (cb_begin << 2) - cb_begin; + } + + } else { // long blocks + + next_cb_boundary = sfBandIndex[sfreq].l[(++cb) + 1]; + } + } + + // Do long/short dependent scaling operations + + if ((gr_info.window_switching_flag != 0) && + (((gr_info.block_type == 2) && (gr_info.mixed_block_flag == 0)) || + ((gr_info.block_type == 2) && (gr_info.mixed_block_flag != 0) && (j >= 36)))) { + + t_index = (index - cb_begin) / cb_width; + int idx = scalefac[ch].s[t_index][cb] + << gr_info.scalefac_scale; + idx += (gr_info.subblock_gain[t_index] << 2); + + xr_1d[quotien][reste] *= two_to_negative_half_pow[idx]; + + } else { // LONG block types 0,1,3 & 1st 2 subbands of switched blocks + int idx = scalefac[ch].l[cb]; + + if (gr_info.preflag != 0) + idx += pretab[cb]; + + idx = idx << gr_info.scalefac_scale; + xr_1d[quotien][reste] *= two_to_negative_half_pow[idx]; + } + index++; + } + + for (j = nonzero[ch]; j < 576; j++) { + // Modif E.B 02/22/99 + int reste = j % SSLIMIT; + int quotien = (j - reste) / SSLIMIT; + if (reste < 0) reste = 0; + if (quotien < 0) quotien = 0; + xr_1d[quotien][reste] = 0.0f; + } + } + + /** + * + */ + private void reorder(float[][] xr, int ch, int gr) { + gr_info_s gr_info = (si.ch[ch].gr[gr]); + int freq, freq3; + int index; + int sfb, sfb_start, sfb_lines; + int src_line, des_line; + float[][] xr_1d = xr; + + if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) { + + for (index = 0; index < 576; index++) + out_1d[index] = 0.0f; + + if (gr_info.mixed_block_flag != 0) { + // NO REORDER FOR LOW 2 SUBBANDS + for (index = 0; index < 36; index++) { + // Modif E.B 02/22/99 + int reste = index % SSLIMIT; + int quotien = (index - reste) / SSLIMIT; + out_1d[index] = xr_1d[quotien][reste]; + } + for (sfb = 3; sfb < 13; sfb++) { + sfb_start = sfBandIndex[sfreq].s[sfb]; + sfb_lines = sfBandIndex[sfreq].s[sfb + 1] - sfb_start; + + int sfb_start3 = (sfb_start << 2) - sfb_start; + + for (freq = 0, freq3 = 0; freq < sfb_lines; + freq++, freq3 += 3) { + + src_line = sfb_start3 + freq; + des_line = sfb_start3 + freq3; + // Modif E.B 02/22/99 + int reste = src_line % SSLIMIT; + int quotien = (src_line - reste) / SSLIMIT; + + out_1d[des_line] = xr_1d[quotien][reste]; + src_line += sfb_lines; + des_line++; + + reste = src_line % SSLIMIT; + quotien = (src_line - reste) / SSLIMIT; + + out_1d[des_line] = xr_1d[quotien][reste]; + src_line += sfb_lines; + des_line++; + + reste = src_line % SSLIMIT; + quotien = (src_line - reste) / SSLIMIT; + + out_1d[des_line] = xr_1d[quotien][reste]; + } + } + + } else { // pure short + for (index = 0; index < 576; index++) { + int j = reorder_table[sfreq][index]; + int reste = j % SSLIMIT; + int quotien = (j - reste) / SSLIMIT; + out_1d[index] = xr_1d[quotien][reste]; + } + } + } else { // long blocks + for (index = 0; index < 576; index++) { + // Modif E.B 02/22/99 + int reste = index % SSLIMIT; + int quotien = (index - reste) / SSLIMIT; + out_1d[index] = xr_1d[quotien][reste]; + } + } + } + + int[] is_pos = new int[576]; + float[] is_ratio = new float[576]; + + /** + * + */ + private void stereo(int gr) { + int sb, ss; + + if (channels == 1) { // mono , bypass xr[0][][] to lr[0][][] + + for (sb = 0; sb < SBLIMIT; sb++) + for (ss = 0; ss < SSLIMIT; ss += 3) { + lr[0][sb][ss] = ro[0][sb][ss]; + lr[0][sb][ss + 1] = ro[0][sb][ss + 1]; + lr[0][sb][ss + 2] = ro[0][sb][ss + 2]; + } + + } else { + + gr_info_s gr_info = (si.ch[0].gr[gr]); + int mode_ext = header.mode_extension(); + int sfb; + int i; + int lines, temp, temp2; + + boolean ms_stereo = ((header.mode() == Header.JOINT_STEREO) && ((mode_ext & 0x2) != 0)); + boolean i_stereo = ((header.mode() == Header.JOINT_STEREO) && ((mode_ext & 0x1) != 0)); + boolean lsf = ((header.version() == Header.MPEG2_LSF || header.version() == Header.MPEG25_LSF)); // SZD + + int io_type = (gr_info.scalefac_compress & 1); + + // initialization + + for (i = 0; i < 576; i++) { + is_pos[i] = 7; + + is_ratio[i] = 0.0f; + } + + if (i_stereo) { + if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) { + if (gr_info.mixed_block_flag != 0) { + + int max_sfb = 0; + + for (int j = 0; j < 3; j++) { + int sfbcnt; + sfbcnt = 2; + for (sfb = 12; sfb >= 3; sfb--) { + i = sfBandIndex[sfreq].s[sfb]; + lines = sfBandIndex[sfreq].s[sfb + 1] - i; + i = (i << 2) - i + (j + 1) * lines - 1; + + while (lines > 0) { + if (ro[1][i / 18][i % 18] != 0.0f) { + // MDM: in java, array access is very slow. + // Is quicker to compute div and mod values. + //if (ro[1][ss_div[i]][ss_mod[i]] != 0.0f) { + sfbcnt = sfb; + sfb = -10; + lines = -10; + } + + lines--; + i--; + + } // while (lines > 0) + + } // for (sfb=12 ... + sfb = sfbcnt + 1; + + if (sfb > max_sfb) + max_sfb = sfb; + + while (sfb < 12) { + temp = sfBandIndex[sfreq].s[sfb]; + sb = sfBandIndex[sfreq].s[sfb + 1] - temp; + i = (temp << 2) - temp + j * sb; + + for (; sb > 0; sb--) { + is_pos[i] = scalefac[1].s[j][sfb]; + if (is_pos[i] != 7) + if (lsf) + i_stereo_k_values(is_pos[i], io_type, i); + else + is_ratio[i] = TAN12[is_pos[i]]; + + i++; + } // for (; sb>0... + sfb++; + } // while (sfb < 12) + sfb = sfBandIndex[sfreq].s[10]; + sb = sfBandIndex[sfreq].s[11] - sfb; + sfb = (sfb << 2) - sfb + j * sb; + temp = sfBandIndex[sfreq].s[11]; + sb = sfBandIndex[sfreq].s[12] - temp; + i = (temp << 2) - temp + j * sb; + + for (; sb > 0; sb--) { + is_pos[i] = is_pos[sfb]; + + if (lsf) { + k[0][i] = k[0][sfb]; + k[1][i] = k[1][sfb]; + } else { + is_ratio[i] = is_ratio[sfb]; + } + i++; + } // for (; sb > 0 ... + } + if (max_sfb <= 3) { + i = 2; + ss = 17; + sb = -1; + while (i >= 0) { + if (ro[1][i][ss] != 0.0f) { + sb = (i << 4) + (i << 1) + ss; + i = -1; + } else { + ss--; + if (ss < 0) { + i--; + ss = 17; + } + } // if (ro ... + } // while (i>=0) + i = 0; + while (sfBandIndex[sfreq].l[i] <= sb) + i++; + sfb = i; + i = sfBandIndex[sfreq].l[i]; + for (; sfb < 8; sfb++) { + sb = sfBandIndex[sfreq].l[sfb + 1] - sfBandIndex[sfreq].l[sfb]; + for (; sb > 0; sb--) { + is_pos[i] = scalefac[1].l[sfb]; + if (is_pos[i] != 7) + if (lsf) + i_stereo_k_values(is_pos[i], io_type, i); + else + is_ratio[i] = TAN12[is_pos[i]]; + i++; + } // for (; sb>0 ... + } // for (; sfb<8 ... + } // for (j=0 ... + } else { // if (gr_info.mixed_block_flag) + for (int j = 0; j < 3; j++) { + int sfbcnt; + sfbcnt = -1; + for (sfb = 12; sfb >= 0; sfb--) { + temp = sfBandIndex[sfreq].s[sfb]; + lines = sfBandIndex[sfreq].s[sfb + 1] - temp; + i = (temp << 2) - temp + (j + 1) * lines - 1; + + while (lines > 0) { + if (ro[1][i / 18][i % 18] != 0.0f) { + // MDM: in java, array access is very slow. + // Is quicker to compute div and mod values. + sfbcnt = sfb; + sfb = -10; + lines = -10; + } + lines--; + i--; + } // while (lines > 0) */ + + } // for (sfb=12 ... + sfb = sfbcnt + 1; + while (sfb < 12) { + temp = sfBandIndex[sfreq].s[sfb]; + sb = sfBandIndex[sfreq].s[sfb + 1] - temp; + i = (temp << 2) - temp + j * sb; + for (; sb > 0; sb--) { + is_pos[i] = scalefac[1].s[j][sfb]; + if (is_pos[i] != 7) + if (lsf) + i_stereo_k_values(is_pos[i], io_type, i); + else + is_ratio[i] = TAN12[is_pos[i]]; + i++; + } // for (; sb>0 ... + sfb++; + } // while (sfb<12) + + temp = sfBandIndex[sfreq].s[10]; + temp2 = sfBandIndex[sfreq].s[11]; + sb = temp2 - temp; + sfb = (temp << 2) - temp + j * sb; + sb = sfBandIndex[sfreq].s[12] - temp2; + i = (temp2 << 2) - temp2 + j * sb; + + for (; sb > 0; sb--) { + is_pos[i] = is_pos[sfb]; + + if (lsf) { + k[0][i] = k[0][sfb]; + k[1][i] = k[1][sfb]; + } else { + is_ratio[i] = is_ratio[sfb]; + } + i++; + } // for (; sb>0 ... + } // for (sfb=12 + } // for (j=0 ... + } else { // if (gr_info.window_switching_flag ... + i = 31; + ss = 17; + sb = 0; + while (i >= 0) { + if (ro[1][i][ss] != 0.0f) { + sb = (i << 4) + (i << 1) + ss; + i = -1; + } else { + ss--; + if (ss < 0) { + i--; + ss = 17; + } + } + } + i = 0; + while (sfBandIndex[sfreq].l[i] <= sb) + i++; + + sfb = i; + i = sfBandIndex[sfreq].l[i]; + for (; sfb < 21; sfb++) { + sb = sfBandIndex[sfreq].l[sfb + 1] - sfBandIndex[sfreq].l[sfb]; + for (; sb > 0; sb--) { + is_pos[i] = scalefac[1].l[sfb]; + if (is_pos[i] != 7) + if (lsf) + i_stereo_k_values(is_pos[i], io_type, i); + else + is_ratio[i] = TAN12[is_pos[i]]; + i++; + } + } + sfb = sfBandIndex[sfreq].l[20]; + for (sb = 576 - sfBandIndex[sfreq].l[21]; (sb > 0) && (i < 576); sb--) { + is_pos[i] = is_pos[sfb]; // error here : i >=576 + + if (lsf) { + k[0][i] = k[0][sfb]; + k[1][i] = k[1][sfb]; + } else { + is_ratio[i] = is_ratio[sfb]; + } + i++; + } // if (gr_info.mixed_block_flag) + } // if (gr_info.window_switching_flag ... + } // if (i_stereo) + + i = 0; + for (sb = 0; sb < SBLIMIT; sb++) + for (ss = 0; ss < SSLIMIT; ss++) { + if (is_pos[i] == 7) { + if (ms_stereo) { + lr[0][sb][ss] = (ro[0][sb][ss] + ro[1][sb][ss]) * 0.707106781f; + lr[1][sb][ss] = (ro[0][sb][ss] - ro[1][sb][ss]) * 0.707106781f; + } else { + lr[0][sb][ss] = ro[0][sb][ss]; + lr[1][sb][ss] = ro[1][sb][ss]; + } + } else if (i_stereo) { + + if (lsf) { + lr[0][sb][ss] = ro[0][sb][ss] * k[0][i]; + lr[1][sb][ss] = ro[0][sb][ss] * k[1][i]; + } else { + lr[1][sb][ss] = ro[0][sb][ss] / (1 + is_ratio[i]); + lr[0][sb][ss] = lr[1][sb][ss] * is_ratio[i]; + } + } + i++; + } + } // channels == 2 + } + + /** + * + */ + private void antialias(int ch, int gr) { + int sb18, ss, sb18lim; + gr_info_s gr_info = (si.ch[ch].gr[gr]); + // 31 alias-reduction operations between each pair of sub-bands + // with 8 butterflies between each pair + + if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2) && + !(gr_info.mixed_block_flag != 0)) + return; + + if ((gr_info.window_switching_flag != 0) && (gr_info.mixed_block_flag != 0) && + (gr_info.block_type == 2)) { + sb18lim = 18; + } else { + sb18lim = 558; + } + + for (sb18 = 0; sb18 < sb18lim; sb18 += 18) { + for (ss = 0; ss < 8; ss++) { + int src_idx1 = sb18 + 17 - ss; + int src_idx2 = sb18 + 18 + ss; + float bu = out_1d[src_idx1]; + float bd = out_1d[src_idx2]; + out_1d[src_idx1] = (bu * cs[ss]) - (bd * ca[ss]); + out_1d[src_idx2] = (bd * cs[ss]) + (bu * ca[ss]); + } + } + } + + // MDM: tsOutCopy and rawout do not need initializing, so the arrays + // can be reused. + float[] tsOutCopy = new float[18]; + float[] rawout = new float[36]; + + /** + * + */ + private void hybrid(int ch, int gr) { + int bt; + int sb18; + gr_info_s gr_info = (si.ch[ch].gr[gr]); + float[] tsOut; + + float[][] prvblk; + + for (sb18 = 0; sb18 < 576; sb18 += 18) { + bt = ((gr_info.window_switching_flag != 0) && (gr_info.mixed_block_flag != 0) && + (sb18 < 36)) ? 0 : gr_info.block_type; + + tsOut = out_1d; + // Modif E.B 02/22/99 + System.arraycopy(tsOut, 0 + sb18, tsOutCopy, 0, 18); + + inv_mdct(tsOutCopy, rawout, bt); + + + System.arraycopy(tsOutCopy, 0, tsOut, 0 + sb18, 18); + // Fin Modif + + // overlap addition + prvblk = prevblck; + + tsOut[0 + sb18] = rawout[0] + prvblk[ch][sb18 + 0]; + prvblk[ch][sb18 + 0] = rawout[18]; + tsOut[1 + sb18] = rawout[1] + prvblk[ch][sb18 + 1]; + prvblk[ch][sb18 + 1] = rawout[19]; + tsOut[2 + sb18] = rawout[2] + prvblk[ch][sb18 + 2]; + prvblk[ch][sb18 + 2] = rawout[20]; + tsOut[3 + sb18] = rawout[3] + prvblk[ch][sb18 + 3]; + prvblk[ch][sb18 + 3] = rawout[21]; + tsOut[4 + sb18] = rawout[4] + prvblk[ch][sb18 + 4]; + prvblk[ch][sb18 + 4] = rawout[22]; + tsOut[5 + sb18] = rawout[5] + prvblk[ch][sb18 + 5]; + prvblk[ch][sb18 + 5] = rawout[23]; + tsOut[6 + sb18] = rawout[6] + prvblk[ch][sb18 + 6]; + prvblk[ch][sb18 + 6] = rawout[24]; + tsOut[7 + sb18] = rawout[7] + prvblk[ch][sb18 + 7]; + prvblk[ch][sb18 + 7] = rawout[25]; + tsOut[8 + sb18] = rawout[8] + prvblk[ch][sb18 + 8]; + prvblk[ch][sb18 + 8] = rawout[26]; + tsOut[9 + sb18] = rawout[9] + prvblk[ch][sb18 + 9]; + prvblk[ch][sb18 + 9] = rawout[27]; + tsOut[10 + sb18] = rawout[10] + prvblk[ch][sb18 + 10]; + prvblk[ch][sb18 + 10] = rawout[28]; + tsOut[11 + sb18] = rawout[11] + prvblk[ch][sb18 + 11]; + prvblk[ch][sb18 + 11] = rawout[29]; + tsOut[12 + sb18] = rawout[12] + prvblk[ch][sb18 + 12]; + prvblk[ch][sb18 + 12] = rawout[30]; + tsOut[13 + sb18] = rawout[13] + prvblk[ch][sb18 + 13]; + prvblk[ch][sb18 + 13] = rawout[31]; + tsOut[14 + sb18] = rawout[14] + prvblk[ch][sb18 + 14]; + prvblk[ch][sb18 + 14] = rawout[32]; + tsOut[15 + sb18] = rawout[15] + prvblk[ch][sb18 + 15]; + prvblk[ch][sb18 + 15] = rawout[33]; + tsOut[16 + sb18] = rawout[16] + prvblk[ch][sb18 + 16]; + prvblk[ch][sb18 + 16] = rawout[34]; + tsOut[17 + sb18] = rawout[17] + prvblk[ch][sb18 + 17]; + prvblk[ch][sb18 + 17] = rawout[35]; + } + } + + /** + * + */ + private void do_downmix() { + for (int sb = 0; sb < SSLIMIT; sb++) { + for (int ss = 0; ss < SSLIMIT; ss += 3) { + lr[0][sb][ss] = (lr[0][sb][ss] + lr[1][sb][ss]) * 0.5f; + lr[0][sb][ss + 1] = (lr[0][sb][ss + 1] + lr[1][sb][ss + 1]) * 0.5f; + lr[0][sb][ss + 2] = (lr[0][sb][ss + 2] + lr[1][sb][ss + 2]) * 0.5f; + } + } + } + + /** + * Fast INV_MDCT. + */ + public void inv_mdct(float[] in, float[] out, int block_type) { + float[] win_bt; + int i; + + float tmpf_0, tmpf_1, tmpf_2, tmpf_3, tmpf_4, tmpf_5, tmpf_6, tmpf_7, tmpf_8, tmpf_9; + float tmpf_10, tmpf_11, tmpf_12, tmpf_13, tmpf_14, tmpf_15, tmpf_16, tmpf_17; + + tmpf_0 = tmpf_1 = tmpf_2 = tmpf_3 = tmpf_4 = tmpf_5 = tmpf_6 = tmpf_7 = tmpf_8 = tmpf_9 = + tmpf_10 = tmpf_11 = tmpf_12 = tmpf_13 = tmpf_14 = tmpf_15 = tmpf_16 = tmpf_17 = 0.0f; + + if (block_type == 2) { + + out[0] = 0.0f; + out[1] = 0.0f; + out[2] = 0.0f; + out[3] = 0.0f; + out[4] = 0.0f; + out[5] = 0.0f; + out[6] = 0.0f; + out[7] = 0.0f; + out[8] = 0.0f; + out[9] = 0.0f; + out[10] = 0.0f; + out[11] = 0.0f; + out[12] = 0.0f; + out[13] = 0.0f; + out[14] = 0.0f; + out[15] = 0.0f; + out[16] = 0.0f; + out[17] = 0.0f; + out[18] = 0.0f; + out[19] = 0.0f; + out[20] = 0.0f; + out[21] = 0.0f; + out[22] = 0.0f; + out[23] = 0.0f; + out[24] = 0.0f; + out[25] = 0.0f; + out[26] = 0.0f; + out[27] = 0.0f; + out[28] = 0.0f; + out[29] = 0.0f; + out[30] = 0.0f; + out[31] = 0.0f; + out[32] = 0.0f; + out[33] = 0.0f; + out[34] = 0.0f; + out[35] = 0.0f; + + int six_i = 0; + + for (i = 0; i < 3; i++) { + // 12 point IMDCT + // Begin 12 point IDCT + // Input aliasing for 12 pt IDCT + in[15 + i] += in[12 + i]; + in[12 + i] += in[9 + i]; + in[9 + i] += in[6 + i]; + in[6 + i] += in[3 + i]; + in[3 + i] += in[0 + i]; + + // Input aliasing on odd indices (for 6 point IDCT) + in[15 + i] += in[9 + i]; + in[9 + i] += in[3 + i]; + + // 3 point IDCT on even indices + float pp1, pp2, sum; + pp2 = in[12 + i] * 0.500000000f; + pp1 = in[6 + i] * 0.866025403f; + sum = in[0 + i] + pp2; + tmpf_1 = in[0 + i] - in[12 + i]; + tmpf_0 = sum + pp1; + tmpf_2 = sum - pp1; + + // End 3 point IDCT on even indices + // 3 point IDCT on odd indices (for 6 point IDCT) + pp2 = in[15 + i] * 0.500000000f; + pp1 = in[9 + i] * 0.866025403f; + sum = in[3 + i] + pp2; + tmpf_4 = in[3 + i] - in[15 + i]; + tmpf_5 = sum + pp1; + tmpf_3 = sum - pp1; + // End 3 point IDCT on odd indices + // Twiddle factors on odd indices (for 6 point IDCT) + + tmpf_3 *= 1.931851653f; + tmpf_4 *= 0.707106781f; + tmpf_5 *= 0.517638090f; + + // Output butterflies on 2 3 point IDCT's (for 6 point IDCT) + float save = tmpf_0; + tmpf_0 += tmpf_5; + tmpf_5 = save - tmpf_5; + save = tmpf_1; + tmpf_1 += tmpf_4; + tmpf_4 = save - tmpf_4; + save = tmpf_2; + tmpf_2 += tmpf_3; + tmpf_3 = save - tmpf_3; + + // End 6 point IDCT + // Twiddle factors on indices (for 12 point IDCT) + + tmpf_0 *= 0.504314480f; + tmpf_1 *= 0.541196100f; + tmpf_2 *= 0.630236207f; + tmpf_3 *= 0.821339815f; + tmpf_4 *= 1.306562965f; + tmpf_5 *= 3.830648788f; + + // End 12 point IDCT + + // Shift to 12 point modified IDCT, multiply by window type 2 + tmpf_8 = -tmpf_0 * 0.793353340f; + tmpf_9 = -tmpf_0 * 0.608761429f; + tmpf_7 = -tmpf_1 * 0.923879532f; + tmpf_10 = -tmpf_1 * 0.382683432f; + tmpf_6 = -tmpf_2 * 0.991444861f; + tmpf_11 = -tmpf_2 * 0.130526192f; + + tmpf_0 = tmpf_3; + tmpf_1 = tmpf_4 * 0.382683432f; + tmpf_2 = tmpf_5 * 0.608761429f; + + tmpf_3 = -tmpf_5 * 0.793353340f; + tmpf_4 = -tmpf_4 * 0.923879532f; + tmpf_5 = -tmpf_0 * 0.991444861f; + + tmpf_0 *= 0.130526192f; + + out[six_i + 6] += tmpf_0; + out[six_i + 7] += tmpf_1; + out[six_i + 8] += tmpf_2; + out[six_i + 9] += tmpf_3; + out[six_i + 10] += tmpf_4; + out[six_i + 11] += tmpf_5; + out[six_i + 12] += tmpf_6; + out[six_i + 13] += tmpf_7; + out[six_i + 14] += tmpf_8; + out[six_i + 15] += tmpf_9; + out[six_i + 16] += tmpf_10; + out[six_i + 17] += tmpf_11; + + six_i += 6; + } + } else { + // 36 point IDCT + // input aliasing for 36 point IDCT + in[17] += in[16]; + in[16] += in[15]; + in[15] += in[14]; + in[14] += in[13]; + in[13] += in[12]; + in[12] += in[11]; + in[11] += in[10]; + in[10] += in[9]; + in[9] += in[8]; + in[8] += in[7]; + in[7] += in[6]; + in[6] += in[5]; + in[5] += in[4]; + in[4] += in[3]; + in[3] += in[2]; + in[2] += in[1]; + in[1] += in[0]; + + // 18 point IDCT for odd indices + // input aliasing for 18 point IDCT + in[17] += in[15]; + in[15] += in[13]; + in[13] += in[11]; + in[11] += in[9]; + in[9] += in[7]; + in[7] += in[5]; + in[5] += in[3]; + in[3] += in[1]; + + float tmp0, tmp1, tmp2, tmp3, tmp4, tmp0_, tmp1_, tmp2_, tmp3_; + float tmp0o, tmp1o, tmp2o, tmp3o, tmp4o, tmp0_o, tmp1_o, tmp2_o, tmp3_o; + + // Fast 9 Point Inverse Discrete Cosine Transform + // + // By Francois-Raymond Boyer + // mailto:boyerf@iro.umontreal.ca + // http://www.iro.umontreal.ca/~boyerf + // + // The code has been optimized for Intel processors + // (takes a lot of time to convert float to and from iternal FPU representation) + // + // It is a simple "factorization" of the IDCT matrix. + + // 9 point IDCT on even indices + + // 5 points on odd indices (not realy an IDCT) + float i00 = in[0] + in[0]; + float iip12 = i00 + in[12]; + + tmp0 = iip12 + in[4] * 1.8793852415718f + in[8] * 1.532088886238f + in[16] * 0.34729635533386f; + tmp1 = i00 + in[4] - in[8] - in[12] - in[12] - in[16]; + tmp2 = iip12 - in[4] * 0.34729635533386f - in[8] * 1.8793852415718f + in[16] * 1.532088886238f; + tmp3 = iip12 - in[4] * 1.532088886238f + in[8] * 0.34729635533386f - in[16] * 1.8793852415718f; + tmp4 = in[0] - in[4] + in[8] - in[12] + in[16]; + + // 4 points on even indices + float i66_ = in[6] * 1.732050808f; // Sqrt[3] + + tmp0_ = in[2] * 1.9696155060244f + i66_ + in[10] * 1.2855752193731f + in[14] * 0.68404028665134f; + tmp1_ = (in[2] - in[10] - in[14]) * 1.732050808f; + tmp2_ = in[2] * 1.2855752193731f - i66_ - in[10] * 0.68404028665134f + in[14] * 1.9696155060244f; + tmp3_ = in[2] * 0.68404028665134f - i66_ + in[10] * 1.9696155060244f - in[14] * 1.2855752193731f; + + // 9 point IDCT on odd indices + // 5 points on odd indices (not realy an IDCT) + float i0 = in[0 + 1] + in[0 + 1]; + float i0p12 = i0 + in[12 + 1]; + + tmp0o = i0p12 + in[4 + 1] * 1.8793852415718f + in[8 + 1] * 1.532088886238f + in[16 + 1] * 0.34729635533386f; + tmp1o = i0 + in[4 + 1] - in[8 + 1] - in[12 + 1] - in[12 + 1] - in[16 + 1]; + tmp2o = i0p12 - in[4 + 1] * 0.34729635533386f - in[8 + 1] * 1.8793852415718f + in[16 + 1] * 1.532088886238f; + tmp3o = i0p12 - in[4 + 1] * 1.532088886238f + in[8 + 1] * 0.34729635533386f - in[16 + 1] * 1.8793852415718f; + tmp4o = (in[0 + 1] - in[4 + 1] + in[8 + 1] - in[12 + 1] + in[16 + 1]) * 0.707106781f; // Twiddled + + // 4 points on even indices + float i6_ = in[6 + 1] * 1.732050808f; // Sqrt[3] + + tmp0_o = in[2 + 1] * 1.9696155060244f + i6_ + in[10 + 1] * 1.2855752193731f + in[14 + 1] * 0.68404028665134f; + tmp1_o = (in[2 + 1] - in[10 + 1] - in[14 + 1]) * 1.732050808f; + tmp2_o = in[2 + 1] * 1.2855752193731f - i6_ - in[10 + 1] * 0.68404028665134f + in[14 + 1] * 1.9696155060244f; + tmp3_o = in[2 + 1] * 0.68404028665134f - i6_ + in[10 + 1] * 1.9696155060244f - in[14 + 1] * 1.2855752193731f; + + // Twiddle factors on odd indices + // and + // Butterflies on 9 point IDCT's + // and + // twiddle factors for 36 point IDCT + + float e, o; + e = tmp0 + tmp0_; + o = (tmp0o + tmp0_o) * 0.501909918f; + tmpf_0 = e + o; + tmpf_17 = e - o; + e = tmp1 + tmp1_; + o = (tmp1o + tmp1_o) * 0.517638090f; + tmpf_1 = e + o; + tmpf_16 = e - o; + e = tmp2 + tmp2_; + o = (tmp2o + tmp2_o) * 0.551688959f; + tmpf_2 = e + o; + tmpf_15 = e - o; + e = tmp3 + tmp3_; + o = (tmp3o + tmp3_o) * 0.610387294f; + tmpf_3 = e + o; + tmpf_14 = e - o; + tmpf_4 = tmp4 + tmp4o; + tmpf_13 = tmp4 - tmp4o; + e = tmp3 - tmp3_; + o = (tmp3o - tmp3_o) * 0.871723397f; + tmpf_5 = e + o; + tmpf_12 = e - o; + e = tmp2 - tmp2_; + o = (tmp2o - tmp2_o) * 1.183100792f; + tmpf_6 = e + o; + tmpf_11 = e - o; + e = tmp1 - tmp1_; + o = (tmp1o - tmp1_o) * 1.931851653f; + tmpf_7 = e + o; + tmpf_10 = e - o; + e = tmp0 - tmp0_; + o = (tmp0o - tmp0_o) * 5.736856623f; + tmpf_8 = e + o; + tmpf_9 = e - o; + + // end 36 point IDCT */ + // shift to modified IDCT + win_bt = win[block_type]; + + out[0] = -tmpf_9 * win_bt[0]; + out[1] = -tmpf_10 * win_bt[1]; + out[2] = -tmpf_11 * win_bt[2]; + out[3] = -tmpf_12 * win_bt[3]; + out[4] = -tmpf_13 * win_bt[4]; + out[5] = -tmpf_14 * win_bt[5]; + out[6] = -tmpf_15 * win_bt[6]; + out[7] = -tmpf_16 * win_bt[7]; + out[8] = -tmpf_17 * win_bt[8]; + out[9] = tmpf_17 * win_bt[9]; + out[10] = tmpf_16 * win_bt[10]; + out[11] = tmpf_15 * win_bt[11]; + out[12] = tmpf_14 * win_bt[12]; + out[13] = tmpf_13 * win_bt[13]; + out[14] = tmpf_12 * win_bt[14]; + out[15] = tmpf_11 * win_bt[15]; + out[16] = tmpf_10 * win_bt[16]; + out[17] = tmpf_9 * win_bt[17]; + out[18] = tmpf_8 * win_bt[18]; + out[19] = tmpf_7 * win_bt[19]; + out[20] = tmpf_6 * win_bt[20]; + out[21] = tmpf_5 * win_bt[21]; + out[22] = tmpf_4 * win_bt[22]; + out[23] = tmpf_3 * win_bt[23]; + out[24] = tmpf_2 * win_bt[24]; + out[25] = tmpf_1 * win_bt[25]; + out[26] = tmpf_0 * win_bt[26]; + out[27] = tmpf_0 * win_bt[27]; + out[28] = tmpf_1 * win_bt[28]; + out[29] = tmpf_2 * win_bt[29]; + out[30] = tmpf_3 * win_bt[30]; + out[31] = tmpf_4 * win_bt[31]; + out[32] = tmpf_5 * win_bt[32]; + out[33] = tmpf_6 * win_bt[33]; + out[34] = tmpf_7 * win_bt[34]; + out[35] = tmpf_8 * win_bt[35]; + } + } + + @SuppressWarnings("unused") + private int counter = 0; + private static final int SSLIMIT = 18; + private static final int SBLIMIT = 32; + + /** + * L3TABLE + */ + static class SBI { + public int[] l; + public int[] s; + + public SBI() { + l = new int[23]; + s = new int[14]; + } + + public SBI(int[] thel, int[] thes) { + l = thel; + s = thes; + } + } + + static class gr_info_s { + public int part2_3_length = 0; + public int big_values = 0; + public int global_gain = 0; + public int scalefac_compress = 0; + public int window_switching_flag = 0; + public int block_type = 0; + public int mixed_block_flag = 0; + public int[] table_select; + public int[] subblock_gain; + public int region0_count = 0; + public int region1_count = 0; + public int preflag = 0; + public int scalefac_scale = 0; + public int count1table_select = 0; + + /** + * Dummy Constructor + */ + public gr_info_s() { + table_select = new int[3]; + subblock_gain = new int[3]; + } + } + + static class temporaire { + public int[] scfsi; + public gr_info_s[] gr; + + /** + * Dummy Constructor + */ + public temporaire() { + scfsi = new int[4]; + gr = new gr_info_s[2]; + gr[0] = new gr_info_s(); + gr[1] = new gr_info_s(); + } + } + + static class III_side_info_t { + + public int main_data_begin = 0; + public int private_bits = 0; + public temporaire[] ch; + + /** + * Dummy Constructor + */ + public III_side_info_t() { + ch = new temporaire[2]; + ch[0] = new temporaire(); + ch[1] = new temporaire(); + } + } + + static class temporaire2 { + /** [cb] */ + public int[] l; + /** [window][cb] */ + public int[][] s; + + /** + * Dummy Constructor + */ + public temporaire2() { + l = new int[23]; + s = new int[3][13]; + } + } + + private static final int[][] slen = { + {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4}, + {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3} + }; + + public static final int[] pretab = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 + }; + + private SBI[] sfBandIndex; // Init in the constructor. + + public static final float[] two_to_negative_half_pow = { + 1.0000000000E+00f, 7.0710678119E-01f, 5.0000000000E-01f, 3.5355339059E-01f, + 2.5000000000E-01f, 1.7677669530E-01f, 1.2500000000E-01f, 8.8388347648E-02f, + 6.2500000000E-02f, 4.4194173824E-02f, 3.1250000000E-02f, 2.2097086912E-02f, + 1.5625000000E-02f, 1.1048543456E-02f, 7.8125000000E-03f, 5.5242717280E-03f, + 3.9062500000E-03f, 2.7621358640E-03f, 1.9531250000E-03f, 1.3810679320E-03f, + 9.7656250000E-04f, 6.9053396600E-04f, 4.8828125000E-04f, 3.4526698300E-04f, + 2.4414062500E-04f, 1.7263349150E-04f, 1.2207031250E-04f, 8.6316745750E-05f, + 6.1035156250E-05f, 4.3158372875E-05f, 3.0517578125E-05f, 2.1579186438E-05f, + 1.5258789062E-05f, 1.0789593219E-05f, 7.6293945312E-06f, 5.3947966094E-06f, + 3.8146972656E-06f, 2.6973983047E-06f, 1.9073486328E-06f, 1.3486991523E-06f, + 9.5367431641E-07f, 6.7434957617E-07f, 4.7683715820E-07f, 3.3717478809E-07f, + 2.3841857910E-07f, 1.6858739404E-07f, 1.1920928955E-07f, 8.4293697022E-08f, + 5.9604644775E-08f, 4.2146848511E-08f, 2.9802322388E-08f, 2.1073424255E-08f, + 1.4901161194E-08f, 1.0536712128E-08f, 7.4505805969E-09f, 5.2683560639E-09f, + 3.7252902985E-09f, 2.6341780319E-09f, 1.8626451492E-09f, 1.3170890160E-09f, + 9.3132257462E-10f, 6.5854450798E-10f, 4.6566128731E-10f, 3.2927225399E-10f + }; + + + public static final float[] t_43 = create_t_43(); + + static private float[] create_t_43() { + float[] t43 = new float[8192]; + final double d43 = (4.0 / 3.0); + + for (int i = 0; i < 8192; i++) { + t43[i] = (float) Math.pow(i, d43); + } + return t43; + } + + public static final float[][] io = { + { + 1.0000000000E+00f, 8.4089641526E-01f, 7.0710678119E-01f, 5.9460355751E-01f, + 5.0000000001E-01f, 4.2044820763E-01f, 3.5355339060E-01f, 2.9730177876E-01f, + 2.5000000001E-01f, 2.1022410382E-01f, 1.7677669530E-01f, 1.4865088938E-01f, + 1.2500000000E-01f, 1.0511205191E-01f, 8.8388347652E-02f, 7.4325444691E-02f, + 6.2500000003E-02f, 5.2556025956E-02f, 4.4194173826E-02f, 3.7162722346E-02f, + 3.1250000002E-02f, 2.6278012978E-02f, 2.2097086913E-02f, 1.8581361173E-02f, + 1.5625000001E-02f, 1.3139006489E-02f, 1.1048543457E-02f, 9.2906805866E-03f, + 7.8125000006E-03f, 6.5695032447E-03f, 5.5242717285E-03f, 4.6453402934E-03f + }, { + 1.0000000000E+00f, 7.0710678119E-01f, 5.0000000000E-01f, 3.5355339060E-01f, + 2.5000000000E-01f, 1.7677669530E-01f, 1.2500000000E-01f, 8.8388347650E-02f, + 6.2500000001E-02f, 4.4194173825E-02f, 3.1250000001E-02f, 2.2097086913E-02f, + 1.5625000000E-02f, 1.1048543456E-02f, 7.8125000002E-03f, 5.5242717282E-03f, + 3.9062500001E-03f, 2.7621358641E-03f, 1.9531250001E-03f, 1.3810679321E-03f, + 9.7656250004E-04f, 6.9053396603E-04f, 4.8828125002E-04f, 3.4526698302E-04f, + 2.4414062501E-04f, 1.7263349151E-04f, 1.2207031251E-04f, 8.6316745755E-05f, + 6.1035156254E-05f, 4.3158372878E-05f, 3.0517578127E-05f, 2.1579186439E-05f + } + }; + + + public static final float[] TAN12 = { + 0.0f, 0.26794919f, 0.57735027f, 1.0f, + 1.73205081f, 3.73205081f, 9.9999999e10f, -3.73205081f, + -1.73205081f, -1.0f, -0.57735027f, -0.26794919f, + 0.0f, 0.26794919f, 0.57735027f, 1.0f + }; + + // REVIEW: in java, the array lookup may well be slower than + // the actual calculation + // 576 / 18 + private static int[][] reorder_table; // SZD: will be generated on demand + + /** + * Loads the data for the reorder + */ + static int[] reorder(int[] scalefac_band) { // SZD: converted from LAME + int j = 0; + int[] ix = new int[576]; + for (int sfb = 0; sfb < 13; sfb++) { + int start = scalefac_band[sfb]; + int end = scalefac_band[sfb + 1]; + for (int window = 0; window < 3; window++) + for (int i = start; i < end; i++) + ix[3 * i + window] = j++; + } + return ix; + } + + private static final float[] cs = { + 0.857492925712f, 0.881741997318f, 0.949628649103f, 0.983314592492f, + 0.995517816065f, 0.999160558175f, 0.999899195243f, 0.999993155067f + }; + + private static final float[] ca = { + -0.5144957554270f, -0.4717319685650f, -0.3133774542040f, -0.1819131996110f, + -0.0945741925262f, -0.0409655828852f, -0.0141985685725f, -0.00369997467375f + }; + + /** + * INV_MDCT + */ + public static final float[][] win = { + { + -1.6141214951E-02f, -5.3603178919E-02f, -1.0070713296E-01f, -1.6280817573E-01f, + -4.9999999679E-01f, -3.8388735032E-01f, -6.2061144372E-01f, -1.1659756083E+00f, + -3.8720752656E+00f, -4.2256286556E+00f, -1.5195289984E+00f, -9.7416483388E-01f, + -7.3744074053E-01f, -1.2071067773E+00f, -5.1636156596E-01f, -4.5426052317E-01f, + -4.0715656898E-01f, -3.6969460527E-01f, -3.3876269197E-01f, -3.1242222492E-01f, + -2.8939587111E-01f, -2.6880081906E-01f, -5.0000000266E-01f, -2.3251417468E-01f, + -2.1596714708E-01f, -2.0004979098E-01f, -1.8449493497E-01f, -1.6905846094E-01f, + -1.5350360518E-01f, -1.3758624925E-01f, -1.2103922149E-01f, -2.0710679058E-01f, + -8.4752577594E-02f, -6.4157525656E-02f, -4.1131172614E-02f, -1.4790705759E-02f + }, { + -1.6141214951E-02f, -5.3603178919E-02f, -1.0070713296E-01f, -1.6280817573E-01f, + -4.9999999679E-01f, -3.8388735032E-01f, -6.2061144372E-01f, -1.1659756083E+00f, + -3.8720752656E+00f, -4.2256286556E+00f, -1.5195289984E+00f, -9.7416483388E-01f, + -7.3744074053E-01f, -1.2071067773E+00f, -5.1636156596E-01f, -4.5426052317E-01f, + -4.0715656898E-01f, -3.6969460527E-01f, -3.3908542600E-01f, -3.1511810350E-01f, + -2.9642226150E-01f, -2.8184548650E-01f, -5.4119610000E-01f, -2.6213228100E-01f, + -2.5387916537E-01f, -2.3296291359E-01f, -1.9852728987E-01f, -1.5233534808E-01f, + -9.6496400054E-02f, -3.3423828516E-02f, 0.0000000000E+00f, 0.0000000000E+00f, + 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f + }, { + -4.8300800645E-02f, -1.5715656932E-01f, -2.8325045177E-01f, -4.2953747763E-01f, + -1.2071067795E+00f, -8.2426483178E-01f, -1.1451749106E+00f, -1.7695290101E+00f, + -4.5470225061E+00f, -3.4890531002E+00f, -7.3296292804E-01f, -1.5076514758E-01f, + 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, + 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, + 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, + 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, + 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, + 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f + }, { + 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, + 0.0000000000E+00f, 0.0000000000E+00f, -1.5076513660E-01f, -7.3296291107E-01f, + -3.4890530566E+00f, -4.5470224727E+00f, -1.7695290031E+00f, -1.1451749092E+00f, + -8.3137738100E-01f, -1.3065629650E+00f, -5.4142014250E-01f, -4.6528974900E-01f, + -4.1066990750E-01f, -3.7004680800E-01f, -3.3876269197E-01f, -3.1242222492E-01f, + -2.8939587111E-01f, -2.6880081906E-01f, -5.0000000266E-01f, -2.3251417468E-01f, + -2.1596714708E-01f, -2.0004979098E-01f, -1.8449493497E-01f, -1.6905846094E-01f, + -1.5350360518E-01f, -1.3758624925E-01f, -1.2103922149E-01f, -2.0710679058E-01f, + -8.4752577594E-02f, -6.4157525656E-02f, -4.1131172614E-02f, -1.4790705759E-02f + } + }; + + // END OF INV_MDCT + + static class Sftable { + public int[] l; + public int[] s; + + public Sftable() { + l = new int[5]; + s = new int[3]; + } + + public Sftable(int[] thel, int[] thes) { + l = thel; + s = thes; + } + } + + public Sftable sftable; + + public static final int[][][] nr_of_sfb_block = { + {{6, 5, 5, 5}, {9, 9, 9, 9}, {6, 9, 9, 9}}, + {{6, 5, 7, 3}, {9, 9, 12, 6}, {6, 9, 12, 6}}, + {{11, 10, 0, 0}, {18, 18, 0, 0}, {15, 18, 0, 0}}, + {{7, 7, 7, 0}, {12, 12, 12, 0}, {6, 15, 12, 0}}, + {{6, 6, 6, 3}, {12, 9, 9, 6}, {6, 12, 9, 6}}, + {{8, 8, 5, 0}, {15, 12, 9, 0}, {6, 18, 9, 0}} + }; +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Manager.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Manager.java new file mode 100644 index 000000000..c1b52a458 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Manager.java @@ -0,0 +1,43 @@ +/* + * 11/19/04 1.0 moved to LGPL. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Work in progress. + *

+ * Manages a number of controls. + */ +public class Manager //implements Control +{ + public void addControl(Control c) { + + } + + public void removeControl(Control c) { + + } + + public void removeAll() { + + } + + // control interface delegates to a managed control + +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Obuffer.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Obuffer.java new file mode 100644 index 000000000..6d9dd1a0b --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Obuffer.java @@ -0,0 +1,86 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Added appendSamples() method for efficiency. MDM. + * 15/02/99 ,Java Conversion by E.B ,ebsp@iname.com, JavaLayer + * + * Declarations for output buffer, includes operating system + * implementation of the virtual Obuffer. Optional routines + * enabling seeks and stops added by Jeff Tsay. + * + * @(#) obuffer.h 1.8, last edit: 6/15/94 16:51:56 + * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de) + * @(#) Berlin University of Technology + * + * Idea and first implementation for u-law output with fast downsampling by + * Jim Boucher (jboucher@flash.bu.edu) + * + * LinuxObuffer class written by + * Louis P. Kruger (lpkruger@phoenix.princeton.edu) + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Base Class for audio output. + */ +public abstract class Obuffer { + public static final int OBUFFERSIZE = 2 * 1152; // max. 2 * 1152 samples per frame + public static final int MAXCHANNELS = 2; // max. number of channels + + /** + * Takes a 16 Bit PCM sample. + */ + public abstract void append(int channel, short value); + + /** + * Accepts 32 new PCM samples. + */ + public void appendSamples(int channel, float[] f) { + short s; + for (int i = 0; i < 32; ) { + s = clip(f[i++]); + append(channel, s); + } + } + + /** + * Clip Sample to 16 Bits + */ + private short clip(float sample) { + return ((sample > 32767.0f) ? 32767 : + ((sample < -32768.0f) ? -32768 : + (short) sample)); + } + + /** + * Write the samples to the file or directly to the audio hardware. + */ + public abstract void write_buffer(int val); + + public abstract void close(); + + /** + * Clears all data in the buffer (for seeking). + */ + public abstract void clear_buffer(); + + /** + * Notify the buffer that the user has stopped the stream. + */ + public abstract void set_stop_flag(); +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/OutputChannels.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/OutputChannels.java new file mode 100644 index 000000000..9ca04e8c8 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/OutputChannels.java @@ -0,0 +1,131 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial implementation. mdm@techie.com. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + + +/** + * A Type-safe representation of the the supported output channel + * constants. + *

+ * This class is immutable and, hence, is thread safe. + * + * @author Mat McGowan 12/12/99 + * @since 0.0.7 + */ +public class OutputChannels { + /** + * Flag to indicate output should include both channels. + */ + public static final int BOTH_CHANNELS = 0; + + /** + * Flag to indicate output should include the left channel only. + */ + public static final int LEFT_CHANNEL = 1; + + /** + * Flag to indicate output should include the right channel only. + */ + public static final int RIGHT_CHANNEL = 2; + + /** + * Flag to indicate output is mono. + */ + public static final int DOWNMIX_CHANNELS = 3; + + public static final OutputChannels LEFT = new OutputChannels(LEFT_CHANNEL); + public static final OutputChannels RIGHT = new OutputChannels(RIGHT_CHANNEL); + public static final OutputChannels BOTH = new OutputChannels(BOTH_CHANNELS); + public static final OutputChannels DOWNMIX = new OutputChannels(DOWNMIX_CHANNELS); + + private int outputChannels; + + /** + * Creates an OutputChannels instance + * corresponding to the given channel code. + * + * @param code one of the OutputChannels channel code constants. + * @throws IllegalArgumentException if code is not a valid + * channel code. + */ + static public OutputChannels fromInt(int code) { + switch (code) { + case LEFT_CHANNEL: + return LEFT; + case RIGHT_CHANNEL: + return RIGHT; + case BOTH_CHANNELS: + return BOTH; + case DOWNMIX_CHANNELS: + return DOWNMIX; + default: + throw new IllegalArgumentException("Invalid channel code: " + code); + } + } + + private OutputChannels(int channels) { + outputChannels = channels; + + if (channels < 0 || channels > 3) + throw new IllegalArgumentException("channels"); + } + + /** + * Retrieves the code representing the desired output channels. + * Will be one of LEFT_CHANNEL, RIGHT_CHANNEL, BOTH_CHANNELS + * or DOWNMIX_CHANNELS. + * + * @return the channel code represented by this instance. + */ + public int getChannelsOutputCode() { + return outputChannels; + } + + /** + * Retrieves the number of output channels represented + * by this channel output type. + * + * @return The number of output channels for this channel output + * type. This will be 2 for BOTH_CHANNELS only, and 1 + * for all other types. + */ + public int getChannelCount() { + int count = (outputChannels == BOTH_CHANNELS) ? 2 : 1; + return count; + } + + + public boolean equals(Object o) { + boolean equals = false; + + if (o instanceof OutputChannels) { + OutputChannels oc = (OutputChannels) o; + equals = (oc.outputChannels == outputChannels); + } + + return equals; + } + + public int hashCode() { + return outputChannels; + } + +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/SampleBuffer.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/SampleBuffer.java new file mode 100644 index 000000000..eaf4141e3 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/SampleBuffer.java @@ -0,0 +1,118 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 12/12/99 Initial Version based on FileObuffer. mdm@techie.com. + * + * FileObuffer: + * 15/02/99 Java Conversion by E.B ,javalayer@javazoom.net + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * The SampleBuffer class implements an output buffer + * that provides storage for a fixed size block of samples. + */ +public class SampleBuffer extends Obuffer { + + private short[] buffer; + private int[] bufferp; + private int channels; + private int frequency; + + /** + * Constructor + */ + public SampleBuffer(int sample_frequency, int number_of_channels) { + buffer = new short[OBUFFERSIZE]; + bufferp = new int[MAXCHANNELS]; + channels = number_of_channels; + frequency = sample_frequency; + + for (int i = 0; i < number_of_channels; ++i) + bufferp[i] = (short) i; + } + + public int getChannelCount() { + return this.channels; + } + + public int getSampleFrequency() { + return this.frequency; + } + + public short[] getBuffer() { + return this.buffer; + } + + public int getBufferLength() { + return bufferp[0]; + } + + /** + * Takes a 16 Bit PCM sample. + */ + public void append(int channel, short value) { + buffer[bufferp[channel]] = value; + bufferp[channel] += channels; + } + + public void appendSamples(int channel, float[] f) { + int pos = bufferp[channel]; + + short s; + float fs; + for (int i = 0; i < 32; ) { + fs = f[i++]; + fs = (fs > 32767.0f ? 32767.0f + : (Math.max(fs, -32767.0f))); + + s = (short) fs; + buffer[pos] = s; + pos += channels; + } + + bufferp[channel] = pos; + } + + + /** + * Write the samples to the file (Random Acces). + */ + public void write_buffer(int val) { + + } + + public void close() { + } + + /** + * + */ + public void clear_buffer() { + for (int i = 0; i < channels; ++i) + bufferp[i] = (short) i; + } + + /** + * + */ + public void set_stop_flag() { + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Source.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Source.java new file mode 100644 index 000000000..89f9b318e --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/Source.java @@ -0,0 +1,47 @@ +/* + * 11/19/04 1.0 moved to LGPL. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.IOException; + + +/** + * Work in progress. + *

+ * Class to describe a seekable data source. + */ +public interface Source { + + long LENGTH_UNKNOWN = -1; + + int read(byte[] b, int offs, int len) + throws IOException; + + + boolean willReadBlock(); + + boolean isSeekable(); + + long length(); + + long tell(); + + long seek(long pos); +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/SynthesisFilter.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/SynthesisFilter.java new file mode 100644 index 000000000..97ed3c53f --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/SynthesisFilter.java @@ -0,0 +1,1678 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 04/01/00 Fixes for running under build 23xx Microsoft JVM. mdm. + * + * 19/12/99 Performance improvements to compute_pcm_samples(). + * Mat McGowan. mdm@techie.com. + * + * 16/02/99 Java Conversion by E.B , javalayer@javazoom.net + * + * @(#) synthesis_filter.h 1.8, last edit: 6/15/94 16:52:00 + * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de) + * @(#) Berlin University of Technology + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.IOException; + + +/** + * A class for the synthesis filter bank. + * This class does a fast downsampling from 32, 44.1 or 48 kHz to 8 kHz, if ULAW is defined. + * Frequencies above 4 kHz are removed by ignoring higher subbands. + */ +final class SynthesisFilter { + private float[] v1; + private float[] v2; + private float[] actual_v; // v1 or v2 + private int actual_write_pos; // 0-15 + private float[] samples; // 32 new subband samples + private int channel; + private float scalefactor; + private float[] eq; + + /** + * Contructor. + * The scalefactor scales the calculated float pcm samples to short values + * (raw pcm samples are in [-1.0, 1.0], if no violations occur). + */ + public SynthesisFilter(int channelnumber, float factor, float[] eq0) { + if (d == null) { + d = load_d(); + d16 = splitArray(d, 16); + } + + v1 = new float[512]; + v2 = new float[512]; + samples = new float[32]; + channel = channelnumber; + scalefactor = factor; + setEQ(eq); + //setQuality(HIGH_QUALITY); + + reset(); + } + + public void setEQ(float[] eq0) { + this.eq = eq0; + if (eq == null) { + eq = new float[32]; + for (int i = 0; i < 32; i++) + eq[i] = 1.0f; + } + if (eq.length < 32) { + throw new IllegalArgumentException("eq0"); + } + + } + + /** + * Reset the synthesis filter. + */ + public void reset() { + //float[] floatp; + // float[] floatp2; + + // initialize v1[] and v2[]: + //for (floatp = v1 + 512, floatp2 = v2 + 512; floatp > v1; ) + // *--floatp = *--floatp2 = 0.0; + for (int p = 0; p < 512; p++) + v1[p] = v2[p] = 0.0f; + + // initialize samples[]: + //for (floatp = samples + 32; floatp > samples; ) + // *--floatp = 0.0; + for (int p2 = 0; p2 < 32; p2++) + samples[p2] = 0.0f; + + actual_v = v1; + actual_write_pos = 15; + } + + + /** + * Inject Sample. + */ + public void input_sample(float sample, int subbandnumber) { + samples[subbandnumber] = eq[subbandnumber] * sample; + } + + public void input_samples(float[] s) { + for (int i = 31; i >= 0; i--) { + samples[i] = s[i] * eq[i]; + } + } + + /** + * Compute new values via a fast cosine transform. + */ + private void compute_new_v() { + // p is fully initialized from x1 + //float[] p = _p; + // pp is fully initialized from p + + float new_v0, new_v1, new_v2, new_v3, new_v4, new_v5, new_v6, new_v7, new_v8, new_v9; + float new_v10, new_v11, new_v12, new_v13, new_v14, new_v15, new_v16, new_v17, new_v18, new_v19; + float new_v20, new_v21, new_v22, new_v23, new_v24, new_v25, new_v26, new_v27, new_v28, new_v29; + float new_v30, new_v31; + + new_v0 = new_v1 = new_v2 = new_v3 = new_v4 = new_v5 = new_v6 = new_v7 = new_v8 = new_v9 = + new_v10 = new_v11 = new_v12 = new_v13 = new_v14 = new_v15 = new_v16 = new_v17 = new_v18 = new_v19 = + new_v20 = new_v21 = new_v22 = new_v23 = new_v24 = new_v25 = new_v26 = new_v27 = new_v28 = new_v29 = + new_v30 = new_v31 = 0.0f; + + + float[] s = samples; + + float s0 = s[0]; + float s1 = s[1]; + float s2 = s[2]; + float s3 = s[3]; + float s4 = s[4]; + float s5 = s[5]; + float s6 = s[6]; + float s7 = s[7]; + float s8 = s[8]; + float s9 = s[9]; + float s10 = s[10]; + float s11 = s[11]; + float s12 = s[12]; + float s13 = s[13]; + float s14 = s[14]; + float s15 = s[15]; + float s16 = s[16]; + float s17 = s[17]; + float s18 = s[18]; + float s19 = s[19]; + float s20 = s[20]; + float s21 = s[21]; + float s22 = s[22]; + float s23 = s[23]; + float s24 = s[24]; + float s25 = s[25]; + float s26 = s[26]; + float s27 = s[27]; + float s28 = s[28]; + float s29 = s[29]; + float s30 = s[30]; + float s31 = s[31]; + + float p0 = s0 + s31; + float p1 = s1 + s30; + float p2 = s2 + s29; + float p3 = s3 + s28; + float p4 = s4 + s27; + float p5 = s5 + s26; + float p6 = s6 + s25; + float p7 = s7 + s24; + float p8 = s8 + s23; + float p9 = s9 + s22; + float p10 = s10 + s21; + float p11 = s11 + s20; + float p12 = s12 + s19; + float p13 = s13 + s18; + float p14 = s14 + s17; + float p15 = s15 + s16; + + float pp0 = p0 + p15; + float pp1 = p1 + p14; + float pp2 = p2 + p13; + float pp3 = p3 + p12; + float pp4 = p4 + p11; + float pp5 = p5 + p10; + float pp6 = p6 + p9; + float pp7 = p7 + p8; + float pp8 = (p0 - p15) * cos1_32; + float pp9 = (p1 - p14) * cos3_32; + float pp10 = (p2 - p13) * cos5_32; + float pp11 = (p3 - p12) * cos7_32; + float pp12 = (p4 - p11) * cos9_32; + float pp13 = (p5 - p10) * cos11_32; + float pp14 = (p6 - p9) * cos13_32; + float pp15 = (p7 - p8) * cos15_32; + + p0 = pp0 + pp7; + p1 = pp1 + pp6; + p2 = pp2 + pp5; + p3 = pp3 + pp4; + p4 = (pp0 - pp7) * cos1_16; + p5 = (pp1 - pp6) * cos3_16; + p6 = (pp2 - pp5) * cos5_16; + p7 = (pp3 - pp4) * cos7_16; + p8 = pp8 + pp15; + p9 = pp9 + pp14; + p10 = pp10 + pp13; + p11 = pp11 + pp12; + p12 = (pp8 - pp15) * cos1_16; + p13 = (pp9 - pp14) * cos3_16; + p14 = (pp10 - pp13) * cos5_16; + p15 = (pp11 - pp12) * cos7_16; + + + pp0 = p0 + p3; + pp1 = p1 + p2; + pp2 = (p0 - p3) * cos1_8; + pp3 = (p1 - p2) * cos3_8; + pp4 = p4 + p7; + pp5 = p5 + p6; + pp6 = (p4 - p7) * cos1_8; + pp7 = (p5 - p6) * cos3_8; + pp8 = p8 + p11; + pp9 = p9 + p10; + pp10 = (p8 - p11) * cos1_8; + pp11 = (p9 - p10) * cos3_8; + pp12 = p12 + p15; + pp13 = p13 + p14; + pp14 = (p12 - p15) * cos1_8; + pp15 = (p13 - p14) * cos3_8; + + p0 = pp0 + pp1; + p1 = (pp0 - pp1) * cos1_4; + p2 = pp2 + pp3; + p3 = (pp2 - pp3) * cos1_4; + p4 = pp4 + pp5; + p5 = (pp4 - pp5) * cos1_4; + p6 = pp6 + pp7; + p7 = (pp6 - pp7) * cos1_4; + p8 = pp8 + pp9; + p9 = (pp8 - pp9) * cos1_4; + p10 = pp10 + pp11; + p11 = (pp10 - pp11) * cos1_4; + p12 = pp12 + pp13; + p13 = (pp12 - pp13) * cos1_4; + p14 = pp14 + pp15; + p15 = (pp14 - pp15) * cos1_4; + + // this is pretty insane coding + float tmp1; + new_v19/*36-17*/ = -(new_v4 = (new_v12 = p7) + p5) - p6; + new_v27/*44-17*/ = -p6 - p7 - p4; + new_v6 = (new_v10 = (new_v14 = p15) + p11) + p13; + new_v17/*34-17*/ = -(new_v2 = p15 + p13 + p9) - p14; + new_v21/*38-17*/ = (tmp1 = -p14 - p15 - p10 - p11) - p13; + new_v29/*46-17*/ = -p14 - p15 - p12 - p8; + new_v25/*42-17*/ = tmp1 - p12; + new_v31/*48-17*/ = -p0; + new_v0 = p1; + new_v23/*40-17*/ = -(new_v8 = p3) - p2; + + p0 = (s0 - s31) * cos1_64; + p1 = (s1 - s30) * cos3_64; + p2 = (s2 - s29) * cos5_64; + p3 = (s3 - s28) * cos7_64; + p4 = (s4 - s27) * cos9_64; + p5 = (s5 - s26) * cos11_64; + p6 = (s6 - s25) * cos13_64; + p7 = (s7 - s24) * cos15_64; + p8 = (s8 - s23) * cos17_64; + p9 = (s9 - s22) * cos19_64; + p10 = (s10 - s21) * cos21_64; + p11 = (s11 - s20) * cos23_64; + p12 = (s12 - s19) * cos25_64; + p13 = (s13 - s18) * cos27_64; + p14 = (s14 - s17) * cos29_64; + p15 = (s15 - s16) * cos31_64; + + + pp0 = p0 + p15; + pp1 = p1 + p14; + pp2 = p2 + p13; + pp3 = p3 + p12; + pp4 = p4 + p11; + pp5 = p5 + p10; + pp6 = p6 + p9; + pp7 = p7 + p8; + pp8 = (p0 - p15) * cos1_32; + pp9 = (p1 - p14) * cos3_32; + pp10 = (p2 - p13) * cos5_32; + pp11 = (p3 - p12) * cos7_32; + pp12 = (p4 - p11) * cos9_32; + pp13 = (p5 - p10) * cos11_32; + pp14 = (p6 - p9) * cos13_32; + pp15 = (p7 - p8) * cos15_32; + + + p0 = pp0 + pp7; + p1 = pp1 + pp6; + p2 = pp2 + pp5; + p3 = pp3 + pp4; + p4 = (pp0 - pp7) * cos1_16; + p5 = (pp1 - pp6) * cos3_16; + p6 = (pp2 - pp5) * cos5_16; + p7 = (pp3 - pp4) * cos7_16; + p8 = pp8 + pp15; + p9 = pp9 + pp14; + p10 = pp10 + pp13; + p11 = pp11 + pp12; + p12 = (pp8 - pp15) * cos1_16; + p13 = (pp9 - pp14) * cos3_16; + p14 = (pp10 - pp13) * cos5_16; + p15 = (pp11 - pp12) * cos7_16; + + + pp0 = p0 + p3; + pp1 = p1 + p2; + pp2 = (p0 - p3) * cos1_8; + pp3 = (p1 - p2) * cos3_8; + pp4 = p4 + p7; + pp5 = p5 + p6; + pp6 = (p4 - p7) * cos1_8; + pp7 = (p5 - p6) * cos3_8; + pp8 = p8 + p11; + pp9 = p9 + p10; + pp10 = (p8 - p11) * cos1_8; + pp11 = (p9 - p10) * cos3_8; + pp12 = p12 + p15; + pp13 = p13 + p14; + pp14 = (p12 - p15) * cos1_8; + pp15 = (p13 - p14) * cos3_8; + + + p0 = pp0 + pp1; + p1 = (pp0 - pp1) * cos1_4; + p2 = pp2 + pp3; + p3 = (pp2 - pp3) * cos1_4; + p4 = pp4 + pp5; + p5 = (pp4 - pp5) * cos1_4; + p6 = pp6 + pp7; + p7 = (pp6 - pp7) * cos1_4; + p8 = pp8 + pp9; + p9 = (pp8 - pp9) * cos1_4; + p10 = pp10 + pp11; + p11 = (pp10 - pp11) * cos1_4; + p12 = pp12 + pp13; + p13 = (pp12 - pp13) * cos1_4; + p14 = pp14 + pp15; + p15 = (pp14 - pp15) * cos1_4; + + + // manually doing something that a compiler should handle sucks + // coding like this is hard to read + float tmp2; + new_v5 = (new_v11 = (new_v13 = (new_v15 = p15) + p7) + p11) + + p5 + p13; + new_v7 = (new_v9 = p15 + p11 + p3) + p13; + new_v16/*33-17*/ = -(new_v1 = (tmp1 = p13 + p15 + p9) + p1) - p14; + new_v18/*35-17*/ = -(new_v3 = tmp1 + p5 + p7) - p6 - p14; + + new_v22/*39-17*/ = (tmp1 = -p10 - p11 - p14 - p15) + - p13 - p2 - p3; + new_v20/*37-17*/ = tmp1 - p13 - p5 - p6 - p7; + new_v24/*41-17*/ = tmp1 - p12 - p2 - p3; + new_v26/*43-17*/ = tmp1 - p12 - (tmp2 = p4 + p6 + p7); + new_v30/*47-17*/ = (tmp1 = -p8 - p12 - p14 - p15) - p0; + new_v28/*45-17*/ = tmp1 - tmp2; + + // insert V[0-15] (== new_v[0-15]) into actual v: + // float[] x2 = actual_v + actual_write_pos; + float[] dest = actual_v; + + int pos = actual_write_pos; + + dest[0 + pos] = new_v0; + dest[16 + pos] = new_v1; + dest[32 + pos] = new_v2; + dest[48 + pos] = new_v3; + dest[64 + pos] = new_v4; + dest[80 + pos] = new_v5; + dest[96 + pos] = new_v6; + dest[112 + pos] = new_v7; + dest[128 + pos] = new_v8; + dest[144 + pos] = new_v9; + dest[160 + pos] = new_v10; + dest[176 + pos] = new_v11; + dest[192 + pos] = new_v12; + dest[208 + pos] = new_v13; + dest[224 + pos] = new_v14; + dest[240 + pos] = new_v15; + + // V[16] is always 0.0: + dest[256 + pos] = 0.0f; + + // insert V[17-31] (== -new_v[15-1]) into actual v: + dest[272 + pos] = -new_v15; + dest[288 + pos] = -new_v14; + dest[304 + pos] = -new_v13; + dest[320 + pos] = -new_v12; + dest[336 + pos] = -new_v11; + dest[352 + pos] = -new_v10; + dest[368 + pos] = -new_v9; + dest[384 + pos] = -new_v8; + dest[400 + pos] = -new_v7; + dest[416 + pos] = -new_v6; + dest[432 + pos] = -new_v5; + dest[448 + pos] = -new_v4; + dest[464 + pos] = -new_v3; + dest[480 + pos] = -new_v2; + dest[496 + pos] = -new_v1; + + // insert V[32] (== -new_v[0]) into other v: + dest = (actual_v == v1) ? v2 : v1; + + dest[0 + pos] = -new_v0; + // insert V[33-48] (== new_v[16-31]) into other v: + dest[16 + pos] = new_v16; + dest[32 + pos] = new_v17; + dest[48 + pos] = new_v18; + dest[64 + pos] = new_v19; + dest[80 + pos] = new_v20; + dest[96 + pos] = new_v21; + dest[112 + pos] = new_v22; + dest[128 + pos] = new_v23; + dest[144 + pos] = new_v24; + dest[160 + pos] = new_v25; + dest[176 + pos] = new_v26; + dest[192 + pos] = new_v27; + dest[208 + pos] = new_v28; + dest[224 + pos] = new_v29; + dest[240 + pos] = new_v30; + dest[256 + pos] = new_v31; + + // insert V[49-63] (== new_v[30-16]) into other v: + dest[272 + pos] = new_v30; + dest[288 + pos] = new_v29; + dest[304 + pos] = new_v28; + dest[320 + pos] = new_v27; + dest[336 + pos] = new_v26; + dest[352 + pos] = new_v25; + dest[368 + pos] = new_v24; + dest[384 + pos] = new_v23; + dest[400 + pos] = new_v22; + dest[416 + pos] = new_v21; + dest[432 + pos] = new_v20; + dest[448 + pos] = new_v19; + dest[464 + pos] = new_v18; + dest[480 + pos] = new_v17; + dest[496 + pos] = new_v16; +/* + } + else + { + v1[0 + actual_write_pos] = -new_v0; + // insert V[33-48] (== new_v[16-31]) into other v: + v1[16 + actual_write_pos] = new_v16; + v1[32 + actual_write_pos] = new_v17; + v1[48 + actual_write_pos] = new_v18; + v1[64 + actual_write_pos] = new_v19; + v1[80 + actual_write_pos] = new_v20; + v1[96 + actual_write_pos] = new_v21; + v1[112 + actual_write_pos] = new_v22; + v1[128 + actual_write_pos] = new_v23; + v1[144 + actual_write_pos] = new_v24; + v1[160 + actual_write_pos] = new_v25; + v1[176 + actual_write_pos] = new_v26; + v1[192 + actual_write_pos] = new_v27; + v1[208 + actual_write_pos] = new_v28; + v1[224 + actual_write_pos] = new_v29; + v1[240 + actual_write_pos] = new_v30; + v1[256 + actual_write_pos] = new_v31; + + // insert V[49-63] (== new_v[30-16]) into other v: + v1[272 + actual_write_pos] = new_v30; + v1[288 + actual_write_pos] = new_v29; + v1[304 + actual_write_pos] = new_v28; + v1[320 + actual_write_pos] = new_v27; + v1[336 + actual_write_pos] = new_v26; + v1[352 + actual_write_pos] = new_v25; + v1[368 + actual_write_pos] = new_v24; + v1[384 + actual_write_pos] = new_v23; + v1[400 + actual_write_pos] = new_v22; + v1[416 + actual_write_pos] = new_v21; + v1[432 + actual_write_pos] = new_v20; + v1[448 + actual_write_pos] = new_v19; + v1[464 + actual_write_pos] = new_v18; + v1[480 + actual_write_pos] = new_v17; + v1[496 + actual_write_pos] = new_v16; + } +*/ + } + + /** + * Compute new values via a fast cosine transform. + */ + @SuppressWarnings("unused") + private void compute_new_v_old() { + // p is fully initialized from x1 + //float[] p = _p; + // pp is fully initialized from p + + float[] new_v = new float[32]; // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3 + float[] p = new float[16]; + float[] pp = new float[16]; + + + for (int i = 31; i >= 0; i--) { + new_v[i] = 0.0f; + } + + float[] x1 = samples; + + p[0] = x1[0] + x1[31]; + p[1] = x1[1] + x1[30]; + p[2] = x1[2] + x1[29]; + p[3] = x1[3] + x1[28]; + p[4] = x1[4] + x1[27]; + p[5] = x1[5] + x1[26]; + p[6] = x1[6] + x1[25]; + p[7] = x1[7] + x1[24]; + p[8] = x1[8] + x1[23]; + p[9] = x1[9] + x1[22]; + p[10] = x1[10] + x1[21]; + p[11] = x1[11] + x1[20]; + p[12] = x1[12] + x1[19]; + p[13] = x1[13] + x1[18]; + p[14] = x1[14] + x1[17]; + p[15] = x1[15] + x1[16]; + + pp[0] = p[0] + p[15]; + pp[1] = p[1] + p[14]; + pp[2] = p[2] + p[13]; + pp[3] = p[3] + p[12]; + pp[4] = p[4] + p[11]; + pp[5] = p[5] + p[10]; + pp[6] = p[6] + p[9]; + pp[7] = p[7] + p[8]; + pp[8] = (p[0] - p[15]) * cos1_32; + pp[9] = (p[1] - p[14]) * cos3_32; + pp[10] = (p[2] - p[13]) * cos5_32; + pp[11] = (p[3] - p[12]) * cos7_32; + pp[12] = (p[4] - p[11]) * cos9_32; + pp[13] = (p[5] - p[10]) * cos11_32; + pp[14] = (p[6] - p[9]) * cos13_32; + pp[15] = (p[7] - p[8]) * cos15_32; + + p[0] = pp[0] + pp[7]; + p[1] = pp[1] + pp[6]; + p[2] = pp[2] + pp[5]; + p[3] = pp[3] + pp[4]; + p[4] = (pp[0] - pp[7]) * cos1_16; + p[5] = (pp[1] - pp[6]) * cos3_16; + p[6] = (pp[2] - pp[5]) * cos5_16; + p[7] = (pp[3] - pp[4]) * cos7_16; + p[8] = pp[8] + pp[15]; + p[9] = pp[9] + pp[14]; + p[10] = pp[10] + pp[13]; + p[11] = pp[11] + pp[12]; + p[12] = (pp[8] - pp[15]) * cos1_16; + p[13] = (pp[9] - pp[14]) * cos3_16; + p[14] = (pp[10] - pp[13]) * cos5_16; + p[15] = (pp[11] - pp[12]) * cos7_16; + + + pp[0] = p[0] + p[3]; + pp[1] = p[1] + p[2]; + pp[2] = (p[0] - p[3]) * cos1_8; + pp[3] = (p[1] - p[2]) * cos3_8; + pp[4] = p[4] + p[7]; + pp[5] = p[5] + p[6]; + pp[6] = (p[4] - p[7]) * cos1_8; + pp[7] = (p[5] - p[6]) * cos3_8; + pp[8] = p[8] + p[11]; + pp[9] = p[9] + p[10]; + pp[10] = (p[8] - p[11]) * cos1_8; + pp[11] = (p[9] - p[10]) * cos3_8; + pp[12] = p[12] + p[15]; + pp[13] = p[13] + p[14]; + pp[14] = (p[12] - p[15]) * cos1_8; + pp[15] = (p[13] - p[14]) * cos3_8; + + p[0] = pp[0] + pp[1]; + p[1] = (pp[0] - pp[1]) * cos1_4; + p[2] = pp[2] + pp[3]; + p[3] = (pp[2] - pp[3]) * cos1_4; + p[4] = pp[4] + pp[5]; + p[5] = (pp[4] - pp[5]) * cos1_4; + p[6] = pp[6] + pp[7]; + p[7] = (pp[6] - pp[7]) * cos1_4; + p[8] = pp[8] + pp[9]; + p[9] = (pp[8] - pp[9]) * cos1_4; + p[10] = pp[10] + pp[11]; + p[11] = (pp[10] - pp[11]) * cos1_4; + p[12] = pp[12] + pp[13]; + p[13] = (pp[12] - pp[13]) * cos1_4; + p[14] = pp[14] + pp[15]; + p[15] = (pp[14] - pp[15]) * cos1_4; + + // this is pretty insane coding + float tmp1; + new_v[36 - 17] = -(new_v[4] = (new_v[12] = p[7]) + p[5]) - p[6]; + new_v[44 - 17] = -p[6] - p[7] - p[4]; + new_v[6] = (new_v[10] = (new_v[14] = p[15]) + p[11]) + p[13]; + new_v[34 - 17] = -(new_v[2] = p[15] + p[13] + p[9]) - p[14]; + new_v[38 - 17] = (tmp1 = -p[14] - p[15] - p[10] - p[11]) - p[13]; + new_v[46 - 17] = -p[14] - p[15] - p[12] - p[8]; + new_v[42 - 17] = tmp1 - p[12]; + new_v[48 - 17] = -p[0]; + new_v[0] = p[1]; + new_v[40 - 17] = -(new_v[8] = p[3]) - p[2]; + + p[0] = (x1[0] - x1[31]) * cos1_64; + p[1] = (x1[1] - x1[30]) * cos3_64; + p[2] = (x1[2] - x1[29]) * cos5_64; + p[3] = (x1[3] - x1[28]) * cos7_64; + p[4] = (x1[4] - x1[27]) * cos9_64; + p[5] = (x1[5] - x1[26]) * cos11_64; + p[6] = (x1[6] - x1[25]) * cos13_64; + p[7] = (x1[7] - x1[24]) * cos15_64; + p[8] = (x1[8] - x1[23]) * cos17_64; + p[9] = (x1[9] - x1[22]) * cos19_64; + p[10] = (x1[10] - x1[21]) * cos21_64; + p[11] = (x1[11] - x1[20]) * cos23_64; + p[12] = (x1[12] - x1[19]) * cos25_64; + p[13] = (x1[13] - x1[18]) * cos27_64; + p[14] = (x1[14] - x1[17]) * cos29_64; + p[15] = (x1[15] - x1[16]) * cos31_64; + + + pp[0] = p[0] + p[15]; + pp[1] = p[1] + p[14]; + pp[2] = p[2] + p[13]; + pp[3] = p[3] + p[12]; + pp[4] = p[4] + p[11]; + pp[5] = p[5] + p[10]; + pp[6] = p[6] + p[9]; + pp[7] = p[7] + p[8]; + pp[8] = (p[0] - p[15]) * cos1_32; + pp[9] = (p[1] - p[14]) * cos3_32; + pp[10] = (p[2] - p[13]) * cos5_32; + pp[11] = (p[3] - p[12]) * cos7_32; + pp[12] = (p[4] - p[11]) * cos9_32; + pp[13] = (p[5] - p[10]) * cos11_32; + pp[14] = (p[6] - p[9]) * cos13_32; + pp[15] = (p[7] - p[8]) * cos15_32; + + + p[0] = pp[0] + pp[7]; + p[1] = pp[1] + pp[6]; + p[2] = pp[2] + pp[5]; + p[3] = pp[3] + pp[4]; + p[4] = (pp[0] - pp[7]) * cos1_16; + p[5] = (pp[1] - pp[6]) * cos3_16; + p[6] = (pp[2] - pp[5]) * cos5_16; + p[7] = (pp[3] - pp[4]) * cos7_16; + p[8] = pp[8] + pp[15]; + p[9] = pp[9] + pp[14]; + p[10] = pp[10] + pp[13]; + p[11] = pp[11] + pp[12]; + p[12] = (pp[8] - pp[15]) * cos1_16; + p[13] = (pp[9] - pp[14]) * cos3_16; + p[14] = (pp[10] - pp[13]) * cos5_16; + p[15] = (pp[11] - pp[12]) * cos7_16; + + + pp[0] = p[0] + p[3]; + pp[1] = p[1] + p[2]; + pp[2] = (p[0] - p[3]) * cos1_8; + pp[3] = (p[1] - p[2]) * cos3_8; + pp[4] = p[4] + p[7]; + pp[5] = p[5] + p[6]; + pp[6] = (p[4] - p[7]) * cos1_8; + pp[7] = (p[5] - p[6]) * cos3_8; + pp[8] = p[8] + p[11]; + pp[9] = p[9] + p[10]; + pp[10] = (p[8] - p[11]) * cos1_8; + pp[11] = (p[9] - p[10]) * cos3_8; + pp[12] = p[12] + p[15]; + pp[13] = p[13] + p[14]; + pp[14] = (p[12] - p[15]) * cos1_8; + pp[15] = (p[13] - p[14]) * cos3_8; + + + p[0] = pp[0] + pp[1]; + p[1] = (pp[0] - pp[1]) * cos1_4; + p[2] = pp[2] + pp[3]; + p[3] = (pp[2] - pp[3]) * cos1_4; + p[4] = pp[4] + pp[5]; + p[5] = (pp[4] - pp[5]) * cos1_4; + p[6] = pp[6] + pp[7]; + p[7] = (pp[6] - pp[7]) * cos1_4; + p[8] = pp[8] + pp[9]; + p[9] = (pp[8] - pp[9]) * cos1_4; + p[10] = pp[10] + pp[11]; + p[11] = (pp[10] - pp[11]) * cos1_4; + p[12] = pp[12] + pp[13]; + p[13] = (pp[12] - pp[13]) * cos1_4; + p[14] = pp[14] + pp[15]; + p[15] = (pp[14] - pp[15]) * cos1_4; + + + // manually doing something that a compiler should handle sucks + // coding like this is hard to read + float tmp2; + new_v[5] = (new_v[11] = (new_v[13] = (new_v[15] = p[15]) + p[7]) + p[11]) + + p[5] + p[13]; + new_v[7] = (new_v[9] = p[15] + p[11] + p[3]) + p[13]; + new_v[33 - 17] = -(new_v[1] = (tmp1 = p[13] + p[15] + p[9]) + p[1]) - p[14]; + new_v[35 - 17] = -(new_v[3] = tmp1 + p[5] + p[7]) - p[6] - p[14]; + + new_v[39 - 17] = (tmp1 = -p[10] - p[11] - p[14] - p[15]) + - p[13] - p[2] - p[3]; + new_v[37 - 17] = tmp1 - p[13] - p[5] - p[6] - p[7]; + new_v[41 - 17] = tmp1 - p[12] - p[2] - p[3]; + new_v[43 - 17] = tmp1 - p[12] - (tmp2 = p[4] + p[6] + p[7]); + new_v[47 - 17] = (tmp1 = -p[8] - p[12] - p[14] - p[15]) - p[0]; + new_v[45 - 17] = tmp1 - tmp2; + + // insert V[0-15] (== new_v[0-15]) into actual v: + x1 = new_v; + // float[] x2 = actual_v + actual_write_pos; + float[] dest = actual_v; + + dest[0 + actual_write_pos] = x1[0]; + dest[16 + actual_write_pos] = x1[1]; + dest[32 + actual_write_pos] = x1[2]; + dest[48 + actual_write_pos] = x1[3]; + dest[64 + actual_write_pos] = x1[4]; + dest[80 + actual_write_pos] = x1[5]; + dest[96 + actual_write_pos] = x1[6]; + dest[112 + actual_write_pos] = x1[7]; + dest[128 + actual_write_pos] = x1[8]; + dest[144 + actual_write_pos] = x1[9]; + dest[160 + actual_write_pos] = x1[10]; + dest[176 + actual_write_pos] = x1[11]; + dest[192 + actual_write_pos] = x1[12]; + dest[208 + actual_write_pos] = x1[13]; + dest[224 + actual_write_pos] = x1[14]; + dest[240 + actual_write_pos] = x1[15]; + + // V[16] is always 0.0: + dest[256 + actual_write_pos] = 0.0f; + + // insert V[17-31] (== -new_v[15-1]) into actual v: + dest[272 + actual_write_pos] = -x1[15]; + dest[288 + actual_write_pos] = -x1[14]; + dest[304 + actual_write_pos] = -x1[13]; + dest[320 + actual_write_pos] = -x1[12]; + dest[336 + actual_write_pos] = -x1[11]; + dest[352 + actual_write_pos] = -x1[10]; + dest[368 + actual_write_pos] = -x1[9]; + dest[384 + actual_write_pos] = -x1[8]; + dest[400 + actual_write_pos] = -x1[7]; + dest[416 + actual_write_pos] = -x1[6]; + dest[432 + actual_write_pos] = -x1[5]; + dest[448 + actual_write_pos] = -x1[4]; + dest[464 + actual_write_pos] = -x1[3]; + dest[480 + actual_write_pos] = -x1[2]; + dest[496 + actual_write_pos] = -x1[1]; + + // insert V[32] (== -new_v[0]) into other v: + + } + + /** + * Compute PCM Samples. + */ + + private float[] _tmpOut = new float[32]; + + + private void compute_pcm_samples0(Obuffer buffer) { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + float pcm_sample; + final float[] dp = d16[i]; + pcm_sample = ((vp[0 + dvp] * dp[0]) + + (vp[15 + dvp] * dp[1]) + + (vp[14 + dvp] * dp[2]) + + (vp[13 + dvp] * dp[3]) + + (vp[12 + dvp] * dp[4]) + + (vp[11 + dvp] * dp[5]) + + (vp[10 + dvp] * dp[6]) + + (vp[9 + dvp] * dp[7]) + + (vp[8 + dvp] * dp[8]) + + (vp[7 + dvp] * dp[9]) + + (vp[6 + dvp] * dp[10]) + + (vp[5 + dvp] * dp[11]) + + (vp[4 + dvp] * dp[12]) + + (vp[3 + dvp] * dp[13]) + + (vp[2 + dvp] * dp[14]) + + (vp[1 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples1(Obuffer buffer) { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = ((vp[1 + dvp] * dp[0]) + + (vp[0 + dvp] * dp[1]) + + (vp[15 + dvp] * dp[2]) + + (vp[14 + dvp] * dp[3]) + + (vp[13 + dvp] * dp[4]) + + (vp[12 + dvp] * dp[5]) + + (vp[11 + dvp] * dp[6]) + + (vp[10 + dvp] * dp[7]) + + (vp[9 + dvp] * dp[8]) + + (vp[8 + dvp] * dp[9]) + + (vp[7 + dvp] * dp[10]) + + (vp[6 + dvp] * dp[11]) + + (vp[5 + dvp] * dp[12]) + + (vp[4 + dvp] * dp[13]) + + (vp[3 + dvp] * dp[14]) + + (vp[2 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples2(Obuffer buffer) { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = ((vp[2 + dvp] * dp[0]) + + (vp[1 + dvp] * dp[1]) + + (vp[0 + dvp] * dp[2]) + + (vp[15 + dvp] * dp[3]) + + (vp[14 + dvp] * dp[4]) + + (vp[13 + dvp] * dp[5]) + + (vp[12 + dvp] * dp[6]) + + (vp[11 + dvp] * dp[7]) + + (vp[10 + dvp] * dp[8]) + + (vp[9 + dvp] * dp[9]) + + (vp[8 + dvp] * dp[10]) + + (vp[7 + dvp] * dp[11]) + + (vp[6 + dvp] * dp[12]) + + (vp[5 + dvp] * dp[13]) + + (vp[4 + dvp] * dp[14]) + + (vp[3 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples3(Obuffer buffer) { + final float[] vp = actual_v; + + @SuppressWarnings("unused") + int idx = 0; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = ((vp[3 + dvp] * dp[0]) + + (vp[2 + dvp] * dp[1]) + + (vp[1 + dvp] * dp[2]) + + (vp[0 + dvp] * dp[3]) + + (vp[15 + dvp] * dp[4]) + + (vp[14 + dvp] * dp[5]) + + (vp[13 + dvp] * dp[6]) + + (vp[12 + dvp] * dp[7]) + + (vp[11 + dvp] * dp[8]) + + (vp[10 + dvp] * dp[9]) + + (vp[9 + dvp] * dp[10]) + + (vp[8 + dvp] * dp[11]) + + (vp[7 + dvp] * dp[12]) + + (vp[6 + dvp] * dp[13]) + + (vp[5 + dvp] * dp[14]) + + (vp[4 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples4(Obuffer buffer) { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = ((vp[4 + dvp] * dp[0]) + + (vp[3 + dvp] * dp[1]) + + (vp[2 + dvp] * dp[2]) + + (vp[1 + dvp] * dp[3]) + + (vp[0 + dvp] * dp[4]) + + (vp[15 + dvp] * dp[5]) + + (vp[14 + dvp] * dp[6]) + + (vp[13 + dvp] * dp[7]) + + (vp[12 + dvp] * dp[8]) + + (vp[11 + dvp] * dp[9]) + + (vp[10 + dvp] * dp[10]) + + (vp[9 + dvp] * dp[11]) + + (vp[8 + dvp] * dp[12]) + + (vp[7 + dvp] * dp[13]) + + (vp[6 + dvp] * dp[14]) + + (vp[5 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples5(Obuffer buffer) { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = ((vp[5 + dvp] * dp[0]) + + (vp[4 + dvp] * dp[1]) + + (vp[3 + dvp] * dp[2]) + + (vp[2 + dvp] * dp[3]) + + (vp[1 + dvp] * dp[4]) + + (vp[0 + dvp] * dp[5]) + + (vp[15 + dvp] * dp[6]) + + (vp[14 + dvp] * dp[7]) + + (vp[13 + dvp] * dp[8]) + + (vp[12 + dvp] * dp[9]) + + (vp[11 + dvp] * dp[10]) + + (vp[10 + dvp] * dp[11]) + + (vp[9 + dvp] * dp[12]) + + (vp[8 + dvp] * dp[13]) + + (vp[7 + dvp] * dp[14]) + + (vp[6 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples6(Obuffer buffer) { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = ((vp[6 + dvp] * dp[0]) + + (vp[5 + dvp] * dp[1]) + + (vp[4 + dvp] * dp[2]) + + (vp[3 + dvp] * dp[3]) + + (vp[2 + dvp] * dp[4]) + + (vp[1 + dvp] * dp[5]) + + (vp[0 + dvp] * dp[6]) + + (vp[15 + dvp] * dp[7]) + + (vp[14 + dvp] * dp[8]) + + (vp[13 + dvp] * dp[9]) + + (vp[12 + dvp] * dp[10]) + + (vp[11 + dvp] * dp[11]) + + (vp[10 + dvp] * dp[12]) + + (vp[9 + dvp] * dp[13]) + + (vp[8 + dvp] * dp[14]) + + (vp[7 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples7(Obuffer buffer) { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = ((vp[7 + dvp] * dp[0]) + + (vp[6 + dvp] * dp[1]) + + (vp[5 + dvp] * dp[2]) + + (vp[4 + dvp] * dp[3]) + + (vp[3 + dvp] * dp[4]) + + (vp[2 + dvp] * dp[5]) + + (vp[1 + dvp] * dp[6]) + + (vp[0 + dvp] * dp[7]) + + (vp[15 + dvp] * dp[8]) + + (vp[14 + dvp] * dp[9]) + + (vp[13 + dvp] * dp[10]) + + (vp[12 + dvp] * dp[11]) + + (vp[11 + dvp] * dp[12]) + + (vp[10 + dvp] * dp[13]) + + (vp[9 + dvp] * dp[14]) + + (vp[8 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples8(Obuffer buffer) { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = ((vp[8 + dvp] * dp[0]) + + (vp[7 + dvp] * dp[1]) + + (vp[6 + dvp] * dp[2]) + + (vp[5 + dvp] * dp[3]) + + (vp[4 + dvp] * dp[4]) + + (vp[3 + dvp] * dp[5]) + + (vp[2 + dvp] * dp[6]) + + (vp[1 + dvp] * dp[7]) + + (vp[0 + dvp] * dp[8]) + + (vp[15 + dvp] * dp[9]) + + (vp[14 + dvp] * dp[10]) + + (vp[13 + dvp] * dp[11]) + + (vp[12 + dvp] * dp[12]) + + (vp[11 + dvp] * dp[13]) + + (vp[10 + dvp] * dp[14]) + + (vp[9 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples9(Obuffer buffer) { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = ((vp[9 + dvp] * dp[0]) + + (vp[8 + dvp] * dp[1]) + + (vp[7 + dvp] * dp[2]) + + (vp[6 + dvp] * dp[3]) + + (vp[5 + dvp] * dp[4]) + + (vp[4 + dvp] * dp[5]) + + (vp[3 + dvp] * dp[6]) + + (vp[2 + dvp] * dp[7]) + + (vp[1 + dvp] * dp[8]) + + (vp[0 + dvp] * dp[9]) + + (vp[15 + dvp] * dp[10]) + + (vp[14 + dvp] * dp[11]) + + (vp[13 + dvp] * dp[12]) + + (vp[12 + dvp] * dp[13]) + + (vp[11 + dvp] * dp[14]) + + (vp[10 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples10(Obuffer buffer) { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = ((vp[10 + dvp] * dp[0]) + + (vp[9 + dvp] * dp[1]) + + (vp[8 + dvp] * dp[2]) + + (vp[7 + dvp] * dp[3]) + + (vp[6 + dvp] * dp[4]) + + (vp[5 + dvp] * dp[5]) + + (vp[4 + dvp] * dp[6]) + + (vp[3 + dvp] * dp[7]) + + (vp[2 + dvp] * dp[8]) + + (vp[1 + dvp] * dp[9]) + + (vp[0 + dvp] * dp[10]) + + (vp[15 + dvp] * dp[11]) + + (vp[14 + dvp] * dp[12]) + + (vp[13 + dvp] * dp[13]) + + (vp[12 + dvp] * dp[14]) + + (vp[11 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples11(Obuffer buffer) { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = ((vp[11 + dvp] * dp[0]) + + (vp[10 + dvp] * dp[1]) + + (vp[9 + dvp] * dp[2]) + + (vp[8 + dvp] * dp[3]) + + (vp[7 + dvp] * dp[4]) + + (vp[6 + dvp] * dp[5]) + + (vp[5 + dvp] * dp[6]) + + (vp[4 + dvp] * dp[7]) + + (vp[3 + dvp] * dp[8]) + + (vp[2 + dvp] * dp[9]) + + (vp[1 + dvp] * dp[10]) + + (vp[0 + dvp] * dp[11]) + + (vp[15 + dvp] * dp[12]) + + (vp[14 + dvp] * dp[13]) + + (vp[13 + dvp] * dp[14]) + + (vp[12 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples12(Obuffer buffer) { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = ((vp[12 + dvp] * dp[0]) + + (vp[11 + dvp] * dp[1]) + + (vp[10 + dvp] * dp[2]) + + (vp[9 + dvp] * dp[3]) + + (vp[8 + dvp] * dp[4]) + + (vp[7 + dvp] * dp[5]) + + (vp[6 + dvp] * dp[6]) + + (vp[5 + dvp] * dp[7]) + + (vp[4 + dvp] * dp[8]) + + (vp[3 + dvp] * dp[9]) + + (vp[2 + dvp] * dp[10]) + + (vp[1 + dvp] * dp[11]) + + (vp[0 + dvp] * dp[12]) + + (vp[15 + dvp] * dp[13]) + + (vp[14 + dvp] * dp[14]) + + (vp[13 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples13(Obuffer buffer) { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = ((vp[13 + dvp] * dp[0]) + + (vp[12 + dvp] * dp[1]) + + (vp[11 + dvp] * dp[2]) + + (vp[10 + dvp] * dp[3]) + + (vp[9 + dvp] * dp[4]) + + (vp[8 + dvp] * dp[5]) + + (vp[7 + dvp] * dp[6]) + + (vp[6 + dvp] * dp[7]) + + (vp[5 + dvp] * dp[8]) + + (vp[4 + dvp] * dp[9]) + + (vp[3 + dvp] * dp[10]) + + (vp[2 + dvp] * dp[11]) + + (vp[1 + dvp] * dp[12]) + + (vp[0 + dvp] * dp[13]) + + (vp[15 + dvp] * dp[14]) + + (vp[14 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples14(Obuffer buffer) { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = ((vp[14 + dvp] * dp[0]) + + (vp[13 + dvp] * dp[1]) + + (vp[12 + dvp] * dp[2]) + + (vp[11 + dvp] * dp[3]) + + (vp[10 + dvp] * dp[4]) + + (vp[9 + dvp] * dp[5]) + + (vp[8 + dvp] * dp[6]) + + (vp[7 + dvp] * dp[7]) + + (vp[6 + dvp] * dp[8]) + + (vp[5 + dvp] * dp[9]) + + (vp[4 + dvp] * dp[10]) + + (vp[3 + dvp] * dp[11]) + + (vp[2 + dvp] * dp[12]) + + (vp[1 + dvp] * dp[13]) + + (vp[0 + dvp] * dp[14]) + + (vp[15 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples15(Obuffer buffer) { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp = 0; + + // fat chance of having this loop unroll + for (int i = 0; i < 32; i++) { + float pcm_sample; + final float[] dp = d16[i]; + pcm_sample = ((vp[15 + dvp] * dp[0]) + + (vp[14 + dvp] * dp[1]) + + (vp[13 + dvp] * dp[2]) + + (vp[12 + dvp] * dp[3]) + + (vp[11 + dvp] * dp[4]) + + (vp[10 + dvp] * dp[5]) + + (vp[9 + dvp] * dp[6]) + + (vp[8 + dvp] * dp[7]) + + (vp[7 + dvp] * dp[8]) + + (vp[6 + dvp] * dp[9]) + + (vp[5 + dvp] * dp[10]) + + (vp[4 + dvp] * dp[11]) + + (vp[3 + dvp] * dp[12]) + + (vp[2 + dvp] * dp[13]) + + (vp[1 + dvp] * dp[14]) + + (vp[0 + dvp] * dp[15]) + ) * scalefactor; + + tmpOut[i] = pcm_sample; + dvp += 16; + } // for + } + + private void compute_pcm_samples(Obuffer buffer) { + + switch (actual_write_pos) { + case 0: + compute_pcm_samples0(buffer); + break; + case 1: + compute_pcm_samples1(buffer); + break; + case 2: + compute_pcm_samples2(buffer); + break; + case 3: + compute_pcm_samples3(buffer); + break; + case 4: + compute_pcm_samples4(buffer); + break; + case 5: + compute_pcm_samples5(buffer); + break; + case 6: + compute_pcm_samples6(buffer); + break; + case 7: + compute_pcm_samples7(buffer); + break; + case 8: + compute_pcm_samples8(buffer); + break; + case 9: + compute_pcm_samples9(buffer); + break; + case 10: + compute_pcm_samples10(buffer); + break; + case 11: + compute_pcm_samples11(buffer); + break; + case 12: + compute_pcm_samples12(buffer); + break; + case 13: + compute_pcm_samples13(buffer); + break; + case 14: + compute_pcm_samples14(buffer); + break; + case 15: + compute_pcm_samples15(buffer); + break; + } + + if (buffer != null) { + buffer.appendSamples(channel, _tmpOut); + } + + } + + /** + * Calculate 32 PCM samples and put the into the Obuffer-object. + */ + + public void calculate_pcm_samples(Obuffer buffer) { + compute_new_v(); + compute_pcm_samples(buffer); + + actual_write_pos = (actual_write_pos + 1) & 0xf; + actual_v = (actual_v == v1) ? v2 : v1; + + // initialize samples[]: + //for (register float *floatp = samples + 32; floatp > samples; ) + // *--floatp = 0.0f; + + // MDM: this may not be necessary. The Layer III decoder always + // outputs 32 subband samples, but I haven't checked layer I & II. + for (int p = 0; p < 32; p++) + samples[p] = 0.0f; + } + + + private static final double MY_PI = 3.14159265358979323846; + private static final float cos1_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI / 64.0))); + private static final float cos3_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 64.0))); + private static final float cos5_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 5.0 / 64.0))); + private static final float cos7_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 7.0 / 64.0))); + private static final float cos9_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 9.0 / 64.0))); + private static final float cos11_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 11.0 / 64.0))); + private static final float cos13_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 13.0 / 64.0))); + private static final float cos15_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 15.0 / 64.0))); + private static final float cos17_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 17.0 / 64.0))); + private static final float cos19_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 19.0 / 64.0))); + private static final float cos21_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 21.0 / 64.0))); + private static final float cos23_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 23.0 / 64.0))); + private static final float cos25_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 25.0 / 64.0))); + private static final float cos27_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 27.0 / 64.0))); + private static final float cos29_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 29.0 / 64.0))); + private static final float cos31_64 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 31.0 / 64.0))); + private static final float cos1_32 = (float) (1.0 / (2.0 * Math.cos(MY_PI / 32.0))); + private static final float cos3_32 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 32.0))); + private static final float cos5_32 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 5.0 / 32.0))); + private static final float cos7_32 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 7.0 / 32.0))); + private static final float cos9_32 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 9.0 / 32.0))); + private static final float cos11_32 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 11.0 / 32.0))); + private static final float cos13_32 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 13.0 / 32.0))); + private static final float cos15_32 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 15.0 / 32.0))); + private static final float cos1_16 = (float) (1.0 / (2.0 * Math.cos(MY_PI / 16.0))); + private static final float cos3_16 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 16.0))); + private static final float cos5_16 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 5.0 / 16.0))); + private static final float cos7_16 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 7.0 / 16.0))); + private static final float cos1_8 = (float) (1.0 / (2.0 * Math.cos(MY_PI / 8.0))); + private static final float cos3_8 = (float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 8.0))); + private static final float cos1_4 = (float) (1.0 / (2.0 * Math.cos(MY_PI / 4.0))); + + // Note: These values are not in the same order + // as in Annex 3-B.3 of the ISO/IEC DIS 11172-3 + // private float d[] = {0.000000000, -4.000442505}; + + private static float[] d = null; + + /** + * d[] split into subarrays of length 16. This provides for + * more faster access by allowing a block of 16 to be addressed + * with constant offset. + **/ + private static float[][] d16 = null; + + /** + * Loads the data for the d[] from the resource SFd.ser. + * + * @return the loaded values for d[]. + */ + static private float[] load_d() { + try { + Class elemType = Float.TYPE; + Object o = JavaLayerUtils.deserializeArrayResource("sfd.ser", elemType, 512); + return (float[]) o; + } catch (IOException ex) { + throw new ExceptionInInitializerError(ex); + } + } + + /** + * Converts a 1D array into a number of smaller arrays. This is used + * to achieve offset + constant indexing into an array. Each sub-array + * represents a block of values of the original array. + * + * @param array The array to split up into blocks. + * @param blockSize The size of the blocks to split the array + * into. This must be an exact divisor of + * the length of the array, or some data + * will be lost from the main array. + * @return An array of arrays in which each element in the returned + * array will be of length blockSize. + */ + static private float[][] splitArray(final float[] array, final int blockSize) { + int size = array.length / blockSize; + float[][] split = new float[size][]; + for (int i = 0; i < size; i++) { + split[i] = subArray(array, i * blockSize, blockSize); + } + return split; + } + + /** + * Returns a subarray of an existing array. + * + * @param array The array to retrieve a subarra from. + * @param offs The offset in the array that corresponds to + * the first index of the subarray. + * @param len The number of indeces in the subarray. + * @return The subarray, which may be of length 0. + */ + static private float[] subArray(final float[] array, final int offs, int len) { + if (offs + len > array.length) { + len = array.length - offs; + } + + if (len < 0) + len = 0; + + float[] subarray = new float[len]; + System.arraycopy(array, offs + 0, subarray, 0, len); + + return subarray; + } + + // The original data for d[]. This data is loaded from a file + // to reduce the overall package size and to improve performance. +/* + static final float d_data[] = { + 0.000000000f, -0.000442505f, 0.003250122f, -0.007003784f, + 0.031082153f, -0.078628540f, 0.100311279f, -0.572036743f, + 1.144989014f, 0.572036743f, 0.100311279f, 0.078628540f, + 0.031082153f, 0.007003784f, 0.003250122f, 0.000442505f, + -0.000015259f, -0.000473022f, 0.003326416f, -0.007919312f, + 0.030517578f, -0.084182739f, 0.090927124f, -0.600219727f, + 1.144287109f, 0.543823242f, 0.108856201f, 0.073059082f, + 0.031478882f, 0.006118774f, 0.003173828f, 0.000396729f, + -0.000015259f, -0.000534058f, 0.003387451f, -0.008865356f, + 0.029785156f, -0.089706421f, 0.080688477f, -0.628295898f, + 1.142211914f, 0.515609741f, 0.116577148f, 0.067520142f, + 0.031738281f, 0.005294800f, 0.003082275f, 0.000366211f, + -0.000015259f, -0.000579834f, 0.003433228f, -0.009841919f, + 0.028884888f, -0.095169067f, 0.069595337f, -0.656219482f, + 1.138763428f, 0.487472534f, 0.123474121f, 0.061996460f, + 0.031845093f, 0.004486084f, 0.002990723f, 0.000320435f, + -0.000015259f, -0.000625610f, 0.003463745f, -0.010848999f, + 0.027801514f, -0.100540161f, 0.057617188f, -0.683914185f, + 1.133926392f, 0.459472656f, 0.129577637f, 0.056533813f, + 0.031814575f, 0.003723145f, 0.002899170f, 0.000289917f, + -0.000015259f, -0.000686646f, 0.003479004f, -0.011886597f, + 0.026535034f, -0.105819702f, 0.044784546f, -0.711318970f, + 1.127746582f, 0.431655884f, 0.134887695f, 0.051132202f, + 0.031661987f, 0.003005981f, 0.002792358f, 0.000259399f, + -0.000015259f, -0.000747681f, 0.003479004f, -0.012939453f, + 0.025085449f, -0.110946655f, 0.031082153f, -0.738372803f, + 1.120223999f, 0.404083252f, 0.139450073f, 0.045837402f, + 0.031387329f, 0.002334595f, 0.002685547f, 0.000244141f, + -0.000030518f, -0.000808716f, 0.003463745f, -0.014022827f, + 0.023422241f, -0.115921021f, 0.016510010f, -0.765029907f, + 1.111373901f, 0.376800537f, 0.143264771f, 0.040634155f, + 0.031005859f, 0.001693726f, 0.002578735f, 0.000213623f, + -0.000030518f, -0.000885010f, 0.003417969f, -0.015121460f, + 0.021575928f, -0.120697021f, 0.001068115f, -0.791213989f, + 1.101211548f, 0.349868774f, 0.146362305f, 0.035552979f, + 0.030532837f, 0.001098633f, 0.002456665f, 0.000198364f, + -0.000030518f, -0.000961304f, 0.003372192f, -0.016235352f, + 0.019531250f, -0.125259399f, -0.015228271f, -0.816864014f, + 1.089782715f, 0.323318481f, 0.148773193f, 0.030609131f, + 0.029937744f, 0.000549316f, 0.002349854f, 0.000167847f, + -0.000030518f, -0.001037598f, 0.003280640f, -0.017349243f, + 0.017257690f, -0.129562378f, -0.032379150f, -0.841949463f, + 1.077117920f, 0.297210693f, 0.150497437f, 0.025817871f, + 0.029281616f, 0.000030518f, 0.002243042f, 0.000152588f, + -0.000045776f, -0.001113892f, 0.003173828f, -0.018463135f, + 0.014801025f, -0.133590698f, -0.050354004f, -0.866363525f, + 1.063217163f, 0.271591187f, 0.151596069f, 0.021179199f, + 0.028533936f, -0.000442505f, 0.002120972f, 0.000137329f, + -0.000045776f, -0.001205444f, 0.003051758f, -0.019577026f, + 0.012115479f, -0.137298584f, -0.069168091f, -0.890090942f, + 1.048156738f, 0.246505737f, 0.152069092f, 0.016708374f, + 0.027725220f, -0.000869751f, 0.002014160f, 0.000122070f, + -0.000061035f, -0.001296997f, 0.002883911f, -0.020690918f, + 0.009231567f, -0.140670776f, -0.088775635f, -0.913055420f, + 1.031936646f, 0.221984863f, 0.151962280f, 0.012420654f, + 0.026840210f, -0.001266479f, 0.001907349f, 0.000106812f, + -0.000061035f, -0.001388550f, 0.002700806f, -0.021789551f, + 0.006134033f, -0.143676758f, -0.109161377f, -0.935195923f, + 1.014617920f, 0.198059082f, 0.151306152f, 0.008316040f, + 0.025909424f, -0.001617432f, 0.001785278f, 0.000106812f, + -0.000076294f, -0.001480103f, 0.002487183f, -0.022857666f, + 0.002822876f, -0.146255493f, -0.130310059f, -0.956481934f, + 0.996246338f, 0.174789429f, 0.150115967f, 0.004394531f, + 0.024932861f, -0.001937866f, 0.001693726f, 0.000091553f, + -0.000076294f, -0.001586914f, 0.002227783f, -0.023910522f, + -0.000686646f, -0.148422241f, -0.152206421f, -0.976852417f, + 0.976852417f, 0.152206421f, 0.148422241f, 0.000686646f, + 0.023910522f, -0.002227783f, 0.001586914f, 0.000076294f, + -0.000091553f, -0.001693726f, 0.001937866f, -0.024932861f, + -0.004394531f, -0.150115967f, -0.174789429f, -0.996246338f, + 0.956481934f, 0.130310059f, 0.146255493f, -0.002822876f, + 0.022857666f, -0.002487183f, 0.001480103f, 0.000076294f, + -0.000106812f, -0.001785278f, 0.001617432f, -0.025909424f, + -0.008316040f, -0.151306152f, -0.198059082f, -1.014617920f, + 0.935195923f, 0.109161377f, 0.143676758f, -0.006134033f, + 0.021789551f, -0.002700806f, 0.001388550f, 0.000061035f, + -0.000106812f, -0.001907349f, 0.001266479f, -0.026840210f, + -0.012420654f, -0.151962280f, -0.221984863f, -1.031936646f, + 0.913055420f, 0.088775635f, 0.140670776f, -0.009231567f, + 0.020690918f, -0.002883911f, 0.001296997f, 0.000061035f, + -0.000122070f, -0.002014160f, 0.000869751f, -0.027725220f, + -0.016708374f, -0.152069092f, -0.246505737f, -1.048156738f, + 0.890090942f, 0.069168091f, 0.137298584f, -0.012115479f, + 0.019577026f, -0.003051758f, 0.001205444f, 0.000045776f, + -0.000137329f, -0.002120972f, 0.000442505f, -0.028533936f, + -0.021179199f, -0.151596069f, -0.271591187f, -1.063217163f, + 0.866363525f, 0.050354004f, 0.133590698f, -0.014801025f, + 0.018463135f, -0.003173828f, 0.001113892f, 0.000045776f, + -0.000152588f, -0.002243042f, -0.000030518f, -0.029281616f, + -0.025817871f, -0.150497437f, -0.297210693f, -1.077117920f, + 0.841949463f, 0.032379150f, 0.129562378f, -0.017257690f, + 0.017349243f, -0.003280640f, 0.001037598f, 0.000030518f, + -0.000167847f, -0.002349854f, -0.000549316f, -0.029937744f, + -0.030609131f, -0.148773193f, -0.323318481f, -1.089782715f, + 0.816864014f, 0.015228271f, 0.125259399f, -0.019531250f, + 0.016235352f, -0.003372192f, 0.000961304f, 0.000030518f, + -0.000198364f, -0.002456665f, -0.001098633f, -0.030532837f, + -0.035552979f, -0.146362305f, -0.349868774f, -1.101211548f, + 0.791213989f, -0.001068115f, 0.120697021f, -0.021575928f, + 0.015121460f, -0.003417969f, 0.000885010f, 0.000030518f, + -0.000213623f, -0.002578735f, -0.001693726f, -0.031005859f, + -0.040634155f, -0.143264771f, -0.376800537f, -1.111373901f, + 0.765029907f, -0.016510010f, 0.115921021f, -0.023422241f, + 0.014022827f, -0.003463745f, 0.000808716f, 0.000030518f, + -0.000244141f, -0.002685547f, -0.002334595f, -0.031387329f, + -0.045837402f, -0.139450073f, -0.404083252f, -1.120223999f, + 0.738372803f, -0.031082153f, 0.110946655f, -0.025085449f, + 0.012939453f, -0.003479004f, 0.000747681f, 0.000015259f, + -0.000259399f, -0.002792358f, -0.003005981f, -0.031661987f, + -0.051132202f, -0.134887695f, -0.431655884f, -1.127746582f, + 0.711318970f, -0.044784546f, 0.105819702f, -0.026535034f, + 0.011886597f, -0.003479004f, 0.000686646f, 0.000015259f, + -0.000289917f, -0.002899170f, -0.003723145f, -0.031814575f, + -0.056533813f, -0.129577637f, -0.459472656f, -1.133926392f, + 0.683914185f, -0.057617188f, 0.100540161f, -0.027801514f, + 0.010848999f, -0.003463745f, 0.000625610f, 0.000015259f, + -0.000320435f, -0.002990723f, -0.004486084f, -0.031845093f, + -0.061996460f, -0.123474121f, -0.487472534f, -1.138763428f, + 0.656219482f, -0.069595337f, 0.095169067f, -0.028884888f, + 0.009841919f, -0.003433228f, 0.000579834f, 0.000015259f, + -0.000366211f, -0.003082275f, -0.005294800f, -0.031738281f, + -0.067520142f, -0.116577148f, -0.515609741f, -1.142211914f, + 0.628295898f, -0.080688477f, 0.089706421f, -0.029785156f, + 0.008865356f, -0.003387451f, 0.000534058f, 0.000015259f, + -0.000396729f, -0.003173828f, -0.006118774f, -0.031478882f, + -0.073059082f, -0.108856201f, -0.543823242f, -1.144287109f, + 0.600219727f, -0.090927124f, 0.084182739f, -0.030517578f, + 0.007919312f, -0.003326416f, 0.000473022f, 0.000015259f + }; + */ +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/huffcodetab.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/huffcodetab.java new file mode 100644 index 000000000..2bf33066f --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/huffcodetab.java @@ -0,0 +1,582 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 16/11/99 Renamed class, added javadoc, and changed table + * name from String to 3 chars. mdm@techie.com + * 02/15/99 Java Conversion by E.B, javalayer@javazoom.net + * + * 04/19/97 : Adapted from the ISO MPEG Audio Subgroup Software Simulation + * Group's public c source for its MPEG audio decoder. Miscellaneous + * changes by Jeff Tsay (ctsay@pasteur.eecs.berkeley.edu). + *----------------------------------------------------------------------- + * Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reserved + * MPEG/audio coding/decoding software, work in progress + * NOT for public distribution until verified and approved by the + * MPEG/audio committee. For further information, please contact + * Davis Pan, 508-493-2241, e-mail: pan@3d.enet.dec.com + * + * VERSION 4.1 + * changes made since last update: + * date programmers comment + * 27.2.92 F.O.Witte (ITT Intermetall) + * 8/24/93 M. Iwadare Changed for 1 pass decoding. + * 7/14/94 J. Koller useless 'typedef' before huffcodetab removed + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Class to implements Huffman decoder. + */ +final class huffcodetab { + private static final int MXOFF = 250; + private static final int HTN = 34; + + /** string, containing table_description */ + private char tablename0 = ' '; + /** string, containing table_description */ + private char tablename1 = ' '; + /** string, containing table_description */ + @SuppressWarnings("unused") + private char tablename2 = ' '; + + /** max. x-index+ */ + private int xlen; + /** max. y-index+ */ + private int ylen; + /** number of linbits */ + private int linbits; + /** max number to be stored in linbits */ + @SuppressWarnings("unused") + private int linmax; + /** a positive value indicates a reference */ + @SuppressWarnings("unused") + private int ref; + /** pointer to array[xlen][ylen] */ + @SuppressWarnings("unused") + private int[] table = null; + /** pointer to array[xlen][ylen] */ + @SuppressWarnings("unused") + private int[] hlen = null; + /** decoder tree */ + private int[][] val = null; + /** length of decoder tree */ + private int treelen; + + private static final int[][] ValTab0 = { + {0, 0} // dummy + }; + + private static final int[][] ValTab1 = { + {2, 1}, {0, 0}, {2, 1}, {0, 16}, {2, 1}, {0, 1}, {0, 17}, + }; + + private static final int[][] ValTab2 = { + {2, 1}, {0, 0}, {4, 1}, {2, 1}, {0, 16}, {0, 1}, {2, 1}, {0, 17}, {4, 1}, {2, 1}, + {0, 32}, {0, 33}, {2, 1}, {0, 18}, {2, 1}, {0, 2}, {0, 34}, + }; + + private static final int[][] ValTab3 = { + {4, 1}, {2, 1}, {0, 0}, {0, 1}, {2, 1}, {0, 17}, {2, 1}, {0, 16}, {4, 1}, {2, 1}, + {0, 32}, {0, 33}, {2, 1}, {0, 18}, {2, 1}, {0, 2}, {0, 34}, + }; + + private static final int[][] ValTab4 = {{0, 0}}; // dummy + + private static final int[][] ValTab5 = { + {2, 1}, {0, 0}, {4, 1}, {2, 1}, {0, 16}, {0, 1}, {2, 1}, {0, 17}, {8, 1}, {4, 1}, + {2, 1}, {0, 32}, {0, 2}, {2, 1}, {0, 33}, {0, 18}, {8, 1}, {4, 1}, {2, 1}, {0, 34}, + {0, 48}, {2, 1}, {0, 3}, {0, 19}, {2, 1}, {0, 49}, {2, 1}, {0, 50}, {2, 1}, {0, 35}, + {0, 51}, + }; + + private static final int[][] ValTab6 = { + {6, 1}, {4, 1}, {2, 1}, {0, 0}, {0, 16}, {0, 17}, {6, 1}, {2, 1}, {0, 1}, {2, 1}, + {0, 32}, {0, 33}, {6, 1}, {2, 1}, {0, 18}, {2, 1}, {0, 2}, {0, 34}, {4, 1}, {2, 1}, + {0, 49}, {0, 19}, {4, 1}, {2, 1}, {0, 48}, {0, 50}, {2, 1}, {0, 35}, {2, 1}, {0, 3}, + {0, 51}, + }; + + private static final int[][] ValTab7 = { + {2, 1}, {0, 0}, {4, 1}, {2, 1}, {0, 16}, {0, 1}, {8, 1}, {2, 1}, {0, 17}, {4, 1}, + {2, 1}, {0, 32}, {0, 2}, {0, 33}, {18, 1}, {6, 1}, {2, 1}, {0, 18}, {2, 1}, {0, 34}, + {0, 48}, {4, 1}, {2, 1}, {0, 49}, {0, 19}, {4, 1}, {2, 1}, {0, 3}, {0, 50}, {2, 1}, + {0, 35}, {0, 4}, {10, 1}, {4, 1}, {2, 1}, {0, 64}, {0, 65}, {2, 1}, {0, 20}, {2, 1}, + {0, 66}, {0, 36}, {12, 1}, {6, 1}, {4, 1}, {2, 1}, {0, 51}, {0, 67}, {0, 80}, {4, 1}, + {2, 1}, {0, 52}, {0, 5}, {0, 81}, {6, 1}, {2, 1}, {0, 21}, {2, 1}, {0, 82}, {0, 37}, + {4, 1}, {2, 1}, {0, 68}, {0, 53}, {4, 1}, {2, 1}, {0, 83}, {0, 84}, {2, 1}, {0, 69}, + {0, 85}, + }; + + private static final int[][] ValTab8 = { + {6, 1}, {2, 1}, {0, 0}, {2, 1}, {0, 16}, {0, 1}, {2, 1}, {0, 17}, {4, 1}, {2, 1}, + {0, 33}, {0, 18}, {14, 1}, {4, 1}, {2, 1}, {0, 32}, {0, 2}, {2, 1}, {0, 34}, {4, 1}, + {2, 1}, {0, 48}, {0, 3}, {2, 1}, {0, 49}, {0, 19}, {14, 1}, {8, 1}, {4, 1}, {2, 1}, + {0, 50}, {0, 35}, {2, 1}, {0, 64}, {0, 4}, {2, 1}, {0, 65}, {2, 1}, {0, 20}, {0, 66}, + {12, 1}, {6, 1}, {2, 1}, {0, 36}, {2, 1}, {0, 51}, {0, 80}, {4, 1}, {2, 1}, {0, 67}, + {0, 52}, {0, 81}, {6, 1}, {2, 1}, {0, 21}, {2, 1}, {0, 5}, {0, 82}, {6, 1}, {2, 1}, + {0, 37}, {2, 1}, {0, 68}, {0, 53}, {2, 1}, {0, 83}, {2, 1}, {0, 69}, {2, 1}, {0, 84}, + {0, 85}, + }; + + private static final int[][] ValTab9 = { + {8, 1}, {4, 1}, {2, 1}, {0, 0}, {0, 16}, {2, 1}, {0, 1}, {0, 17}, {10, 1}, {4, 1}, + {2, 1}, {0, 32}, {0, 33}, {2, 1}, {0, 18}, {2, 1}, {0, 2}, {0, 34}, {12, 1}, {6, 1}, + {4, 1}, {2, 1}, {0, 48}, {0, 3}, {0, 49}, {2, 1}, {0, 19}, {2, 1}, {0, 50}, {0, 35}, + {12, 1}, {4, 1}, {2, 1}, {0, 65}, {0, 20}, {4, 1}, {2, 1}, {0, 64}, {0, 51}, {2, 1}, + {0, 66}, {0, 36}, {10, 1}, {6, 1}, {4, 1}, {2, 1}, {0, 4}, {0, 80}, {0, 67}, {2, 1}, + {0, 52}, {0, 81}, {8, 1}, {4, 1}, {2, 1}, {0, 21}, {0, 82}, {2, 1}, {0, 37}, {0, 68}, + {6, 1}, {4, 1}, {2, 1}, {0, 5}, {0, 84}, {0, 83}, {2, 1}, {0, 53}, {2, 1}, {0, 69}, + {0, 85}, + }; + + private static final int[][] ValTab10 = { + {2, 1}, {0, 0}, {4, 1}, {2, 1}, {0, 16}, {0, 1}, {10, 1}, {2, 1}, {0, 17}, {4, 1}, + {2, 1}, {0, 32}, {0, 2}, {2, 1}, {0, 33}, {0, 18}, {28, 1}, {8, 1}, {4, 1}, {2, 1}, + {0, 34}, {0, 48}, {2, 1}, {0, 49}, {0, 19}, {8, 1}, {4, 1}, {2, 1}, {0, 3}, {0, 50}, + {2, 1}, {0, 35}, {0, 64}, {4, 1}, {2, 1}, {0, 65}, {0, 20}, {4, 1}, {2, 1}, {0, 4}, + {0, 51}, {2, 1}, {0, 66}, {0, 36}, {28, 1}, {10, 1}, {6, 1}, {4, 1}, {2, 1}, {0, 80}, + {0, 5}, {0, 96}, {2, 1}, {0, 97}, {0, 22}, {12, 1}, {6, 1}, {4, 1}, {2, 1}, {0, 67}, + {0, 52}, {0, 81}, {2, 1}, {0, 21}, {2, 1}, {0, 82}, {0, 37}, {4, 1}, {2, 1}, {0, 38}, + {0, 54}, {0, 113}, {20, 1}, {8, 1}, {2, 1}, {0, 23}, {4, 1}, {2, 1}, {0, 68}, {0, 83}, + {0, 6}, {6, 1}, {4, 1}, {2, 1}, {0, 53}, {0, 69}, {0, 98}, {2, 1}, {0, 112}, {2, 1}, + {0, 7}, {0, 100}, {14, 1}, {4, 1}, {2, 1}, {0, 114}, {0, 39}, {6, 1}, {2, 1}, {0, 99}, + {2, 1}, {0, 84}, {0, 85}, {2, 1}, {0, 70}, {0, 115}, {8, 1}, {4, 1}, {2, 1}, {0, 55}, + {0, 101}, {2, 1}, {0, 86}, {0, 116}, {6, 1}, {2, 1}, {0, 71}, {2, 1}, {0, 102}, {0, 117}, + {4, 1}, {2, 1}, {0, 87}, {0, 118}, {2, 1}, {0, 103}, {0, 119}, + }; + + private static final int[][] ValTab11 = { + {6, 1}, {2, 1}, {0, 0}, {2, 1}, {0, 16}, {0, 1}, {8, 1}, {2, 1}, {0, 17}, {4, 1}, + {2, 1}, {0, 32}, {0, 2}, {0, 18}, {24, 1}, {8, 1}, {2, 1}, {0, 33}, {2, 1}, {0, 34}, + {2, 1}, {0, 48}, {0, 3}, {4, 1}, {2, 1}, {0, 49}, {0, 19}, {4, 1}, {2, 1}, {0, 50}, + {0, 35}, {4, 1}, {2, 1}, {0, 64}, {0, 4}, {2, 1}, {0, 65}, {0, 20}, {30, 1}, {16, 1}, + {10, 1}, {4, 1}, {2, 1}, {0, 66}, {0, 36}, {4, 1}, {2, 1}, {0, 51}, {0, 67}, {0, 80}, + {4, 1}, {2, 1}, {0, 52}, {0, 81}, {0, 97}, {6, 1}, {2, 1}, {0, 22}, {2, 1}, {0, 6}, + {0, 38}, {2, 1}, {0, 98}, {2, 1}, {0, 21}, {2, 1}, {0, 5}, {0, 82}, {16, 1}, {10, 1}, + {6, 1}, {4, 1}, {2, 1}, {0, 37}, {0, 68}, {0, 96}, {2, 1}, {0, 99}, {0, 54}, {4, 1}, + {2, 1}, {0, 112}, {0, 23}, {0, 113}, {16, 1}, {6, 1}, {4, 1}, {2, 1}, {0, 7}, {0, 100}, + {0, 114}, {2, 1}, {0, 39}, {4, 1}, {2, 1}, {0, 83}, {0, 53}, {2, 1}, {0, 84}, {0, 69}, + {10, 1}, {4, 1}, {2, 1}, {0, 70}, {0, 115}, {2, 1}, {0, 55}, {2, 1}, {0, 101}, {0, 86}, + {10, 1}, {6, 1}, {4, 1}, {2, 1}, {0, 85}, {0, 87}, {0, 116}, {2, 1}, {0, 71}, {0, 102}, + {4, 1}, {2, 1}, {0, 117}, {0, 118}, {2, 1}, {0, 103}, {0, 119}, + }; + + private static final int[][] ValTab12 = { + {12, 1}, {4, 1}, {2, 1}, {0, 16}, {0, 1}, {2, 1}, {0, 17}, {2, 1}, {0, 0}, {2, 1}, + {0, 32}, {0, 2}, {16, 1}, {4, 1}, {2, 1}, {0, 33}, {0, 18}, {4, 1}, {2, 1}, {0, 34}, + {0, 49}, {2, 1}, {0, 19}, {2, 1}, {0, 48}, {2, 1}, {0, 3}, {0, 64}, {26, 1}, {8, 1}, + {4, 1}, {2, 1}, {0, 50}, {0, 35}, {2, 1}, {0, 65}, {0, 51}, {10, 1}, {4, 1}, {2, 1}, + {0, 20}, {0, 66}, {2, 1}, {0, 36}, {2, 1}, {0, 4}, {0, 80}, {4, 1}, {2, 1}, {0, 67}, + {0, 52}, {2, 1}, {0, 81}, {0, 21}, {28, 1}, {14, 1}, {8, 1}, {4, 1}, {2, 1}, {0, 82}, + {0, 37}, {2, 1}, {0, 83}, {0, 53}, {4, 1}, {2, 1}, {0, 96}, {0, 22}, {0, 97}, {4, 1}, + {2, 1}, {0, 98}, {0, 38}, {6, 1}, {4, 1}, {2, 1}, {0, 5}, {0, 6}, {0, 68}, {2, 1}, + {0, 84}, {0, 69}, {18, 1}, {10, 1}, {4, 1}, {2, 1}, {0, 99}, {0, 54}, {4, 1}, {2, 1}, + {0, 112}, {0, 7}, {0, 113}, {4, 1}, {2, 1}, {0, 23}, {0, 100}, {2, 1}, {0, 70}, {0, 114}, + {10, 1}, {6, 1}, {2, 1}, {0, 39}, {2, 1}, {0, 85}, {0, 115}, {2, 1}, {0, 55}, {0, 86}, + {8, 1}, {4, 1}, {2, 1}, {0, 101}, {0, 116}, {2, 1}, {0, 71}, {0, 102}, {4, 1}, {2, 1}, + {0, 117}, {0, 87}, {2, 1}, {0, 118}, {2, 1}, {0, 103}, {0, 119}, + }; + + private static final int[][] ValTab13 = { + {2, 1}, {0, 0}, {6, 1}, {2, 1}, {0, 16}, {2, 1}, {0, 1}, {0, 17}, {28, 1}, {8, 1}, + {4, 1}, {2, 1}, {0, 32}, {0, 2}, {2, 1}, {0, 33}, {0, 18}, {8, 1}, {4, 1}, {2, 1}, + {0, 34}, {0, 48}, {2, 1}, {0, 3}, {0, 49}, {6, 1}, {2, 1}, {0, 19}, {2, 1}, {0, 50}, + {0, 35}, {4, 1}, {2, 1}, {0, 64}, {0, 4}, {0, 65}, {70, 1}, {28, 1}, {14, 1}, {6, 1}, + {2, 1}, {0, 20}, {2, 1}, {0, 51}, {0, 66}, {4, 1}, {2, 1}, {0, 36}, {0, 80}, {2, 1}, + {0, 67}, {0, 52}, {4, 1}, {2, 1}, {0, 81}, {0, 21}, {4, 1}, {2, 1}, {0, 5}, {0, 82}, + {2, 1}, {0, 37}, {2, 1}, {0, 68}, {0, 83}, {14, 1}, {8, 1}, {4, 1}, {2, 1}, {0, 96}, + {0, 6}, {2, 1}, {0, 97}, {0, 22}, {4, 1}, {2, 1}, {0, 128}, {0, 8}, {0, 129}, {16, 1}, + {8, 1}, {4, 1}, {2, 1}, {0, 53}, {0, 98}, {2, 1}, {0, 38}, {0, 84}, {4, 1}, {2, 1}, + {0, 69}, {0, 99}, {2, 1}, {0, 54}, {0, 112}, {6, 1}, {4, 1}, {2, 1}, {0, 7}, {0, 85}, + {0, 113}, {2, 1}, {0, 23}, {2, 1}, {0, 39}, {0, 55}, {72, 1}, {24, 1}, {12, 1}, {4, 1}, + {2, 1}, {0, 24}, {0, 130}, {2, 1}, {0, 40}, {4, 1}, {2, 1}, {0, 100}, {0, 70}, {0, 114}, + {8, 1}, {4, 1}, {2, 1}, {0, 132}, {0, 72}, {2, 1}, {0, 144}, {0, 9}, {2, 1}, {0, 145}, + {0, 25}, {24, 1}, {14, 1}, {8, 1}, {4, 1}, {2, 1}, {0, 115}, {0, 101}, {2, 1}, {0, 86}, + {0, 116}, {4, 1}, {2, 1}, {0, 71}, {0, 102}, {0, 131}, {6, 1}, {2, 1}, {0, 56}, {2, 1}, + {0, 117}, {0, 87}, {2, 1}, {0, 146}, {0, 41}, {14, 1}, {8, 1}, {4, 1}, {2, 1}, {0, 103}, + {0, 133}, {2, 1}, {0, 88}, {0, 57}, {2, 1}, {0, 147}, {2, 1}, {0, 73}, {0, 134}, {6, 1}, + {2, 1}, {0, 160}, {2, 1}, {0, 104}, {0, 10}, {2, 1}, {0, 161}, {0, 26}, {68, 1}, {24, 1}, + {12, 1}, {4, 1}, {2, 1}, {0, 162}, {0, 42}, {4, 1}, {2, 1}, {0, 149}, {0, 89}, {2, 1}, + {0, 163}, {0, 58}, {8, 1}, {4, 1}, {2, 1}, {0, 74}, {0, 150}, {2, 1}, {0, 176}, {0, 11}, + {2, 1}, {0, 177}, {0, 27}, {20, 1}, {8, 1}, {2, 1}, {0, 178}, {4, 1}, {2, 1}, {0, 118}, + {0, 119}, {0, 148}, {6, 1}, {4, 1}, {2, 1}, {0, 135}, {0, 120}, {0, 164}, {4, 1}, {2, 1}, + {0, 105}, {0, 165}, {0, 43}, {12, 1}, {6, 1}, {4, 1}, {2, 1}, {0, 90}, {0, 136}, {0, 179}, + {2, 1}, {0, 59}, {2, 1}, {0, 121}, {0, 166}, {6, 1}, {4, 1}, {2, 1}, {0, 106}, {0, 180}, + {0, 192}, {4, 1}, {2, 1}, {0, 12}, {0, 152}, {0, 193}, {60, 1}, {22, 1}, {10, 1}, {6, 1}, + {2, 1}, {0, 28}, {2, 1}, {0, 137}, {0, 181}, {2, 1}, {0, 91}, {0, 194}, {4, 1}, {2, 1}, + {0, 44}, {0, 60}, {4, 1}, {2, 1}, {0, 182}, {0, 107}, {2, 1}, {0, 196}, {0, 76}, {16, 1}, + {8, 1}, {4, 1}, {2, 1}, {0, 168}, {0, 138}, {2, 1}, {0, 208}, {0, 13}, {2, 1}, {0, 209}, + {2, 1}, {0, 75}, {2, 1}, {0, 151}, {0, 167}, {12, 1}, {6, 1}, {2, 1}, {0, 195}, {2, 1}, + {0, 122}, {0, 153}, {4, 1}, {2, 1}, {0, 197}, {0, 92}, {0, 183}, {4, 1}, {2, 1}, {0, 29}, + {0, 210}, {2, 1}, {0, 45}, {2, 1}, {0, 123}, {0, 211}, {52, 1}, {28, 1}, {12, 1}, {4, 1}, + {2, 1}, {0, 61}, {0, 198}, {4, 1}, {2, 1}, {0, 108}, {0, 169}, {2, 1}, {0, 154}, {0, 212}, + {8, 1}, {4, 1}, {2, 1}, {0, 184}, {0, 139}, {2, 1}, {0, 77}, {0, 199}, {4, 1}, {2, 1}, + {0, 124}, {0, 213}, {2, 1}, {0, 93}, {0, 224}, {10, 1}, {4, 1}, {2, 1}, {0, 225}, {0, 30}, + {4, 1}, {2, 1}, {0, 14}, {0, 46}, {0, 226}, {8, 1}, {4, 1}, {2, 1}, {0, 227}, {0, 109}, + {2, 1}, {0, 140}, {0, 228}, {4, 1}, {2, 1}, {0, 229}, {0, 186}, {0, 240}, {38, 1}, {16, 1}, + {4, 1}, {2, 1}, {0, 241}, {0, 31}, {6, 1}, {4, 1}, {2, 1}, {0, 170}, {0, 155}, {0, 185}, + {2, 1}, {0, 62}, {2, 1}, {0, 214}, {0, 200}, {12, 1}, {6, 1}, {2, 1}, {0, 78}, {2, 1}, + {0, 215}, {0, 125}, {2, 1}, {0, 171}, {2, 1}, {0, 94}, {0, 201}, {6, 1}, {2, 1}, {0, 15}, + {2, 1}, {0, 156}, {0, 110}, {2, 1}, {0, 242}, {0, 47}, {32, 1}, {16, 1}, {6, 1}, {4, 1}, + {2, 1}, {0, 216}, {0, 141}, {0, 63}, {6, 1}, {2, 1}, {0, 243}, {2, 1}, {0, 230}, {0, 202}, + {2, 1}, {0, 244}, {0, 79}, {8, 1}, {4, 1}, {2, 1}, {0, 187}, {0, 172}, {2, 1}, {0, 231}, + {0, 245}, {4, 1}, {2, 1}, {0, 217}, {0, 157}, {2, 1}, {0, 95}, {0, 232}, {30, 1}, {12, 1}, + {6, 1}, {2, 1}, {0, 111}, {2, 1}, {0, 246}, {0, 203}, {4, 1}, {2, 1}, {0, 188}, {0, 173}, + {0, 218}, {8, 1}, {2, 1}, {0, 247}, {4, 1}, {2, 1}, {0, 126}, {0, 127}, {0, 142}, {6, 1}, + {4, 1}, {2, 1}, {0, 158}, {0, 174}, {0, 204}, {2, 1}, {0, 248}, {0, 143}, {18, 1}, {8, 1}, + {4, 1}, {2, 1}, {0, 219}, {0, 189}, {2, 1}, {0, 234}, {0, 249}, {4, 1}, {2, 1}, {0, 159}, + {0, 235}, {2, 1}, {0, 190}, {2, 1}, {0, 205}, {0, 250}, {14, 1}, {4, 1}, {2, 1}, {0, 221}, + {0, 236}, {6, 1}, {4, 1}, {2, 1}, {0, 233}, {0, 175}, {0, 220}, {2, 1}, {0, 206}, {0, 251}, + {8, 1}, {4, 1}, {2, 1}, {0, 191}, {0, 222}, {2, 1}, {0, 207}, {0, 238}, {4, 1}, {2, 1}, + {0, 223}, {0, 239}, {2, 1}, {0, 255}, {2, 1}, {0, 237}, {2, 1}, {0, 253}, {2, 1}, {0, 252}, + {0, 254}, + }; + + private static final int[][] ValTab14 = { + {0, 0} // dummy + }; + + private static final int[][] ValTab15 = { + {16, 1}, {6, 1}, {2, 1}, {0, 0}, {2, 1}, {0, 16}, {0, 1}, {2, 1}, {0, 17}, {4, 1}, + {2, 1}, {0, 32}, {0, 2}, {2, 1}, {0, 33}, {0, 18}, {50, 1}, {16, 1}, {6, 1}, {2, 1}, + {0, 34}, {2, 1}, {0, 48}, {0, 49}, {6, 1}, {2, 1}, {0, 19}, {2, 1}, {0, 3}, {0, 64}, + {2, 1}, {0, 50}, {0, 35}, {14, 1}, {6, 1}, {4, 1}, {2, 1}, {0, 4}, {0, 20}, {0, 65}, + {4, 1}, {2, 1}, {0, 51}, {0, 66}, {2, 1}, {0, 36}, {0, 67}, {10, 1}, {6, 1}, {2, 1}, + {0, 52}, {2, 1}, {0, 80}, {0, 5}, {2, 1}, {0, 81}, {0, 21}, {4, 1}, {2, 1}, {0, 82}, + {0, 37}, {4, 1}, {2, 1}, {0, 68}, {0, 83}, {0, 97}, {90, 1}, {36, 1}, {18, 1}, {10, 1}, + {6, 1}, {2, 1}, {0, 53}, {2, 1}, {0, 96}, {0, 6}, {2, 1}, {0, 22}, {0, 98}, {4, 1}, + {2, 1}, {0, 38}, {0, 84}, {2, 1}, {0, 69}, {0, 99}, {10, 1}, {6, 1}, {2, 1}, {0, 54}, + {2, 1}, {0, 112}, {0, 7}, {2, 1}, {0, 113}, {0, 85}, {4, 1}, {2, 1}, {0, 23}, {0, 100}, + {2, 1}, {0, 114}, {0, 39}, {24, 1}, {16, 1}, {8, 1}, {4, 1}, {2, 1}, {0, 70}, {0, 115}, + {2, 1}, {0, 55}, {0, 101}, {4, 1}, {2, 1}, {0, 86}, {0, 128}, {2, 1}, {0, 8}, {0, 116}, + {4, 1}, {2, 1}, {0, 129}, {0, 24}, {2, 1}, {0, 130}, {0, 40}, {16, 1}, {8, 1}, {4, 1}, + {2, 1}, {0, 71}, {0, 102}, {2, 1}, {0, 131}, {0, 56}, {4, 1}, {2, 1}, {0, 117}, {0, 87}, + {2, 1}, {0, 132}, {0, 72}, {6, 1}, {4, 1}, {2, 1}, {0, 144}, {0, 25}, {0, 145}, {4, 1}, + {2, 1}, {0, 146}, {0, 118}, {2, 1}, {0, 103}, {0, 41}, {92, 1}, {36, 1}, {18, 1}, {10, 1}, + {4, 1}, {2, 1}, {0, 133}, {0, 88}, {4, 1}, {2, 1}, {0, 9}, {0, 119}, {0, 147}, {4, 1}, + {2, 1}, {0, 57}, {0, 148}, {2, 1}, {0, 73}, {0, 134}, {10, 1}, {6, 1}, {2, 1}, {0, 104}, + {2, 1}, {0, 160}, {0, 10}, {2, 1}, {0, 161}, {0, 26}, {4, 1}, {2, 1}, {0, 162}, {0, 42}, + {2, 1}, {0, 149}, {0, 89}, {26, 1}, {14, 1}, {6, 1}, {2, 1}, {0, 163}, {2, 1}, {0, 58}, + {0, 135}, {4, 1}, {2, 1}, {0, 120}, {0, 164}, {2, 1}, {0, 74}, {0, 150}, {6, 1}, {4, 1}, + {2, 1}, {0, 105}, {0, 176}, {0, 177}, {4, 1}, {2, 1}, {0, 27}, {0, 165}, {0, 178}, {14, 1}, + {8, 1}, {4, 1}, {2, 1}, {0, 90}, {0, 43}, {2, 1}, {0, 136}, {0, 151}, {2, 1}, {0, 179}, + {2, 1}, {0, 121}, {0, 59}, {8, 1}, {4, 1}, {2, 1}, {0, 106}, {0, 180}, {2, 1}, {0, 75}, + {0, 193}, {4, 1}, {2, 1}, {0, 152}, {0, 137}, {2, 1}, {0, 28}, {0, 181}, {80, 1}, {34, 1}, + {16, 1}, {6, 1}, {4, 1}, {2, 1}, {0, 91}, {0, 44}, {0, 194}, {6, 1}, {4, 1}, {2, 1}, + {0, 11}, {0, 192}, {0, 166}, {2, 1}, {0, 167}, {0, 122}, {10, 1}, {4, 1}, {2, 1}, {0, 195}, + {0, 60}, {4, 1}, {2, 1}, {0, 12}, {0, 153}, {0, 182}, {4, 1}, {2, 1}, {0, 107}, {0, 196}, + {2, 1}, {0, 76}, {0, 168}, {20, 1}, {10, 1}, {4, 1}, {2, 1}, {0, 138}, {0, 197}, {4, 1}, + {2, 1}, {0, 208}, {0, 92}, {0, 209}, {4, 1}, {2, 1}, {0, 183}, {0, 123}, {2, 1}, {0, 29}, + {2, 1}, {0, 13}, {0, 45}, {12, 1}, {4, 1}, {2, 1}, {0, 210}, {0, 211}, {4, 1}, {2, 1}, + {0, 61}, {0, 198}, {2, 1}, {0, 108}, {0, 169}, {6, 1}, {4, 1}, {2, 1}, {0, 154}, {0, 184}, + {0, 212}, {4, 1}, {2, 1}, {0, 139}, {0, 77}, {2, 1}, {0, 199}, {0, 124}, {68, 1}, {34, 1}, + {18, 1}, {10, 1}, {4, 1}, {2, 1}, {0, 213}, {0, 93}, {4, 1}, {2, 1}, {0, 224}, {0, 14}, + {0, 225}, {4, 1}, {2, 1}, {0, 30}, {0, 226}, {2, 1}, {0, 170}, {0, 46}, {8, 1}, {4, 1}, + {2, 1}, {0, 185}, {0, 155}, {2, 1}, {0, 227}, {0, 214}, {4, 1}, {2, 1}, {0, 109}, {0, 62}, + {2, 1}, {0, 200}, {0, 140}, {16, 1}, {8, 1}, {4, 1}, {2, 1}, {0, 228}, {0, 78}, {2, 1}, + {0, 215}, {0, 125}, {4, 1}, {2, 1}, {0, 229}, {0, 186}, {2, 1}, {0, 171}, {0, 94}, {8, 1}, + {4, 1}, {2, 1}, {0, 201}, {0, 156}, {2, 1}, {0, 241}, {0, 31}, {6, 1}, {4, 1}, {2, 1}, + {0, 240}, {0, 110}, {0, 242}, {2, 1}, {0, 47}, {0, 230}, {38, 1}, {18, 1}, {8, 1}, {4, 1}, + {2, 1}, {0, 216}, {0, 243}, {2, 1}, {0, 63}, {0, 244}, {6, 1}, {2, 1}, {0, 79}, {2, 1}, + {0, 141}, {0, 217}, {2, 1}, {0, 187}, {0, 202}, {8, 1}, {4, 1}, {2, 1}, {0, 172}, {0, 231}, + {2, 1}, {0, 126}, {0, 245}, {8, 1}, {4, 1}, {2, 1}, {0, 157}, {0, 95}, {2, 1}, {0, 232}, + {0, 142}, {2, 1}, {0, 246}, {0, 203}, {34, 1}, {18, 1}, {10, 1}, {6, 1}, {4, 1}, {2, 1}, + {0, 15}, {0, 174}, {0, 111}, {2, 1}, {0, 188}, {0, 218}, {4, 1}, {2, 1}, {0, 173}, {0, 247}, + {2, 1}, {0, 127}, {0, 233}, {8, 1}, {4, 1}, {2, 1}, {0, 158}, {0, 204}, {2, 1}, {0, 248}, + {0, 143}, {4, 1}, {2, 1}, {0, 219}, {0, 189}, {2, 1}, {0, 234}, {0, 249}, {16, 1}, {8, 1}, + {4, 1}, {2, 1}, {0, 159}, {0, 220}, {2, 1}, {0, 205}, {0, 235}, {4, 1}, {2, 1}, {0, 190}, + {0, 250}, {2, 1}, {0, 175}, {0, 221}, {14, 1}, {6, 1}, {4, 1}, {2, 1}, {0, 236}, {0, 206}, + {0, 251}, {4, 1}, {2, 1}, {0, 191}, {0, 237}, {2, 1}, {0, 222}, {0, 252}, {6, 1}, {4, 1}, + {2, 1}, {0, 207}, {0, 253}, {0, 238}, {4, 1}, {2, 1}, {0, 223}, {0, 254}, {2, 1}, {0, 239}, + {0, 255}, + }; + + private static final int[][] ValTab16 = { + {2, 1}, {0, 0}, {6, 1}, {2, 1}, {0, 16}, {2, 1}, {0, 1}, {0, 17}, {42, 1}, {8, 1}, + {4, 1}, {2, 1}, {0, 32}, {0, 2}, {2, 1}, {0, 33}, {0, 18}, {10, 1}, {6, 1}, {2, 1}, + {0, 34}, {2, 1}, {0, 48}, {0, 3}, {2, 1}, {0, 49}, {0, 19}, {10, 1}, {4, 1}, {2, 1}, + {0, 50}, {0, 35}, {4, 1}, {2, 1}, {0, 64}, {0, 4}, {0, 65}, {6, 1}, {2, 1}, {0, 20}, + {2, 1}, {0, 51}, {0, 66}, {4, 1}, {2, 1}, {0, 36}, {0, 80}, {2, 1}, {0, 67}, {0, 52}, + {138, 1}, {40, 1}, {16, 1}, {6, 1}, {4, 1}, {2, 1}, {0, 5}, {0, 21}, {0, 81}, {4, 1}, + {2, 1}, {0, 82}, {0, 37}, {4, 1}, {2, 1}, {0, 68}, {0, 53}, {0, 83}, {10, 1}, {6, 1}, + {4, 1}, {2, 1}, {0, 96}, {0, 6}, {0, 97}, {2, 1}, {0, 22}, {0, 98}, {8, 1}, {4, 1}, + {2, 1}, {0, 38}, {0, 84}, {2, 1}, {0, 69}, {0, 99}, {4, 1}, {2, 1}, {0, 54}, {0, 112}, + {0, 113}, {40, 1}, {18, 1}, {8, 1}, {2, 1}, {0, 23}, {2, 1}, {0, 7}, {2, 1}, {0, 85}, + {0, 100}, {4, 1}, {2, 1}, {0, 114}, {0, 39}, {4, 1}, {2, 1}, {0, 70}, {0, 101}, {0, 115}, + {10, 1}, {6, 1}, {2, 1}, {0, 55}, {2, 1}, {0, 86}, {0, 8}, {2, 1}, {0, 128}, {0, 129}, + {6, 1}, {2, 1}, {0, 24}, {2, 1}, {0, 116}, {0, 71}, {2, 1}, {0, 130}, {2, 1}, {0, 40}, + {0, 102}, {24, 1}, {14, 1}, {8, 1}, {4, 1}, {2, 1}, {0, 131}, {0, 56}, {2, 1}, {0, 117}, + {0, 132}, {4, 1}, {2, 1}, {0, 72}, {0, 144}, {0, 145}, {6, 1}, {2, 1}, {0, 25}, {2, 1}, + {0, 9}, {0, 118}, {2, 1}, {0, 146}, {0, 41}, {14, 1}, {8, 1}, {4, 1}, {2, 1}, {0, 133}, + {0, 88}, {2, 1}, {0, 147}, {0, 57}, {4, 1}, {2, 1}, {0, 160}, {0, 10}, {0, 26}, {8, 1}, + {2, 1}, {0, 162}, {2, 1}, {0, 103}, {2, 1}, {0, 87}, {0, 73}, {6, 1}, {2, 1}, {0, 148}, + {2, 1}, {0, 119}, {0, 134}, {2, 1}, {0, 161}, {2, 1}, {0, 104}, {0, 149}, {220, 1}, {126, 1}, + {50, 1}, {26, 1}, {12, 1}, {6, 1}, {2, 1}, {0, 42}, {2, 1}, {0, 89}, {0, 58}, {2, 1}, + {0, 163}, {2, 1}, {0, 135}, {0, 120}, {8, 1}, {4, 1}, {2, 1}, {0, 164}, {0, 74}, {2, 1}, + {0, 150}, {0, 105}, {4, 1}, {2, 1}, {0, 176}, {0, 11}, {0, 177}, {10, 1}, {4, 1}, {2, 1}, + {0, 27}, {0, 178}, {2, 1}, {0, 43}, {2, 1}, {0, 165}, {0, 90}, {6, 1}, {2, 1}, {0, 179}, + {2, 1}, {0, 166}, {0, 106}, {4, 1}, {2, 1}, {0, 180}, {0, 75}, {2, 1}, {0, 12}, {0, 193}, + {30, 1}, {14, 1}, {6, 1}, {4, 1}, {2, 1}, {0, 181}, {0, 194}, {0, 44}, {4, 1}, {2, 1}, + {0, 167}, {0, 195}, {2, 1}, {0, 107}, {0, 196}, {8, 1}, {2, 1}, {0, 29}, {4, 1}, {2, 1}, + {0, 136}, {0, 151}, {0, 59}, {4, 1}, {2, 1}, {0, 209}, {0, 210}, {2, 1}, {0, 45}, {0, 211}, + {18, 1}, {6, 1}, {4, 1}, {2, 1}, {0, 30}, {0, 46}, {0, 226}, {6, 1}, {4, 1}, {2, 1}, + {0, 121}, {0, 152}, {0, 192}, {2, 1}, {0, 28}, {2, 1}, {0, 137}, {0, 91}, {14, 1}, {6, 1}, + {2, 1}, {0, 60}, {2, 1}, {0, 122}, {0, 182}, {4, 1}, {2, 1}, {0, 76}, {0, 153}, {2, 1}, + {0, 168}, {0, 138}, {6, 1}, {2, 1}, {0, 13}, {2, 1}, {0, 197}, {0, 92}, {4, 1}, {2, 1}, + {0, 61}, {0, 198}, {2, 1}, {0, 108}, {0, 154}, {88, 1}, {86, 1}, {36, 1}, {16, 1}, {8, 1}, + {4, 1}, {2, 1}, {0, 139}, {0, 77}, {2, 1}, {0, 199}, {0, 124}, {4, 1}, {2, 1}, {0, 213}, + {0, 93}, {2, 1}, {0, 224}, {0, 14}, {8, 1}, {2, 1}, {0, 227}, {4, 1}, {2, 1}, {0, 208}, + {0, 183}, {0, 123}, {6, 1}, {4, 1}, {2, 1}, {0, 169}, {0, 184}, {0, 212}, {2, 1}, {0, 225}, + {2, 1}, {0, 170}, {0, 185}, {24, 1}, {10, 1}, {6, 1}, {4, 1}, {2, 1}, {0, 155}, {0, 214}, + {0, 109}, {2, 1}, {0, 62}, {0, 200}, {6, 1}, {4, 1}, {2, 1}, {0, 140}, {0, 228}, {0, 78}, + {4, 1}, {2, 1}, {0, 215}, {0, 229}, {2, 1}, {0, 186}, {0, 171}, {12, 1}, {4, 1}, {2, 1}, + {0, 156}, {0, 230}, {4, 1}, {2, 1}, {0, 110}, {0, 216}, {2, 1}, {0, 141}, {0, 187}, {8, 1}, + {4, 1}, {2, 1}, {0, 231}, {0, 157}, {2, 1}, {0, 232}, {0, 142}, {4, 1}, {2, 1}, {0, 203}, + {0, 188}, {0, 158}, {0, 241}, {2, 1}, {0, 31}, {2, 1}, {0, 15}, {0, 47}, {66, 1}, {56, 1}, + {2, 1}, {0, 242}, {52, 1}, {50, 1}, {20, 1}, {8, 1}, {2, 1}, {0, 189}, {2, 1}, {0, 94}, + {2, 1}, {0, 125}, {0, 201}, {6, 1}, {2, 1}, {0, 202}, {2, 1}, {0, 172}, {0, 126}, {4, 1}, + {2, 1}, {0, 218}, {0, 173}, {0, 204}, {10, 1}, {6, 1}, {2, 1}, {0, 174}, {2, 1}, {0, 219}, + {0, 220}, {2, 1}, {0, 205}, {0, 190}, {6, 1}, {4, 1}, {2, 1}, {0, 235}, {0, 237}, {0, 238}, + {6, 1}, {4, 1}, {2, 1}, {0, 217}, {0, 234}, {0, 233}, {2, 1}, {0, 222}, {4, 1}, {2, 1}, + {0, 221}, {0, 236}, {0, 206}, {0, 63}, {0, 240}, {4, 1}, {2, 1}, {0, 243}, {0, 244}, {2, 1}, + {0, 79}, {2, 1}, {0, 245}, {0, 95}, {10, 1}, {2, 1}, {0, 255}, {4, 1}, {2, 1}, {0, 246}, + {0, 111}, {2, 1}, {0, 247}, {0, 127}, {12, 1}, {6, 1}, {2, 1}, {0, 143}, {2, 1}, {0, 248}, + {0, 249}, {4, 1}, {2, 1}, {0, 159}, {0, 250}, {0, 175}, {8, 1}, {4, 1}, {2, 1}, {0, 251}, + {0, 191}, {2, 1}, {0, 252}, {0, 207}, {4, 1}, {2, 1}, {0, 253}, {0, 223}, {2, 1}, {0, 254}, + {0, 239}, + }; + + private static final int[][] ValTab24 = { + {60, 1}, {8, 1}, {4, 1}, {2, 1}, {0, 0}, {0, 16}, {2, 1}, {0, 1}, {0, 17}, {14, 1}, + {6, 1}, {4, 1}, {2, 1}, {0, 32}, {0, 2}, {0, 33}, {2, 1}, {0, 18}, {2, 1}, {0, 34}, + {2, 1}, {0, 48}, {0, 3}, {14, 1}, {4, 1}, {2, 1}, {0, 49}, {0, 19}, {4, 1}, {2, 1}, + {0, 50}, {0, 35}, {4, 1}, {2, 1}, {0, 64}, {0, 4}, {0, 65}, {8, 1}, {4, 1}, {2, 1}, + {0, 20}, {0, 51}, {2, 1}, {0, 66}, {0, 36}, {6, 1}, {4, 1}, {2, 1}, {0, 67}, {0, 52}, + {0, 81}, {6, 1}, {4, 1}, {2, 1}, {0, 80}, {0, 5}, {0, 21}, {2, 1}, {0, 82}, {0, 37}, + {250, 1}, {98, 1}, {34, 1}, {18, 1}, {10, 1}, {4, 1}, {2, 1}, {0, 68}, {0, 83}, {2, 1}, + {0, 53}, {2, 1}, {0, 96}, {0, 6}, {4, 1}, {2, 1}, {0, 97}, {0, 22}, {2, 1}, {0, 98}, + {0, 38}, {8, 1}, {4, 1}, {2, 1}, {0, 84}, {0, 69}, {2, 1}, {0, 99}, {0, 54}, {4, 1}, + {2, 1}, {0, 113}, {0, 85}, {2, 1}, {0, 100}, {0, 70}, {32, 1}, {14, 1}, {6, 1}, {2, 1}, + {0, 114}, {2, 1}, {0, 39}, {0, 55}, {2, 1}, {0, 115}, {4, 1}, {2, 1}, {0, 112}, {0, 7}, + {0, 23}, {10, 1}, {4, 1}, {2, 1}, {0, 101}, {0, 86}, {4, 1}, {2, 1}, {0, 128}, {0, 8}, + {0, 129}, {4, 1}, {2, 1}, {0, 116}, {0, 71}, {2, 1}, {0, 24}, {0, 130}, {16, 1}, {8, 1}, + {4, 1}, {2, 1}, {0, 40}, {0, 102}, {2, 1}, {0, 131}, {0, 56}, {4, 1}, {2, 1}, {0, 117}, + {0, 87}, {2, 1}, {0, 132}, {0, 72}, {8, 1}, {4, 1}, {2, 1}, {0, 145}, {0, 25}, {2, 1}, + {0, 146}, {0, 118}, {4, 1}, {2, 1}, {0, 103}, {0, 41}, {2, 1}, {0, 133}, {0, 88}, {92, 1}, + {34, 1}, {16, 1}, {8, 1}, {4, 1}, {2, 1}, {0, 147}, {0, 57}, {2, 1}, {0, 148}, {0, 73}, + {4, 1}, {2, 1}, {0, 119}, {0, 134}, {2, 1}, {0, 104}, {0, 161}, {8, 1}, {4, 1}, {2, 1}, + {0, 162}, {0, 42}, {2, 1}, {0, 149}, {0, 89}, {4, 1}, {2, 1}, {0, 163}, {0, 58}, {2, 1}, + {0, 135}, {2, 1}, {0, 120}, {0, 74}, {22, 1}, {12, 1}, {4, 1}, {2, 1}, {0, 164}, {0, 150}, + {4, 1}, {2, 1}, {0, 105}, {0, 177}, {2, 1}, {0, 27}, {0, 165}, {6, 1}, {2, 1}, {0, 178}, + {2, 1}, {0, 90}, {0, 43}, {2, 1}, {0, 136}, {0, 179}, {16, 1}, {10, 1}, {6, 1}, {2, 1}, + {0, 144}, {2, 1}, {0, 9}, {0, 160}, {2, 1}, {0, 151}, {0, 121}, {4, 1}, {2, 1}, {0, 166}, + {0, 106}, {0, 180}, {12, 1}, {6, 1}, {2, 1}, {0, 26}, {2, 1}, {0, 10}, {0, 176}, {2, 1}, + {0, 59}, {2, 1}, {0, 11}, {0, 192}, {4, 1}, {2, 1}, {0, 75}, {0, 193}, {2, 1}, {0, 152}, + {0, 137}, {67, 1}, {34, 1}, {16, 1}, {8, 1}, {4, 1}, {2, 1}, {0, 28}, {0, 181}, {2, 1}, + {0, 91}, {0, 194}, {4, 1}, {2, 1}, {0, 44}, {0, 167}, {2, 1}, {0, 122}, {0, 195}, {10, 1}, + {6, 1}, {2, 1}, {0, 60}, {2, 1}, {0, 12}, {0, 208}, {2, 1}, {0, 182}, {0, 107}, {4, 1}, + {2, 1}, {0, 196}, {0, 76}, {2, 1}, {0, 153}, {0, 168}, {16, 1}, {8, 1}, {4, 1}, {2, 1}, + {0, 138}, {0, 197}, {2, 1}, {0, 92}, {0, 209}, {4, 1}, {2, 1}, {0, 183}, {0, 123}, {2, 1}, + {0, 29}, {0, 210}, {9, 1}, {4, 1}, {2, 1}, {0, 45}, {0, 211}, {2, 1}, {0, 61}, {0, 198}, + {85, 250}, {4, 1}, {2, 1}, {0, 108}, {0, 169}, {2, 1}, {0, 154}, {0, 212}, {32, 1}, {16, 1}, + {8, 1}, {4, 1}, {2, 1}, {0, 184}, {0, 139}, {2, 1}, {0, 77}, {0, 199}, {4, 1}, {2, 1}, + {0, 124}, {0, 213}, {2, 1}, {0, 93}, {0, 225}, {8, 1}, {4, 1}, {2, 1}, {0, 30}, {0, 226}, + {2, 1}, {0, 170}, {0, 185}, {4, 1}, {2, 1}, {0, 155}, {0, 227}, {2, 1}, {0, 214}, {0, 109}, + {20, 1}, {10, 1}, {6, 1}, {2, 1}, {0, 62}, {2, 1}, {0, 46}, {0, 78}, {2, 1}, {0, 200}, + {0, 140}, {4, 1}, {2, 1}, {0, 228}, {0, 215}, {4, 1}, {2, 1}, {0, 125}, {0, 171}, {0, 229}, + {10, 1}, {4, 1}, {2, 1}, {0, 186}, {0, 94}, {2, 1}, {0, 201}, {2, 1}, {0, 156}, {0, 110}, + {8, 1}, {2, 1}, {0, 230}, {2, 1}, {0, 13}, {2, 1}, {0, 224}, {0, 14}, {4, 1}, {2, 1}, + {0, 216}, {0, 141}, {2, 1}, {0, 187}, {0, 202}, {74, 1}, {2, 1}, {0, 255}, {64, 1}, {58, 1}, + {32, 1}, {16, 1}, {8, 1}, {4, 1}, {2, 1}, {0, 172}, {0, 231}, {2, 1}, {0, 126}, {0, 217}, + {4, 1}, {2, 1}, {0, 157}, {0, 232}, {2, 1}, {0, 142}, {0, 203}, {8, 1}, {4, 1}, {2, 1}, + {0, 188}, {0, 218}, {2, 1}, {0, 173}, {0, 233}, {4, 1}, {2, 1}, {0, 158}, {0, 204}, {2, 1}, + {0, 219}, {0, 189}, {16, 1}, {8, 1}, {4, 1}, {2, 1}, {0, 234}, {0, 174}, {2, 1}, {0, 220}, + {0, 205}, {4, 1}, {2, 1}, {0, 235}, {0, 190}, {2, 1}, {0, 221}, {0, 236}, {8, 1}, {4, 1}, + {2, 1}, {0, 206}, {0, 237}, {2, 1}, {0, 222}, {0, 238}, {0, 15}, {4, 1}, {2, 1}, {0, 240}, + {0, 31}, {0, 241}, {4, 1}, {2, 1}, {0, 242}, {0, 47}, {2, 1}, {0, 243}, {0, 63}, {18, 1}, + {8, 1}, {4, 1}, {2, 1}, {0, 244}, {0, 79}, {2, 1}, {0, 245}, {0, 95}, {4, 1}, {2, 1}, + {0, 246}, {0, 111}, {2, 1}, {0, 247}, {2, 1}, {0, 127}, {0, 143}, {10, 1}, {4, 1}, {2, 1}, + {0, 248}, {0, 249}, {4, 1}, {2, 1}, {0, 159}, {0, 175}, {0, 250}, {8, 1}, {4, 1}, {2, 1}, + {0, 251}, {0, 191}, {2, 1}, {0, 252}, {0, 207}, {4, 1}, {2, 1}, {0, 253}, {0, 223}, {2, 1}, + {0, 254}, {0, 239}, + }; + + private static final int[][] ValTab32 = { + {2, 1}, {0, 0}, {8, 1}, {4, 1}, {2, 1}, {0, 8}, {0, 4}, {2, 1}, {0, 1}, {0, 2}, + {8, 1}, {4, 1}, {2, 1}, {0, 12}, {0, 10}, {2, 1}, {0, 3}, {0, 6}, {6, 1}, {2, 1}, + {0, 9}, {2, 1}, {0, 5}, {0, 7}, {4, 1}, {2, 1}, {0, 14}, {0, 13}, {2, 1}, {0, 15}, + {0, 11}, + }; + + private static final int[][] ValTab33 = { + {16, 1}, {8, 1}, {4, 1}, {2, 1}, {0, 0}, {0, 1}, {2, 1}, {0, 2}, {0, 3}, {4, 1}, + {2, 1}, {0, 4}, {0, 5}, {2, 1}, {0, 6}, {0, 7}, {8, 1}, {4, 1}, {2, 1}, {0, 8}, + {0, 9}, {2, 1}, {0, 10}, {0, 11}, {4, 1}, {2, 1}, {0, 12}, {0, 13}, {2, 1}, {0, 14}, + {0, 15}, + }; + + /** Simulate extern struct */ + public static huffcodetab[] ht = null; + + @SuppressWarnings("unused") + private static int[] bitbuf = new int[32]; + + /** + * Big Constructor : Computes all Huffman Tables. + */ + private huffcodetab(String S, int XLEN, int YLEN, int LINBITS, int LINMAX, int REF, + int[] TABLE, int[] HLEN, int[][] VAL, int TREELEN) { + tablename0 = S.charAt(0); + tablename1 = S.charAt(1); + tablename2 = S.charAt(2); + xlen = XLEN; + ylen = YLEN; + linbits = LINBITS; + linmax = LINMAX; + ref = REF; + table = TABLE; + hlen = HLEN; + val = VAL; + treelen = TREELEN; + } + + /** + * Do the huffman-decoding. + * note! for counta,countb -the 4 bit value is returned in y, + * discard x. + */ + public static int huffman_decoder(huffcodetab h, int[] x, int[] y, int[] v, int[] w, BitReserve br) { + // array of all huffcodtable headers + // 0..31 Huffman code table 0..31 + // 32,33 count1-tables + + int dmask = 1 << ((4 * 8) - 1); + @SuppressWarnings("unused") + int hs = 4 * 8; + int level; + int point = 0; + int error = 1; + level = dmask; + + if (h.val == null) return 2; + + // table 0 needs no bits + if (h.treelen == 0) { + x[0] = y[0] = 0; + return 0; + } + + // Lookup in Huffman table. + + do { + if (h.val[point][0] == 0) { // end of tree + x[0] = h.val[point][1] >>> 4; + y[0] = h.val[point][1] & 0xf; + error = 0; + break; + } + + if (br.hget1bit() != 0) { + while (h.val[point][1] >= MXOFF) point += h.val[point][1]; + point += h.val[point][1]; + } else { + while (h.val[point][0] >= MXOFF) point += h.val[point][0]; + point += h.val[point][0]; + } + level >>>= 1; + // MDM: ht[0] is always 0; + } while ((level != 0) || (point < 0)); + + // Process sign encodings for quadruples tables. + if (h.tablename0 == '3' && (h.tablename1 == '2' || h.tablename1 == '3')) { + v[0] = (y[0] >> 3) & 1; + w[0] = (y[0] >> 2) & 1; + x[0] = (y[0] >> 1) & 1; + y[0] = y[0] & 1; + + // v, w, x and y are reversed in the bitstream. + // switch them around to make test bistream work. + + if (v[0] != 0) + if (br.hget1bit() != 0) v[0] = -v[0]; + if (w[0] != 0) + if (br.hget1bit() != 0) w[0] = -w[0]; + if (x[0] != 0) + if (br.hget1bit() != 0) x[0] = -x[0]; + if (y[0] != 0) + if (br.hget1bit() != 0) y[0] = -y[0]; + } else { + // Process sign and escape encodings for dual tables. + // x and y are reversed in the test bitstream. + // Reverse x and y here to make test bitstream work. + + if (h.linbits != 0) + if ((h.xlen - 1) == x[0]) + x[0] += br.hgetbits(h.linbits); + if (x[0] != 0) + if (br.hget1bit() != 0) x[0] = -x[0]; + if (h.linbits != 0) + if ((h.ylen - 1) == y[0]) + y[0] += br.hgetbits(h.linbits); + if (y[0] != 0) + if (br.hget1bit() != 0) y[0] = -y[0]; + } + return error; + } + + public static void initHuff() { + if (ht != null) + return; + + ht = new huffcodetab[HTN]; + ht[0] = new huffcodetab("0 ", 0, 0, 0, 0, -1, null, null, ValTab0, 0); + ht[1] = new huffcodetab("1 ", 2, 2, 0, 0, -1, null, null, ValTab1, 7); + ht[2] = new huffcodetab("2 ", 3, 3, 0, 0, -1, null, null, ValTab2, 17); + ht[3] = new huffcodetab("3 ", 3, 3, 0, 0, -1, null, null, ValTab3, 17); + ht[4] = new huffcodetab("4 ", 0, 0, 0, 0, -1, null, null, ValTab4, 0); + ht[5] = new huffcodetab("5 ", 4, 4, 0, 0, -1, null, null, ValTab5, 31); + ht[6] = new huffcodetab("6 ", 4, 4, 0, 0, -1, null, null, ValTab6, 31); + ht[7] = new huffcodetab("7 ", 6, 6, 0, 0, -1, null, null, ValTab7, 71); + ht[8] = new huffcodetab("8 ", 6, 6, 0, 0, -1, null, null, ValTab8, 71); + ht[9] = new huffcodetab("9 ", 6, 6, 0, 0, -1, null, null, ValTab9, 71); + ht[10] = new huffcodetab("10 ", 8, 8, 0, 0, -1, null, null, ValTab10, 127); + ht[11] = new huffcodetab("11 ", 8, 8, 0, 0, -1, null, null, ValTab11, 127); + ht[12] = new huffcodetab("12 ", 8, 8, 0, 0, -1, null, null, ValTab12, 127); + ht[13] = new huffcodetab("13 ", 16, 16, 0, 0, -1, null, null, ValTab13, 511); + ht[14] = new huffcodetab("14 ", 0, 0, 0, 0, -1, null, null, ValTab14, 0); + ht[15] = new huffcodetab("15 ", 16, 16, 0, 0, -1, null, null, ValTab15, 511); + ht[16] = new huffcodetab("16 ", 16, 16, 1, 1, -1, null, null, ValTab16, 511); + ht[17] = new huffcodetab("17 ", 16, 16, 2, 3, 16, null, null, ValTab16, 511); + ht[18] = new huffcodetab("18 ", 16, 16, 3, 7, 16, null, null, ValTab16, 511); + ht[19] = new huffcodetab("19 ", 16, 16, 4, 15, 16, null, null, ValTab16, 511); + ht[20] = new huffcodetab("20 ", 16, 16, 6, 63, 16, null, null, ValTab16, 511); + ht[21] = new huffcodetab("21 ", 16, 16, 8, 255, 16, null, null, ValTab16, 511); + ht[22] = new huffcodetab("22 ", 16, 16, 10, 1023, 16, null, null, ValTab16, 511); + ht[23] = new huffcodetab("23 ", 16, 16, 13, 8191, 16, null, null, ValTab16, 511); + ht[24] = new huffcodetab("24 ", 16, 16, 4, 15, -1, null, null, ValTab24, 512); + ht[25] = new huffcodetab("25 ", 16, 16, 5, 31, 24, null, null, ValTab24, 512); + ht[26] = new huffcodetab("26 ", 16, 16, 6, 63, 24, null, null, ValTab24, 512); + ht[27] = new huffcodetab("27 ", 16, 16, 7, 127, 24, null, null, ValTab24, 512); + ht[28] = new huffcodetab("28 ", 16, 16, 8, 255, 24, null, null, ValTab24, 512); + ht[29] = new huffcodetab("29 ", 16, 16, 9, 511, 24, null, null, ValTab24, 512); + ht[30] = new huffcodetab("30 ", 16, 16, 11, 2047, 24, null, null, ValTab24, 512); + ht[31] = new huffcodetab("31 ", 16, 16, 13, 8191, 24, null, null, ValTab24, 512); + ht[32] = new huffcodetab("32 ", 1, 16, 0, 0, -1, null, null, ValTab32, 31); + ht[33] = new huffcodetab("33 ", 1, 16, 0, 0, -1, null, null, ValTab33, 31); + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/readme.txt b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/readme.txt new file mode 100644 index 000000000..7a765ec7d --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/decoder/readme.txt @@ -0,0 +1,15 @@ + +TODO: + + +Implement high-level Player and Converter classes. + +Add MP1 and MP2 support and test. + +Add option to run each "stage" on own thread. +E.g. read & parse input, decode subbands, subband synthesis, audio output. + +Retrofit seek support (temporarily removed when reworking classes.) + + +Document and give example code. \ No newline at end of file diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/AudioDevice.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/AudioDevice.java new file mode 100644 index 000000000..3af5a259e --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/AudioDevice.java @@ -0,0 +1,101 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 29/01/00 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player; + +import javazoom.jl.decoder.Decoder; +import javazoom.jl.decoder.JavaLayerException; + + +/** + * The AudioDevice interface provides an abstraction for + * a device capable of sounding audio samples. Samples are written to + * the device wia the write() method. The device assumes + * that these samples are signed 16-bit samples taken at the output frequency + * of the decoder. If the decoder outputs more than one channel, the samples for + * each channel are assumed to appear consecutively, with the lower numbered + * channels preceeding higher-numbered channels. E.g. if there are two + * channels, the samples will appear in this order: + *


+ *
+ *        l0, r0, l1, r1, l2, r2...
+ *
+ * where
+ *    lx indicates the xth sample on channel 0
+ *  rx indicates the xth sample on channel 1
+ * 
+ * + * @author Mat McGowan + * @since 0.0.8 + */ +public interface AudioDevice { + /** + * Prepares the AudioDevice for playback of audio samples. + * + * @param decoder The decoder that will be providing the audio + * samples. + *

+ * If the audio device is already open, this method returns silently. + */ + void open(Decoder decoder) throws JavaLayerException; + + /** + * Retrieves the open state of this audio device. + * + * @return true if this audio device is open and playing + * audio samples, or false otherwise. + */ + boolean isOpen(); + + /** + * Writes a number of samples to this AudioDevice. + * + * @param samples The array of signed 16-bit samples to write + * to the audio device. + * @param offs The offset of the first sample. + * @param len The number of samples to write. + *

+ * This method may return prior to the samples actually being played + * by the audio device. + */ + void write(short[] samples, int offs, int len) throws JavaLayerException; + + /** + * Closes this audio device. Any currently playing audio is stopped + * as soon as possible. Any previously written audio data that has not been heard + * is discarded. + *

+ * The implementation should ensure that any threads currently blocking + * on the device (e.g. during a write or flush + * operation should be unblocked by this method. + */ + void close(); + + /** + * Blocks until all audio samples previously written to this audio device have + * been heard. + */ + void flush(); + + /** + * Retrieves the current playback position in milliseconds. + */ + int getPosition(); +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/AudioDeviceBase.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/AudioDeviceBase.java new file mode 100644 index 000000000..f18060b49 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/AudioDeviceBase.java @@ -0,0 +1,160 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 29/01/00 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player; + +import javazoom.jl.decoder.Decoder; +import javazoom.jl.decoder.JavaLayerException; + + +/** + * The AudioDeviceBase class provides a simple thread-safe + * implementation of the AudioDevice interface. + * Template methods are provided for subclasses to override and + * in doing so provide the implementation for the main operations + * of the AudioDevice interface. + *

+ * REVIEW: It is desirable to be able to use the decoder whe + * in the implementation of open(), but the decoder + * has not yet read a frame, and so much of the + * desired information (sample rate, channels etc.) + * are not available. + * @author Mat McGowan + * @since 0.0.8 + */ +public abstract class AudioDeviceBase implements AudioDevice { + private boolean open = false; + + private Decoder decoder = null; + + /** + * Opens this audio device. + * + * @param decoder The decoder that will provide audio data + * to this audio device. + */ + public synchronized void open(Decoder decoder) throws JavaLayerException { + if (!isOpen()) { + this.decoder = decoder; + openImpl(); + setOpen(true); + } + } + + /** + * Template method to provide the + * implementation for the opening of the audio device. + */ + protected void openImpl() throws JavaLayerException { + } + + /** + * Sets the open state for this audio device. + */ + protected void setOpen(boolean open) { + this.open = open; + } + + /** + * Determines if this audio device is open or not. + * + * @return true if the audio device is open, + * false if it is not. + */ + public synchronized boolean isOpen() { + return open; + } + + /** + * Closes this audio device. If the device is currently playing + * audio, playback is stopped immediately without flushing + * any buffered audio data. + */ + public synchronized void close() { + if (isOpen()) { + closeImpl(); + setOpen(false); + decoder = null; + } + } + + /** + * Template method to provide the implementation for + * closing the audio device. + */ + protected void closeImpl() { + } + + /** + * Writes audio data to this audio device. Audio data is + * assumed to be in the output format of the decoder. This + * method may return before the data has actually been sounded + * by the device if the device buffers audio samples. + * + * @param samples The samples to write to the audio device. + * @param offs The offset into the array of the first sample to write. + * @param len The number of samples from the array to write. + * @throws JavaLayerException if the audio data could not be + * written to the audio device. + * If the audio device is not open, this method does nthing. + */ + public void write(short[] samples, int offs, int len) + throws JavaLayerException { + if (isOpen()) { + writeImpl(samples, offs, len); + } + } + + /** + * Template method to provide the implementation for + * writing audio samples to the audio device. + */ + protected void writeImpl(short[] samples, int offs, int len) + throws JavaLayerException { + } + + /** + * Waits for any buffered audio samples to be played by the + * audio device. This method should only be called prior + * to closing the device. + */ + public void flush() { + if (isOpen()) { + flushImpl(); + } + } + + /** + * Template method to provide the implementation for + * flushing any buffered audio data. + */ + protected void flushImpl() { + } + + /** + * Retrieves the decoder that provides audio data to this + * audio device. + * + * @return The associated decoder. + */ + protected Decoder getDecoder() { + return decoder; + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/AudioDeviceFactory.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/AudioDeviceFactory.java new file mode 100644 index 000000000..6b0dfcd21 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/AudioDeviceFactory.java @@ -0,0 +1,64 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 29/01/00 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player; + +import javazoom.jl.decoder.JavaLayerException; + + +/** + * An AudioDeviceFactory class is responsible for creating + * a specific AudioDevice implementation. A factory implementation + * can be as simple or complex as desired and may support just one implementation + * or may return several implementations depending upon the execution + * environment. + *

+ * When implementing a factory that provides an AudioDevice that uses + * class that may not be present, the factory should dynamically link to any + * specific implementation classes required to instantiate or test the audio + * implementation. This is so that the application as a whole + * can run without these classes being present. The audio + * device implementation, however, will usually statically link to the classes + * required. (See the JavaSound deivce and factory for an example + * of this.) + * + * @author Mat McGowan + * @see FactoryRegistry + * @since 0.0.8 + */ +public abstract class AudioDeviceFactory { + + /** + * Creates a new AudioDevice. + * + * @return a new instance of a specific class of AudioDevice. + * @throws JavaLayerException if an instance of AudioDevice could not + * be created. + */ + public abstract AudioDevice createAudioDevice() throws JavaLayerException; + + /** + * @return 0 ~ 100 + * @since 1.0.2 + */ + protected int priority() { + return 100; + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/FactoryRegistry.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/FactoryRegistry.java new file mode 100644 index 000000000..7093e5219 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/FactoryRegistry.java @@ -0,0 +1,129 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 29/01/00 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.logging.Logger; + +import javazoom.jl.decoder.JavaLayerException; + + +/** + * The FactoryRegistry class stores the factories + * for all the audio device implementations available in the system. + *

+ * Instances of this class are thread-safe. + * + * @author Mat McGowan + * @since 0.0.8 + * @see "META-INF/services/javazoom.jl.player.AudioDeviceFactory" + */ +public class FactoryRegistry { + + private static final Logger logger = Logger.getLogger(FactoryRegistry.class.getName()); + + private static FactoryRegistry instance = null; + + public static synchronized FactoryRegistry systemRegistry() { + if (instance == null) { + instance = new FactoryRegistry(); + instance.registerDefaultFactories(); + } + return instance; + } + + protected final Map, AudioDeviceFactory> factories = new HashMap<>(); + + /** + * Registers an AudioDeviceFactory instance + * with this registry. + */ + public void addFactory(AudioDeviceFactory factory) { + factories.put(factory.getClass(), factory); + } + + public void removeFactoryType(Class cls) { + factories.remove(cls); + } + + public void removeFactory(AudioDeviceFactory factory) { + factories.remove(factory.getClass()); + } + + /** + * specify a factory + * @since 1.0.2 + * @throws NullPointerException if not registered class is specified. + */ + public AudioDevice createAudioDevice(Class clazz) throws JavaLayerException { + return factories.get(clazz).createAudioDevice(); + } + + /** + * @since 1.0.2 selecting factory depends on {@link AudioDeviceFactory#priority()} + * @throws JavaLayerException not found or others + */ + public AudioDevice createAudioDevice() throws JavaLayerException { + AudioDevice device = null; + + JavaLayerException lastEx = null; +logger.fine("factories order: " + Arrays.toString(getFactoriesPriority())); + for (AudioDeviceFactory factory : getFactoriesPriority()) { + try { + device = factory.createAudioDevice(); + break; + } catch (JavaLayerException ex) { + lastEx = ex; + } + } + + if (device == null && lastEx != null) { + throw new JavaLayerException("Cannot create AudioDevice", lastEx); + } + + return device; + } + + /** + * @since 1.0.2 order of factories depends on {@link AudioDeviceFactory#priority()} + */ + protected AudioDeviceFactory[] getFactoriesPriority() { + synchronized (factories) { + return factories.values().stream().sorted((o1, o2) -> o2.priority() - o1.priority()).toArray(AudioDeviceFactory[]::new); + } + } + + /** + * @since 1.0.2 this uses the service loader + */ + protected void registerDefaultFactories() { + ServiceLoader loader = ServiceLoader.load(AudioDeviceFactory.class); + for (AudioDeviceFactory factory : loader) { +logger.fine("initial factory: " + factory); + addFactory(factory); + } + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/JavaSoundAudioDevice.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/JavaSoundAudioDevice.java new file mode 100644 index 000000000..123e892b9 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/JavaSoundAudioDevice.java @@ -0,0 +1,171 @@ +/* + * 11/26/04 Buffer size modified to support JRE 1.5 optimizations. + * (CPU usage < 1% under P4/2Ghz, RAM < 12MB). + * jlayer@javazoom.net + * 11/19/04 1.0 moved to LGPL. + * 06/04/01 Too fast playback fixed. mdm@techie.com + * 29/01/00 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.Line; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.SourceDataLine; + +import javazoom.jl.decoder.Decoder; +import javazoom.jl.decoder.JavaLayerException; + + +/** + * The JavaSoundAudioDevice implements an audio + * device by using the JavaSound API. + * + * @author Mat McGowan + * @since 0.0.8 + */ +public class JavaSoundAudioDevice extends AudioDeviceBase { + private SourceDataLine source = null; + + private AudioFormat fmt = null; + + private byte[] byteBuf = new byte[4096]; + + protected void setAudioFormat(AudioFormat fmt0) { + fmt = fmt0; + } + + protected AudioFormat getAudioFormat() { + if (fmt == null) { + Decoder decoder = getDecoder(); + fmt = new AudioFormat(decoder.getOutputFrequency(), + 16, + decoder.getOutputChannels(), + true, + false); + } + return fmt; + } + + protected DataLine.Info getSourceLineInfo() { + AudioFormat fmt = getAudioFormat(); + DataLine.Info info = new DataLine.Info(SourceDataLine.class, fmt); + return info; + } + + public void open(AudioFormat fmt) throws JavaLayerException { + if (!isOpen()) { + setAudioFormat(fmt); + openImpl(); + setOpen(true); + } + } + + protected void openImpl() + throws JavaLayerException { + } + + // createSource fix. + protected void createSource() throws JavaLayerException { + Throwable t = null; + try { + Line line = AudioSystem.getLine(getSourceLineInfo()); + if (line instanceof SourceDataLine) { + source = (SourceDataLine) line; + //source.open(fmt, millisecondsToBytes(fmt, 2000)); + source.open(fmt); + source.start(); + + } + } catch (RuntimeException | LineUnavailableException | LinkageError ex) { + t = ex; + } + if (source == null) throw new JavaLayerException("cannot obtain source audio line", t); + } + + public int millisecondsToBytes(AudioFormat fmt, int time) { + return (int) (time * (fmt.getSampleRate() * fmt.getChannels() * fmt.getSampleSizeInBits()) / 8000.0); + } + + protected void closeImpl() { + if (source != null) { + source.close(); + } + } + + protected void writeImpl(short[] samples, int offs, int len) + throws JavaLayerException { + if (source == null) + createSource(); + + byte[] b = toByteArray(samples, offs, len); + source.write(b, 0, len * 2); + } + + protected byte[] getByteArray(int length) { + if (byteBuf.length < length) { + byteBuf = new byte[length + 1024]; + } + return byteBuf; + } + + protected byte[] toByteArray(short[] samples, int offs, int len) { + byte[] b = getByteArray(len * 2); + int idx = 0; + short s; + while (len-- > 0) { + s = samples[offs++]; + b[idx++] = (byte) s; + b[idx++] = (byte) (s >>> 8); + } + return b; + } + + protected void flushImpl() { + if (source != null) { + source.drain(); + } + } + + public int getPosition() { + int pos = 0; + if (source != null) { + pos = (int) (source.getMicrosecondPosition() / 1000); + } + return pos; + } + + /** + * Runs a short test by playing a short silent sound. + */ + public void test() + throws JavaLayerException { + try { + open(new AudioFormat(22050, 16, 1, true, false)); + short[] data = new short[22050 / 10]; + write(data, 0, data.length); + flush(); + close(); + } catch (RuntimeException ex) { + throw new JavaLayerException("Device test failed: " + ex); + } + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/JavaSoundAudioDeviceFactory.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/JavaSoundAudioDeviceFactory.java new file mode 100644 index 000000000..106ea2b21 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/JavaSoundAudioDeviceFactory.java @@ -0,0 +1,57 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 29/01/00 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player; + +import javazoom.jl.decoder.JavaLayerException; + + +/** + * This class is responsible for creating instances of the + * JavaSoundAudioDevice. The audio device implementation is loaded + * and tested dynamically as not all systems will have support + * for JavaSound, or they may have the incorrect version. + */ +public class JavaSoundAudioDeviceFactory extends AudioDeviceFactory { + + private boolean tested = false; + + @Override + public synchronized AudioDevice createAudioDevice() + throws JavaLayerException { + + if (!tested) { + testAudioDevice(); + tested = true; + } + + return new JavaSoundAudioDevice(); + } + + private void testAudioDevice() throws JavaLayerException { + JavaSoundAudioDevice dev = new JavaSoundAudioDevice(); + dev.test(); + } + + @Override + protected int priority() { + return 90; + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/NullAudioDevice.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/NullAudioDevice.java new file mode 100644 index 000000000..19ba14d0e --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/NullAudioDevice.java @@ -0,0 +1,35 @@ +/* + * 11/19/04 1.0 moved o LGPL. + * 29/01/00 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player; + +/** + * The NullAudioDevice implements a silent, no-op + * audio device. This is useful for testing purposes. + * + * @author Mat McGowan + * @since 0.0.8 + */ +public class NullAudioDevice extends AudioDeviceBase { + + public int getPosition() { + return 0; + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/NullAudioDeviceFactory.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/NullAudioDeviceFactory.java new file mode 100644 index 000000000..1012fd50a --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/NullAudioDeviceFactory.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 by Naohide Sano, All rights reserved. + * + * Programmed by Naohide Sano + */ + +package javazoom.jl.player; + +/** + * NullAudioDeviceFactory. + * + * @author Naohide Sano (nsano) + * @version 0.00 2022/10/03 nsano initial version
+ * @since 1.0.2 + */ +public class NullAudioDeviceFactory extends AudioDeviceFactory { + + @Override + public synchronized AudioDevice createAudioDevice() { + return new NullAudioDevice(); + } + + @Override + protected int priority() { + return 0; + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/Player.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/Player.java new file mode 100644 index 000000000..e5aca468a --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/Player.java @@ -0,0 +1,209 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 29/01/00 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player; + +import java.io.InputStream; + +import javazoom.jl.decoder.Bitstream; +import javazoom.jl.decoder.BitstreamException; +import javazoom.jl.decoder.Decoder; +import javazoom.jl.decoder.Header; +import javazoom.jl.decoder.JavaLayerException; +import javazoom.jl.decoder.SampleBuffer; + + +/** + * The Player class implements a simple player for playback + * of an MPEG audio stream. + *

+ * REVIEW: the audio device should not be opened until the + * first MPEG audio frame has been decoded. + * + * @author Mat McGowan + * @since 0.0.8 + */ +public class Player { + + /** + * The current frame number. + */ + @SuppressWarnings("unused") + private int frame = 0; + + /** + * The MPEG audio bitstream. + */ + private Bitstream bitstream; + + /** + * The MPEG audio decoder. + */ + private Decoder decoder; + + /** + * The AudioDevice the audio samples are written to. + */ + private AudioDevice audio; + + /** + * Has the player been closed? + */ + private boolean closed = false; + + /** + * Has the player played back all frames from the stream? + */ + private boolean complete = false; + + private int lastPosition = 0; + + /** + * Creates a new Player instance. + */ + public Player(InputStream stream) throws JavaLayerException { + this(stream, null); + } + + public Player(InputStream stream, AudioDevice device) throws JavaLayerException { + bitstream = new Bitstream(stream); + decoder = new Decoder(); + + if (device != null) { + audio = device; + } else { + FactoryRegistry r = FactoryRegistry.systemRegistry(); + audio = r.createAudioDevice(); + } + audio.open(decoder); + } + + public void play() throws JavaLayerException { + play(Integer.MAX_VALUE); + } + + /** + * Plays a number of MPEG audio frames. + * + * @param frames The number of frames to play. + * @return true if the last frame was played, or false if there are + * more frames. + */ + public boolean play(int frames) throws JavaLayerException { + boolean ret = true; + + while (frames-- > 0 && ret) { + ret = decodeFrame(); + } + + if (!ret) { + // last frame, ensure all data flushed to the audio device. + AudioDevice out = audio; + if (out != null) { + out.flush(); + synchronized (this) { + complete = (!closed); + close(); + } + } + } + return ret; + } + + /** + * Closes this player. Any audio currently playing is stopped + * immediately. + */ + public synchronized void close() { + AudioDevice out = audio; + if (out != null) { + closed = true; + audio = null; + // this may fail, so ensure object state is set up before + // calling this method. + out.close(); + lastPosition = out.getPosition(); + try { + bitstream.close(); + } catch (BitstreamException ex) { + } + } + } + + /** + * Returns the completed status of this player. + * + * @return true if all available MPEG audio frames have been + * decoded, or false otherwise. + */ + public synchronized boolean isComplete() { + return complete; + } + + /** + * Retrieves the position in milliseconds of the current audio + * sample being played. This method delegates to the + * AudioDevice that is used by this player to sound + * the decoded audio samples. + */ + public int getPosition() { + int position = lastPosition; + + AudioDevice out = audio; + if (out != null) { + position = out.getPosition(); + } + return position; + } + + /** + * Decodes a single frame. + * + * @return true if there are no more frames to decode, false otherwise. + */ + protected boolean decodeFrame() throws JavaLayerException { + try { + AudioDevice out = audio; + if (out == null) + return false; + + Header h = bitstream.readFrame(); + + if (h == null) + return false; + + // sample buffer set when decoder constructed + SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h, bitstream); + + synchronized (this) { + out = audio; + if (out != null) { + out.write(output.getBuffer(), 0, output.getBufferLength()); + } + } + + bitstream.closeFrame(); + } catch (RuntimeException ex) { + throw new JavaLayerException("Exception decoding audio frame", ex); + } + + return true; + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/PlayerApplet.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/PlayerApplet.java new file mode 100644 index 000000000..9f6acd375 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/PlayerApplet.java @@ -0,0 +1,212 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 29/01/00 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player; + +import java.applet.Applet; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import javazoom.jl.decoder.JavaLayerException; + + +/** + * A simple applet that plays an MPEG audio file. + * The URL (relative to the document base) + * is passed as the "audioURL" parameter. + * + * @author Mat McGowan + * @since 0.0.8 + */ +public class PlayerApplet extends Applet implements Runnable { + + static public final String AUDIO_PARAMETER = "audioURL"; + + /** + * The Player used to play the MPEG audio file. + */ + private Player player = null; + + /** + * The thread that runs the player. + */ + private Thread playerThread = null; + + private String fileName = null; + + /** + * Retrieves the AudioDevice instance that will + * be used to sound the audio data. + * + * @return an audio device instance that will be used to + * sound the audio stream. + */ + protected AudioDevice getAudioDevice() throws JavaLayerException { + return FactoryRegistry.systemRegistry().createAudioDevice(); + } + + /** + * Retrieves the InputStream that provides the MPEG audio + * stream data. + * + * @return an InputStream from which the MPEG audio data + * is read, or null if an error occurs. + */ + protected InputStream getAudioStream() { + InputStream in = null; + + try { + URL url = getAudioURL(); + if (url != null) + in = url.openStream(); + } catch (IOException ex) { + ex.printStackTrace(); + } + return in; + } + + protected String getAudioFileName() { + String urlString = fileName; + if (urlString == null) { + urlString = getParameter(AUDIO_PARAMETER); + } + return urlString; + } + + protected URL getAudioURL() { + String urlString = getAudioFileName(); + URL url = null; + if (urlString != null) { + try { + url = new URL(getDocumentBase(), urlString); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + return url; + } + + /** + * Sets the URL of the audio stream to play. + */ + public void setFileName(String name) { + fileName = name; + } + + public String getFileName() { + return fileName; + } + + /** + * Stops the audio player. If the player is already stopped + * this method is a no-op. + */ + protected void stopPlayer() throws JavaLayerException { + if (player != null) { + player.close(); + player = null; + playerThread = null; + } + } + + /** + * Decompresses audio data from an InputStream and plays it + * back through an AudioDevice. The playback is run on a newly + * created thread. + * + * @param in The InputStream that provides the MPEG audio data. + * @param dev The AudioDevice to use to sound the decompressed data. + * @throws JavaLayerException if there was a problem decoding + * or playing the audio data. + */ + protected void play(InputStream in, AudioDevice dev) throws JavaLayerException { + stopPlayer(); + + if (in != null && dev != null) { + player = new Player(in, dev); + playerThread = createPlayerThread(); + playerThread.start(); + } + } + + /** + * Creates a new thread used to run the audio player. + * + * @return A new Thread that, once started, runs the audio player. + */ + protected Thread createPlayerThread() { + return new Thread(this, "Audio player thread"); + } + + /** + * Initializes this applet. + */ + public void init() { + } + + /** + * Starts this applet. An input stream and audio device + * are created and passed to the play() method. + */ + public void start() { + String name = getAudioFileName(); + try { + InputStream in = getAudioStream(); + AudioDevice dev = getAudioDevice(); + play(in, dev); + } catch (JavaLayerException ex) { + synchronized (System.err) { + System.err.println("Unable to play " + name); + ex.printStackTrace(); + } + } + } + + /** + * Stops this applet. If audio is currently playing, it is + * stopped. + */ + public void stop() { + try { + stopPlayer(); + } catch (JavaLayerException ex) { + ex.printStackTrace(); + } + } + + public void destroy() { + } + + /** + * The run method for the audio player thread. Simply calls + * play() on the player to play the entire stream. + */ + public void run() { + if (player != null) { + try { + player.play(); + } catch (JavaLayerException ex) { + System.err.println("Problem playing audio: " + ex); + ex.printStackTrace(); + } + } + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/advanced/AdvancedPlayer.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/advanced/AdvancedPlayer.java new file mode 100644 index 000000000..4d1ce4c76 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/advanced/AdvancedPlayer.java @@ -0,0 +1,217 @@ +/* + * 11/19/04 1.0 moved to LGPL. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player.advanced; + +import java.io.InputStream; + +import javazoom.jl.decoder.Bitstream; +import javazoom.jl.decoder.BitstreamException; +import javazoom.jl.decoder.Decoder; +import javazoom.jl.decoder.Header; +import javazoom.jl.decoder.JavaLayerException; +import javazoom.jl.decoder.SampleBuffer; +import javazoom.jl.player.AudioDevice; +import javazoom.jl.player.FactoryRegistry; + + +/** + * a hybrid of javazoom.jl.player.Player tweeked to include play(startFrame, endFrame) + * hopefully this will be included in the api + */ +public class AdvancedPlayer { + + /** The MPEG audio bitstream. */ + private Bitstream bitstream; + /** The MPEG audio decoder. */ + private Decoder decoder; + /** The AudioDevice the audio samples are written to. */ + private AudioDevice audio; + /** Has the player been closed? */ + private boolean closed = false; + /** Has the player played back all frames from the stream? */ + private boolean complete = false; + private int lastPosition = 0; + /** Listener for the playback process */ + private PlaybackListener listener; + + /** + * Creates a new Player instance. + */ + public AdvancedPlayer(InputStream stream) throws JavaLayerException { + this(stream, null); + } + + public AdvancedPlayer(InputStream stream, AudioDevice device) throws JavaLayerException { + bitstream = new Bitstream(stream); + + if (device != null) audio = device; + else audio = FactoryRegistry.systemRegistry().createAudioDevice(); + audio.open(decoder = new Decoder()); + } + + public void play() throws JavaLayerException { + play(Integer.MAX_VALUE); + } + + /** + * Plays a number of MPEG audio frames. + * + * @param frames The number of frames to play. + * @return true if the last frame was played, or false if there are + * more frames. + */ + public boolean play(int frames) throws JavaLayerException { + boolean ret = true; + + // report to listener + if (listener != null) listener.playbackStarted(createEvent(PlaybackEvent.STARTED)); + + while (frames-- > 0 && ret) { + ret = decodeFrame(); + } + + // last frame, ensure all data flushed to the audio device. + AudioDevice out = audio; + if (out != null) { + out.flush(); + synchronized (this) { + complete = (!closed); + close(); + } + + // report to listener + if (listener != null) listener.playbackFinished(createEvent(out, PlaybackEvent.STOPPED)); + } + + return ret; + } + + /** + * Cloases this player. Any audio currently playing is stopped + * immediately. + */ + public synchronized void close() { + AudioDevice out = audio; + if (out != null) { + closed = true; + audio = null; + // this may fail, so ensure object state is set up before + // calling this method. + out.close(); + lastPosition = out.getPosition(); + try { + bitstream.close(); + } catch (BitstreamException ex) { + } + } + } + + /** + * Decodes a single frame. + * + * @return true if there are no more frames to decode, false otherwise. + */ + protected boolean decodeFrame() throws JavaLayerException { + try { + AudioDevice out = audio; + if (out == null) return false; + + Header h = bitstream.readFrame(); + if (h == null) return false; + + // sample buffer set when decoder constructed + SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h, bitstream); + + synchronized (this) { + out = audio; + if (out != null) { + out.write(output.getBuffer(), 0, output.getBufferLength()); + } + } + + bitstream.closeFrame(); + } catch (RuntimeException ex) { + throw new JavaLayerException("Exception decoding audio frame", ex); + } + return true; + } + + /** + * skips over a single frame + * + * @return false if there are no more frames to decode, true otherwise. + */ + protected boolean skipFrame() throws JavaLayerException { + Header h = bitstream.readFrame(); + if (h == null) return false; + bitstream.closeFrame(); + return true; + } + + /** + * Plays a range of MPEG audio frames + * + * @param start The first frame to play + * @param end The last frame to play + * @return true if the last frame was played, or false if there are more frames. + */ + public boolean play(final int start, final int end) throws JavaLayerException { + boolean ret = true; + int offset = start; + while (offset-- > 0 && ret) ret = skipFrame(); + return play(end - start); + } + + /** + * Constructs a PlaybackEvent + */ + private PlaybackEvent createEvent(int id) { + return createEvent(audio, id); + } + + /** + * Constructs a PlaybackEvent + */ + private PlaybackEvent createEvent(AudioDevice dev, int id) { + return new PlaybackEvent(this, id, dev.getPosition()); + } + + /** + * sets the PlaybackListener + */ + public void setPlayBackListener(PlaybackListener listener) { + this.listener = listener; + } + + /** + * gets the PlaybackListener + */ + public PlaybackListener getPlayBackListener() { + return listener; + } + + /** + * closes the player and notifies PlaybackListener + */ + public void stop() { + listener.playbackFinished(createEvent(PlaybackEvent.STOPPED)); + close(); + } +} \ No newline at end of file diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/advanced/PlaybackEvent.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/advanced/PlaybackEvent.java new file mode 100644 index 000000000..c46ce293a --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/advanced/PlaybackEvent.java @@ -0,0 +1,65 @@ +/* + * 11/19/04 1.0 moved to LGPL. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player.advanced; + +/** + * An event which indicates a Player has performed an 'playback + * action' + * + * @author Paul Stanton (http://wanto.f2o.org/) + */ +public class PlaybackEvent { + public static final int STOPPED = 1; + public static final int STARTED = 2; + + private AdvancedPlayer source; + private int frame; + private int id; + + public PlaybackEvent(AdvancedPlayer source, int id, int frame) { + this.id = id; + this.source = source; + this.frame = frame; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getFrame() { + return frame; + } + + public void setFrame(int frame) { + this.frame = frame; + } + + public AdvancedPlayer getSource() { + return source; + } + + public void setSource(AdvancedPlayer source) { + this.source = source; + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/advanced/PlaybackListener.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/advanced/PlaybackListener.java new file mode 100644 index 000000000..62658bd93 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/advanced/PlaybackListener.java @@ -0,0 +1,33 @@ +/* + * 11/19/04 1.0 moved to LGPL. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player.advanced; + +/** + * Listener for javalayer Player playback + * + * @author Paul Stanton (http://wanto.f2o.org/) + */ +public abstract class PlaybackListener { + public void playbackStarted(PlaybackEvent evt) { + } + + public void playbackFinished(PlaybackEvent evt) { + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/advanced/jlap.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/advanced/jlap.java new file mode 100644 index 000000000..96f9b0669 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/advanced/jlap.java @@ -0,0 +1,98 @@ +/* + * 11/19/04 1.0 moved to LGPL. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player.advanced; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; + +import javazoom.jl.decoder.JavaLayerException; + + +/** + * This class implements a sample player using Playback listener. + */ +public class jlap { + + public static void main(String[] args) { + jlap test = new jlap(); + if (args.length != 1) { + test.showUsage(); + System.exit(0); + } else { + try { + test.play(args[0]); + } catch (Exception ex) { + System.err.println(ex.getMessage()); + System.exit(0); + } + } + } + + public void play(String filename) throws JavaLayerException, IOException { + InfoListener lst = new InfoListener(); + playMp3(new File(filename), lst); + } + + public void showUsage() { + System.out.println("Usage: jla "); + System.out.println(); + System.out.println(" e.g. : java javazoom.jl.player.advanced.jlap localfile.mp3"); + } + + public static AdvancedPlayer playMp3(File mp3, PlaybackListener listener) throws IOException, JavaLayerException { + return playMp3(mp3, 0, Integer.MAX_VALUE, listener); + } + + public static AdvancedPlayer playMp3(File mp3, int start, int end, PlaybackListener listener) throws IOException, + JavaLayerException { + return playMp3(new BufferedInputStream(Files.newInputStream(mp3.toPath())), start, end, listener); + } + + public static AdvancedPlayer playMp3(final InputStream is, + final int start, + final int end, + PlaybackListener listener) throws JavaLayerException { + final AdvancedPlayer player = new AdvancedPlayer(is); + player.setPlayBackListener(listener); + // run in new thread + new Thread(() -> { + try { + player.play(start, end); + } catch (Exception e) { + throw new RuntimeException(e.getMessage()); + } + }).start(); + return player; + } + + public static class InfoListener extends PlaybackListener { + public void playbackStarted(PlaybackEvent evt) { + System.out.println("Play started from frame " + evt.getFrame()); + } + + public void playbackFinished(PlaybackEvent evt) { + System.out.println("Play completed at frame " + evt.getFrame()); + System.exit(0); + } + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/jlp.java b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/jlp.java new file mode 100644 index 000000000..c2b1384c6 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/java/javazoom/jl/player/jlp.java @@ -0,0 +1,174 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 06/04/01 Streaming support added. javalayer@javazoom.net + * + * 29/01/00 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player; + +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.logging.Logger; + +import javazoom.jl.decoder.JavaLayerException; + + +/** + * The jlp class implements a simple command-line + * player for MPEG audio files. + * + * @author Mat McGowan (mdm@techie.com) + */ +public class jlp { + + private static final Logger logger = Logger.getLogger(jlp.class.getName()); + + private String fFilename = null; + private boolean remote = false; + private AudioDevice audioDevice; + private Player player; + + public static void main(String[] args) { + int retval = 0; + try { + jlp player = createInstance(args); + if (player != null) + player.play(); + } catch (Exception ex) { + System.err.println(ex); + ex.printStackTrace(System.err); + retval = 1; + } + System.exit(retval); + } + + static public jlp createInstance(String[] args) { + jlp player = new jlp(); + if (!player.parseArgs(args)) + player = null; + return player; + } + + private jlp() { + } + + public jlp(String filename) { + init(filename); + } + + protected void init(String filename) { + fFilename = filename; + } + + protected boolean parseArgs(String[] args) { + boolean parsed = false; + if (args.length == 1) { + init(args[0]); + parsed = true; + remote = false; + } else if (args.length == 2) { + if (!(args[0].equals("-url"))) { + showUsage(); + } else { + init(args[1]); + parsed = true; + remote = true; + } + } else { + showUsage(); + } + return parsed; + } + + public void showUsage() { + System.out.println("Usage: jlp [-url] "); + System.out.println(); + System.out.println(" e.g. : java javazoom.jl.player.jlp localfile.mp3"); + System.out.println(" java javazoom.jl.player.jlp -url http://www.server.com/remotefile.mp3"); + System.out.println(" java javazoom.jl.player.jlp -url http://www.shoutcastserver.com:8000"); + } + + public void play() + throws JavaLayerException { + try { + System.out.println("playing " + fFilename + "..."); + InputStream in; + if (remote) in = getURLInputStream(); + else in = getInputStream(); + AudioDevice dev = setAudioDevice(); + logger.fine("audioDevice: " + dev); + player = new Player(in, dev); + player.play(); + } catch (Exception ex) { + throw new JavaLayerException("Problem playing file " + fFilename, ex); + } + } + + /** @since 1.0.2 */ + public void stop() { + player.close(); + } + + /** + * Playing file from URL (Streaming). + */ + protected InputStream getURLInputStream() + throws Exception { + + URL url = new URL(fFilename); + InputStream fin = url.openStream(); + BufferedInputStream bin = new BufferedInputStream(fin); + return bin; + } + + /** + * Playing file from FileInputStream. + */ + protected InputStream getInputStream() + throws IOException { + FileInputStream fin = new FileInputStream(fFilename); + BufferedInputStream bin = new BufferedInputStream(fin); + return bin; + } + + /** + * Use when you want to use a specific audio device. + * @since 1.0.2 + */ + public void setAudioDevice(AudioDevice audioDevice) { + this.audioDevice = audioDevice; + } + + /** + * if you don't use {@link #setAudioDevice}, + * default audio device depends on service loader. + * @since 1.0.2 default audio device depends on service loader + */ + public AudioDevice setAudioDevice() + throws JavaLayerException { + if (audioDevice == null) { + audioDevice = FactoryRegistry.systemRegistry().createAudioDevice(); + } + return audioDevice; + } +} diff --git a/libsrc/jlayer-1.0.2/src/main/resources/META-INF/services/javazoom.jl.player.AudioDeviceFactory b/libsrc/jlayer-1.0.2/src/main/resources/META-INF/services/javazoom.jl.player.AudioDeviceFactory new file mode 100644 index 000000000..f0889dc77 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/main/resources/META-INF/services/javazoom.jl.player.AudioDeviceFactory @@ -0,0 +1,2 @@ +javazoom.jl.player.JavaSoundAudioDeviceFactory +javazoom.jl.player.NullAudioDeviceFactory \ No newline at end of file diff --git a/libsrc/jlayer-1.0.2/src/main/resources/javazoom/jl/decoder/au2lin.ser b/libsrc/jlayer-1.0.2/src/main/resources/javazoom/jl/decoder/au2lin.ser new file mode 100644 index 000000000..0b20bc8bb Binary files /dev/null and b/libsrc/jlayer-1.0.2/src/main/resources/javazoom/jl/decoder/au2lin.ser differ diff --git a/libsrc/jlayer-1.0.2/src/main/resources/javazoom/jl/decoder/l3reorder.ser b/libsrc/jlayer-1.0.2/src/main/resources/javazoom/jl/decoder/l3reorder.ser new file mode 100644 index 000000000..da216fcf4 Binary files /dev/null and b/libsrc/jlayer-1.0.2/src/main/resources/javazoom/jl/decoder/l3reorder.ser differ diff --git a/libsrc/jlayer-1.0.2/src/main/resources/javazoom/jl/decoder/lin2au.ser b/libsrc/jlayer-1.0.2/src/main/resources/javazoom/jl/decoder/lin2au.ser new file mode 100644 index 000000000..ec1c83d30 Binary files /dev/null and b/libsrc/jlayer-1.0.2/src/main/resources/javazoom/jl/decoder/lin2au.ser differ diff --git a/libsrc/jlayer-1.0.2/src/main/resources/javazoom/jl/decoder/sfd.ser b/libsrc/jlayer-1.0.2/src/main/resources/javazoom/jl/decoder/sfd.ser new file mode 100644 index 000000000..440c7c678 Binary files /dev/null and b/libsrc/jlayer-1.0.2/src/main/resources/javazoom/jl/decoder/sfd.ser differ diff --git a/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/decoder/BitstreamTest.java b/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/decoder/BitstreamTest.java new file mode 100644 index 000000000..449c63b92 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/decoder/BitstreamTest.java @@ -0,0 +1,140 @@ +/* + * 11/19/2004 : 1.0 moved to LGPL. + * 01/01/2004 : Initial version by E.B javalayer@javazoom.net + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.Properties; +import java.util.logging.Level; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import vavi.util.Debug; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + + +/** + * Bitstream unit test. + * It matches test.mp3 properties to test.mp3.properties expected results. + * As we don't ship test.mp3, you have to generate your own test.mp3.properties + * Uncomment out = System.out; in setUp() method to generated it on stdout from + * your own MP3 file. + * + * @since 0.4 + */ +public class BitstreamTest { + + private String basefile = null; + private String name = null; + private String filename = null; + private Properties props = null; + private FileInputStream mp3in = null; + private Bitstream in = null; + + @BeforeEach + protected void setUp() throws Exception { + props = new Properties(); + InputStream pin = getClass().getClassLoader().getResourceAsStream("test.mp3.properties"); + props.load(pin); + basefile = props.getProperty("basefile"); + name = props.getProperty("filename"); + filename = basefile + name; + mp3in = new FileInputStream(filename); + in = new Bitstream(mp3in); + } + + @AfterEach + protected void tearDown() throws Exception { + in.close(); + mp3in.close(); + } + + @Test + public void testStream() throws Exception { + InputStream id3in = in.getRawID3v2(); + int size = id3in.available(); + Header header = in.readFrame(); + Debug.println(Level.FINE, "--- " + filename + " ---"); + Debug.println(Level.FINE, "ID3v2Size=" + size); + Debug.println(Level.FINE, "version=" + header.version()); + Debug.println(Level.FINE, "version_string=" + header.version_string()); + Debug.println(Level.FINE, "layer=" + header.layer()); + Debug.println(Level.FINE, "frequency=" + header.frequency()); + Debug.println(Level.FINE, "frequency_string=" + header.sample_frequency_string()); + Debug.println(Level.FINE, "bitrate=" + header.bitrate()); + Debug.println(Level.FINE, "bitrate_string=" + header.bitrate_string()); + Debug.println(Level.FINE, "mode=" + header.mode()); + Debug.println(Level.FINE, "mode_string=" + header.mode_string()); + Debug.println(Level.FINE, "slots=" + header.slots()); + Debug.println(Level.FINE, "vbr=" + header.vbr()); + Debug.println(Level.FINE, "vbr_scale=" + header.vbr_scale()); + Debug.println(Level.FINE, "max_number_of_frames=" + header.max_number_of_frames(mp3in.available())); + Debug.println(Level.FINE, "min_number_of_frames=" + header.min_number_of_frames(mp3in.available())); + Debug.println(Level.FINE, "ms_per_frame=" + header.ms_per_frame()); + Debug.println(Level.FINE, "frames_per_second=" + (float) ((1.0 / (header.ms_per_frame())) * 1000.0)); + Debug.println(Level.FINE, "total_ms=" + header.total_ms(mp3in.available())); + Debug.println(Level.FINE, "SyncHeader=" + header.getSyncHeader()); + Debug.println(Level.FINE, "checksums=" + header.checksums()); + Debug.println(Level.FINE, "copyright=" + header.copyright()); + Debug.println(Level.FINE, "original=" + header.original()); + Debug.println(Level.FINE, "padding=" + header.padding()); + Debug.println(Level.FINE, "framesize=" + header.calculate_framesize()); + Debug.println(Level.FINE, "number_of_subbands=" + header.number_of_subbands()); + assertEquals(Integer.parseInt(props.getProperty("ID3v2Size")), size, "ID3v2Size"); + assertEquals(Integer.parseInt(props.getProperty("version")), header.version(), "version"); + assertEquals(props.getProperty("version_string"), header.version_string(), "version_string"); + assertEquals(Integer.parseInt(props.getProperty("layer")), header.layer(), "layer"); + assertEquals(Integer.parseInt(props.getProperty("frequency")), header.frequency(), "frequency"); + assertEquals(props.getProperty("frequency_string"), header.sample_frequency_string(), "frequency_string"); + assertEquals(Integer.parseInt(props.getProperty("bitrate")), header.bitrate(), "bitrate"); + assertEquals(props.getProperty("bitrate_string"), header.bitrate_string(), "bitrate_string"); + assertEquals(Integer.parseInt(props.getProperty("mode")), header.mode(), "mode"); + assertEquals(props.getProperty("mode_string"), header.mode_string(), "mode_string"); + assertEquals(Integer.parseInt(props.getProperty("slots")), header.slots(), "slots"); + assertEquals(Boolean.valueOf(props.getProperty("vbr")), header.vbr(), "vbr"); + assertEquals(Integer.parseInt(props.getProperty("vbr_scale")), header.vbr_scale(), "vbr_scale"); + assertEquals(Integer.parseInt(props.getProperty("max_number_of_frames")), + header.max_number_of_frames(mp3in.available()), + "max_number_of_frames"); + assertEquals(Integer.parseInt(props.getProperty("min_number_of_frames")), + header.min_number_of_frames(mp3in.available()), + "min_number_of_frames"); + assertEquals(Float.parseFloat(props.getProperty("ms_per_frame")), header.ms_per_frame(), "ms_per_frame"); + assertEquals(Float + .parseFloat(props.getProperty("frames_per_second")), (float) ((1.0 / (header.ms_per_frame())) * 1000.0), "frames_per_second"); + assertEquals(Float.parseFloat(props.getProperty("total_ms")), header.total_ms(mp3in.available()), "total_ms"); + assertEquals(Integer.parseInt(props.getProperty("SyncHeader")), header.getSyncHeader(), "SyncHeader"); + assertEquals(Boolean.valueOf(props.getProperty("checksums")), header.checksums(), "checksums"); + assertEquals(Boolean.valueOf(props.getProperty("copyright")), header.copyright(), "copyright"); + assertEquals(Boolean.valueOf(props.getProperty("original")), header.original(), "original"); + assertEquals(Boolean.valueOf(props.getProperty("padding")), header.padding(), "padding"); + assertEquals(Integer.parseInt(props.getProperty("framesize")), header.calculate_framesize(), "framesize"); + assertEquals(Integer.parseInt(props.getProperty("number_of_subbands")), + header.number_of_subbands(), + "number_of_subbands"); + in.closeFrame(); + } +} diff --git a/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/player/JavaSoundAudioDeviceTest.java b/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/player/JavaSoundAudioDeviceTest.java new file mode 100644 index 000000000..682cbe4a2 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/player/JavaSoundAudioDeviceTest.java @@ -0,0 +1,13 @@ +package javazoom.jl.player; + +import javax.sound.sampled.AudioFormat; + +import org.junit.jupiter.api.Test; + + +class JavaSoundAudioDeviceTest { + + @Test + void test() throws Exception { + } +} \ No newline at end of file diff --git a/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/player/jlpTest.java b/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/player/jlpTest.java new file mode 100644 index 000000000..14d26cfa6 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/player/jlpTest.java @@ -0,0 +1,101 @@ +/* + * 11/19/2004 : 1.0 moved to LGPL. + * 01/01/2004 : Initial version by E.B javalayer@javazoom.net + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.player; + +import java.io.InputStream; +import java.util.Properties; + +import javazoom.jl.player.my.MyJavaSoundAudioDevice; +import javazoom.jl.player.my.MyJavaSoundAudioDeviceFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledIfSystemProperty; +import vavix.util.DelayedWorker; + +import static org.junit.jupiter.api.Assertions.assertTrue; + + +/** + * Simple player unit test. + * It takes around 3-6% of CPU and 10MB RAM under Win2K/PIII/1GHz/JDK1.5.0 + * It takes around 10-12% of CPU and 10MB RAM under Win2K/PIII/1GHz/JDK1.4.1 + * It takes around 08-10% of CPU and 10MB RAM under Win2K/PIII/1GHz/JDK1.3.1 + * + * @since 0.4 + */ +public class jlpTest { + + private Properties props = null; + private String filename = null; + + long time; + + @BeforeEach + public void setUp() throws Exception { + props = new Properties(); + InputStream pin = getClass().getClassLoader().getResourceAsStream("test.mp3.properties"); + props.load(pin); + String basefile = props.getProperty("basefile"); + String name = props.getProperty("filename"); + filename = basefile + name; + System.err.println(filename); + time = System.getProperty("vavi.test", "").equals("ide") ? 100000 : 3000; + } + + @Test + @DisplayName("original audio device") + public void testPlay() throws Exception { + String[] args = new String[1]; + args[0] = filename; + jlp player = jlp.createInstance(args); + player.setAudioDevice(FactoryRegistry.systemRegistry().createAudioDevice(JavaSoundAudioDeviceFactory.class)); + DelayedWorker.later(3000, player::stop); + player.play(); + assertTrue(true, "Play"); + } + + @Test + @DisplayName("my audio device w/ volume") + public void testPlay2() throws Exception { + String[] args = new String[1]; + args[0] = filename; + jlp player = jlp.createInstance(args); + // my audio device might have first priority + ((MyJavaSoundAudioDevice) player.setAudioDevice()).setVolume(0.05f); + DelayedWorker.later(3000, player::stop); + player.play(); + assertTrue(true, "Play"); + } + + @Test + @DisplayName("specified my audio device w/ volume") + public void testPlay3() throws Exception { + String[] args = new String[1]; + args[0] = filename; + jlp player = jlp.createInstance(args); + player.setAudioDevice(FactoryRegistry.systemRegistry().createAudioDevice(MyJavaSoundAudioDeviceFactory.class)); + ((MyJavaSoundAudioDevice) player.setAudioDevice()).setVolume(0.05f); + DelayedWorker.later(3000, player::stop); + player.play(); + assertTrue(true, "Play"); + } +} diff --git a/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/player/my/MyJavaSoundAudioDevice.java b/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/player/my/MyJavaSoundAudioDevice.java new file mode 100644 index 000000000..5ac91bd8e --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/player/my/MyJavaSoundAudioDevice.java @@ -0,0 +1,164 @@ +/* + * https://stackoverflow.com/a/35087343 + */ + +package javazoom.jl.player.my; + +import java.util.logging.Level; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.FloatControl; +import javax.sound.sampled.Line; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.SourceDataLine; + +import javazoom.jl.decoder.JavaLayerException; +import javazoom.jl.player.AudioDeviceBase; +import javazoom.jl.player.AudioDeviceFactory; +import vavi.util.Debug; + + +/** + * this is the sample {@link AudioDeviceFactory} implementation. + * default {@link javazoom.jl.player.JavaSoundAudioDeviceFactory} doesn't have volume control. + */ +public class MyJavaSoundAudioDevice extends AudioDeviceBase { + + private SourceDataLine source = null; + private AudioFormat fmt = null; + private byte[] byteBuf = new byte[4096]; + + protected void setAudioFormat(AudioFormat fmt0) { + fmt = fmt0; + } + + protected AudioFormat getAudioFormat() { + fmt = new AudioFormat(44100, + 16, + 2, + true, + false); + + return fmt; + } + + protected DataLine.Info getSourceLineInfo() { + AudioFormat fmt = getAudioFormat(); + DataLine.Info info = new DataLine.Info(SourceDataLine.class, fmt); + return info; + } + + public void open(AudioFormat fmt) throws JavaLayerException { + if (!isOpen()) { + setAudioFormat(fmt); + openImpl(); + setOpen(true); + } + } + + /** */ + private float gain = 6.0206f; + + /** @param gain 0 ~ 1 */ + public void setVolume(float gain) { + this.gain = (float) (Math.log10(gain) * 20.0); +Debug.println(Level.FINE, "volume: " + gain + ", " + hashCode()); + } + + /** */ + private void setLineGain() { + FloatControl volControl = (FloatControl) source.getControl(FloatControl.Type.MASTER_GAIN); + volControl.setValue(gain); +Debug.println(Level.FINE, "volume: " + gain + ", " + hashCode()); + } + + public void openImpl() + throws JavaLayerException { + } + + // createSource fix. + public void createSource() throws JavaLayerException { + Throwable t = null; + try { + Line line = AudioSystem.getLine(getSourceLineInfo()); + if (line instanceof SourceDataLine) { + source = (SourceDataLine) line; + source.open(fmt); + setLineGain(); + + source.start(); + } + } catch (RuntimeException | LinkageError | LineUnavailableException ex) { +ex.printStackTrace(); + t = ex; + } + if (source == null) { + throw new JavaLayerException("cannot obtain source audio line", t); + } + } + + public int millisecondsToBytes(AudioFormat fmt, int time) { + return (int) (time * (fmt.getSampleRate() * fmt.getChannels() * fmt.getSampleSizeInBits()) / 8000.0); + } + + protected void closeImpl() { + if (source != null) { + source.close(); + } + } + + protected void writeImpl(short[] samples, int offs, int len) + throws JavaLayerException { + if (source == null) { + createSource(); + } + + byte[] b = toByteArray(samples, offs, len); + source.write(b, 0, len * 2); + } + + protected byte[] getByteArray(int length) { + if (byteBuf.length < length) { + byteBuf = new byte[length + 1024]; + } + return byteBuf; + } + + protected byte[] toByteArray(short[] samples, int offs, int len) { + byte[] b = getByteArray(len * 2); + int idx = 0; + short s; + while (len-- > 0) { + s = samples[offs++]; + b[idx++] = (byte) s; + b[idx++] = (byte) (s >>> 8); + } + return b; + } + + protected void flushImpl() { + if (source != null) { + source.drain(); + } + } + + public int getPosition() { + int pos = 0; + if (source != null) { + pos = (int) (source.getMicrosecondPosition() / 1000); + } + return pos; + } + + /** + * Runs a short test by playing a short silent sound. + */ + public void test() throws JavaLayerException { + open(new AudioFormat(22000, 16, 1, true, false)); + short[] data = new short[22000 / 10]; + write(data, 0, data.length); + flush(); + close(); + } +} \ No newline at end of file diff --git a/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/player/my/MyJavaSoundAudioDeviceFactory.java b/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/player/my/MyJavaSoundAudioDeviceFactory.java new file mode 100644 index 000000000..ed01de92c --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/test/java/javazoom/jl/player/my/MyJavaSoundAudioDeviceFactory.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 by Naohide Sano, All rights reserved. + * + * Programmed by Naohide Sano + */ + +package javazoom.jl.player.my; + +import javazoom.jl.decoder.JavaLayerException; +import javazoom.jl.player.AudioDevice; +import javazoom.jl.player.AudioDeviceFactory; + + +/** + * factory for MyJavaSoundAudioDevice. + * + * @author Naohide Sano (nsano) + * @version 0.00 2022/10/03 nsano initial version
+ * @see "META-INF/services/javazoom.jl.player.AudioDeviceFactory" + */ +public class MyJavaSoundAudioDeviceFactory extends AudioDeviceFactory { + + private boolean tested = false; + + @Override + public synchronized AudioDevice createAudioDevice() + throws JavaLayerException { + + if (!tested) { + testAudioDevice(); + tested = true; + } + + return new MyJavaSoundAudioDevice(); + } + + private void testAudioDevice() throws JavaLayerException { + MyJavaSoundAudioDevice dev = new MyJavaSoundAudioDevice(); + dev.test(); + } +} diff --git a/libsrc/jlayer-1.0.2/src/test/resources/META-INF/services/javazoom.jl.player.AudioDeviceFactory b/libsrc/jlayer-1.0.2/src/test/resources/META-INF/services/javazoom.jl.player.AudioDeviceFactory new file mode 100644 index 000000000..23e0e32a6 --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/test/resources/META-INF/services/javazoom.jl.player.AudioDeviceFactory @@ -0,0 +1 @@ +javazoom.jl.player.my.MyJavaSoundAudioDeviceFactory \ No newline at end of file diff --git a/libsrc/jlayer-1.0.2/src/test/resources/logging.properties b/libsrc/jlayer-1.0.2/src/test/resources/logging.properties new file mode 100644 index 000000000..465833e8c --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/test/resources/logging.properties @@ -0,0 +1,7 @@ +handlers=java.util.logging.ConsoleHandler +.level=INFO +java.util.logging.ConsoleHandler.level=ALL +java.util.logging.ConsoleHandler.formatter=vavi.util.logging.VaviFormatter + +#vavi.util.level=FINE +#javazoom.jl.level=FINE \ No newline at end of file diff --git a/libsrc/jlayer-1.0.2/src/test/resources/test.mp3 b/libsrc/jlayer-1.0.2/src/test/resources/test.mp3 new file mode 100644 index 000000000..52191305c Binary files /dev/null and b/libsrc/jlayer-1.0.2/src/test/resources/test.mp3 differ diff --git a/libsrc/jlayer-1.0.2/src/test/resources/test.mp3.properties b/libsrc/jlayer-1.0.2/src/test/resources/test.mp3.properties new file mode 100644 index 000000000..2f13b7c7d --- /dev/null +++ b/libsrc/jlayer-1.0.2/src/test/resources/test.mp3.properties @@ -0,0 +1,29 @@ +# MP3 file +basefile=src/test/resources/ +filename=test.mp3 +# BitStream properties +ID3v2Size=67 +version=1 +version_string=MPEG-1 +layer=3 +frequency=44100 +frequency_string=44.1 kHz +bitrate=192000 +bitrate_string=192 kbit/s +mode=0 +mode_string=Stereo +slots=588 +vbr=false +vbr_scale=0 +max_number_of_frames=14276 +min_number_of_frames=14253 +ms_per_frame=26.12245 +frames_per_second=38.28125 +total_ms=372924.1 +SyncHeader=-348160 +checksums=true +copyright=false +original=false +padding=false +framesize=622 +number_of_subbands=30 \ No newline at end of file diff --git a/nbproject/project.xml b/nbproject/project.xml index a95ea1bc4..ce00f293b 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -320,7 +320,7 @@ src - lib/LZMA.jar;lib/jpproxy.jar;lib/trident-6.2.jar;lib/substance-flamingo-6.2.jar;lib/flamingo-6.2.jar;lib/substance-6.2.jar;lib/jl1.0.1.jar;lib/nellymoser.jar;lib/gif.jar;lib/avi.jar;lib/ttf.jar;lib/jpacker.jar;lib/sfntly.jar;lib/gnujpdf.jar;libsrc/ffdec_lib/src;lib/tablelayout.jar;lib/jsyntaxpane-0.9.5.jar;lib/JavactiveX.jar;lib/flashdebugger.jar;lib/treetable.jar;lib/minimal-json-0.9.5.jar;lib/graphs.jar;lib/vlcj-4.7.3.jar;lib/jna-3.5.1.jar;lib/jna-platform-3.5.1.jar + lib/LZMA.jar;lib/jpproxy.jar;lib/trident-6.2.jar;lib/substance-flamingo-6.2.jar;lib/flamingo-6.2.jar;lib/substance-6.2.jar;lib/nellymoser.jar;lib/gif.jar;lib/avi.jar;lib/ttf.jar;lib/jpacker.jar;lib/sfntly.jar;lib/gnujpdf.jar;libsrc/ffdec_lib/src;lib/tablelayout.jar;lib/jsyntaxpane-0.9.5.jar;lib/JavactiveX.jar;lib/flashdebugger.jar;lib/treetable.jar;lib/minimal-json-0.9.5.jar;lib/graphs.jar;lib/vlcj-4.7.3.jar;lib/jna-3.5.1.jar;lib/jna-platform-3.5.1.jar;lib/jlayer-1.0.2.jar build javadoc reports