summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2007-06-05 16:58:29 +0000
committerDave Chapman <dave@dchapman.com>2007-06-05 16:58:29 +0000
commit520274219a0745384cb9bc6df4d7ee7905090f5d (patch)
tree8d6f4536b6758d00e72a2a9457f892ce28a591bd
parent887b31c01aebb46c0fcc6910241a4a64d9e7991e (diff)
downloadrockbox-520274219a0745384cb9bc6df4d7ee7905090f5d.tar.gz
rockbox-520274219a0745384cb9bc6df4d7ee7905090f5d.zip
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
-rw-r--r--apps/codecs/Makefile16
-rw-r--r--apps/codecs/SOURCES1
-rw-r--r--apps/codecs/ape.c162
-rw-r--r--apps/codecs/demac/COPYING339
-rw-r--r--apps/codecs/demac/Makefile43
-rw-r--r--apps/codecs/demac/README69
-rw-r--r--apps/codecs/demac/demac.c272
-rw-r--r--apps/codecs/demac/libdemac/Makefile43
-rw-r--r--apps/codecs/demac/libdemac/SOURCES10
-rw-r--r--apps/codecs/demac/libdemac/crc.c119
-rw-r--r--apps/codecs/demac/libdemac/decoder.c184
-rw-r--r--apps/codecs/demac/libdemac/decoder.h40
-rw-r--r--apps/codecs/demac/libdemac/demac.h45
-rw-r--r--apps/codecs/demac/libdemac/entropy.c314
-rw-r--r--apps/codecs/demac/libdemac/entropy.h40
-rw-r--r--apps/codecs/demac/libdemac/filter.c215
-rw-r--r--apps/codecs/demac/libdemac/filter.h48
-rw-r--r--apps/codecs/demac/libdemac/filter_1280_15.c27
-rw-r--r--apps/codecs/demac/libdemac/filter_16_11.c27
-rw-r--r--apps/codecs/demac/libdemac/filter_256_13.c27
-rw-r--r--apps/codecs/demac/libdemac/filter_32_10.c27
-rw-r--r--apps/codecs/demac/libdemac/filter_64_11.c27
-rw-r--r--apps/codecs/demac/libdemac/parser.c357
-rw-r--r--apps/codecs/demac/libdemac/parser.h137
-rw-r--r--apps/codecs/demac/libdemac/predictor.c196
-rw-r--r--apps/codecs/demac/libdemac/predictor.h36
-rw-r--r--apps/codecs/demac/libdemac/rangecoding.h180
-rw-r--r--apps/codecs/demac/libdemac/vector_math16.h140
-rw-r--r--apps/codecs/demac/libdemac/vector_math32.h54
-rw-r--r--apps/codecs/demac/wavwrite.c107
-rw-r--r--apps/codecs/demac/wavwrite.h32
-rw-r--r--apps/filetypes.c2
-rw-r--r--apps/metadata.c58
-rw-r--r--firmware/export/id3.h1
-rw-r--r--firmware/id3.c3
-rwxr-xr-xtools/configure38
36 files changed, 3413 insertions, 23 deletions
diff --git a/apps/codecs/Makefile b/apps/codecs/Makefile
index cece4ad3d0..ba54333104 100644
--- a/apps/codecs/Makefile
+++ b/apps/codecs/Makefile
@@ -17,7 +17,7 @@ ifdef APPEXTRA
17endif 17endif
18 18
19ifdef SOFTWARECODECS 19ifdef SOFTWARECODECS
20 CODECLIBS = -lmad -la52 -lffmpegFLAC -lTremor -lwavpack -lmusepack -lalac -lfaad -lm4a -lspeex 20 CODECLIBS = -lmad -la52 -lffmpegFLAC -lTremor -lwavpack -lmusepack -lalac -lfaad -lm4a -lspeex -ldemac
21endif 21endif
22 22
23# we "borrow" the plugin LDS file 23# we "borrow" the plugin LDS file
@@ -39,7 +39,7 @@ DIRS = .
39 39
40CODECDEPS = $(LINKCODEC) $(BUILDDIR)/libcodec.a 40CODECDEPS = $(LINKCODEC) $(BUILDDIR)/libcodec.a
41 41
42.PHONY: libmad liba52 libffmpegFLAC libTremor libspeex libwavpack libmusepack libalac libfaad libm4a 42.PHONY: libmad liba52 libffmpegFLAC libTremor libspeex libwavpack libmusepack libalac libfaad libm4a libdemac
43 43
44OUTPUT = $(SOFTWARECODECS) 44OUTPUT = $(SOFTWARECODECS)
45 45
@@ -64,6 +64,7 @@ $(OBJDIR)/wavpack.elf : $(OBJDIR)/wavpack.o $(BUILDDIR)/libwavpack.a $(OBJDIR)/c
64$(OBJDIR)/alac.elf : $(OBJDIR)/alac.o $(BUILDDIR)/libalac.a $(BUILDDIR)/libm4a.a $(OBJDIR)/codec_crt0.o 64$(OBJDIR)/alac.elf : $(OBJDIR)/alac.o $(BUILDDIR)/libalac.a $(BUILDDIR)/libm4a.a $(OBJDIR)/codec_crt0.o
65$(OBJDIR)/aac.elf : $(OBJDIR)/aac.o $(BUILDDIR)/libfaad.a $(BUILDDIR)/libm4a.a $(OBJDIR)/codec_crt0.o 65$(OBJDIR)/aac.elf : $(OBJDIR)/aac.o $(BUILDDIR)/libfaad.a $(BUILDDIR)/libm4a.a $(OBJDIR)/codec_crt0.o
66$(OBJDIR)/shorten.elf : $(OBJDIR)/shorten.o $(BUILDDIR)/libffmpegFLAC.a $(OBJDIR)/codec_crt0.o 66$(OBJDIR)/shorten.elf : $(OBJDIR)/shorten.o $(BUILDDIR)/libffmpegFLAC.a $(OBJDIR)/codec_crt0.o
67$(OBJDIR)/ape.elf : $(OBJDIR)/ape.o $(BUILDDIR)/libdemac.a $(OBJDIR)/codec_crt0.o
67$(OBJDIR)/aiff_enc.elf: $(OBJDIR)/aiff_enc.o $(OBJDIR)/codec_crt0.o 68$(OBJDIR)/aiff_enc.elf: $(OBJDIR)/aiff_enc.o $(OBJDIR)/codec_crt0.o
68$(OBJDIR)/mp3_enc.elf: $(OBJDIR)/mp3_enc.o $(OBJDIR)/codec_crt0.o 69$(OBJDIR)/mp3_enc.elf: $(OBJDIR)/mp3_enc.o $(OBJDIR)/codec_crt0.o
69$(OBJDIR)/wav_enc.elf: $(OBJDIR)/wav_enc.o $(OBJDIR)/codec_crt0.o 70$(OBJDIR)/wav_enc.elf: $(OBJDIR)/wav_enc.o $(OBJDIR)/codec_crt0.o
@@ -198,18 +199,25 @@ libfaad:
198 $(SILENT)mkdir -p $(OBJDIR)/libfaad 199 $(SILENT)mkdir -p $(OBJDIR)/libfaad
199 $(call PRINTS,MAKE in libfaad)$(MAKE) -C libfaad OBJDIR=$(OBJDIR)/libfaad OUTPUT=$(BUILDDIR)/libfaad.a 200 $(call PRINTS,MAKE in libfaad)$(MAKE) -C libfaad OBJDIR=$(OBJDIR)/libfaad OUTPUT=$(BUILDDIR)/libfaad.a
200 201
202$(BUILDDIR)/libdemac.a: libdemac
203
204libdemac:
205 $(SILENT)mkdir -p $(OBJDIR)/libdemac
206 $(call PRINTS,MAKE in libdemac)$(MAKE) -C demac/libdemac OBJDIR=$(OBJDIR)/libdemac OUTPUT=$(BUILDDIR)/libdemac.a
207
201clean: 208clean:
202 $(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 209 $(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
203 $(SILENT)$(MAKE) -C libmad clean OBJDIR=$(OBJDIR)/libmad 210 $(SILENT)$(MAKE) -C libmad clean OBJDIR=$(OBJDIR)/libmad
204 $(SILENT)$(MAKE) -C liba52 clean OBJDIR=$(OBJDIR)/liba52 211 $(SILENT)$(MAKE) -C liba52 clean OBJDIR=$(OBJDIR)/liba52
205 $(SILENT)$(MAKE) -C libffmpegFLAC clean OBJDIR=$(OBJDIR)/libffmpegFLAC 212 $(SILENT)$(MAKE) -C libffmpegFLAC clean OBJDIR=$(OBJDIR)/libffmpegFLAC
206 $(SILENT)$(MAKE) -C Tremor clean OBJDIR=$(OBJDIR)/Tremor 213 $(SILENT)$(MAKE) -C Tremor clean OBJDIR=$(OBJDIR)/Tremor
207 $(SILENT)$(MAKE) -C libspeex clean OBJDIR=$(OBJDIR)/libspeex 214 $(SILENT)$(MAKE) -C libspeex clean OBJDIR=$(OBJDIR)/libspeex
208 $(SILENT)$(MAKE) -C libwavpack clean OBJDIR=$(OBJDIR)/libwavpack 215 $(SILENT)$(MAKE) -C libwavpack clean OBJDIR=$(OBJDIR)/libwavpack
209 $(SILENT)$(MAKE) -C libmusepack clean OBJDIR=$(OBJDIR)/libmusepack 216 $(SILENT)$(MAKE) -C libmusepack clean OBJDIR=$(OBJDIR)/libmusepack
210 $(SILENT)$(MAKE) -C libalac clean OBJDIR=$(OBJDIR)/libalac 217 $(SILENT)$(MAKE) -C libalac clean OBJDIR=$(OBJDIR)/libalac
211 $(SILENT)$(MAKE) -C libfaad clean OBJDIR=$(OBJDIR)/libfaad 218 $(SILENT)$(MAKE) -C libfaad clean OBJDIR=$(OBJDIR)/libfaad
212 $(SILENT)$(MAKE) -C libm4a clean OBJDIR=$(OBJDIR)/libm4a 219 $(SILENT)$(MAKE) -C libm4a clean OBJDIR=$(OBJDIR)/libm4a
220 $(SILENT)$(MAKE) -C demac/libdemac clean OBJDIR=$(OBJDIR)/libdemac
213 $(SILENT)$(MAKE) -C lib clean OBJDIR=$(OBJDIR)/lib 221 $(SILENT)$(MAKE) -C lib clean OBJDIR=$(OBJDIR)/lib
214 222
215ifneq ($(MAKECMDGOALS),clean) 223ifneq ($(MAKECMDGOALS),clean)
diff --git a/apps/codecs/SOURCES b/apps/codecs/SOURCES
index 123a9c0f3f..7a3d4055cc 100644
--- a/apps/codecs/SOURCES
+++ b/apps/codecs/SOURCES
@@ -11,6 +11,7 @@ alac.c
11#if MEMORYSIZE > 1 11#if MEMORYSIZE > 1
12aac.c 12aac.c
13#endif 13#endif
14ape.c
14shorten.c 15shorten.c
15aiff.c 16aiff.c
16speex.c 17speex.c
diff --git a/apps/codecs/ape.c b/apps/codecs/ape.c
new file mode 100644
index 0000000000..b77abc0c74
--- /dev/null
+++ b/apps/codecs/ape.c
@@ -0,0 +1,162 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Dave Chapman
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "codeclib.h"
21#define ROCKBOX
22#include <codecs/demac/libdemac/demac.h>
23
24CODEC_HEADER
25
26#define BLOCKS_PER_LOOP 4608
27#define MAX_CHANNELS 2
28#define MAX_BYTESPERSAMPLE 3
29
30#define INPUT_CHUNKSIZE (32*1024)
31
32/* 4608*4 = 18432 bytes per channel */
33static int32_t decoded0[BLOCKS_PER_LOOP] IBSS_ATTR;
34static int32_t decoded1[BLOCKS_PER_LOOP] IBSS_ATTR;
35
36#define MAX_SUPPORTED_SEEKTABLE_SIZE 5000
37
38/* this is the codec entry point */
39enum codec_status codec_main(void)
40{
41 struct ape_ctx_t ape_ctx;
42 uint32_t samplesdone;
43 uint32_t elapsedtime;
44 size_t bytesleft;
45 int retval;
46
47 uint32_t currentframe;
48 int nblocks;
49 int bytesconsumed;
50 unsigned char* inbuffer;
51 int blockstodecode;
52 int res;
53 int firstbyte;
54
55 /* Generic codec initialisation */
56 ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
57 ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, 1024*128);
58
59 ci->configure(DSP_SET_SAMPLE_DEPTH, APE_OUTPUT_DEPTH-1);
60
61 next_track:
62
63 if (codec_init()) {
64 LOGF("APE: Error initialising codec\n");
65 retval = CODEC_ERROR;
66 goto exit;
67 }
68
69 inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE);
70
71 /* Read the file headers to populate the ape_ctx struct */
72 if (ape_parseheaderbuf(inbuffer,&ape_ctx) < 0) {
73 LOGF("APE: Error reading header\n");
74 retval = CODEC_ERROR;
75 goto exit;
76 }
77 ci->advance_buffer(ape_ctx.firstframe);
78
79 while (!*ci->taginfo_ready && !ci->stop_codec)
80 ci->sleep(1);
81
82 ci->configure(DSP_SWITCH_FREQUENCY, ape_ctx.samplerate);
83 ci->configure(DSP_SET_STEREO_MODE, ape_ctx.channels == 1 ?
84 STEREO_MONO : STEREO_NONINTERLEAVED);
85 codec_set_replaygain(ci->id3);
86
87 /* The main decoding loop */
88
89 currentframe = 0;
90 samplesdone = 0;
91
92 /* Initialise the buffer */
93 inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE);
94 firstbyte = 3; /* Take account of the little-endian 32-bit byte ordering */
95
96 /* The main decoding loop - we decode the frames a small chunk at a time */
97 while (currentframe < ape_ctx.totalframes)
98 {
99 /* Calculate how many blocks there are in this frame */
100 if (currentframe == (ape_ctx.totalframes - 1))
101 nblocks = ape_ctx.finalframeblocks;
102 else
103 nblocks = ape_ctx.blocksperframe;
104
105 ape_ctx.currentframeblocks = nblocks;
106
107 /* Initialise the frame decoder */
108 init_frame_decoder(&ape_ctx, inbuffer, &firstbyte, &bytesconsumed);
109
110 ci->advance_buffer(bytesconsumed);
111 inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE);
112
113 /* Decode the frame a chunk at a time */
114 while (nblocks > 0)
115 {
116 ci->yield();
117 if (ci->stop_codec || ci->new_track) {
118 break;
119 }
120
121 blockstodecode = MIN(BLOCKS_PER_LOOP, nblocks);
122
123 if ((res = decode_chunk(&ape_ctx, inbuffer, &firstbyte,
124 &bytesconsumed,
125 decoded0, decoded1,
126 blockstodecode)) < 0)
127 {
128 /* Frame decoding error, abort */
129 LOGF("APE: Frame %d, error %d\n",currentframe,res);
130 retval = CODEC_ERROR;
131 goto done;
132 }
133
134 ci->yield();
135 ci->pcmbuf_insert(decoded0, decoded1, blockstodecode);
136
137 /* Update the elapsed-time indicator */
138 samplesdone += blockstodecode;
139 elapsedtime = (samplesdone*10)/(ape_ctx.samplerate/100);
140 ci->set_elapsed(elapsedtime);
141
142 ci->advance_buffer(bytesconsumed);
143 inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE);
144
145 /* Decrement the block count */
146 nblocks -= blockstodecode;
147 }
148
149 currentframe++;
150 }
151
152 retval = CODEC_OK;
153
154done:
155 LOGF("APE: Decoded %ld samples\n",samplesdone);
156
157 if (ci->request_next_track())
158 goto next_track;
159
160exit:
161 return retval;
162}
diff --git a/apps/codecs/demac/COPYING b/apps/codecs/demac/COPYING
new file mode 100644
index 0000000000..d511905c16
--- /dev/null
+++ b/apps/codecs/demac/COPYING
@@ -0,0 +1,339 @@
1 GNU GENERAL PUBLIC LICENSE
2 Version 2, June 1991
3
4 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9 Preamble
10
11 The licenses for most software are designed to take away your
12freedom to share and change it. By contrast, the GNU General Public
13License is intended to guarantee your freedom to share and change free
14software--to make sure the software is free for all its users. This
15General Public License applies to most of the Free Software
16Foundation's software and to any other program whose authors commit to
17using it. (Some other Free Software Foundation software is covered by
18the GNU Lesser General Public License instead.) You can apply it to
19your programs, too.
20
21 When we speak of free software, we are referring to freedom, not
22price. Our General Public Licenses are designed to make sure that you
23have the freedom to distribute copies of free software (and charge for
24this service if you wish), that you receive source code or can get it
25if you want it, that you can change the software or use pieces of it
26in new free programs; and that you know you can do these things.
27
28 To protect your rights, we need to make restrictions that forbid
29anyone to deny you these rights or to ask you to surrender the rights.
30These restrictions translate to certain responsibilities for you if you
31distribute copies of the software, or if you modify it.
32
33 For example, if you distribute copies of such a program, whether
34gratis or for a fee, you must give the recipients all the rights that
35you have. You must make sure that they, too, receive or can get the
36source code. And you must show them these terms so they know their
37rights.
38
39 We protect your rights with two steps: (1) copyright the software, and
40(2) offer you this license which gives you legal permission to copy,
41distribute and/or modify the software.
42
43 Also, for each author's protection and ours, we want to make certain
44that everyone understands that there is no warranty for this free
45software. If the software is modified by someone else and passed on, we
46want its recipients to know that what they have is not the original, so
47that any problems introduced by others will not reflect on the original
48authors' reputations.
49
50 Finally, any free program is threatened constantly by software
51patents. We wish to avoid the danger that redistributors of a free
52program will individually obtain patent licenses, in effect making the
53program proprietary. To prevent this, we have made it clear that any
54patent must be licensed for everyone's free use or not licensed at all.
55
56 The precise terms and conditions for copying, distribution and
57modification follow.
58
59 GNU GENERAL PUBLIC LICENSE
60 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
62 0. This License applies to any program or other work which contains
63a notice placed by the copyright holder saying it may be distributed
64under the terms of this General Public License. The "Program", below,
65refers to any such program or work, and a "work based on the Program"
66means either the Program or any derivative work under copyright law:
67that is to say, a work containing the Program or a portion of it,
68either verbatim or with modifications and/or translated into another
69language. (Hereinafter, translation is included without limitation in
70the term "modification".) Each licensee is addressed as "you".
71
72Activities other than copying, distribution and modification are not
73covered by this License; they are outside its scope. The act of
74running the Program is not restricted, and the output from the Program
75is covered only if its contents constitute a work based on the
76Program (independent of having been made by running the Program).
77Whether that is true depends on what the Program does.
78
79 1. You may copy and distribute verbatim copies of the Program's
80source code as you receive it, in any medium, provided that you
81conspicuously and appropriately publish on each copy an appropriate
82copyright notice and disclaimer of warranty; keep intact all the
83notices that refer to this License and to the absence of any warranty;
84and give any other recipients of the Program a copy of this License
85along with the Program.
86
87You may charge a fee for the physical act of transferring a copy, and
88you may at your option offer warranty protection in exchange for a fee.
89
90 2. You may modify your copy or copies of the Program or any portion
91of it, thus forming a work based on the Program, and copy and
92distribute such modifications or work under the terms of Section 1
93above, provided that you also meet all of these conditions:
94
95 a) You must cause the modified files to carry prominent notices
96 stating that you changed the files and the date of any change.
97
98 b) You must cause any work that you distribute or publish, that in
99 whole or in part contains or is derived from the Program or any
100 part thereof, to be licensed as a whole at no charge to all third
101 parties under the terms of this License.
102
103 c) If the modified program normally reads commands interactively
104 when run, you must cause it, when started running for such
105 interactive use in the most ordinary way, to print or display an
106 announcement including an appropriate copyright notice and a
107 notice that there is no warranty (or else, saying that you provide
108 a warranty) and that users may redistribute the program under
109 these conditions, and telling the user how to view a copy of this
110 License. (Exception: if the Program itself is interactive but
111 does not normally print such an announcement, your work based on
112 the Program is not required to print an announcement.)
113
114These requirements apply to the modified work as a whole. If
115identifiable sections of that work are not derived from the Program,
116and can be reasonably considered independent and separate works in
117themselves, then this License, and its terms, do not apply to those
118sections when you distribute them as separate works. But when you
119distribute the same sections as part of a whole which is a work based
120on the Program, the distribution of the whole must be on the terms of
121this License, whose permissions for other licensees extend to the
122entire whole, and thus to each and every part regardless of who wrote it.
123
124Thus, it is not the intent of this section to claim rights or contest
125your rights to work written entirely by you; rather, the intent is to
126exercise the right to control the distribution of derivative or
127collective works based on the Program.
128
129In addition, mere aggregation of another work not based on the Program
130with the Program (or with a work based on the Program) on a volume of
131a storage or distribution medium does not bring the other work under
132the scope of this License.
133
134 3. You may copy and distribute the Program (or a work based on it,
135under Section 2) in object code or executable form under the terms of
136Sections 1 and 2 above provided that you also do one of the following:
137
138 a) Accompany it with the complete corresponding machine-readable
139 source code, which must be distributed under the terms of Sections
140 1 and 2 above on a medium customarily used for software interchange; or,
141
142 b) Accompany it with a written offer, valid for at least three
143 years, to give any third party, for a charge no more than your
144 cost of physically performing source distribution, a complete
145 machine-readable copy of the corresponding source code, to be
146 distributed under the terms of Sections 1 and 2 above on a medium
147 customarily used for software interchange; or,
148
149 c) Accompany it with the information you received as to the offer
150 to distribute corresponding source code. (This alternative is
151 allowed only for noncommercial distribution and only if you
152 received the program in object code or executable form with such
153 an offer, in accord with Subsection b above.)
154
155The source code for a work means the preferred form of the work for
156making modifications to it. For an executable work, complete source
157code means all the source code for all modules it contains, plus any
158associated interface definition files, plus the scripts used to
159control compilation and installation of the executable. However, as a
160special exception, the source code distributed need not include
161anything that is normally distributed (in either source or binary
162form) with the major components (compiler, kernel, and so on) of the
163operating system on which the executable runs, unless that component
164itself accompanies the executable.
165
166If distribution of executable or object code is made by offering
167access to copy from a designated place, then offering equivalent
168access to copy the source code from the same place counts as
169distribution of the source code, even though third parties are not
170compelled to copy the source along with the object code.
171
172 4. You may not copy, modify, sublicense, or distribute the Program
173except as expressly provided under this License. Any attempt
174otherwise to copy, modify, sublicense or distribute the Program is
175void, and will automatically terminate your rights under this License.
176However, parties who have received copies, or rights, from you under
177this License will not have their licenses terminated so long as such
178parties remain in full compliance.
179
180 5. You are not required to accept this License, since you have not
181signed it. However, nothing else grants you permission to modify or
182distribute the Program or its derivative works. These actions are
183prohibited by law if you do not accept this License. Therefore, by
184modifying or distributing the Program (or any work based on the
185Program), you indicate your acceptance of this License to do so, and
186all its terms and conditions for copying, distributing or modifying
187the Program or works based on it.
188
189 6. Each time you redistribute the Program (or any work based on the
190Program), the recipient automatically receives a license from the
191original licensor to copy, distribute or modify the Program subject to
192these terms and conditions. You may not impose any further
193restrictions on the recipients' exercise of the rights granted herein.
194You are not responsible for enforcing compliance by third parties to
195this License.
196
197 7. If, as a consequence of a court judgment or allegation of patent
198infringement or for any other reason (not limited to patent issues),
199conditions are imposed on you (whether by court order, agreement or
200otherwise) that contradict the conditions of this License, they do not
201excuse you from the conditions of this License. If you cannot
202distribute so as to satisfy simultaneously your obligations under this
203License and any other pertinent obligations, then as a consequence you
204may not distribute the Program at all. For example, if a patent
205license would not permit royalty-free redistribution of the Program by
206all those who receive copies directly or indirectly through you, then
207the only way you could satisfy both it and this License would be to
208refrain entirely from distribution of the Program.
209
210If any portion of this section is held invalid or unenforceable under
211any particular circumstance, the balance of the section is intended to
212apply and the section as a whole is intended to apply in other
213circumstances.
214
215It is not the purpose of this section to induce you to infringe any
216patents or other property right claims or to contest validity of any
217such claims; this section has the sole purpose of protecting the
218integrity of the free software distribution system, which is
219implemented by public license practices. Many people have made
220generous contributions to the wide range of software distributed
221through that system in reliance on consistent application of that
222system; it is up to the author/donor to decide if he or she is willing
223to distribute software through any other system and a licensee cannot
224impose that choice.
225
226This section is intended to make thoroughly clear what is believed to
227be a consequence of the rest of this License.
228
229 8. If the distribution and/or use of the Program is restricted in
230certain countries either by patents or by copyrighted interfaces, the
231original copyright holder who places the Program under this License
232may add an explicit geographical distribution limitation excluding
233those countries, so that distribution is permitted only in or among
234countries not thus excluded. In such case, this License incorporates
235the limitation as if written in the body of this License.
236
237 9. The Free Software Foundation may publish revised and/or new versions
238of the General Public License from time to time. Such new versions will
239be similar in spirit to the present version, but may differ in detail to
240address new problems or concerns.
241
242Each version is given a distinguishing version number. If the Program
243specifies a version number of this License which applies to it and "any
244later version", you have the option of following the terms and conditions
245either of that version or of any later version published by the Free
246Software Foundation. If the Program does not specify a version number of
247this License, you may choose any version ever published by the Free Software
248Foundation.
249
250 10. If you wish to incorporate parts of the Program into other free
251programs whose distribution conditions are different, write to the author
252to ask for permission. For software which is copyrighted by the Free
253Software Foundation, write to the Free Software Foundation; we sometimes
254make exceptions for this. Our decision will be guided by the two goals
255of preserving the free status of all derivatives of our free software and
256of promoting the sharing and reuse of software generally.
257
258 NO WARRANTY
259
260 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268REPAIR OR CORRECTION.
269
270 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278POSSIBILITY OF SUCH DAMAGES.
279
280 END OF TERMS AND CONDITIONS
281
282 How to Apply These Terms to Your New Programs
283
284 If you develop a new program, and you want it to be of the greatest
285possible use to the public, the best way to achieve this is to make it
286free software which everyone can redistribute and change under these terms.
287
288 To do so, attach the following notices to the program. It is safest
289to attach them to the start of each source file to most effectively
290convey the exclusion of warranty; and each file should have at least
291the "copyright" line and a pointer to where the full notice is found.
292
293 <one line to give the program's name and a brief idea of what it does.>
294 Copyright (C) <year> <name of author>
295
296 This program is free software; you can redistribute it and/or modify
297 it under the terms of the GNU General Public License as published by
298 the Free Software Foundation; either version 2 of the License, or
299 (at your option) any later version.
300
301 This program is distributed in the hope that it will be useful,
302 but WITHOUT ANY WARRANTY; without even the implied warranty of
303 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 GNU General Public License for more details.
305
306 You should have received a copy of the GNU General Public License along
307 with this program; if not, write to the Free Software Foundation, Inc.,
308 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309
310Also add information on how to contact you by electronic and paper mail.
311
312If the program is interactive, make it output a short notice like this
313when it starts in an interactive mode:
314
315 Gnomovision version 69, Copyright (C) year name of author
316 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 This is free software, and you are welcome to redistribute it
318 under certain conditions; type `show c' for details.
319
320The hypothetical commands `show w' and `show c' should show the appropriate
321parts of the General Public License. Of course, the commands you use may
322be called something other than `show w' and `show c'; they could even be
323mouse-clicks or menu items--whatever suits your program.
324
325You should also get your employer (if you work as a programmer) or your
326school, if any, to sign a "copyright disclaimer" for the program, if
327necessary. Here is a sample; alter the names:
328
329 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
332 <signature of Ty Coon>, 1 April 1989
333 Ty Coon, President of Vice
334
335This General Public License does not permit incorporating your program into
336proprietary programs. If your program is a subroutine library, you may
337consider it more useful to permit linking proprietary applications with the
338library. If this is what you want to do, use the GNU Lesser General
339Public License instead of this License.
diff --git a/apps/codecs/demac/Makefile b/apps/codecs/demac/Makefile
new file mode 100644
index 0000000000..e0ed4ad341
--- /dev/null
+++ b/apps/codecs/demac/Makefile
@@ -0,0 +1,43 @@
1# $Id:$
2
3FILTERS = 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
4LIBOBJS = libdemac/parser.o libdemac/decoder.o libdemac/entropy.o libdemac/predictor.o libdemac/crc.o $(FILTERS)
5OBJS = demac.o wavwrite.o $(LIBOBJS)
6
7CFLAGS = -Wall -O3 -Ilibdemac
8
9ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
10EXT = .exe
11CROSS =
12CFLAGS += -mno-cygwin
13else
14 ifdef WIN
15 EXT = .exe
16 CROSS = i586-mingw32msvc-
17 else
18 EXT =
19 CROSS =
20 endif
21endif
22
23CC = $(CROSS)gcc
24STRIP = $(CROSS)strip
25OUTPUT = demac$(EXT)
26
27all: $(OUTPUT)
28
29$(OUTPUT): $(OBJS)
30 $(CC) -o $(OUTPUT) $(OBJS)
31
32.c.o :
33 $(CC) $(CFLAGS) $(INC) -c -o $@ $<
34
35libdemac/filter_16_11.o: libdemac/filter.c
36libdemac/filter_64_11.o: libdemac/filter.c
37libdemac/filter_256_13.o: libdemac/filter.c
38libdemac/filter_1280_15.o: libdemac/filter.c
39libdemac/filter_32_10.o: libdemac/filter.c
40libdemac/entropy.o: libdemac/rangecoding.h
41
42clean:
43 rm -f $(OUTPUT) $(OBJS) *~ */*~
diff --git a/apps/codecs/demac/README b/apps/codecs/demac/README
new file mode 100644
index 0000000000..2fcdd95edf
--- /dev/null
+++ b/apps/codecs/demac/README
@@ -0,0 +1,69 @@
1demac - a decoder for Monkey's Audio files.
2
3Introduction
4
5demac is an implementation in portable ANSI C of a decoder for the
6Monkey's Audio lossless compression format. It has the following
7features:
8
9 * Open source (GNU GPL)
10 * Written in portable ANSI C
11 * Designed for use on low memory and embedded devices. All internal
12 buffers are statically declared - the core library doesn't require
13 malloc/free. This has the disadvantage that the library isn't
14 re-entrant.
15
16
17Compatibility
18
19
20libdemac is still in the early stages of development but has been
21relatively well tested with v3.99 files at all compression levels.
22
23v3.97 files have received less testing - 16-bit files seem to work,
24but 24-bit files are causing problems in the range decoder.
25
26Files earlier than v3.97 are not supported by libdemac, but support
27might be added in the future.
28
29
30Source Code
31
32The source code in this directory is structured as follows:
33
34demac/Makefile - Makefile for the standalone demac decoder
35demac/demac.c - Simple standalone test program to decoder an APE file to WAV
36demac/wavwrite.[ch] - Helper functions for demac.c
37demac/libdemac/Makefile - A Makefile for use in Rockbox
38demac/libdemac/*.[ch] - The main libdemac code
39
40
41Latest Version
42
43The latest version of demac and libdemac can always be found in the
44"apps/codecs/demac/" directory in the Rockbox source. You can check
45this out from svn with the command:
46
47svn co svn://svn.rockbox.org/rockbox/trunk/apps/codecs/demac demac
48
49Or browse the source code online here:
50
51http://svn.rockbox.org/viewvc.cgi/trunk/apps/codecs/demac
52
53
54
55Acknowledgements
56
57Thanks to Matt. T. Ashland for writing Monkey's Audio. His website
58can be found here: http://www.monkeysaudio.com
59
60
61Copyright and license
62
63
64libdemac is (C) 2007 Dave Chapman and is licensed under the GNU
65GPL. See the COPYING file in this directory.
66
67The exception is the majority of rangecoding.h, which is (C) 1997,
681998, 1999, 2000 Michael Schindler and is also licensed under the GPL.
69See that source file for full details.
diff --git a/apps/codecs/demac/demac.c b/apps/codecs/demac/demac.c
new file mode 100644
index 0000000000..da132ff248
--- /dev/null
+++ b/apps/codecs/demac/demac.c
@@ -0,0 +1,272 @@
1/*
2
3demac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25/*
26
27This example is intended to demonstrate how the decoder can be used in
28embedded devices - there is no usage of dynamic memory (i.e. no
29malloc/free) and small buffer sizes are chosen to minimise both the
30memory usage and decoding latency.
31
32This implementation requires the following memory and supports decoding of all APE files up to 24-bit Stereo.
33
3432768 - data from the input stream to be presented to the decoder in one contiguous chunk.
3518432 - decoding buffer (left channel)
3618432 - decoding buffer (right channel)
37
3817408+5120+2240 - buffers used for filter histories (compression levels 2000-5000)
39
40In addition, this example uses a static 27648 byte buffer as temporary
41storage for outputting the data to a WAV file but that could be
42avoided by writing the decoded data one sample at a time.
43
44*/
45
46#include <stdio.h>
47#include <inttypes.h>
48#include <stdlib.h>
49#include <sys/types.h>
50#include <sys/stat.h>
51#include <fcntl.h>
52#include <unistd.h>
53#include <string.h>
54
55#include "demac.h"
56#include "wavwrite.h"
57
58#ifndef __WIN32__
59#define O_BINARY 0
60#endif
61
62#define CALC_CRC 1
63
64#define BLOCKS_PER_LOOP 4608
65#define MAX_CHANNELS 2
66#define MAX_BYTESPERSAMPLE 3
67
68#define INPUT_CHUNKSIZE (32*1024)
69
70#ifndef MIN
71#define MIN(a,b) ((a) < (b) ? (a) : (b))
72#endif
73
74
75/* 4608*2*3 = 27648 bytes */
76static unsigned char wavbuffer[BLOCKS_PER_LOOP*MAX_CHANNELS*MAX_BYTESPERSAMPLE];
77
78/* 4608*4 = 18432 bytes per channel */
79static int32_t decoded0[BLOCKS_PER_LOOP];
80static int32_t decoded1[BLOCKS_PER_LOOP];
81
82/* We assume that 32KB of compressed data is enough to extract up to
83 27648 bytes of decompressed data. */
84
85static unsigned char inbuffer[INPUT_CHUNKSIZE];
86
87int ape_decode(char* infile, char* outfile)
88{
89 int fd;
90 int fdwav;
91 int currentframe;
92 int nblocks;
93 int bytesconsumed;
94 struct ape_ctx_t ape_ctx;
95 int i, n;
96 unsigned char* p;
97 int bytesinbuffer;
98 int blockstodecode;
99 int res;
100 int firstbyte;
101 int16_t sample16;
102 int32_t sample32;
103 uint32_t frame_crc;
104 int crc_errors = 0;
105
106 fd = open(infile,O_RDONLY|O_BINARY);
107 if (fd < 0) return -1;
108
109 /* Read the file headers to populate the ape_ctx struct */
110 if (ape_parseheader(fd,&ape_ctx) < 0) {
111 printf("Cannot read header\n");
112 close(fd);
113 return -1;
114 }
115
116 if ((ape_ctx.fileversion < APE_MIN_VERSION) || (ape_ctx.fileversion > APE_MAX_VERSION)) {
117 printf("Unsupported file version - %.2f\n", ape_ctx.fileversion/1000.0);
118 close(fd);
119 return -2;
120 }
121
122 //ape_dumpinfo(&ape_ctx);
123
124 printf("Decoding file - v%.2f, compression level %d\n",ape_ctx.fileversion/1000.0,ape_ctx.compressiontype);
125
126 /* Open the WAV file and write a canonical 44-byte WAV header
127 based on the audio format information in the ape_ctx struct.
128
129 NOTE: This example doesn't write the original WAV header and
130 tail data which are (optionally) stored in the APE file.
131 */
132 fdwav = open_wav(&ape_ctx,outfile);
133
134 currentframe = 0;
135
136 /* Initialise the buffer */
137 lseek(fd, ape_ctx.firstframe, SEEK_SET);
138 bytesinbuffer = read(fd, inbuffer, INPUT_CHUNKSIZE);
139 firstbyte = 3; /* Take account of the little-endian 32-bit byte ordering */
140
141 /* The main decoding loop - we decode the frames a small chunk at a time */
142 while (currentframe < ape_ctx.totalframes)
143 {
144 /* Calculate how many blocks there are in this frame */
145 if (currentframe == (ape_ctx.totalframes - 1))
146 nblocks = ape_ctx.finalframeblocks;
147 else
148 nblocks = ape_ctx.blocksperframe;
149
150 ape_ctx.currentframeblocks = nblocks;
151
152 /* Initialise the frame decoder */
153 init_frame_decoder(&ape_ctx, inbuffer, &firstbyte, &bytesconsumed);
154
155 /* Update buffer */
156 memmove(inbuffer,inbuffer + bytesconsumed, bytesinbuffer - bytesconsumed);
157 bytesinbuffer -= bytesconsumed;
158
159 n = read(fd, inbuffer + bytesinbuffer, INPUT_CHUNKSIZE - bytesinbuffer);
160 bytesinbuffer += n;
161
162#if CALC_CRC
163 frame_crc = ape_initcrc();
164#endif
165
166 /* Decode the frame a chunk at a time */
167 while (nblocks > 0)
168 {
169 blockstodecode = MIN(BLOCKS_PER_LOOP, nblocks);
170
171 if ((res = decode_chunk(&ape_ctx, inbuffer, &firstbyte,
172 &bytesconsumed,
173 decoded0, decoded1,
174 blockstodecode)) < 0)
175 {
176 /* Frame decoding error, abort */
177 close(fd);
178 return res;
179 }
180
181 /* Convert the output samples to WAV format and write to output file */
182 p = wavbuffer;
183 if (ape_ctx.bps == 16) {
184 for (i = 0 ; i < blockstodecode ; i++)
185 {
186 sample16 = decoded0[i];
187 *(p++) = sample16 & 0xff;
188 *(p++) = (sample16&0xff00) >> 8;
189
190 if (ape_ctx.channels == 2) {
191 sample16 = decoded1[i];
192 *(p++) = sample16 & 0xff;
193 *(p++) = (sample16&0xff00) >> 8;
194 }
195 }
196 } else if (ape_ctx.bps == 24) {
197 for (i = 0 ; i < blockstodecode ; i++)
198 {
199 sample32 = decoded0[i];
200 *(p++) = sample32 & 0xff;
201 *(p++) = (sample32&0xff00) >> 8;
202 *(p++) = (sample32&0xff0000) >> 16;
203
204 if (ape_ctx.channels == 2) {
205 sample32 = decoded1[i];
206 *(p++) = sample32 & 0xff;
207 *(p++) = (sample32&0xff00) >> 8;
208 *(p++) = (sample32&0xff0000) >> 16;
209 }
210 }
211 }
212
213#if CALC_CRC
214 frame_crc = ape_updatecrc(wavbuffer, p - wavbuffer, frame_crc);
215#endif
216 write(fdwav,wavbuffer,p - wavbuffer);
217
218 /* Update the buffer */
219 memmove(inbuffer,inbuffer + bytesconsumed, bytesinbuffer - bytesconsumed);
220 bytesinbuffer -= bytesconsumed;
221
222 n = read(fd, inbuffer + bytesinbuffer, INPUT_CHUNKSIZE - bytesinbuffer);
223 bytesinbuffer += n;
224
225 /* Decrement the block count */
226 nblocks -= blockstodecode;
227 }
228
229#if CALC_CRC
230 frame_crc = ape_finishcrc(frame_crc);
231
232 if (ape_ctx.CRC != frame_crc)
233 {
234 fprintf(stderr,"CRC error in frame %d\n",currentframe);
235 crc_errors++;
236 }
237#endif
238
239 currentframe++;
240 }
241
242 close(fd);
243 close(fdwav);
244
245 if (crc_errors > 0)
246 return -1;
247 else
248 return 0;
249}
250
251int main(int argc, char* argv[])
252{
253 int res;
254
255 if (argc != 3) {
256 fprintf(stderr,"Usage: demac infile.ape outfile.wav\n");
257 return 0;
258 }
259
260 res = ape_decode(argv[1], argv[2]);
261
262 if (res < 0)
263 {
264 fprintf(stderr,"DECODING ERROR %d, ABORTING\n", res);
265 }
266 else
267 {
268 fprintf(stderr,"DECODED OK - NO CRC ERRORS.\n");
269 }
270
271 return 0;
272}
diff --git a/apps/codecs/demac/libdemac/Makefile b/apps/codecs/demac/libdemac/Makefile
new file mode 100644
index 0000000000..7fc784dd5f
--- /dev/null
+++ b/apps/codecs/demac/libdemac/Makefile
@@ -0,0 +1,43 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id:$
8#
9
10INCLUDES=-I$(APPSDIR) -I.. -I. -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
11 -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(BUILDDIR)
12
13ifdef APPEXTRA
14 INCLUDES += $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA)))
15endif
16
17DEMACOPTS = -O3 -DROCKBOX
18CFLAGS = $(INCLUDES) $(GCCOPTS) $(TARGET_INC) $(DEMACOPTS) $(TARGET) \
19$(EXTRA_DEFINES) -DMEM=${MEMORYSIZE} $(PROFILE_OPTS)
20
21# This sets up 'SRC' based on the files mentioned in SOURCES
22include $(TOOLSDIR)/makesrc.inc
23
24SOURCES = $(SRC)
25OBJS2 := $(SRC:%.c=$(OBJDIR)/%.o)
26OBJS = $(patsubst %.S, $(OBJDIR)/%.o, $(OBJS2))
27DEPFILE = $(OBJDIR)/dep-libdemac
28DIRS =
29
30all: $(OUTPUT)
31
32$(OUTPUT): $(OBJS)
33 $(call PRINTS,AR+RANLIB $(@F))$(AR) ruv $@ $+ >/dev/null 2>&1
34 $(SILENT)$(RANLIB) $@
35
36include $(TOOLSDIR)/make.inc
37
38clean:
39 $(call PRINTS,cleaning libdemac)rm -f $(OBJS) $(OUTPUT) $(DEPFILE)
40
41ifneq ($(MAKECMDGOALS),clean)
42-include $(DEPFILE)
43endif
diff --git a/apps/codecs/demac/libdemac/SOURCES b/apps/codecs/demac/libdemac/SOURCES
new file mode 100644
index 0000000000..76b891a90d
--- /dev/null
+++ b/apps/codecs/demac/libdemac/SOURCES
@@ -0,0 +1,10 @@
1crc.c
2predictor.c
3entropy.c
4decoder.c
5parser.c
6filter_1280_15.c
7filter_16_11.c
8filter_256_13.c
9filter_32_10.c
10filter_64_11.c
diff --git a/apps/codecs/demac/libdemac/crc.c b/apps/codecs/demac/libdemac/crc.c
new file mode 100644
index 0000000000..c23de7d043
--- /dev/null
+++ b/apps/codecs/demac/libdemac/crc.c
@@ -0,0 +1,119 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#include <inttypes.h>
26
27static uint32_t crctab32[] =
28{
29 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
30 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
31 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
32 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
33 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
34 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
35 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
36 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
37 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
38 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
39 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
40 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
41 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
42 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
43 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
44 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
45
46 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
47 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
48 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
49 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
50 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
51 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
52 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
53 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
54 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
55 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
56 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
57 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
58 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
59 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
60 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
61 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
62
63 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
64 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
65 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
66 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
67 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
68 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
69 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
70 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
71 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
72 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
73 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
74 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
75 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
76 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
77 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
78 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
79
80 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
81 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
82 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
83 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
84 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
85 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
86 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
87 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
88 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
89 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
90 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
91 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
92 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
93 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
94 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
95 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
96};
97
98uint32_t ape_initcrc(void)
99{
100 return 0xffffffff;
101}
102
103/* Update the CRC from a block of WAV-format audio data */
104uint32_t ape_updatecrc(unsigned char *block, int count, uint32_t crc)
105{
106 while (count--)
107 crc = (crc >> 8) ^ crctab32[(crc & 0xff) ^ *block++];
108
109 return crc;
110}
111
112uint32_t ape_finishcrc(uint32_t crc)
113{
114 crc ^= 0xffffffff;
115 crc >>= 1;
116
117 return crc;
118}
119
diff --git a/apps/codecs/demac/libdemac/decoder.c b/apps/codecs/demac/libdemac/decoder.c
new file mode 100644
index 0000000000..22b6e8d325
--- /dev/null
+++ b/apps/codecs/demac/libdemac/decoder.c
@@ -0,0 +1,184 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#include <inttypes.h>
26#include <string.h>
27
28#include "demac.h"
29#include "predictor.h"
30#include "entropy.h"
31#include "filter.h"
32
33/* Statically allocate the filter buffers */
34
35static int16_t filterbuf32[(32*3 + HISTORY_SIZE) * 2] IBSS_ATTR; /* 4480 bytes */
36static int16_t filterbuf256[(256*3 + HISTORY_SIZE) * 2] IBSS_ATTR; /* 5120 bytes */
37
38/* This is only needed for "insane" files, and no Rockbox targets can
39 hope to decode them in realtime anyway. */
40static int16_t filterbuf1280[(1280*3 + HISTORY_SIZE) * 2]; /* 17408 bytes */
41
42void init_frame_decoder(struct ape_ctx_t* ape_ctx,
43 unsigned char* inbuffer, int* firstbyte,
44 int* bytesconsumed)
45{
46 init_entropy_decoder(ape_ctx, inbuffer, firstbyte, bytesconsumed);
47 //printf("CRC=0x%08x\n",ape_ctx->CRC);
48 //printf("Flags=0x%08x\n",ape_ctx->frameflags);
49
50 init_predictor_decoder(ape_ctx);
51
52 switch (ape_ctx->compressiontype)
53 {
54 case 2000:
55 init_filter_16_11(filterbuf32);
56 break;
57
58 case 3000:
59 init_filter_64_11(filterbuf256);
60 break;
61
62 case 4000:
63 init_filter_256_13(filterbuf256);
64 init_filter_32_10(filterbuf32);
65 break;
66
67 case 5000:
68 init_filter_1280_15(filterbuf1280);
69 init_filter_256_13(filterbuf256);
70 init_filter_16_11(filterbuf32);
71 }
72}
73
74int decode_chunk(struct ape_ctx_t* ape_ctx,
75 unsigned char* inbuffer, int* firstbyte,
76 int* bytesconsumed,
77 int32_t* decoded0, int32_t* decoded1,
78 int count)
79{
80 int res;
81 int32_t left, right;
82#ifdef ROCKBOX
83 int scale = (APE_OUTPUT_DEPTH - ape_ctx->bps);
84 #define SCALE(x) ((x) << scale)
85#else
86 #define SCALE(x) (x)
87#endif
88
89 if ((ape_ctx->channels==1) || (ape_ctx->frameflags & APE_FRAMECODE_PSEUDO_STEREO)) {
90 if (ape_ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {
91 res = entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed, decoded0, decoded1, count);
92 /* We are pure silence, so we're done. */
93 return 0;
94 } else {
95 res = entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed, decoded0, NULL, count);
96 }
97
98 switch (ape_ctx->compressiontype)
99 {
100 case 2000:
101 apply_filter_16_11(ape_ctx->fileversion,decoded0,NULL,count);
102 break;
103
104 case 3000:
105 apply_filter_64_11(ape_ctx->fileversion,decoded0,NULL,count);
106 break;
107
108 case 4000:
109 apply_filter_32_10(ape_ctx->fileversion,decoded0,NULL,count);
110 apply_filter_256_13(ape_ctx->fileversion,decoded0,NULL,count);
111 break;
112
113 case 5000:
114 apply_filter_16_11(ape_ctx->fileversion,decoded0,NULL,count);
115 apply_filter_256_13(ape_ctx->fileversion,decoded0,NULL,count);
116 apply_filter_1280_15(ape_ctx->fileversion,decoded0,NULL,count);
117 }
118
119 /* Now apply the predictor decoding */
120 predictor_decode_mono(ape_ctx,decoded0,count);
121
122 if (ape_ctx->channels==2) {
123 /* Pseudo-stereo - just copy left channel to right channel */
124 while (count--)
125 {
126 left = *decoded0;
127 *(decoded1++) = *(decoded0++) = SCALE(left);
128 }
129 } else {
130 /* Mono - do nothing unless it's 8-bit audio */
131 if (ape_ctx->bps == 8) {
132 /* TODO: Handle 8-bit streams */
133 }
134 }
135 } else { /* Stereo */
136 if (ape_ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {
137 /* We are pure silence, so we're done. */
138 return 0;
139 }
140
141 res = entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed, decoded0, decoded1, count);
142
143 /* Apply filters - compression type 1000 doesn't have any */
144 switch (ape_ctx->compressiontype)
145 {
146 case 2000:
147 apply_filter_16_11(ape_ctx->fileversion,decoded0,decoded1,count);
148 break;
149
150 case 3000:
151 apply_filter_64_11(ape_ctx->fileversion,decoded0,decoded1,count);
152 break;
153
154 case 4000:
155 apply_filter_32_10(ape_ctx->fileversion,decoded0,decoded1,count);
156 apply_filter_256_13(ape_ctx->fileversion,decoded0,decoded1,count);
157 break;
158
159 case 5000:
160 apply_filter_16_11(ape_ctx->fileversion,decoded0,decoded1,count);
161 apply_filter_256_13(ape_ctx->fileversion,decoded0,decoded1,count);
162 apply_filter_1280_15(ape_ctx->fileversion,decoded0,decoded1,count);
163 }
164
165 /* Now apply the predictor decoding */
166 predictor_decode_stereo(ape_ctx,decoded0,decoded1,count);
167
168 if (ape_ctx->bps == 8) {
169 /* TODO: Handle 8-bit streams */
170 } else {
171 /* Decorrelate and scale to output depth */
172 while (count--)
173 {
174 left = *decoded1 - (*decoded0 / 2);
175 right = left + *decoded0;
176
177 *(decoded0++) = SCALE(left);
178 *(decoded1++) = SCALE(right);
179 }
180 }
181 }
182
183 return res;
184}
diff --git a/apps/codecs/demac/libdemac/decoder.h b/apps/codecs/demac/libdemac/decoder.h
new file mode 100644
index 0000000000..0c3bd15b37
--- /dev/null
+++ b/apps/codecs/demac/libdemac/decoder.h
@@ -0,0 +1,40 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#ifndef _APE_DECODER_H
26#define _APE_DECODER_H
27
28#include <inttypes.h>
29#include "parser.h"
30
31void init_frame_decoder(struct ape_ctx_t* ape_ctx,
32 unsigned char* inbuffer, int* firstbyte,
33 int* bytesconsumed);
34
35int decode_chunk(struct ape_ctx_t* ape_ctx,
36 unsigned char* inbuffer, int* firstbyte,
37 int* bytesconsumed,
38 int32_t* decoded0, int32_t* decoded1,
39 int count);
40#endif
diff --git a/apps/codecs/demac/libdemac/demac.h b/apps/codecs/demac/libdemac/demac.h
new file mode 100644
index 0000000000..d1bb361574
--- /dev/null
+++ b/apps/codecs/demac/libdemac/demac.h
@@ -0,0 +1,45 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#ifndef _APE_DECODER_H
26#define _APE_DECODER_H
27
28#include <inttypes.h>
29#include "parser.h"
30
31void init_frame_decoder(struct ape_ctx_t* ape_ctx,
32 unsigned char* inbuffer, int* firstbyte,
33 int* bytesconsumed);
34
35int decode_chunk(struct ape_ctx_t* ape_ctx,
36 unsigned char* inbuffer, int* firstbyte,
37 int* bytesconsumed,
38 int32_t* decoded0, int32_t* decoded1,
39 int count);
40
41uint32_t ape_initcrc(void);
42uint32_t ape_updatecrc(unsigned char *block, int count, uint32_t crc);
43uint32_t ape_finishcrc(uint32_t crc);
44
45#endif
diff --git a/apps/codecs/demac/libdemac/entropy.c b/apps/codecs/demac/libdemac/entropy.c
new file mode 100644
index 0000000000..2c60420250
--- /dev/null
+++ b/apps/codecs/demac/libdemac/entropy.c
@@ -0,0 +1,314 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#include <inttypes.h>
26#include <string.h>
27
28#include "parser.h"
29#include "entropy.h"
30#include "rangecoding.h" /* Range-coding (static inline) functions */
31
32#define MODEL_ELEMENTS 64
33
34/*
35 The following counts arrays for use with the range decoder are
36 hard-coded in the Monkey's Audio decoder.
37*/
38
39static const int counts_3970[65] ICONST_ATTR =
40{
41 0,14824,28224,39348,47855,53994,58171,60926,
42 62682,63786,64463,64878,65126,65276,65365,65419,
43 65450,65469,65480,65487,65491,65493,65494,65495,
44 65496,65497,65498,65499,65500,65501,65502,65503,
45 65504,65505,65506,65507,65508,65509,65510,65511,
46 65512,65513,65514,65515,65516,65517,65518,65519,
47 65520,65521,65522,65523,65524,65525,65526,65527,
48 65528,65529,65530,65531,65532,65533,65534,65535,
49 65536
50};
51
52/* counts_diff_3970[i] = counts_3970[i+1] - counts_3970[i] */
53static const int counts_diff_3970[64] ICONST_ATTR =
54{
55 14824,13400,11124,8507,6139,4177,2755,1756,
56 1104,677,415,248,150,89,54,31,
57 19,11,7,4,2,1,1,1,
58 1,1,1,1,1,1,1,1,
59 1,1,1,1,1,1,1,1,
60 1,1,1,1,1,1,1,1,
61 1,1,1,1,1,1,1,1,
62 1,1,1,1,1,1,1,1
63};
64
65static const int counts_3980[65] ICONST_ATTR =
66{
67 0,19578,36160,48417,56323,60899,63265,64435,
68 64971,65232,65351,65416,65447,65466,65476,65482,
69 65485,65488,65490,65491,65492,65493,65494,65495,
70 65496,65497,65498,65499,65500,65501,65502,65503,
71 65504,65505,65506,65507,65508,65509,65510,65511,
72 65512,65513,65514,65515,65516,65517,65518,65519,
73 65520,65521,65522,65523,65524,65525,65526,65527,
74 65528,65529,65530,65531,65532,65533,65534,65535,
75 65536
76};
77
78/* counts_diff_3980[i] = counts_3980[i+1] - counts_3980[i] */
79
80static const int counts_diff_3980[64] ICONST_ATTR =
81{
82 19578,16582,12257,7906,4576,2366,1170,536,
83 261,119,65,31,19,10,6,3,
84 3,2,1,1,1,1,1,1,
85 1,1,1,1,1,1,1,1,
86 1,1,1,1,1,1,1,1,
87 1,1,1,1,1,1,1,1,
88 1,1,1,1,1,1,1,1,
89 1,1,1,1,1,1,1,1
90};
91
92/*
93 range_get_symbol_* functions based on main decoding loop in simple_d.c from
94 http://www.compressconsult.com/rangecoder/rngcod13.zip
95 (c) Michael Schindler
96*/
97
98static inline int range_get_symbol_3980(void)
99{
100 int symbol, cf;
101
102 cf = range_decode_culshift(16);
103
104 /* figure out the symbol inefficiently; a binary search would be much better */
105 for (symbol = 0; counts_3980[symbol+1] <= cf; symbol++);
106
107 range_decode_update(counts_diff_3980[symbol],counts_3980[symbol]);
108
109 return symbol;
110}
111
112static inline int range_get_symbol_3970(void)
113{
114 int symbol, cf;
115
116 cf = range_decode_culshift(16);
117
118 /* figure out the symbol inefficiently; a binary search would be much better */
119 for (symbol = 0; counts_3970[symbol+1] <= cf; symbol++);
120
121 range_decode_update(counts_diff_3970[symbol],counts_3970[symbol]);
122
123 return symbol;
124}
125
126/* MAIN DECODING FUNCTIONS */
127
128struct rice_t
129{
130 uint32_t k;
131 uint32_t ksum;
132};
133
134static struct rice_t riceX IBSS_ATTR;
135static struct rice_t riceY IBSS_ATTR;
136
137static inline void update_rice(struct rice_t* rice, int x)
138{
139 rice->ksum += ((x + 1) / 2) - ((rice->ksum + 16) >> 5);
140
141 if (rice->k == 0) {
142 rice->k = 1;
143 } else if (rice->ksum < ((uint32_t)1 << (rice->k + 4))) {
144 rice->k--;
145 } else if (rice->ksum >= ((uint32_t)1 << (rice->k + 5))) {
146 rice->k++;
147 }
148}
149
150static inline int entropy_decode3980(struct rice_t* rice)
151{
152 int base, x, pivot, overflow;
153
154 pivot = rice->ksum >> 5;
155 if (pivot == 0) pivot=1;
156
157 overflow = range_get_symbol_3980();
158
159 if (overflow == (MODEL_ELEMENTS-1)) {
160 overflow = range_decode_short() << 16;
161 overflow |= range_decode_short();
162 }
163
164 if (pivot >= 0x10000) {
165 /* Codepath for 24-bit streams */
166 int nbits, lo_bits, base_hi, base_lo;
167
168 /* Count the number of bits in pivot */
169 nbits = 17; /* We know there must be at least 17 bits */
170 while ((pivot >> nbits) > 0) { nbits++; }
171
172 /* base_lo is the low (nbits-16) bits of base
173 base_hi is the high 16 bits of base
174 */
175 lo_bits = (nbits - 16);
176
177 base_hi = range_decode_culfreq((pivot >> lo_bits) + 1);
178 range_decode_update(1, base_hi);
179
180 base_lo = range_decode_culfreq(1 << lo_bits);
181 range_decode_update(1, base_lo);
182
183 base = (base_hi << lo_bits) + base_lo;
184 } else {
185 /* Codepath for 16-bit streams */
186 base = range_decode_culfreq(pivot);
187 range_decode_update(1, base);
188 }
189
190 x = base + (overflow * pivot);
191 update_rice(rice, x);
192
193 /* Convert to signed */
194 if (x & 1)
195 return (x >> 1) + 1;
196 else
197 return -(x >> 1);
198}
199
200
201static inline int entropy_decode3970(struct rice_t* rice)
202{
203 int x, tmpk;
204
205 int overflow = range_get_symbol_3970();
206
207 if (overflow == (MODEL_ELEMENTS - 1)) {
208 tmpk = range_decode_bits(5);
209 overflow = 0;
210 } else {
211 tmpk = (rice->k < 1) ? 0 : rice->k - 1;
212 }
213
214 if (tmpk <= 16) {
215 x = range_decode_bits(tmpk);
216 } else {
217 x = range_decode_short();
218 x |= (range_decode_bits(tmpk - 16) << 16);
219 }
220 x += (overflow << tmpk);
221
222 update_rice(rice, x);
223
224 /* Convert to signed */
225 if (x & 1)
226 return (x >> 1) + 1;
227 else
228 return -(x >> 1);
229}
230
231void init_entropy_decoder(struct ape_ctx_t* ape_ctx,
232 unsigned char* inbuffer, int* firstbyte,
233 int* bytesconsumed)
234{
235 bytebuffer = inbuffer;
236 bytebufferoffset = *firstbyte;
237
238 /* Read the CRC */
239 ape_ctx->CRC = read_byte();
240 ape_ctx->CRC = (ape_ctx->CRC << 8) | read_byte();
241 ape_ctx->CRC = (ape_ctx->CRC << 8) | read_byte();
242 ape_ctx->CRC = (ape_ctx->CRC << 8) | read_byte();
243
244 /* Read the frame flags if they exist */
245 ape_ctx->frameflags = 0;
246 if ((ape_ctx->fileversion > 3820) && (ape_ctx->CRC & 0x80000000)) {
247 ape_ctx->CRC &= ~0x80000000;
248
249 ape_ctx->frameflags = read_byte();
250 ape_ctx->frameflags = (ape_ctx->frameflags << 8) | read_byte();
251 ape_ctx->frameflags = (ape_ctx->frameflags << 8) | read_byte();
252 ape_ctx->frameflags = (ape_ctx->frameflags << 8) | read_byte();
253 }
254 /* Keep a count of the blocks decoded in this frame */
255 ape_ctx->blocksdecoded = 0;
256
257 /* Initialise the rice structs */
258 riceX.k = 10;
259 riceX.ksum = (1 << riceX.k) * 16;
260 riceY.k = 10;
261 riceY.ksum = (1 << riceY.k) * 16;
262
263 /* The first 8 bits of input are ignored. */
264 skip_byte();
265
266 range_start_decoding();
267
268 /* Return the new state of the buffer */
269 *bytesconsumed = (intptr_t)bytebuffer - (intptr_t)inbuffer;
270 *firstbyte = bytebufferoffset;
271}
272
273int entropy_decode(struct ape_ctx_t* ape_ctx,
274 unsigned char* inbuffer, int* firstbyte,
275 int* bytesconsumed,
276 int32_t* decoded0, int32_t* decoded1,
277 int blockstodecode)
278{
279 bytebuffer = inbuffer;
280 bytebufferoffset = *firstbyte;
281
282 ape_ctx->blocksdecoded += blockstodecode;
283
284 if (ape_ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {
285 /* We are pure silence, just memset the output buffer. */
286 memset(decoded0, 0, blockstodecode * sizeof(int32_t));
287 memset(decoded1, 0, blockstodecode * sizeof(int32_t));
288 } else {
289 if (ape_ctx->fileversion > 3970) {
290 while (blockstodecode--) {
291 *(decoded0++) = entropy_decode3980(&riceY);
292 if (decoded1 != NULL)
293 *(decoded1++) = entropy_decode3980(&riceX);
294 }
295 } else {
296 while (blockstodecode--) {
297 *(decoded0++) = entropy_decode3970(&riceY);
298 if (decoded1 != NULL)
299 *(decoded1++) = entropy_decode3970(&riceX);
300 }
301 }
302 }
303
304 if (ape_ctx->blocksdecoded == ape_ctx->currentframeblocks)
305 {
306 range_done_decoding();
307 }
308
309 /* Return the new state of the buffer */
310 *bytesconsumed = bytebuffer - inbuffer;
311 *firstbyte = bytebufferoffset;
312
313 return(0);
314}
diff --git a/apps/codecs/demac/libdemac/entropy.h b/apps/codecs/demac/libdemac/entropy.h
new file mode 100644
index 0000000000..dd6736cb15
--- /dev/null
+++ b/apps/codecs/demac/libdemac/entropy.h
@@ -0,0 +1,40 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#ifndef _APE_ENTROPY_H
26#define _APE_ENTROPY_H
27
28#include <inttypes.h>
29
30void init_entropy_decoder(struct ape_ctx_t* ape_ctx,
31 unsigned char* inbuffer, int* firstbyte,
32 int* bytesconsumed);
33
34int entropy_decode(struct ape_ctx_t* ape_ctx,
35 unsigned char* inbuffer, int* firstbyte,
36 int* bytesconsumed,
37 int32_t* decoded0, int32_t* decoded1,
38 int blockstodecode);
39
40#endif
diff --git a/apps/codecs/demac/libdemac/filter.c b/apps/codecs/demac/libdemac/filter.c
new file mode 100644
index 0000000000..76faa67aa7
--- /dev/null
+++ b/apps/codecs/demac/libdemac/filter.c
@@ -0,0 +1,215 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#include <string.h>
26#include <inttypes.h>
27
28#include "demac.h"
29#include "filter.h"
30
31#include "vector_math16.h"
32
33struct filter_t {
34 int16_t* coeffs; /* ORDER entries */
35
36 /* We store all the filter delays in a single buffer */
37 int16_t* historybuffer; /* ORDER*2 + HISTORY_SIZE entries */
38
39 int16_t* delay;
40 int16_t* adaptcoeffs;
41
42 int avg;
43};
44
45/* We name the functions according to the ORDER and FRACBITS
46 pre-processor symbols and build multiple .o files from this .c file
47 - this increases code-size but gives the compiler more scope for
48 optimising the individual functions, as well as replacing a lot of
49 variables with constants.
50*/
51
52#if FRACBITS == 11
53 #if ORDER == 16
54 #define INIT_FILTER init_filter_16_11
55 #define APPLY_FILTER apply_filter_16_11
56 #elif ORDER == 64
57 #define INIT_FILTER init_filter_64_11
58 #define APPLY_FILTER apply_filter_64_11
59 #endif
60#elif FRACBITS == 13
61 #define INIT_FILTER init_filter_256_13
62 #define APPLY_FILTER apply_filter_256_13
63#elif FRACBITS == 10
64 #define INIT_FILTER init_filter_32_10
65 #define APPLY_FILTER apply_filter_32_10
66#elif FRACBITS == 15
67 #define INIT_FILTER init_filter_1280_15
68 #define APPLY_FILTER apply_filter_1280_15
69#endif
70
71/* Some macros to handle the fixed-point stuff */
72
73#define FP_HALF (1 << (FRACBITS - 1)) /* 0.5 in fixed-point format. */
74#define FP_TO_INT(x) ((x + FP_HALF) >> FRACBITS); /* round(x) */
75
76#define SATURATE(x) (int16_t)(((x) == (int16_t)(x)) ? (x) : ((x) >> 31) ^ 0x7FFF);
77
78/* Apply the filter with state f to count entries in data[] */
79
80static inline void do_apply_filter_3980(struct filter_t* f, int32_t* data, int count)
81{
82 int res;
83 int absres;
84
85 while(count--)
86 {
87 res = FP_TO_INT(scalarproduct(f->delay - ORDER, f->coeffs));
88
89 if (*data < 0)
90 vector_add(f->coeffs, f->adaptcoeffs - ORDER);
91 else if (*data > 0)
92 vector_sub(f->coeffs, f->adaptcoeffs - ORDER);
93
94 /* Convert res from (32-FRACBITS).FRACBITS fixed-point format to an
95 integer (rounding to nearest) and add the input value to
96 it */
97 res += *data;
98
99 *data++ = res;
100
101 /* Update the output history */
102 *f->delay++ = SATURATE(res);
103
104 /* Version 3.98 and later files */
105
106 /* Update the adaption coefficients */
107 absres = (res < 0 ? -res : res);
108
109 if (absres > (f->avg * 3))
110 *f->adaptcoeffs = ((res >> 25) & 64) - 32;
111 else if (absres > (f->avg * 4) / 3)
112 *f->adaptcoeffs = ((res >> 26) & 32) - 16;
113 else if (absres > 0)
114 *f->adaptcoeffs = ((res >> 27) & 16) - 8;
115 else
116 *f->adaptcoeffs = 0;
117
118 f->avg += (absres - f->avg) / 16;
119
120 f->adaptcoeffs[-1] >>= 1;
121 f->adaptcoeffs[-2] >>= 1;
122 f->adaptcoeffs[-8] >>= 1;
123
124 f->adaptcoeffs++;
125
126 /* Have we filled the history buffer? */
127 if (f->delay == f->historybuffer + HISTORY_SIZE + (ORDER*2)) {
128 memmove(f->historybuffer, f->delay - (ORDER*2),
129 (ORDER*2) * sizeof(int16_t));
130 f->delay = f->historybuffer + ORDER*2;
131 f->adaptcoeffs = f->historybuffer + ORDER;
132 }
133 }
134}
135
136static inline void do_apply_filter_3970(struct filter_t* f, int32_t* data, int count)
137{
138 int res;
139
140 while(count--)
141 {
142 res = FP_TO_INT(scalarproduct(f->delay - ORDER, f->coeffs));
143
144 if (*data < 0)
145 vector_add(f->coeffs, f->adaptcoeffs - ORDER);
146 else if (*data > 0)
147 vector_sub(f->coeffs, f->adaptcoeffs - ORDER);
148
149 /* Convert res from (32-FRACBITS).FRACBITS fixed-point format to an
150 integer (rounding to nearest) and add the input value to
151 it */
152 res += *data;
153
154 *data++ = res;
155
156 /* Update the output history */
157 *f->delay++ = SATURATE(res);
158
159 /* Version ??? to < 3.98 files (untested) */
160 f->adaptcoeffs[0] = (res == 0) ? 0 : ((res >> 28) & 8) - 4;
161 f->adaptcoeffs[-4] >>= 1;
162 f->adaptcoeffs[-8] >>= 1;
163
164 f->adaptcoeffs++;
165
166 /* Have we filled the history buffer? */
167 if (f->delay == f->historybuffer + HISTORY_SIZE + (ORDER*2)) {
168 memmove(f->historybuffer, f->delay - (ORDER*2),
169 (ORDER*2) * sizeof(int16_t));
170 f->delay = f->historybuffer + ORDER*2;
171 f->adaptcoeffs = f->historybuffer + ORDER;
172 }
173 }
174}
175
176static struct filter_t filter0 IBSS_ATTR;
177static struct filter_t filter1 IBSS_ATTR;
178
179static void do_init_filter(struct filter_t* f, int16_t* buf)
180{
181 f->coeffs = buf;
182 f->historybuffer = buf + ORDER;
183
184 /* Zero the output history buffer */
185 memset(f->historybuffer, 0 , (ORDER*2) * sizeof(int16_t));
186 f->delay = f->historybuffer + ORDER*2;
187 f->adaptcoeffs = f->historybuffer + ORDER;
188
189 /* Zero the co-efficients */
190 memset(f->coeffs, 0, ORDER * sizeof(int16_t));
191
192 /* Zero the running average */
193 f->avg = 0;
194}
195
196void INIT_FILTER(int16_t* buf)
197{
198 do_init_filter(&filter0, buf);
199 do_init_filter(&filter1, buf + ORDER * 3 + HISTORY_SIZE);
200}
201
202int APPLY_FILTER(int fileversion, int32_t* data0, int32_t* data1, int count)
203{
204 if (fileversion >= 3980) {
205 do_apply_filter_3980(&filter0, data0, count);
206 if (data1 != NULL)
207 do_apply_filter_3980(&filter1, data1, count);
208 } else {
209 do_apply_filter_3970(&filter0, data0, count);
210 if (data1 != NULL)
211 do_apply_filter_3970(&filter1, data1, count);
212 }
213
214 return 0;
215}
diff --git a/apps/codecs/demac/libdemac/filter.h b/apps/codecs/demac/libdemac/filter.h
new file mode 100644
index 0000000000..b98403cfc8
--- /dev/null
+++ b/apps/codecs/demac/libdemac/filter.h
@@ -0,0 +1,48 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#ifndef _APE_FILTER_H
26#define _APE_FILTER_H
27
28#include <inttypes.h>
29
30/* The size of the history buffers */
31#define HISTORY_SIZE 512
32
33void init_filter_16_11(int16_t* buf);
34int apply_filter_16_11(int fileversion, int32_t* decoded0, int32_t* decoded1, int count);
35
36void init_filter_64_11(int16_t* buf);
37int apply_filter_64_11(int fileversion, int32_t* decoded0, int32_t* decoded1, int count);
38
39void init_filter_32_10(int16_t* buf);
40int apply_filter_32_10(int fileversion, int32_t* decoded0, int32_t* decoded1, int count);
41
42void init_filter_256_13(int16_t* buf);
43int apply_filter_256_13(int fileversion, int32_t* decoded0, int32_t* decoded1, int count);
44
45void init_filter_1280_15(int16_t* buf);
46int apply_filter_1280_15(int fileversion, int32_t* decoded0, int32_t* decoded1, int count);
47
48#endif
diff --git a/apps/codecs/demac/libdemac/filter_1280_15.c b/apps/codecs/demac/libdemac/filter_1280_15.c
new file mode 100644
index 0000000000..edf1ce1bb1
--- /dev/null
+++ b/apps/codecs/demac/libdemac/filter_1280_15.c
@@ -0,0 +1,27 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#define ORDER 1280
26#define FRACBITS 15
27#include "filter.c"
diff --git a/apps/codecs/demac/libdemac/filter_16_11.c b/apps/codecs/demac/libdemac/filter_16_11.c
new file mode 100644
index 0000000000..07e4b96dc2
--- /dev/null
+++ b/apps/codecs/demac/libdemac/filter_16_11.c
@@ -0,0 +1,27 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#define ORDER 16
26#define FRACBITS 11
27#include "filter.c"
diff --git a/apps/codecs/demac/libdemac/filter_256_13.c b/apps/codecs/demac/libdemac/filter_256_13.c
new file mode 100644
index 0000000000..370dec1d5a
--- /dev/null
+++ b/apps/codecs/demac/libdemac/filter_256_13.c
@@ -0,0 +1,27 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#define ORDER 256
26#define FRACBITS 13
27#include "filter.c"
diff --git a/apps/codecs/demac/libdemac/filter_32_10.c b/apps/codecs/demac/libdemac/filter_32_10.c
new file mode 100644
index 0000000000..b585de98a4
--- /dev/null
+++ b/apps/codecs/demac/libdemac/filter_32_10.c
@@ -0,0 +1,27 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#define ORDER 32
26#define FRACBITS 10
27#include "filter.c"
diff --git a/apps/codecs/demac/libdemac/filter_64_11.c b/apps/codecs/demac/libdemac/filter_64_11.c
new file mode 100644
index 0000000000..8b8d326d1d
--- /dev/null
+++ b/apps/codecs/demac/libdemac/filter_64_11.c
@@ -0,0 +1,27 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#define ORDER 64
26#define FRACBITS 11
27#include "filter.c"
diff --git a/apps/codecs/demac/libdemac/parser.c b/apps/codecs/demac/libdemac/parser.c
new file mode 100644
index 0000000000..bcb542dbb6
--- /dev/null
+++ b/apps/codecs/demac/libdemac/parser.c
@@ -0,0 +1,357 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#include <inttypes.h>
26#include <string.h>
27#ifndef ROCKBOX
28#include <stdio.h>
29#include <stdlib.h>
30#include <sys/types.h>
31#include <sys/stat.h>
32#include <fcntl.h>
33#include <unistd.h>
34#endif
35
36#include "parser.h"
37
38
39static inline int16_t get_int16(unsigned char* buf)
40{
41 return(buf[0] | (buf[1] << 8));
42}
43
44static inline uint16_t get_uint16(unsigned char* buf)
45{
46 return(buf[0] | (buf[1] << 8));
47}
48
49static inline uint32_t get_uint32(unsigned char* buf)
50{
51 return(buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24));
52}
53
54
55int ape_parseheaderbuf(unsigned char* buf, struct ape_ctx_t* ape_ctx)
56{
57 unsigned char* header;
58
59 memset(ape_ctx,0,sizeof(struct ape_ctx_t));
60 /* TODO: Skip any leading junk such as id3v2 tags */
61 ape_ctx->junklength = 0;
62
63 memcpy(ape_ctx->magic, buf, 4);
64 if (memcmp(ape_ctx->magic,"MAC ",4)!=0)
65 {
66 return -1;
67 }
68
69 ape_ctx->fileversion = get_int16(buf + 4);
70
71 if (ape_ctx->fileversion >= 3980)
72 {
73 ape_ctx->padding1 = get_int16(buf + 6);
74 ape_ctx->descriptorlength = get_uint32(buf + 8);
75 ape_ctx->headerlength = get_uint32(buf + 12);
76 ape_ctx->seektablelength = get_uint32(buf + 16);
77 ape_ctx->wavheaderlength = get_uint32(buf + 20);
78 ape_ctx->audiodatalength = get_uint32(buf + 24);
79 ape_ctx->audiodatalength_high = get_uint32(buf + 28);
80 ape_ctx->wavtaillength = get_uint32(buf + 32);
81 memcpy(ape_ctx->md5, buf + 36, 16);
82
83 header = buf + ape_ctx->descriptorlength;
84
85 /* Read header data */
86 ape_ctx->compressiontype = get_uint16(header + 0);
87 ape_ctx->formatflags = get_uint16(header + 2);
88 ape_ctx->blocksperframe = get_uint32(header + 4);
89 ape_ctx->finalframeblocks = get_uint32(header + 8);
90 ape_ctx->totalframes = get_uint32(header + 12);
91 ape_ctx->bps = get_uint16(header + 16);
92 ape_ctx->channels = get_uint16(header + 18);
93 ape_ctx->samplerate = get_uint32(header + 20);
94
95 ape_ctx->firstframe = ape_ctx->junklength + ape_ctx->descriptorlength +
96 ape_ctx->headerlength + ape_ctx->seektablelength +
97 ape_ctx->wavheaderlength;
98 } else {
99 ape_ctx->compressiontype = get_uint16(buf + 6);
100 ape_ctx->formatflags = get_uint16(buf + 8);
101 ape_ctx->channels = get_uint16(buf + 10);
102 ape_ctx->samplerate = get_uint32(buf + 14);
103 ape_ctx->wavheaderlength = get_uint32(buf + 18);
104 ape_ctx->totalframes = get_uint32(buf + 26);
105 ape_ctx->finalframeblocks = get_uint32(buf + 30);
106 }
107
108 ape_ctx->totalsamples = ape_ctx->finalframeblocks;
109 if (ape_ctx->totalframes > 1)
110 ape_ctx->totalsamples += ape_ctx->blocksperframe * (ape_ctx->totalframes-1);
111
112 /* TODO: Parse and store seektable */
113
114 return 0;
115}
116
117
118#ifndef ROCKBOX
119/* Helper functions */
120
121static int read_uint16(int fd, uint16_t* x)
122{
123 unsigned char tmp[2];
124 int n;
125
126 n = read(fd,tmp,2);
127
128 if (n != 2)
129 return -1;
130
131 *x = tmp[0] | (tmp[1] << 8);
132
133 return 0;
134}
135
136static int read_int16(int fd, int16_t* x)
137{
138 return read_uint16(fd, (uint16_t*)x);
139}
140
141static int read_uint32(int fd, uint32_t* x)
142{
143 unsigned char tmp[4];
144 int n;
145
146 n = read(fd,tmp,4);
147
148 if (n != 4)
149 return -1;
150
151 *x = tmp[0] | (tmp[1] << 8) | (tmp[2] << 16) | (tmp[3] << 24);
152
153 return 0;
154}
155
156int ape_parseheader(int fd, struct ape_ctx_t* ape_ctx)
157{
158 int i,n;
159
160 /* TODO: Skip any leading junk such as id3v2 tags */
161 ape_ctx->junklength = 0;
162
163 lseek(fd,ape_ctx->junklength,SEEK_SET);
164
165 n = read(fd,&ape_ctx->magic,4);
166 if (n != 4) return -1;
167
168 if (memcmp(ape_ctx->magic,"MAC ",4)!=0)
169 {
170 return -1;
171 }
172
173 if (read_int16(fd,&ape_ctx->fileversion) < 0)
174 return -1;
175
176 if (ape_ctx->fileversion >= 3980)
177 {
178 if (read_int16(fd,&ape_ctx->padding1) < 0)
179 return -1;
180 if (read_uint32(fd,&ape_ctx->descriptorlength) < 0)
181 return -1;
182 if (read_uint32(fd,&ape_ctx->headerlength) < 0)
183 return -1;
184 if (read_uint32(fd,&ape_ctx->seektablelength) < 0)
185 return -1;
186 if (read_uint32(fd,&ape_ctx->wavheaderlength) < 0)
187 return -1;
188 if (read_uint32(fd,&ape_ctx->audiodatalength) < 0)
189 return -1;
190 if (read_uint32(fd,&ape_ctx->audiodatalength_high) < 0)
191 return -1;
192 if (read_uint32(fd,&ape_ctx->wavtaillength) < 0)
193 return -1;
194 if (read(fd,&ape_ctx->md5,16) != 16)
195 return -1;
196
197 /* Skip any unknown bytes at the end of the descriptor. This is for future
198 compatibility */
199 if (ape_ctx->descriptorlength > 52)
200 lseek(fd,ape_ctx->descriptorlength - 52, SEEK_CUR);
201
202 /* Read header data */
203 if (read_uint16(fd,&ape_ctx->compressiontype) < 0)
204 return -1;
205 if (read_uint16(fd,&ape_ctx->formatflags) < 0)
206 return -1;
207 if (read_uint32(fd,&ape_ctx->blocksperframe) < 0)
208 return -1;
209 if (read_uint32(fd,&ape_ctx->finalframeblocks) < 0)
210 return -1;
211 if (read_uint32(fd,&ape_ctx->totalframes) < 0)
212 return -1;
213 if (read_uint16(fd,&ape_ctx->bps) < 0)
214 return -1;
215 if (read_uint16(fd,&ape_ctx->channels) < 0)
216 return -1;
217 if (read_uint32(fd,&ape_ctx->samplerate) < 0)
218 return -1;
219 } else {
220 ape_ctx->descriptorlength = 0;
221 ape_ctx->headerlength = 32;
222
223 if (read_uint16(fd,&ape_ctx->compressiontype) < 0)
224 return -1;
225 if (read_uint16(fd,&ape_ctx->formatflags) < 0)
226 return -1;
227 if (read_uint16(fd,&ape_ctx->channels) < 0)
228 return -1;
229 if (read_uint32(fd,&ape_ctx->samplerate) < 0)
230 return -1;
231 if (read_uint32(fd,&ape_ctx->wavheaderlength) < 0)
232 return -1;
233 if (read_uint32(fd,&ape_ctx->wavtaillength) < 0)
234 return -1;
235 if (read_uint32(fd,&ape_ctx->totalframes) < 0)
236 return -1;
237 if (read_uint32(fd,&ape_ctx->finalframeblocks) < 0)
238 return -1;
239
240 if (ape_ctx->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL)
241 {
242 lseek(fd, 4, SEEK_CUR); /* Skip the peak level */
243 ape_ctx->headerlength += 4;
244 }
245
246 if (ape_ctx->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS)
247 {
248 if (read_uint32(fd,&ape_ctx->seektablelength) < 0)
249 return -1;
250 ape_ctx->headerlength += 4;
251 ape_ctx->seektablelength *= sizeof(int32_t);
252 } else {
253 ape_ctx->seektablelength = ape_ctx->totalframes * sizeof(int32_t);
254 }
255
256 if (ape_ctx->formatflags & MAC_FORMAT_FLAG_8_BIT)
257 ape_ctx->bps = 8;
258 else if (ape_ctx->formatflags & MAC_FORMAT_FLAG_24_BIT)
259 ape_ctx->bps = 24;
260 else
261 ape_ctx->bps = 16;
262
263 if (ape_ctx->fileversion >= 3950)
264 ape_ctx->blocksperframe = 73728 * 4;
265 else if ((ape_ctx->fileversion >= 3900) || (ape_ctx->fileversion >= 3800 && ape_ctx->compressiontype >= 4000))
266 ape_ctx->blocksperframe = 73728;
267 else
268 ape_ctx->blocksperframe = 9216;
269
270 /* Skip any stored wav header */
271 if (!(ape_ctx->formatflags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER))
272 {
273 lseek(fd, ape_ctx->wavheaderlength, SEEK_CUR);
274 }
275 }
276
277 ape_ctx->totalsamples = ape_ctx->finalframeblocks;
278 if (ape_ctx->totalframes > 1)
279 ape_ctx->totalsamples += ape_ctx->blocksperframe * (ape_ctx->totalframes-1);
280
281 if (ape_ctx->seektablelength > 0)
282 {
283 ape_ctx->seektable = malloc(ape_ctx->seektablelength);
284 if (ape_ctx->seektable == NULL)
285 return -1;
286 for (i=0; i < ape_ctx->seektablelength / sizeof(uint32_t); i++)
287 {
288 if (read_uint32(fd,&ape_ctx->seektable[i]) < 0)
289 {
290 free(ape_ctx->seektable);
291 return -1;
292 }
293 }
294 }
295
296 ape_ctx->firstframe = ape_ctx->junklength + ape_ctx->descriptorlength +
297 ape_ctx->headerlength + ape_ctx->seektablelength +
298 ape_ctx->wavheaderlength;
299
300 return 0;
301}
302
303void ape_dumpinfo(struct ape_ctx_t* ape_ctx)
304{
305 int i;
306
307 printf("Descriptor Block:\n\n");
308 printf("magic = \"%c%c%c%c\"\n",
309 ape_ctx->magic[0],ape_ctx->magic[1],
310 ape_ctx->magic[2],ape_ctx->magic[3]);
311 printf("fileversion = %d\n",ape_ctx->fileversion);
312 printf("descriptorlength = %d\n",ape_ctx->descriptorlength);
313 printf("headerlength = %d\n",ape_ctx->headerlength);
314 printf("seektablelength = %d\n",ape_ctx->seektablelength);
315 printf("wavheaderlength = %d\n",ape_ctx->wavheaderlength);
316 printf("audiodatalength = %d\n",ape_ctx->audiodatalength);
317 printf("audiodatalength_high = %d\n",ape_ctx->audiodatalength_high);
318 printf("wavtaillength = %d\n",ape_ctx->wavtaillength);
319 printf("md5 = ");
320 for (i = 0; i < 16; i++)
321 printf("%02x",ape_ctx->md5[i]);
322 printf("\n");
323
324 printf("\nHeader Block:\n\n");
325
326 printf("compressiontype = %d\n",ape_ctx->compressiontype);
327 printf("formatflags = %d\n",ape_ctx->formatflags);
328 printf("blocksperframe = %d\n",ape_ctx->blocksperframe);
329 printf("finalframeblocks = %d\n",ape_ctx->finalframeblocks);
330 printf("totalframes = %d\n",ape_ctx->totalframes);
331 printf("bps = %d\n",ape_ctx->bps);
332 printf("channels = %d\n",ape_ctx->channels);
333 printf("samplerate = %d\n",ape_ctx->samplerate);
334
335 printf("\nSeektable\n\n");
336 if ((ape_ctx->seektablelength / sizeof(uint32_t)) != ape_ctx->totalframes)
337 {
338 printf("No seektable\n");
339 }
340 else
341 {
342 for ( i = 0; i < ape_ctx->seektablelength / sizeof(uint32_t) ; i++)
343 {
344 if (i < ape_ctx->totalframes-1) {
345 printf("%8d %d (%d bytes)\n",i,ape_ctx->seektable[i],ape_ctx->seektable[i+1]-ape_ctx->seektable[i]);
346 } else {
347 printf("%8d %d\n",i,ape_ctx->seektable[i]);
348 }
349 }
350 }
351 printf("\nCalculated information:\n\n");
352 printf("junklength = %d\n",ape_ctx->junklength);
353 printf("firstframe = %d\n",ape_ctx->firstframe);
354 printf("totalsamples = %d\n",ape_ctx->totalsamples);
355}
356
357#endif /* !ROCKBOX */
diff --git a/apps/codecs/demac/libdemac/parser.h b/apps/codecs/demac/libdemac/parser.h
new file mode 100644
index 0000000000..edf4222fd5
--- /dev/null
+++ b/apps/codecs/demac/libdemac/parser.h
@@ -0,0 +1,137 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#ifndef _APE_PARSER_H
26#define _APE_PARSER_H
27
28#include <inttypes.h>
29
30#ifdef ROCKBOX
31/* Include the Rockbox Codec API when building for Rockbox */
32#define APE_OUTPUT_DEPTH 29
33#ifndef ROCKBOX_PLUGIN
34#include "../lib/codeclib.h"
35#include <codecs.h>
36#endif
37#else
38#define APE_OUTPUT_DEPTH (ape_ctx->bps)
39#define IBSS_ATTR
40#define ICONST_ATTR
41#define ICODE_ATTR
42#endif
43
44/* The earliest and latest file formats supported by this library */
45#define APE_MIN_VERSION 3970
46#define APE_MAX_VERSION 3990
47
48#define MAC_FORMAT_FLAG_8_BIT 1 // is 8-bit [OBSOLETE]
49#define MAC_FORMAT_FLAG_CRC 2 // uses the new CRC32 error detection [OBSOLETE]
50#define MAC_FORMAT_FLAG_HAS_PEAK_LEVEL 4 // uint32 nPeakLevel after the header [OBSOLETE]
51#define MAC_FORMAT_FLAG_24_BIT 8 // is 24-bit [OBSOLETE]
52#define MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS 16 // has the number of seek elements after the peak level
53#define MAC_FORMAT_FLAG_CREATE_WAV_HEADER 32 // create the wave header on decompression (not stored)
54
55
56/* Special frame codes:
57
58 MONO_SILENCE - All PCM samples in frame are zero (mono streams only)
59 LEFT_SILENCE - All PCM samples for left channel in frame are zero (stereo streams)
60 RIGHT_SILENCE - All PCM samples for left channel in frame are zero (stereo streams)
61 PSEUDO_STEREO - Left and Right channels are identical
62
63*/
64
65#define APE_FRAMECODE_MONO_SILENCE 1
66#define APE_FRAMECODE_STEREO_SILENCE 3
67#define APE_FRAMECODE_PSEUDO_STEREO 4
68
69#define HISTORY_SIZE 512
70#define PREDICTOR_ORDER 8
71
72struct predictor_t
73{
74 /* Adaption co-efficients */
75 int32_t coeffsA[4];
76 int32_t coeffsB[5];
77
78 /* Filter histories */
79 int32_t historybuffer[HISTORY_SIZE + PREDICTOR_ORDER * 4];
80 int32_t* delayA;
81 int32_t* delayB;
82 int32_t* adaptcoeffsA;
83 int32_t* adaptcoeffsB;
84
85 int32_t lastA;
86
87 int32_t filterA;
88 int32_t filterB;
89};
90
91struct ape_ctx_t
92{
93 /* Derived fields */
94 uint32_t junklength;
95 uint32_t firstframe;
96 uint32_t totalsamples;
97
98 /* Info from Descriptor Block */
99 char magic[4];
100 int16_t fileversion;
101 int16_t padding1;
102 uint32_t descriptorlength;
103 uint32_t headerlength;
104 uint32_t seektablelength;
105 uint32_t wavheaderlength;
106 uint32_t audiodatalength;
107 uint32_t audiodatalength_high;
108 uint32_t wavtaillength;
109 uint8_t md5[16];
110
111 /* Info from Header Block */
112 uint16_t compressiontype;
113 uint16_t formatflags;
114 uint32_t blocksperframe;
115 uint32_t finalframeblocks;
116 uint32_t totalframes;
117 uint16_t bps;
118 uint16_t channels;
119 uint32_t samplerate;
120
121 /* Seektable */
122 uint32_t* seektable;
123
124 /* Decoder state */
125 uint32_t CRC;
126 int frameflags;
127 int currentframeblocks;
128 int blocksdecoded;
129 struct predictor_t predictorY;
130 struct predictor_t predictorX;
131};
132
133int ape_parseheader(int fd, struct ape_ctx_t* ape_ctx);
134int ape_parseheaderbuf(unsigned char* buf, struct ape_ctx_t* ape_ctx);
135void ape_dumpinfo(struct ape_ctx_t* ape_ctx);
136
137#endif
diff --git a/apps/codecs/demac/libdemac/predictor.c b/apps/codecs/demac/libdemac/predictor.c
new file mode 100644
index 0000000000..ef72fedfbd
--- /dev/null
+++ b/apps/codecs/demac/libdemac/predictor.c
@@ -0,0 +1,196 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#include <inttypes.h>
26#include <string.h>
27
28#include "parser.h"
29#include "predictor.h"
30
31#include "vector_math32.h"
32
33/* Return 0 if x is zero, -1 if x is positive, 1 if x is negative */
34#define SIGN(x) (x) ? (((x) > 0) ? -1 : 1) : 0
35
36static const int32_t initial_coeffs[4] = {
37 360, 317, -109, 98
38};
39
40static void init_predictor(struct predictor_t* p)
41{
42 /* Zero the history buffers */
43 memset(p->historybuffer, 0, (PREDICTOR_ORDER*4) * sizeof(int32_t));
44 p->delayA = p->historybuffer + PREDICTOR_ORDER*4;
45 p->delayB = p->historybuffer + PREDICTOR_ORDER*3;
46 p->adaptcoeffsA = p->historybuffer + PREDICTOR_ORDER*2;
47 p->adaptcoeffsB = p->historybuffer + PREDICTOR_ORDER;
48
49 /* Initialise and zero the co-efficients */
50 memcpy(p->coeffsA, initial_coeffs, sizeof(initial_coeffs));
51 memset(p->coeffsB, 0, sizeof(p->coeffsB));
52
53 p->filterA = 0;
54 p->filterB = 0;
55
56 p->lastA = 0;
57}
58
59static int do_predictor_decode(struct predictor_t* p, int32_t A, int32_t B)
60{
61 int32_t predictionA, predictionB, currentA;
62
63 p->delayA[0] = p->lastA;
64 p->delayA[-1] = p->delayA[0] - p->delayA[-1];
65
66 predictionA = scalarproduct4_rev32(p->coeffsA,p->delayA);
67
68 /* Apply a scaled first-order filter compression */
69 p->delayB[0] = B - ((p->filterB * 31) >> 5);
70 p->filterB = B;
71
72 p->delayB[-1] = p->delayB[0] - p->delayB[-1];
73
74 predictionB = scalarproduct5_rev32(p->coeffsB,p->delayB);
75
76 currentA = A + ((predictionA + (predictionB >> 1)) >> 10);
77
78 p->adaptcoeffsA[0] = SIGN(p->delayA[0]);
79 p->adaptcoeffsA[-1] = SIGN(p->delayA[-1]);
80
81 p->adaptcoeffsB[0] = SIGN(p->delayB[0]);
82 p->adaptcoeffsB[-1] = SIGN(p->delayB[-1]);
83
84 if (A > 0)
85 {
86 vector_sub4_rev32(p->coeffsA, p->adaptcoeffsA);
87 vector_sub5_rev32(p->coeffsB, p->adaptcoeffsB);
88 }
89 else if (A < 0)
90 {
91 vector_add4_rev32(p->coeffsA, p->adaptcoeffsA);
92 vector_add5_rev32(p->coeffsB, p->adaptcoeffsB);
93 }
94
95 p->delayA++;
96 p->delayB++;
97 p->adaptcoeffsA++;
98 p->adaptcoeffsB++;
99
100 /* Have we filled the history buffer? */
101 if (p->delayA == p->historybuffer + HISTORY_SIZE + (PREDICTOR_ORDER*4)) {
102 memmove(p->historybuffer, p->delayA - (PREDICTOR_ORDER*4),
103 (PREDICTOR_ORDER*4) * sizeof(int32_t));
104 p->delayA = p->historybuffer + PREDICTOR_ORDER*4;
105 p->delayB = p->historybuffer + PREDICTOR_ORDER*3;
106 p->adaptcoeffsA = p->historybuffer + PREDICTOR_ORDER*2;
107 p->adaptcoeffsB = p->historybuffer + PREDICTOR_ORDER;
108 }
109
110 p->lastA = currentA;
111 p->filterA = currentA + ((p->filterA * 31) >> 5);
112
113 return p->filterA;
114}
115
116static int32_t X;
117
118void init_predictor_decoder(struct ape_ctx_t* ape_ctx)
119{
120 X = 0;
121
122 init_predictor(&ape_ctx->predictorY);
123 init_predictor(&ape_ctx->predictorX);
124}
125
126int predictor_decode_stereo(struct ape_ctx_t* ape_ctx, int32_t* decoded0, int32_t* decoded1, int count) ICODE_ATTR;
127int predictor_decode_stereo(struct ape_ctx_t* ape_ctx, int32_t* decoded0, int32_t* decoded1, int count)
128{
129 while (count--)
130 {
131 *decoded0 = do_predictor_decode(&ape_ctx->predictorY, *decoded0, X);
132 X = do_predictor_decode(&ape_ctx->predictorX, *decoded1, *(decoded0)++);
133 *(decoded1++) = X;
134 }
135
136 return 0;
137}
138
139int predictor_decode_mono(struct ape_ctx_t* ape_ctx, int32_t* decoded0, int count)
140{
141 struct predictor_t* p = &ape_ctx->predictorY;
142 int32_t predictionA, currentA, A;
143
144 currentA = p->lastA;
145
146 while (count--)
147 {
148 A = *decoded0;
149
150 p->delayA[0] = currentA;
151 p->delayA[-1] = p->delayA[0] - p->delayA[-1];
152
153 predictionA = (p->delayA[0] * p->coeffsA[0]) +
154 (p->delayA[-1] * p->coeffsA[1]) +
155 (p->delayA[-2] * p->coeffsA[2]) +
156 (p->delayA[-3] * p->coeffsA[3]);
157
158 currentA = A + (predictionA >> 10);
159
160 p->adaptcoeffsA[0] = SIGN(p->delayA[0]);
161 p->adaptcoeffsA[-1] = SIGN(p->delayA[-1]);
162
163 if (A > 0)
164 {
165 p->coeffsA[0] -= p->adaptcoeffsA[0];
166 p->coeffsA[1] -= p->adaptcoeffsA[-1];
167 p->coeffsA[2] -= p->adaptcoeffsA[-2];
168 p->coeffsA[3] -= p->adaptcoeffsA[-3];
169 }
170 else if (A < 0)
171 {
172 p->coeffsA[0] += p->adaptcoeffsA[0];
173 p->coeffsA[1] += p->adaptcoeffsA[-1];
174 p->coeffsA[2] += p->adaptcoeffsA[-2];
175 p->coeffsA[3] += p->adaptcoeffsA[-3];
176 }
177
178 p->delayA++;
179 p->adaptcoeffsA++;
180
181 /* Have we filled the history buffer? */
182 if (p->delayA == p->historybuffer + HISTORY_SIZE + (PREDICTOR_ORDER*4)) {
183 memmove(p->historybuffer, p->delayA - (PREDICTOR_ORDER*4),
184 (PREDICTOR_ORDER*4) * sizeof(int32_t));
185 p->delayA = p->historybuffer + PREDICTOR_ORDER*4;
186 p->adaptcoeffsA = p->historybuffer + PREDICTOR_ORDER*2;
187 }
188
189 p->filterA = currentA + ((p->filterA * 31) >> 5);
190 *(decoded0++) = p->filterA;
191 }
192
193 p->lastA = currentA;
194
195 return 0;
196}
diff --git a/apps/codecs/demac/libdemac/predictor.h b/apps/codecs/demac/libdemac/predictor.h
new file mode 100644
index 0000000000..3c023c8188
--- /dev/null
+++ b/apps/codecs/demac/libdemac/predictor.h
@@ -0,0 +1,36 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#ifndef _APE_PREDICTOR_H
26#define _APE_PREDICTOR_H
27
28#include <inttypes.h>
29#include "parser.h"
30#include "filter.h"
31
32void init_predictor_decoder(struct ape_ctx_t* ape_ctx);
33int predictor_decode_stereo(struct ape_ctx_t* ape_ctx, int32_t* decoded0, int32_t* decoded1, int count);
34int predictor_decode_mono(struct ape_ctx_t* ape_ctx, int32_t* decoded0, int count);
35
36#endif
diff --git a/apps/codecs/demac/libdemac/rangecoding.h b/apps/codecs/demac/libdemac/rangecoding.h
new file mode 100644
index 0000000000..8be5e923ba
--- /dev/null
+++ b/apps/codecs/demac/libdemac/rangecoding.h
@@ -0,0 +1,180 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25/*
26
27Range decoder adapted from rangecod.c included in:
28
29 http://www.compressconsult.com/rangecoder/rngcod13.zip
30
31 rangecod.c range encoding
32
33 (c) Michael Schindler
34 1997, 1998, 1999, 2000
35 http://www.compressconsult.com/
36 michael@compressconsult.com
37
38 This program is free software; you can redistribute it and/or modify
39 it under the terms of the GNU General Public License as published by
40 the Free Software Foundation; either version 2 of the License, or
41 (at your option) any later version.
42
43
44The encoding functions were removed, and functions turned into "static
45inline" functions and moved to a .h file. Some minor cosmetic changes
46were made (e.g. turning pre-processor symbols into upper-case,
47removing the rc parameter from each function (and the RNGC macro)).
48
49
50*/
51
52
53/* BITSTREAM READING FUNCTIONS */
54
55/* We deal with the input data one byte at a time - to ensure
56 functionality on CPUs of any endianness regardless of any requirements
57 for aligned reads.
58*/
59
60static unsigned char* bytebuffer IBSS_ATTR;
61static int bytebufferoffset IBSS_ATTR;
62
63static inline void skip_byte(void)
64{
65 if (bytebufferoffset) {
66 bytebufferoffset--;
67 } else {
68 bytebufferoffset = 3;
69 bytebuffer += 4;
70 }
71}
72
73static inline int read_byte(void)
74{
75 int ch = bytebuffer[bytebufferoffset];
76
77 skip_byte();
78
79 return ch;
80}
81
82/* RANGE DECODING FUNCTIONS */
83
84/* SIZE OF RANGE ENCODING CODE VALUES. */
85
86#define CODE_BITS 32
87#define TOP_VALUE ((unsigned int)1 << (CODE_BITS-1))
88#define SHIFT_BITS (CODE_BITS - 9)
89#define EXTRA_BITS ((CODE_BITS-2) % 8 + 1)
90#define BOTTOM_VALUE (TOP_VALUE >> 8)
91
92struct rangecoder_t
93{
94 uint32_t low; /* low end of interval */
95 uint32_t range; /* length of interval */
96 uint32_t help; /* bytes_to_follow resp. intermediate value */
97 unsigned int buffer; /* buffer for input/output */
98};
99
100static struct rangecoder_t rc;
101
102/* Start the decoder */
103static inline void range_start_decoding(void)
104{
105 rc.buffer = read_byte();
106 rc.low = rc.buffer >> (8 - EXTRA_BITS);
107 rc.range = (uint32_t) 1 << EXTRA_BITS;
108}
109
110static inline void range_dec_normalize(void)
111{
112 while (rc.range <= BOTTOM_VALUE)
113 {
114 rc.buffer = (rc.buffer << 8) | read_byte();
115 rc.low = (rc.low << 8) | ((rc.buffer >> 1) & 0xff);
116 rc.range <<= 8;
117 }
118}
119
120/* Calculate culmulative frequency for next symbol. Does NO update!*/
121/* tot_f is the total frequency */
122/* or: totf is (code_value)1<<shift */
123/* returns the culmulative frequency */
124static inline int range_decode_culfreq(int tot_f)
125{ int tmp;
126
127 range_dec_normalize();
128
129 rc.help = rc.range / tot_f;
130 tmp = rc.low / rc.help;
131
132 return tmp;
133}
134
135static inline int range_decode_culshift(int shift)
136{
137 int tmp;
138 range_dec_normalize();
139 rc.help = rc.range>>shift;
140 tmp = rc.low/rc.help;
141 return tmp;
142}
143
144
145/* Update decoding state */
146/* sy_f is the interval length (frequency of the symbol) */
147/* lt_f is the lower end (frequency sum of < symbols) */
148static inline void range_decode_update(int sy_f, int lt_f)
149{ int tmp;
150 tmp = rc.help * lt_f;
151 rc.low -= tmp;
152 rc.range = rc.help * sy_f;
153}
154
155
156/* Decode a byte/short without modelling */
157static inline unsigned char decode_byte(void)
158{ int tmp = range_decode_culshift(8);
159 range_decode_update( 1,tmp);
160 return tmp;
161}
162
163static inline int short range_decode_short(void)
164{ int tmp = range_decode_culshift(16);
165 range_decode_update( 1,tmp);
166 return tmp;
167}
168
169/* Decode n bits (n <= 16) without modelling - based on range_decode_short */
170static inline int range_decode_bits(int n)
171{ int tmp = range_decode_culshift(n);
172 range_decode_update( 1,tmp);
173 return tmp;
174}
175
176
177/* Finish decoding */
178static inline void range_done_decoding(void)
179{ range_dec_normalize(); /* normalize to use up all bytes */
180}
diff --git a/apps/codecs/demac/libdemac/vector_math16.h b/apps/codecs/demac/libdemac/vector_math16.h
new file mode 100644
index 0000000000..5d82abe930
--- /dev/null
+++ b/apps/codecs/demac/libdemac/vector_math16.h
@@ -0,0 +1,140 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25static inline void vector_add(int16_t* v1, int16_t* v2)
26{
27#if ORDER > 32
28 int order = (ORDER >> 5);
29 while (order--)
30#endif
31 {
32 *v1++ += *v2++;
33 *v1++ += *v2++;
34 *v1++ += *v2++;
35 *v1++ += *v2++;
36 *v1++ += *v2++;
37 *v1++ += *v2++;
38 *v1++ += *v2++;
39 *v1++ += *v2++;
40 *v1++ += *v2++;
41 *v1++ += *v2++;
42 *v1++ += *v2++;
43 *v1++ += *v2++;
44 *v1++ += *v2++;
45 *v1++ += *v2++;
46 *v1++ += *v2++;
47 *v1++ += *v2++;
48#if ORDER > 16
49 *v1++ += *v2++;
50 *v1++ += *v2++;
51 *v1++ += *v2++;
52 *v1++ += *v2++;
53 *v1++ += *v2++;
54 *v1++ += *v2++;
55 *v1++ += *v2++;
56 *v1++ += *v2++;
57 *v1++ += *v2++;
58 *v1++ += *v2++;
59 *v1++ += *v2++;
60 *v1++ += *v2++;
61 *v1++ += *v2++;
62 *v1++ += *v2++;
63 *v1++ += *v2++;
64 *v1++ += *v2++;
65#endif
66 }
67}
68
69static inline void vector_sub(int16_t* v1, int16_t* v2)
70{
71#if ORDER > 32
72 int order = (ORDER >> 5);
73 while (order--)
74#endif
75 {
76 *v1++ -= *v2++;
77 *v1++ -= *v2++;
78 *v1++ -= *v2++;
79 *v1++ -= *v2++;
80 *v1++ -= *v2++;
81 *v1++ -= *v2++;
82 *v1++ -= *v2++;
83 *v1++ -= *v2++;
84 *v1++ -= *v2++;
85 *v1++ -= *v2++;
86 *v1++ -= *v2++;
87 *v1++ -= *v2++;
88 *v1++ -= *v2++;
89 *v1++ -= *v2++;
90 *v1++ -= *v2++;
91 *v1++ -= *v2++;
92#if ORDER > 16
93 *v1++ -= *v2++;
94 *v1++ -= *v2++;
95 *v1++ -= *v2++;
96 *v1++ -= *v2++;
97 *v1++ -= *v2++;
98 *v1++ -= *v2++;
99 *v1++ -= *v2++;
100 *v1++ -= *v2++;
101 *v1++ -= *v2++;
102 *v1++ -= *v2++;
103 *v1++ -= *v2++;
104 *v1++ -= *v2++;
105 *v1++ -= *v2++;
106 *v1++ -= *v2++;
107 *v1++ -= *v2++;
108 *v1++ -= *v2++;
109#endif
110 }
111}
112
113static inline int32_t scalarproduct(int16_t* v1, int16_t* v2)
114{
115 int res = 0;
116
117#if ORDER > 16
118 int order = (ORDER >> 4);
119 while (order--)
120#endif
121 {
122 res += *v1++ * *v2++;
123 res += *v1++ * *v2++;
124 res += *v1++ * *v2++;
125 res += *v1++ * *v2++;
126 res += *v1++ * *v2++;
127 res += *v1++ * *v2++;
128 res += *v1++ * *v2++;
129 res += *v1++ * *v2++;
130 res += *v1++ * *v2++;
131 res += *v1++ * *v2++;
132 res += *v1++ * *v2++;
133 res += *v1++ * *v2++;
134 res += *v1++ * *v2++;
135 res += *v1++ * *v2++;
136 res += *v1++ * *v2++;
137 res += *v1++ * *v2++;
138 }
139 return res;
140}
diff --git a/apps/codecs/demac/libdemac/vector_math32.h b/apps/codecs/demac/libdemac/vector_math32.h
new file mode 100644
index 0000000000..b32867ca5d
--- /dev/null
+++ b/apps/codecs/demac/libdemac/vector_math32.h
@@ -0,0 +1,54 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25/* 32-bit vector math functions */
26
27#define scalarproduct4_rev32(x,y) ((x[0] * y[0]) + (x[1] * y[-1]) + \
28 (x[2] * y[-2]) + (x[3] * y[-3]))
29
30#define scalarproduct5_rev32(x,y) ((x[0] * y[0]) + (x[1] * y[-1]) + \
31 (x[2] * y[-2]) + (x[3] * y[-3]) + \
32 (x[4] * y[-4]))
33
34#define vector_sub4_rev32(x, y) { x[0] -= y[0]; \
35 x[1] -= y[-1]; \
36 x[2] -= y[-2]; \
37 x[3] -= y[-3]; }
38
39#define vector_sub5_rev32(x, y) { x[0] -= y[0]; \
40 x[1] -= y[-1]; \
41 x[2] -= y[-2]; \
42 x[3] -= y[-3]; \
43 x[4] -= y[-4]; }
44
45#define vector_add4_rev32(x, y) { x[0] += y[0]; \
46 x[1] += y[-1]; \
47 x[2] += y[-2]; \
48 x[3] += y[-3]; }
49
50#define vector_add5_rev32(x, y) { x[0] += y[0]; \
51 x[1] += y[-1]; \
52 x[2] += y[-2]; \
53 x[3] += y[-3]; \
54 x[4] += y[-4]; }
diff --git a/apps/codecs/demac/wavwrite.c b/apps/codecs/demac/wavwrite.c
new file mode 100644
index 0000000000..5fb82e148a
--- /dev/null
+++ b/apps/codecs/demac/wavwrite.c
@@ -0,0 +1,107 @@
1/*
2
3demac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#include <stdio.h>
26#include <inttypes.h>
27#include <stdlib.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <fcntl.h>
31#include <unistd.h>
32#include <string.h>
33
34#include "parser.h"
35
36
37static unsigned char wav_header[44]={
38 'R','I','F','F',// 0 - ChunkID
39 0,0,0,0, // 4 - ChunkSize (filesize-8)
40 'W','A','V','E',// 8 - Format
41 'f','m','t',' ',// 12 - SubChunkID
42 16,0,0,0, // 16 - SubChunk1ID // 16 for PCM
43 1,0, // 20 - AudioFormat (1=Uncompressed)
44 2,0, // 22 - NumChannels
45 0,0,0,0, // 24 - SampleRate in Hz
46 0,0,0,0, // 28 - Byte Rate (SampleRate*NumChannels*(BitsPerSample/8)
47 4,0, // 32 - BlockAlign (== NumChannels * BitsPerSample/8)
48 16,0, // 34 - BitsPerSample
49 'd','a','t','a',// 36 - Subchunk2ID
50 0,0,0,0 // 40 - Subchunk2Size
51};
52
53int open_wav(struct ape_ctx_t* ape_ctx, char* filename)
54{
55 int fd;
56 int x;
57 int filesize;
58 int bytespersample;
59
60 fd=creat(filename,0644);
61 if (fd < 0)
62 return fd;
63
64 bytespersample=ape_ctx->bps/8;
65
66 filesize=ape_ctx->totalsamples*bytespersample*ape_ctx->channels+44;
67
68 // ChunkSize
69 x=filesize-8;
70 wav_header[4]=(x&0xff);
71 wav_header[5]=(x&0xff00)>>8;
72 wav_header[6]=(x&0xff0000)>>16;
73 wav_header[7]=(x&0xff000000)>>24;
74
75 // Number of channels
76 wav_header[22]=ape_ctx->channels;
77
78 // Samplerate
79 wav_header[24]=ape_ctx->samplerate&0xff;
80 wav_header[25]=(ape_ctx->samplerate&0xff00)>>8;
81 wav_header[26]=(ape_ctx->samplerate&0xff0000)>>16;
82 wav_header[27]=(ape_ctx->samplerate&0xff000000)>>24;
83
84 // ByteRate
85 x=ape_ctx->samplerate*(ape_ctx->bps/8)*ape_ctx->channels;
86 wav_header[28]=(x&0xff);
87 wav_header[29]=(x&0xff00)>>8;
88 wav_header[30]=(x&0xff0000)>>16;
89 wav_header[31]=(x&0xff000000)>>24;
90
91 // BlockAlign
92 wav_header[32]=(ape_ctx->bps/8)*ape_ctx->channels;
93
94 // Bits per sample
95 wav_header[34]=ape_ctx->bps;
96
97 // Subchunk2Size
98 x=filesize-44;
99 wav_header[40]=(x&0xff);
100 wav_header[41]=(x&0xff00)>>8;
101 wav_header[42]=(x&0xff0000)>>16;
102 wav_header[43]=(x&0xff000000)>>24;
103
104 write(fd,wav_header,sizeof(wav_header));
105
106 return fd;
107}
diff --git a/apps/codecs/demac/wavwrite.h b/apps/codecs/demac/wavwrite.h
new file mode 100644
index 0000000000..eba8ac7e31
--- /dev/null
+++ b/apps/codecs/demac/wavwrite.h
@@ -0,0 +1,32 @@
1/*
2
3demac - A Monkey's Audio decoder
4
5$Id:$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#ifndef _APE_WAVWRITE_H
26#define _APE_WAVWRITE_H
27
28#include "parser.h"
29
30int open_wav(struct ape_ctx_t* ape_ctx, char* filename);
31
32#endif
diff --git a/apps/filetypes.c b/apps/filetypes.c
index 3e03c0bda1..e826efc7dc 100644
--- a/apps/filetypes.c
+++ b/apps/filetypes.c
@@ -76,6 +76,8 @@ const struct filetype inbuilt_filetypes[] = {
76 { "nsf", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA }, 76 { "nsf", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
77 { "nsfe",FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA }, 77 { "nsfe",FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
78 { "spc", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA }, 78 { "spc", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
79 { "ape", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
80 { "mac", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
79#endif 81#endif
80 { "m3u", FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST }, 82 { "m3u", FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST },
81 { "m3u8",FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST }, 83 { "m3u8",FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST },
diff --git a/apps/metadata.c b/apps/metadata.c
index 1bbff1d370..60191b1eb8 100644
--- a/apps/metadata.c
+++ b/apps/metadata.c
@@ -982,6 +982,56 @@ static bool get_flac_metadata(int fd, struct mp3entry* id3)
982 return true; 982 return true;
983} 983}
984 984
985static bool get_monkeys_metadata(int fd, struct mp3entry* id3)
986{
987 /* Use the trackname part of the id3 structure as a temporary buffer */
988 unsigned char* buf = (unsigned char *)id3->path;
989 unsigned char* header;
990 bool rc = false;
991 uint32_t descriptorlength;
992 uint32_t totalsamples;
993 uint32_t blocksperframe, finalframeblocks, totalframes;
994
995 lseek(fd, 0, SEEK_SET);
996
997 if (read(fd, buf, 4) < 4)
998 {
999 return rc;
1000 }
1001
1002 if (memcmp(buf, "MAC ", 4) != 0)
1003 {
1004 return rc;
1005 }
1006
1007 read(fd, buf + 4, MAX_PATH - 4);
1008
1009 descriptorlength = buf[8] | (buf[9] << 8) |
1010 (buf[10] << 16) | (buf[11] << 24);
1011
1012 header = buf + descriptorlength;
1013
1014 blocksperframe = header[4] | (header[5] << 8) |
1015 (header[6] << 16) | (header[7] << 24);
1016 finalframeblocks = header[8] | (header[9] << 8) |
1017 (header[10] << 16) | (header[11] << 24);
1018 totalframes = header[12] | (header[13] << 8) |
1019 (header[14] << 16) | (header[15] << 24);
1020
1021 id3->vbr = true; /* All FLAC files are VBR */
1022 id3->filesize = filesize(fd);
1023 id3->frequency = header[20] | (header[21] << 8) |
1024 (header[22] << 16) | (header[23] << 24);
1025
1026 totalsamples = finalframeblocks;
1027 if (totalframes > 1)
1028 totalsamples += blocksperframe * (totalframes-1);
1029
1030 id3->length = ((int64_t) totalsamples * 1000) / id3->frequency;
1031 id3->bitrate = (id3->filesize * 8) / id3->length;
1032 return true;
1033}
1034
985static bool get_wave_metadata(int fd, struct mp3entry* id3) 1035static bool get_wave_metadata(int fd, struct mp3entry* id3)
986{ 1036{
987 /* Use the trackname part of the id3 structure as a temporary buffer */ 1037 /* 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,
2152 2202
2153 break; 2203 break;
2154 2204
2205 case AFMT_APE:
2206 if (!get_monkeys_metadata(fd, &(track->id3)))
2207 {
2208 return false;
2209 }
2210 read_ape_tags(fd, &(track->id3));
2211 break;
2212
2155 case AFMT_MPC: 2213 case AFMT_MPC:
2156 if (!get_musepack_metadata(fd, &(track->id3))) 2214 if (!get_musepack_metadata(fd, &(track->id3)))
2157 return false; 2215 return false;
diff --git a/firmware/export/id3.h b/firmware/export/id3.h
index 5cc600face..791f86390e 100644
--- a/firmware/export/id3.h
+++ b/firmware/export/id3.h
@@ -53,6 +53,7 @@ enum
53 AFMT_NSF, /* NESM (NES Sound Format) */ 53 AFMT_NSF, /* NESM (NES Sound Format) */
54 AFMT_SPEEX, /* Ogg Speex speech */ 54 AFMT_SPEEX, /* Ogg Speex speech */
55 AFMT_SPC, /* SPC700 save state */ 55 AFMT_SPC, /* SPC700 save state */
56 AFMT_APE, /* Monkey's Audio (APE) */
56#endif 57#endif
57 58
58 /* add new formats at any index above this line to have a sensible order - 59 /* add new formats at any index above this line to have a sensible order -
diff --git a/firmware/id3.c b/firmware/id3.c
index eaaf2a9ecd..3e7b392554 100644
--- a/firmware/id3.c
+++ b/firmware/id3.c
@@ -107,6 +107,9 @@ const struct afmt_entry audio_formats[AFMT_NUM_CODECS] =
107 /* SPC700 Save State */ 107 /* SPC700 Save State */
108 [AFMT_SPC] = 108 [AFMT_SPC] =
109 AFMT_ENTRY("SPC", "spc", NULL, "spc\0" ), 109 AFMT_ENTRY("SPC", "spc", NULL, "spc\0" ),
110 /* APE (Monkey's Audio) */
111 [AFMT_APE] =
112 AFMT_ENTRY("APE", "ape", NULL, "ape\0mac\0" ),
110#endif 113#endif
111}; 114};
112 115
diff --git a/tools/configure b/tools/configure
index 1f041f7ebf..1a84a487ee 100755
--- a/tools/configure
+++ b/tools/configure
@@ -756,7 +756,7 @@ EOF
756 archosrom="" 756 archosrom=""
757 flash="$pwd/rombox.iriver" 757 flash="$pwd/rombox.iriver"
758 plugins="yes" 758 plugins="yes"
759 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 759 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
760 # toolset is the tools within the tools directory that we build for 760 # toolset is the tools within the tools directory that we build for
761 # this particular target. 761 # this particular target.
762 toolset=$iriverbitmaptools 762 toolset=$iriverbitmaptools
@@ -781,7 +781,7 @@ EOF
781 archosrom="" 781 archosrom=""
782 flash="" 782 flash=""
783 plugins="yes" 783 plugins="yes"
784 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 784 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
785 # toolset is the tools within the tools directory that we build for 785 # toolset is the tools within the tools directory that we build for
786 # this particular target. 786 # this particular target.
787 toolset=$iriverbitmaptools 787 toolset=$iriverbitmaptools
@@ -806,7 +806,7 @@ EOF
806 archosrom="" 806 archosrom=""
807 flash="" 807 flash=""
808 plugins="yes" 808 plugins="yes"
809 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 809 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
810 # toolset is the tools within the tools directory that we build for 810 # toolset is the tools within the tools directory that we build for
811 # this particular target. 811 # this particular target.
812 toolset=$iriverbitmaptools 812 toolset=$iriverbitmaptools
@@ -831,7 +831,7 @@ EOF
831 archosrom="" 831 archosrom=""
832 flash="" 832 flash=""
833 plugins="yes" 833 plugins="yes"
834 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 834 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
835 # toolset is the tools within the tools directory that we build for 835 # toolset is the tools within the tools directory that we build for
836 # this particular target. 836 # this particular target.
837 toolset="$iaudiobitmaptools" 837 toolset="$iaudiobitmaptools"
@@ -857,7 +857,7 @@ EOF
857 archosrom="" 857 archosrom=""
858 flash="" 858 flash=""
859 plugins="yes" 859 plugins="yes"
860 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 860 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
861 # toolset is the tools within the tools directory that we build for 861 # toolset is the tools within the tools directory that we build for
862 # this particular target. 862 # this particular target.
863 toolset="$iaudiobitmaptools" 863 toolset="$iaudiobitmaptools"
@@ -881,7 +881,7 @@ EOF
881 archosrom="" 881 archosrom=""
882 flash="" 882 flash=""
883 plugins="yes" 883 plugins="yes"
884 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 884 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
885 bootoutput="bootloader-$archos.ipod" 885 bootoutput="bootloader-$archos.ipod"
886 # toolset is the tools within the tools directory that we build for 886 # toolset is the tools within the tools directory that we build for
887 # this particular target. 887 # this particular target.
@@ -906,7 +906,7 @@ EOF
906 archosrom="" 906 archosrom=""
907 flash="" 907 flash=""
908 plugins="yes" 908 plugins="yes"
909 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 909 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
910 bootoutput="bootloader-$archos.ipod" 910 bootoutput="bootloader-$archos.ipod"
911 # toolset is the tools within the tools directory that we build for 911 # toolset is the tools within the tools directory that we build for
912 # this particular target. 912 # this particular target.
@@ -930,7 +930,7 @@ EOF
930 archosrom="" 930 archosrom=""
931 flash="" 931 flash=""
932 plugins="yes" 932 plugins="yes"
933 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 933 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
934 bootoutput="bootloader-$archos.ipod" 934 bootoutput="bootloader-$archos.ipod"
935 # toolset is the tools within the tools directory that we build for 935 # toolset is the tools within the tools directory that we build for
936 # this particular target. 936 # this particular target.
@@ -955,7 +955,7 @@ EOF
955 archosrom="" 955 archosrom=""
956 flash="" 956 flash=""
957 plugins="yes" 957 plugins="yes"
958 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 958 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
959 bootoutput="bootloader-$archos.ipod" 959 bootoutput="bootloader-$archos.ipod"
960 # toolset is the tools within the tools directory that we build for 960 # toolset is the tools within the tools directory that we build for
961 # this particular target. 961 # this particular target.
@@ -980,7 +980,7 @@ EOF
980 archosrom="" 980 archosrom=""
981 flash="" 981 flash=""
982 plugins="yes" 982 plugins="yes"
983 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 983 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
984 bootoutput="bootloader-$archos.ipod" 984 bootoutput="bootloader-$archos.ipod"
985 # toolset is the tools within the tools directory that we build for 985 # toolset is the tools within the tools directory that we build for
986 # this particular target. 986 # this particular target.
@@ -1005,7 +1005,7 @@ EOF
1005 archosrom="" 1005 archosrom=""
1006 flash="" 1006 flash=""
1007 plugins="yes" 1007 plugins="yes"
1008 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 1008 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
1009 bootoutput="bootloader-$archos.ipod" 1009 bootoutput="bootloader-$archos.ipod"
1010 # toolset is the tools within the tools directory that we build for 1010 # toolset is the tools within the tools directory that we build for
1011 # this particular target. 1011 # this particular target.
@@ -1030,7 +1030,7 @@ EOF
1030 archosrom="" 1030 archosrom=""
1031 flash="" 1031 flash=""
1032 plugins="yes" 1032 plugins="yes"
1033 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 1033 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
1034 # toolset is the tools within the tools directory that we build for 1034 # toolset is the tools within the tools directory that we build for
1035 # this particular target. 1035 # this particular target.
1036 toolset=$genericbitmaptools 1036 toolset=$genericbitmaptools
@@ -1053,7 +1053,7 @@ EOF
1053 archosrom="" 1053 archosrom=""
1054 flash="" 1054 flash=""
1055 plugins="yes" 1055 plugins="yes"
1056 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 1056 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
1057 toolset=$gigabeatbitmaptools 1057 toolset=$gigabeatbitmaptools
1058 boottool="$rootdir/tools/scramble -gigabeat" 1058 boottool="$rootdir/tools/scramble -gigabeat"
1059 bootoutput="FWIMG01.DAT" 1059 bootoutput="FWIMG01.DAT"
@@ -1077,7 +1077,7 @@ EOF
1077 archosrom="" 1077 archosrom=""
1078 flash="" 1078 flash=""
1079 plugins="yes" 1079 plugins="yes"
1080 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 1080 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
1081 bootoutput="bootloader-$archos.ipod" 1081 bootoutput="bootloader-$archos.ipod"
1082 # toolset is the tools within the tools directory that we build for 1082 # toolset is the tools within the tools directory that we build for
1083 # this particular target. 1083 # this particular target.
@@ -1102,7 +1102,7 @@ EOF
1102 archosrom="" 1102 archosrom=""
1103 flash="" 1103 flash=""
1104 plugins="yes" 1104 plugins="yes"
1105 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 1105 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
1106 boottool="$rootdir/tools/scramble -mi4v3 -model=h10 -type=RBBL" 1106 boottool="$rootdir/tools/scramble -mi4v3 -model=h10 -type=RBBL"
1107 bootoutput="H10_20GC.mi4" 1107 bootoutput="H10_20GC.mi4"
1108 # toolset is the tools within the tools directory that we build for 1108 # toolset is the tools within the tools directory that we build for
@@ -1128,7 +1128,7 @@ EOF
1128 archosrom="" 1128 archosrom=""
1129 flash="" 1129 flash=""
1130 plugins="yes" 1130 plugins="yes"
1131 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 1131 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
1132 boottool="$rootdir/tools/scramble -mi4v2 -model=h105 -type=RBBL" 1132 boottool="$rootdir/tools/scramble -mi4v2 -model=h105 -type=RBBL"
1133 bootoutput="H10.mi4" 1133 bootoutput="H10.mi4"
1134 # toolset is the tools within the tools directory that we build for 1134 # toolset is the tools within the tools directory that we build for
@@ -1154,7 +1154,7 @@ EOF
1154 archosrom="" 1154 archosrom=""
1155 flash="" 1155 flash=""
1156 plugins="yes" 1156 plugins="yes"
1157 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 1157 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
1158 boottool="$rootdir/tools/scramble -mi4v3 -model=e200 -type=RBBL" 1158 boottool="$rootdir/tools/scramble -mi4v3 -model=e200 -type=RBBL"
1159 bootoutput="PP5022.mi4" 1159 bootoutput="PP5022.mi4"
1160 # toolset is the tools within the tools directory that we build for 1160 # toolset is the tools within the tools directory that we build for
@@ -1183,7 +1183,7 @@ EOF
1183 archosrom="" 1183 archosrom=""
1184 flash="" 1184 flash=""
1185 plugins="yes" 1185 plugins="yes"
1186 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 1186 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
1187 boottool="$rootdir/tools/scramble -mi4r -model=e20r -type=RBBL" 1187 boottool="$rootdir/tools/scramble -mi4r -model=e20r -type=RBBL"
1188 bootoutput="pp5022.mi4" 1188 bootoutput="pp5022.mi4"
1189 # toolset is the tools within the tools directory that we build for 1189 # toolset is the tools within the tools directory that we build for
@@ -1209,7 +1209,7 @@ EOF
1209 archosrom="" 1209 archosrom=""
1210 flash="" 1210 flash=""
1211 plugins="yes" 1211 plugins="yes"
1212 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex" 1212 codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
1213 boottool="$rootdir/tools/scramble -mi4v2" 1213 boottool="$rootdir/tools/scramble -mi4v2"
1214 bootoutput="pp5020.mi4" 1214 bootoutput="pp5020.mi4"
1215 # toolset is the tools within the tools directory that we build for 1215 # toolset is the tools within the tools directory that we build for