mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-03-27 09:32:28 +08:00
add libwma codec.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@26 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
3
bsp/stm32_radio/libwma/SOURCES
Normal file
3
bsp/stm32_radio/libwma/SOURCES
Normal file
@@ -0,0 +1,3 @@
|
||||
wmadeci.c
|
||||
wmafixed.c
|
||||
bitstream.c
|
||||
24
bsp/stm32_radio/libwma/asf.h
Normal file
24
bsp/stm32_radio/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
|
||||
228
bsp/stm32_radio/libwma/asm_arm.h
Normal file
228
bsp/stm32_radio/libwma/asm_arm.h
Normal file
@@ -0,0 +1,228 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
|
||||
* *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
|
||||
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: arm7 and later wide math functions
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#ifndef __ASM_ARM_H__
|
||||
#define __ASM_ARM_H__
|
||||
|
||||
#if !defined(_V_WIDE_MATH) && !defined(_LOW_ACCURACY_)
|
||||
#define _V_WIDE_MATH
|
||||
|
||||
static inline int32_t MULT32(int32_t x, int32_t y) {
|
||||
int lo,hi;
|
||||
asm volatile("smull\t%0, %1, %2, %3"
|
||||
: "=&r"(lo),"=&r"(hi)
|
||||
: "%r"(x),"r"(y)
|
||||
: "cc");
|
||||
return(hi);
|
||||
}
|
||||
|
||||
static inline int32_t MULT31(int32_t x, int32_t y) {
|
||||
return MULT32(x,y)<<1;
|
||||
}
|
||||
|
||||
static inline int32_t MULT31_SHIFT15(int32_t x, int32_t y) {
|
||||
int lo,hi;
|
||||
asm volatile("smull %0, %1, %2, %3\n\t"
|
||||
"movs %0, %0, lsr #15\n\t"
|
||||
"adc %1, %0, %1, lsl #17\n\t"
|
||||
: "=&r"(lo),"=&r"(hi)
|
||||
: "%r"(x),"r"(y)
|
||||
: "cc");
|
||||
return(hi);
|
||||
}
|
||||
|
||||
#define MB() asm volatile ("" : : : "memory")
|
||||
|
||||
#define XPROD32(a, b, t, v, x, y) \
|
||||
{ \
|
||||
long l; \
|
||||
asm( "smull %0, %1, %4, %6\n\t" \
|
||||
"smlal %0, %1, %5, %7\n\t" \
|
||||
"rsb %3, %4, #0\n\t" \
|
||||
"smull %0, %2, %5, %6\n\t" \
|
||||
"smlal %0, %2, %3, %7" \
|
||||
: "=&r" (l), "=&r" (x), "=&r" (y), "=r" ((a)) \
|
||||
: "3" ((a)), "r" ((b)), "r" ((t)), "r" ((v)) \
|
||||
: "cc" ); \
|
||||
}
|
||||
|
||||
static inline void XPROD31(int32_t a, int32_t b,
|
||||
int32_t t, int32_t v,
|
||||
int32_t *x, int32_t *y)
|
||||
{
|
||||
int x1, y1, l;
|
||||
asm( "smull %0, %1, %4, %6\n\t"
|
||||
"smlal %0, %1, %5, %7\n\t"
|
||||
"rsb %3, %4, #0\n\t"
|
||||
"smull %0, %2, %5, %6\n\t"
|
||||
"smlal %0, %2, %3, %7"
|
||||
: "=&r" (l), "=&r" (x1), "=&r" (y1), "=r" (a)
|
||||
: "3" (a), "r" (b), "r" (t), "r" (v)
|
||||
: "cc" );
|
||||
*x = x1 << 1;
|
||||
MB();
|
||||
*y = y1 << 1;
|
||||
}
|
||||
|
||||
static inline void XNPROD31(int32_t a, int32_t b,
|
||||
int32_t t, int32_t v,
|
||||
int32_t *x, int32_t *y)
|
||||
{
|
||||
int x1, y1, l;
|
||||
asm( "rsb %2, %4, #0\n\t"
|
||||
"smull %0, %1, %3, %5\n\t"
|
||||
"smlal %0, %1, %2, %6\n\t"
|
||||
"smull %0, %2, %4, %5\n\t"
|
||||
"smlal %0, %2, %3, %6"
|
||||
: "=&r" (l), "=&r" (x1), "=&r" (y1)
|
||||
: "r" (a), "r" (b), "r" (t), "r" (v)
|
||||
: "cc" );
|
||||
*x = x1 << 1;
|
||||
MB();
|
||||
*y = y1 << 1;
|
||||
}
|
||||
|
||||
#ifndef _V_VECT_OPS
|
||||
#define _V_VECT_OPS
|
||||
|
||||
/* asm versions of vector operations for block.c, window.c */
|
||||
static inline
|
||||
void vect_add(int32_t *x, int32_t *y, int n)
|
||||
{
|
||||
while (n>=4) {
|
||||
asm volatile ("ldmia %[x], {r0, r1, r2, r3};"
|
||||
"ldmia %[y]!, {r4, r5, r6, r7};"
|
||||
"add r0, r0, r4;"
|
||||
"add r1, r1, r5;"
|
||||
"add r2, r2, r6;"
|
||||
"add r3, r3, r7;"
|
||||
"stmia %[x]!, {r0, r1, r2, r3};"
|
||||
: [x] "+r" (x), [y] "+r" (y)
|
||||
: : "r0", "r1", "r2", "r3",
|
||||
"r4", "r5", "r6", "r7",
|
||||
"memory");
|
||||
n -= 4;
|
||||
}
|
||||
/* add final elements */
|
||||
while (n>0) {
|
||||
*x++ += *y++;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
static inline
|
||||
void vect_copy(int32_t *x, int32_t *y, int n)
|
||||
{
|
||||
while (n>=4) {
|
||||
asm volatile ("ldmia %[y]!, {r0, r1, r2, r3};"
|
||||
"stmia %[x]!, {r0, r1, r2, r3};"
|
||||
: [x] "+r" (x), [y] "+r" (y)
|
||||
: : "r0", "r1", "r2", "r3",
|
||||
"memory");
|
||||
n -= 4;
|
||||
}
|
||||
/* copy final elements */
|
||||
while (n>0) {
|
||||
*x++ = *y++;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
static inline
|
||||
void vect_mult_fw(int32_t *data, int32_t *window, int n)
|
||||
{
|
||||
while (n>=4) {
|
||||
asm volatile ("ldmia %[d], {r0, r1, r2, r3};"
|
||||
"ldmia %[w]!, {r4, r5, r6, r7};"
|
||||
"smull r8, r9, r0, r4;"
|
||||
"mov r0, r9, lsl #1;"
|
||||
"smull r8, r9, r1, r5;"
|
||||
"mov r1, r9, lsl #1;"
|
||||
"smull r8, r9, r2, r6;"
|
||||
"mov r2, r9, lsl #1;"
|
||||
"smull r8, r9, r3, r7;"
|
||||
"mov r3, r9, lsl #1;"
|
||||
"stmia %[d]!, {r0, r1, r2, r3};"
|
||||
: [d] "+r" (data), [w] "+r" (window)
|
||||
: : "r0", "r1", "r2", "r3",
|
||||
"r4", "r5", "r6", "r7", "r8", "r9",
|
||||
"memory", "cc");
|
||||
n -= 4;
|
||||
}
|
||||
while(n>0) {
|
||||
*data = MULT31(*data, *window);
|
||||
data++;
|
||||
window++;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
static inline
|
||||
void vect_mult_bw(int32_t *data, int32_t *window, int n)
|
||||
{
|
||||
while (n>=4) {
|
||||
asm volatile ("ldmia %[d], {r0, r1, r2, r3};"
|
||||
"ldmda %[w]!, {r4, r5, r6, r7};"
|
||||
"smull r8, r9, r0, r7;"
|
||||
"mov r0, r9, lsl #1;"
|
||||
"smull r8, r9, r1, r6;"
|
||||
"mov r1, r9, lsl #1;"
|
||||
"smull r8, r9, r2, r5;"
|
||||
"mov r2, r9, lsl #1;"
|
||||
"smull r8, r9, r3, r4;"
|
||||
"mov r3, r9, lsl #1;"
|
||||
"stmia %[d]!, {r0, r1, r2, r3};"
|
||||
: [d] "+r" (data), [w] "+r" (window)
|
||||
: : "r0", "r1", "r2", "r3",
|
||||
"r4", "r5", "r6", "r7", "r8", "r9",
|
||||
"memory", "cc");
|
||||
n -= 4;
|
||||
}
|
||||
while(n>0) {
|
||||
*data = MULT31(*data, *window);
|
||||
data++;
|
||||
window--;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _V_CLIP_MATH
|
||||
#define _V_CLIP_MATH
|
||||
|
||||
static inline int32_t CLIP_TO_15(int32_t x) {
|
||||
int tmp;
|
||||
asm volatile("subs %1, %0, #32768\n\t"
|
||||
"movpl %0, #0x7f00\n\t"
|
||||
"orrpl %0, %0, #0xff\n"
|
||||
"adds %1, %0, #32768\n\t"
|
||||
"movmi %0, #0x8000"
|
||||
: "+r"(x),"=r"(tmp)
|
||||
:
|
||||
: "cc");
|
||||
return(x);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _V_LSP_MATH_ASM
|
||||
#define _V_LSP_MATH_ASM
|
||||
#endif
|
||||
|
||||
#endif
|
||||
150
bsp/stm32_radio/libwma/bswap.h
Normal file
150
bsp/stm32_radio/libwma/bswap.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* @file bswap.h
|
||||
* byte swap.
|
||||
*/
|
||||
|
||||
#ifndef __BSWAP_H__
|
||||
#define __BSWAP_H__
|
||||
|
||||
#ifdef HAVE_BYTESWAP_H
|
||||
#include <byteswap.h>
|
||||
#else
|
||||
|
||||
#ifdef ROCKBOX
|
||||
#include "codecs.h"
|
||||
|
||||
/* rockbox' optimised inline functions */
|
||||
#define bswap_16(x) swap16(x)
|
||||
#define bswap_32(x) swap32(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)
|
||||
|
||||
#elif defined(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 WORDS_BIGENDIAN
|
||||
#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__ */
|
||||
79
bsp/stm32_radio/libwma/codeclib.h
Normal file
79
bsp/stm32_radio/libwma/codeclib.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: codeclib.h 19704 2009-01-07 09:53:46Z zagor $
|
||||
*
|
||||
* Copyright (C) 2005 Dave Chapman
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __CODECLIB_H__
|
||||
#define __CODECLIB_H__
|
||||
#include "ffmpeg_config.h"
|
||||
// #include "codecs.h"
|
||||
// #include <sys/types.h>
|
||||
|
||||
extern struct codec_api *ci;
|
||||
extern size_t mem_ptr;
|
||||
extern size_t bufsize;
|
||||
extern unsigned char* mp3buf; /* The actual MP3 buffer from Rockbox */
|
||||
extern unsigned char* mallocbuf; /* The free space after the codec in the codec buffer */
|
||||
extern unsigned char* filebuf; /* The rest of the MP3 buffer */
|
||||
|
||||
/* Standard library functions that are used by the codecs follow here */
|
||||
|
||||
/* Get these functions 'out of the way' of the standard functions. Not doing
|
||||
* so confuses the cygwin linker, and maybe others. These functions need to
|
||||
* be implemented elsewhere */
|
||||
#define malloc(x) codec_malloc(x)
|
||||
#define calloc(x,y) codec_calloc(x,y)
|
||||
#define realloc(x,y) codec_realloc(x,y)
|
||||
#define free(x) codec_free(x)
|
||||
#define alloca(x) __builtin_alloca(x)
|
||||
|
||||
void* codec_malloc(size_t size);
|
||||
void* codec_calloc(size_t nmemb, size_t size);
|
||||
void* codec_realloc(void* ptr, size_t size);
|
||||
void codec_free(void* ptr);
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
int memcmp(const void *s1, const void *s2, size_t n);
|
||||
void *memmove(void *s1, const void *s2, size_t n);
|
||||
|
||||
size_t strlen(const char *s);
|
||||
char *strcpy(char *dest, const char *src);
|
||||
char *strcat(char *dest, const char *src);
|
||||
int strcmp(const char *, const char *);
|
||||
|
||||
void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
|
||||
|
||||
#define abs(x) ((x)>0?(x):-(x))
|
||||
#define labs(x) abs(x)
|
||||
|
||||
/*MDCT library functions*/
|
||||
|
||||
extern void mdct_backward(int n, int32_t *in, int32_t *out);
|
||||
|
||||
#if defined(CPU_ARM) && (ARM_ARCH == 4)
|
||||
/* optimised unsigned integer division for ARMv4, in IRAM */
|
||||
unsigned udiv32_arm(unsigned a, unsigned b);
|
||||
#define UDIV32(a, b) udiv32_arm(a, b)
|
||||
#else
|
||||
/* default */
|
||||
#define UDIV32(a, b) (a / b)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
23
bsp/stm32_radio/libwma/ffmpeg_config.h
Normal file
23
bsp/stm32_radio/libwma/ffmpeg_config.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/* Automatically generated by configure - do not modify */
|
||||
#ifndef _FFMPEG_CONFIG_H
|
||||
#define _FFMPEG_CONFIG_H
|
||||
// #include "codecs.h"
|
||||
|
||||
#ifdef CPU_ARM
|
||||
#define CONFIG_ALIGN 1
|
||||
#endif
|
||||
|
||||
#ifdef ROCKBOX_BIG_ENDIAN
|
||||
#define WORDS_BIGENDIAN
|
||||
#endif
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define inline __inline
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
#define DEBUGF(fmt, ...)
|
||||
|
||||
#endif
|
||||
18
bsp/stm32_radio/libwma/libwma.make
Normal file
18
bsp/stm32_radio/libwma/libwma.make
Normal file
@@ -0,0 +1,18 @@
|
||||
# __________ __ ___.
|
||||
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
# \/ \/ \/ \/ \/
|
||||
# $Id: libwma.make 20151 2009-03-01 09:04:15Z amiconn $
|
||||
#
|
||||
|
||||
# libwma
|
||||
WMALIB := $(CODECDIR)/libwma.a
|
||||
WMALIB_SRC := $(call preprocess, $(APPSDIR)/codecs/libwma/SOURCES)
|
||||
WMALIB_OBJ := $(call c2obj, $(WMALIB_SRC))
|
||||
OTHER_SRC += $(WMALIB_SRC)
|
||||
|
||||
$(WMALIB): $(WMALIB_OBJ)
|
||||
$(SILENT)$(shell rm -f $@)
|
||||
$(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null
|
||||
518
bsp/stm32_radio/libwma/mdct2.c
Normal file
518
bsp/stm32_radio/libwma/mdct2.c
Normal file
File diff suppressed because it is too large
Load Diff
75
bsp/stm32_radio/libwma/mdct2.h
Normal file
75
bsp/stm32_radio/libwma/mdct2.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
|
||||
* *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
|
||||
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: modified discrete cosine transform prototypes
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#ifndef _OGG_mdct_H_
|
||||
#define _OGG_mdct_H_
|
||||
|
||||
#include "ffmpeg_config.h"
|
||||
|
||||
#ifdef _LOW_ACCURACY_
|
||||
# define X(n) (((((n)>>22)+1)>>1) - ((((n)>>22)+1)>>9))
|
||||
# //define LOOKUP_T const unsigned char
|
||||
#else
|
||||
# define X(n) (n)
|
||||
# //define LOOKUP_T const ogg_int32_t
|
||||
#endif
|
||||
|
||||
// #include <codecs.h>
|
||||
#include "asm_arm.h"
|
||||
// #include "asm_mcf5249.h"
|
||||
// #include "codeclib_misc.h"
|
||||
|
||||
#ifndef ICONST_ATTR_TREMOR_WINDOW
|
||||
#define ICONST_ATTR_TREMOR_WINDOW ICONST_ATTR
|
||||
#endif
|
||||
|
||||
#ifndef ICODE_ATTR_TREMOR_MDCT
|
||||
#define ICODE_ATTR_TREMOR_MDCT ICODE_ATTR
|
||||
#endif
|
||||
|
||||
#ifndef ICODE_ATTR_TREMOR_NOT_MDCT
|
||||
#define ICODE_ATTR_TREMOR_NOT_MDCT ICODE_ATTR
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef _LOW_ACCURACY_
|
||||
#define cPI3_8 (0x0062)
|
||||
#define cPI2_8 (0x00b5)
|
||||
#define cPI1_8 (0x00ed)
|
||||
#else
|
||||
#define cPI3_8 (0x30fbc54d)
|
||||
#define cPI2_8 (0x5a82799a)
|
||||
#define cPI1_8 (0x7641af3d)
|
||||
#endif
|
||||
|
||||
|
||||
extern void mdct_backward(int n, int32_t *in, int32_t *out);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
544
bsp/stm32_radio/libwma/mdct_lookup.h
Normal file
544
bsp/stm32_radio/libwma/mdct_lookup.h
Normal file
File diff suppressed because it is too large
Load Diff
4
bsp/stm32_radio/libwma/types.h
Normal file
4
bsp/stm32_radio/libwma/types.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#include "codeclib.h"
|
||||
|
||||
#define fixed32 int32_t
|
||||
#define fixed64 int64_t
|
||||
20
bsp/stm32_radio/libwma/wma_arm.S
Normal file
20
bsp/stm32_radio/libwma/wma_arm.S
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
MULT32
|
||||
ENDP
|
||||
|
||||
MULT31_SHIFT15
|
||||
ENDP
|
||||
|
||||
XPROD32
|
||||
ENDP
|
||||
|
||||
XPROD31
|
||||
ENDP
|
||||
|
||||
XNPROD31
|
||||
ENDP
|
||||
|
||||
CLIP_TO_15
|
||||
ENDP
|
||||
|
||||
END
|
||||
271
bsp/stm32_radio/libwma/wmabitstream.c
Normal file
271
bsp/stm32_radio/libwma/wmabitstream.c
Normal file
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Common bit i/o utils
|
||||
* Copyright (c) 2000, 2001 Fabrice Bellard.
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg 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 FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file bitstream.c
|
||||
* bitstream api.
|
||||
*/
|
||||
|
||||
#include "wmabitstream.h"
|
||||
#include "codeclib.h"
|
||||
|
||||
/**
|
||||
* Same as av_mallocz_static(), but does a realloc.
|
||||
*
|
||||
* @param[in] ptr The block of memory to reallocate.
|
||||
* @param[in] size The requested size.
|
||||
* @return Block of memory of requested size.
|
||||
* @deprecated. Code which uses ff_realloc_static is broken/missdesigned
|
||||
* and should correctly use static arrays
|
||||
*/
|
||||
attribute_deprecated void *ff_realloc_static(void *ptr, unsigned int size);
|
||||
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
void align_put_bits(PutBitContext *s)
|
||||
{
|
||||
#ifdef ALT_BITSTREAM_WRITER
|
||||
put_bits(s,( - s->index) & 7,0);
|
||||
#else
|
||||
put_bits(s,s->bit_left & 7,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ff_put_string(PutBitContext * pbc, char *s, int put_zero)
|
||||
{
|
||||
while(*s){
|
||||
put_bits(pbc, 8, *s);
|
||||
s++;
|
||||
}
|
||||
if(put_zero)
|
||||
put_bits(pbc, 8, 0);
|
||||
}
|
||||
|
||||
/* VLC decoding */
|
||||
|
||||
//#define DEBUG_VLC
|
||||
|
||||
#define GET_DATA(v, table, i, wrap, size) \
|
||||
{\
|
||||
const uint8_t *ptr = (const uint8_t *)table + i * wrap;\
|
||||
switch(size) {\
|
||||
case 1:\
|
||||
v = *(const uint8_t *)ptr;\
|
||||
break;\
|
||||
case 2:\
|
||||
v = *(const uint16_t *)ptr;\
|
||||
break;\
|
||||
default:\
|
||||
v = *(const uint32_t *)ptr;\
|
||||
break;\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
static int alloc_table(VLC *vlc, int size)
|
||||
{
|
||||
int index;
|
||||
index = vlc->table_size;
|
||||
vlc->table_size += size;
|
||||
if (vlc->table_size > vlc->table_allocated) {
|
||||
DEBUGF("Tried to allocate past the end of a Huffman table: %d/%d\n",
|
||||
vlc->table_allocated, vlc->table_allocated+(1 << vlc->bits));
|
||||
vlc->table_allocated += (1 << vlc->bits);
|
||||
if (!vlc->table)
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
static int build_table(VLC *vlc, int table_nb_bits,
|
||||
int nb_codes,
|
||||
const void *bits, int bits_wrap, int bits_size,
|
||||
const void *codes, int codes_wrap, int codes_size,
|
||||
uint32_t code_prefix, int n_prefix)
|
||||
{
|
||||
int i, j, k, n, table_size, table_index, nb, n1, index, code_prefix2;
|
||||
uint32_t code;
|
||||
int flags = 0;
|
||||
VLC_TYPE (*table)[2];
|
||||
|
||||
table_size = 1 << table_nb_bits;
|
||||
table_index = alloc_table(vlc, table_size);
|
||||
#ifdef DEBUG_VLC
|
||||
printf("new table index=%d size=%d code_prefix=%x n=%d\n",
|
||||
table_index, table_size, code_prefix, n_prefix);
|
||||
#endif
|
||||
if (table_index < 0)
|
||||
return -1;
|
||||
table = &vlc->table[table_index];
|
||||
|
||||
for(i=0;i<table_size;i++) {
|
||||
table[i][1] = 0; //bits
|
||||
table[i][0] = -1; //codes
|
||||
}
|
||||
|
||||
/* first pass: map codes and compute auxillary table sizes */
|
||||
for(i=0;i<nb_codes;i++) {
|
||||
GET_DATA(n, bits, i, bits_wrap, bits_size);
|
||||
GET_DATA(code, codes, i, codes_wrap, codes_size);
|
||||
/* we accept tables with holes */
|
||||
if (n <= 0)
|
||||
continue;
|
||||
#if defined(DEBUG_VLC) && 0
|
||||
printf("i=%d n=%d code=0x%x\n", i, n, code);
|
||||
#endif
|
||||
/* if code matches the prefix, it is in the table */
|
||||
n -= n_prefix;
|
||||
if(flags & INIT_VLC_LE)
|
||||
code_prefix2= code & (n_prefix>=32 ? 0xffffffff : (uint32_t)(1 << n_prefix)-1);
|
||||
else
|
||||
code_prefix2= code >> n;
|
||||
if (n > 0 && (int)code_prefix2 == (int)code_prefix) {
|
||||
if (n <= table_nb_bits) {
|
||||
/* no need to add another table */
|
||||
j = (code << (table_nb_bits - n)) & (table_size - 1);
|
||||
nb = 1 << (table_nb_bits - n);
|
||||
for(k=0;k<nb;k++) {
|
||||
if(flags & INIT_VLC_LE)
|
||||
j = (code >> n_prefix) + (k<<n);
|
||||
#ifdef DEBUG_VLC
|
||||
av_log(NULL, 0, "%4x: code=%d n=%d\n",
|
||||
j, i, n);
|
||||
#endif
|
||||
if (table[j][1] /*bits*/ != 0) {
|
||||
return -1;
|
||||
}
|
||||
table[j][1] = n; //bits
|
||||
table[j][0] = i; //code
|
||||
j++;
|
||||
}
|
||||
} else {
|
||||
n -= table_nb_bits;
|
||||
j = (code >> ((flags & INIT_VLC_LE) ? n_prefix : n)) & ((1 << table_nb_bits) - 1);
|
||||
#ifdef DEBUG_VLC
|
||||
av_log(NULL, 0,"%4x: n=%d (subtable)\n",
|
||||
j, n);
|
||||
#endif
|
||||
/* compute table size */
|
||||
n1 = -table[j][1]; //bits
|
||||
if (n > n1)
|
||||
n1 = n;
|
||||
table[j][1] = -n1; //bits
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* second pass : fill auxillary tables recursively */
|
||||
for(i=0;i<table_size;i++) {
|
||||
n = table[i][1]; //bits
|
||||
if (n < 0) {
|
||||
n = -n;
|
||||
if (n > table_nb_bits) {
|
||||
n = table_nb_bits;
|
||||
table[i][1] = -n; //bits
|
||||
}
|
||||
index = build_table(vlc, n, nb_codes,
|
||||
bits, bits_wrap, bits_size,
|
||||
codes, codes_wrap, codes_size,
|
||||
(flags & INIT_VLC_LE) ? (code_prefix | (i << n_prefix)) : ((code_prefix << table_nb_bits) | i),
|
||||
n_prefix + table_nb_bits);
|
||||
if (index < 0)
|
||||
return -1;
|
||||
/* note: realloc has been done, so reload tables */
|
||||
table = &vlc->table[table_index];
|
||||
table[i][0] = index; //code
|
||||
}
|
||||
}
|
||||
return table_index;
|
||||
}
|
||||
|
||||
|
||||
/* Build VLC decoding tables suitable for use with get_vlc().
|
||||
|
||||
'nb_bits' set thee decoding table size (2^nb_bits) entries. The
|
||||
bigger it is, the faster is the decoding. But it should not be too
|
||||
big to save memory and L1 cache. '9' is a good compromise.
|
||||
|
||||
'nb_codes' : number of vlcs codes
|
||||
|
||||
'bits' : table which gives the size (in bits) of each vlc code.
|
||||
|
||||
'codes' : table which gives the bit pattern of of each vlc code.
|
||||
|
||||
'xxx_wrap' : give the number of bytes between each entry of the
|
||||
'bits' or 'codes' tables.
|
||||
|
||||
'xxx_size' : gives the number of bytes of each entry of the 'bits'
|
||||
or 'codes' tables.
|
||||
|
||||
'wrap' and 'size' allows to use any memory configuration and types
|
||||
(byte/word/long) to store the 'bits' and 'codes' tables.
|
||||
|
||||
'use_static' should be set to 1 for tables, which should be freed
|
||||
with av_free_static(), 0 if free_vlc() will be used.
|
||||
*/
|
||||
int init_vlc(VLC *vlc, int nb_bits, int nb_codes,
|
||||
const void *bits, int bits_wrap, int bits_size,
|
||||
const void *codes, int codes_wrap, int codes_size,
|
||||
int flags)
|
||||
{
|
||||
|
||||
vlc->bits = nb_bits;
|
||||
vlc->table_size = 0;
|
||||
|
||||
#ifdef DEBUG_VLC
|
||||
printf("build table nb_codes=%d\n", nb_codes);
|
||||
#endif
|
||||
|
||||
if (build_table(vlc, nb_bits, nb_codes,
|
||||
bits, bits_wrap, bits_size,
|
||||
codes, codes_wrap, codes_size,
|
||||
0, 0) < 0) {
|
||||
//av_free(vlc->table);
|
||||
return -1;
|
||||
}
|
||||
/* return flags to block gcc warning while allowing us to keep
|
||||
* consistent with ffmpeg's function parameters
|
||||
*/
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
989
bsp/stm32_radio/libwma/wmabitstream.h
Normal file
989
bsp/stm32_radio/libwma/wmabitstream.h
Normal file
File diff suppressed because it is too large
Load Diff
2609
bsp/stm32_radio/libwma/wmadata.h
Normal file
2609
bsp/stm32_radio/libwma/wmadata.h
Normal file
File diff suppressed because it is too large
Load Diff
149
bsp/stm32_radio/libwma/wmadec.h
Normal file
149
bsp/stm32_radio/libwma/wmadec.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* WMA compatible decoder
|
||||
* Copyright (c) 2002 The FFmpeg Project.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _WMADEC_H
|
||||
#define _WMADEC_H
|
||||
|
||||
#include "asf.h"
|
||||
#include "wmabitstream.h" /* For GetBitContext */
|
||||
#include "types.h"
|
||||
|
||||
//#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 IRAM for targets with 48k/80k IRAM split*/
|
||||
#ifndef IBSS_ATTR_WMA_LARGE_IRAM
|
||||
#if (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
|
||||
/* PP5022/24 and MCF5250 have 128KB of IRAM, but only PP5022+ have 80KB allocated for codecs */
|
||||
#define IBSS_ATTR_WMA_LARGE_IRAM IBSS_ATTR
|
||||
#else
|
||||
/* other PP's and MCF5249 have 96KB of IRAM */
|
||||
#define IBSS_ATTR_WMA_LARGE_IRAM
|
||||
#endif
|
||||
#endif
|
||||
|
||||
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 */
|
||||
int exponents_bsize[MAX_CHANNELS]; // log2 ratio frame/exp. length
|
||||
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];
|
||||
fixed32 *windows[BLOCK_NB_SIZES];
|
||||
/* 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;
|
||||
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];
|
||||
fixed32 lsp_pow_m_table1[(1 << LSP_POW_BITS)];
|
||||
fixed32 lsp_pow_m_table2[(1 << LSP_POW_BITS)];
|
||||
|
||||
/* State of current superframe decoding */
|
||||
int bit_offset;
|
||||
int nb_frames;
|
||||
int current_frame;
|
||||
|
||||
#ifdef TRACE
|
||||
int frame_count;
|
||||
#endif
|
||||
} WMADecodeContext;
|
||||
|
||||
int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx);
|
||||
int wma_decode_superframe_init(WMADecodeContext* s, const uint8_t *buf, int buf_size);
|
||||
int wma_decode_superframe_frame(WMADecodeContext* s, int32_t *samples, const uint8_t *buf, int buf_size);
|
||||
|
||||
#endif
|
||||
1619
bsp/stm32_radio/libwma/wmadeci.c
Normal file
1619
bsp/stm32_radio/libwma/wmadeci.c
Normal file
File diff suppressed because it is too large
Load Diff
243
bsp/stm32_radio/libwma/wmafixed.c
Normal file
243
bsp/stm32_radio/libwma/wmafixed.c
Normal file
@@ -0,0 +1,243 @@
|
||||
/****************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* Copyright (C) 2007 Michael Giacomelli
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "wmadec.h"
|
||||
#include "wmafixed.h"
|
||||
// #include <codecs.h>
|
||||
|
||||
fixed64 IntTo64(int x){
|
||||
fixed64 res = 0;
|
||||
unsigned char *p = (unsigned char *)&res;
|
||||
|
||||
#ifdef ROCKBOX_BIG_ENDIAN
|
||||
p[5] = x & 0xff;
|
||||
p[4] = (x & 0xff00)>>8;
|
||||
p[3] = (x & 0xff0000)>>16;
|
||||
p[2] = (x & 0xff000000)>>24;
|
||||
#else
|
||||
p[2] = x & 0xff;
|
||||
p[3] = (x & 0xff00)>>8;
|
||||
p[4] = (x & 0xff0000)>>16;
|
||||
p[5] = (x & 0xff000000)>>24;
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
int IntFrom64(fixed64 x)
|
||||
{
|
||||
int res = 0;
|
||||
unsigned char *p = (unsigned char *)&x;
|
||||
|
||||
#ifdef ROCKBOX_BIG_ENDIAN
|
||||
res = p[5] | (p[4]<<8) | (p[3]<<16) | (p[2]<<24);
|
||||
#else
|
||||
res = p[2] | (p[3]<<8) | (p[4]<<16) | (p[5]<<24);
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
fixed32 Fixed32From64(fixed64 x)
|
||||
{
|
||||
return x & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
fixed64 Fixed32To64(fixed32 x)
|
||||
{
|
||||
return (fixed64)x;
|
||||
}
|
||||
|
||||
/*
|
||||
Not performance senstitive code here
|
||||
|
||||
*/
|
||||
|
||||
|
||||
fixed64 fixmul64byfixed(fixed64 x, fixed32 y)
|
||||
{
|
||||
|
||||
//return x * y;
|
||||
return (x * y);
|
||||
// return (fixed64) fixmul32(Fixed32From64(x),y);
|
||||
}
|
||||
|
||||
|
||||
fixed32 fixdiv32(fixed32 x, fixed32 y)
|
||||
{
|
||||
fixed64 temp;
|
||||
|
||||
if(x == 0)
|
||||
return 0;
|
||||
if(y == 0)
|
||||
return 0x7fffffff;
|
||||
temp = x;
|
||||
temp <<= PRECISION;
|
||||
return (fixed32)(temp / y);
|
||||
}
|
||||
|
||||
fixed64 fixdiv64(fixed64 x, fixed64 y)
|
||||
{
|
||||
fixed64 temp;
|
||||
|
||||
if(x == 0)
|
||||
return 0;
|
||||
if(y == 0)
|
||||
return 0x07ffffffffffffffLL;
|
||||
temp = x;
|
||||
temp <<= PRECISION64;
|
||||
return (fixed64)(temp / y);
|
||||
}
|
||||
|
||||
fixed32 fixsqrt32(fixed32 x)
|
||||
{
|
||||
|
||||
unsigned long r = 0, s, v = (unsigned long)x;
|
||||
|
||||
#define STEP(k) s = r + (1 << k * 2); r >>= 1; \
|
||||
if (s <= v) { v -= s; r |= (1 << k * 2); }
|
||||
|
||||
STEP(15);
|
||||
STEP(14);
|
||||
STEP(13);
|
||||
STEP(12);
|
||||
STEP(11);
|
||||
STEP(10);
|
||||
STEP(9);
|
||||
STEP(8);
|
||||
STEP(7);
|
||||
STEP(6);
|
||||
STEP(5);
|
||||
STEP(4);
|
||||
STEP(3);
|
||||
STEP(2);
|
||||
STEP(1);
|
||||
STEP(0);
|
||||
|
||||
return (fixed32)(r << (PRECISION / 2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Inverse gain of circular cordic rotation in s0.31 format. */
|
||||
static const long cordic_circular_gain = 0xb2458939; /* 0.607252929 */
|
||||
|
||||
/* Table of values of atan(2^-i) in 0.32 format fractions of pi where pi = 0xffffffff / 2 */
|
||||
static const unsigned long atan_table[] = {
|
||||
0x1fffffff, /* +0.785398163 (or pi/4) */
|
||||
0x12e4051d, /* +0.463647609 */
|
||||
0x09fb385b, /* +0.244978663 */
|
||||
0x051111d4, /* +0.124354995 */
|
||||
0x028b0d43, /* +0.062418810 */
|
||||
0x0145d7e1, /* +0.031239833 */
|
||||
0x00a2f61e, /* +0.015623729 */
|
||||
0x00517c55, /* +0.007812341 */
|
||||
0x0028be53, /* +0.003906230 */
|
||||
0x00145f2e, /* +0.001953123 */
|
||||
0x000a2f98, /* +0.000976562 */
|
||||
0x000517cc, /* +0.000488281 */
|
||||
0x00028be6, /* +0.000244141 */
|
||||
0x000145f3, /* +0.000122070 */
|
||||
0x0000a2f9, /* +0.000061035 */
|
||||
0x0000517c, /* +0.000030518 */
|
||||
0x000028be, /* +0.000015259 */
|
||||
0x0000145f, /* +0.000007629 */
|
||||
0x00000a2f, /* +0.000003815 */
|
||||
0x00000517, /* +0.000001907 */
|
||||
0x0000028b, /* +0.000000954 */
|
||||
0x00000145, /* +0.000000477 */
|
||||
0x000000a2, /* +0.000000238 */
|
||||
0x00000051, /* +0.000000119 */
|
||||
0x00000028, /* +0.000000060 */
|
||||
0x00000014, /* +0.000000030 */
|
||||
0x0000000a, /* +0.000000015 */
|
||||
0x00000005, /* +0.000000007 */
|
||||
0x00000002, /* +0.000000004 */
|
||||
0x00000001, /* +0.000000002 */
|
||||
0x00000000, /* +0.000000001 */
|
||||
0x00000000, /* +0.000000000 */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Below here functions do not use standard fixed precision!
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Implements sin and cos using CORDIC rotation.
|
||||
*
|
||||
* @param phase has range from 0 to 0xffffffff, representing 0 and
|
||||
* 2*pi respectively.
|
||||
* @param cos return address for cos
|
||||
* @return sin of phase, value is a signed value from LONG_MIN to LONG_MAX,
|
||||
* representing -1 and 1 respectively.
|
||||
*
|
||||
* Gives at least 24 bits precision (last 2-8 bits or so are probably off)
|
||||
*/
|
||||
long fsincos(unsigned long phase, fixed32 *cos)
|
||||
{
|
||||
int32_t x, x1, y, y1;
|
||||
unsigned long z, z1;
|
||||
int i;
|
||||
|
||||
/* Setup initial vector */
|
||||
x = cordic_circular_gain;
|
||||
y = 0;
|
||||
z = phase;
|
||||
|
||||
/* The phase has to be somewhere between 0..pi for this to work right */
|
||||
if (z < 0xffffffff / 4) {
|
||||
/* z in first quadrant, z += pi/2 to correct */
|
||||
x = -x;
|
||||
z += 0xffffffff / 4;
|
||||
} else if (z < 3 * (0xffffffff / 4)) {
|
||||
/* z in third quadrant, z -= pi/2 to correct */
|
||||
z -= 0xffffffff / 4;
|
||||
} else {
|
||||
/* z in fourth quadrant, z -= 3pi/2 to correct */
|
||||
x = -x;
|
||||
z -= 3 * (0xffffffff / 4);
|
||||
}
|
||||
|
||||
/* Each iteration adds roughly 1-bit of extra precision */
|
||||
for (i = 0; i < 31; i++) {
|
||||
x1 = x >> i;
|
||||
y1 = y >> i;
|
||||
z1 = atan_table[i];
|
||||
|
||||
/* Decided which direction to rotate vector. Pivot point is pi/2 */
|
||||
if (z >= 0xffffffff / 4) {
|
||||
x -= y1;
|
||||
y += x1;
|
||||
z -= z1;
|
||||
} else {
|
||||
x += y1;
|
||||
y -= x1;
|
||||
z += z1;
|
||||
}
|
||||
}
|
||||
|
||||
if (cos)
|
||||
*cos = x;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
144
bsp/stm32_radio/libwma/wmafixed.h
Normal file
144
bsp/stm32_radio/libwma/wmafixed.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/****************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* Copyright (C) 2007 Michael Giacomelli
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* fixed precision code. We use a combination of Sign 15.16 and Sign.31
|
||||
precision here.
|
||||
|
||||
The WMA decoder does not always follow this convention, and occasionally
|
||||
renormalizes values to other formats in order to maximize precision.
|
||||
However, only the two precisions above are provided in this file.
|
||||
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define PRECISION 16
|
||||
#define PRECISION64 16
|
||||
|
||||
|
||||
#define fixtof64(x) (float)((float)(x) / (float)(1 << PRECISION64)) //does not work on int64_t!
|
||||
#define ftofix32(x) ((fixed32)((x) * (float)(1 << PRECISION) + ((x) < 0 ? -0.5 : 0.5)))
|
||||
#define itofix64(x) (IntTo64(x))
|
||||
#define itofix32(x) ((x) << PRECISION)
|
||||
#define fixtoi32(x) ((x) >> PRECISION)
|
||||
#define fixtoi64(x) (IntFrom64(x))
|
||||
|
||||
|
||||
/*fixed functions*/
|
||||
|
||||
fixed64 IntTo64(int x);
|
||||
int IntFrom64(fixed64 x);
|
||||
fixed32 Fixed32From64(fixed64 x);
|
||||
fixed64 Fixed32To64(fixed32 x);
|
||||
fixed64 fixmul64byfixed(fixed64 x, fixed32 y);
|
||||
fixed32 fixdiv32(fixed32 x, fixed32 y);
|
||||
fixed64 fixdiv64(fixed64 x, fixed64 y);
|
||||
fixed32 fixsqrt32(fixed32 x);
|
||||
long fsincos(unsigned long phase, fixed32 *cos);
|
||||
|
||||
#ifdef CPU_ARM
|
||||
|
||||
/*Sign-15.16 format */
|
||||
|
||||
#define fixmul32(x, y) \
|
||||
({ int32_t __hi; \
|
||||
uint32_t __lo; \
|
||||
int32_t __result; \
|
||||
asm ("smull %0, %1, %3, %4\n\t" \
|
||||
"movs %0, %0, lsr %5\n\t" \
|
||||
"adc %2, %0, %1, lsl %6" \
|
||||
: "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
|
||||
: "%r" (x), "r" (y), \
|
||||
"M" (PRECISION), "M" (32 - PRECISION) \
|
||||
: "cc"); \
|
||||
__result; \
|
||||
})
|
||||
|
||||
#define fixmul32b(x, y) \
|
||||
({ int32_t __hi; \
|
||||
uint32_t __lo; \
|
||||
int32_t __result; \
|
||||
asm ("smull %0, %1, %3, %4\n\t" \
|
||||
"movs %2, %1, lsl #1" \
|
||||
: "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
|
||||
: "%r" (x), "r" (y) \
|
||||
: "cc"); \
|
||||
__result; \
|
||||
})
|
||||
|
||||
#elif defined(CPU_COLDFIRE)
|
||||
|
||||
static inline int32_t fixmul32(int32_t x, int32_t y)
|
||||
{
|
||||
#if PRECISION != 16
|
||||
#warning Coldfire fixmul32() only works for PRECISION == 16
|
||||
#endif
|
||||
int32_t t1;
|
||||
asm (
|
||||
"mac.l %[x], %[y], %%acc0 \n" /* multiply */
|
||||
"mulu.l %[y], %[x] \n" /* get lower half, avoid emac stall */
|
||||
"movclr.l %%acc0, %[t1] \n" /* get higher half */
|
||||
"lsr.l #1, %[t1] \n"
|
||||
"move.w %[t1], %[x] \n"
|
||||
"swap %[x] \n"
|
||||
: [t1] "=&d" (t1), [x] "+d" (x)
|
||||
: [y] "d" (y)
|
||||
);
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline int32_t fixmul32b(int32_t x, int32_t y)
|
||||
{
|
||||
asm (
|
||||
"mac.l %[x], %[y], %%acc0 \n" /* multiply */
|
||||
"movclr.l %%acc0, %[x] \n" /* get higher half */
|
||||
: [x] "+d" (x)
|
||||
: [y] "d" (y)
|
||||
);
|
||||
return x;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline fixed32 fixmul32(fixed32 x, fixed32 y)
|
||||
{
|
||||
fixed64 temp;
|
||||
temp = x;
|
||||
temp *= y;
|
||||
|
||||
temp >>= PRECISION;
|
||||
|
||||
return (fixed32)temp;
|
||||
}
|
||||
|
||||
static inline fixed32 fixmul32b(fixed32 x, fixed32 y)
|
||||
{
|
||||
fixed64 temp;
|
||||
|
||||
temp = x;
|
||||
temp *= y;
|
||||
|
||||
temp >>= 31; //16+31-16 = 31 bits
|
||||
|
||||
return (fixed32)temp;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user