diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs/SOURCES | 1 | ||||
-rw-r--r-- | apps/codecs/codecs.make | 1 | ||||
-rw-r--r-- | apps/codecs/librm/rm.c | 29 | ||||
-rw-r--r-- | apps/codecs/raac.c | 176 | ||||
-rw-r--r-- | apps/metadata.c | 3 | ||||
-rw-r--r-- | apps/metadata.h | 1 | ||||
-rw-r--r-- | apps/metadata/rm.c | 19 |
7 files changed, 217 insertions, 13 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 | |||
10 | alac.c | 10 | alac.c |
11 | #endif | 11 | #endif |
12 | cook.c | 12 | cook.c |
13 | raac.c | ||
13 | mpc.c | 14 | mpc.c |
14 | wma.c | 15 | wma.c |
15 | sid.c | 16 | sid.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 | |||
29 | CODEC_HEADER | ||
30 | #define DATA_HEADER_SIZE 18 | ||
31 | static void init_rm(RMContext *rmctx) | ||
32 | { | ||
33 | memcpy(rmctx, (void*)(( (intptr_t)ci->id3->id3v2buf + 3 ) &~ 3), sizeof(RMContext)); | ||
34 | } | ||
35 | |||
36 | RMContext rmctx; | ||
37 | RMPacket pkt; | ||
38 | /* this is the codec entry point */ | ||
39 | enum 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 | |||
54 | next_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 */ | ||
97 | seek_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 | |||
169 | done: | ||
170 | if (ci->request_next_track()) | ||
171 | goto next_track; | ||
172 | |||
173 | exit: | ||
174 | return err; | ||
175 | } | ||
176 | |||
diff --git a/apps/metadata.c b/apps/metadata.c index a0409a83ac..80f2c126e2 100644 --- a/apps/metadata.c +++ b/apps/metadata.c | |||
@@ -118,6 +118,9 @@ const struct afmt_entry audio_formats[AFMT_NUM_CODECS] = | |||
118 | /* Cook in RM/RA */ | 118 | /* Cook in RM/RA */ |
119 | [AFMT_COOK] = | 119 | [AFMT_COOK] = |
120 | AFMT_ENTRY("Cook", "cook", NULL, "rm\0ra\0" ), | 120 | AFMT_ENTRY("Cook", "cook", NULL, "rm\0ra\0" ), |
121 | /* AAC in RM/RA */ | ||
122 | [AFMT_RAAC] = | ||
123 | AFMT_ENTRY("RAAC", "raac", NULL, NULL ), | ||
121 | #endif | 124 | #endif |
122 | }; | 125 | }; |
123 | 126 | ||
diff --git a/apps/metadata.h b/apps/metadata.h index f3b50c947d..0125b29e5e 100644 --- a/apps/metadata.h +++ b/apps/metadata.h | |||
@@ -62,6 +62,7 @@ enum | |||
62 | AFMT_MOD, /* Amiga MOD File Format */ | 62 | AFMT_MOD, /* Amiga MOD File Format */ |
63 | AFMT_SAP, /* Amiga 8Bit SAP Format */ | 63 | AFMT_SAP, /* Amiga 8Bit SAP Format */ |
64 | AFMT_COOK, /* Cook in RM/RA */ | 64 | AFMT_COOK, /* Cook in RM/RA */ |
65 | AFMT_RAAC, /* AAC in RM/RA */ | ||
65 | #endif | 66 | #endif |
66 | 67 | ||
67 | /* add new formats at any index above this line to have a sensible order - | 68 | /* add new formats at any index above this line to have a sensible order - |
diff --git a/apps/metadata/rm.c b/apps/metadata/rm.c index bfaa803be7..95889c35c3 100644 --- a/apps/metadata/rm.c +++ b/apps/metadata/rm.c | |||
@@ -169,6 +169,11 @@ static inline int real_read_audio_stream_info(int fd, RMContext *rmctx) | |||
169 | rmctx->codec_type = cook; | 169 | rmctx->codec_type = cook; |
170 | break; | 170 | break; |
171 | 171 | ||
172 | case FOURCC('r','a','a','c'): | ||
173 | case FOURCC('r','a','c','p'): | ||
174 | rmctx->codec_type = aac; | ||
175 | break; | ||
176 | |||
172 | default: /* Not a supported codec */ | 177 | default: /* Not a supported codec */ |
173 | return -1; | 178 | return -1; |
174 | } | 179 | } |
@@ -183,7 +188,10 @@ static inline int real_read_audio_stream_info(int fd, RMContext *rmctx) | |||
183 | DEBUGF(" fourcc = %s\n",fourcc2str(fourcc)); | 188 | DEBUGF(" fourcc = %s\n",fourcc2str(fourcc)); |
184 | DEBUGF(" codec_extra_data_length = %ld\n",rmctx->extradata_size); | 189 | DEBUGF(" codec_extra_data_length = %ld\n",rmctx->extradata_size); |
185 | DEBUGF(" codec_extradata :\n"); | 190 | DEBUGF(" codec_extradata :\n"); |
186 | print_cook_extradata(rmctx); | 191 | if(rmctx->codec_type == cook) { |
192 | DEBUGF(" cook_extradata :\n"); | ||
193 | print_cook_extradata(rmctx); | ||
194 | } | ||
187 | 195 | ||
188 | } | 196 | } |
189 | 197 | ||
@@ -391,12 +399,11 @@ bool get_rm_metadata(int fd, struct mp3entry* id3) | |||
391 | id3->artist = id3->id3v1buf[1]; | 399 | id3->artist = id3->id3v1buf[1]; |
392 | id3->comment = id3->id3v1buf[3]; | 400 | id3->comment = id3->id3v1buf[3]; |
393 | 401 | ||
394 | /*switch(rmctx->codec_type) | 402 | switch(rmctx->codec_type) |
395 | { | 403 | { |
396 | case cook: | 404 | case aac: |
397 | id3->codectype = AFMT_COOK; | 405 | id3->codectype = AFMT_RAAC; |
398 | break; | 406 | } |
399 | }*/ | ||
400 | 407 | ||
401 | id3->bitrate = rmctx->bit_rate / 1000; | 408 | id3->bitrate = rmctx->bit_rate / 1000; |
402 | id3->frequency = rmctx->sample_rate; | 409 | id3->frequency = rmctx->sample_rate; |