summaryrefslogtreecommitdiff
path: root/apps/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs')
-rw-r--r--apps/codecs/SOURCES1
-rw-r--r--apps/codecs/codecs.make1
-rw-r--r--apps/codecs/librm/rm.c29
-rw-r--r--apps/codecs/raac.c176
4 files changed, 200 insertions, 7 deletions
diff --git a/apps/codecs/SOURCES b/apps/codecs/SOURCES
index 44a8498fa9..dc6819d272 100644
--- a/apps/codecs/SOURCES
+++ b/apps/codecs/SOURCES
@@ -10,6 +10,7 @@ wavpack.c
10alac.c 10alac.c
11#endif 11#endif
12cook.c 12cook.c
13raac.c
13mpc.c 14mpc.c
14wma.c 15wma.c
15sid.c 16sid.c
diff --git a/apps/codecs/codecs.make b/apps/codecs/codecs.make
index fbe3b1c978..b327bd7c69 100644
--- a/apps/codecs/codecs.make
+++ b/apps/codecs/codecs.make
@@ -76,6 +76,7 @@ $(CODECDIR)/wma.codec : $(CODECDIR)/libwma.a
76$(CODECDIR)/wavpack_enc.codec: $(CODECDIR)/libwavpack.a 76$(CODECDIR)/wavpack_enc.codec: $(CODECDIR)/libwavpack.a
77$(CODECDIR)/asap.codec : $(CODECDIR)/libasap.a 77$(CODECDIR)/asap.codec : $(CODECDIR)/libasap.a
78$(CODECDIR)/cook.codec : $(CODECDIR)/libcook.a $(CODECDIR)/librm.a 78$(CODECDIR)/cook.codec : $(CODECDIR)/libcook.a $(CODECDIR)/librm.a
79$(CODECDIR)/raac.codec : $(CODECDIR)/libfaad.a $(CODECDIR)/librm.a
79 80
80$(CODECS): $(CODECLIB) # this must be last in codec dependency list 81$(CODECS): $(CODECLIB) # this must be last in codec dependency list
81 82
diff --git a/apps/codecs/librm/rm.c b/apps/codecs/librm/rm.c
index c9c40986ba..a48fb51cc6 100644
--- a/apps/codecs/librm/rm.c
+++ b/apps/codecs/librm/rm.c
@@ -529,13 +529,28 @@ int rm_get_packet(uint8_t **src,RMContext *rmctx, RMPacket *pkt)
529 529
530 advance_buffer(src,12); 530 advance_buffer(src,12);
531 consumed += 12; 531 consumed += 12;
532 for(x = 0 ; x < w/sps; x++) 532 if (rmctx->codec_type == cook) {
533 { 533 for(x = 0 ; x < w/sps; x++)
534 place = sps*(h*x+((h+1)/2)*(y&1)+(y>>1)); 534 {
535 pkt->frames[place/sps] = *src; 535 place = sps*(h*x+((h+1)/2)*(y&1)+(y>>1));
536 advance_buffer(src,sps); 536 pkt->frames[place/sps] = *src;
537 consumed += sps; 537 advance_buffer(src,sps);
538 } 538 consumed += sps;
539 }
540 }
541 else if (rmctx->codec_type == aac) {
542 rmctx->sub_packet_cnt = (get_uint16be(*src) & 0xf0) >> 4;
543 advance_buffer(src, 2);
544 consumed += 2;
545 if (rmctx->sub_packet_cnt) {
546 for(x = 0; x < rmctx->sub_packet_cnt; x++) {
547 rmctx->sub_packet_lengths[x] = get_uint16be(*src);
548 advance_buffer(src, 2);
549 consumed += 2;
550 }
551 rmctx->audio_pkt_cnt = --rmctx->sub_packet_cnt;
552 }
553 }
539 rmctx->audio_pkt_cnt++; 554 rmctx->audio_pkt_cnt++;
540 }while(++(rmctx->sub_packet_cnt) < h); 555 }while(++(rmctx->sub_packet_cnt) < h);
541 556
diff --git a/apps/codecs/raac.c b/apps/codecs/raac.c
new file mode 100644
index 0000000000..cfc5b4a460
--- /dev/null
+++ b/apps/codecs/raac.c
@@ -0,0 +1,176 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: aac.c 19743 2009-01-10 21:10:56Z zagor $
9 *
10 * Copyright (C) 2009 Mohamed Tarek
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "codeclib.h"
23#include "librm/rm.h"
24#include "libfaad/common.h"
25#include "libfaad/structs.h"
26#include "libfaad/decoder.h"
27#include "libfaad/output.h"
28
29CODEC_HEADER
30#define DATA_HEADER_SIZE 18
31static void init_rm(RMContext *rmctx)
32{
33 memcpy(rmctx, (void*)(( (intptr_t)ci->id3->id3v2buf + 3 ) &~ 3), sizeof(RMContext));
34}
35
36RMContext rmctx;
37RMPacket pkt;
38/* this is the codec entry point */
39enum codec_status codec_main(void)
40{
41 static NeAACDecFrameInfo frame_info;
42 NeAACDecHandle decoder;
43 size_t n;
44 int32_t *output;
45 unsigned int i;
46 unsigned char* buffer;
47 int err, consumed, pkt_offset, skipped = 0;
48 uint32_t s = 0; /* sample rate */
49 unsigned char c = 0; /* channels */
50 /* Generic codec initialisation */
51 ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED);
52 ci->configure(DSP_SET_SAMPLE_DEPTH, 16);
53
54next_track:
55 err = CODEC_OK;
56
57 if (codec_init()) {
58 DEBUGF("FAAD: Codec init error\n");
59 return CODEC_ERROR;
60 }
61
62 while (!*ci->taginfo_ready && !ci->stop_codec)
63 ci->sleep(1);
64
65 ci->memset(&rmctx,0,sizeof(RMContext));
66 ci->memset(&pkt,0,sizeof(RMPacket));
67 init_rm(&rmctx);
68 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
69 codec_set_replaygain(ci->id3);
70
71 /* initialise the sound converter */
72 decoder = NeAACDecOpen();
73
74 if (!decoder) {
75 DEBUGF("FAAD: Decode open error\n");
76 err = CODEC_ERROR;
77 goto done;
78 }
79 NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration(decoder);
80 conf->outputFormat = FAAD_FMT_16BIT;
81 NeAACDecSetConfiguration(decoder, conf);
82
83 decoder->config.defObjectType = rmctx.codec_extradata[0];
84 decoder->config.defSampleRate = rmctx.sample_rate;
85 err = NeAACDecInit(decoder, NULL, 0, &s, &c);
86
87 if (err) {
88 DEBUGF("FAAD: DecInit: %d, %d\n", err, decoder->object_type);
89 err = CODEC_ERROR;
90 goto done;
91 }
92 ci->id3->frequency = s;
93 ci->set_elapsed(0);
94 ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE);
95
96 /* The main decoding loop */
97seek_start:
98 while (1) {
99 ci->yield();
100 if (ci->stop_codec || ci->new_track) {
101 break;
102 }
103
104 if (ci->seek_time) {
105
106 /* Do not allow seeking beyond the file's length */
107 if ((unsigned) ci->seek_time > ci->id3->length) {
108 ci->seek_complete();
109 goto done;
110 }
111
112 ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE);
113
114 /* Seek to the start of the track */
115 if (ci->seek_time == 1) {
116 ci->set_elapsed(0);
117 ci->seek_complete();
118 goto seek_start;
119 }
120
121 skipped = 0;
122 while(1) {
123 buffer = ci->request_buffer(&n,rmctx.audio_framesize + 1000);
124 pkt_offset = skipped - pkt.length;
125 consumed = rm_get_packet(&buffer, &rmctx, &pkt);
126 if(consumed < 0) {
127 DEBUGF("rm_get_packet failed\n");
128 return CODEC_ERROR;
129 }
130 skipped += pkt.length;
131 if(pkt.timestamp > (unsigned)ci->seek_time) break;
132 ci->advance_buffer(pkt.length);
133 }
134 ci->seek_buffer(pkt_offset + rmctx.data_offset + DATA_HEADER_SIZE);
135 buffer = ci->request_buffer(&n,rmctx.audio_framesize + 1000);
136 ci->seek_complete();
137 }
138
139 /* Request the required number of bytes from the input buffer */
140 buffer=ci->request_buffer(&n,rmctx.audio_framesize + 1000);
141 consumed = rm_get_packet(&buffer, &rmctx, &pkt);
142 if(consumed < 0) {
143 DEBUGF("rm_get_packet failed\n");
144 return CODEC_ERROR;
145 }
146
147 if (pkt.timestamp >= ci->id3->length)
148 goto done;
149 /* Decode one block - returned samples will be host-endian */
150 for(i = 0; i < rmctx.sub_packet_cnt; i++) {
151 output = (int32_t *)NeAACDecDecode(decoder, &frame_info, buffer, rmctx.sub_packet_lengths[i]);
152 buffer += rmctx.sub_packet_lengths[i];
153 if (frame_info.error > 0) {
154 DEBUGF("FAAD: decode error '%s'\n", NeAACDecGetErrorMessage(frame_info.error));
155 err = CODEC_ERROR;
156 goto exit;
157 }
158 output = (int32_t *) output_to_PCM(decoder, decoder->time_out, output,
159 rmctx.nb_channels, decoder->frameLength, decoder->config.outputFormat);
160 ci->pcmbuf_insert(output, NULL, frame_info.samples/rmctx.nb_channels);
161 ci->set_elapsed(pkt.timestamp);
162 }
163
164 ci->advance_buffer(pkt.length);
165 }
166
167 err = CODEC_OK;
168
169done:
170 if (ci->request_next_track())
171 goto next_track;
172
173exit:
174 return err;
175}
176