forked from len0rd/rockbox
Initial commit of Monkey's Audio (.ape/.mac) support. Note that Monkey's is an extremely CPU-intensive codec, and that the decoding speed is directly related to the compression level (-c1000, -c2000, -c3000, -c4000 or -c5000) used when encoding the file. Current performance is: -c1000 to -c3000 are realtime on a Gigabeat, -c1000 is realtime on Coldfire targets (H100, H300 and Cowon), and nothing is realtime on PortalPlayer targets (iPods, H10, Sansa). Hopefully this can be improved. More information at FS #7256.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13562 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
887b31c01a
commit
520274219a
36 changed files with 3413 additions and 23 deletions
|
|
@ -17,7 +17,7 @@ ifdef APPEXTRA
|
|||
endif
|
||||
|
||||
ifdef SOFTWARECODECS
|
||||
CODECLIBS = -lmad -la52 -lffmpegFLAC -lTremor -lwavpack -lmusepack -lalac -lfaad -lm4a -lspeex
|
||||
CODECLIBS = -lmad -la52 -lffmpegFLAC -lTremor -lwavpack -lmusepack -lalac -lfaad -lm4a -lspeex -ldemac
|
||||
endif
|
||||
|
||||
# we "borrow" the plugin LDS file
|
||||
|
|
@ -39,7 +39,7 @@ DIRS = .
|
|||
|
||||
CODECDEPS = $(LINKCODEC) $(BUILDDIR)/libcodec.a
|
||||
|
||||
.PHONY: libmad liba52 libffmpegFLAC libTremor libspeex libwavpack libmusepack libalac libfaad libm4a
|
||||
.PHONY: libmad liba52 libffmpegFLAC libTremor libspeex libwavpack libmusepack libalac libfaad libm4a libdemac
|
||||
|
||||
OUTPUT = $(SOFTWARECODECS)
|
||||
|
||||
|
|
@ -64,6 +64,7 @@ $(OBJDIR)/wavpack.elf : $(OBJDIR)/wavpack.o $(BUILDDIR)/libwavpack.a $(OBJDIR)/c
|
|||
$(OBJDIR)/alac.elf : $(OBJDIR)/alac.o $(BUILDDIR)/libalac.a $(BUILDDIR)/libm4a.a $(OBJDIR)/codec_crt0.o
|
||||
$(OBJDIR)/aac.elf : $(OBJDIR)/aac.o $(BUILDDIR)/libfaad.a $(BUILDDIR)/libm4a.a $(OBJDIR)/codec_crt0.o
|
||||
$(OBJDIR)/shorten.elf : $(OBJDIR)/shorten.o $(BUILDDIR)/libffmpegFLAC.a $(OBJDIR)/codec_crt0.o
|
||||
$(OBJDIR)/ape.elf : $(OBJDIR)/ape.o $(BUILDDIR)/libdemac.a $(OBJDIR)/codec_crt0.o
|
||||
$(OBJDIR)/aiff_enc.elf: $(OBJDIR)/aiff_enc.o $(OBJDIR)/codec_crt0.o
|
||||
$(OBJDIR)/mp3_enc.elf: $(OBJDIR)/mp3_enc.o $(OBJDIR)/codec_crt0.o
|
||||
$(OBJDIR)/wav_enc.elf: $(OBJDIR)/wav_enc.o $(OBJDIR)/codec_crt0.o
|
||||
|
|
@ -198,18 +199,25 @@ libfaad:
|
|||
$(SILENT)mkdir -p $(OBJDIR)/libfaad
|
||||
$(call PRINTS,MAKE in libfaad)$(MAKE) -C libfaad OBJDIR=$(OBJDIR)/libfaad OUTPUT=$(BUILDDIR)/libfaad.a
|
||||
|
||||
$(BUILDDIR)/libdemac.a: libdemac
|
||||
|
||||
libdemac:
|
||||
$(SILENT)mkdir -p $(OBJDIR)/libdemac
|
||||
$(call PRINTS,MAKE in libdemac)$(MAKE) -C demac/libdemac OBJDIR=$(OBJDIR)/libdemac OUTPUT=$(BUILDDIR)/libdemac.a
|
||||
|
||||
clean:
|
||||
$(call PRINTS,cleaning codecs)rm -fr $(OBJDIR)/libmad $(BUILDDIR)/libmad.a $(OBJDIR)/liba52 $(BUILDDIR)/liba52.a $(OBJDIR)/libffmpegFLAC $(BUILDDIR)/libffmpegFLAC.a $(OBJDIR)/Tremor $(BUILDDIR)/libTremor.a $(OBJDIR)/libspeex $(BUILDDIR)/libSpeex.a $(OBJDIR)/libwavpack $(BUILDDIR)/libwavpack.a $(OBJDIR)/libmusepack $(BUILDDIR)/libmusepack.a $(OBJDIR)/libalac $(BUILDDIR)/libalac.a $(OBJDIR)/libfaad $(BUILDDIR)/libfaad.a $(OBJDIR)/libm4a $(BUILDDIR)/libm4a.a
|
||||
$(call PRINTS,cleaning codecs)rm -fr $(OBJDIR)/libmad $(BUILDDIR)/libmad.a $(OBJDIR)/liba52 $(BUILDDIR)/liba52.a $(OBJDIR)/libffmpegFLAC $(BUILDDIR)/libffmpegFLAC.a $(OBJDIR)/Tremor $(BUILDDIR)/libTremor.a $(OBJDIR)/libspeex $(BUILDDIR)/libSpeex.a $(OBJDIR)/libwavpack $(BUILDDIR)/libwavpack.a $(OBJDIR)/libmusepack $(BUILDDIR)/libmusepack.a $(OBJDIR)/libalac $(BUILDDIR)/libalac.a $(OBJDIR)/libfaad $(BUILDDIR)/libfaad.a $(OBJDIR)/libm4a $(BUILDDIR)/libm4a.a $(OBJDIR)/libdemac $(BUILDDIR)/libdemac.a
|
||||
$(SILENT)$(MAKE) -C libmad clean OBJDIR=$(OBJDIR)/libmad
|
||||
$(SILENT)$(MAKE) -C liba52 clean OBJDIR=$(OBJDIR)/liba52
|
||||
$(SILENT)$(MAKE) -C libffmpegFLAC clean OBJDIR=$(OBJDIR)/libffmpegFLAC
|
||||
$(SILENT)$(MAKE) -C Tremor clean OBJDIR=$(OBJDIR)/Tremor
|
||||
$(SILENT)$(MAKE) -C libspeex clean OBJDIR=$(OBJDIR)/libspeex
|
||||
$(SILENT)$(MAKE) -C libspeex clean OBJDIR=$(OBJDIR)/libspeex
|
||||
$(SILENT)$(MAKE) -C libwavpack clean OBJDIR=$(OBJDIR)/libwavpack
|
||||
$(SILENT)$(MAKE) -C libmusepack clean OBJDIR=$(OBJDIR)/libmusepack
|
||||
$(SILENT)$(MAKE) -C libalac clean OBJDIR=$(OBJDIR)/libalac
|
||||
$(SILENT)$(MAKE) -C libfaad clean OBJDIR=$(OBJDIR)/libfaad
|
||||
$(SILENT)$(MAKE) -C libm4a clean OBJDIR=$(OBJDIR)/libm4a
|
||||
$(SILENT)$(MAKE) -C demac/libdemac clean OBJDIR=$(OBJDIR)/libdemac
|
||||
$(SILENT)$(MAKE) -C lib clean OBJDIR=$(OBJDIR)/lib
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ alac.c
|
|||
#if MEMORYSIZE > 1
|
||||
aac.c
|
||||
#endif
|
||||
ape.c
|
||||
shorten.c
|
||||
aiff.c
|
||||
speex.c
|
||||
|
|
|
|||
162
apps/codecs/ape.c
Normal file
162
apps/codecs/ape.c
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 Dave Chapman
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "codeclib.h"
|
||||
#define ROCKBOX
|
||||
#include <codecs/demac/libdemac/demac.h>
|
||||
|
||||
CODEC_HEADER
|
||||
|
||||
#define BLOCKS_PER_LOOP 4608
|
||||
#define MAX_CHANNELS 2
|
||||
#define MAX_BYTESPERSAMPLE 3
|
||||
|
||||
#define INPUT_CHUNKSIZE (32*1024)
|
||||
|
||||
/* 4608*4 = 18432 bytes per channel */
|
||||
static int32_t decoded0[BLOCKS_PER_LOOP] IBSS_ATTR;
|
||||
static int32_t decoded1[BLOCKS_PER_LOOP] IBSS_ATTR;
|
||||
|
||||
#define MAX_SUPPORTED_SEEKTABLE_SIZE 5000
|
||||
|
||||
/* this is the codec entry point */
|
||||
enum codec_status codec_main(void)
|
||||
{
|
||||
struct ape_ctx_t ape_ctx;
|
||||
uint32_t samplesdone;
|
||||
uint32_t elapsedtime;
|
||||
size_t bytesleft;
|
||||
int retval;
|
||||
|
||||
uint32_t currentframe;
|
||||
int nblocks;
|
||||
int bytesconsumed;
|
||||
unsigned char* inbuffer;
|
||||
int blockstodecode;
|
||||
int res;
|
||||
int firstbyte;
|
||||
|
||||
/* Generic codec initialisation */
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
||||
ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, 1024*128);
|
||||
|
||||
ci->configure(DSP_SET_SAMPLE_DEPTH, APE_OUTPUT_DEPTH-1);
|
||||
|
||||
next_track:
|
||||
|
||||
if (codec_init()) {
|
||||
LOGF("APE: Error initialising codec\n");
|
||||
retval = CODEC_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE);
|
||||
|
||||
/* Read the file headers to populate the ape_ctx struct */
|
||||
if (ape_parseheaderbuf(inbuffer,&ape_ctx) < 0) {
|
||||
LOGF("APE: Error reading header\n");
|
||||
retval = CODEC_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
ci->advance_buffer(ape_ctx.firstframe);
|
||||
|
||||
while (!*ci->taginfo_ready && !ci->stop_codec)
|
||||
ci->sleep(1);
|
||||
|
||||
ci->configure(DSP_SWITCH_FREQUENCY, ape_ctx.samplerate);
|
||||
ci->configure(DSP_SET_STEREO_MODE, ape_ctx.channels == 1 ?
|
||||
STEREO_MONO : STEREO_NONINTERLEAVED);
|
||||
codec_set_replaygain(ci->id3);
|
||||
|
||||
/* The main decoding loop */
|
||||
|
||||
currentframe = 0;
|
||||
samplesdone = 0;
|
||||
|
||||
/* Initialise the buffer */
|
||||
inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE);
|
||||
firstbyte = 3; /* Take account of the little-endian 32-bit byte ordering */
|
||||
|
||||
/* The main decoding loop - we decode the frames a small chunk at a time */
|
||||
while (currentframe < ape_ctx.totalframes)
|
||||
{
|
||||
/* Calculate how many blocks there are in this frame */
|
||||
if (currentframe == (ape_ctx.totalframes - 1))
|
||||
nblocks = ape_ctx.finalframeblocks;
|
||||
else
|
||||
nblocks = ape_ctx.blocksperframe;
|
||||
|
||||
ape_ctx.currentframeblocks = nblocks;
|
||||
|
||||
/* Initialise the frame decoder */
|
||||
init_frame_decoder(&ape_ctx, inbuffer, &firstbyte, &bytesconsumed);
|
||||
|
||||
ci->advance_buffer(bytesconsumed);
|
||||
inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE);
|
||||
|
||||
/* Decode the frame a chunk at a time */
|
||||
while (nblocks > 0)
|
||||
{
|
||||
ci->yield();
|
||||
if (ci->stop_codec || ci->new_track) {
|
||||
break;
|
||||
}
|
||||
|
||||
blockstodecode = MIN(BLOCKS_PER_LOOP, nblocks);
|
||||
|
||||
if ((res = decode_chunk(&ape_ctx, inbuffer, &firstbyte,
|
||||
&bytesconsumed,
|
||||
decoded0, decoded1,
|
||||
blockstodecode)) < 0)
|
||||
{
|
||||
/* Frame decoding error, abort */
|
||||
LOGF("APE: Frame %d, error %d\n",currentframe,res);
|
||||
retval = CODEC_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ci->yield();
|
||||
ci->pcmbuf_insert(decoded0, decoded1, blockstodecode);
|
||||
|
||||
/* Update the elapsed-time indicator */
|
||||
samplesdone += blockstodecode;
|
||||
elapsedtime = (samplesdone*10)/(ape_ctx.samplerate/100);
|
||||
ci->set_elapsed(elapsedtime);
|
||||
|
||||
ci->advance_buffer(bytesconsumed);
|
||||
inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE);
|
||||
|
||||
/* Decrement the block count */
|
||||
nblocks -= blockstodecode;
|
||||
}
|
||||
|
||||
currentframe++;
|
||||
}
|
||||
|
||||
retval = CODEC_OK;
|
||||
|
||||
done:
|
||||
LOGF("APE: Decoded %ld samples\n",samplesdone);
|
||||
|
||||
if (ci->request_next_track())
|
||||
goto next_track;
|
||||
|
||||
exit:
|
||||
return retval;
|
||||
}
|
||||
339
apps/codecs/demac/COPYING
Normal file
339
apps/codecs/demac/COPYING
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, 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 or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
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 give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
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 Program or any portion
|
||||
of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
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 Program, 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 Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) 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; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, 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 executable. However, as a
|
||||
special exception, the source code 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.
|
||||
|
||||
If distribution of executable or 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 counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program 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.
|
||||
|
||||
5. 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 Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program 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 to
|
||||
this License.
|
||||
|
||||
7. 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 Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program 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 Program.
|
||||
|
||||
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.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program 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.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the 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 Program
|
||||
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 Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, 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
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), 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 Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. 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.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
43
apps/codecs/demac/Makefile
Normal file
43
apps/codecs/demac/Makefile
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# $Id:$
|
||||
|
||||
FILTERS = libdemac/filter_16_11.o libdemac/filter_64_11.o libdemac/filter_256_13.o libdemac/filter_32_10.o libdemac/filter_1280_15.o
|
||||
LIBOBJS = libdemac/parser.o libdemac/decoder.o libdemac/entropy.o libdemac/predictor.o libdemac/crc.o $(FILTERS)
|
||||
OBJS = demac.o wavwrite.o $(LIBOBJS)
|
||||
|
||||
CFLAGS = -Wall -O3 -Ilibdemac
|
||||
|
||||
ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
|
||||
EXT = .exe
|
||||
CROSS =
|
||||
CFLAGS += -mno-cygwin
|
||||
else
|
||||
ifdef WIN
|
||||
EXT = .exe
|
||||
CROSS = i586-mingw32msvc-
|
||||
else
|
||||
EXT =
|
||||
CROSS =
|
||||
endif
|
||||
endif
|
||||
|
||||
CC = $(CROSS)gcc
|
||||
STRIP = $(CROSS)strip
|
||||
OUTPUT = demac$(EXT)
|
||||
|
||||
all: $(OUTPUT)
|
||||
|
||||
$(OUTPUT): $(OBJS)
|
||||
$(CC) -o $(OUTPUT) $(OBJS)
|
||||
|
||||
.c.o :
|
||||
$(CC) $(CFLAGS) $(INC) -c -o $@ $<
|
||||
|
||||
libdemac/filter_16_11.o: libdemac/filter.c
|
||||
libdemac/filter_64_11.o: libdemac/filter.c
|
||||
libdemac/filter_256_13.o: libdemac/filter.c
|
||||
libdemac/filter_1280_15.o: libdemac/filter.c
|
||||
libdemac/filter_32_10.o: libdemac/filter.c
|
||||
libdemac/entropy.o: libdemac/rangecoding.h
|
||||
|
||||
clean:
|
||||
rm -f $(OUTPUT) $(OBJS) *~ */*~
|
||||
69
apps/codecs/demac/README
Normal file
69
apps/codecs/demac/README
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
demac - a decoder for Monkey's Audio files.
|
||||
|
||||
Introduction
|
||||
|
||||
demac is an implementation in portable ANSI C of a decoder for the
|
||||
Monkey's Audio lossless compression format. It has the following
|
||||
features:
|
||||
|
||||
* Open source (GNU GPL)
|
||||
* Written in portable ANSI C
|
||||
* Designed for use on low memory and embedded devices. All internal
|
||||
buffers are statically declared - the core library doesn't require
|
||||
malloc/free. This has the disadvantage that the library isn't
|
||||
re-entrant.
|
||||
|
||||
|
||||
Compatibility
|
||||
|
||||
|
||||
libdemac is still in the early stages of development but has been
|
||||
relatively well tested with v3.99 files at all compression levels.
|
||||
|
||||
v3.97 files have received less testing - 16-bit files seem to work,
|
||||
but 24-bit files are causing problems in the range decoder.
|
||||
|
||||
Files earlier than v3.97 are not supported by libdemac, but support
|
||||
might be added in the future.
|
||||
|
||||
|
||||
Source Code
|
||||
|
||||
The source code in this directory is structured as follows:
|
||||
|
||||
demac/Makefile - Makefile for the standalone demac decoder
|
||||
demac/demac.c - Simple standalone test program to decoder an APE file to WAV
|
||||
demac/wavwrite.[ch] - Helper functions for demac.c
|
||||
demac/libdemac/Makefile - A Makefile for use in Rockbox
|
||||
demac/libdemac/*.[ch] - The main libdemac code
|
||||
|
||||
|
||||
Latest Version
|
||||
|
||||
The latest version of demac and libdemac can always be found in the
|
||||
"apps/codecs/demac/" directory in the Rockbox source. You can check
|
||||
this out from svn with the command:
|
||||
|
||||
svn co svn://svn.rockbox.org/rockbox/trunk/apps/codecs/demac demac
|
||||
|
||||
Or browse the source code online here:
|
||||
|
||||
http://svn.rockbox.org/viewvc.cgi/trunk/apps/codecs/demac
|
||||
|
||||
|
||||
|
||||
Acknowledgements
|
||||
|
||||
Thanks to Matt. T. Ashland for writing Monkey's Audio. His website
|
||||
can be found here: http://www.monkeysaudio.com
|
||||
|
||||
|
||||
Copyright and license
|
||||
|
||||
|
||||
libdemac is (C) 2007 Dave Chapman and is licensed under the GNU
|
||||
GPL. See the COPYING file in this directory.
|
||||
|
||||
The exception is the majority of rangecoding.h, which is (C) 1997,
|
||||
1998, 1999, 2000 Michael Schindler and is also licensed under the GPL.
|
||||
See that source file for full details.
|
||||
272
apps/codecs/demac/demac.c
Normal file
272
apps/codecs/demac/demac.c
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
|
||||
demac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This example is intended to demonstrate how the decoder can be used in
|
||||
embedded devices - there is no usage of dynamic memory (i.e. no
|
||||
malloc/free) and small buffer sizes are chosen to minimise both the
|
||||
memory usage and decoding latency.
|
||||
|
||||
This implementation requires the following memory and supports decoding of all APE files up to 24-bit Stereo.
|
||||
|
||||
32768 - data from the input stream to be presented to the decoder in one contiguous chunk.
|
||||
18432 - decoding buffer (left channel)
|
||||
18432 - decoding buffer (right channel)
|
||||
|
||||
17408+5120+2240 - buffers used for filter histories (compression levels 2000-5000)
|
||||
|
||||
In addition, this example uses a static 27648 byte buffer as temporary
|
||||
storage for outputting the data to a WAV file but that could be
|
||||
avoided by writing the decoded data one sample at a time.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "demac.h"
|
||||
#include "wavwrite.h"
|
||||
|
||||
#ifndef __WIN32__
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#define CALC_CRC 1
|
||||
|
||||
#define BLOCKS_PER_LOOP 4608
|
||||
#define MAX_CHANNELS 2
|
||||
#define MAX_BYTESPERSAMPLE 3
|
||||
|
||||
#define INPUT_CHUNKSIZE (32*1024)
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
|
||||
/* 4608*2*3 = 27648 bytes */
|
||||
static unsigned char wavbuffer[BLOCKS_PER_LOOP*MAX_CHANNELS*MAX_BYTESPERSAMPLE];
|
||||
|
||||
/* 4608*4 = 18432 bytes per channel */
|
||||
static int32_t decoded0[BLOCKS_PER_LOOP];
|
||||
static int32_t decoded1[BLOCKS_PER_LOOP];
|
||||
|
||||
/* We assume that 32KB of compressed data is enough to extract up to
|
||||
27648 bytes of decompressed data. */
|
||||
|
||||
static unsigned char inbuffer[INPUT_CHUNKSIZE];
|
||||
|
||||
int ape_decode(char* infile, char* outfile)
|
||||
{
|
||||
int fd;
|
||||
int fdwav;
|
||||
int currentframe;
|
||||
int nblocks;
|
||||
int bytesconsumed;
|
||||
struct ape_ctx_t ape_ctx;
|
||||
int i, n;
|
||||
unsigned char* p;
|
||||
int bytesinbuffer;
|
||||
int blockstodecode;
|
||||
int res;
|
||||
int firstbyte;
|
||||
int16_t sample16;
|
||||
int32_t sample32;
|
||||
uint32_t frame_crc;
|
||||
int crc_errors = 0;
|
||||
|
||||
fd = open(infile,O_RDONLY|O_BINARY);
|
||||
if (fd < 0) return -1;
|
||||
|
||||
/* Read the file headers to populate the ape_ctx struct */
|
||||
if (ape_parseheader(fd,&ape_ctx) < 0) {
|
||||
printf("Cannot read header\n");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((ape_ctx.fileversion < APE_MIN_VERSION) || (ape_ctx.fileversion > APE_MAX_VERSION)) {
|
||||
printf("Unsupported file version - %.2f\n", ape_ctx.fileversion/1000.0);
|
||||
close(fd);
|
||||
return -2;
|
||||
}
|
||||
|
||||
//ape_dumpinfo(&ape_ctx);
|
||||
|
||||
printf("Decoding file - v%.2f, compression level %d\n",ape_ctx.fileversion/1000.0,ape_ctx.compressiontype);
|
||||
|
||||
/* Open the WAV file and write a canonical 44-byte WAV header
|
||||
based on the audio format information in the ape_ctx struct.
|
||||
|
||||
NOTE: This example doesn't write the original WAV header and
|
||||
tail data which are (optionally) stored in the APE file.
|
||||
*/
|
||||
fdwav = open_wav(&ape_ctx,outfile);
|
||||
|
||||
currentframe = 0;
|
||||
|
||||
/* Initialise the buffer */
|
||||
lseek(fd, ape_ctx.firstframe, SEEK_SET);
|
||||
bytesinbuffer = read(fd, inbuffer, INPUT_CHUNKSIZE);
|
||||
firstbyte = 3; /* Take account of the little-endian 32-bit byte ordering */
|
||||
|
||||
/* The main decoding loop - we decode the frames a small chunk at a time */
|
||||
while (currentframe < ape_ctx.totalframes)
|
||||
{
|
||||
/* Calculate how many blocks there are in this frame */
|
||||
if (currentframe == (ape_ctx.totalframes - 1))
|
||||
nblocks = ape_ctx.finalframeblocks;
|
||||
else
|
||||
nblocks = ape_ctx.blocksperframe;
|
||||
|
||||
ape_ctx.currentframeblocks = nblocks;
|
||||
|
||||
/* Initialise the frame decoder */
|
||||
init_frame_decoder(&ape_ctx, inbuffer, &firstbyte, &bytesconsumed);
|
||||
|
||||
/* Update buffer */
|
||||
memmove(inbuffer,inbuffer + bytesconsumed, bytesinbuffer - bytesconsumed);
|
||||
bytesinbuffer -= bytesconsumed;
|
||||
|
||||
n = read(fd, inbuffer + bytesinbuffer, INPUT_CHUNKSIZE - bytesinbuffer);
|
||||
bytesinbuffer += n;
|
||||
|
||||
#if CALC_CRC
|
||||
frame_crc = ape_initcrc();
|
||||
#endif
|
||||
|
||||
/* Decode the frame a chunk at a time */
|
||||
while (nblocks > 0)
|
||||
{
|
||||
blockstodecode = MIN(BLOCKS_PER_LOOP, nblocks);
|
||||
|
||||
if ((res = decode_chunk(&ape_ctx, inbuffer, &firstbyte,
|
||||
&bytesconsumed,
|
||||
decoded0, decoded1,
|
||||
blockstodecode)) < 0)
|
||||
{
|
||||
/* Frame decoding error, abort */
|
||||
close(fd);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Convert the output samples to WAV format and write to output file */
|
||||
p = wavbuffer;
|
||||
if (ape_ctx.bps == 16) {
|
||||
for (i = 0 ; i < blockstodecode ; i++)
|
||||
{
|
||||
sample16 = decoded0[i];
|
||||
*(p++) = sample16 & 0xff;
|
||||
*(p++) = (sample16&0xff00) >> 8;
|
||||
|
||||
if (ape_ctx.channels == 2) {
|
||||
sample16 = decoded1[i];
|
||||
*(p++) = sample16 & 0xff;
|
||||
*(p++) = (sample16&0xff00) >> 8;
|
||||
}
|
||||
}
|
||||
} else if (ape_ctx.bps == 24) {
|
||||
for (i = 0 ; i < blockstodecode ; i++)
|
||||
{
|
||||
sample32 = decoded0[i];
|
||||
*(p++) = sample32 & 0xff;
|
||||
*(p++) = (sample32&0xff00) >> 8;
|
||||
*(p++) = (sample32&0xff0000) >> 16;
|
||||
|
||||
if (ape_ctx.channels == 2) {
|
||||
sample32 = decoded1[i];
|
||||
*(p++) = sample32 & 0xff;
|
||||
*(p++) = (sample32&0xff00) >> 8;
|
||||
*(p++) = (sample32&0xff0000) >> 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if CALC_CRC
|
||||
frame_crc = ape_updatecrc(wavbuffer, p - wavbuffer, frame_crc);
|
||||
#endif
|
||||
write(fdwav,wavbuffer,p - wavbuffer);
|
||||
|
||||
/* Update the buffer */
|
||||
memmove(inbuffer,inbuffer + bytesconsumed, bytesinbuffer - bytesconsumed);
|
||||
bytesinbuffer -= bytesconsumed;
|
||||
|
||||
n = read(fd, inbuffer + bytesinbuffer, INPUT_CHUNKSIZE - bytesinbuffer);
|
||||
bytesinbuffer += n;
|
||||
|
||||
/* Decrement the block count */
|
||||
nblocks -= blockstodecode;
|
||||
}
|
||||
|
||||
#if CALC_CRC
|
||||
frame_crc = ape_finishcrc(frame_crc);
|
||||
|
||||
if (ape_ctx.CRC != frame_crc)
|
||||
{
|
||||
fprintf(stderr,"CRC error in frame %d\n",currentframe);
|
||||
crc_errors++;
|
||||
}
|
||||
#endif
|
||||
|
||||
currentframe++;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
close(fdwav);
|
||||
|
||||
if (crc_errors > 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int res;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr,"Usage: demac infile.ape outfile.wav\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
res = ape_decode(argv[1], argv[2]);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
fprintf(stderr,"DECODING ERROR %d, ABORTING\n", res);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"DECODED OK - NO CRC ERRORS.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
43
apps/codecs/demac/libdemac/Makefile
Normal file
43
apps/codecs/demac/libdemac/Makefile
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# __________ __ ___.
|
||||
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
# \/ \/ \/ \/ \/
|
||||
# $Id:$
|
||||
#
|
||||
|
||||
INCLUDES=-I$(APPSDIR) -I.. -I. -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
|
||||
-I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(BUILDDIR)
|
||||
|
||||
ifdef APPEXTRA
|
||||
INCLUDES += $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA)))
|
||||
endif
|
||||
|
||||
DEMACOPTS = -O3 -DROCKBOX
|
||||
CFLAGS = $(INCLUDES) $(GCCOPTS) $(TARGET_INC) $(DEMACOPTS) $(TARGET) \
|
||||
$(EXTRA_DEFINES) -DMEM=${MEMORYSIZE} $(PROFILE_OPTS)
|
||||
|
||||
# This sets up 'SRC' based on the files mentioned in SOURCES
|
||||
include $(TOOLSDIR)/makesrc.inc
|
||||
|
||||
SOURCES = $(SRC)
|
||||
OBJS2 := $(SRC:%.c=$(OBJDIR)/%.o)
|
||||
OBJS = $(patsubst %.S, $(OBJDIR)/%.o, $(OBJS2))
|
||||
DEPFILE = $(OBJDIR)/dep-libdemac
|
||||
DIRS =
|
||||
|
||||
all: $(OUTPUT)
|
||||
|
||||
$(OUTPUT): $(OBJS)
|
||||
$(call PRINTS,AR+RANLIB $(@F))$(AR) ruv $@ $+ >/dev/null 2>&1
|
||||
$(SILENT)$(RANLIB) $@
|
||||
|
||||
include $(TOOLSDIR)/make.inc
|
||||
|
||||
clean:
|
||||
$(call PRINTS,cleaning libdemac)rm -f $(OBJS) $(OUTPUT) $(DEPFILE)
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
-include $(DEPFILE)
|
||||
endif
|
||||
10
apps/codecs/demac/libdemac/SOURCES
Normal file
10
apps/codecs/demac/libdemac/SOURCES
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
crc.c
|
||||
predictor.c
|
||||
entropy.c
|
||||
decoder.c
|
||||
parser.c
|
||||
filter_1280_15.c
|
||||
filter_16_11.c
|
||||
filter_256_13.c
|
||||
filter_32_10.c
|
||||
filter_64_11.c
|
||||
119
apps/codecs/demac/libdemac/crc.c
Normal file
119
apps/codecs/demac/libdemac/crc.c
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
static uint32_t crctab32[] =
|
||||
{
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
|
||||
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
|
||||
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
||||
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
|
||||
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
||||
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
|
||||
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
||||
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
|
||||
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
|
||||
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
||||
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
|
||||
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
|
||||
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
||||
|
||||
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
|
||||
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
||||
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
|
||||
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
||||
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
|
||||
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
||||
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
|
||||
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
||||
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
|
||||
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
||||
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
|
||||
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
|
||||
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
|
||||
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
||||
|
||||
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
|
||||
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
||||
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
|
||||
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
||||
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
|
||||
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
||||
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
|
||||
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
||||
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
|
||||
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
|
||||
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
||||
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
|
||||
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
||||
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
|
||||
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
||||
|
||||
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
|
||||
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
||||
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
|
||||
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
|
||||
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
|
||||
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
|
||||
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
|
||||
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
||||
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
|
||||
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
|
||||
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
||||
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
|
||||
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||
};
|
||||
|
||||
uint32_t ape_initcrc(void)
|
||||
{
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
/* Update the CRC from a block of WAV-format audio data */
|
||||
uint32_t ape_updatecrc(unsigned char *block, int count, uint32_t crc)
|
||||
{
|
||||
while (count--)
|
||||
crc = (crc >> 8) ^ crctab32[(crc & 0xff) ^ *block++];
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
uint32_t ape_finishcrc(uint32_t crc)
|
||||
{
|
||||
crc ^= 0xffffffff;
|
||||
crc >>= 1;
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
184
apps/codecs/demac/libdemac/decoder.c
Normal file
184
apps/codecs/demac/libdemac/decoder.c
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "demac.h"
|
||||
#include "predictor.h"
|
||||
#include "entropy.h"
|
||||
#include "filter.h"
|
||||
|
||||
/* Statically allocate the filter buffers */
|
||||
|
||||
static int16_t filterbuf32[(32*3 + HISTORY_SIZE) * 2] IBSS_ATTR; /* 4480 bytes */
|
||||
static int16_t filterbuf256[(256*3 + HISTORY_SIZE) * 2] IBSS_ATTR; /* 5120 bytes */
|
||||
|
||||
/* This is only needed for "insane" files, and no Rockbox targets can
|
||||
hope to decode them in realtime anyway. */
|
||||
static int16_t filterbuf1280[(1280*3 + HISTORY_SIZE) * 2]; /* 17408 bytes */
|
||||
|
||||
void init_frame_decoder(struct ape_ctx_t* ape_ctx,
|
||||
unsigned char* inbuffer, int* firstbyte,
|
||||
int* bytesconsumed)
|
||||
{
|
||||
init_entropy_decoder(ape_ctx, inbuffer, firstbyte, bytesconsumed);
|
||||
//printf("CRC=0x%08x\n",ape_ctx->CRC);
|
||||
//printf("Flags=0x%08x\n",ape_ctx->frameflags);
|
||||
|
||||
init_predictor_decoder(ape_ctx);
|
||||
|
||||
switch (ape_ctx->compressiontype)
|
||||
{
|
||||
case 2000:
|
||||
init_filter_16_11(filterbuf32);
|
||||
break;
|
||||
|
||||
case 3000:
|
||||
init_filter_64_11(filterbuf256);
|
||||
break;
|
||||
|
||||
case 4000:
|
||||
init_filter_256_13(filterbuf256);
|
||||
init_filter_32_10(filterbuf32);
|
||||
break;
|
||||
|
||||
case 5000:
|
||||
init_filter_1280_15(filterbuf1280);
|
||||
init_filter_256_13(filterbuf256);
|
||||
init_filter_16_11(filterbuf32);
|
||||
}
|
||||
}
|
||||
|
||||
int decode_chunk(struct ape_ctx_t* ape_ctx,
|
||||
unsigned char* inbuffer, int* firstbyte,
|
||||
int* bytesconsumed,
|
||||
int32_t* decoded0, int32_t* decoded1,
|
||||
int count)
|
||||
{
|
||||
int res;
|
||||
int32_t left, right;
|
||||
#ifdef ROCKBOX
|
||||
int scale = (APE_OUTPUT_DEPTH - ape_ctx->bps);
|
||||
#define SCALE(x) ((x) << scale)
|
||||
#else
|
||||
#define SCALE(x) (x)
|
||||
#endif
|
||||
|
||||
if ((ape_ctx->channels==1) || (ape_ctx->frameflags & APE_FRAMECODE_PSEUDO_STEREO)) {
|
||||
if (ape_ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {
|
||||
res = entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed, decoded0, decoded1, count);
|
||||
/* We are pure silence, so we're done. */
|
||||
return 0;
|
||||
} else {
|
||||
res = entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed, decoded0, NULL, count);
|
||||
}
|
||||
|
||||
switch (ape_ctx->compressiontype)
|
||||
{
|
||||
case 2000:
|
||||
apply_filter_16_11(ape_ctx->fileversion,decoded0,NULL,count);
|
||||
break;
|
||||
|
||||
case 3000:
|
||||
apply_filter_64_11(ape_ctx->fileversion,decoded0,NULL,count);
|
||||
break;
|
||||
|
||||
case 4000:
|
||||
apply_filter_32_10(ape_ctx->fileversion,decoded0,NULL,count);
|
||||
apply_filter_256_13(ape_ctx->fileversion,decoded0,NULL,count);
|
||||
break;
|
||||
|
||||
case 5000:
|
||||
apply_filter_16_11(ape_ctx->fileversion,decoded0,NULL,count);
|
||||
apply_filter_256_13(ape_ctx->fileversion,decoded0,NULL,count);
|
||||
apply_filter_1280_15(ape_ctx->fileversion,decoded0,NULL,count);
|
||||
}
|
||||
|
||||
/* Now apply the predictor decoding */
|
||||
predictor_decode_mono(ape_ctx,decoded0,count);
|
||||
|
||||
if (ape_ctx->channels==2) {
|
||||
/* Pseudo-stereo - just copy left channel to right channel */
|
||||
while (count--)
|
||||
{
|
||||
left = *decoded0;
|
||||
*(decoded1++) = *(decoded0++) = SCALE(left);
|
||||
}
|
||||
} else {
|
||||
/* Mono - do nothing unless it's 8-bit audio */
|
||||
if (ape_ctx->bps == 8) {
|
||||
/* TODO: Handle 8-bit streams */
|
||||
}
|
||||
}
|
||||
} else { /* Stereo */
|
||||
if (ape_ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {
|
||||
/* We are pure silence, so we're done. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
res = entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed, decoded0, decoded1, count);
|
||||
|
||||
/* Apply filters - compression type 1000 doesn't have any */
|
||||
switch (ape_ctx->compressiontype)
|
||||
{
|
||||
case 2000:
|
||||
apply_filter_16_11(ape_ctx->fileversion,decoded0,decoded1,count);
|
||||
break;
|
||||
|
||||
case 3000:
|
||||
apply_filter_64_11(ape_ctx->fileversion,decoded0,decoded1,count);
|
||||
break;
|
||||
|
||||
case 4000:
|
||||
apply_filter_32_10(ape_ctx->fileversion,decoded0,decoded1,count);
|
||||
apply_filter_256_13(ape_ctx->fileversion,decoded0,decoded1,count);
|
||||
break;
|
||||
|
||||
case 5000:
|
||||
apply_filter_16_11(ape_ctx->fileversion,decoded0,decoded1,count);
|
||||
apply_filter_256_13(ape_ctx->fileversion,decoded0,decoded1,count);
|
||||
apply_filter_1280_15(ape_ctx->fileversion,decoded0,decoded1,count);
|
||||
}
|
||||
|
||||
/* Now apply the predictor decoding */
|
||||
predictor_decode_stereo(ape_ctx,decoded0,decoded1,count);
|
||||
|
||||
if (ape_ctx->bps == 8) {
|
||||
/* TODO: Handle 8-bit streams */
|
||||
} else {
|
||||
/* Decorrelate and scale to output depth */
|
||||
while (count--)
|
||||
{
|
||||
left = *decoded1 - (*decoded0 / 2);
|
||||
right = left + *decoded0;
|
||||
|
||||
*(decoded0++) = SCALE(left);
|
||||
*(decoded1++) = SCALE(right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
40
apps/codecs/demac/libdemac/decoder.h
Normal file
40
apps/codecs/demac/libdemac/decoder.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _APE_DECODER_H
|
||||
#define _APE_DECODER_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "parser.h"
|
||||
|
||||
void init_frame_decoder(struct ape_ctx_t* ape_ctx,
|
||||
unsigned char* inbuffer, int* firstbyte,
|
||||
int* bytesconsumed);
|
||||
|
||||
int decode_chunk(struct ape_ctx_t* ape_ctx,
|
||||
unsigned char* inbuffer, int* firstbyte,
|
||||
int* bytesconsumed,
|
||||
int32_t* decoded0, int32_t* decoded1,
|
||||
int count);
|
||||
#endif
|
||||
45
apps/codecs/demac/libdemac/demac.h
Normal file
45
apps/codecs/demac/libdemac/demac.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _APE_DECODER_H
|
||||
#define _APE_DECODER_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "parser.h"
|
||||
|
||||
void init_frame_decoder(struct ape_ctx_t* ape_ctx,
|
||||
unsigned char* inbuffer, int* firstbyte,
|
||||
int* bytesconsumed);
|
||||
|
||||
int decode_chunk(struct ape_ctx_t* ape_ctx,
|
||||
unsigned char* inbuffer, int* firstbyte,
|
||||
int* bytesconsumed,
|
||||
int32_t* decoded0, int32_t* decoded1,
|
||||
int count);
|
||||
|
||||
uint32_t ape_initcrc(void);
|
||||
uint32_t ape_updatecrc(unsigned char *block, int count, uint32_t crc);
|
||||
uint32_t ape_finishcrc(uint32_t crc);
|
||||
|
||||
#endif
|
||||
314
apps/codecs/demac/libdemac/entropy.c
Normal file
314
apps/codecs/demac/libdemac/entropy.c
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "parser.h"
|
||||
#include "entropy.h"
|
||||
#include "rangecoding.h" /* Range-coding (static inline) functions */
|
||||
|
||||
#define MODEL_ELEMENTS 64
|
||||
|
||||
/*
|
||||
The following counts arrays for use with the range decoder are
|
||||
hard-coded in the Monkey's Audio decoder.
|
||||
*/
|
||||
|
||||
static const int counts_3970[65] ICONST_ATTR =
|
||||
{
|
||||
0,14824,28224,39348,47855,53994,58171,60926,
|
||||
62682,63786,64463,64878,65126,65276,65365,65419,
|
||||
65450,65469,65480,65487,65491,65493,65494,65495,
|
||||
65496,65497,65498,65499,65500,65501,65502,65503,
|
||||
65504,65505,65506,65507,65508,65509,65510,65511,
|
||||
65512,65513,65514,65515,65516,65517,65518,65519,
|
||||
65520,65521,65522,65523,65524,65525,65526,65527,
|
||||
65528,65529,65530,65531,65532,65533,65534,65535,
|
||||
65536
|
||||
};
|
||||
|
||||
/* counts_diff_3970[i] = counts_3970[i+1] - counts_3970[i] */
|
||||
static const int counts_diff_3970[64] ICONST_ATTR =
|
||||
{
|
||||
14824,13400,11124,8507,6139,4177,2755,1756,
|
||||
1104,677,415,248,150,89,54,31,
|
||||
19,11,7,4,2,1,1,1,
|
||||
1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1
|
||||
};
|
||||
|
||||
static const int counts_3980[65] ICONST_ATTR =
|
||||
{
|
||||
0,19578,36160,48417,56323,60899,63265,64435,
|
||||
64971,65232,65351,65416,65447,65466,65476,65482,
|
||||
65485,65488,65490,65491,65492,65493,65494,65495,
|
||||
65496,65497,65498,65499,65500,65501,65502,65503,
|
||||
65504,65505,65506,65507,65508,65509,65510,65511,
|
||||
65512,65513,65514,65515,65516,65517,65518,65519,
|
||||
65520,65521,65522,65523,65524,65525,65526,65527,
|
||||
65528,65529,65530,65531,65532,65533,65534,65535,
|
||||
65536
|
||||
};
|
||||
|
||||
/* counts_diff_3980[i] = counts_3980[i+1] - counts_3980[i] */
|
||||
|
||||
static const int counts_diff_3980[64] ICONST_ATTR =
|
||||
{
|
||||
19578,16582,12257,7906,4576,2366,1170,536,
|
||||
261,119,65,31,19,10,6,3,
|
||||
3,2,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1
|
||||
};
|
||||
|
||||
/*
|
||||
range_get_symbol_* functions based on main decoding loop in simple_d.c from
|
||||
http://www.compressconsult.com/rangecoder/rngcod13.zip
|
||||
(c) Michael Schindler
|
||||
*/
|
||||
|
||||
static inline int range_get_symbol_3980(void)
|
||||
{
|
||||
int symbol, cf;
|
||||
|
||||
cf = range_decode_culshift(16);
|
||||
|
||||
/* figure out the symbol inefficiently; a binary search would be much better */
|
||||
for (symbol = 0; counts_3980[symbol+1] <= cf; symbol++);
|
||||
|
||||
range_decode_update(counts_diff_3980[symbol],counts_3980[symbol]);
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
static inline int range_get_symbol_3970(void)
|
||||
{
|
||||
int symbol, cf;
|
||||
|
||||
cf = range_decode_culshift(16);
|
||||
|
||||
/* figure out the symbol inefficiently; a binary search would be much better */
|
||||
for (symbol = 0; counts_3970[symbol+1] <= cf; symbol++);
|
||||
|
||||
range_decode_update(counts_diff_3970[symbol],counts_3970[symbol]);
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
/* MAIN DECODING FUNCTIONS */
|
||||
|
||||
struct rice_t
|
||||
{
|
||||
uint32_t k;
|
||||
uint32_t ksum;
|
||||
};
|
||||
|
||||
static struct rice_t riceX IBSS_ATTR;
|
||||
static struct rice_t riceY IBSS_ATTR;
|
||||
|
||||
static inline void update_rice(struct rice_t* rice, int x)
|
||||
{
|
||||
rice->ksum += ((x + 1) / 2) - ((rice->ksum + 16) >> 5);
|
||||
|
||||
if (rice->k == 0) {
|
||||
rice->k = 1;
|
||||
} else if (rice->ksum < ((uint32_t)1 << (rice->k + 4))) {
|
||||
rice->k--;
|
||||
} else if (rice->ksum >= ((uint32_t)1 << (rice->k + 5))) {
|
||||
rice->k++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int entropy_decode3980(struct rice_t* rice)
|
||||
{
|
||||
int base, x, pivot, overflow;
|
||||
|
||||
pivot = rice->ksum >> 5;
|
||||
if (pivot == 0) pivot=1;
|
||||
|
||||
overflow = range_get_symbol_3980();
|
||||
|
||||
if (overflow == (MODEL_ELEMENTS-1)) {
|
||||
overflow = range_decode_short() << 16;
|
||||
overflow |= range_decode_short();
|
||||
}
|
||||
|
||||
if (pivot >= 0x10000) {
|
||||
/* Codepath for 24-bit streams */
|
||||
int nbits, lo_bits, base_hi, base_lo;
|
||||
|
||||
/* Count the number of bits in pivot */
|
||||
nbits = 17; /* We know there must be at least 17 bits */
|
||||
while ((pivot >> nbits) > 0) { nbits++; }
|
||||
|
||||
/* base_lo is the low (nbits-16) bits of base
|
||||
base_hi is the high 16 bits of base
|
||||
*/
|
||||
lo_bits = (nbits - 16);
|
||||
|
||||
base_hi = range_decode_culfreq((pivot >> lo_bits) + 1);
|
||||
range_decode_update(1, base_hi);
|
||||
|
||||
base_lo = range_decode_culfreq(1 << lo_bits);
|
||||
range_decode_update(1, base_lo);
|
||||
|
||||
base = (base_hi << lo_bits) + base_lo;
|
||||
} else {
|
||||
/* Codepath for 16-bit streams */
|
||||
base = range_decode_culfreq(pivot);
|
||||
range_decode_update(1, base);
|
||||
}
|
||||
|
||||
x = base + (overflow * pivot);
|
||||
update_rice(rice, x);
|
||||
|
||||
/* Convert to signed */
|
||||
if (x & 1)
|
||||
return (x >> 1) + 1;
|
||||
else
|
||||
return -(x >> 1);
|
||||
}
|
||||
|
||||
|
||||
static inline int entropy_decode3970(struct rice_t* rice)
|
||||
{
|
||||
int x, tmpk;
|
||||
|
||||
int overflow = range_get_symbol_3970();
|
||||
|
||||
if (overflow == (MODEL_ELEMENTS - 1)) {
|
||||
tmpk = range_decode_bits(5);
|
||||
overflow = 0;
|
||||
} else {
|
||||
tmpk = (rice->k < 1) ? 0 : rice->k - 1;
|
||||
}
|
||||
|
||||
if (tmpk <= 16) {
|
||||
x = range_decode_bits(tmpk);
|
||||
} else {
|
||||
x = range_decode_short();
|
||||
x |= (range_decode_bits(tmpk - 16) << 16);
|
||||
}
|
||||
x += (overflow << tmpk);
|
||||
|
||||
update_rice(rice, x);
|
||||
|
||||
/* Convert to signed */
|
||||
if (x & 1)
|
||||
return (x >> 1) + 1;
|
||||
else
|
||||
return -(x >> 1);
|
||||
}
|
||||
|
||||
void init_entropy_decoder(struct ape_ctx_t* ape_ctx,
|
||||
unsigned char* inbuffer, int* firstbyte,
|
||||
int* bytesconsumed)
|
||||
{
|
||||
bytebuffer = inbuffer;
|
||||
bytebufferoffset = *firstbyte;
|
||||
|
||||
/* Read the CRC */
|
||||
ape_ctx->CRC = read_byte();
|
||||
ape_ctx->CRC = (ape_ctx->CRC << 8) | read_byte();
|
||||
ape_ctx->CRC = (ape_ctx->CRC << 8) | read_byte();
|
||||
ape_ctx->CRC = (ape_ctx->CRC << 8) | read_byte();
|
||||
|
||||
/* Read the frame flags if they exist */
|
||||
ape_ctx->frameflags = 0;
|
||||
if ((ape_ctx->fileversion > 3820) && (ape_ctx->CRC & 0x80000000)) {
|
||||
ape_ctx->CRC &= ~0x80000000;
|
||||
|
||||
ape_ctx->frameflags = read_byte();
|
||||
ape_ctx->frameflags = (ape_ctx->frameflags << 8) | read_byte();
|
||||
ape_ctx->frameflags = (ape_ctx->frameflags << 8) | read_byte();
|
||||
ape_ctx->frameflags = (ape_ctx->frameflags << 8) | read_byte();
|
||||
}
|
||||
/* Keep a count of the blocks decoded in this frame */
|
||||
ape_ctx->blocksdecoded = 0;
|
||||
|
||||
/* Initialise the rice structs */
|
||||
riceX.k = 10;
|
||||
riceX.ksum = (1 << riceX.k) * 16;
|
||||
riceY.k = 10;
|
||||
riceY.ksum = (1 << riceY.k) * 16;
|
||||
|
||||
/* The first 8 bits of input are ignored. */
|
||||
skip_byte();
|
||||
|
||||
range_start_decoding();
|
||||
|
||||
/* Return the new state of the buffer */
|
||||
*bytesconsumed = (intptr_t)bytebuffer - (intptr_t)inbuffer;
|
||||
*firstbyte = bytebufferoffset;
|
||||
}
|
||||
|
||||
int entropy_decode(struct ape_ctx_t* ape_ctx,
|
||||
unsigned char* inbuffer, int* firstbyte,
|
||||
int* bytesconsumed,
|
||||
int32_t* decoded0, int32_t* decoded1,
|
||||
int blockstodecode)
|
||||
{
|
||||
bytebuffer = inbuffer;
|
||||
bytebufferoffset = *firstbyte;
|
||||
|
||||
ape_ctx->blocksdecoded += blockstodecode;
|
||||
|
||||
if (ape_ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {
|
||||
/* We are pure silence, just memset the output buffer. */
|
||||
memset(decoded0, 0, blockstodecode * sizeof(int32_t));
|
||||
memset(decoded1, 0, blockstodecode * sizeof(int32_t));
|
||||
} else {
|
||||
if (ape_ctx->fileversion > 3970) {
|
||||
while (blockstodecode--) {
|
||||
*(decoded0++) = entropy_decode3980(&riceY);
|
||||
if (decoded1 != NULL)
|
||||
*(decoded1++) = entropy_decode3980(&riceX);
|
||||
}
|
||||
} else {
|
||||
while (blockstodecode--) {
|
||||
*(decoded0++) = entropy_decode3970(&riceY);
|
||||
if (decoded1 != NULL)
|
||||
*(decoded1++) = entropy_decode3970(&riceX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ape_ctx->blocksdecoded == ape_ctx->currentframeblocks)
|
||||
{
|
||||
range_done_decoding();
|
||||
}
|
||||
|
||||
/* Return the new state of the buffer */
|
||||
*bytesconsumed = bytebuffer - inbuffer;
|
||||
*firstbyte = bytebufferoffset;
|
||||
|
||||
return(0);
|
||||
}
|
||||
40
apps/codecs/demac/libdemac/entropy.h
Normal file
40
apps/codecs/demac/libdemac/entropy.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _APE_ENTROPY_H
|
||||
#define _APE_ENTROPY_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
void init_entropy_decoder(struct ape_ctx_t* ape_ctx,
|
||||
unsigned char* inbuffer, int* firstbyte,
|
||||
int* bytesconsumed);
|
||||
|
||||
int entropy_decode(struct ape_ctx_t* ape_ctx,
|
||||
unsigned char* inbuffer, int* firstbyte,
|
||||
int* bytesconsumed,
|
||||
int32_t* decoded0, int32_t* decoded1,
|
||||
int blockstodecode);
|
||||
|
||||
#endif
|
||||
215
apps/codecs/demac/libdemac/filter.c
Normal file
215
apps/codecs/demac/libdemac/filter.c
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "demac.h"
|
||||
#include "filter.h"
|
||||
|
||||
#include "vector_math16.h"
|
||||
|
||||
struct filter_t {
|
||||
int16_t* coeffs; /* ORDER entries */
|
||||
|
||||
/* We store all the filter delays in a single buffer */
|
||||
int16_t* historybuffer; /* ORDER*2 + HISTORY_SIZE entries */
|
||||
|
||||
int16_t* delay;
|
||||
int16_t* adaptcoeffs;
|
||||
|
||||
int avg;
|
||||
};
|
||||
|
||||
/* We name the functions according to the ORDER and FRACBITS
|
||||
pre-processor symbols and build multiple .o files from this .c file
|
||||
- this increases code-size but gives the compiler more scope for
|
||||
optimising the individual functions, as well as replacing a lot of
|
||||
variables with constants.
|
||||
*/
|
||||
|
||||
#if FRACBITS == 11
|
||||
#if ORDER == 16
|
||||
#define INIT_FILTER init_filter_16_11
|
||||
#define APPLY_FILTER apply_filter_16_11
|
||||
#elif ORDER == 64
|
||||
#define INIT_FILTER init_filter_64_11
|
||||
#define APPLY_FILTER apply_filter_64_11
|
||||
#endif
|
||||
#elif FRACBITS == 13
|
||||
#define INIT_FILTER init_filter_256_13
|
||||
#define APPLY_FILTER apply_filter_256_13
|
||||
#elif FRACBITS == 10
|
||||
#define INIT_FILTER init_filter_32_10
|
||||
#define APPLY_FILTER apply_filter_32_10
|
||||
#elif FRACBITS == 15
|
||||
#define INIT_FILTER init_filter_1280_15
|
||||
#define APPLY_FILTER apply_filter_1280_15
|
||||
#endif
|
||||
|
||||
/* Some macros to handle the fixed-point stuff */
|
||||
|
||||
#define FP_HALF (1 << (FRACBITS - 1)) /* 0.5 in fixed-point format. */
|
||||
#define FP_TO_INT(x) ((x + FP_HALF) >> FRACBITS); /* round(x) */
|
||||
|
||||
#define SATURATE(x) (int16_t)(((x) == (int16_t)(x)) ? (x) : ((x) >> 31) ^ 0x7FFF);
|
||||
|
||||
/* Apply the filter with state f to count entries in data[] */
|
||||
|
||||
static inline void do_apply_filter_3980(struct filter_t* f, int32_t* data, int count)
|
||||
{
|
||||
int res;
|
||||
int absres;
|
||||
|
||||
while(count--)
|
||||
{
|
||||
res = FP_TO_INT(scalarproduct(f->delay - ORDER, f->coeffs));
|
||||
|
||||
if (*data < 0)
|
||||
vector_add(f->coeffs, f->adaptcoeffs - ORDER);
|
||||
else if (*data > 0)
|
||||
vector_sub(f->coeffs, f->adaptcoeffs - ORDER);
|
||||
|
||||
/* Convert res from (32-FRACBITS).FRACBITS fixed-point format to an
|
||||
integer (rounding to nearest) and add the input value to
|
||||
it */
|
||||
res += *data;
|
||||
|
||||
*data++ = res;
|
||||
|
||||
/* Update the output history */
|
||||
*f->delay++ = SATURATE(res);
|
||||
|
||||
/* Version 3.98 and later files */
|
||||
|
||||
/* Update the adaption coefficients */
|
||||
absres = (res < 0 ? -res : res);
|
||||
|
||||
if (absres > (f->avg * 3))
|
||||
*f->adaptcoeffs = ((res >> 25) & 64) - 32;
|
||||
else if (absres > (f->avg * 4) / 3)
|
||||
*f->adaptcoeffs = ((res >> 26) & 32) - 16;
|
||||
else if (absres > 0)
|
||||
*f->adaptcoeffs = ((res >> 27) & 16) - 8;
|
||||
else
|
||||
*f->adaptcoeffs = 0;
|
||||
|
||||
f->avg += (absres - f->avg) / 16;
|
||||
|
||||
f->adaptcoeffs[-1] >>= 1;
|
||||
f->adaptcoeffs[-2] >>= 1;
|
||||
f->adaptcoeffs[-8] >>= 1;
|
||||
|
||||
f->adaptcoeffs++;
|
||||
|
||||
/* Have we filled the history buffer? */
|
||||
if (f->delay == f->historybuffer + HISTORY_SIZE + (ORDER*2)) {
|
||||
memmove(f->historybuffer, f->delay - (ORDER*2),
|
||||
(ORDER*2) * sizeof(int16_t));
|
||||
f->delay = f->historybuffer + ORDER*2;
|
||||
f->adaptcoeffs = f->historybuffer + ORDER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void do_apply_filter_3970(struct filter_t* f, int32_t* data, int count)
|
||||
{
|
||||
int res;
|
||||
|
||||
while(count--)
|
||||
{
|
||||
res = FP_TO_INT(scalarproduct(f->delay - ORDER, f->coeffs));
|
||||
|
||||
if (*data < 0)
|
||||
vector_add(f->coeffs, f->adaptcoeffs - ORDER);
|
||||
else if (*data > 0)
|
||||
vector_sub(f->coeffs, f->adaptcoeffs - ORDER);
|
||||
|
||||
/* Convert res from (32-FRACBITS).FRACBITS fixed-point format to an
|
||||
integer (rounding to nearest) and add the input value to
|
||||
it */
|
||||
res += *data;
|
||||
|
||||
*data++ = res;
|
||||
|
||||
/* Update the output history */
|
||||
*f->delay++ = SATURATE(res);
|
||||
|
||||
/* Version ??? to < 3.98 files (untested) */
|
||||
f->adaptcoeffs[0] = (res == 0) ? 0 : ((res >> 28) & 8) - 4;
|
||||
f->adaptcoeffs[-4] >>= 1;
|
||||
f->adaptcoeffs[-8] >>= 1;
|
||||
|
||||
f->adaptcoeffs++;
|
||||
|
||||
/* Have we filled the history buffer? */
|
||||
if (f->delay == f->historybuffer + HISTORY_SIZE + (ORDER*2)) {
|
||||
memmove(f->historybuffer, f->delay - (ORDER*2),
|
||||
(ORDER*2) * sizeof(int16_t));
|
||||
f->delay = f->historybuffer + ORDER*2;
|
||||
f->adaptcoeffs = f->historybuffer + ORDER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct filter_t filter0 IBSS_ATTR;
|
||||
static struct filter_t filter1 IBSS_ATTR;
|
||||
|
||||
static void do_init_filter(struct filter_t* f, int16_t* buf)
|
||||
{
|
||||
f->coeffs = buf;
|
||||
f->historybuffer = buf + ORDER;
|
||||
|
||||
/* Zero the output history buffer */
|
||||
memset(f->historybuffer, 0 , (ORDER*2) * sizeof(int16_t));
|
||||
f->delay = f->historybuffer + ORDER*2;
|
||||
f->adaptcoeffs = f->historybuffer + ORDER;
|
||||
|
||||
/* Zero the co-efficients */
|
||||
memset(f->coeffs, 0, ORDER * sizeof(int16_t));
|
||||
|
||||
/* Zero the running average */
|
||||
f->avg = 0;
|
||||
}
|
||||
|
||||
void INIT_FILTER(int16_t* buf)
|
||||
{
|
||||
do_init_filter(&filter0, buf);
|
||||
do_init_filter(&filter1, buf + ORDER * 3 + HISTORY_SIZE);
|
||||
}
|
||||
|
||||
int APPLY_FILTER(int fileversion, int32_t* data0, int32_t* data1, int count)
|
||||
{
|
||||
if (fileversion >= 3980) {
|
||||
do_apply_filter_3980(&filter0, data0, count);
|
||||
if (data1 != NULL)
|
||||
do_apply_filter_3980(&filter1, data1, count);
|
||||
} else {
|
||||
do_apply_filter_3970(&filter0, data0, count);
|
||||
if (data1 != NULL)
|
||||
do_apply_filter_3970(&filter1, data1, count);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
48
apps/codecs/demac/libdemac/filter.h
Normal file
48
apps/codecs/demac/libdemac/filter.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _APE_FILTER_H
|
||||
#define _APE_FILTER_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
/* The size of the history buffers */
|
||||
#define HISTORY_SIZE 512
|
||||
|
||||
void init_filter_16_11(int16_t* buf);
|
||||
int apply_filter_16_11(int fileversion, int32_t* decoded0, int32_t* decoded1, int count);
|
||||
|
||||
void init_filter_64_11(int16_t* buf);
|
||||
int apply_filter_64_11(int fileversion, int32_t* decoded0, int32_t* decoded1, int count);
|
||||
|
||||
void init_filter_32_10(int16_t* buf);
|
||||
int apply_filter_32_10(int fileversion, int32_t* decoded0, int32_t* decoded1, int count);
|
||||
|
||||
void init_filter_256_13(int16_t* buf);
|
||||
int apply_filter_256_13(int fileversion, int32_t* decoded0, int32_t* decoded1, int count);
|
||||
|
||||
void init_filter_1280_15(int16_t* buf);
|
||||
int apply_filter_1280_15(int fileversion, int32_t* decoded0, int32_t* decoded1, int count);
|
||||
|
||||
#endif
|
||||
27
apps/codecs/demac/libdemac/filter_1280_15.c
Normal file
27
apps/codecs/demac/libdemac/filter_1280_15.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#define ORDER 1280
|
||||
#define FRACBITS 15
|
||||
#include "filter.c"
|
||||
27
apps/codecs/demac/libdemac/filter_16_11.c
Normal file
27
apps/codecs/demac/libdemac/filter_16_11.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#define ORDER 16
|
||||
#define FRACBITS 11
|
||||
#include "filter.c"
|
||||
27
apps/codecs/demac/libdemac/filter_256_13.c
Normal file
27
apps/codecs/demac/libdemac/filter_256_13.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#define ORDER 256
|
||||
#define FRACBITS 13
|
||||
#include "filter.c"
|
||||
27
apps/codecs/demac/libdemac/filter_32_10.c
Normal file
27
apps/codecs/demac/libdemac/filter_32_10.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#define ORDER 32
|
||||
#define FRACBITS 10
|
||||
#include "filter.c"
|
||||
27
apps/codecs/demac/libdemac/filter_64_11.c
Normal file
27
apps/codecs/demac/libdemac/filter_64_11.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#define ORDER 64
|
||||
#define FRACBITS 11
|
||||
#include "filter.c"
|
||||
357
apps/codecs/demac/libdemac/parser.c
Normal file
357
apps/codecs/demac/libdemac/parser.c
Normal file
|
|
@ -0,0 +1,357 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#ifndef ROCKBOX
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
|
||||
static inline int16_t get_int16(unsigned char* buf)
|
||||
{
|
||||
return(buf[0] | (buf[1] << 8));
|
||||
}
|
||||
|
||||
static inline uint16_t get_uint16(unsigned char* buf)
|
||||
{
|
||||
return(buf[0] | (buf[1] << 8));
|
||||
}
|
||||
|
||||
static inline uint32_t get_uint32(unsigned char* buf)
|
||||
{
|
||||
return(buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24));
|
||||
}
|
||||
|
||||
|
||||
int ape_parseheaderbuf(unsigned char* buf, struct ape_ctx_t* ape_ctx)
|
||||
{
|
||||
unsigned char* header;
|
||||
|
||||
memset(ape_ctx,0,sizeof(struct ape_ctx_t));
|
||||
/* TODO: Skip any leading junk such as id3v2 tags */
|
||||
ape_ctx->junklength = 0;
|
||||
|
||||
memcpy(ape_ctx->magic, buf, 4);
|
||||
if (memcmp(ape_ctx->magic,"MAC ",4)!=0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ape_ctx->fileversion = get_int16(buf + 4);
|
||||
|
||||
if (ape_ctx->fileversion >= 3980)
|
||||
{
|
||||
ape_ctx->padding1 = get_int16(buf + 6);
|
||||
ape_ctx->descriptorlength = get_uint32(buf + 8);
|
||||
ape_ctx->headerlength = get_uint32(buf + 12);
|
||||
ape_ctx->seektablelength = get_uint32(buf + 16);
|
||||
ape_ctx->wavheaderlength = get_uint32(buf + 20);
|
||||
ape_ctx->audiodatalength = get_uint32(buf + 24);
|
||||
ape_ctx->audiodatalength_high = get_uint32(buf + 28);
|
||||
ape_ctx->wavtaillength = get_uint32(buf + 32);
|
||||
memcpy(ape_ctx->md5, buf + 36, 16);
|
||||
|
||||
header = buf + ape_ctx->descriptorlength;
|
||||
|
||||
/* Read header data */
|
||||
ape_ctx->compressiontype = get_uint16(header + 0);
|
||||
ape_ctx->formatflags = get_uint16(header + 2);
|
||||
ape_ctx->blocksperframe = get_uint32(header + 4);
|
||||
ape_ctx->finalframeblocks = get_uint32(header + 8);
|
||||
ape_ctx->totalframes = get_uint32(header + 12);
|
||||
ape_ctx->bps = get_uint16(header + 16);
|
||||
ape_ctx->channels = get_uint16(header + 18);
|
||||
ape_ctx->samplerate = get_uint32(header + 20);
|
||||
|
||||
ape_ctx->firstframe = ape_ctx->junklength + ape_ctx->descriptorlength +
|
||||
ape_ctx->headerlength + ape_ctx->seektablelength +
|
||||
ape_ctx->wavheaderlength;
|
||||
} else {
|
||||
ape_ctx->compressiontype = get_uint16(buf + 6);
|
||||
ape_ctx->formatflags = get_uint16(buf + 8);
|
||||
ape_ctx->channels = get_uint16(buf + 10);
|
||||
ape_ctx->samplerate = get_uint32(buf + 14);
|
||||
ape_ctx->wavheaderlength = get_uint32(buf + 18);
|
||||
ape_ctx->totalframes = get_uint32(buf + 26);
|
||||
ape_ctx->finalframeblocks = get_uint32(buf + 30);
|
||||
}
|
||||
|
||||
ape_ctx->totalsamples = ape_ctx->finalframeblocks;
|
||||
if (ape_ctx->totalframes > 1)
|
||||
ape_ctx->totalsamples += ape_ctx->blocksperframe * (ape_ctx->totalframes-1);
|
||||
|
||||
/* TODO: Parse and store seektable */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifndef ROCKBOX
|
||||
/* Helper functions */
|
||||
|
||||
static int read_uint16(int fd, uint16_t* x)
|
||||
{
|
||||
unsigned char tmp[2];
|
||||
int n;
|
||||
|
||||
n = read(fd,tmp,2);
|
||||
|
||||
if (n != 2)
|
||||
return -1;
|
||||
|
||||
*x = tmp[0] | (tmp[1] << 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_int16(int fd, int16_t* x)
|
||||
{
|
||||
return read_uint16(fd, (uint16_t*)x);
|
||||
}
|
||||
|
||||
static int read_uint32(int fd, uint32_t* x)
|
||||
{
|
||||
unsigned char tmp[4];
|
||||
int n;
|
||||
|
||||
n = read(fd,tmp,4);
|
||||
|
||||
if (n != 4)
|
||||
return -1;
|
||||
|
||||
*x = tmp[0] | (tmp[1] << 8) | (tmp[2] << 16) | (tmp[3] << 24);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ape_parseheader(int fd, struct ape_ctx_t* ape_ctx)
|
||||
{
|
||||
int i,n;
|
||||
|
||||
/* TODO: Skip any leading junk such as id3v2 tags */
|
||||
ape_ctx->junklength = 0;
|
||||
|
||||
lseek(fd,ape_ctx->junklength,SEEK_SET);
|
||||
|
||||
n = read(fd,&ape_ctx->magic,4);
|
||||
if (n != 4) return -1;
|
||||
|
||||
if (memcmp(ape_ctx->magic,"MAC ",4)!=0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (read_int16(fd,&ape_ctx->fileversion) < 0)
|
||||
return -1;
|
||||
|
||||
if (ape_ctx->fileversion >= 3980)
|
||||
{
|
||||
if (read_int16(fd,&ape_ctx->padding1) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->descriptorlength) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->headerlength) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->seektablelength) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->wavheaderlength) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->audiodatalength) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->audiodatalength_high) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->wavtaillength) < 0)
|
||||
return -1;
|
||||
if (read(fd,&ape_ctx->md5,16) != 16)
|
||||
return -1;
|
||||
|
||||
/* Skip any unknown bytes at the end of the descriptor. This is for future
|
||||
compatibility */
|
||||
if (ape_ctx->descriptorlength > 52)
|
||||
lseek(fd,ape_ctx->descriptorlength - 52, SEEK_CUR);
|
||||
|
||||
/* Read header data */
|
||||
if (read_uint16(fd,&ape_ctx->compressiontype) < 0)
|
||||
return -1;
|
||||
if (read_uint16(fd,&ape_ctx->formatflags) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->blocksperframe) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->finalframeblocks) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->totalframes) < 0)
|
||||
return -1;
|
||||
if (read_uint16(fd,&ape_ctx->bps) < 0)
|
||||
return -1;
|
||||
if (read_uint16(fd,&ape_ctx->channels) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->samplerate) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
ape_ctx->descriptorlength = 0;
|
||||
ape_ctx->headerlength = 32;
|
||||
|
||||
if (read_uint16(fd,&ape_ctx->compressiontype) < 0)
|
||||
return -1;
|
||||
if (read_uint16(fd,&ape_ctx->formatflags) < 0)
|
||||
return -1;
|
||||
if (read_uint16(fd,&ape_ctx->channels) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->samplerate) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->wavheaderlength) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->wavtaillength) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->totalframes) < 0)
|
||||
return -1;
|
||||
if (read_uint32(fd,&ape_ctx->finalframeblocks) < 0)
|
||||
return -1;
|
||||
|
||||
if (ape_ctx->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL)
|
||||
{
|
||||
lseek(fd, 4, SEEK_CUR); /* Skip the peak level */
|
||||
ape_ctx->headerlength += 4;
|
||||
}
|
||||
|
||||
if (ape_ctx->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS)
|
||||
{
|
||||
if (read_uint32(fd,&ape_ctx->seektablelength) < 0)
|
||||
return -1;
|
||||
ape_ctx->headerlength += 4;
|
||||
ape_ctx->seektablelength *= sizeof(int32_t);
|
||||
} else {
|
||||
ape_ctx->seektablelength = ape_ctx->totalframes * sizeof(int32_t);
|
||||
}
|
||||
|
||||
if (ape_ctx->formatflags & MAC_FORMAT_FLAG_8_BIT)
|
||||
ape_ctx->bps = 8;
|
||||
else if (ape_ctx->formatflags & MAC_FORMAT_FLAG_24_BIT)
|
||||
ape_ctx->bps = 24;
|
||||
else
|
||||
ape_ctx->bps = 16;
|
||||
|
||||
if (ape_ctx->fileversion >= 3950)
|
||||
ape_ctx->blocksperframe = 73728 * 4;
|
||||
else if ((ape_ctx->fileversion >= 3900) || (ape_ctx->fileversion >= 3800 && ape_ctx->compressiontype >= 4000))
|
||||
ape_ctx->blocksperframe = 73728;
|
||||
else
|
||||
ape_ctx->blocksperframe = 9216;
|
||||
|
||||
/* Skip any stored wav header */
|
||||
if (!(ape_ctx->formatflags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER))
|
||||
{
|
||||
lseek(fd, ape_ctx->wavheaderlength, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
ape_ctx->totalsamples = ape_ctx->finalframeblocks;
|
||||
if (ape_ctx->totalframes > 1)
|
||||
ape_ctx->totalsamples += ape_ctx->blocksperframe * (ape_ctx->totalframes-1);
|
||||
|
||||
if (ape_ctx->seektablelength > 0)
|
||||
{
|
||||
ape_ctx->seektable = malloc(ape_ctx->seektablelength);
|
||||
if (ape_ctx->seektable == NULL)
|
||||
return -1;
|
||||
for (i=0; i < ape_ctx->seektablelength / sizeof(uint32_t); i++)
|
||||
{
|
||||
if (read_uint32(fd,&ape_ctx->seektable[i]) < 0)
|
||||
{
|
||||
free(ape_ctx->seektable);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ape_ctx->firstframe = ape_ctx->junklength + ape_ctx->descriptorlength +
|
||||
ape_ctx->headerlength + ape_ctx->seektablelength +
|
||||
ape_ctx->wavheaderlength;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ape_dumpinfo(struct ape_ctx_t* ape_ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("Descriptor Block:\n\n");
|
||||
printf("magic = \"%c%c%c%c\"\n",
|
||||
ape_ctx->magic[0],ape_ctx->magic[1],
|
||||
ape_ctx->magic[2],ape_ctx->magic[3]);
|
||||
printf("fileversion = %d\n",ape_ctx->fileversion);
|
||||
printf("descriptorlength = %d\n",ape_ctx->descriptorlength);
|
||||
printf("headerlength = %d\n",ape_ctx->headerlength);
|
||||
printf("seektablelength = %d\n",ape_ctx->seektablelength);
|
||||
printf("wavheaderlength = %d\n",ape_ctx->wavheaderlength);
|
||||
printf("audiodatalength = %d\n",ape_ctx->audiodatalength);
|
||||
printf("audiodatalength_high = %d\n",ape_ctx->audiodatalength_high);
|
||||
printf("wavtaillength = %d\n",ape_ctx->wavtaillength);
|
||||
printf("md5 = ");
|
||||
for (i = 0; i < 16; i++)
|
||||
printf("%02x",ape_ctx->md5[i]);
|
||||
printf("\n");
|
||||
|
||||
printf("\nHeader Block:\n\n");
|
||||
|
||||
printf("compressiontype = %d\n",ape_ctx->compressiontype);
|
||||
printf("formatflags = %d\n",ape_ctx->formatflags);
|
||||
printf("blocksperframe = %d\n",ape_ctx->blocksperframe);
|
||||
printf("finalframeblocks = %d\n",ape_ctx->finalframeblocks);
|
||||
printf("totalframes = %d\n",ape_ctx->totalframes);
|
||||
printf("bps = %d\n",ape_ctx->bps);
|
||||
printf("channels = %d\n",ape_ctx->channels);
|
||||
printf("samplerate = %d\n",ape_ctx->samplerate);
|
||||
|
||||
printf("\nSeektable\n\n");
|
||||
if ((ape_ctx->seektablelength / sizeof(uint32_t)) != ape_ctx->totalframes)
|
||||
{
|
||||
printf("No seektable\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < ape_ctx->seektablelength / sizeof(uint32_t) ; i++)
|
||||
{
|
||||
if (i < ape_ctx->totalframes-1) {
|
||||
printf("%8d %d (%d bytes)\n",i,ape_ctx->seektable[i],ape_ctx->seektable[i+1]-ape_ctx->seektable[i]);
|
||||
} else {
|
||||
printf("%8d %d\n",i,ape_ctx->seektable[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\nCalculated information:\n\n");
|
||||
printf("junklength = %d\n",ape_ctx->junklength);
|
||||
printf("firstframe = %d\n",ape_ctx->firstframe);
|
||||
printf("totalsamples = %d\n",ape_ctx->totalsamples);
|
||||
}
|
||||
|
||||
#endif /* !ROCKBOX */
|
||||
137
apps/codecs/demac/libdemac/parser.h
Normal file
137
apps/codecs/demac/libdemac/parser.h
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _APE_PARSER_H
|
||||
#define _APE_PARSER_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef ROCKBOX
|
||||
/* Include the Rockbox Codec API when building for Rockbox */
|
||||
#define APE_OUTPUT_DEPTH 29
|
||||
#ifndef ROCKBOX_PLUGIN
|
||||
#include "../lib/codeclib.h"
|
||||
#include <codecs.h>
|
||||
#endif
|
||||
#else
|
||||
#define APE_OUTPUT_DEPTH (ape_ctx->bps)
|
||||
#define IBSS_ATTR
|
||||
#define ICONST_ATTR
|
||||
#define ICODE_ATTR
|
||||
#endif
|
||||
|
||||
/* The earliest and latest file formats supported by this library */
|
||||
#define APE_MIN_VERSION 3970
|
||||
#define APE_MAX_VERSION 3990
|
||||
|
||||
#define MAC_FORMAT_FLAG_8_BIT 1 // is 8-bit [OBSOLETE]
|
||||
#define MAC_FORMAT_FLAG_CRC 2 // uses the new CRC32 error detection [OBSOLETE]
|
||||
#define MAC_FORMAT_FLAG_HAS_PEAK_LEVEL 4 // uint32 nPeakLevel after the header [OBSOLETE]
|
||||
#define MAC_FORMAT_FLAG_24_BIT 8 // is 24-bit [OBSOLETE]
|
||||
#define MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS 16 // has the number of seek elements after the peak level
|
||||
#define MAC_FORMAT_FLAG_CREATE_WAV_HEADER 32 // create the wave header on decompression (not stored)
|
||||
|
||||
|
||||
/* Special frame codes:
|
||||
|
||||
MONO_SILENCE - All PCM samples in frame are zero (mono streams only)
|
||||
LEFT_SILENCE - All PCM samples for left channel in frame are zero (stereo streams)
|
||||
RIGHT_SILENCE - All PCM samples for left channel in frame are zero (stereo streams)
|
||||
PSEUDO_STEREO - Left and Right channels are identical
|
||||
|
||||
*/
|
||||
|
||||
#define APE_FRAMECODE_MONO_SILENCE 1
|
||||
#define APE_FRAMECODE_STEREO_SILENCE 3
|
||||
#define APE_FRAMECODE_PSEUDO_STEREO 4
|
||||
|
||||
#define HISTORY_SIZE 512
|
||||
#define PREDICTOR_ORDER 8
|
||||
|
||||
struct predictor_t
|
||||
{
|
||||
/* Adaption co-efficients */
|
||||
int32_t coeffsA[4];
|
||||
int32_t coeffsB[5];
|
||||
|
||||
/* Filter histories */
|
||||
int32_t historybuffer[HISTORY_SIZE + PREDICTOR_ORDER * 4];
|
||||
int32_t* delayA;
|
||||
int32_t* delayB;
|
||||
int32_t* adaptcoeffsA;
|
||||
int32_t* adaptcoeffsB;
|
||||
|
||||
int32_t lastA;
|
||||
|
||||
int32_t filterA;
|
||||
int32_t filterB;
|
||||
};
|
||||
|
||||
struct ape_ctx_t
|
||||
{
|
||||
/* Derived fields */
|
||||
uint32_t junklength;
|
||||
uint32_t firstframe;
|
||||
uint32_t totalsamples;
|
||||
|
||||
/* Info from Descriptor Block */
|
||||
char magic[4];
|
||||
int16_t fileversion;
|
||||
int16_t padding1;
|
||||
uint32_t descriptorlength;
|
||||
uint32_t headerlength;
|
||||
uint32_t seektablelength;
|
||||
uint32_t wavheaderlength;
|
||||
uint32_t audiodatalength;
|
||||
uint32_t audiodatalength_high;
|
||||
uint32_t wavtaillength;
|
||||
uint8_t md5[16];
|
||||
|
||||
/* Info from Header Block */
|
||||
uint16_t compressiontype;
|
||||
uint16_t formatflags;
|
||||
uint32_t blocksperframe;
|
||||
uint32_t finalframeblocks;
|
||||
uint32_t totalframes;
|
||||
uint16_t bps;
|
||||
uint16_t channels;
|
||||
uint32_t samplerate;
|
||||
|
||||
/* Seektable */
|
||||
uint32_t* seektable;
|
||||
|
||||
/* Decoder state */
|
||||
uint32_t CRC;
|
||||
int frameflags;
|
||||
int currentframeblocks;
|
||||
int blocksdecoded;
|
||||
struct predictor_t predictorY;
|
||||
struct predictor_t predictorX;
|
||||
};
|
||||
|
||||
int ape_parseheader(int fd, struct ape_ctx_t* ape_ctx);
|
||||
int ape_parseheaderbuf(unsigned char* buf, struct ape_ctx_t* ape_ctx);
|
||||
void ape_dumpinfo(struct ape_ctx_t* ape_ctx);
|
||||
|
||||
#endif
|
||||
196
apps/codecs/demac/libdemac/predictor.c
Normal file
196
apps/codecs/demac/libdemac/predictor.c
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "parser.h"
|
||||
#include "predictor.h"
|
||||
|
||||
#include "vector_math32.h"
|
||||
|
||||
/* Return 0 if x is zero, -1 if x is positive, 1 if x is negative */
|
||||
#define SIGN(x) (x) ? (((x) > 0) ? -1 : 1) : 0
|
||||
|
||||
static const int32_t initial_coeffs[4] = {
|
||||
360, 317, -109, 98
|
||||
};
|
||||
|
||||
static void init_predictor(struct predictor_t* p)
|
||||
{
|
||||
/* Zero the history buffers */
|
||||
memset(p->historybuffer, 0, (PREDICTOR_ORDER*4) * sizeof(int32_t));
|
||||
p->delayA = p->historybuffer + PREDICTOR_ORDER*4;
|
||||
p->delayB = p->historybuffer + PREDICTOR_ORDER*3;
|
||||
p->adaptcoeffsA = p->historybuffer + PREDICTOR_ORDER*2;
|
||||
p->adaptcoeffsB = p->historybuffer + PREDICTOR_ORDER;
|
||||
|
||||
/* Initialise and zero the co-efficients */
|
||||
memcpy(p->coeffsA, initial_coeffs, sizeof(initial_coeffs));
|
||||
memset(p->coeffsB, 0, sizeof(p->coeffsB));
|
||||
|
||||
p->filterA = 0;
|
||||
p->filterB = 0;
|
||||
|
||||
p->lastA = 0;
|
||||
}
|
||||
|
||||
static int do_predictor_decode(struct predictor_t* p, int32_t A, int32_t B)
|
||||
{
|
||||
int32_t predictionA, predictionB, currentA;
|
||||
|
||||
p->delayA[0] = p->lastA;
|
||||
p->delayA[-1] = p->delayA[0] - p->delayA[-1];
|
||||
|
||||
predictionA = scalarproduct4_rev32(p->coeffsA,p->delayA);
|
||||
|
||||
/* Apply a scaled first-order filter compression */
|
||||
p->delayB[0] = B - ((p->filterB * 31) >> 5);
|
||||
p->filterB = B;
|
||||
|
||||
p->delayB[-1] = p->delayB[0] - p->delayB[-1];
|
||||
|
||||
predictionB = scalarproduct5_rev32(p->coeffsB,p->delayB);
|
||||
|
||||
currentA = A + ((predictionA + (predictionB >> 1)) >> 10);
|
||||
|
||||
p->adaptcoeffsA[0] = SIGN(p->delayA[0]);
|
||||
p->adaptcoeffsA[-1] = SIGN(p->delayA[-1]);
|
||||
|
||||
p->adaptcoeffsB[0] = SIGN(p->delayB[0]);
|
||||
p->adaptcoeffsB[-1] = SIGN(p->delayB[-1]);
|
||||
|
||||
if (A > 0)
|
||||
{
|
||||
vector_sub4_rev32(p->coeffsA, p->adaptcoeffsA);
|
||||
vector_sub5_rev32(p->coeffsB, p->adaptcoeffsB);
|
||||
}
|
||||
else if (A < 0)
|
||||
{
|
||||
vector_add4_rev32(p->coeffsA, p->adaptcoeffsA);
|
||||
vector_add5_rev32(p->coeffsB, p->adaptcoeffsB);
|
||||
}
|
||||
|
||||
p->delayA++;
|
||||
p->delayB++;
|
||||
p->adaptcoeffsA++;
|
||||
p->adaptcoeffsB++;
|
||||
|
||||
/* Have we filled the history buffer? */
|
||||
if (p->delayA == p->historybuffer + HISTORY_SIZE + (PREDICTOR_ORDER*4)) {
|
||||
memmove(p->historybuffer, p->delayA - (PREDICTOR_ORDER*4),
|
||||
(PREDICTOR_ORDER*4) * sizeof(int32_t));
|
||||
p->delayA = p->historybuffer + PREDICTOR_ORDER*4;
|
||||
p->delayB = p->historybuffer + PREDICTOR_ORDER*3;
|
||||
p->adaptcoeffsA = p->historybuffer + PREDICTOR_ORDER*2;
|
||||
p->adaptcoeffsB = p->historybuffer + PREDICTOR_ORDER;
|
||||
}
|
||||
|
||||
p->lastA = currentA;
|
||||
p->filterA = currentA + ((p->filterA * 31) >> 5);
|
||||
|
||||
return p->filterA;
|
||||
}
|
||||
|
||||
static int32_t X;
|
||||
|
||||
void init_predictor_decoder(struct ape_ctx_t* ape_ctx)
|
||||
{
|
||||
X = 0;
|
||||
|
||||
init_predictor(&ape_ctx->predictorY);
|
||||
init_predictor(&ape_ctx->predictorX);
|
||||
}
|
||||
|
||||
int predictor_decode_stereo(struct ape_ctx_t* ape_ctx, int32_t* decoded0, int32_t* decoded1, int count) ICODE_ATTR;
|
||||
int predictor_decode_stereo(struct ape_ctx_t* ape_ctx, int32_t* decoded0, int32_t* decoded1, int count)
|
||||
{
|
||||
while (count--)
|
||||
{
|
||||
*decoded0 = do_predictor_decode(&ape_ctx->predictorY, *decoded0, X);
|
||||
X = do_predictor_decode(&ape_ctx->predictorX, *decoded1, *(decoded0)++);
|
||||
*(decoded1++) = X;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int predictor_decode_mono(struct ape_ctx_t* ape_ctx, int32_t* decoded0, int count)
|
||||
{
|
||||
struct predictor_t* p = &ape_ctx->predictorY;
|
||||
int32_t predictionA, currentA, A;
|
||||
|
||||
currentA = p->lastA;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
A = *decoded0;
|
||||
|
||||
p->delayA[0] = currentA;
|
||||
p->delayA[-1] = p->delayA[0] - p->delayA[-1];
|
||||
|
||||
predictionA = (p->delayA[0] * p->coeffsA[0]) +
|
||||
(p->delayA[-1] * p->coeffsA[1]) +
|
||||
(p->delayA[-2] * p->coeffsA[2]) +
|
||||
(p->delayA[-3] * p->coeffsA[3]);
|
||||
|
||||
currentA = A + (predictionA >> 10);
|
||||
|
||||
p->adaptcoeffsA[0] = SIGN(p->delayA[0]);
|
||||
p->adaptcoeffsA[-1] = SIGN(p->delayA[-1]);
|
||||
|
||||
if (A > 0)
|
||||
{
|
||||
p->coeffsA[0] -= p->adaptcoeffsA[0];
|
||||
p->coeffsA[1] -= p->adaptcoeffsA[-1];
|
||||
p->coeffsA[2] -= p->adaptcoeffsA[-2];
|
||||
p->coeffsA[3] -= p->adaptcoeffsA[-3];
|
||||
}
|
||||
else if (A < 0)
|
||||
{
|
||||
p->coeffsA[0] += p->adaptcoeffsA[0];
|
||||
p->coeffsA[1] += p->adaptcoeffsA[-1];
|
||||
p->coeffsA[2] += p->adaptcoeffsA[-2];
|
||||
p->coeffsA[3] += p->adaptcoeffsA[-3];
|
||||
}
|
||||
|
||||
p->delayA++;
|
||||
p->adaptcoeffsA++;
|
||||
|
||||
/* Have we filled the history buffer? */
|
||||
if (p->delayA == p->historybuffer + HISTORY_SIZE + (PREDICTOR_ORDER*4)) {
|
||||
memmove(p->historybuffer, p->delayA - (PREDICTOR_ORDER*4),
|
||||
(PREDICTOR_ORDER*4) * sizeof(int32_t));
|
||||
p->delayA = p->historybuffer + PREDICTOR_ORDER*4;
|
||||
p->adaptcoeffsA = p->historybuffer + PREDICTOR_ORDER*2;
|
||||
}
|
||||
|
||||
p->filterA = currentA + ((p->filterA * 31) >> 5);
|
||||
*(decoded0++) = p->filterA;
|
||||
}
|
||||
|
||||
p->lastA = currentA;
|
||||
|
||||
return 0;
|
||||
}
|
||||
36
apps/codecs/demac/libdemac/predictor.h
Normal file
36
apps/codecs/demac/libdemac/predictor.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _APE_PREDICTOR_H
|
||||
#define _APE_PREDICTOR_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "parser.h"
|
||||
#include "filter.h"
|
||||
|
||||
void init_predictor_decoder(struct ape_ctx_t* ape_ctx);
|
||||
int predictor_decode_stereo(struct ape_ctx_t* ape_ctx, int32_t* decoded0, int32_t* decoded1, int count);
|
||||
int predictor_decode_mono(struct ape_ctx_t* ape_ctx, int32_t* decoded0, int count);
|
||||
|
||||
#endif
|
||||
180
apps/codecs/demac/libdemac/rangecoding.h
Normal file
180
apps/codecs/demac/libdemac/rangecoding.h
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Range decoder adapted from rangecod.c included in:
|
||||
|
||||
http://www.compressconsult.com/rangecoder/rngcod13.zip
|
||||
|
||||
rangecod.c range encoding
|
||||
|
||||
(c) Michael Schindler
|
||||
1997, 1998, 1999, 2000
|
||||
http://www.compressconsult.com/
|
||||
michael@compressconsult.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
The encoding functions were removed, and functions turned into "static
|
||||
inline" functions and moved to a .h file. Some minor cosmetic changes
|
||||
were made (e.g. turning pre-processor symbols into upper-case,
|
||||
removing the rc parameter from each function (and the RNGC macro)).
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* BITSTREAM READING FUNCTIONS */
|
||||
|
||||
/* We deal with the input data one byte at a time - to ensure
|
||||
functionality on CPUs of any endianness regardless of any requirements
|
||||
for aligned reads.
|
||||
*/
|
||||
|
||||
static unsigned char* bytebuffer IBSS_ATTR;
|
||||
static int bytebufferoffset IBSS_ATTR;
|
||||
|
||||
static inline void skip_byte(void)
|
||||
{
|
||||
if (bytebufferoffset) {
|
||||
bytebufferoffset--;
|
||||
} else {
|
||||
bytebufferoffset = 3;
|
||||
bytebuffer += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int read_byte(void)
|
||||
{
|
||||
int ch = bytebuffer[bytebufferoffset];
|
||||
|
||||
skip_byte();
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
/* RANGE DECODING FUNCTIONS */
|
||||
|
||||
/* SIZE OF RANGE ENCODING CODE VALUES. */
|
||||
|
||||
#define CODE_BITS 32
|
||||
#define TOP_VALUE ((unsigned int)1 << (CODE_BITS-1))
|
||||
#define SHIFT_BITS (CODE_BITS - 9)
|
||||
#define EXTRA_BITS ((CODE_BITS-2) % 8 + 1)
|
||||
#define BOTTOM_VALUE (TOP_VALUE >> 8)
|
||||
|
||||
struct rangecoder_t
|
||||
{
|
||||
uint32_t low; /* low end of interval */
|
||||
uint32_t range; /* length of interval */
|
||||
uint32_t help; /* bytes_to_follow resp. intermediate value */
|
||||
unsigned int buffer; /* buffer for input/output */
|
||||
};
|
||||
|
||||
static struct rangecoder_t rc;
|
||||
|
||||
/* Start the decoder */
|
||||
static inline void range_start_decoding(void)
|
||||
{
|
||||
rc.buffer = read_byte();
|
||||
rc.low = rc.buffer >> (8 - EXTRA_BITS);
|
||||
rc.range = (uint32_t) 1 << EXTRA_BITS;
|
||||
}
|
||||
|
||||
static inline void range_dec_normalize(void)
|
||||
{
|
||||
while (rc.range <= BOTTOM_VALUE)
|
||||
{
|
||||
rc.buffer = (rc.buffer << 8) | read_byte();
|
||||
rc.low = (rc.low << 8) | ((rc.buffer >> 1) & 0xff);
|
||||
rc.range <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate culmulative frequency for next symbol. Does NO update!*/
|
||||
/* tot_f is the total frequency */
|
||||
/* or: totf is (code_value)1<<shift */
|
||||
/* returns the culmulative frequency */
|
||||
static inline int range_decode_culfreq(int tot_f)
|
||||
{ int tmp;
|
||||
|
||||
range_dec_normalize();
|
||||
|
||||
rc.help = rc.range / tot_f;
|
||||
tmp = rc.low / rc.help;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static inline int range_decode_culshift(int shift)
|
||||
{
|
||||
int tmp;
|
||||
range_dec_normalize();
|
||||
rc.help = rc.range>>shift;
|
||||
tmp = rc.low/rc.help;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/* Update decoding state */
|
||||
/* sy_f is the interval length (frequency of the symbol) */
|
||||
/* lt_f is the lower end (frequency sum of < symbols) */
|
||||
static inline void range_decode_update(int sy_f, int lt_f)
|
||||
{ int tmp;
|
||||
tmp = rc.help * lt_f;
|
||||
rc.low -= tmp;
|
||||
rc.range = rc.help * sy_f;
|
||||
}
|
||||
|
||||
|
||||
/* Decode a byte/short without modelling */
|
||||
static inline unsigned char decode_byte(void)
|
||||
{ int tmp = range_decode_culshift(8);
|
||||
range_decode_update( 1,tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static inline int short range_decode_short(void)
|
||||
{ int tmp = range_decode_culshift(16);
|
||||
range_decode_update( 1,tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* Decode n bits (n <= 16) without modelling - based on range_decode_short */
|
||||
static inline int range_decode_bits(int n)
|
||||
{ int tmp = range_decode_culshift(n);
|
||||
range_decode_update( 1,tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/* Finish decoding */
|
||||
static inline void range_done_decoding(void)
|
||||
{ range_dec_normalize(); /* normalize to use up all bytes */
|
||||
}
|
||||
140
apps/codecs/demac/libdemac/vector_math16.h
Normal file
140
apps/codecs/demac/libdemac/vector_math16.h
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
static inline void vector_add(int16_t* v1, int16_t* v2)
|
||||
{
|
||||
#if ORDER > 32
|
||||
int order = (ORDER >> 5);
|
||||
while (order--)
|
||||
#endif
|
||||
{
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
#if ORDER > 16
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
*v1++ += *v2++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static inline void vector_sub(int16_t* v1, int16_t* v2)
|
||||
{
|
||||
#if ORDER > 32
|
||||
int order = (ORDER >> 5);
|
||||
while (order--)
|
||||
#endif
|
||||
{
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
#if ORDER > 16
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
*v1++ -= *v2++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static inline int32_t scalarproduct(int16_t* v1, int16_t* v2)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
#if ORDER > 16
|
||||
int order = (ORDER >> 4);
|
||||
while (order--)
|
||||
#endif
|
||||
{
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
res += *v1++ * *v2++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
54
apps/codecs/demac/libdemac/vector_math32.h
Normal file
54
apps/codecs/demac/libdemac/vector_math32.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
/* 32-bit vector math functions */
|
||||
|
||||
#define scalarproduct4_rev32(x,y) ((x[0] * y[0]) + (x[1] * y[-1]) + \
|
||||
(x[2] * y[-2]) + (x[3] * y[-3]))
|
||||
|
||||
#define scalarproduct5_rev32(x,y) ((x[0] * y[0]) + (x[1] * y[-1]) + \
|
||||
(x[2] * y[-2]) + (x[3] * y[-3]) + \
|
||||
(x[4] * y[-4]))
|
||||
|
||||
#define vector_sub4_rev32(x, y) { x[0] -= y[0]; \
|
||||
x[1] -= y[-1]; \
|
||||
x[2] -= y[-2]; \
|
||||
x[3] -= y[-3]; }
|
||||
|
||||
#define vector_sub5_rev32(x, y) { x[0] -= y[0]; \
|
||||
x[1] -= y[-1]; \
|
||||
x[2] -= y[-2]; \
|
||||
x[3] -= y[-3]; \
|
||||
x[4] -= y[-4]; }
|
||||
|
||||
#define vector_add4_rev32(x, y) { x[0] += y[0]; \
|
||||
x[1] += y[-1]; \
|
||||
x[2] += y[-2]; \
|
||||
x[3] += y[-3]; }
|
||||
|
||||
#define vector_add5_rev32(x, y) { x[0] += y[0]; \
|
||||
x[1] += y[-1]; \
|
||||
x[2] += y[-2]; \
|
||||
x[3] += y[-3]; \
|
||||
x[4] += y[-4]; }
|
||||
107
apps/codecs/demac/wavwrite.c
Normal file
107
apps/codecs/demac/wavwrite.c
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
|
||||
demac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
|
||||
static unsigned char wav_header[44]={
|
||||
'R','I','F','F',// 0 - ChunkID
|
||||
0,0,0,0, // 4 - ChunkSize (filesize-8)
|
||||
'W','A','V','E',// 8 - Format
|
||||
'f','m','t',' ',// 12 - SubChunkID
|
||||
16,0,0,0, // 16 - SubChunk1ID // 16 for PCM
|
||||
1,0, // 20 - AudioFormat (1=Uncompressed)
|
||||
2,0, // 22 - NumChannels
|
||||
0,0,0,0, // 24 - SampleRate in Hz
|
||||
0,0,0,0, // 28 - Byte Rate (SampleRate*NumChannels*(BitsPerSample/8)
|
||||
4,0, // 32 - BlockAlign (== NumChannels * BitsPerSample/8)
|
||||
16,0, // 34 - BitsPerSample
|
||||
'd','a','t','a',// 36 - Subchunk2ID
|
||||
0,0,0,0 // 40 - Subchunk2Size
|
||||
};
|
||||
|
||||
int open_wav(struct ape_ctx_t* ape_ctx, char* filename)
|
||||
{
|
||||
int fd;
|
||||
int x;
|
||||
int filesize;
|
||||
int bytespersample;
|
||||
|
||||
fd=creat(filename,0644);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
bytespersample=ape_ctx->bps/8;
|
||||
|
||||
filesize=ape_ctx->totalsamples*bytespersample*ape_ctx->channels+44;
|
||||
|
||||
// ChunkSize
|
||||
x=filesize-8;
|
||||
wav_header[4]=(x&0xff);
|
||||
wav_header[5]=(x&0xff00)>>8;
|
||||
wav_header[6]=(x&0xff0000)>>16;
|
||||
wav_header[7]=(x&0xff000000)>>24;
|
||||
|
||||
// Number of channels
|
||||
wav_header[22]=ape_ctx->channels;
|
||||
|
||||
// Samplerate
|
||||
wav_header[24]=ape_ctx->samplerate&0xff;
|
||||
wav_header[25]=(ape_ctx->samplerate&0xff00)>>8;
|
||||
wav_header[26]=(ape_ctx->samplerate&0xff0000)>>16;
|
||||
wav_header[27]=(ape_ctx->samplerate&0xff000000)>>24;
|
||||
|
||||
// ByteRate
|
||||
x=ape_ctx->samplerate*(ape_ctx->bps/8)*ape_ctx->channels;
|
||||
wav_header[28]=(x&0xff);
|
||||
wav_header[29]=(x&0xff00)>>8;
|
||||
wav_header[30]=(x&0xff0000)>>16;
|
||||
wav_header[31]=(x&0xff000000)>>24;
|
||||
|
||||
// BlockAlign
|
||||
wav_header[32]=(ape_ctx->bps/8)*ape_ctx->channels;
|
||||
|
||||
// Bits per sample
|
||||
wav_header[34]=ape_ctx->bps;
|
||||
|
||||
// Subchunk2Size
|
||||
x=filesize-44;
|
||||
wav_header[40]=(x&0xff);
|
||||
wav_header[41]=(x&0xff00)>>8;
|
||||
wav_header[42]=(x&0xff0000)>>16;
|
||||
wav_header[43]=(x&0xff000000)>>24;
|
||||
|
||||
write(fd,wav_header,sizeof(wav_header));
|
||||
|
||||
return fd;
|
||||
}
|
||||
32
apps/codecs/demac/wavwrite.h
Normal file
32
apps/codecs/demac/wavwrite.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
|
||||
demac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _APE_WAVWRITE_H
|
||||
#define _APE_WAVWRITE_H
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
int open_wav(struct ape_ctx_t* ape_ctx, char* filename);
|
||||
|
||||
#endif
|
||||
|
|
@ -76,6 +76,8 @@ const struct filetype inbuilt_filetypes[] = {
|
|||
{ "nsf", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
|
||||
{ "nsfe",FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
|
||||
{ "spc", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
|
||||
{ "ape", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
|
||||
{ "mac", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
|
||||
#endif
|
||||
{ "m3u", FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST },
|
||||
{ "m3u8",FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST },
|
||||
|
|
|
|||
|
|
@ -982,6 +982,56 @@ static bool get_flac_metadata(int fd, struct mp3entry* id3)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool get_monkeys_metadata(int fd, struct mp3entry* id3)
|
||||
{
|
||||
/* Use the trackname part of the id3 structure as a temporary buffer */
|
||||
unsigned char* buf = (unsigned char *)id3->path;
|
||||
unsigned char* header;
|
||||
bool rc = false;
|
||||
uint32_t descriptorlength;
|
||||
uint32_t totalsamples;
|
||||
uint32_t blocksperframe, finalframeblocks, totalframes;
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
if (read(fd, buf, 4) < 4)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (memcmp(buf, "MAC ", 4) != 0)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
read(fd, buf + 4, MAX_PATH - 4);
|
||||
|
||||
descriptorlength = buf[8] | (buf[9] << 8) |
|
||||
(buf[10] << 16) | (buf[11] << 24);
|
||||
|
||||
header = buf + descriptorlength;
|
||||
|
||||
blocksperframe = header[4] | (header[5] << 8) |
|
||||
(header[6] << 16) | (header[7] << 24);
|
||||
finalframeblocks = header[8] | (header[9] << 8) |
|
||||
(header[10] << 16) | (header[11] << 24);
|
||||
totalframes = header[12] | (header[13] << 8) |
|
||||
(header[14] << 16) | (header[15] << 24);
|
||||
|
||||
id3->vbr = true; /* All FLAC files are VBR */
|
||||
id3->filesize = filesize(fd);
|
||||
id3->frequency = header[20] | (header[21] << 8) |
|
||||
(header[22] << 16) | (header[23] << 24);
|
||||
|
||||
totalsamples = finalframeblocks;
|
||||
if (totalframes > 1)
|
||||
totalsamples += blocksperframe * (totalframes-1);
|
||||
|
||||
id3->length = ((int64_t) totalsamples * 1000) / id3->frequency;
|
||||
id3->bitrate = (id3->filesize * 8) / id3->length;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool get_wave_metadata(int fd, struct mp3entry* id3)
|
||||
{
|
||||
/* Use the trackname part of the id3 structure as a temporary buffer */
|
||||
|
|
@ -2152,6 +2202,14 @@ bool get_metadata(struct track_info* track, int fd, const char* trackname,
|
|||
|
||||
break;
|
||||
|
||||
case AFMT_APE:
|
||||
if (!get_monkeys_metadata(fd, &(track->id3)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
read_ape_tags(fd, &(track->id3));
|
||||
break;
|
||||
|
||||
case AFMT_MPC:
|
||||
if (!get_musepack_metadata(fd, &(track->id3)))
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ enum
|
|||
AFMT_NSF, /* NESM (NES Sound Format) */
|
||||
AFMT_SPEEX, /* Ogg Speex speech */
|
||||
AFMT_SPC, /* SPC700 save state */
|
||||
AFMT_APE, /* Monkey's Audio (APE) */
|
||||
#endif
|
||||
|
||||
/* add new formats at any index above this line to have a sensible order -
|
||||
|
|
|
|||
|
|
@ -107,6 +107,9 @@ const struct afmt_entry audio_formats[AFMT_NUM_CODECS] =
|
|||
/* SPC700 Save State */
|
||||
[AFMT_SPC] =
|
||||
AFMT_ENTRY("SPC", "spc", NULL, "spc\0" ),
|
||||
/* APE (Monkey's Audio) */
|
||||
[AFMT_APE] =
|
||||
AFMT_ENTRY("APE", "ape", NULL, "ape\0mac\0" ),
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
|||
38
tools/configure
vendored
38
tools/configure
vendored
|
|
@ -756,7 +756,7 @@ EOF
|
|||
archosrom=""
|
||||
flash="$pwd/rombox.iriver"
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
toolset=$iriverbitmaptools
|
||||
|
|
@ -781,7 +781,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
toolset=$iriverbitmaptools
|
||||
|
|
@ -806,7 +806,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
toolset=$iriverbitmaptools
|
||||
|
|
@ -831,7 +831,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
toolset="$iaudiobitmaptools"
|
||||
|
|
@ -857,7 +857,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
toolset="$iaudiobitmaptools"
|
||||
|
|
@ -881,7 +881,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
bootoutput="bootloader-$archos.ipod"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
|
|
@ -906,7 +906,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
bootoutput="bootloader-$archos.ipod"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
|
|
@ -930,7 +930,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
bootoutput="bootloader-$archos.ipod"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
|
|
@ -955,7 +955,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
bootoutput="bootloader-$archos.ipod"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
|
|
@ -980,7 +980,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
bootoutput="bootloader-$archos.ipod"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
|
|
@ -1005,7 +1005,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
bootoutput="bootloader-$archos.ipod"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
|
|
@ -1030,7 +1030,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
toolset=$genericbitmaptools
|
||||
|
|
@ -1053,7 +1053,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
toolset=$gigabeatbitmaptools
|
||||
boottool="$rootdir/tools/scramble -gigabeat"
|
||||
bootoutput="FWIMG01.DAT"
|
||||
|
|
@ -1077,7 +1077,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
bootoutput="bootloader-$archos.ipod"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
|
|
@ -1102,7 +1102,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
boottool="$rootdir/tools/scramble -mi4v3 -model=h10 -type=RBBL"
|
||||
bootoutput="H10_20GC.mi4"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
|
|
@ -1128,7 +1128,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
boottool="$rootdir/tools/scramble -mi4v2 -model=h105 -type=RBBL"
|
||||
bootoutput="H10.mi4"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
|
|
@ -1154,7 +1154,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
boottool="$rootdir/tools/scramble -mi4v3 -model=e200 -type=RBBL"
|
||||
bootoutput="PP5022.mi4"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
|
|
@ -1183,7 +1183,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
boottool="$rootdir/tools/scramble -mi4r -model=e20r -type=RBBL"
|
||||
bootoutput="pp5022.mi4"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
|
|
@ -1209,7 +1209,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
boottool="$rootdir/tools/scramble -mi4v2"
|
||||
bootoutput="pp5020.mi4"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue