Initial, work-in-progress, version of a WMA codec using Michael Giacomelli's fixed-point and malloc-less WMA decoder (based on the ffmpeg WMA decoder from early 2006, and also building on the work started by Paul Jones). The codec itself and the ASF parsing code were written by me, inspired by the ASF parser in libasf. Current performance is around 400% realtime on gigabeat, 100% realtime on PP and 20% realtime on Coldfire.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13769 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
2ca895bae7
commit
c72824786a
26 changed files with 5929 additions and 24 deletions
|
@ -110,6 +110,7 @@ metadata.c
|
|||
metadata/metadata_common.c
|
||||
metadata/aiff.c
|
||||
metadata/ape.c
|
||||
metadata/asf.c
|
||||
metadata/adx.c
|
||||
metadata/flac.c
|
||||
metadata/monkeys.c
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
#include "settings.h"
|
||||
|
||||
#ifdef CODEC
|
||||
|
||||
#if defined(DEBUG) || defined(SIMULATOR)
|
||||
#undef DEBUGF
|
||||
#define DEBUGF ci->debugf
|
||||
|
|
|
@ -17,7 +17,7 @@ ifdef APPEXTRA
|
|||
endif
|
||||
|
||||
ifdef SOFTWARECODECS
|
||||
CODECLIBS = -lmad -la52 -lffmpegFLAC -lTremor -lwavpack -lmusepack -lalac -lfaad -lm4a -lspeex -ldemac
|
||||
CODECLIBS = -lmad -la52 -lffmpegFLAC -lTremor -lwavpack -lmusepack -lalac -lfaad -lm4a -lspeex -ldemac -lwma
|
||||
endif
|
||||
|
||||
# we "borrow" the plugin LDS file
|
||||
|
@ -39,7 +39,7 @@ DIRS = .
|
|||
|
||||
CODECDEPS = $(LINKCODEC) $(BUILDDIR)/libcodec.a
|
||||
|
||||
.PHONY: libmad liba52 libffmpegFLAC libTremor libspeex libwavpack libmusepack libalac libfaad libm4a libdemac
|
||||
.PHONY: libmad liba52 libffmpegFLAC libTremor libspeex libwavpack libmusepack libalac libfaad libm4a libdemac libwma
|
||||
|
||||
OUTPUT = $(SOFTWARECODECS)
|
||||
|
||||
|
@ -65,6 +65,7 @@ $(OBJDIR)/alac.elf : $(OBJDIR)/alac.o $(BUILDDIR)/libalac.a $(BUILDDIR)/libm4a.a
|
|||
$(OBJDIR)/aac.elf : $(OBJDIR)/aac.o $(BUILDDIR)/libfaad.a $(BUILDDIR)/libm4a.a $(OBJDIR)/codec_crt0.o
|
||||
$(OBJDIR)/shorten.elf : $(OBJDIR)/shorten.o $(BUILDDIR)/libffmpegFLAC.a $(OBJDIR)/codec_crt0.o
|
||||
$(OBJDIR)/ape.elf : $(OBJDIR)/ape.o $(BUILDDIR)/libdemac.a $(OBJDIR)/codec_crt0.o
|
||||
$(OBJDIR)/wma.elf : $(OBJDIR)/wma.o $(BUILDDIR)/libwma.a $(OBJDIR)/codec_crt0.o
|
||||
$(OBJDIR)/aiff_enc.elf: $(OBJDIR)/aiff_enc.o $(OBJDIR)/codec_crt0.o
|
||||
$(OBJDIR)/mp3_enc.elf: $(OBJDIR)/mp3_enc.o $(OBJDIR)/codec_crt0.o
|
||||
$(OBJDIR)/wav_enc.elf: $(OBJDIR)/wav_enc.o $(OBJDIR)/codec_crt0.o
|
||||
|
@ -151,6 +152,12 @@ liba52:
|
|||
$(SILENT)mkdir -p $(OBJDIR)/liba52
|
||||
$(call PRINTS,MAKE in liba52)$(MAKE) -C liba52 OBJDIR=$(OBJDIR)/liba52 OUTPUT=$(BUILDDIR)/liba52.a
|
||||
|
||||
$(BUILDDIR)/libwma.a: libwma
|
||||
|
||||
libwma:
|
||||
$(SILENT)mkdir -p $(OBJDIR)/libwma
|
||||
$(call PRINTS,MAKE in libwma)$(MAKE) -C libwma OBJDIR=$(OBJDIR)/libwma OUTPUT=$(BUILDDIR)/libwma.a
|
||||
|
||||
$(BUILDDIR)/libffmpegFLAC.a: libffmpegFLAC
|
||||
|
||||
libffmpegFLAC:
|
||||
|
@ -206,7 +213,7 @@ libdemac:
|
|||
$(call PRINTS,MAKE in libdemac)$(MAKE) -C demac/libdemac OBJDIR=$(OBJDIR)/libdemac OUTPUT=$(BUILDDIR)/libdemac.a
|
||||
|
||||
clean:
|
||||
$(call PRINTS,cleaning codecs)rm -fr $(OBJDIR)/libmad $(BUILDDIR)/libmad.a $(OBJDIR)/liba52 $(BUILDDIR)/liba52.a $(OBJDIR)/libffmpegFLAC $(BUILDDIR)/libffmpegFLAC.a $(OBJDIR)/Tremor $(BUILDDIR)/libTremor.a $(OBJDIR)/libspeex $(BUILDDIR)/libSpeex.a $(OBJDIR)/libwavpack $(BUILDDIR)/libwavpack.a $(OBJDIR)/libmusepack $(BUILDDIR)/libmusepack.a $(OBJDIR)/libalac $(BUILDDIR)/libalac.a $(OBJDIR)/libfaad $(BUILDDIR)/libfaad.a $(OBJDIR)/libm4a $(BUILDDIR)/libm4a.a $(OBJDIR)/libdemac $(BUILDDIR)/libdemac.a
|
||||
$(call PRINTS,cleaning codecs)rm -fr $(OBJDIR)/libmad $(BUILDDIR)/libmad.a $(OBJDIR)/liba52 $(BUILDDIR)/liba52.a $(OBJDIR)/libffmpegFLAC $(BUILDDIR)/libffmpegFLAC.a $(OBJDIR)/Tremor $(BUILDDIR)/libTremor.a $(OBJDIR)/libspeex $(BUILDDIR)/libSpeex.a $(OBJDIR)/libwavpack $(BUILDDIR)/libwavpack.a $(OBJDIR)/libmusepack $(BUILDDIR)/libmusepack.a $(OBJDIR)/libalac $(BUILDDIR)/libalac.a $(OBJDIR)/libfaad $(BUILDDIR)/libfaad.a $(OBJDIR)/libm4a $(BUILDDIR)/libm4a.a $(OBJDIR)/libdemac $(BUILDDIR)/libdemac.a $(OBJDIR)/libwma $(BUILDDIR)/libwma.a
|
||||
$(SILENT)$(MAKE) -C libmad clean OBJDIR=$(OBJDIR)/libmad
|
||||
$(SILENT)$(MAKE) -C liba52 clean OBJDIR=$(OBJDIR)/liba52
|
||||
$(SILENT)$(MAKE) -C libffmpegFLAC clean OBJDIR=$(OBJDIR)/libffmpegFLAC
|
||||
|
@ -218,6 +225,7 @@ clean:
|
|||
$(SILENT)$(MAKE) -C libfaad clean OBJDIR=$(OBJDIR)/libfaad
|
||||
$(SILENT)$(MAKE) -C libm4a clean OBJDIR=$(OBJDIR)/libm4a
|
||||
$(SILENT)$(MAKE) -C demac/libdemac clean OBJDIR=$(OBJDIR)/libdemac
|
||||
$(SILENT)$(MAKE) -C libwma clean OBJDIR=$(OBJDIR)/libwma
|
||||
$(SILENT)$(MAKE) -C lib clean OBJDIR=$(OBJDIR)/lib
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
|
|
|
@ -8,6 +8,7 @@ a52.c
|
|||
mpc.c
|
||||
wavpack.c
|
||||
alac.c
|
||||
wma.c
|
||||
#if MEMORYSIZE > 1
|
||||
aac.c
|
||||
#endif
|
||||
|
|
43
apps/codecs/libwma/Makefile
Normal file
43
apps/codecs/libwma/Makefile
Normal file
|
@ -0,0 +1,43 @@
|
|||
# __________ __ ___.
|
||||
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
# \/ \/ \/ \/ \/
|
||||
# $Id: Makefile 11401 2006-10-30 18:14:12Z learman $
|
||||
#
|
||||
|
||||
INCLUDES=-I$(APPSDIR) -I.. -I. -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
|
||||
-I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(BUILDDIR)
|
||||
|
||||
ifdef APPEXTRA
|
||||
INCLUDES += $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA)))
|
||||
endif
|
||||
|
||||
WMAOPTS = -O2
|
||||
CFLAGS = $(INCLUDES) $(GCCOPTS) $(TARGET_INC) $(WMAOPTS) $(TARGET) \
|
||||
$(EXTRA_DEFINES) -DMEM=${MEMORYSIZE} $(PROFILE_OPTS) -DCODEC=1
|
||||
|
||||
# This sets up 'SRC' based on the files mentioned in SOURCES
|
||||
include $(TOOLSDIR)/makesrc.inc
|
||||
|
||||
SOURCES = $(SRC)
|
||||
OBJS2 := $(SRC:%.c=$(OBJDIR)/%.o)
|
||||
OBJS = $(patsubst %.S, $(OBJDIR)/%.o, $(OBJS2))
|
||||
DEPFILE = $(OBJDIR)/dep-libwma
|
||||
DIRS =
|
||||
|
||||
all: $(OUTPUT)
|
||||
|
||||
$(OUTPUT): $(OBJS)
|
||||
$(call PRINTS,AR+RANLIB $(@F))$(AR) ruv $@ $+ >/dev/null 2>&1
|
||||
$(SILENT)$(RANLIB) $@
|
||||
|
||||
include $(TOOLSDIR)/make.inc
|
||||
|
||||
clean:
|
||||
$(call PRINTS,cleaning libwma)rm -f $(OBJS) $(OUTPUT) $(DEPFILE)
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
-include $(DEPFILE)
|
||||
endif
|
2
apps/codecs/libwma/SOURCES
Normal file
2
apps/codecs/libwma/SOURCES
Normal file
|
@ -0,0 +1,2 @@
|
|||
wmadeci.c
|
||||
common.c
|
24
apps/codecs/libwma/asf.h
Normal file
24
apps/codecs/libwma/asf.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef _ASF_H
|
||||
#define _ASF_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
/* ASF codec IDs */
|
||||
#define ASF_CODEC_ID_WMAV1 0x160
|
||||
#define ASF_CODEC_ID_WMAV2 0x161
|
||||
|
||||
struct asf_waveformatex_s {
|
||||
uint32_t packet_size;
|
||||
int audiostream;
|
||||
uint16_t codec_id;
|
||||
uint16_t channels;
|
||||
uint32_t rate;
|
||||
uint32_t bitrate;
|
||||
uint16_t blockalign;
|
||||
uint16_t bitspersample;
|
||||
uint16_t datalen;
|
||||
uint8_t data[6];
|
||||
};
|
||||
typedef struct asf_waveformatex_s asf_waveformatex_t;
|
||||
|
||||
#endif
|
58
apps/codecs/libwma/avcodec.h
Normal file
58
apps/codecs/libwma/avcodec.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
#ifndef AVCODEC_H
|
||||
#define AVCODEC_H
|
||||
|
||||
/**
|
||||
* @file avcodec.h
|
||||
* external api header.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <sys/types.h> /* size_t */
|
||||
|
||||
/**
|
||||
* Required number of additionally allocated bytes at the end of the input bitstream for decoding.
|
||||
* this is mainly needed because some optimized bitstream readers read
|
||||
* 32 or 64 bit at once and could read over the end<br>
|
||||
* Note, if the first 23 bits of the additional bytes are not 0 then damaged
|
||||
* MPEG bitstreams could cause overread and segfault
|
||||
*/
|
||||
#define FF_INPUT_BUFFER_PADDING_SIZE 8
|
||||
|
||||
/* memory */
|
||||
void *av_malloc(unsigned int size);
|
||||
void *av_mallocz(unsigned int size);
|
||||
void *av_realloc(void *ptr, unsigned int size);
|
||||
void av_free(void *ptr);
|
||||
char *av_strdup(const char *s);
|
||||
void __av_freep(void **ptr);
|
||||
#define av_freep(p) __av_freep((void **)(p))
|
||||
void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size);
|
||||
/* for static data only */
|
||||
/* call av_free_static to release all staticaly allocated tables */
|
||||
void av_free_static(void);
|
||||
void *__av_mallocz_static(void** location, unsigned int size);
|
||||
#define av_mallocz_static(p, s) __av_mallocz_static((void **)(p), s)
|
||||
|
||||
/* av_log API */
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define AV_LOG_ERROR 0
|
||||
#define AV_LOG_INFO 1
|
||||
#define AV_LOG_DEBUG 2
|
||||
|
||||
extern void av_log(int level, const char *fmt, ...);
|
||||
extern void av_vlog(int level, const char *fmt, va_list);
|
||||
extern int av_log_get_level(void);
|
||||
extern void av_log_set_level(int);
|
||||
extern void av_log_set_callback(void (*)(int, const char*, va_list));
|
||||
|
||||
#undef AV_LOG_TRAP_PRINTF
|
||||
#ifdef AV_LOG_TRAP_PRINTF
|
||||
#define printf DO NOT USE
|
||||
#define fprintf DO NOT USE
|
||||
#undef stderr
|
||||
#define stderr DO NOT USE
|
||||
#endif
|
||||
|
||||
#endif /* AVCODEC_H */
|
127
apps/codecs/libwma/bswap.h
Normal file
127
apps/codecs/libwma/bswap.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
/**
|
||||
* @file bswap.h
|
||||
* byte swap.
|
||||
*/
|
||||
|
||||
#ifndef __BSWAP_H__
|
||||
#define __BSWAP_H__
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef ARCH_X86
|
||||
static inline unsigned short ByteSwap16(unsigned short x)
|
||||
{
|
||||
__asm("xchgb %b0,%h0" :
|
||||
"=q" (x) :
|
||||
"0" (x));
|
||||
return x;
|
||||
}
|
||||
#define bswap_16(x) ByteSwap16(x)
|
||||
|
||||
static inline unsigned int ByteSwap32(unsigned int x)
|
||||
{
|
||||
#if __CPU__ > 386
|
||||
__asm("bswap %0":
|
||||
"=r" (x) :
|
||||
#else
|
||||
__asm("xchgb %b0,%h0\n"
|
||||
" rorl $16,%0\n"
|
||||
" xchgb %b0,%h0":
|
||||
"=q" (x) :
|
||||
#endif
|
||||
"0" (x));
|
||||
return x;
|
||||
}
|
||||
#define bswap_32(x) ByteSwap32(x)
|
||||
|
||||
static inline unsigned long long int ByteSwap64(unsigned long long int x)
|
||||
{
|
||||
register union { __extension__ uint64_t __ll;
|
||||
uint32_t __l[2]; } __x;
|
||||
asm("xchgl %0,%1":
|
||||
"=r"(__x.__l[0]),"=r"(__x.__l[1]):
|
||||
"0"(bswap_32((unsigned long)x)),"1"(bswap_32((unsigned long)(x>>32))));
|
||||
return __x.__ll;
|
||||
}
|
||||
#define bswap_64(x) ByteSwap64(x)
|
||||
|
||||
#elif defined(ARCH_SH4)
|
||||
|
||||
static inline uint16_t ByteSwap16(uint16_t x) {
|
||||
__asm__("swap.b %0,%0":"=r"(x):"0"(x));
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline uint32_t ByteSwap32(uint32_t x) {
|
||||
__asm__(
|
||||
"swap.b %0,%0\n"
|
||||
"swap.w %0,%0\n"
|
||||
"swap.b %0,%0\n"
|
||||
:"=r"(x):"0"(x));
|
||||
return x;
|
||||
}
|
||||
|
||||
#define bswap_16(x) ByteSwap16(x)
|
||||
#define bswap_32(x) ByteSwap32(x)
|
||||
|
||||
static inline uint64_t ByteSwap64(uint64_t x)
|
||||
{
|
||||
union {
|
||||
uint64_t ll;
|
||||
struct {
|
||||
uint32_t l,h;
|
||||
} l;
|
||||
} r;
|
||||
r.l.l = bswap_32 (x);
|
||||
r.l.h = bswap_32 (x>>32);
|
||||
return r.ll;
|
||||
}
|
||||
#define bswap_64(x) ByteSwap64(x)
|
||||
|
||||
#else
|
||||
|
||||
#define bswap_16(x) (((x) & 0x00ff) << 8 | ((x) & 0xff00) >> 8)
|
||||
|
||||
|
||||
// code from bits/byteswap.h (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
#define bswap_32(x) \
|
||||
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
|
||||
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
|
||||
|
||||
static inline uint64_t ByteSwap64(uint64_t x)
|
||||
{
|
||||
union {
|
||||
uint64_t ll;
|
||||
uint32_t l[2];
|
||||
} w, r;
|
||||
w.ll = x;
|
||||
r.l[0] = bswap_32 (w.l[1]);
|
||||
r.l[1] = bswap_32 (w.l[0]);
|
||||
return r.ll;
|
||||
}
|
||||
#define bswap_64(x) ByteSwap64(x)
|
||||
|
||||
#endif /* !ARCH_X86 */
|
||||
|
||||
#endif /* !HAVE_BYTESWAP_H */
|
||||
|
||||
// be2me ... BigEndian to MachineEndian
|
||||
// le2me ... LittleEndian to MachineEndian
|
||||
|
||||
#ifdef ROCKBOX_BIG_ENDIAN
|
||||
#define be2me_16(x) (x)
|
||||
#define be2me_32(x) (x)
|
||||
#define be2me_64(x) (x)
|
||||
#define le2me_16(x) bswap_16(x)
|
||||
#define le2me_32(x) bswap_32(x)
|
||||
#define le2me_64(x) bswap_64(x)
|
||||
#else
|
||||
#define be2me_16(x) bswap_16(x)
|
||||
#define be2me_32(x) bswap_32(x)
|
||||
#define be2me_64(x) bswap_64(x)
|
||||
#define le2me_16(x) (x)
|
||||
#define le2me_32(x) (x)
|
||||
#define le2me_64(x) (x)
|
||||
#endif
|
||||
|
||||
#endif /* __BSWAP_H__ */
|
107
apps/codecs/libwma/common.c
Normal file
107
apps/codecs/libwma/common.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Common bit i/o utils
|
||||
* Copyright (c) 2000, 2001 Fabrice Bellard.
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file common.c
|
||||
* common internal api.
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
|
||||
const uint8_t ff_sqrt_tab[128]={
|
||||
0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11
|
||||
};
|
||||
|
||||
const uint8_t ff_log2_tab[256]={
|
||||
0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
|
||||
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
||||
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
|
||||
};
|
||||
|
||||
/**
|
||||
* init GetBitContext.
|
||||
* @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger then the actual read bits
|
||||
* because some optimized bitstream readers read 32 or 64 bit at once and could read over the end
|
||||
* @param bit_size the size of the buffer in bits
|
||||
*/
|
||||
void init_get_bits(GetBitContext *s,
|
||||
const uint8_t *buffer, int bit_size)
|
||||
{
|
||||
const int buffer_size= (bit_size+7)>>3;
|
||||
|
||||
s->buffer= buffer;
|
||||
s->size_in_bits= bit_size;
|
||||
s->buffer_end= buffer + buffer_size;
|
||||
s->index=0;
|
||||
{
|
||||
OPEN_READER(re, s)
|
||||
UPDATE_CACHE(re, s)
|
||||
UPDATE_CACHE(re, s)
|
||||
CLOSE_READER(re, s)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* reads 0-32 bits.
|
||||
*/
|
||||
unsigned int get_bits_long(GetBitContext *s, int n){
|
||||
if(n<=17) return get_bits(s, n);
|
||||
else{
|
||||
int ret= get_bits(s, 16) << (n-16);
|
||||
return ret | get_bits(s, n-16);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shows 0-32 bits.
|
||||
*/
|
||||
unsigned int show_bits_long(GetBitContext *s, int n){
|
||||
if(n<=17) return show_bits(s, n);
|
||||
else{
|
||||
GetBitContext gb= *s;
|
||||
int ret= get_bits_long(s, n);
|
||||
*s= gb;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
void align_get_bits(GetBitContext *s)
|
||||
{
|
||||
int n= (-get_bits_count(s)) & 7;
|
||||
if(n) skip_bits(s, n);
|
||||
}
|
||||
|
||||
int check_marker(GetBitContext *s, const char *msg)
|
||||
{
|
||||
(void)msg;
|
||||
int bit= get_bits1(s);
|
||||
return bit;
|
||||
}
|
||||
|
387
apps/codecs/libwma/common.h
Normal file
387
apps/codecs/libwma/common.h
Normal file
|
@ -0,0 +1,387 @@
|
|||
/**
|
||||
* @file common.h
|
||||
* common internal api header.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
/* only include the following when compiling package */
|
||||
#include "ffmpeg_config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
|
||||
# define always_inline __attribute__((always_inline)) inline
|
||||
#else
|
||||
# define always_inline inline
|
||||
#endif
|
||||
|
||||
#ifndef INT64_MAX
|
||||
#define INT64_MAX 9223372036854775807LL
|
||||
#endif
|
||||
|
||||
# if defined(__MINGW32__) || defined(__CYGWIN__) || \
|
||||
defined(__OS2__) || (defined (__OpenBSD__) && !defined(__ELF__))
|
||||
# define MANGLE(a) "_" #a
|
||||
# else
|
||||
# define MANGLE(a) #a
|
||||
# endif
|
||||
|
||||
/* debug stuff */
|
||||
|
||||
# ifndef DEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
# include <assert.h>
|
||||
|
||||
/* dprintf macros */
|
||||
# if defined(CONFIG_WIN32) && !defined(__MINGW32__)
|
||||
|
||||
inline void dprintf(const char* fmt,...) {}
|
||||
|
||||
# else
|
||||
|
||||
# ifdef DEBUG
|
||||
# define dprintf(fmt,...) printf(fmt, __VA_ARGS__)
|
||||
# else
|
||||
# define dprintf(fmt,...)
|
||||
# endif
|
||||
|
||||
# endif /* !CONFIG_WIN32 */
|
||||
|
||||
# define av_abort() do { av_log(AV_LOG_ERROR, "Abort at %s:%d\n", __FILE__, __LINE__); abort(); } while (0)
|
||||
|
||||
//rounded divison & shift
|
||||
#define RSHIFT(a,b) ((a) > 0 ? ((a) + (1<<((b)-1)))>>(b) : ((a) + (1<<((b)-1))-1)>>(b))
|
||||
/* assume b>0 */
|
||||
#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))
|
||||
|
||||
extern const uint32_t inverse[256];
|
||||
|
||||
#define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s)))
|
||||
#define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s)))
|
||||
|
||||
/* bit input */
|
||||
|
||||
typedef struct GetBitContext {
|
||||
const uint8_t *buffer, *buffer_end;
|
||||
int index;
|
||||
int size_in_bits;
|
||||
} GetBitContext;
|
||||
|
||||
static inline int get_bits_count(GetBitContext *s);
|
||||
|
||||
/* used to avoid missaligned exceptions on some archs (alpha, ...) */
|
||||
static inline uint32_t unaligned32(const void *v) {
|
||||
struct Unaligned {
|
||||
uint32_t i;
|
||||
} __attribute__((packed));
|
||||
|
||||
return ((const struct Unaligned *) v)->i;
|
||||
}
|
||||
|
||||
|
||||
/* Bitstream reader API docs:
|
||||
name
|
||||
abritary name which is used as prefix for the internal variables
|
||||
|
||||
gb
|
||||
getbitcontext
|
||||
|
||||
OPEN_READER(name, gb)
|
||||
loads gb into local variables
|
||||
|
||||
CLOSE_READER(name, gb)
|
||||
stores local vars in gb
|
||||
|
||||
UPDATE_CACHE(name, gb)
|
||||
refills the internal cache from the bitstream
|
||||
after this call at least MIN_CACHE_BITS will be available,
|
||||
|
||||
GET_CACHE(name, gb)
|
||||
will output the contents of the internal cache, next bit is MSB of 32 or 64 bit (FIXME 64bit)
|
||||
|
||||
SHOW_UBITS(name, gb, num)
|
||||
will return the nest num bits
|
||||
|
||||
SHOW_SBITS(name, gb, num)
|
||||
will return the nest num bits and do sign extension
|
||||
|
||||
SKIP_BITS(name, gb, num)
|
||||
will skip over the next num bits
|
||||
note, this is equinvalent to SKIP_CACHE; SKIP_COUNTER
|
||||
|
||||
SKIP_CACHE(name, gb, num)
|
||||
will remove the next num bits from the cache (note SKIP_COUNTER MUST be called before UPDATE_CACHE / CLOSE_READER)
|
||||
|
||||
SKIP_COUNTER(name, gb, num)
|
||||
will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS)
|
||||
|
||||
LAST_SKIP_CACHE(name, gb, num)
|
||||
will remove the next num bits from the cache if it is needed for UPDATE_CACHE otherwise it will do nothing
|
||||
|
||||
LAST_SKIP_BITS(name, gb, num)
|
||||
is equinvalent to SKIP_LAST_CACHE; SKIP_COUNTER
|
||||
|
||||
for examples see get_bits, show_bits, skip_bits, get_vlc
|
||||
*/
|
||||
|
||||
static inline int unaligned32_be(const void *v)
|
||||
{
|
||||
#ifdef CONFIG_ALIGN
|
||||
const uint8_t *p=v;
|
||||
return (((p[0]<<8) | p[1])<<16) | (p[2]<<8) | (p[3]);
|
||||
#else
|
||||
return be2me_32( unaligned32(v)); //original
|
||||
#endif
|
||||
}
|
||||
|
||||
#define MIN_CACHE_BITS 25
|
||||
|
||||
#define OPEN_READER(name, gb)\
|
||||
int name##_index= (gb)->index;\
|
||||
int name##_cache= 0;\
|
||||
|
||||
#define CLOSE_READER(name, gb)\
|
||||
(gb)->index= name##_index;\
|
||||
|
||||
#define UPDATE_CACHE(name, gb)\
|
||||
name##_cache= unaligned32_be( ((uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\
|
||||
|
||||
#define SKIP_CACHE(name, gb, num)\
|
||||
name##_cache <<= (num);\
|
||||
|
||||
// FIXME name?
|
||||
#define SKIP_COUNTER(name, gb, num)\
|
||||
name##_index += (num);\
|
||||
|
||||
#define SKIP_BITS(name, gb, num)\
|
||||
{\
|
||||
SKIP_CACHE(name, gb, num)\
|
||||
SKIP_COUNTER(name, gb, num)\
|
||||
}\
|
||||
|
||||
#define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
|
||||
#define LAST_SKIP_CACHE(name, gb, num) ;
|
||||
|
||||
#define SHOW_UBITS(name, gb, num)\
|
||||
NEG_USR32(name##_cache, num)
|
||||
|
||||
#define SHOW_SBITS(name, gb, num)\
|
||||
NEG_SSR32(name##_cache, num)
|
||||
|
||||
#define GET_CACHE(name, gb)\
|
||||
((uint32_t)name##_cache)
|
||||
|
||||
static inline int get_bits_count(GetBitContext *s){
|
||||
return s->index;
|
||||
}
|
||||
|
||||
/**
|
||||
* reads 0-17 bits.
|
||||
* Note, the alt bitstream reader can read upto 25 bits, but the libmpeg2 reader cant
|
||||
*/
|
||||
static inline unsigned int get_bits(GetBitContext *s, int n){
|
||||
register int tmp;
|
||||
OPEN_READER(re, s)
|
||||
UPDATE_CACHE(re, s)
|
||||
tmp= SHOW_UBITS(re, s, n);
|
||||
LAST_SKIP_BITS(re, s, n)
|
||||
CLOSE_READER(re, s)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
unsigned int get_bits_long(GetBitContext *s, int n);
|
||||
|
||||
/**
|
||||
* shows 0-17 bits.
|
||||
* Note, the alt bitstream reader can read upto 25 bits, but the libmpeg2 reader cant
|
||||
*/
|
||||
static inline unsigned int show_bits(GetBitContext *s, int n){
|
||||
register int tmp;
|
||||
OPEN_READER(re, s)
|
||||
UPDATE_CACHE(re, s)
|
||||
tmp= SHOW_UBITS(re, s, n);
|
||||
// CLOSE_READER(re, s)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
unsigned int show_bits_long(GetBitContext *s, int n);
|
||||
|
||||
static inline void skip_bits(GetBitContext *s, int n){
|
||||
//Note gcc seems to optimize this to s->index+=n for the ALT_READER :))
|
||||
OPEN_READER(re, s)
|
||||
UPDATE_CACHE(re, s)
|
||||
LAST_SKIP_BITS(re, s, n)
|
||||
CLOSE_READER(re, s)
|
||||
}
|
||||
|
||||
static inline unsigned int get_bits1(GetBitContext *s){
|
||||
int index= s->index;
|
||||
uint8_t result= s->buffer[ index>>3 ];
|
||||
result<<= (index&0x07);
|
||||
result>>= 8 - 1;
|
||||
index++;
|
||||
s->index= index;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline unsigned int show_bits1(GetBitContext *s){
|
||||
return show_bits(s, 1);
|
||||
}
|
||||
|
||||
static inline void skip_bits1(GetBitContext *s){
|
||||
skip_bits(s, 1);
|
||||
}
|
||||
|
||||
void init_get_bits(GetBitContext *s,
|
||||
const uint8_t *buffer, int buffer_size);
|
||||
|
||||
int check_marker(GetBitContext *s, const char *msg);
|
||||
void align_get_bits(GetBitContext *s);
|
||||
|
||||
//#define TRACE
|
||||
|
||||
#ifdef TRACE
|
||||
|
||||
static inline void print_bin(int bits, int n){
|
||||
int i;
|
||||
|
||||
for(i=n-1; i>=0; i--){
|
||||
printf("%d", (bits>>i)&1);
|
||||
}
|
||||
for(i=n; i<24; i++)
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static inline int get_bits_trace(GetBitContext *s, int n, char *file, char *func, int line){
|
||||
int r= get_bits(s, n);
|
||||
|
||||
print_bin(r, n);
|
||||
printf("%5d %2d %3d bit @%5d in %s %s:%d\n", r, n, r, get_bits_count(s)-n, file, func, line);
|
||||
return r;
|
||||
}
|
||||
static inline int get_vlc_trace(GetBitContext *s, VLC_TYPE (*table)[2], int bits, int max_depth, char *file, char *func, int line){
|
||||
int show= show_bits(s, 24);
|
||||
int pos= get_bits_count(s);
|
||||
int r= get_vlc2(s, table, bits, max_depth);
|
||||
int len= get_bits_count(s) - pos;
|
||||
int bits2= show>>(24-len);
|
||||
|
||||
print_bin(bits2, len);
|
||||
|
||||
printf("%5d %2d %3d vlc @%5d in %s %s:%d\n", bits2, len, r, pos, file, func, line);
|
||||
return r;
|
||||
}
|
||||
static inline int get_xbits_trace(GetBitContext *s, int n, char *file, char *func, int line){
|
||||
int show= show_bits(s, n);
|
||||
int r= get_xbits(s, n);
|
||||
|
||||
print_bin(show, n);
|
||||
printf("%5d %2d %3d xbt @%5d in %s %s:%d\n", show, n, r, get_bits_count(s)-n, file, func, line);
|
||||
return r;
|
||||
}
|
||||
|
||||
#define get_bits(s, n) get_bits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__)
|
||||
#define get_bits1(s) get_bits_trace(s, 1, __FILE__, __PRETTY_FUNCTION__, __LINE__)
|
||||
#define get_xbits(s, n) get_xbits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__)
|
||||
#define get_vlc(s, vlc) get_vlc_trace(s, (vlc)->table, (vlc)->bits, 3, __FILE__, __PRETTY_FUNCTION__, __LINE__)
|
||||
#define get_vlc2(s, tab, bits, max) get_vlc_trace(s, tab, bits, max, __FILE__, __PRETTY_FUNCTION__, __LINE__)
|
||||
|
||||
#define tprintf printf
|
||||
|
||||
#else //TRACE
|
||||
#define tprintf(_arg...) {}
|
||||
#endif
|
||||
|
||||
/* define it to include statistics code (useful only for optimizing
|
||||
codec efficiency */
|
||||
//#define STATS
|
||||
|
||||
#ifdef STATS
|
||||
|
||||
enum {
|
||||
ST_UNKNOWN,
|
||||
ST_DC,
|
||||
ST_INTRA_AC,
|
||||
ST_INTER_AC,
|
||||
ST_INTRA_MB,
|
||||
ST_INTER_MB,
|
||||
ST_MV,
|
||||
ST_NB,
|
||||
};
|
||||
|
||||
extern int st_current_index;
|
||||
extern unsigned int st_bit_counts[ST_NB];
|
||||
extern unsigned int st_out_bit_counts[ST_NB];
|
||||
|
||||
void print_stats(void);
|
||||
#endif
|
||||
|
||||
/* misc math functions */
|
||||
extern const uint8_t ff_log2_tab[256];
|
||||
|
||||
static inline int av_log2(unsigned int v)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = 0;
|
||||
if (v & 0xffff0000) {
|
||||
v >>= 16;
|
||||
n += 16;
|
||||
}
|
||||
if (v & 0xff00) {
|
||||
v >>= 8;
|
||||
n += 8;
|
||||
}
|
||||
n += ff_log2_tab[v];
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static inline int clip(int a, int amin, int amax)
|
||||
{
|
||||
if (a < amin)
|
||||
return amin;
|
||||
else if (a > amax)
|
||||
return amax;
|
||||
else
|
||||
return a;
|
||||
}
|
||||
|
||||
/* math */
|
||||
extern const uint8_t ff_sqrt_tab[128];
|
||||
|
||||
int64_t ff_gcd(int64_t a, int64_t b);
|
||||
|
||||
static inline int ff_sqrt(int a)
|
||||
{
|
||||
int ret=0;
|
||||
int s;
|
||||
int ret_sq=0;
|
||||
|
||||
if(a<128) return ff_sqrt_tab[a];
|
||||
|
||||
for(s=15; s>=0; s--){
|
||||
int b= ret_sq + (1<<(s*2)) + (ret<<s)*2;
|
||||
if(b<=a){
|
||||
ret_sq=b;
|
||||
ret+= 1<<s;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* COMMON_H */
|
106
apps/codecs/libwma/dsputil.h
Normal file
106
apps/codecs/libwma/dsputil.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* DSP utils
|
||||
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file dsputil.h
|
||||
* DSP utils.
|
||||
* note, many functions in here may use MMX which trashes the FPU state, it is
|
||||
* absolutely necessary to call emms_c() between dsp & float/double code
|
||||
*/
|
||||
|
||||
#ifndef DSPUTIL_H
|
||||
#define DSPUTIL_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
void dsputil_static_init(void);
|
||||
|
||||
/* FFT computation */
|
||||
|
||||
/* NOTE: soon integer code will be added, so you must use the
|
||||
FFTSample type */
|
||||
typedef float FFTSample;
|
||||
|
||||
typedef struct FFTComplex {
|
||||
FFTSample re, im;
|
||||
} FFTComplex;
|
||||
|
||||
typedef struct FFTContext {
|
||||
int nbits;
|
||||
int inverse;
|
||||
uint16_t *revtab;
|
||||
FFTComplex *exptab;
|
||||
FFTComplex *exptab1; /* only used by SSE code */
|
||||
void (*fft_calc)(struct FFTContext *s, FFTComplex *z);
|
||||
} FFTContext;
|
||||
|
||||
int fft_inits(FFTContext *s, int nbits, int inverse);
|
||||
void fft_permute(FFTContext *s, FFTComplex *z);
|
||||
void fft_calc_c(FFTContext *s, FFTComplex *z);
|
||||
void fft_calc_sse(FFTContext *s, FFTComplex *z);
|
||||
void fft_calc_altivec(FFTContext *s, FFTComplex *z);
|
||||
|
||||
static inline void fft_calc(FFTContext *s, FFTComplex *z)
|
||||
{
|
||||
s->fft_calc(s, z);
|
||||
}
|
||||
void fft_end(FFTContext *s);
|
||||
|
||||
/* MDCT computation */
|
||||
|
||||
typedef struct MDCTContext {
|
||||
int n; /* size of MDCT (i.e. number of input data * 2) */
|
||||
int nbits; /* n = 2^nbits */
|
||||
/* pre/post rotation tables */
|
||||
FFTSample *tcos;
|
||||
FFTSample *tsin;
|
||||
FFTContext fft;
|
||||
} MDCTContext;
|
||||
|
||||
int ff_mdct_init(MDCTContext *s, int nbits, int inverse);
|
||||
void ff_imdct_calc(MDCTContext *s, FFTSample *output,
|
||||
const FFTSample *input, FFTSample *tmp);
|
||||
void ff_mdct_calc(MDCTContext *s, FFTSample *out,
|
||||
const FFTSample *input, FFTSample *tmp);
|
||||
void ff_mdct_end(MDCTContext *s);
|
||||
|
||||
#define WARPER8_16(name8, name16)\
|
||||
static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\
|
||||
return name8(s, dst , src , stride, h)\
|
||||
+name8(s, dst+8 , src+8 , stride, h);\
|
||||
}
|
||||
|
||||
#define WARPER8_16_SQ(name8, name16)\
|
||||
static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\
|
||||
int score=0;\
|
||||
score +=name8(s, dst , src , stride, 8);\
|
||||
score +=name8(s, dst+8 , src+8 , stride, 8);\
|
||||
if(h==16){\
|
||||
dst += 8*stride;\
|
||||
src += 8*stride;\
|
||||
score +=name8(s, dst , src , stride, 8);\
|
||||
score +=name8(s, dst+8 , src+8 , stride, 8);\
|
||||
}\
|
||||
return score;\
|
||||
}
|
||||
|
||||
#endif
|
18
apps/codecs/libwma/ffmpeg_config.h
Normal file
18
apps/codecs/libwma/ffmpeg_config.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* Automatically generated by configure - do not modify */
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
|
||||
#define CONFIG_ALIGN 1
|
||||
|
||||
#define ARCH_X86 1
|
||||
#undef HAVE_MMX
|
||||
#define __CPU__ 586
|
||||
#define HAVE_BUILTIN_VECTOR 1
|
||||
#define HAVE_LOCALTIME_R 1
|
||||
#define HAVE_LRINTF 1
|
||||
#undef HAVE_VHOOK
|
||||
#define HAVE_MALLOC_H 1
|
||||
#define HAVE_MEMALIGN 1
|
||||
#define SIMPLE_IDCT 1
|
||||
|
||||
#endif
|
1412
apps/codecs/libwma/wmadata.h
Normal file
1412
apps/codecs/libwma/wmadata.h
Normal file
File diff suppressed because it is too large
Load diff
162
apps/codecs/libwma/wmadec.h
Normal file
162
apps/codecs/libwma/wmadec.h
Normal file
|
@ -0,0 +1,162 @@
|
|||
#ifndef _WMADEC_H
|
||||
#define _WMADEC_H
|
||||
|
||||
#include "asf.h"
|
||||
#include "common.h" /* For GetBitContext */
|
||||
//#include "dsputil.h" /* For MDCTContext */
|
||||
|
||||
|
||||
//#define TRACE
|
||||
/* size of blocks */
|
||||
#define BLOCK_MIN_BITS 7
|
||||
#define BLOCK_MAX_BITS 11
|
||||
#define BLOCK_MAX_SIZE (1 << BLOCK_MAX_BITS)
|
||||
|
||||
#define BLOCK_NB_SIZES (BLOCK_MAX_BITS - BLOCK_MIN_BITS + 1)
|
||||
|
||||
/* XXX: find exact max size */
|
||||
#define HIGH_BAND_MAX_SIZE 16
|
||||
|
||||
#define NB_LSP_COEFS 10
|
||||
|
||||
/* XXX: is it a suitable value ? */
|
||||
#define MAX_CODED_SUPERFRAME_SIZE 16384
|
||||
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
#define M_PI_F 0x3243f // in fixed 32 format
|
||||
#define TWO_M_PI_F 0x6487f //in fixed 32
|
||||
|
||||
#define MAX_CHANNELS 2
|
||||
|
||||
#define NOISE_TAB_SIZE 8192
|
||||
|
||||
#define LSP_POW_BITS 7
|
||||
|
||||
#define VLC_TYPE int16_t
|
||||
|
||||
typedef struct VLC
|
||||
{
|
||||
int bits;
|
||||
VLC_TYPE (*table)[2]; ///< code, bits
|
||||
int table_size, table_allocated;
|
||||
}
|
||||
VLC;
|
||||
|
||||
#define fixed32 int32_t
|
||||
#define fixed64 int64_t
|
||||
|
||||
typedef fixed32 FFTSample;
|
||||
|
||||
typedef struct FFTComplex
|
||||
{
|
||||
fixed32 re, im;
|
||||
}
|
||||
FFTComplex;
|
||||
|
||||
typedef struct FFTContext
|
||||
{
|
||||
int nbits;
|
||||
int inverse;
|
||||
uint16_t *revtab;
|
||||
FFTComplex *exptab;
|
||||
FFTComplex *exptab1; /* only used by SSE code */
|
||||
int (*fft_calc)(struct FFTContext *s, FFTComplex *z);
|
||||
}
|
||||
FFTContext;
|
||||
|
||||
typedef struct MDCTContext
|
||||
{
|
||||
int n; /* size of MDCT (i.e. number of input data * 2) */
|
||||
int nbits; /* n = 2^nbits */
|
||||
/* pre/post rotation tables */
|
||||
fixed32 *tcos;
|
||||
fixed32 *tsin;
|
||||
FFTContext fft;
|
||||
}
|
||||
MDCTContext;
|
||||
|
||||
typedef struct WMADecodeContext
|
||||
{
|
||||
GetBitContext gb;
|
||||
|
||||
int nb_block_sizes; /* number of block sizes */
|
||||
|
||||
int sample_rate;
|
||||
int nb_channels;
|
||||
int bit_rate;
|
||||
int version; /* 1 = 0x160 (WMAV1), 2 = 0x161 (WMAV2) */
|
||||
int block_align;
|
||||
int use_bit_reservoir;
|
||||
int use_variable_block_len;
|
||||
int use_exp_vlc; /* exponent coding: 0 = lsp, 1 = vlc + delta */
|
||||
int use_noise_coding; /* true if perceptual noise is added */
|
||||
int byte_offset_bits;
|
||||
VLC exp_vlc;
|
||||
int exponent_sizes[BLOCK_NB_SIZES];
|
||||
uint16_t exponent_bands[BLOCK_NB_SIZES][25];
|
||||
int high_band_start[BLOCK_NB_SIZES]; /* index of first coef in high band */
|
||||
int coefs_start; /* first coded coef */
|
||||
int coefs_end[BLOCK_NB_SIZES]; /* max number of coded coefficients */
|
||||
int exponent_high_sizes[BLOCK_NB_SIZES];
|
||||
int exponent_high_bands[BLOCK_NB_SIZES][HIGH_BAND_MAX_SIZE];
|
||||
VLC hgain_vlc;
|
||||
|
||||
/* coded values in high bands */
|
||||
int high_band_coded[MAX_CHANNELS][HIGH_BAND_MAX_SIZE];
|
||||
int high_band_values[MAX_CHANNELS][HIGH_BAND_MAX_SIZE];
|
||||
|
||||
/* there are two possible tables for spectral coefficients */
|
||||
VLC coef_vlc[2];
|
||||
uint16_t *run_table[2];
|
||||
uint16_t *level_table[2];
|
||||
/* frame info */
|
||||
int frame_len; /* frame length in samples */
|
||||
int frame_len_bits; /* frame_len = 1 << frame_len_bits */
|
||||
|
||||
/* block info */
|
||||
int reset_block_lengths;
|
||||
int block_len_bits; /* log2 of current block length */
|
||||
int next_block_len_bits; /* log2 of next block length */
|
||||
int prev_block_len_bits; /* log2 of prev block length */
|
||||
int block_len; /* block length in samples */
|
||||
int block_num; /* block number in current frame */
|
||||
int block_pos; /* current position in frame */
|
||||
uint8_t ms_stereo; /* true if mid/side stereo mode */
|
||||
uint8_t channel_coded[MAX_CHANNELS]; /* true if channel is coded */
|
||||
fixed32 exponents[MAX_CHANNELS][BLOCK_MAX_SIZE];
|
||||
fixed32 max_exponent[MAX_CHANNELS];
|
||||
int16_t coefs1[MAX_CHANNELS][BLOCK_MAX_SIZE];
|
||||
fixed32 coefs[MAX_CHANNELS][BLOCK_MAX_SIZE];
|
||||
MDCTContext mdct_ctx[BLOCK_NB_SIZES];
|
||||
fixed32 *windows[BLOCK_NB_SIZES];
|
||||
FFTComplex mdct_tmp[BLOCK_MAX_SIZE]; /* temporary storage for imdct */
|
||||
/* output buffer for one frame and the last for IMDCT windowing */
|
||||
fixed32 frame_out[MAX_CHANNELS][BLOCK_MAX_SIZE * 2];
|
||||
/* last frame info */
|
||||
uint8_t last_superframe[MAX_CODED_SUPERFRAME_SIZE + 4]; /* padding added */
|
||||
int last_bitoffset;
|
||||
int last_superframe_len;
|
||||
fixed32 noise_table[NOISE_TAB_SIZE];
|
||||
int noise_index;
|
||||
fixed32 noise_mult; /* XXX: suppress that and integrate it in the noise array */
|
||||
/* lsp_to_curve tables */
|
||||
fixed32 lsp_cos_table[BLOCK_MAX_SIZE];
|
||||
fixed64 lsp_pow_e_table[256];
|
||||
fixed64 lsp_pow_m_table1[(1 << LSP_POW_BITS)];
|
||||
fixed64 lsp_pow_m_table2[(1 << LSP_POW_BITS)];
|
||||
|
||||
#ifdef TRACE
|
||||
|
||||
int frame_count;
|
||||
#endif
|
||||
}
|
||||
WMADecodeContext;
|
||||
|
||||
int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx);
|
||||
int wma_decode_superframe(WMADecodeContext* s,
|
||||
void *data, int *data_size,
|
||||
uint8_t *buf, int buf_size);
|
||||
int wma_decode_end(WMADecodeContext *s);
|
||||
|
||||
#endif
|
2592
apps/codecs/libwma/wmadeci.c
Normal file
2592
apps/codecs/libwma/wmadeci.c
Normal file
File diff suppressed because it is too large
Load diff
385
apps/codecs/wma.c
Normal file
385
apps/codecs/wma.c
Normal file
|
@ -0,0 +1,385 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: flac.c 12830 2007-03-18 09:50:53Z learman $
|
||||
*
|
||||
* Copyright (C) 2005 Dave Chapman
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "codeclib.h"
|
||||
#include "libwma/asf.h"
|
||||
#include "libwma/wmadec.h"
|
||||
|
||||
CODEC_HEADER
|
||||
|
||||
#define MAX_BLOCKSIZE 2048
|
||||
|
||||
/* The output buffers containing the decoded samples (channels 0 and 1) */
|
||||
|
||||
/* NOTE: WMADecodeContext is 142688 bytes (on x86) */
|
||||
static WMADecodeContext wmadec;
|
||||
|
||||
/* TODO: Check the size of this */
|
||||
#define OUTBUF_SIZE 256*1024
|
||||
|
||||
enum asf_error_e {
|
||||
ASF_ERROR_INTERNAL = -1, /* incorrect input to API calls */
|
||||
ASF_ERROR_OUTOFMEM = -2, /* some malloc inside program failed */
|
||||
ASF_ERROR_EOF = -3, /* unexpected end of file */
|
||||
ASF_ERROR_IO = -4, /* error reading or writing to file */
|
||||
ASF_ERROR_INVALID_LENGTH = -5, /* length value conflict in input data */
|
||||
ASF_ERROR_INVALID_VALUE = -6, /* other value conflict in input data */
|
||||
ASF_ERROR_INVALID_OBJECT = -7, /* ASF object missing or in wrong place */
|
||||
ASF_ERROR_OBJECT_SIZE = -8, /* invalid ASF object size (too small) */
|
||||
ASF_ERROR_SEEKABLE = -9, /* file not seekable */
|
||||
ASF_ERROR_SEEK = -10 /* file is seekable but seeking failed */
|
||||
};
|
||||
|
||||
/* Read an unaligned 32-bit little endian long from buffer. */
|
||||
static unsigned long get_long_le(void* buf)
|
||||
{
|
||||
unsigned char* p = (unsigned char*) buf;
|
||||
|
||||
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
|
||||
}
|
||||
|
||||
/* Read an unaligned 16-bit little endian short from buffer. */
|
||||
static unsigned short get_short_le(void* buf)
|
||||
{
|
||||
unsigned char* p = (unsigned char*) buf;
|
||||
|
||||
return p[0] | (p[1] << 8);
|
||||
}
|
||||
|
||||
#define GETLEN2b(bits) (((bits) == 0x03) ? 4 : bits)
|
||||
|
||||
#define GETVALUE2b(bits, data) \
|
||||
(((bits) != 0x03) ? ((bits) != 0x02) ? ((bits) != 0x01) ? \
|
||||
0 : *(data) : get_short_le(data) : get_long_le(data))
|
||||
|
||||
static int asf_read_packet(int* padding, asf_waveformatex_t* wfx)
|
||||
{
|
||||
uint8_t tmp8, packet_flags, packet_property;
|
||||
int ec_length, opaque_data, ec_length_type;
|
||||
int datalen;
|
||||
uint8_t data[18];
|
||||
uint8_t* datap;
|
||||
uint32_t length;
|
||||
uint32_t padding_length;
|
||||
uint32_t send_time;
|
||||
uint16_t duration;
|
||||
uint16_t payload_count;
|
||||
int payload_length_type;
|
||||
uint32_t payload_hdrlen;
|
||||
int payload_datalen;
|
||||
int multiple;
|
||||
uint32_t replicated_length;
|
||||
uint32_t media_object_number;
|
||||
uint32_t media_object_offset;
|
||||
uint32_t bytesread = 0;
|
||||
|
||||
if (ci->read_filebuf(&tmp8, 1) == 0) {
|
||||
return ASF_ERROR_EOF;
|
||||
}
|
||||
bytesread++;
|
||||
|
||||
/* TODO: We need a better way to detect endofstream */
|
||||
if (tmp8 != 0x82) { return -1; }
|
||||
|
||||
//DEBUGF("tmp8=0x%02x\n",tmp8);
|
||||
|
||||
if (tmp8 & 0x80) {
|
||||
ec_length = tmp8 & 0x0f;
|
||||
opaque_data = (tmp8 >> 4) & 0x01;
|
||||
ec_length_type = (tmp8 >> 5) & 0x03;
|
||||
|
||||
if (ec_length_type != 0x00 || opaque_data != 0 || ec_length != 0x02) {
|
||||
DEBUGF("incorrect error correction flags\n");
|
||||
return ASF_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
/* Skip ec_data */
|
||||
ci->advance_buffer(ec_length);
|
||||
bytesread += ec_length;
|
||||
} else {
|
||||
ec_length = 0;
|
||||
}
|
||||
|
||||
if (ci->read_filebuf(&packet_flags, 1) == 0) { return ASF_ERROR_EOF; }
|
||||
if (ci->read_filebuf(&packet_property, 1) == 0) { return ASF_ERROR_EOF; }
|
||||
bytesread += 2;
|
||||
|
||||
datalen = GETLEN2b((packet_flags >> 1) & 0x03) +
|
||||
GETLEN2b((packet_flags >> 3) & 0x03) +
|
||||
GETLEN2b((packet_flags >> 5) & 0x03) + 6;
|
||||
|
||||
#if 0
|
||||
if (datalen > sizeof(data)) {
|
||||
DEBUGF("Unexpectedly long datalen in data - %d\n",datalen);
|
||||
return ASF_ERROR_OUTOFMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ci->read_filebuf(data, datalen) == 0) {
|
||||
return ASF_ERROR_EOF;
|
||||
}
|
||||
|
||||
bytesread += datalen;
|
||||
|
||||
datap = data;
|
||||
length = GETVALUE2b((packet_flags >> 5) & 0x03, datap);
|
||||
datap += GETLEN2b((packet_flags >> 5) & 0x03);
|
||||
/* sequence value is not used */
|
||||
GETVALUE2b((packet_flags >> 1) & 0x03, datap);
|
||||
datap += GETLEN2b((packet_flags >> 1) & 0x03);
|
||||
padding_length = GETVALUE2b((packet_flags >> 3) & 0x03, datap);
|
||||
datap += GETLEN2b((packet_flags >> 3) & 0x03);
|
||||
send_time = get_long_le(datap);
|
||||
datap += 4;
|
||||
duration = get_short_le(datap);
|
||||
datap += 2;
|
||||
|
||||
/* this is really idiotic, packet length can (and often will) be
|
||||
* undefined and we just have to use the header packet size as the size
|
||||
* value */
|
||||
if (!((packet_flags >> 5) & 0x03)) {
|
||||
length = wfx->packet_size;
|
||||
}
|
||||
|
||||
/* this is also really idiotic, if packet length is smaller than packet
|
||||
* size, we need to manually add the additional bytes into padding length
|
||||
*/
|
||||
if (length < wfx->packet_size) {
|
||||
padding_length += wfx->packet_size - length;
|
||||
length = wfx->packet_size;
|
||||
}
|
||||
|
||||
if (length > wfx->packet_size) {
|
||||
DEBUGF("packet with too big length value\n");
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
/* check if we have multiple payloads */
|
||||
if (packet_flags & 0x01) {
|
||||
if (ci->read_filebuf(&tmp8, 1) == 0) {
|
||||
return ASF_ERROR_EOF;
|
||||
}
|
||||
payload_count = tmp8 & 0x3f;
|
||||
payload_length_type = (tmp8 >> 6) & 0x03;
|
||||
bytesread++;
|
||||
} else {
|
||||
payload_count = 1;
|
||||
payload_length_type = 0x02; /* not used */
|
||||
}
|
||||
|
||||
if (length < bytesread) {
|
||||
DEBUGF("header exceeded packet size, invalid file - length=%d, bytesread=%d\n",(int)length,(int)bytesread);
|
||||
/* FIXME: should this be checked earlier? */
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
if (ci->read_filebuf(&tmp8, 1) == 0) {
|
||||
return ASF_ERROR_EOF;
|
||||
}
|
||||
//DEBUGF("stream = %u\n",tmp8&0x7f);
|
||||
bytesread++;
|
||||
|
||||
if ((tmp8 & 0x7f) != wfx->audiostream) {
|
||||
/* Not interested in this packet, just skip it */
|
||||
ci->advance_buffer(length - bytesread);
|
||||
return 0;
|
||||
} else {
|
||||
/* We are now at the data */
|
||||
//DEBUGF("Read packet - length=%u, padding_length=%u, send_time=%u, duration=%u, payload_count=%d, bytesread=%d\n",length,padding_length,(int)send_time,duration,payload_count,bytesread);
|
||||
|
||||
/* TODO: Loop through all payloads in this packet - or do we
|
||||
assume that audio streams only have one payload per packet? */
|
||||
|
||||
payload_hdrlen = GETLEN2b(packet_property & 0x03) +
|
||||
GETLEN2b((packet_property >> 2) & 0x03) +
|
||||
GETLEN2b((packet_property >> 4) & 0x03);
|
||||
|
||||
//DEBUGF("payload_hdrlen = %d\n",payload_hdrlen);
|
||||
#if 0
|
||||
/* TODO */
|
||||
if (payload_hdrlen > size) {
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
#endif
|
||||
if (payload_hdrlen > sizeof(data)) {
|
||||
DEBUGF("Unexpectedly long datalen in data - %d\n",datalen);
|
||||
return ASF_ERROR_OUTOFMEM;
|
||||
}
|
||||
|
||||
if (ci->read_filebuf(data, payload_hdrlen) == 0) {
|
||||
return ASF_ERROR_EOF;
|
||||
}
|
||||
bytesread += payload_hdrlen;
|
||||
|
||||
datap = data;
|
||||
media_object_number = GETVALUE2b((packet_property >> 4) & 0x03, datap);
|
||||
datap += GETLEN2b((packet_property >> 4) & 0x03);
|
||||
media_object_offset = GETVALUE2b((packet_property >> 2) & 0x03, datap);
|
||||
datap += GETLEN2b((packet_property >> 2) & 0x03);
|
||||
replicated_length = GETVALUE2b(packet_property & 0x03, datap);
|
||||
datap += GETLEN2b(packet_property & 0x03);
|
||||
|
||||
/* TODO: Validate replicated_length */
|
||||
/* TODO: Is the content of this important for us? */
|
||||
ci->advance_buffer(replicated_length);
|
||||
bytesread += replicated_length;
|
||||
|
||||
|
||||
multiple = packet_flags & 0x01;
|
||||
|
||||
if (multiple) {
|
||||
int x;
|
||||
|
||||
x = GETLEN2b(payload_length_type);
|
||||
|
||||
if (x != 2) {
|
||||
/* in multiple payloads datalen should be a word */
|
||||
return ASF_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (skip + tmp > datalen) {
|
||||
/* not enough data */
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
#endif
|
||||
if (ci->read_filebuf(&data, x) == 0) {
|
||||
return ASF_ERROR_EOF;
|
||||
}
|
||||
bytesread += x;
|
||||
payload_datalen = GETVALUE2b(payload_length_type, data);
|
||||
} else {
|
||||
payload_datalen = length - bytesread;
|
||||
}
|
||||
|
||||
//DEBUGF("WE HAVE DATA - %d bytes\n", payload_datalen);
|
||||
// lseek(fd, payload_datalen, SEEK_CUR);
|
||||
*padding = padding_length;
|
||||
return payload_datalen;
|
||||
}
|
||||
}
|
||||
|
||||
/* this is the codec entry point */
|
||||
enum codec_status codec_main(void)
|
||||
{
|
||||
uint32_t samplesdone;
|
||||
uint32_t elapsedtime;
|
||||
int retval;
|
||||
asf_waveformatex_t wfx;
|
||||
uint32_t currentframe;
|
||||
unsigned char* inbuffer;
|
||||
size_t resume_offset;
|
||||
size_t n;
|
||||
int wmares, res, padding, outbufsize;
|
||||
uint8_t* outbuf;
|
||||
|
||||
/* Generic codec initialisation */
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
||||
ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, 1024*128);
|
||||
|
||||
ci->configure(DSP_SET_SAMPLE_DEPTH, 15);
|
||||
|
||||
next_track:
|
||||
|
||||
/* Wait for the metadata to be read */
|
||||
while (!*ci->taginfo_ready && !ci->stop_codec)
|
||||
ci->sleep(1);
|
||||
|
||||
retval = CODEC_OK;
|
||||
|
||||
/* Remember the resume position - when the codec is opened, the
|
||||
playback engine will reset it. */
|
||||
resume_offset = ci->id3->offset;
|
||||
|
||||
if (codec_init()) {
|
||||
LOGF("WMA: Error initialising codec\n");
|
||||
retval = CODEC_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
outbuf = codec_malloc(OUTBUF_SIZE);
|
||||
|
||||
/* Copy the format metadata we've stored in the id3 TOC field. This
|
||||
saves us from parsing it again here. */
|
||||
memcpy(&wfx, ci->id3->toc, sizeof(wfx));
|
||||
|
||||
wma_decode_init(&wmadec,&wfx);
|
||||
|
||||
/* Now advance the file position to the first frame */
|
||||
ci->seek_buffer(ci->id3->first_frame_offset);
|
||||
|
||||
ci->configure(DSP_SWITCH_FREQUENCY, wfx.rate);
|
||||
ci->configure(DSP_SET_STEREO_MODE, wfx.channels == 1 ?
|
||||
STEREO_MONO : STEREO_INTERLEAVED);
|
||||
codec_set_replaygain(ci->id3);
|
||||
|
||||
/* The main decoding loop */
|
||||
|
||||
currentframe = 0;
|
||||
samplesdone = 0;
|
||||
|
||||
DEBUGF("**************** IN WMA.C ******************\n");
|
||||
wma_decode_init(&wmadec,&wfx);
|
||||
|
||||
res = 1;
|
||||
while (res >= 0)
|
||||
{
|
||||
ci->yield();
|
||||
if (ci->stop_codec || ci->new_track) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Deal with any pending seek requests - ignore them */
|
||||
if (ci->seek_time)
|
||||
{
|
||||
ci->seek_complete();
|
||||
}
|
||||
|
||||
res = asf_read_packet(&padding, &wfx);
|
||||
if (res > 0) {
|
||||
inbuffer = ci->request_buffer(&n, res - padding);
|
||||
|
||||
wmares = wma_decode_superframe(&wmadec,
|
||||
outbuf,&outbufsize,
|
||||
inbuffer,res - padding);
|
||||
|
||||
ci->advance_buffer(res);
|
||||
|
||||
if (wmares > 0) {
|
||||
ci->pcmbuf_insert(outbuf, NULL, outbufsize / (wfx.channels * 2));
|
||||
samplesdone += (outbufsize / (wfx.channels * 2));
|
||||
DEBUGF("Decoded %d samples\n",(outbufsize / (wfx.channels * 2)));
|
||||
elapsedtime = (samplesdone*10)/(wfx.rate/100);
|
||||
ci->set_elapsed(elapsedtime);
|
||||
}
|
||||
|
||||
ci->yield ();
|
||||
}
|
||||
}
|
||||
retval = CODEC_OK;
|
||||
|
||||
done:
|
||||
LOGF("WMA: Decoded %ld samples\n",samplesdone);
|
||||
|
||||
if (ci->request_next_track())
|
||||
goto next_track;
|
||||
|
||||
exit:
|
||||
return retval;
|
||||
}
|
|
@ -133,6 +133,13 @@ bool get_metadata(struct track_info* track, int fd, const char* trackname,
|
|||
|
||||
break;
|
||||
|
||||
case AFMT_WMA:
|
||||
if (!get_asf_metadata(fd, &(track->id3)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case AFMT_APE:
|
||||
if (!get_monkeys_metadata(fd, &(track->id3)))
|
||||
{
|
||||
|
|
418
apps/metadata/asf.c
Normal file
418
apps/metadata/asf.c
Normal file
|
@ -0,0 +1,418 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 Dave Chapman
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "id3.h"
|
||||
#include "debug.h"
|
||||
#include "rbunicode.h"
|
||||
#include "metadata_common.h"
|
||||
#include <codecs/libwma/asf.h>
|
||||
|
||||
static asf_waveformatex_t wfx;
|
||||
|
||||
/* TODO: Just read the GUIDs into a 16-byte array, and use memcmp to compare */
|
||||
struct guid_s {
|
||||
uint32_t v1;
|
||||
uint16_t v2;
|
||||
uint16_t v3;
|
||||
uint8_t v4[8];
|
||||
};
|
||||
typedef struct guid_s guid_t;
|
||||
|
||||
struct asf_object_s {
|
||||
guid_t guid;
|
||||
uint64_t size;
|
||||
uint64_t datalen;
|
||||
};
|
||||
typedef struct asf_object_s asf_object_t;
|
||||
|
||||
enum asf_error_e {
|
||||
ASF_ERROR_INTERNAL = -1, /* incorrect input to API calls */
|
||||
ASF_ERROR_OUTOFMEM = -2, /* some malloc inside program failed */
|
||||
ASF_ERROR_EOF = -3, /* unexpected end of file */
|
||||
ASF_ERROR_IO = -4, /* error reading or writing to file */
|
||||
ASF_ERROR_INVALID_LENGTH = -5, /* length value conflict in input data */
|
||||
ASF_ERROR_INVALID_VALUE = -6, /* other value conflict in input data */
|
||||
ASF_ERROR_INVALID_OBJECT = -7, /* ASF object missing or in wrong place */
|
||||
ASF_ERROR_OBJECT_SIZE = -8, /* invalid ASF object size (too small) */
|
||||
ASF_ERROR_SEEKABLE = -9, /* file not seekable */
|
||||
ASF_ERROR_SEEK = -10 /* file is seekable but seeking failed */
|
||||
};
|
||||
|
||||
static const guid_t asf_guid_null =
|
||||
{0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
/* top level object guids */
|
||||
|
||||
static const guid_t asf_guid_header =
|
||||
{0x75B22630, 0x668E, 0x11CF, {0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}};
|
||||
|
||||
static const guid_t asf_guid_data =
|
||||
{0x75B22636, 0x668E, 0x11CF, {0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}};
|
||||
|
||||
static const guid_t asf_guid_index =
|
||||
{0x33000890, 0xE5B1, 0x11CF, {0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB}};
|
||||
|
||||
/* header level object guids */
|
||||
|
||||
static const guid_t asf_guid_file_properties =
|
||||
{0x8cabdca1, 0xa947, 0x11cf, {0x8E, 0xe4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}};
|
||||
|
||||
static const guid_t asf_guid_stream_properties =
|
||||
{0xB7DC0791, 0xA9B7, 0x11CF, {0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}};
|
||||
|
||||
static const guid_t asf_guid_content_description =
|
||||
{0x75B22633, 0x668E, 0x11CF, {0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}};
|
||||
|
||||
static const guid_t asf_guid_extended_content_description =
|
||||
{0xD2D0A440, 0xE307, 0x11D2, {0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50}};
|
||||
|
||||
/* stream type guids */
|
||||
|
||||
static const guid_t asf_guid_stream_type_audio =
|
||||
{0xF8699E40, 0x5B4D, 0x11CF, {0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B}};
|
||||
|
||||
static int asf_guid_match(const guid_t *guid1, const guid_t *guid2)
|
||||
{
|
||||
if((guid1->v1 != guid2->v1) ||
|
||||
(guid1->v2 != guid2->v2) ||
|
||||
(guid1->v3 != guid2->v3) ||
|
||||
(memcmp(guid1->v4, guid2->v4, 8))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Read the 16 byte GUID from a file */
|
||||
static void asf_readGUID(int fd, guid_t* guid)
|
||||
{
|
||||
read_uint32le(fd, &guid->v1);
|
||||
read_uint16le(fd, &guid->v2);
|
||||
read_uint16le(fd, &guid->v3);
|
||||
read(fd, guid->v4, 8);
|
||||
}
|
||||
|
||||
static void asf_read_object_header(asf_object_t *obj, int fd)
|
||||
{
|
||||
asf_readGUID(fd, &obj->guid);
|
||||
read_uint64le(fd, &obj->size);
|
||||
obj->datalen = 0;
|
||||
}
|
||||
|
||||
static int asf_parse_header(int fd, struct mp3entry* id3)
|
||||
{
|
||||
asf_object_t current;
|
||||
asf_object_t header;
|
||||
uint64_t datalen;
|
||||
int i;
|
||||
int fileprop = 0;
|
||||
uint64_t play_duration;
|
||||
uint64_t tmp64;
|
||||
uint32_t tmp32;
|
||||
uint16_t tmp16;
|
||||
uint8_t tmp8;
|
||||
uint16_t flags;
|
||||
uint32_t subobjects;
|
||||
uint8_t utf16buf[512];
|
||||
uint8_t utf8buf[512];
|
||||
|
||||
asf_read_object_header((asf_object_t *) &header, fd);
|
||||
|
||||
DEBUGF("header.size=%d\n",(int)header.size);
|
||||
if (header.size < 30) {
|
||||
/* invalid size for header object */
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
}
|
||||
|
||||
read_uint32le(fd, &subobjects);
|
||||
|
||||
/* Two reserved bytes - do we need to read them? */
|
||||
lseek(fd, 2, SEEK_CUR);
|
||||
|
||||
DEBUGF("Read header - size=%d, subobjects=%lu\n",(int)header.size, subobjects);
|
||||
|
||||
if (subobjects > 0) {
|
||||
header.datalen = header.size - 30;
|
||||
|
||||
/* TODO: Check that we have datalen bytes left in the file */
|
||||
datalen = header.datalen;
|
||||
|
||||
for (i=0; i<(int)subobjects; i++) {
|
||||
DEBUGF("Parsing header object %d - datalen=%d\n",i,(int)datalen);
|
||||
if (datalen < 24) {
|
||||
DEBUGF("not enough data for reading object\n");
|
||||
break;
|
||||
}
|
||||
|
||||
asf_read_object_header(¤t, fd);
|
||||
|
||||
if (current.size > datalen || current.size < 24) {
|
||||
DEBUGF("invalid object size - current.size=%d, datalen=%d\n",(int)current.size,(int)datalen);
|
||||
break;
|
||||
}
|
||||
|
||||
if (asf_guid_match(¤t.guid, &asf_guid_file_properties)) {
|
||||
if (current.size < 104)
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
|
||||
if (fileprop) {
|
||||
/* multiple file properties objects not allowed */
|
||||
return ASF_ERROR_INVALID_OBJECT;
|
||||
}
|
||||
|
||||
fileprop = 1;
|
||||
/* All we want is the play duration - uint64_t at offset 40 */
|
||||
lseek(fd, 40, SEEK_CUR);
|
||||
|
||||
read_uint64le(fd, &play_duration);
|
||||
id3->length = play_duration / 10000;
|
||||
|
||||
DEBUGF("****** length = %lums\n", id3->length);
|
||||
|
||||
/* Read the packet size - uint32_t at offset 68 */
|
||||
lseek(fd, 20, SEEK_CUR);
|
||||
read_uint32le(fd, &wfx.packet_size);
|
||||
|
||||
/* Skip bytes remaining in object */
|
||||
lseek(fd, current.size - 24 - 72, SEEK_CUR);
|
||||
} else if (asf_guid_match(¤t.guid, &asf_guid_stream_properties)) {
|
||||
guid_t guid;
|
||||
uint32_t propdatalen;
|
||||
|
||||
if (current.size < 78)
|
||||
return ASF_ERROR_OBJECT_SIZE;
|
||||
|
||||
#if 0
|
||||
asf_byteio_getGUID(&guid, current->data);
|
||||
datalen = asf_byteio_getDWLE(current->data + 40);
|
||||
flags = asf_byteio_getWLE(current->data + 48);
|
||||
#endif
|
||||
|
||||
asf_readGUID(fd, &guid);
|
||||
|
||||
lseek(fd, 24, SEEK_CUR);
|
||||
read_uint32le(fd, &propdatalen);
|
||||
lseek(fd, 4, SEEK_CUR);
|
||||
read_uint16le(fd, &flags);
|
||||
|
||||
if (!asf_guid_match(&guid, &asf_guid_stream_type_audio)) {
|
||||
DEBUGF("Found stream properties for non audio stream, skipping\n");
|
||||
lseek(fd,current.size - 24 - 50,SEEK_CUR);
|
||||
} else {
|
||||
lseek(fd, 4, SEEK_CUR);
|
||||
DEBUGF("Found stream properties for audio stream %d\n",flags&0x7f);
|
||||
|
||||
/* TODO: Check codec_id and find the lowest numbered audio stream in the file */
|
||||
wfx.audiostream = flags&0x7f;
|
||||
|
||||
if (propdatalen < 18) {
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (asf_byteio_getWLE(data + 16) > datalen - 16) {
|
||||
return ASF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
#endif
|
||||
read_uint16le(fd, &wfx.codec_id);
|
||||
read_uint16le(fd, &wfx.channels);
|
||||
read_uint32le(fd, &wfx.rate);
|
||||
read_uint32le(fd, &wfx.bitrate);
|
||||
wfx.bitrate *= 8;
|
||||
read_uint16le(fd, &wfx.blockalign);
|
||||
read_uint16le(fd, &wfx.bitspersample);
|
||||
read_uint16le(fd, &wfx.datalen);
|
||||
|
||||
/* Round bitrate to the nearest kbit */
|
||||
id3->bitrate = (wfx.bitrate + 500) / 1000;
|
||||
id3->frequency = wfx.rate;
|
||||
|
||||
if (wfx.codec_id == ASF_CODEC_ID_WMAV1) {
|
||||
read(fd, wfx.data, 4);
|
||||
lseek(fd,current.size - 24 - 72 - 4,SEEK_CUR);
|
||||
/* A hack - copy the wfx struct to the MP3 TOC field in the id3 struct */
|
||||
memcpy(id3->toc, &wfx, sizeof(wfx));
|
||||
} else if (wfx.codec_id == ASF_CODEC_ID_WMAV2) {
|
||||
read(fd, wfx.data, 6);
|
||||
lseek(fd,current.size - 24 - 72 - 6,SEEK_CUR);
|
||||
/* A hack - copy the wfx struct to the MP3 TOC field in the id3 struct */
|
||||
memcpy(id3->toc, &wfx, sizeof(wfx));
|
||||
} else {
|
||||
lseek(fd,current.size - 24 - 72,SEEK_CUR);
|
||||
}
|
||||
|
||||
}
|
||||
} else if (asf_guid_match(¤t.guid, &asf_guid_content_description)) {
|
||||
/* Object contains five 16-bit string lengths, followed by the five strings:
|
||||
title, artist, copyright, description, rating
|
||||
*/
|
||||
uint16_t strlength[5];
|
||||
int i;
|
||||
|
||||
DEBUGF("Found GUID_CONTENT_DESCRIPTION - size=%d\n",(int)(current.size - 24));
|
||||
|
||||
/* Read the 5 string lengths - number of bytes included trailing zero */
|
||||
for (i=0; i<5; i++) {
|
||||
read_uint16le(fd, &strlength[i]);
|
||||
DEBUGF("strlength = %u\n",strlength[i]);
|
||||
}
|
||||
|
||||
for (i=0; i<5 ; i++) {
|
||||
if (strlength[i] > 0) {
|
||||
read(fd, utf16buf, strlength[i]);
|
||||
utf16LEdecode(utf16buf, utf8buf, strlength[i]);
|
||||
DEBUGF("TAG %d = %s\n",i,utf8buf);
|
||||
}
|
||||
}
|
||||
} else if (asf_guid_match(¤t.guid, &asf_guid_extended_content_description)) {
|
||||
uint16_t count;
|
||||
int i;
|
||||
int bytesleft = current.size - 24;
|
||||
DEBUGF("Found GUID_EXTENDED_CONTENT_DESCRIPTION\n");
|
||||
|
||||
read_uint16le(fd, &count);
|
||||
bytesleft -= 2;
|
||||
DEBUGF("extended metadata count = %u\n",count);
|
||||
|
||||
for (i=0; i < count; i++) {
|
||||
uint16_t length, type;
|
||||
|
||||
read_uint16le(fd, &length);
|
||||
read(fd, utf16buf, length);
|
||||
utf16LEdecode(utf16buf, utf8buf, length);
|
||||
DEBUGF("Key=\"%s\" ",utf8buf);
|
||||
bytesleft -= 2 + length;
|
||||
|
||||
read_uint16le(fd, &type);
|
||||
read_uint16le(fd, &length);
|
||||
switch(type)
|
||||
{
|
||||
case 0: /* String */
|
||||
read(fd, utf16buf, length);
|
||||
utf16LEdecode(utf16buf, utf8buf, length);
|
||||
DEBUGF("Value=\"%s\"\n",utf8buf);
|
||||
break;
|
||||
|
||||
case 1: /* Hex string */
|
||||
DEBUGF("Value=NOT YET IMPLEMENTED (HEX STRING)\n");
|
||||
lseek(fd,length,SEEK_CUR);
|
||||
break;
|
||||
|
||||
case 2: /* Bool */
|
||||
read(fd, &tmp8, 1);
|
||||
DEBUGF("Value=%s\n",(tmp8 ? "TRUE" : "FALSE"));
|
||||
lseek(fd,length - 1,SEEK_CUR);
|
||||
break;
|
||||
|
||||
case 3: /* 32-bit int */
|
||||
read_uint32le(fd, &tmp32);
|
||||
DEBUGF("Value=%lu\n",tmp32);
|
||||
lseek(fd,length - 4,SEEK_CUR);
|
||||
break;
|
||||
|
||||
case 4: /* 64-bit int */
|
||||
read_uint64le(fd, &tmp64);
|
||||
DEBUGF("Value=%llu\n",tmp64);
|
||||
lseek(fd,length - 8,SEEK_CUR);
|
||||
break;
|
||||
|
||||
case 5: /* 16-bit int */
|
||||
read_uint16le(fd, &tmp16);
|
||||
DEBUGF("Value=%u\n",tmp16);
|
||||
lseek(fd,length - 2,SEEK_CUR);
|
||||
break;
|
||||
|
||||
default:
|
||||
lseek(fd,length,SEEK_CUR);
|
||||
break;
|
||||
}
|
||||
bytesleft -= 4 + length;
|
||||
}
|
||||
|
||||
lseek(fd, bytesleft, SEEK_CUR);
|
||||
} else {
|
||||
DEBUGF("Skipping %d bytes of object\n",(int)(current.size - 24));
|
||||
lseek(fd,current.size - 24,SEEK_CUR);
|
||||
}
|
||||
|
||||
DEBUGF("Parsed object - size = %d\n",(int)current.size);
|
||||
datalen -= current.size;
|
||||
}
|
||||
|
||||
if (i != (int)subobjects || datalen != 0) {
|
||||
DEBUGF("header data doesn't match given subobject count\n");
|
||||
return ASF_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
DEBUGF("%d subobjects read successfully\n", i);
|
||||
}
|
||||
|
||||
#if 0
|
||||
tmp = asf_parse_header_validate(file, &header);
|
||||
if (tmp < 0) {
|
||||
/* header read ok but doesn't validate correctly */
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
DEBUGF("header validated correctly\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool get_asf_metadata(int fd, struct mp3entry* id3)
|
||||
{
|
||||
int res;
|
||||
asf_object_t obj;
|
||||
|
||||
wfx.audiostream = -1;
|
||||
|
||||
res = asf_parse_header(fd, id3);
|
||||
|
||||
if (res < 0) {
|
||||
DEBUGF("ASF: parsing error - %d\n",res);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wfx.audiostream == -1) {
|
||||
DEBUGF("ASF: No WMA streams found\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
asf_read_object_header(&obj, fd);
|
||||
|
||||
if (!asf_guid_match(&obj.guid, &asf_guid_data)) {
|
||||
DEBUGF("ASF: No data object found\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Store the current file position - no need to parse the header
|
||||
again in the codec. The +26 skips the rest of the data object
|
||||
header.
|
||||
*/
|
||||
id3->first_frame_offset = lseek(fd, 0, SEEK_CUR) + 26;
|
||||
|
||||
return true;
|
||||
}
|
|
@ -94,8 +94,8 @@ long read_string(int fd, char* buf, long buf_size, int eos, long size)
|
|||
return read_bytes;
|
||||
}
|
||||
|
||||
/* Read an unsigned 32-bit integer from a big-endian file. */
|
||||
#ifdef ROCKBOX_LITTLE_ENDIAN
|
||||
/* Read an unsigned 32-bit integer from a big-endian file. */
|
||||
int read_uint32be(int fd, unsigned int* buf)
|
||||
{
|
||||
size_t n;
|
||||
|
@ -104,6 +104,39 @@ int read_uint32be(int fd, unsigned int* buf)
|
|||
*buf = betoh32(*buf);
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
/* Read unsigned integers from a little-endian file. */
|
||||
int read_uint16le(int fd, uint16_t* buf)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
n = read(fd, (char*) buf, 2);
|
||||
*buf = letoh16(*buf);
|
||||
return n;
|
||||
}
|
||||
int read_uint32le(int fd, uint32_t* buf)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
n = read(fd, (char*) buf, 4);
|
||||
*buf = letoh32(*buf);
|
||||
return n;
|
||||
}
|
||||
int read_uint64le(int fd, uint64_t* buf)
|
||||
{
|
||||
size_t n;
|
||||
uint8_t data[8];
|
||||
int i;
|
||||
|
||||
n = read(fd, data, 8);
|
||||
|
||||
for (i=7, *buf=0; i>=0; i--) {
|
||||
*buf <<= 8;
|
||||
*buf |= data[i];
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Read an unaligned 32-bit little endian long from buffer. */
|
||||
|
|
|
@ -35,11 +35,19 @@ bool read_vorbis_tags(int fd, struct mp3entry *id3,
|
|||
|
||||
bool skip_id3v2(int fd, struct mp3entry *id3);
|
||||
long read_string(int fd, char* buf, long buf_size, int eos, long size);
|
||||
|
||||
#ifdef ROCKBOX_BIG_ENDIAN
|
||||
#define read_uint32be(fd,buf) read((fd), (buf), 4)
|
||||
int read_uint16le(int fd, uint16_t* buf);
|
||||
int read_uint32le(int fd, uint32_t* buf);
|
||||
int read_uint64le(int fd, uint64_t* buf);
|
||||
#else
|
||||
int read_uint32be(int fd, unsigned int* buf);
|
||||
#define read_uint16le(fd,buf) read((fd), (buf), 2)
|
||||
#define read_uint32le(fd,buf) read((fd), (buf), 4)
|
||||
#define read_uint64le(fd,buf) read((fd), (buf), 8)
|
||||
#endif
|
||||
|
||||
unsigned long get_long_le(void* buf);
|
||||
unsigned short get_short_le(void* buf);
|
||||
unsigned long get_long_be(void* buf);
|
||||
|
|
|
@ -29,3 +29,4 @@ bool get_spc_metadata(int fd, struct mp3entry* id3);
|
|||
bool get_speex_metadata(int fd, struct mp3entry* id3);
|
||||
bool get_vorbis_metadata(int fd, struct mp3entry* id3);
|
||||
bool get_wave_metadata(int fd, struct mp3entry* id3);
|
||||
bool get_asf_metadata(int fd, struct mp3entry* id3);
|
||||
|
|
|
@ -301,6 +301,8 @@ Ivan Zupan
|
|||
Alexander Papst
|
||||
Christoph Reiter
|
||||
Rhino Banga
|
||||
Paul Jones
|
||||
Michael Giacomelli
|
||||
The libmad team
|
||||
The wavpack team
|
||||
The ffmpeg team
|
||||
|
|
|
@ -56,6 +56,7 @@ enum
|
|||
AFMT_SPEEX, /* Ogg Speex speech */
|
||||
AFMT_SPC, /* SPC700 save state */
|
||||
AFMT_APE, /* Monkey's Audio (APE) */
|
||||
AFMT_WMA, /* WMAV1/V2 in ASF */
|
||||
#endif
|
||||
|
||||
/* add new formats at any index above this line to have a sensible order -
|
||||
|
|
|
@ -110,6 +110,9 @@ const struct afmt_entry audio_formats[AFMT_NUM_CODECS] =
|
|||
/* APE (Monkey's Audio) */
|
||||
[AFMT_APE] =
|
||||
AFMT_ENTRY("APE", "ape", NULL, "ape\0mac\0" ),
|
||||
/* WMA (WMAV1/V2 in ASF) */
|
||||
[AFMT_WMA] =
|
||||
AFMT_ENTRY("WMA", "wma", NULL, "wma\0wmv\0asf" ),
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
38
tools/configure
vendored
38
tools/configure
vendored
|
@ -756,7 +756,7 @@ EOF
|
|||
archosrom=""
|
||||
flash="$pwd/rombox.iriver"
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
toolset=$iriverbitmaptools
|
||||
|
@ -781,7 +781,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
toolset=$iriverbitmaptools
|
||||
|
@ -806,7 +806,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
toolset=$iriverbitmaptools
|
||||
|
@ -831,7 +831,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
toolset="$iaudiobitmaptools"
|
||||
|
@ -857,7 +857,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
toolset="$iaudiobitmaptools"
|
||||
|
@ -881,7 +881,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
bootoutput="bootloader-$archos.ipod"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
|
@ -906,7 +906,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
bootoutput="bootloader-$archos.ipod"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
|
@ -930,7 +930,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
bootoutput="bootloader-$archos.ipod"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
|
@ -955,7 +955,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
bootoutput="bootloader-$archos.ipod"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
|
@ -980,7 +980,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
bootoutput="bootloader-$archos.ipod"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
|
@ -1005,7 +1005,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
bootoutput="bootloader-$archos.ipod"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
|
@ -1030,7 +1030,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
toolset=$genericbitmaptools
|
||||
|
@ -1053,7 +1053,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
toolset=$gigabeatbitmaptools
|
||||
boottool="$rootdir/tools/scramble -gigabeat"
|
||||
bootoutput="FWIMG01.DAT"
|
||||
|
@ -1077,7 +1077,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
bootoutput="bootloader-$archos.ipod"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
|
@ -1102,7 +1102,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
boottool="$rootdir/tools/scramble -mi4v3 -model=h10 -type=RBBL"
|
||||
bootoutput="H10_20GC.mi4"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
|
@ -1128,7 +1128,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
boottool="$rootdir/tools/scramble -mi4v2 -model=h105 -type=RBBL"
|
||||
bootoutput="H10.mi4"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
|
@ -1154,7 +1154,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
boottool="$rootdir/tools/scramble -mi4v3 -model=e200 -type=RBBL"
|
||||
bootoutput="PP5022.mi4"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
|
@ -1183,7 +1183,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
boottool="$rootdir/tools/scramble -mi4r -model=e20r -type=RBBL"
|
||||
bootoutput="pp5022.mi4"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
|
@ -1209,7 +1209,7 @@ EOF
|
|||
archosrom=""
|
||||
flash=""
|
||||
plugins="yes"
|
||||
codecs="libmad liba52 libffmpegFLAC libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
codecs="libmad liba52 libffmpegFLAC libwma libTremor libwavpack libmusepack libalac libfaad libm4a libspeex libdemac"
|
||||
boottool="$rootdir/tools/scramble -mi4v2"
|
||||
bootoutput="pp5020.mi4"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
|
|
Loading…
Reference in a new issue