diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs/libalac/Makefile | 47 | ||||
-rw-r--r-- | apps/codecs/libalac/README.rockbox | 80 | ||||
-rw-r--r-- | apps/codecs/libalac/SOURCES | 2 | ||||
-rw-r--r-- | apps/codecs/libalac/alac.c | 345 | ||||
-rw-r--r-- | apps/codecs/libalac/decomp.h | 30 | ||||
-rw-r--r-- | apps/codecs/libalac/demux.c | 85 | ||||
-rw-r--r-- | apps/codecs/libalac/demux.h | 2 | ||||
-rw-r--r-- | apps/codecs/libalac/stream.h | 11 |
8 files changed, 405 insertions, 197 deletions
diff --git a/apps/codecs/libalac/Makefile b/apps/codecs/libalac/Makefile new file mode 100644 index 0000000000..b815db54b7 --- /dev/null +++ b/apps/codecs/libalac/Makefile | |||
@@ -0,0 +1,47 @@ | |||
1 | # __________ __ ___. | ||
2 | # Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
3 | # Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
4 | # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
5 | # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
6 | # \/ \/ \/ \/ \/ | ||
7 | # $Id$ | ||
8 | # | ||
9 | |||
10 | INCLUDES=-I$(APPSDIR) -I.. -I. -I$(FIRMDIR)/include -I$(FIRMDIR)/export \ | ||
11 | -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(BUILDDIR) | ||
12 | |||
13 | ifdef APPEXTRA | ||
14 | INCLUDES += -I$(APPSDIR)/$(APPEXTRA) | ||
15 | endif | ||
16 | |||
17 | ALACOPTS = -O3 | ||
18 | CFLAGS = $(GCCOPTS) $(ALACOPTS) $(INCLUDES) $(TARGET) $(EXTRA_DEFINES) -DMEM=${MEMORYSIZE} | ||
19 | |||
20 | # This sets up 'SRC' based on the files mentioned in SOURCES | ||
21 | include $(TOOLSDIR)/makesrc.inc | ||
22 | |||
23 | SOURCES = $(SRC) | ||
24 | OBJS2 := $(SRC:%.c=$(OBJDIR)/%.o) | ||
25 | OBJS = $(patsubst %.S, $(OBJDIR)/%.o, $(OBJS2)) | ||
26 | DEPFILE = $(OBJDIR)/dep-libalac | ||
27 | DIRS = | ||
28 | |||
29 | OUTPUT = $(BUILDDIR)/libalac.a | ||
30 | |||
31 | all: $(OUTPUT) | ||
32 | |||
33 | $(OUTPUT): $(OBJS) | ||
34 | @echo "AR $@" | ||
35 | @$(AR) ruv $@ $+ >/dev/null 2>&1 | ||
36 | |||
37 | $(OBJDIR)/libalac/%.o: $(APPSDIR)/codecs/libalac/%.c | ||
38 | @echo "(libalac) CC $<" | ||
39 | @$(CC) -c $(CFLAGS) -I$(APPSDIR)/codecs/libalac/ $< -o $@ | ||
40 | |||
41 | include $(TOOLSDIR)/make.inc | ||
42 | |||
43 | clean: | ||
44 | @echo "cleaning libalac" | ||
45 | @rm -f $(OBJS) $(OUTPUT) $(DEPFILE) | ||
46 | |||
47 | -include $(DEPFILE) | ||
diff --git a/apps/codecs/libalac/README.rockbox b/apps/codecs/libalac/README.rockbox new file mode 100644 index 0000000000..891e581cfc --- /dev/null +++ b/apps/codecs/libalac/README.rockbox | |||
@@ -0,0 +1,80 @@ | |||
1 | Library: Reverse-engineered ALAC decoder v0.1.0 | ||
2 | Imported: 2005-08-14 by Dave Chapman | ||
3 | |||
4 | |||
5 | This directory contains a local version of an ALAC (Apple Lossless Audio | ||
6 | Codec) for use by Rockbox for software decoding of ALAC files. It is | ||
7 | based on the reverse-engineered decoder by David Hamilton. | ||
8 | |||
9 | LICENSING INFORMATION | ||
10 | |||
11 | /* | ||
12 | * ALAC (Apple Lossless Audio Codec) decoder | ||
13 | * Copyright (c) 2005 David Hammerton | ||
14 | * All rights reserved. | ||
15 | * | ||
16 | * This is the actual decoder. | ||
17 | * | ||
18 | * http://crazney.net/programs/itunes/alac.html | ||
19 | * | ||
20 | * Permission is hereby granted, free of charge, to any person | ||
21 | * obtaining a copy of this software and associated documentation | ||
22 | * files (the "Software"), to deal in the Software without | ||
23 | * restriction, including without limitation the rights to use, | ||
24 | * copy, modify, merge, publish, distribute, sublicense, and/or | ||
25 | * sell copies of the Software, and to permit persons to whom the | ||
26 | * Software is furnished to do so, subject to the following conditions: | ||
27 | * | ||
28 | * The above copyright notice and this permission notice shall be | ||
29 | * included in all copies or substantial portions of the Software. | ||
30 | * | ||
31 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
32 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
33 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
34 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
35 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
36 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
37 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
38 | * OTHER DEALINGS IN THE SOFTWARE. | ||
39 | * | ||
40 | */ | ||
41 | |||
42 | IMPORT DETAILS | ||
43 | |||
44 | The base version first imported into Rockbox was the first release | ||
45 | (v0.1.0) of the ALAC decoder by David Hammerton. | ||
46 | |||
47 | Only the files alac.[ch], demux.[ch] and stream.h were used. | ||
48 | |||
49 | stream.c (the original FILE* based I/O implementation) was replaced with | ||
50 | functions in the ALAC codec - to interface with the Rockbox audio playback | ||
51 | system. | ||
52 | |||
53 | References to <stdint.h> were replaced with <inttypes.h> and debugging | ||
54 | calls to fprintf were removed. | ||
55 | |||
56 | The ALAC decoder itself was modified to return samples in host-endian | ||
57 | order, instead of little-endian. | ||
58 | |||
59 | The run-time detection of CPU endianness was replaced with | ||
60 | compile-time tests of the ROCKBOX_LITTLE_ENDIAN define. | ||
61 | |||
62 | All malloc calls were removed from alac.c, but some are still present | ||
63 | in the metadata parser in demux.c - to store unbounded data such as | ||
64 | the size in bytes of each compressed block in the file. | ||
65 | |||
66 | The only changes to demux.c were to remove debugging calls to fprintf. | ||
67 | |||
68 | The most-used buffers (the temporary 32-bit output buffer) were moved | ||
69 | into IRAM (on the iRiver). This was enough to make the decoder work | ||
70 | in real-time. | ||
71 | |||
72 | A point of interest - the -O3 gcc option (the setting used in the | ||
73 | original Makefile provided with the alac decoder) gives a significant | ||
74 | speedup compared to -O2. With -O2, the Coldfire runs at a constant | ||
75 | 120MHz, but with -O3, it can power-down to 40MHz for a small amount of | ||
76 | time. | ||
77 | |||
78 | The file alac.c contained some hints from the original author for | ||
79 | places where major optimisations can be made - specifically the | ||
80 | unrolling and optimisation of certain cases of general loops. | ||
diff --git a/apps/codecs/libalac/SOURCES b/apps/codecs/libalac/SOURCES new file mode 100644 index 0000000000..0c4615619f --- /dev/null +++ b/apps/codecs/libalac/SOURCES | |||
@@ -0,0 +1,2 @@ | |||
1 | alac.c | ||
2 | demux.c | ||
diff --git a/apps/codecs/libalac/alac.c b/apps/codecs/libalac/alac.c index 575bbf5abc..ae1b413eab 100644 --- a/apps/codecs/libalac/alac.c +++ b/apps/codecs/libalac/alac.c | |||
@@ -33,8 +33,9 @@ | |||
33 | #include <stdio.h> | 33 | #include <stdio.h> |
34 | #include <stdlib.h> | 34 | #include <stdlib.h> |
35 | #include <string.h> | 35 | #include <string.h> |
36 | #include <stdint.h> | 36 | #include <inttypes.h> |
37 | 37 | ||
38 | #include "../codec.h" | ||
38 | #include "decomp.h" | 39 | #include "decomp.h" |
39 | 40 | ||
40 | #define _Swap32(v) do { \ | 41 | #define _Swap32(v) do { \ |
@@ -47,53 +48,13 @@ | |||
47 | v = (((v) & 0x00FF) << 0x08) | \ | 48 | v = (((v) & 0x00FF) << 0x08) | \ |
48 | (((v) & 0xFF00) >> 0x08); } while (0) | 49 | (((v) & 0xFF00) >> 0x08); } while (0) |
49 | 50 | ||
50 | 51 | int16_t predictor_coef_table[32] IDATA_ATTR; | |
51 | extern int host_bigendian; | 52 | int16_t predictor_coef_table_a[32] IDATA_ATTR; |
52 | 53 | int16_t predictor_coef_table_b[32] IDATA_ATTR; | |
53 | struct alac_file | 54 | int32_t predicterror_buffer_a[4096]; |
54 | { | 55 | int32_t predicterror_buffer_b[4096]; |
55 | unsigned char *input_buffer; | 56 | int32_t outputsamples_buffer_a[4096] IDATA_ATTR; |
56 | int input_buffer_bitaccumulator; /* used so we can do arbitary | 57 | int32_t outputsamples_buffer_b[4096] IDATA_ATTR; |
57 | bit reads */ | ||
58 | |||
59 | int samplesize; | ||
60 | int numchannels; | ||
61 | int bytespersample; | ||
62 | |||
63 | |||
64 | /* buffers */ | ||
65 | int32_t *predicterror_buffer_a; | ||
66 | int32_t *predicterror_buffer_b; | ||
67 | |||
68 | int32_t *outputsamples_buffer_a; | ||
69 | int32_t *outputsamples_buffer_b; | ||
70 | |||
71 | |||
72 | /* stuff from setinfo */ | ||
73 | uint32_t setinfo_max_samples_per_frame; /* 0x1000 = 4096 */ /* max samples per frame? */ | ||
74 | uint8_t setinfo_7a; /* 0x00 */ | ||
75 | uint8_t setinfo_sample_size; /* 0x10 */ | ||
76 | uint8_t setinfo_rice_historymult; /* 0x28 */ | ||
77 | uint8_t setinfo_rice_initialhistory; /* 0x0a */ | ||
78 | uint8_t setinfo_rice_kmodifier; /* 0x0e */ | ||
79 | uint8_t setinfo_7f; /* 0x02 */ | ||
80 | uint16_t setinfo_80; /* 0x00ff */ | ||
81 | uint32_t setinfo_82; /* 0x000020e7 */ | ||
82 | uint32_t setinfo_86; /* 0x00069fe4 */ | ||
83 | uint32_t setinfo_8a_rate; /* 0x0000ac44 */ | ||
84 | /* end setinfo stuff */ | ||
85 | |||
86 | }; | ||
87 | |||
88 | |||
89 | static void allocate_buffers(alac_file *alac) | ||
90 | { | ||
91 | alac->predicterror_buffer_a = malloc(alac->setinfo_max_samples_per_frame * 4); | ||
92 | alac->predicterror_buffer_b = malloc(alac->setinfo_max_samples_per_frame * 4); | ||
93 | |||
94 | alac->outputsamples_buffer_a = malloc(alac->setinfo_max_samples_per_frame * 4); | ||
95 | alac->outputsamples_buffer_b = malloc(alac->setinfo_max_samples_per_frame * 4); | ||
96 | } | ||
97 | 58 | ||
98 | void alac_set_info(alac_file *alac, char *inputbuffer) | 59 | void alac_set_info(alac_file *alac, char *inputbuffer) |
99 | { | 60 | { |
@@ -107,8 +68,9 @@ void alac_set_info(alac_file *alac, char *inputbuffer) | |||
107 | ptr += 4; /* 0 ? */ | 68 | ptr += 4; /* 0 ? */ |
108 | 69 | ||
109 | alac->setinfo_max_samples_per_frame = *(uint32_t*)ptr; /* buffer size / 2 ? */ | 70 | alac->setinfo_max_samples_per_frame = *(uint32_t*)ptr; /* buffer size / 2 ? */ |
110 | if (!host_bigendian) | 71 | #ifdef ROCKBOX_LITTLE_ENDIAN |
111 | _Swap32(alac->setinfo_max_samples_per_frame); | 72 | _Swap32(alac->setinfo_max_samples_per_frame); |
73 | #endif | ||
112 | ptr += 4; | 74 | ptr += 4; |
113 | alac->setinfo_7a = *(uint8_t*)ptr; | 75 | alac->setinfo_7a = *(uint8_t*)ptr; |
114 | ptr += 1; | 76 | ptr += 1; |
@@ -123,24 +85,25 @@ void alac_set_info(alac_file *alac, char *inputbuffer) | |||
123 | alac->setinfo_7f = *(uint8_t*)ptr; | 85 | alac->setinfo_7f = *(uint8_t*)ptr; |
124 | ptr += 1; | 86 | ptr += 1; |
125 | alac->setinfo_80 = *(uint16_t*)ptr; | 87 | alac->setinfo_80 = *(uint16_t*)ptr; |
126 | if (!host_bigendian) | 88 | #ifdef ROCKBOX_LITTLE_ENDIAN |
127 | _Swap16(alac->setinfo_80); | 89 | _Swap16(alac->setinfo_80); |
90 | #endif | ||
128 | ptr += 2; | 91 | ptr += 2; |
129 | alac->setinfo_82 = *(uint32_t*)ptr; | 92 | alac->setinfo_82 = *(uint32_t*)ptr; |
130 | if (!host_bigendian) | 93 | #ifdef ROCKBOX_LITTLE_ENDIAN |
131 | _Swap32(alac->setinfo_82); | 94 | _Swap32(alac->setinfo_82); |
95 | #endif | ||
132 | ptr += 4; | 96 | ptr += 4; |
133 | alac->setinfo_86 = *(uint32_t*)ptr; | 97 | alac->setinfo_86 = *(uint32_t*)ptr; |
134 | if (!host_bigendian) | 98 | #ifdef ROCKBOX_LITTLE_ENDIAN |
135 | _Swap32(alac->setinfo_86); | 99 | _Swap32(alac->setinfo_86); |
100 | #endif | ||
136 | ptr += 4; | 101 | ptr += 4; |
137 | alac->setinfo_8a_rate = *(uint32_t*)ptr; | 102 | alac->setinfo_8a_rate = *(uint32_t*)ptr; |
138 | if (!host_bigendian) | 103 | #ifdef ROCKBOX_LITTLE_ENDIAN |
139 | _Swap32(alac->setinfo_8a_rate); | 104 | _Swap32(alac->setinfo_8a_rate); |
105 | #endif | ||
140 | ptr += 4; | 106 | ptr += 4; |
141 | |||
142 | allocate_buffers(alac); | ||
143 | |||
144 | } | 107 | } |
145 | 108 | ||
146 | /* stream reading */ | 109 | /* stream reading */ |
@@ -432,23 +395,150 @@ static void predictor_decompress_fir_adapt(int32_t *error_buffer, | |||
432 | } | 395 | } |
433 | } | 396 | } |
434 | 397 | ||
435 | #if 0 | 398 | /* 4 and 8 are very common cases (the only ones i've seen). |
436 | /* 4 and 8 are very common cases (the only ones i've seen). these | 399 | |
437 | * should be unrolled and optimised | 400 | The following code is an initial attempt to unroll and optimise |
401 | these two cases by the Rockbox project. More work is needed. | ||
438 | */ | 402 | */ |
403 | |||
404 | /* optimised case: 4 */ | ||
439 | if (predictor_coef_num == 4) | 405 | if (predictor_coef_num == 4) |
440 | { | 406 | { |
441 | /* FIXME: optimised general case */ | 407 | for (i = 4 + 1; i < output_size; i++) |
408 | { | ||
409 | int sum = 0; | ||
410 | int outval; | ||
411 | int error_val = error_buffer[i]; | ||
412 | |||
413 | sum = (buffer_out[4] - buffer_out[0]) * predictor_coef_table[0] | ||
414 | + (buffer_out[3] - buffer_out[0]) * predictor_coef_table[1] | ||
415 | + (buffer_out[2] - buffer_out[0]) * predictor_coef_table[2] | ||
416 | + (buffer_out[1] - buffer_out[0]) * predictor_coef_table[3]; | ||
417 | |||
418 | outval = (1 << (predictor_quantitization-1)) + sum; | ||
419 | outval = outval >> predictor_quantitization; | ||
420 | outval = outval + buffer_out[0] + error_val; | ||
421 | outval = SIGN_EXTENDED32(outval, readsamplesize); | ||
422 | |||
423 | buffer_out[4+1] = outval; | ||
424 | |||
425 | if (error_val > 0) | ||
426 | { | ||
427 | int predictor_num = 4 - 1; | ||
428 | |||
429 | while (predictor_num >= 0 && error_val > 0) | ||
430 | { | ||
431 | int val = buffer_out[0] - buffer_out[4 - predictor_num]; | ||
432 | |||
433 | if (val!=0) { | ||
434 | if (val < 0) { | ||
435 | predictor_coef_table[predictor_num]++; | ||
436 | val=-val; | ||
437 | } else { | ||
438 | predictor_coef_table[predictor_num]--;; | ||
439 | } | ||
440 | error_val -= ((val >> predictor_quantitization) * (4 - predictor_num)); | ||
441 | } | ||
442 | predictor_num--; | ||
443 | } | ||
444 | } | ||
445 | else if (error_val < 0) | ||
446 | { | ||
447 | int predictor_num = 4 - 1; | ||
448 | |||
449 | while (predictor_num >= 0 && error_val < 0) | ||
450 | { | ||
451 | int val = buffer_out[0] - buffer_out[4 - predictor_num]; | ||
452 | |||
453 | if (val != 0) { | ||
454 | if (val > 0) { | ||
455 | predictor_coef_table[predictor_num]++; | ||
456 | val=-val; /* neg value */ | ||
457 | } else { | ||
458 | predictor_coef_table[predictor_num]--; | ||
459 | } | ||
460 | error_val -= ((val >> predictor_quantitization) * (4 - predictor_num)); | ||
461 | } | ||
462 | predictor_num--; | ||
463 | } | ||
464 | } | ||
465 | |||
466 | buffer_out++; | ||
467 | } | ||
442 | return; | 468 | return; |
443 | } | 469 | } |
444 | 470 | ||
445 | if (predictor_coef_table == 8) | 471 | /* optimised case: 8 */ |
472 | if (predictor_coef_num == 8) | ||
446 | { | 473 | { |
447 | /* FIXME: optimised general case */ | 474 | for (i = 8 + 1; |
448 | return; | 475 | i < output_size; |
449 | } | 476 | i++) |
450 | #endif | 477 | { |
478 | int sum; | ||
479 | int outval; | ||
480 | int error_val = error_buffer[i]; | ||
481 | |||
482 | sum = (buffer_out[8] - buffer_out[0]) * predictor_coef_table[0] | ||
483 | + (buffer_out[7] - buffer_out[0]) * predictor_coef_table[1] | ||
484 | + (buffer_out[6] - buffer_out[0]) * predictor_coef_table[2] | ||
485 | + (buffer_out[5] - buffer_out[0]) * predictor_coef_table[3] | ||
486 | + (buffer_out[4] - buffer_out[0]) * predictor_coef_table[4] | ||
487 | + (buffer_out[3] - buffer_out[0]) * predictor_coef_table[5] | ||
488 | + (buffer_out[2] - buffer_out[0]) * predictor_coef_table[6] | ||
489 | + (buffer_out[1] - buffer_out[0]) * predictor_coef_table[7]; | ||
490 | |||
491 | outval = (1 << (predictor_quantitization-1)) + sum; | ||
492 | outval = outval >> predictor_quantitization; | ||
493 | outval = outval + buffer_out[0] + error_val; | ||
494 | outval = SIGN_EXTENDED32(outval, readsamplesize); | ||
495 | |||
496 | buffer_out[8+1] = outval; | ||
497 | |||
498 | if (error_val > 0) | ||
499 | { | ||
500 | int predictor_num = 8 - 1; | ||
501 | |||
502 | while (predictor_num >= 0 && error_val > 0) | ||
503 | { | ||
504 | int val = buffer_out[0] - buffer_out[8 - predictor_num]; | ||
505 | |||
506 | if (val!=0) { | ||
507 | if (val < 0) { | ||
508 | predictor_coef_table[predictor_num]++; | ||
509 | val=-val; | ||
510 | } else { | ||
511 | predictor_coef_table[predictor_num]--;; | ||
512 | } | ||
513 | error_val -= ((val >> predictor_quantitization) * (8 - predictor_num)); | ||
514 | } | ||
515 | predictor_num--; | ||
516 | } | ||
517 | } | ||
518 | else if (error_val < 0) | ||
519 | { | ||
520 | int predictor_num = 8 - 1; | ||
451 | 521 | ||
522 | while (predictor_num >= 0 && error_val < 0) | ||
523 | { | ||
524 | int val = buffer_out[0] - buffer_out[8 - predictor_num]; | ||
525 | if (val != 0) { | ||
526 | if (val > 0) { | ||
527 | predictor_coef_table[predictor_num]++; | ||
528 | val=-val; /* neg value */ | ||
529 | } else { | ||
530 | predictor_coef_table[predictor_num]--; | ||
531 | } | ||
532 | error_val -= ((val >> predictor_quantitization) * (8 - predictor_num)); | ||
533 | } | ||
534 | predictor_num--; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | buffer_out++; | ||
539 | } | ||
540 | return; | ||
541 | } | ||
452 | 542 | ||
453 | /* general case */ | 543 | /* general case */ |
454 | if (predictor_coef_num > 0) | 544 | if (predictor_coef_num > 0) |
@@ -534,26 +624,12 @@ void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b, | |||
534 | for (i = 0; i < numsamples; i++) | 624 | for (i = 0; i < numsamples; i++) |
535 | { | 625 | { |
536 | int32_t difference, midright; | 626 | int32_t difference, midright; |
537 | int16_t left; | ||
538 | int16_t right; | ||
539 | 627 | ||
540 | midright = buffer_a[i]; | 628 | midright = buffer_a[i]; |
541 | difference = buffer_b[i]; | 629 | difference = buffer_b[i]; |
542 | 630 | ||
543 | 631 | buffer_out[i*numchannels] = (midright - ((difference * interlacing_leftweight) >> interlacing_shift)) + difference; | |
544 | right = midright - ((difference * interlacing_leftweight) >> interlacing_shift); | 632 | buffer_out[i*numchannels + 1] = midright - ((difference * interlacing_leftweight) >> interlacing_shift); |
545 | left = (midright - ((difference * interlacing_leftweight) >> interlacing_shift)) | ||
546 | + difference; | ||
547 | |||
548 | /* output is always little endian */ | ||
549 | if (host_bigendian) | ||
550 | { | ||
551 | _Swap16(left); | ||
552 | _Swap16(right); | ||
553 | } | ||
554 | |||
555 | buffer_out[i*numchannels] = left; | ||
556 | buffer_out[i*numchannels + 1] = right; | ||
557 | } | 633 | } |
558 | 634 | ||
559 | return; | 635 | return; |
@@ -562,34 +638,27 @@ void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b, | |||
562 | /* otherwise basic interlacing took place */ | 638 | /* otherwise basic interlacing took place */ |
563 | for (i = 0; i < numsamples; i++) | 639 | for (i = 0; i < numsamples; i++) |
564 | { | 640 | { |
565 | int16_t left, right; | 641 | buffer_out[i*numchannels] = buffer_a[i]; |
566 | 642 | buffer_out[i*numchannels + 1] = buffer_b[i]; | |
567 | left = buffer_a[i]; | ||
568 | right = buffer_b[i]; | ||
569 | |||
570 | /* output is always little endian */ | ||
571 | if (host_bigendian) | ||
572 | { | ||
573 | _Swap16(left); | ||
574 | _Swap16(right); | ||
575 | } | ||
576 | |||
577 | buffer_out[i*numchannels] = left; | ||
578 | buffer_out[i*numchannels + 1] = right; | ||
579 | } | 643 | } |
580 | } | 644 | } |
581 | 645 | ||
582 | void decode_frame(alac_file *alac, | 646 | int16_t* decode_frame(alac_file *alac, |
583 | unsigned char *inbuffer, | 647 | unsigned char *inbuffer, |
584 | void *outbuffer, int *outputsize) | 648 | int *outputsize) |
585 | { | 649 | { |
586 | int channels; | 650 | int channels; |
651 | int16_t* outbuffer; | ||
587 | int32_t outputsamples = alac->setinfo_max_samples_per_frame; | 652 | int32_t outputsamples = alac->setinfo_max_samples_per_frame; |
588 | 653 | ||
589 | /* setup the stream */ | 654 | /* setup the stream */ |
590 | alac->input_buffer = inbuffer; | 655 | alac->input_buffer = inbuffer; |
591 | alac->input_buffer_bitaccumulator = 0; | 656 | alac->input_buffer_bitaccumulator = 0; |
592 | 657 | ||
658 | /* We can share the same buffer for outputbuffer | ||
659 | and outputsamples_buffer_b - and hence have them both in IRAM*/ | ||
660 | outbuffer=(int16_t*)outputsamples_buffer_b; | ||
661 | |||
593 | channels = readbits(alac, 3); | 662 | channels = readbits(alac, 3); |
594 | 663 | ||
595 | *outputsize = outputsamples * alac->bytespersample; | 664 | *outputsize = outputsamples * alac->bytespersample; |
@@ -631,7 +700,6 @@ void decode_frame(alac_file *alac, | |||
631 | 700 | ||
632 | if (!isnotcompressed) | 701 | if (!isnotcompressed) |
633 | { /* so it is compressed */ | 702 | { /* so it is compressed */ |
634 | int16_t predictor_coef_table[32]; | ||
635 | int predictor_coef_num; | 703 | int predictor_coef_num; |
636 | int prediction_type; | 704 | int prediction_type; |
637 | int prediction_quantitization; | 705 | int prediction_quantitization; |
@@ -659,11 +727,11 @@ void decode_frame(alac_file *alac, | |||
659 | /* these bytes seem to have something to do with | 727 | /* these bytes seem to have something to do with |
660 | * > 2 channel files. | 728 | * > 2 channel files. |
661 | */ | 729 | */ |
662 | fprintf(stderr, "FIXME: unimplemented, unhandling of wasted_bytes\n"); | 730 | //fprintf(stderr, "FIXME: unimplemented, unhandling of wasted_bytes\n"); |
663 | } | 731 | } |
664 | 732 | ||
665 | basterdised_rice_decompress(alac, | 733 | basterdised_rice_decompress(alac, |
666 | alac->predicterror_buffer_a, | 734 | predicterror_buffer_a, |
667 | outputsamples, | 735 | outputsamples, |
668 | readsamplesize, | 736 | readsamplesize, |
669 | alac->setinfo_rice_initialhistory, | 737 | alac->setinfo_rice_initialhistory, |
@@ -673,8 +741,8 @@ void decode_frame(alac_file *alac, | |||
673 | 741 | ||
674 | if (prediction_type == 0) | 742 | if (prediction_type == 0) |
675 | { /* adaptive fir */ | 743 | { /* adaptive fir */ |
676 | predictor_decompress_fir_adapt(alac->predicterror_buffer_a, | 744 | predictor_decompress_fir_adapt(predicterror_buffer_a, |
677 | alac->outputsamples_buffer_a, | 745 | outputsamples_buffer_a, |
678 | outputsamples, | 746 | outputsamples, |
679 | readsamplesize, | 747 | readsamplesize, |
680 | predictor_coef_table, | 748 | predictor_coef_table, |
@@ -683,7 +751,7 @@ void decode_frame(alac_file *alac, | |||
683 | } | 751 | } |
684 | else | 752 | else |
685 | { | 753 | { |
686 | fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type); | 754 | //fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type); |
687 | /* i think the only other prediction type (or perhaps this is just a | 755 | /* i think the only other prediction type (or perhaps this is just a |
688 | * boolean?) runs adaptive fir twice.. like: | 756 | * boolean?) runs adaptive fir twice.. like: |
689 | * predictor_decompress_fir_adapt(predictor_error, tempout, ...) | 757 | * predictor_decompress_fir_adapt(predictor_error, tempout, ...) |
@@ -704,7 +772,7 @@ void decode_frame(alac_file *alac, | |||
704 | 772 | ||
705 | audiobits = SIGN_EXTENDED32(audiobits, readsamplesize); | 773 | audiobits = SIGN_EXTENDED32(audiobits, readsamplesize); |
706 | 774 | ||
707 | alac->outputsamples_buffer_a[i] = audiobits; | 775 | outputsamples_buffer_a[i] = audiobits; |
708 | } | 776 | } |
709 | } | 777 | } |
710 | else | 778 | else |
@@ -722,7 +790,7 @@ void decode_frame(alac_file *alac, | |||
722 | 790 | ||
723 | audiobits |= readbits(alac, readsamplesize - 16); | 791 | audiobits |= readbits(alac, readsamplesize - 16); |
724 | 792 | ||
725 | alac->outputsamples_buffer_a[i] = audiobits; | 793 | outputsamples_buffer_a[i] = audiobits; |
726 | } | 794 | } |
727 | } | 795 | } |
728 | /* wasted_bytes = 0; // unused */ | 796 | /* wasted_bytes = 0; // unused */ |
@@ -735,17 +803,16 @@ void decode_frame(alac_file *alac, | |||
735 | int i; | 803 | int i; |
736 | for (i = 0; i < outputsamples; i++) | 804 | for (i = 0; i < outputsamples; i++) |
737 | { | 805 | { |
738 | int16_t sample = alac->outputsamples_buffer_a[i]; | 806 | /* Output mono data as stereo */ |
739 | if (host_bigendian) | 807 | outbuffer[i*2] = outputsamples_buffer_a[i]; |
740 | _Swap16(sample); | 808 | outbuffer[i*2+1] = outputsamples_buffer_a[i]; |
741 | ((int16_t*)outbuffer)[i * alac->numchannels] = sample; | ||
742 | } | 809 | } |
743 | break; | 810 | break; |
744 | } | 811 | } |
745 | case 20: | 812 | case 20: |
746 | case 24: | 813 | case 24: |
747 | case 32: | 814 | case 32: |
748 | fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size); | 815 | //fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size); |
749 | break; | 816 | break; |
750 | default: | 817 | default: |
751 | break; | 818 | break; |
@@ -788,13 +855,11 @@ void decode_frame(alac_file *alac, | |||
788 | 855 | ||
789 | if (!isnotcompressed) | 856 | if (!isnotcompressed) |
790 | { /* compressed */ | 857 | { /* compressed */ |
791 | int16_t predictor_coef_table_a[32]; | ||
792 | int predictor_coef_num_a; | 858 | int predictor_coef_num_a; |
793 | int prediction_type_a; | 859 | int prediction_type_a; |
794 | int prediction_quantitization_a; | 860 | int prediction_quantitization_a; |
795 | int ricemodifier_a; | 861 | int ricemodifier_a; |
796 | 862 | ||
797 | int16_t predictor_coef_table_b[32]; | ||
798 | int predictor_coef_num_b; | 863 | int predictor_coef_num_b; |
799 | int prediction_type_b; | 864 | int prediction_type_b; |
800 | int prediction_quantitization_b; | 865 | int prediction_quantitization_b; |
@@ -834,12 +899,12 @@ void decode_frame(alac_file *alac, | |||
834 | /*********************/ | 899 | /*********************/ |
835 | if (wasted_bytes) | 900 | if (wasted_bytes) |
836 | { /* see mono case */ | 901 | { /* see mono case */ |
837 | fprintf(stderr, "FIXME: unimplemented, unhandling of wasted_bytes\n"); | 902 | //fprintf(stderr, "FIXME: unimplemented, unhandling of wasted_bytes\n"); |
838 | } | 903 | } |
839 | 904 | ||
840 | /* channel 1 */ | 905 | /* channel 1 */ |
841 | basterdised_rice_decompress(alac, | 906 | basterdised_rice_decompress(alac, |
842 | alac->predicterror_buffer_a, | 907 | predicterror_buffer_a, |
843 | outputsamples, | 908 | outputsamples, |
844 | readsamplesize, | 909 | readsamplesize, |
845 | alac->setinfo_rice_initialhistory, | 910 | alac->setinfo_rice_initialhistory, |
@@ -849,8 +914,8 @@ void decode_frame(alac_file *alac, | |||
849 | 914 | ||
850 | if (prediction_type_a == 0) | 915 | if (prediction_type_a == 0) |
851 | { /* adaptive fir */ | 916 | { /* adaptive fir */ |
852 | predictor_decompress_fir_adapt(alac->predicterror_buffer_a, | 917 | predictor_decompress_fir_adapt(predicterror_buffer_a, |
853 | alac->outputsamples_buffer_a, | 918 | outputsamples_buffer_a, |
854 | outputsamples, | 919 | outputsamples, |
855 | readsamplesize, | 920 | readsamplesize, |
856 | predictor_coef_table_a, | 921 | predictor_coef_table_a, |
@@ -859,12 +924,12 @@ void decode_frame(alac_file *alac, | |||
859 | } | 924 | } |
860 | else | 925 | else |
861 | { /* see mono case */ | 926 | { /* see mono case */ |
862 | fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type_a); | 927 | //fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type_a); |
863 | } | 928 | } |
864 | 929 | ||
865 | /* channel 2 */ | 930 | /* channel 2 */ |
866 | basterdised_rice_decompress(alac, | 931 | basterdised_rice_decompress(alac, |
867 | alac->predicterror_buffer_b, | 932 | predicterror_buffer_b, |
868 | outputsamples, | 933 | outputsamples, |
869 | readsamplesize, | 934 | readsamplesize, |
870 | alac->setinfo_rice_initialhistory, | 935 | alac->setinfo_rice_initialhistory, |
@@ -874,8 +939,8 @@ void decode_frame(alac_file *alac, | |||
874 | 939 | ||
875 | if (prediction_type_b == 0) | 940 | if (prediction_type_b == 0) |
876 | { /* adaptive fir */ | 941 | { /* adaptive fir */ |
877 | predictor_decompress_fir_adapt(alac->predicterror_buffer_b, | 942 | predictor_decompress_fir_adapt(predicterror_buffer_b, |
878 | alac->outputsamples_buffer_b, | 943 | outputsamples_buffer_b, |
879 | outputsamples, | 944 | outputsamples, |
880 | readsamplesize, | 945 | readsamplesize, |
881 | predictor_coef_table_b, | 946 | predictor_coef_table_b, |
@@ -884,7 +949,7 @@ void decode_frame(alac_file *alac, | |||
884 | } | 949 | } |
885 | else | 950 | else |
886 | { | 951 | { |
887 | fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type_b); | 952 | //fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type_b); |
888 | } | 953 | } |
889 | } | 954 | } |
890 | else | 955 | else |
@@ -902,8 +967,8 @@ void decode_frame(alac_file *alac, | |||
902 | audiobits_a = SIGN_EXTENDED32(audiobits_a, alac->setinfo_sample_size); | 967 | audiobits_a = SIGN_EXTENDED32(audiobits_a, alac->setinfo_sample_size); |
903 | audiobits_b = SIGN_EXTENDED32(audiobits_b, alac->setinfo_sample_size); | 968 | audiobits_b = SIGN_EXTENDED32(audiobits_b, alac->setinfo_sample_size); |
904 | 969 | ||
905 | alac->outputsamples_buffer_a[i] = audiobits_a; | 970 | outputsamples_buffer_a[i] = audiobits_a; |
906 | alac->outputsamples_buffer_b[i] = audiobits_b; | 971 | outputsamples_buffer_b[i] = audiobits_b; |
907 | } | 972 | } |
908 | } | 973 | } |
909 | else | 974 | else |
@@ -923,8 +988,8 @@ void decode_frame(alac_file *alac, | |||
923 | audiobits_b = audiobits_b >> (32 - alac->setinfo_sample_size); | 988 | audiobits_b = audiobits_b >> (32 - alac->setinfo_sample_size); |
924 | audiobits_b |= readbits(alac, alac->setinfo_sample_size - 16); | 989 | audiobits_b |= readbits(alac, alac->setinfo_sample_size - 16); |
925 | 990 | ||
926 | alac->outputsamples_buffer_a[i] = audiobits_a; | 991 | outputsamples_buffer_a[i] = audiobits_a; |
927 | alac->outputsamples_buffer_b[i] = audiobits_b; | 992 | outputsamples_buffer_b[i] = audiobits_b; |
928 | } | 993 | } |
929 | } | 994 | } |
930 | /* wasted_bytes = 0; */ | 995 | /* wasted_bytes = 0; */ |
@@ -936,8 +1001,8 @@ void decode_frame(alac_file *alac, | |||
936 | { | 1001 | { |
937 | case 16: | 1002 | case 16: |
938 | { | 1003 | { |
939 | deinterlace_16(alac->outputsamples_buffer_a, | 1004 | deinterlace_16(outputsamples_buffer_a, |
940 | alac->outputsamples_buffer_b, | 1005 | outputsamples_buffer_b, |
941 | (int16_t*)outbuffer, | 1006 | (int16_t*)outbuffer, |
942 | alac->numchannels, | 1007 | alac->numchannels, |
943 | outputsamples, | 1008 | outputsamples, |
@@ -948,7 +1013,7 @@ void decode_frame(alac_file *alac, | |||
948 | case 20: | 1013 | case 20: |
949 | case 24: | 1014 | case 24: |
950 | case 32: | 1015 | case 32: |
951 | fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size); | 1016 | //fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size); |
952 | break; | 1017 | break; |
953 | default: | 1018 | default: |
954 | break; | 1019 | break; |
@@ -957,16 +1022,12 @@ void decode_frame(alac_file *alac, | |||
957 | break; | 1022 | break; |
958 | } | 1023 | } |
959 | } | 1024 | } |
1025 | return outbuffer; | ||
960 | } | 1026 | } |
961 | 1027 | ||
962 | alac_file *create_alac(int samplesize, int numchannels) | 1028 | void create_alac(int samplesize, int numchannels, alac_file* alac) |
963 | { | 1029 | { |
964 | alac_file *newfile = malloc(sizeof(alac_file)); | 1030 | alac->samplesize = samplesize; |
965 | 1031 | alac->numchannels = numchannels; | |
966 | newfile->samplesize = samplesize; | 1032 | alac->bytespersample = (samplesize / 8) * numchannels; |
967 | newfile->numchannels = numchannels; | ||
968 | newfile->bytespersample = (samplesize / 8) * numchannels; | ||
969 | |||
970 | return newfile; | ||
971 | } | 1033 | } |
972 | |||
diff --git a/apps/codecs/libalac/decomp.h b/apps/codecs/libalac/decomp.h index 23dbc52779..e6fa82d3d7 100644 --- a/apps/codecs/libalac/decomp.h +++ b/apps/codecs/libalac/decomp.h | |||
@@ -1,12 +1,34 @@ | |||
1 | #ifndef __ALAC__DECOMP_H | 1 | #ifndef __ALAC__DECOMP_H |
2 | #define __ALAC__DECOMP_H | 2 | #define __ALAC__DECOMP_H |
3 | 3 | ||
4 | typedef struct alac_file alac_file; | 4 | typedef struct |
5 | { | ||
6 | unsigned char *input_buffer; | ||
7 | int input_buffer_bitaccumulator; /* used so we can do arbitary | ||
8 | bit reads */ | ||
9 | int samplesize; | ||
10 | int numchannels; | ||
11 | int bytespersample; | ||
5 | 12 | ||
6 | alac_file *create_alac(int samplesize, int numchannels); | 13 | /* stuff from setinfo */ |
7 | void decode_frame(alac_file *alac, | 14 | uint32_t setinfo_max_samples_per_frame; /* 0x1000 = 4096 */ /* max samples per frame? */ |
15 | uint8_t setinfo_7a; /* 0x00 */ | ||
16 | uint8_t setinfo_sample_size; /* 0x10 */ | ||
17 | uint8_t setinfo_rice_historymult; /* 0x28 */ | ||
18 | uint8_t setinfo_rice_initialhistory; /* 0x0a */ | ||
19 | uint8_t setinfo_rice_kmodifier; /* 0x0e */ | ||
20 | uint8_t setinfo_7f; /* 0x02 */ | ||
21 | uint16_t setinfo_80; /* 0x00ff */ | ||
22 | uint32_t setinfo_82; /* 0x000020e7 */ | ||
23 | uint32_t setinfo_86; /* 0x00069fe4 */ | ||
24 | uint32_t setinfo_8a_rate; /* 0x0000ac44 */ | ||
25 | /* end setinfo stuff */ | ||
26 | } alac_file; | ||
27 | |||
28 | void create_alac(int samplesize, int numchannels, alac_file* alac); | ||
29 | int16_t* decode_frame(alac_file *alac, | ||
8 | unsigned char *inbuffer, | 30 | unsigned char *inbuffer, |
9 | void *outbuffer, int *outputsize); | 31 | int *outputsize); |
10 | void alac_set_info(alac_file *alac, char *inputbuffer); | 32 | void alac_set_info(alac_file *alac, char *inputbuffer); |
11 | 33 | ||
12 | #endif /* __ALAC__DECOMP_H */ | 34 | #endif /* __ALAC__DECOMP_H */ |
diff --git a/apps/codecs/libalac/demux.c b/apps/codecs/libalac/demux.c index 7263a763d4..634dc01ee7 100644 --- a/apps/codecs/libalac/demux.c +++ b/apps/codecs/libalac/demux.c | |||
@@ -32,9 +32,11 @@ | |||
32 | 32 | ||
33 | #include <string.h> | 33 | #include <string.h> |
34 | #include <stdio.h> | 34 | #include <stdio.h> |
35 | #include <stdint.h> | 35 | #include <inttypes.h> |
36 | #include <stdlib.h> | 36 | #include <stdlib.h> |
37 | 37 | ||
38 | #include "../codec.h" | ||
39 | |||
38 | #include "stream.h" | 40 | #include "stream.h" |
39 | #include "demux.h" | 41 | #include "demux.h" |
40 | 42 | ||
@@ -56,7 +58,7 @@ static void read_chunk_ftyp(qtmovie_t *qtmovie, size_t chunk_len) | |||
56 | size_remaining-=4; | 58 | size_remaining-=4; |
57 | if (type != MAKEFOURCC('M','4','A',' ')) | 59 | if (type != MAKEFOURCC('M','4','A',' ')) |
58 | { | 60 | { |
59 | fprintf(stderr, "not M4A file\n"); | 61 | //fprintf(stderr, "not M4A file\n"); |
60 | return; | 62 | return; |
61 | } | 63 | } |
62 | minor_ver = stream_read_uint32(qtmovie->stream); | 64 | minor_ver = stream_read_uint32(qtmovie->stream); |
@@ -151,7 +153,7 @@ static void read_chunk_stsd(qtmovie_t *qtmovie, size_t chunk_len) | |||
151 | 153 | ||
152 | if (numentries != 1) | 154 | if (numentries != 1) |
153 | { | 155 | { |
154 | fprintf(stderr, "only expecting one entry in sample description atom!\n"); | 156 | //fprintf(stderr, "only expecting one entry in sample description atom!\n"); |
155 | return; | 157 | return; |
156 | } | 158 | } |
157 | 159 | ||
@@ -173,8 +175,8 @@ static void read_chunk_stsd(qtmovie_t *qtmovie, size_t chunk_len) | |||
173 | entry_remaining -= 6; | 175 | entry_remaining -= 6; |
174 | 176 | ||
175 | version = stream_read_uint16(qtmovie->stream); | 177 | version = stream_read_uint16(qtmovie->stream); |
176 | if (version != 1) | 178 | // if (version != 1) |
177 | fprintf(stderr, "unknown version??\n"); | 179 | //fprintf(stderr, "unknown version??\n"); |
178 | entry_remaining -= 2; | 180 | entry_remaining -= 2; |
179 | 181 | ||
180 | /* revision level */ | 182 | /* revision level */ |
@@ -245,8 +247,8 @@ static void read_chunk_stsd(qtmovie_t *qtmovie, size_t chunk_len) | |||
245 | 247 | ||
246 | if (qtmovie->res->format != MAKEFOURCC('a','l','a','c')) | 248 | if (qtmovie->res->format != MAKEFOURCC('a','l','a','c')) |
247 | { | 249 | { |
248 | fprintf(stderr, "expecting 'alac' data format, got %c%c%c%c\n", | 250 | // fprintf(stderr, "expecting 'alac' data format, got %c%c%c%c\n", |
249 | SPLITFOURCC(qtmovie->res->format)); | 251 | // SPLITFOURCC(qtmovie->res->format)); |
250 | return; | 252 | return; |
251 | } | 253 | } |
252 | } | 254 | } |
@@ -282,7 +284,7 @@ static void read_chunk_stts(qtmovie_t *qtmovie, size_t chunk_len) | |||
282 | 284 | ||
283 | if (size_remaining) | 285 | if (size_remaining) |
284 | { | 286 | { |
285 | fprintf(stderr, "ehm, size remianing?\n"); | 287 | //fprintf(stderr, "ehm, size remianing?\n"); |
286 | stream_skip(qtmovie->stream, size_remaining); | 288 | stream_skip(qtmovie->stream, size_remaining); |
287 | } | 289 | } |
288 | } | 290 | } |
@@ -305,7 +307,7 @@ static void read_chunk_stsz(qtmovie_t *qtmovie, size_t chunk_len) | |||
305 | /* default sample size */ | 307 | /* default sample size */ |
306 | if (stream_read_uint32(qtmovie->stream) != 0) | 308 | if (stream_read_uint32(qtmovie->stream) != 0) |
307 | { | 309 | { |
308 | fprintf(stderr, "i was expecting variable samples sizes\n"); | 310 | //fprintf(stderr, "i was expecting variable samples sizes\n"); |
309 | stream_read_uint32(qtmovie->stream); | 311 | stream_read_uint32(qtmovie->stream); |
310 | size_remaining -= 4; | 312 | size_remaining -= 4; |
311 | return; | 313 | return; |
@@ -326,7 +328,7 @@ static void read_chunk_stsz(qtmovie_t *qtmovie, size_t chunk_len) | |||
326 | 328 | ||
327 | if (size_remaining) | 329 | if (size_remaining) |
328 | { | 330 | { |
329 | fprintf(stderr, "ehm, size remianing?\n"); | 331 | //fprintf(stderr, "ehm, size remianing?\n"); |
330 | stream_skip(qtmovie->stream, size_remaining); | 332 | stream_skip(qtmovie->stream, size_remaining); |
331 | } | 333 | } |
332 | } | 334 | } |
@@ -343,7 +345,7 @@ static void read_chunk_stbl(qtmovie_t *qtmovie, size_t chunk_len) | |||
343 | sub_chunk_len = stream_read_uint32(qtmovie->stream); | 345 | sub_chunk_len = stream_read_uint32(qtmovie->stream); |
344 | if (sub_chunk_len <= 1 || sub_chunk_len > size_remaining) | 346 | if (sub_chunk_len <= 1 || sub_chunk_len > size_remaining) |
345 | { | 347 | { |
346 | fprintf(stderr, "strange size for chunk inside stbl\n"); | 348 | //fprintf(stderr, "strange size for chunk inside stbl\n"); |
347 | return; | 349 | return; |
348 | } | 350 | } |
349 | 351 | ||
@@ -366,8 +368,8 @@ static void read_chunk_stbl(qtmovie_t *qtmovie, size_t chunk_len) | |||
366 | stream_skip(qtmovie->stream, sub_chunk_len - 8); | 368 | stream_skip(qtmovie->stream, sub_chunk_len - 8); |
367 | break; | 369 | break; |
368 | default: | 370 | default: |
369 | fprintf(stderr, "(stbl) unknown chunk id: %c%c%c%c\n", | 371 | // fprintf(stderr, "(stbl) unknown chunk id: %c%c%c%c\n", |
370 | SPLITFOURCC(sub_chunk_id)); | 372 | // SPLITFOURCC(sub_chunk_id)); |
371 | return; | 373 | return; |
372 | } | 374 | } |
373 | 375 | ||
@@ -383,12 +385,12 @@ static void read_chunk_minf(qtmovie_t *qtmovie, size_t chunk_len) | |||
383 | /**** SOUND HEADER CHUNK ****/ | 385 | /**** SOUND HEADER CHUNK ****/ |
384 | if (stream_read_uint32(qtmovie->stream) != 16) | 386 | if (stream_read_uint32(qtmovie->stream) != 16) |
385 | { | 387 | { |
386 | fprintf(stderr, "unexpected size in media info\n"); | 388 | //fprintf(stderr, "unexpected size in media info\n"); |
387 | return; | 389 | return; |
388 | } | 390 | } |
389 | if (stream_read_uint32(qtmovie->stream) != MAKEFOURCC('s','m','h','d')) | 391 | if (stream_read_uint32(qtmovie->stream) != MAKEFOURCC('s','m','h','d')) |
390 | { | 392 | { |
391 | fprintf(stderr, "not a sound header! can't handle this.\n"); | 393 | //fprintf(stderr, "not a sound header! can't handle this.\n"); |
392 | return; | 394 | return; |
393 | } | 395 | } |
394 | /* now skip the rest */ | 396 | /* now skip the rest */ |
@@ -400,7 +402,7 @@ static void read_chunk_minf(qtmovie_t *qtmovie, size_t chunk_len) | |||
400 | dinf_size = stream_read_uint32(qtmovie->stream); | 402 | dinf_size = stream_read_uint32(qtmovie->stream); |
401 | if (stream_read_uint32(qtmovie->stream) != MAKEFOURCC('d','i','n','f')) | 403 | if (stream_read_uint32(qtmovie->stream) != MAKEFOURCC('d','i','n','f')) |
402 | { | 404 | { |
403 | fprintf(stderr, "expected dinf, didn't get it.\n"); | 405 | //fprintf(stderr, "expected dinf, didn't get it.\n"); |
404 | return; | 406 | return; |
405 | } | 407 | } |
406 | /* skip it */ | 408 | /* skip it */ |
@@ -413,7 +415,7 @@ static void read_chunk_minf(qtmovie_t *qtmovie, size_t chunk_len) | |||
413 | stbl_size = stream_read_uint32(qtmovie->stream); | 415 | stbl_size = stream_read_uint32(qtmovie->stream); |
414 | if (stream_read_uint32(qtmovie->stream) != MAKEFOURCC('s','t','b','l')) | 416 | if (stream_read_uint32(qtmovie->stream) != MAKEFOURCC('s','t','b','l')) |
415 | { | 417 | { |
416 | fprintf(stderr, "expected stbl, didn't get it.\n"); | 418 | //fprintf(stderr, "expected stbl, didn't get it.\n"); |
417 | return; | 419 | return; |
418 | } | 420 | } |
419 | read_chunk_stbl(qtmovie, stbl_size); | 421 | read_chunk_stbl(qtmovie, stbl_size); |
@@ -421,7 +423,7 @@ static void read_chunk_minf(qtmovie_t *qtmovie, size_t chunk_len) | |||
421 | 423 | ||
422 | if (size_remaining) | 424 | if (size_remaining) |
423 | { | 425 | { |
424 | fprintf(stderr, "oops\n"); | 426 | //fprintf(stderr, "oops\n"); |
425 | stream_skip(qtmovie->stream, size_remaining); | 427 | stream_skip(qtmovie->stream, size_remaining); |
426 | } | 428 | } |
427 | } | 429 | } |
@@ -438,7 +440,7 @@ static void read_chunk_mdia(qtmovie_t *qtmovie, size_t chunk_len) | |||
438 | sub_chunk_len = stream_read_uint32(qtmovie->stream); | 440 | sub_chunk_len = stream_read_uint32(qtmovie->stream); |
439 | if (sub_chunk_len <= 1 || sub_chunk_len > size_remaining) | 441 | if (sub_chunk_len <= 1 || sub_chunk_len > size_remaining) |
440 | { | 442 | { |
441 | fprintf(stderr, "strange size for chunk inside mdia\n"); | 443 | //fprintf(stderr, "strange size for chunk inside mdia\n"); |
442 | return; | 444 | return; |
443 | } | 445 | } |
444 | 446 | ||
@@ -456,8 +458,8 @@ static void read_chunk_mdia(qtmovie_t *qtmovie, size_t chunk_len) | |||
456 | read_chunk_minf(qtmovie, sub_chunk_len); | 458 | read_chunk_minf(qtmovie, sub_chunk_len); |
457 | break; | 459 | break; |
458 | default: | 460 | default: |
459 | fprintf(stderr, "(mdia) unknown chunk id: %c%c%c%c\n", | 461 | // fprintf(stderr, "(mdia) unknown chunk id: %c%c%c%c\n", |
460 | SPLITFOURCC(sub_chunk_id)); | 462 | // SPLITFOURCC(sub_chunk_id)); |
461 | return; | 463 | return; |
462 | } | 464 | } |
463 | 465 | ||
@@ -478,7 +480,7 @@ static void read_chunk_trak(qtmovie_t *qtmovie, size_t chunk_len) | |||
478 | sub_chunk_len = stream_read_uint32(qtmovie->stream); | 480 | sub_chunk_len = stream_read_uint32(qtmovie->stream); |
479 | if (sub_chunk_len <= 1 || sub_chunk_len > size_remaining) | 481 | if (sub_chunk_len <= 1 || sub_chunk_len > size_remaining) |
480 | { | 482 | { |
481 | fprintf(stderr, "strange size for chunk inside trak\n"); | 483 | //fprintf(stderr, "strange size for chunk inside trak\n"); |
482 | return; | 484 | return; |
483 | } | 485 | } |
484 | 486 | ||
@@ -493,8 +495,8 @@ static void read_chunk_trak(qtmovie_t *qtmovie, size_t chunk_len) | |||
493 | read_chunk_mdia(qtmovie, sub_chunk_len); | 495 | read_chunk_mdia(qtmovie, sub_chunk_len); |
494 | break; | 496 | break; |
495 | default: | 497 | default: |
496 | fprintf(stderr, "(trak) unknown chunk id: %c%c%c%c\n", | 498 | // fprintf(stderr, "(trak) unknown chunk id: %c%c%c%c\n", |
497 | SPLITFOURCC(sub_chunk_id)); | 499 | // SPLITFOURCC(sub_chunk_id)); |
498 | return; | 500 | return; |
499 | } | 501 | } |
500 | 502 | ||
@@ -533,7 +535,7 @@ static void read_chunk_moov(qtmovie_t *qtmovie, size_t chunk_len) | |||
533 | sub_chunk_len = stream_read_uint32(qtmovie->stream); | 535 | sub_chunk_len = stream_read_uint32(qtmovie->stream); |
534 | if (sub_chunk_len <= 1 || sub_chunk_len > size_remaining) | 536 | if (sub_chunk_len <= 1 || sub_chunk_len > size_remaining) |
535 | { | 537 | { |
536 | fprintf(stderr, "strange size for chunk inside moov\n"); | 538 | //fprintf(stderr, "strange size for chunk inside moov\n"); |
537 | return; | 539 | return; |
538 | } | 540 | } |
539 | 541 | ||
@@ -551,8 +553,8 @@ static void read_chunk_moov(qtmovie_t *qtmovie, size_t chunk_len) | |||
551 | read_chunk_udta(qtmovie, sub_chunk_len); | 553 | read_chunk_udta(qtmovie, sub_chunk_len); |
552 | break; | 554 | break; |
553 | default: | 555 | default: |
554 | fprintf(stderr, "(moov) unknown chunk id: %c%c%c%c\n", | 556 | // fprintf(stderr, "(moov) unknown chunk id: %c%c%c%c\n", |
555 | SPLITFOURCC(sub_chunk_id)); | 557 | // SPLITFOURCC(sub_chunk_id)); |
556 | return; | 558 | return; |
557 | } | 559 | } |
558 | 560 | ||
@@ -574,14 +576,11 @@ static void read_chunk_mdat(qtmovie_t *qtmovie, size_t chunk_len) | |||
574 | 576 | ||
575 | int qtmovie_read(stream_t *file, demux_res_t *demux_res) | 577 | int qtmovie_read(stream_t *file, demux_res_t *demux_res) |
576 | { | 578 | { |
577 | qtmovie_t *qtmovie; | 579 | qtmovie_t qtmovie; |
578 | |||
579 | qtmovie = (qtmovie_t*)malloc(sizeof(qtmovie_t)); | ||
580 | 580 | ||
581 | /* construct the stream */ | 581 | /* construct the stream */ |
582 | qtmovie->stream = file; | 582 | qtmovie.stream = file; |
583 | 583 | qtmovie.res = demux_res; | |
584 | qtmovie->res = demux_res; | ||
585 | 584 | ||
586 | /* read the chunks */ | 585 | /* read the chunks */ |
587 | while (1) | 586 | while (1) |
@@ -589,26 +588,26 @@ int qtmovie_read(stream_t *file, demux_res_t *demux_res) | |||
589 | size_t chunk_len; | 588 | size_t chunk_len; |
590 | fourcc_t chunk_id; | 589 | fourcc_t chunk_id; |
591 | 590 | ||
592 | chunk_len = stream_read_uint32(qtmovie->stream); | 591 | chunk_len = stream_read_uint32(qtmovie.stream); |
593 | if (stream_eof(qtmovie->stream)) | 592 | if (stream_eof(qtmovie.stream)) |
594 | { | 593 | { |
595 | return 0; | 594 | return 0; |
596 | } | 595 | } |
597 | 596 | ||
598 | if (chunk_len == 1) | 597 | if (chunk_len == 1) |
599 | { | 598 | { |
600 | fprintf(stderr, "need 64bit support\n"); | 599 | //fprintf(stderr, "need 64bit support\n"); |
601 | return 0; | 600 | return 0; |
602 | } | 601 | } |
603 | chunk_id = stream_read_uint32(qtmovie->stream); | 602 | chunk_id = stream_read_uint32(qtmovie.stream); |
604 | 603 | ||
605 | switch (chunk_id) | 604 | switch (chunk_id) |
606 | { | 605 | { |
607 | case MAKEFOURCC('f','t','y','p'): | 606 | case MAKEFOURCC('f','t','y','p'): |
608 | read_chunk_ftyp(qtmovie, chunk_len); | 607 | read_chunk_ftyp(&qtmovie, chunk_len); |
609 | break; | 608 | break; |
610 | case MAKEFOURCC('m','o','o','v'): | 609 | case MAKEFOURCC('m','o','o','v'): |
611 | read_chunk_moov(qtmovie, chunk_len); | 610 | read_chunk_moov(&qtmovie, chunk_len); |
612 | break; | 611 | break; |
613 | /* once we hit mdat we stop reading and return. | 612 | /* once we hit mdat we stop reading and return. |
614 | * this is on the assumption that there is no furhter interesting | 613 | * this is on the assumption that there is no furhter interesting |
@@ -617,16 +616,16 @@ int qtmovie_read(stream_t *file, demux_res_t *demux_res) | |||
617 | * for the decoder. And we don't want to rely on fseek/ftell, | 616 | * for the decoder. And we don't want to rely on fseek/ftell, |
618 | * as they may not always be avilable */ | 617 | * as they may not always be avilable */ |
619 | case MAKEFOURCC('m','d','a','t'): | 618 | case MAKEFOURCC('m','d','a','t'): |
620 | read_chunk_mdat(qtmovie, chunk_len); | 619 | read_chunk_mdat(&qtmovie, chunk_len); |
621 | return 1; | 620 | return 1; |
622 | 621 | ||
623 | /* these following atoms can be skipped !!!! */ | 622 | /* these following atoms can be skipped !!!! */ |
624 | case MAKEFOURCC('f','r','e','e'): | 623 | case MAKEFOURCC('f','r','e','e'): |
625 | stream_skip(qtmovie->stream, chunk_len - 8); /* FIXME not 8 */ | 624 | stream_skip(qtmovie.stream, chunk_len - 8); /* FIXME not 8 */ |
626 | break; | 625 | break; |
627 | default: | 626 | default: |
628 | fprintf(stderr, "(top) unknown chunk id: %c%c%c%c\n", | 627 | // fprintf(stderr, "(top) unknown chunk id: %c%c%c%c\n", |
629 | SPLITFOURCC(chunk_id)); | 628 | // SPLITFOURCC(chunk_id)); |
630 | return 0; | 629 | return 0; |
631 | } | 630 | } |
632 | 631 | ||
diff --git a/apps/codecs/libalac/demux.h b/apps/codecs/libalac/demux.h index 62b949fa3b..27c9e826c5 100644 --- a/apps/codecs/libalac/demux.h +++ b/apps/codecs/libalac/demux.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef DEMUX_H | 1 | #ifndef DEMUX_H |
2 | #define DEMUX_H | 2 | #define DEMUX_H |
3 | 3 | ||
4 | #include <stdint.h> | 4 | #include <inttypes.h> |
5 | #include "stream.h" | 5 | #include "stream.h" |
6 | 6 | ||
7 | typedef uint32_t fourcc_t; | 7 | typedef uint32_t fourcc_t; |
diff --git a/apps/codecs/libalac/stream.h b/apps/codecs/libalac/stream.h index 31f93d9059..95be0b56d0 100644 --- a/apps/codecs/libalac/stream.h +++ b/apps/codecs/libalac/stream.h | |||
@@ -3,9 +3,11 @@ | |||
3 | 3 | ||
4 | /* stream.h */ | 4 | /* stream.h */ |
5 | 5 | ||
6 | #include <stdint.h> | 6 | #include <inttypes.h> |
7 | 7 | ||
8 | typedef struct stream_tTAG stream_t; | 8 | typedef struct { |
9 | int eof; | ||
10 | } stream_t; | ||
9 | 11 | ||
10 | void stream_read(stream_t *stream, size_t len, void *buf); | 12 | void stream_read(stream_t *stream, size_t len, void *buf); |
11 | 13 | ||
@@ -22,9 +24,4 @@ void stream_skip(stream_t *stream, size_t skip); | |||
22 | 24 | ||
23 | int stream_eof(stream_t *stream); | 25 | int stream_eof(stream_t *stream); |
24 | 26 | ||
25 | stream_t *stream_create_file(FILE *file, | ||
26 | int bigendian); | ||
27 | void stream_destroy(stream_t *stream); | ||
28 | |||
29 | #endif /* STREAM_H */ | 27 | #endif /* STREAM_H */ |
30 | |||