Correct rtl8710.ocd (use new). Simple main program.

Simplified mainf program (removed MP3 stuff).

Corrected rtl8710.ocd by downloading and compiling new one
from https://bitbucket.org/rebane/rtl8710_openocd/src

Signed-off-by: Drasko DRASKOVIC <drasko.draskovic@gmail.com>
This commit is contained in:
Drasko DRASKOVIC 2017-05-14 19:42:02 +02:00
parent eeb7f808ae
commit 50678283f7
43 changed files with 120 additions and 24195 deletions

View file

@ -26,29 +26,4 @@ CFLAGS += -DLOGUART_STACK_SIZE=1024
#============================================= #=============================================
#user main #user main
ADD_SRC_C += project/src/user/main.c ADD_SRC_C += project/src/user/main.c
# components
ADD_SRC_C += project/src/user/wifi_console.c
ADD_SRC_C += project/src/user/atcmd_user.c
ADD_SRC_C += project/src/user/spiram_fifo.c
#lib mad
ADD_SRC_C += project/src/mad/mad_version.c
ADD_SRC_C += project/src/mad/mpg12/layer12.c
ADD_SRC_C += project/src/mad/frame.c
ADD_SRC_C += project/src/mad/layer3.c
ADD_SRC_C += project/src/mad/align.c
ADD_SRC_C += project/src/mad/decoder.c
ADD_SRC_C += project/src/mad/huffman.c
ADD_SRC_C += project/src/mad/fixed.c
ADD_SRC_C += project/src/mad/bit.c
ADD_SRC_C += project/src/mad/synth.c
ADD_SRC_C += project/src/mad/timer.c
ADD_SRC_C += project/src/mad/stream.c
#driver
ADD_SRC_C += project/src/driver/i2s_freertos.c
#include
INCLUDES += project/inc/mad

View file

@ -1,46 +0,0 @@
#ifndef _I2S_FREERTOS_H_
#define _I2S_FREERTOS_H_
#include "i2s_api.h"
#include "user/playerconfig.h"
#define I2S_DMA_PAGE_WAIT_MS_MIN 4 // 8 // min 2 ms (CPU CLK 166), min 4 ms (CPU CLK 83),
#define I2S_DMA_PAGE_SIZE_MS_96K (96000/1000) // in sizeof(u32)
#define I2S_DMA_PAGE_NUM 4 // Valid number is 2~4
#define I2S0_SCLK_PIN PE_1 // PD_1
#define I2S0_WS_PIN PE_0 // PD_0
#define I2S0_SD_PIN PE_2 // PD_2
#define I2S1_SCLK_PIN PC_1
#define I2S1_WS_PIN PC_0
#define I2S1_SD_PIN PC_2
#define I2S_DEBUG_LEVEL 0
typedef struct _I2S_OBJS_ {
i2s_t i2s_obj;
u32 *currDMABuff; // Current DMA buffer we're writing to
u32 currDMABuffPos; // Current position in that DMA buffer
s32 sampl_err;
#if I2S_DEBUG_LEVEL > 1
u32 underrunCnt; // DMA underrun counter
#endif
}I2S_OBJS, *PI2S_OBJS;
#define MAX_I2S_OBJS 2
#define I2S0_OBJSN 0
#define I2S1_OBJSN 1
//extern PI2S_OBJS pi2s[MAX_I2S_OBJS]; // I2S0, I2S1
int i2sInit(int mask, int bufsize, int word_len); // word_len = WL_16b or WL_24b
void i2sClose(int mask);
char i2sSetRate(int mask, int rate);
u32 i2sPushPWMSamples(u32 sample);
#if I2S_DEBUG_LEVEL > 1
long i2sGetUnderrunCnt(int num);
#endif
#endif

View file

@ -1,607 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: D.dat,v 1.9 2004/01/23 09:41:32 rob Exp $
*/
/*
* These are the coefficients for the subband synthesis window. This is a
* reordered version of Table B.3 from ISO/IEC 11172-3.
*
* Every value is parameterized so that shift optimizations can be made at
* compile-time. For example, every value can be right-shifted 12 bits to
* minimize multiply instruction times without any loss of accuracy.
*/
{ PRESHIFT(0x00000000) /* 0.000000000 */, /* 0 */
-PRESHIFT(0x0001d000) /* -0.000442505 */,
PRESHIFT(0x000d5000) /* 0.003250122 */,
-PRESHIFT(0x001cb000) /* -0.007003784 */,
PRESHIFT(0x007f5000) /* 0.031082153 */,
-PRESHIFT(0x01421000) /* -0.078628540 */,
PRESHIFT(0x019ae000) /* 0.100311279 */,
-PRESHIFT(0x09271000) /* -0.572036743 */,
PRESHIFT(0x1251e000) /* 1.144989014 */,
PRESHIFT(0x09271000) /* 0.572036743 */,
PRESHIFT(0x019ae000) /* 0.100311279 */,
PRESHIFT(0x01421000) /* 0.078628540 */,
PRESHIFT(0x007f5000) /* 0.031082153 */,
PRESHIFT(0x001cb000) /* 0.007003784 */,
PRESHIFT(0x000d5000) /* 0.003250122 */,
PRESHIFT(0x0001d000) /* 0.000442505 */,
PRESHIFT(0x00000000) /* 0.000000000 */,
-PRESHIFT(0x0001d000) /* -0.000442505 */,
PRESHIFT(0x000d5000) /* 0.003250122 */,
-PRESHIFT(0x001cb000) /* -0.007003784 */,
PRESHIFT(0x007f5000) /* 0.031082153 */,
-PRESHIFT(0x01421000) /* -0.078628540 */,
PRESHIFT(0x019ae000) /* 0.100311279 */,
-PRESHIFT(0x09271000) /* -0.572036743 */,
PRESHIFT(0x1251e000) /* 1.144989014 */,
PRESHIFT(0x09271000) /* 0.572036743 */,
PRESHIFT(0x019ae000) /* 0.100311279 */,
PRESHIFT(0x01421000) /* 0.078628540 */,
PRESHIFT(0x007f5000) /* 0.031082153 */,
PRESHIFT(0x001cb000) /* 0.007003784 */,
PRESHIFT(0x000d5000) /* 0.003250122 */,
PRESHIFT(0x0001d000) /* 0.000442505 */ },
{ -PRESHIFT(0x00001000) /* -0.000015259 */, /* 1 */
-PRESHIFT(0x0001f000) /* -0.000473022 */,
PRESHIFT(0x000da000) /* 0.003326416 */,
-PRESHIFT(0x00207000) /* -0.007919312 */,
PRESHIFT(0x007d0000) /* 0.030517578 */,
-PRESHIFT(0x0158d000) /* -0.084182739 */,
PRESHIFT(0x01747000) /* 0.090927124 */,
-PRESHIFT(0x099a8000) /* -0.600219727 */,
PRESHIFT(0x124f0000) /* 1.144287109 */,
PRESHIFT(0x08b38000) /* 0.543823242 */,
PRESHIFT(0x01bde000) /* 0.108856201 */,
PRESHIFT(0x012b4000) /* 0.073059082 */,
PRESHIFT(0x0080f000) /* 0.031478882 */,
PRESHIFT(0x00191000) /* 0.006118774 */,
PRESHIFT(0x000d0000) /* 0.003173828 */,
PRESHIFT(0x0001a000) /* 0.000396729 */,
-PRESHIFT(0x00001000) /* -0.000015259 */,
-PRESHIFT(0x0001f000) /* -0.000473022 */,
PRESHIFT(0x000da000) /* 0.003326416 */,
-PRESHIFT(0x00207000) /* -0.007919312 */,
PRESHIFT(0x007d0000) /* 0.030517578 */,
-PRESHIFT(0x0158d000) /* -0.084182739 */,
PRESHIFT(0x01747000) /* 0.090927124 */,
-PRESHIFT(0x099a8000) /* -0.600219727 */,
PRESHIFT(0x124f0000) /* 1.144287109 */,
PRESHIFT(0x08b38000) /* 0.543823242 */,
PRESHIFT(0x01bde000) /* 0.108856201 */,
PRESHIFT(0x012b4000) /* 0.073059082 */,
PRESHIFT(0x0080f000) /* 0.031478882 */,
PRESHIFT(0x00191000) /* 0.006118774 */,
PRESHIFT(0x000d0000) /* 0.003173828 */,
PRESHIFT(0x0001a000) /* 0.000396729 */ },
{ -PRESHIFT(0x00001000) /* -0.000015259 */, /* 2 */
-PRESHIFT(0x00023000) /* -0.000534058 */,
PRESHIFT(0x000de000) /* 0.003387451 */,
-PRESHIFT(0x00245000) /* -0.008865356 */,
PRESHIFT(0x007a0000) /* 0.029785156 */,
-PRESHIFT(0x016f7000) /* -0.089706421 */,
PRESHIFT(0x014a8000) /* 0.080688477 */,
-PRESHIFT(0x0a0d8000) /* -0.628295898 */,
PRESHIFT(0x12468000) /* 1.142211914 */,
PRESHIFT(0x083ff000) /* 0.515609741 */,
PRESHIFT(0x01dd8000) /* 0.116577148 */,
PRESHIFT(0x01149000) /* 0.067520142 */,
PRESHIFT(0x00820000) /* 0.031738281 */,
PRESHIFT(0x0015b000) /* 0.005294800 */,
PRESHIFT(0x000ca000) /* 0.003082275 */,
PRESHIFT(0x00018000) /* 0.000366211 */,
-PRESHIFT(0x00001000) /* -0.000015259 */,
-PRESHIFT(0x00023000) /* -0.000534058 */,
PRESHIFT(0x000de000) /* 0.003387451 */,
-PRESHIFT(0x00245000) /* -0.008865356 */,
PRESHIFT(0x007a0000) /* 0.029785156 */,
-PRESHIFT(0x016f7000) /* -0.089706421 */,
PRESHIFT(0x014a8000) /* 0.080688477 */,
-PRESHIFT(0x0a0d8000) /* -0.628295898 */,
PRESHIFT(0x12468000) /* 1.142211914 */,
PRESHIFT(0x083ff000) /* 0.515609741 */,
PRESHIFT(0x01dd8000) /* 0.116577148 */,
PRESHIFT(0x01149000) /* 0.067520142 */,
PRESHIFT(0x00820000) /* 0.031738281 */,
PRESHIFT(0x0015b000) /* 0.005294800 */,
PRESHIFT(0x000ca000) /* 0.003082275 */,
PRESHIFT(0x00018000) /* 0.000366211 */ },
{ -PRESHIFT(0x00001000) /* -0.000015259 */, /* 3 */
-PRESHIFT(0x00026000) /* -0.000579834 */,
PRESHIFT(0x000e1000) /* 0.003433228 */,
-PRESHIFT(0x00285000) /* -0.009841919 */,
PRESHIFT(0x00765000) /* 0.028884888 */,
-PRESHIFT(0x0185d000) /* -0.095169067 */,
PRESHIFT(0x011d1000) /* 0.069595337 */,
-PRESHIFT(0x0a7fe000) /* -0.656219482 */,
PRESHIFT(0x12386000) /* 1.138763428 */,
PRESHIFT(0x07ccb000) /* 0.487472534 */,
PRESHIFT(0x01f9c000) /* 0.123474121 */,
PRESHIFT(0x00fdf000) /* 0.061996460 */,
PRESHIFT(0x00827000) /* 0.031845093 */,
PRESHIFT(0x00126000) /* 0.004486084 */,
PRESHIFT(0x000c4000) /* 0.002990723 */,
PRESHIFT(0x00015000) /* 0.000320435 */,
-PRESHIFT(0x00001000) /* -0.000015259 */,
-PRESHIFT(0x00026000) /* -0.000579834 */,
PRESHIFT(0x000e1000) /* 0.003433228 */,
-PRESHIFT(0x00285000) /* -0.009841919 */,
PRESHIFT(0x00765000) /* 0.028884888 */,
-PRESHIFT(0x0185d000) /* -0.095169067 */,
PRESHIFT(0x011d1000) /* 0.069595337 */,
-PRESHIFT(0x0a7fe000) /* -0.656219482 */,
PRESHIFT(0x12386000) /* 1.138763428 */,
PRESHIFT(0x07ccb000) /* 0.487472534 */,
PRESHIFT(0x01f9c000) /* 0.123474121 */,
PRESHIFT(0x00fdf000) /* 0.061996460 */,
PRESHIFT(0x00827000) /* 0.031845093 */,
PRESHIFT(0x00126000) /* 0.004486084 */,
PRESHIFT(0x000c4000) /* 0.002990723 */,
PRESHIFT(0x00015000) /* 0.000320435 */ },
{ -PRESHIFT(0x00001000) /* -0.000015259 */, /* 4 */
-PRESHIFT(0x00029000) /* -0.000625610 */,
PRESHIFT(0x000e3000) /* 0.003463745 */,
-PRESHIFT(0x002c7000) /* -0.010848999 */,
PRESHIFT(0x0071e000) /* 0.027801514 */,
-PRESHIFT(0x019bd000) /* -0.100540161 */,
PRESHIFT(0x00ec0000) /* 0.057617187 */,
-PRESHIFT(0x0af15000) /* -0.683914185 */,
PRESHIFT(0x12249000) /* 1.133926392 */,
PRESHIFT(0x075a0000) /* 0.459472656 */,
PRESHIFT(0x0212c000) /* 0.129577637 */,
PRESHIFT(0x00e79000) /* 0.056533813 */,
PRESHIFT(0x00825000) /* 0.031814575 */,
PRESHIFT(0x000f4000) /* 0.003723145 */,
PRESHIFT(0x000be000) /* 0.002899170 */,
PRESHIFT(0x00013000) /* 0.000289917 */,
-PRESHIFT(0x00001000) /* -0.000015259 */,
-PRESHIFT(0x00029000) /* -0.000625610 */,
PRESHIFT(0x000e3000) /* 0.003463745 */,
-PRESHIFT(0x002c7000) /* -0.010848999 */,
PRESHIFT(0x0071e000) /* 0.027801514 */,
-PRESHIFT(0x019bd000) /* -0.100540161 */,
PRESHIFT(0x00ec0000) /* 0.057617187 */,
-PRESHIFT(0x0af15000) /* -0.683914185 */,
PRESHIFT(0x12249000) /* 1.133926392 */,
PRESHIFT(0x075a0000) /* 0.459472656 */,
PRESHIFT(0x0212c000) /* 0.129577637 */,
PRESHIFT(0x00e79000) /* 0.056533813 */,
PRESHIFT(0x00825000) /* 0.031814575 */,
PRESHIFT(0x000f4000) /* 0.003723145 */,
PRESHIFT(0x000be000) /* 0.002899170 */,
PRESHIFT(0x00013000) /* 0.000289917 */ },
{ -PRESHIFT(0x00001000) /* -0.000015259 */, /* 5 */
-PRESHIFT(0x0002d000) /* -0.000686646 */,
PRESHIFT(0x000e4000) /* 0.003479004 */,
-PRESHIFT(0x0030b000) /* -0.011886597 */,
PRESHIFT(0x006cb000) /* 0.026535034 */,
-PRESHIFT(0x01b17000) /* -0.105819702 */,
PRESHIFT(0x00b77000) /* 0.044784546 */,
-PRESHIFT(0x0b619000) /* -0.711318970 */,
PRESHIFT(0x120b4000) /* 1.127746582 */,
PRESHIFT(0x06e81000) /* 0.431655884 */,
PRESHIFT(0x02288000) /* 0.134887695 */,
PRESHIFT(0x00d17000) /* 0.051132202 */,
PRESHIFT(0x0081b000) /* 0.031661987 */,
PRESHIFT(0x000c5000) /* 0.003005981 */,
PRESHIFT(0x000b7000) /* 0.002792358 */,
PRESHIFT(0x00011000) /* 0.000259399 */,
-PRESHIFT(0x00001000) /* -0.000015259 */,
-PRESHIFT(0x0002d000) /* -0.000686646 */,
PRESHIFT(0x000e4000) /* 0.003479004 */,
-PRESHIFT(0x0030b000) /* -0.011886597 */,
PRESHIFT(0x006cb000) /* 0.026535034 */,
-PRESHIFT(0x01b17000) /* -0.105819702 */,
PRESHIFT(0x00b77000) /* 0.044784546 */,
-PRESHIFT(0x0b619000) /* -0.711318970 */,
PRESHIFT(0x120b4000) /* 1.127746582 */,
PRESHIFT(0x06e81000) /* 0.431655884 */,
PRESHIFT(0x02288000) /* 0.134887695 */,
PRESHIFT(0x00d17000) /* 0.051132202 */,
PRESHIFT(0x0081b000) /* 0.031661987 */,
PRESHIFT(0x000c5000) /* 0.003005981 */,
PRESHIFT(0x000b7000) /* 0.002792358 */,
PRESHIFT(0x00011000) /* 0.000259399 */ },
{ -PRESHIFT(0x00001000) /* -0.000015259 */, /* 6 */
-PRESHIFT(0x00031000) /* -0.000747681 */,
PRESHIFT(0x000e4000) /* 0.003479004 */,
-PRESHIFT(0x00350000) /* -0.012939453 */,
PRESHIFT(0x0066c000) /* 0.025085449 */,
-PRESHIFT(0x01c67000) /* -0.110946655 */,
PRESHIFT(0x007f5000) /* 0.031082153 */,
-PRESHIFT(0x0bd06000) /* -0.738372803 */,
PRESHIFT(0x11ec7000) /* 1.120223999 */,
PRESHIFT(0x06772000) /* 0.404083252 */,
PRESHIFT(0x023b3000) /* 0.139450073 */,
PRESHIFT(0x00bbc000) /* 0.045837402 */,
PRESHIFT(0x00809000) /* 0.031387329 */,
PRESHIFT(0x00099000) /* 0.002334595 */,
PRESHIFT(0x000b0000) /* 0.002685547 */,
PRESHIFT(0x00010000) /* 0.000244141 */,
-PRESHIFT(0x00001000) /* -0.000015259 */,
-PRESHIFT(0x00031000) /* -0.000747681 */,
PRESHIFT(0x000e4000) /* 0.003479004 */,
-PRESHIFT(0x00350000) /* -0.012939453 */,
PRESHIFT(0x0066c000) /* 0.025085449 */,
-PRESHIFT(0x01c67000) /* -0.110946655 */,
PRESHIFT(0x007f5000) /* 0.031082153 */,
-PRESHIFT(0x0bd06000) /* -0.738372803 */,
PRESHIFT(0x11ec7000) /* 1.120223999 */,
PRESHIFT(0x06772000) /* 0.404083252 */,
PRESHIFT(0x023b3000) /* 0.139450073 */,
PRESHIFT(0x00bbc000) /* 0.045837402 */,
PRESHIFT(0x00809000) /* 0.031387329 */,
PRESHIFT(0x00099000) /* 0.002334595 */,
PRESHIFT(0x000b0000) /* 0.002685547 */,
PRESHIFT(0x00010000) /* 0.000244141 */ },
{ -PRESHIFT(0x00002000) /* -0.000030518 */, /* 7 */
-PRESHIFT(0x00035000) /* -0.000808716 */,
PRESHIFT(0x000e3000) /* 0.003463745 */,
-PRESHIFT(0x00397000) /* -0.014022827 */,
PRESHIFT(0x005ff000) /* 0.023422241 */,
-PRESHIFT(0x01dad000) /* -0.115921021 */,
PRESHIFT(0x0043a000) /* 0.016510010 */,
-PRESHIFT(0x0c3d9000) /* -0.765029907 */,
PRESHIFT(0x11c83000) /* 1.111373901 */,
PRESHIFT(0x06076000) /* 0.376800537 */,
PRESHIFT(0x024ad000) /* 0.143264771 */,
PRESHIFT(0x00a67000) /* 0.040634155 */,
PRESHIFT(0x007f0000) /* 0.031005859 */,
PRESHIFT(0x0006f000) /* 0.001693726 */,
PRESHIFT(0x000a9000) /* 0.002578735 */,
PRESHIFT(0x0000e000) /* 0.000213623 */,
-PRESHIFT(0x00002000) /* -0.000030518 */,
-PRESHIFT(0x00035000) /* -0.000808716 */,
PRESHIFT(0x000e3000) /* 0.003463745 */,
-PRESHIFT(0x00397000) /* -0.014022827 */,
PRESHIFT(0x005ff000) /* 0.023422241 */,
-PRESHIFT(0x01dad000) /* -0.115921021 */,
PRESHIFT(0x0043a000) /* 0.016510010 */,
-PRESHIFT(0x0c3d9000) /* -0.765029907 */,
PRESHIFT(0x11c83000) /* 1.111373901 */,
PRESHIFT(0x06076000) /* 0.376800537 */,
PRESHIFT(0x024ad000) /* 0.143264771 */,
PRESHIFT(0x00a67000) /* 0.040634155 */,
PRESHIFT(0x007f0000) /* 0.031005859 */,
PRESHIFT(0x0006f000) /* 0.001693726 */,
PRESHIFT(0x000a9000) /* 0.002578735 */,
PRESHIFT(0x0000e000) /* 0.000213623 */ },
{ -PRESHIFT(0x00002000) /* -0.000030518 */, /* 8 */
-PRESHIFT(0x0003a000) /* -0.000885010 */,
PRESHIFT(0x000e0000) /* 0.003417969 */,
-PRESHIFT(0x003df000) /* -0.015121460 */,
PRESHIFT(0x00586000) /* 0.021575928 */,
-PRESHIFT(0x01ee6000) /* -0.120697021 */,
PRESHIFT(0x00046000) /* 0.001068115 */,
-PRESHIFT(0x0ca8d000) /* -0.791213989 */,
PRESHIFT(0x119e9000) /* 1.101211548 */,
PRESHIFT(0x05991000) /* 0.349868774 */,
PRESHIFT(0x02578000) /* 0.146362305 */,
PRESHIFT(0x0091a000) /* 0.035552979 */,
PRESHIFT(0x007d1000) /* 0.030532837 */,
PRESHIFT(0x00048000) /* 0.001098633 */,
PRESHIFT(0x000a1000) /* 0.002456665 */,
PRESHIFT(0x0000d000) /* 0.000198364 */,
-PRESHIFT(0x00002000) /* -0.000030518 */,
-PRESHIFT(0x0003a000) /* -0.000885010 */,
PRESHIFT(0x000e0000) /* 0.003417969 */,
-PRESHIFT(0x003df000) /* -0.015121460 */,
PRESHIFT(0x00586000) /* 0.021575928 */,
-PRESHIFT(0x01ee6000) /* -0.120697021 */,
PRESHIFT(0x00046000) /* 0.001068115 */,
-PRESHIFT(0x0ca8d000) /* -0.791213989 */,
PRESHIFT(0x119e9000) /* 1.101211548 */,
PRESHIFT(0x05991000) /* 0.349868774 */,
PRESHIFT(0x02578000) /* 0.146362305 */,
PRESHIFT(0x0091a000) /* 0.035552979 */,
PRESHIFT(0x007d1000) /* 0.030532837 */,
PRESHIFT(0x00048000) /* 0.001098633 */,
PRESHIFT(0x000a1000) /* 0.002456665 */,
PRESHIFT(0x0000d000) /* 0.000198364 */ },
{ -PRESHIFT(0x00002000) /* -0.000030518 */, /* 9 */
-PRESHIFT(0x0003f000) /* -0.000961304 */,
PRESHIFT(0x000dd000) /* 0.003372192 */,
-PRESHIFT(0x00428000) /* -0.016235352 */,
PRESHIFT(0x00500000) /* 0.019531250 */,
-PRESHIFT(0x02011000) /* -0.125259399 */,
-PRESHIFT(0x003e6000) /* -0.015228271 */,
-PRESHIFT(0x0d11e000) /* -0.816864014 */,
PRESHIFT(0x116fc000) /* 1.089782715 */,
PRESHIFT(0x052c5000) /* 0.323318481 */,
PRESHIFT(0x02616000) /* 0.148773193 */,
PRESHIFT(0x007d6000) /* 0.030609131 */,
PRESHIFT(0x007aa000) /* 0.029937744 */,
PRESHIFT(0x00024000) /* 0.000549316 */,
PRESHIFT(0x0009a000) /* 0.002349854 */,
PRESHIFT(0x0000b000) /* 0.000167847 */,
-PRESHIFT(0x00002000) /* -0.000030518 */,
-PRESHIFT(0x0003f000) /* -0.000961304 */,
PRESHIFT(0x000dd000) /* 0.003372192 */,
-PRESHIFT(0x00428000) /* -0.016235352 */,
PRESHIFT(0x00500000) /* 0.019531250 */,
-PRESHIFT(0x02011000) /* -0.125259399 */,
-PRESHIFT(0x003e6000) /* -0.015228271 */,
-PRESHIFT(0x0d11e000) /* -0.816864014 */,
PRESHIFT(0x116fc000) /* 1.089782715 */,
PRESHIFT(0x052c5000) /* 0.323318481 */,
PRESHIFT(0x02616000) /* 0.148773193 */,
PRESHIFT(0x007d6000) /* 0.030609131 */,
PRESHIFT(0x007aa000) /* 0.029937744 */,
PRESHIFT(0x00024000) /* 0.000549316 */,
PRESHIFT(0x0009a000) /* 0.002349854 */,
PRESHIFT(0x0000b000) /* 0.000167847 */ },
{ -PRESHIFT(0x00002000) /* -0.000030518 */, /* 10 */
-PRESHIFT(0x00044000) /* -0.001037598 */,
PRESHIFT(0x000d7000) /* 0.003280640 */,
-PRESHIFT(0x00471000) /* -0.017349243 */,
PRESHIFT(0x0046b000) /* 0.017257690 */,
-PRESHIFT(0x0212b000) /* -0.129562378 */,
-PRESHIFT(0x0084a000) /* -0.032379150 */,
-PRESHIFT(0x0d78a000) /* -0.841949463 */,
PRESHIFT(0x113be000) /* 1.077117920 */,
PRESHIFT(0x04c16000) /* 0.297210693 */,
PRESHIFT(0x02687000) /* 0.150497437 */,
PRESHIFT(0x0069c000) /* 0.025817871 */,
PRESHIFT(0x0077f000) /* 0.029281616 */,
PRESHIFT(0x00002000) /* 0.000030518 */,
PRESHIFT(0x00093000) /* 0.002243042 */,
PRESHIFT(0x0000a000) /* 0.000152588 */,
-PRESHIFT(0x00002000) /* -0.000030518 */,
-PRESHIFT(0x00044000) /* -0.001037598 */,
PRESHIFT(0x000d7000) /* 0.003280640 */,
-PRESHIFT(0x00471000) /* -0.017349243 */,
PRESHIFT(0x0046b000) /* 0.017257690 */,
-PRESHIFT(0x0212b000) /* -0.129562378 */,
-PRESHIFT(0x0084a000) /* -0.032379150 */,
-PRESHIFT(0x0d78a000) /* -0.841949463 */,
PRESHIFT(0x113be000) /* 1.077117920 */,
PRESHIFT(0x04c16000) /* 0.297210693 */,
PRESHIFT(0x02687000) /* 0.150497437 */,
PRESHIFT(0x0069c000) /* 0.025817871 */,
PRESHIFT(0x0077f000) /* 0.029281616 */,
PRESHIFT(0x00002000) /* 0.000030518 */,
PRESHIFT(0x00093000) /* 0.002243042 */,
PRESHIFT(0x0000a000) /* 0.000152588 */ },
{ -PRESHIFT(0x00003000) /* -0.000045776 */, /* 11 */
-PRESHIFT(0x00049000) /* -0.001113892 */,
PRESHIFT(0x000d0000) /* 0.003173828 */,
-PRESHIFT(0x004ba000) /* -0.018463135 */,
PRESHIFT(0x003ca000) /* 0.014801025 */,
-PRESHIFT(0x02233000) /* -0.133590698 */,
-PRESHIFT(0x00ce4000) /* -0.050354004 */,
-PRESHIFT(0x0ddca000) /* -0.866363525 */,
PRESHIFT(0x1102f000) /* 1.063217163 */,
PRESHIFT(0x04587000) /* 0.271591187 */,
PRESHIFT(0x026cf000) /* 0.151596069 */,
PRESHIFT(0x0056c000) /* 0.021179199 */,
PRESHIFT(0x0074e000) /* 0.028533936 */,
-PRESHIFT(0x0001d000) /* -0.000442505 */,
PRESHIFT(0x0008b000) /* 0.002120972 */,
PRESHIFT(0x00009000) /* 0.000137329 */,
-PRESHIFT(0x00003000) /* -0.000045776 */,
-PRESHIFT(0x00049000) /* -0.001113892 */,
PRESHIFT(0x000d0000) /* 0.003173828 */,
-PRESHIFT(0x004ba000) /* -0.018463135 */,
PRESHIFT(0x003ca000) /* 0.014801025 */,
-PRESHIFT(0x02233000) /* -0.133590698 */,
-PRESHIFT(0x00ce4000) /* -0.050354004 */,
-PRESHIFT(0x0ddca000) /* -0.866363525 */,
PRESHIFT(0x1102f000) /* 1.063217163 */,
PRESHIFT(0x04587000) /* 0.271591187 */,
PRESHIFT(0x026cf000) /* 0.151596069 */,
PRESHIFT(0x0056c000) /* 0.021179199 */,
PRESHIFT(0x0074e000) /* 0.028533936 */,
-PRESHIFT(0x0001d000) /* -0.000442505 */,
PRESHIFT(0x0008b000) /* 0.002120972 */,
PRESHIFT(0x00009000) /* 0.000137329 */ },
{ -PRESHIFT(0x00003000) /* -0.000045776 */, /* 12 */
-PRESHIFT(0x0004f000) /* -0.001205444 */,
PRESHIFT(0x000c8000) /* 0.003051758 */,
-PRESHIFT(0x00503000) /* -0.019577026 */,
PRESHIFT(0x0031a000) /* 0.012115479 */,
-PRESHIFT(0x02326000) /* -0.137298584 */,
-PRESHIFT(0x011b5000) /* -0.069168091 */,
-PRESHIFT(0x0e3dd000) /* -0.890090942 */,
PRESHIFT(0x10c54000) /* 1.048156738 */,
PRESHIFT(0x03f1b000) /* 0.246505737 */,
PRESHIFT(0x026ee000) /* 0.152069092 */,
PRESHIFT(0x00447000) /* 0.016708374 */,
PRESHIFT(0x00719000) /* 0.027725220 */,
-PRESHIFT(0x00039000) /* -0.000869751 */,
PRESHIFT(0x00084000) /* 0.002014160 */,
PRESHIFT(0x00008000) /* 0.000122070 */,
-PRESHIFT(0x00003000) /* -0.000045776 */,
-PRESHIFT(0x0004f000) /* -0.001205444 */,
PRESHIFT(0x000c8000) /* 0.003051758 */,
-PRESHIFT(0x00503000) /* -0.019577026 */,
PRESHIFT(0x0031a000) /* 0.012115479 */,
-PRESHIFT(0x02326000) /* -0.137298584 */,
-PRESHIFT(0x011b5000) /* -0.069168091 */,
-PRESHIFT(0x0e3dd000) /* -0.890090942 */,
PRESHIFT(0x10c54000) /* 1.048156738 */,
PRESHIFT(0x03f1b000) /* 0.246505737 */,
PRESHIFT(0x026ee000) /* 0.152069092 */,
PRESHIFT(0x00447000) /* 0.016708374 */,
PRESHIFT(0x00719000) /* 0.027725220 */,
-PRESHIFT(0x00039000) /* -0.000869751 */,
PRESHIFT(0x00084000) /* 0.002014160 */,
PRESHIFT(0x00008000) /* 0.000122070 */ },
{ -PRESHIFT(0x00004000) /* -0.000061035 */, /* 13 */
-PRESHIFT(0x00055000) /* -0.001296997 */,
PRESHIFT(0x000bd000) /* 0.002883911 */,
-PRESHIFT(0x0054c000) /* -0.020690918 */,
PRESHIFT(0x0025d000) /* 0.009231567 */,
-PRESHIFT(0x02403000) /* -0.140670776 */,
-PRESHIFT(0x016ba000) /* -0.088775635 */,
-PRESHIFT(0x0e9be000) /* -0.913055420 */,
PRESHIFT(0x1082d000) /* 1.031936646 */,
PRESHIFT(0x038d4000) /* 0.221984863 */,
PRESHIFT(0x026e7000) /* 0.151962280 */,
PRESHIFT(0x0032e000) /* 0.012420654 */,
PRESHIFT(0x006df000) /* 0.026840210 */,
-PRESHIFT(0x00053000) /* -0.001266479 */,
PRESHIFT(0x0007d000) /* 0.001907349 */,
PRESHIFT(0x00007000) /* 0.000106812 */,
-PRESHIFT(0x00004000) /* -0.000061035 */,
-PRESHIFT(0x00055000) /* -0.001296997 */,
PRESHIFT(0x000bd000) /* 0.002883911 */,
-PRESHIFT(0x0054c000) /* -0.020690918 */,
PRESHIFT(0x0025d000) /* 0.009231567 */,
-PRESHIFT(0x02403000) /* -0.140670776 */,
-PRESHIFT(0x016ba000) /* -0.088775635 */,
-PRESHIFT(0x0e9be000) /* -0.913055420 */,
PRESHIFT(0x1082d000) /* 1.031936646 */,
PRESHIFT(0x038d4000) /* 0.221984863 */,
PRESHIFT(0x026e7000) /* 0.151962280 */,
PRESHIFT(0x0032e000) /* 0.012420654 */,
PRESHIFT(0x006df000) /* 0.026840210 */,
-PRESHIFT(0x00053000) /* -0.001266479 */,
PRESHIFT(0x0007d000) /* 0.001907349 */,
PRESHIFT(0x00007000) /* 0.000106812 */ },
{ -PRESHIFT(0x00004000) /* -0.000061035 */, /* 14 */
-PRESHIFT(0x0005b000) /* -0.001388550 */,
PRESHIFT(0x000b1000) /* 0.002700806 */,
-PRESHIFT(0x00594000) /* -0.021789551 */,
PRESHIFT(0x00192000) /* 0.006134033 */,
-PRESHIFT(0x024c8000) /* -0.143676758 */,
-PRESHIFT(0x01bf2000) /* -0.109161377 */,
-PRESHIFT(0x0ef69000) /* -0.935195923 */,
PRESHIFT(0x103be000) /* 1.014617920 */,
PRESHIFT(0x032b4000) /* 0.198059082 */,
PRESHIFT(0x026bc000) /* 0.151306152 */,
PRESHIFT(0x00221000) /* 0.008316040 */,
PRESHIFT(0x006a2000) /* 0.025909424 */,
-PRESHIFT(0x0006a000) /* -0.001617432 */,
PRESHIFT(0x00075000) /* 0.001785278 */,
PRESHIFT(0x00007000) /* 0.000106812 */,
-PRESHIFT(0x00004000) /* -0.000061035 */,
-PRESHIFT(0x0005b000) /* -0.001388550 */,
PRESHIFT(0x000b1000) /* 0.002700806 */,
-PRESHIFT(0x00594000) /* -0.021789551 */,
PRESHIFT(0x00192000) /* 0.006134033 */,
-PRESHIFT(0x024c8000) /* -0.143676758 */,
-PRESHIFT(0x01bf2000) /* -0.109161377 */,
-PRESHIFT(0x0ef69000) /* -0.935195923 */,
PRESHIFT(0x103be000) /* 1.014617920 */,
PRESHIFT(0x032b4000) /* 0.198059082 */,
PRESHIFT(0x026bc000) /* 0.151306152 */,
PRESHIFT(0x00221000) /* 0.008316040 */,
PRESHIFT(0x006a2000) /* 0.025909424 */,
-PRESHIFT(0x0006a000) /* -0.001617432 */,
PRESHIFT(0x00075000) /* 0.001785278 */,
PRESHIFT(0x00007000) /* 0.000106812 */ },
{ -PRESHIFT(0x00005000) /* -0.000076294 */, /* 15 */
-PRESHIFT(0x00061000) /* -0.001480103 */,
PRESHIFT(0x000a3000) /* 0.002487183 */,
-PRESHIFT(0x005da000) /* -0.022857666 */,
PRESHIFT(0x000b9000) /* 0.002822876 */,
-PRESHIFT(0x02571000) /* -0.146255493 */,
-PRESHIFT(0x0215c000) /* -0.130310059 */,
-PRESHIFT(0x0f4dc000) /* -0.956481934 */,
PRESHIFT(0x0ff0a000) /* 0.996246338 */,
PRESHIFT(0x02cbf000) /* 0.174789429 */,
PRESHIFT(0x0266e000) /* 0.150115967 */,
PRESHIFT(0x00120000) /* 0.004394531 */,
PRESHIFT(0x00662000) /* 0.024932861 */,
-PRESHIFT(0x0007f000) /* -0.001937866 */,
PRESHIFT(0x0006f000) /* 0.001693726 */,
PRESHIFT(0x00006000) /* 0.000091553 */,
-PRESHIFT(0x00005000) /* -0.000076294 */,
-PRESHIFT(0x00061000) /* -0.001480103 */,
PRESHIFT(0x000a3000) /* 0.002487183 */,
-PRESHIFT(0x005da000) /* -0.022857666 */,
PRESHIFT(0x000b9000) /* 0.002822876 */,
-PRESHIFT(0x02571000) /* -0.146255493 */,
-PRESHIFT(0x0215c000) /* -0.130310059 */,
-PRESHIFT(0x0f4dc000) /* -0.956481934 */,
PRESHIFT(0x0ff0a000) /* 0.996246338 */,
PRESHIFT(0x02cbf000) /* 0.174789429 */,
PRESHIFT(0x0266e000) /* 0.150115967 */,
PRESHIFT(0x00120000) /* 0.004394531 */,
PRESHIFT(0x00662000) /* 0.024932861 */,
-PRESHIFT(0x0007f000) /* -0.001937866 */,
PRESHIFT(0x0006f000) /* 0.001693726 */,
PRESHIFT(0x00006000) /* 0.000091553 */ },
{ -PRESHIFT(0x00005000) /* -0.000076294 */, /* 16 */
-PRESHIFT(0x00068000) /* -0.001586914 */,
PRESHIFT(0x00092000) /* 0.002227783 */,
-PRESHIFT(0x0061f000) /* -0.023910522 */,
-PRESHIFT(0x0002d000) /* -0.000686646 */,
-PRESHIFT(0x025ff000) /* -0.148422241 */,
-PRESHIFT(0x026f7000) /* -0.152206421 */,
-PRESHIFT(0x0fa13000) /* -0.976852417 */,
PRESHIFT(0x0fa13000) /* 0.976852417 */,
PRESHIFT(0x026f7000) /* 0.152206421 */,
PRESHIFT(0x025ff000) /* 0.148422241 */,
PRESHIFT(0x0002d000) /* 0.000686646 */,
PRESHIFT(0x0061f000) /* 0.023910522 */,
-PRESHIFT(0x00092000) /* -0.002227783 */,
PRESHIFT(0x00068000) /* 0.001586914 */,
PRESHIFT(0x00005000) /* 0.000076294 */,
-PRESHIFT(0x00005000) /* -0.000076294 */,
-PRESHIFT(0x00068000) /* -0.001586914 */,
PRESHIFT(0x00092000) /* 0.002227783 */,
-PRESHIFT(0x0061f000) /* -0.023910522 */,
-PRESHIFT(0x0002d000) /* -0.000686646 */,
-PRESHIFT(0x025ff000) /* -0.148422241 */,
-PRESHIFT(0x026f7000) /* -0.152206421 */,
-PRESHIFT(0x0fa13000) /* -0.976852417 */,
PRESHIFT(0x0fa13000) /* 0.976852417 */,
PRESHIFT(0x026f7000) /* 0.152206421 */,
PRESHIFT(0x025ff000) /* 0.148422241 */,
PRESHIFT(0x0002d000) /* 0.000686646 */,
PRESHIFT(0x0061f000) /* 0.023910522 */,
-PRESHIFT(0x00092000) /* -0.002227783 */,
PRESHIFT(0x00068000) /* 0.001586914 */,
PRESHIFT(0x00005000) /* 0.000076294 */ }

View file

@ -1,3 +0,0 @@
//char unalChar(char const *adr);
#define unalChar(x) *(x)
short unalShort(short const *adr);

View file

@ -1,47 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: bit.h,v 1.12 2004/01/23 09:41:32 rob Exp $
*/
# ifndef LIBMAD_BIT_H
# define LIBMAD_BIT_H
struct mad_bitptr {
unsigned char const *byte;
unsigned short cache;
unsigned short left;
};
void mad_bit_init(struct mad_bitptr *, unsigned char const *);
# define mad_bit_finish(bitptr) /* nothing */
unsigned int mad_bit_length(struct mad_bitptr const *,
struct mad_bitptr const *);
# define mad_bit_bitsleft(bitptr) ((bitptr)->left)
unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *);
void mad_bit_skip(struct mad_bitptr *, unsigned int);
unsigned long mad_bit_read(struct mad_bitptr *, unsigned int);
void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long);
unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short);
# endif

View file

@ -1,76 +0,0 @@
/* config.h. Generated by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to enable diagnostic debugging support. */
/* #undef DEBUG */
/* Define to enable experimental code. */
/* #undef EXPERIMENTAL */
/* Define to disable debugging assertions. */
#define NDEBUG
/* Define to optimize for accuracy over speed. */
/* #undef OPT_ACCURACY */
/* Define to optimize for speed over accuracy. */
#define OPT_SPEED 1
/* Define to enable a fast subband synthesis approximation optimization. */
#define OPT_SSO
/* Define to influence a strict interpretation of the ISO/IEC standards, even
if this is in opposition with best accepted practices. */
/* #undef OPT_STRICT */
/* Name of package */
#define PACKAGE "libmad"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "support@underbit.com"
/* Define to the full name of this package. */
#define PACKAGE_NAME "MPEG Audio Decoder"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "MPEG Audio Decoder 0.15.1b"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libmad"
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.15.1b"
/* The size of a `int', as computed by sizeof. */
#define SIZEOF_INT 4
/* The size of a `long', as computed by sizeof. */
#define SIZEOF_LONG 4
/* The size of a `long long', as computed by sizeof. */
#define SIZEOF_LONG_LONG 8
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#define VERSION "0.15.1b"
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
//#define FPM_DEFAULT
#define FPM_ARM
/* Define to `int' if <sys/types.h> does not define. */
/* #undef pid_t */

View file

@ -1,124 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: decoder.h,v 1.17 2004/01/23 09:41:32 rob Exp $
*/
# ifndef LIBMAD_DECODER_H
# define LIBMAD_DECODER_H
# include "stream.h"
# include "frame.h"
# include "synth.h"
enum mad_decoder_mode {
MAD_DECODER_MODE_SYNC = 0,
MAD_DECODER_MODE_ASYNC
};
enum mad_flow {
MAD_FLOW_CONTINUE = 0x0000, /* continue normally */
MAD_FLOW_STOP = 0x0010, /* stop decoding normally */
MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */
MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */
};
struct sync_t {
struct mad_stream stream; // definito main_data_t un array di circa 4K
struct mad_frame frame;
struct mad_synth synth;
};
// # define MAD_BUFFER_GUARD 8
// # define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD)
// typedef unsigned char main_data_t[MAD_BUFFER_MDLEN]; 2567
// in frame.h
// struct mad_frame {
// struct mad_header header; /* MPEG audio header */
//
// int options; /* decoding options (from stream) */
//
// mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples 9216 */
// mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data 4608 */
//};
//
// in synth.h
//struct mad_synth {
// mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs 4096 */
// /* [ch][eo][peo][s][v] */
//
// unsigned int phase; /* current processing phase */
// struct mad_pcm pcm; /* PCM output */
//};
struct mad_decoder {
enum mad_decoder_mode mode;
int options;
struct {
long pid;
int in;
int out;
} async;
/*
struct {
struct mad_stream stream;
struct mad_frame frame;
struct mad_synth synth;
} *sync;
*/
struct sync_t *sync;
void *cb_data;
enum mad_flow (*input_func)(void *, struct mad_stream *);
enum mad_flow (*header_func)(void *, struct mad_header const *);
enum mad_flow (*filter_func)(void *,
struct mad_stream const *, struct mad_frame *);
enum mad_flow (*output_func)(void *,
struct mad_header const *, struct mad_pcm *);
enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
enum mad_flow (*message_func)(void *, void *, unsigned int *);
};
void mad_decoder_init(struct mad_decoder *, void *,
enum mad_flow (*)(void *, struct mad_stream *),
enum mad_flow (*)(void *, struct mad_header const *),
enum mad_flow (*)(void *,
struct mad_stream const *,
struct mad_frame *),
enum mad_flow (*)(void *,
struct mad_header const *,
struct mad_pcm *),
enum mad_flow (*)(void *,
struct mad_stream *,
struct mad_frame *),
enum mad_flow (*)(void *, void *, unsigned int *));
int mad_decoder_finish(struct mad_decoder *);
# define mad_decoder_options(decoder, opts) \
((void) ((decoder)->options = (opts)))
int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode);
int mad_decoder_message(struct mad_decoder *, void *, unsigned int *);
# endif

View file

@ -1,499 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: fixed.h,v 1.38 2004/02/17 02:02:03 rob Exp $
*/
# ifndef LIBMAD_FIXED_H
# define LIBMAD_FIXED_H
# if SIZEOF_INT >= 4
typedef signed int mad_fixed_t;
typedef signed int mad_fixed64hi_t;
typedef unsigned int mad_fixed64lo_t;
# else
typedef signed long mad_fixed_t;
typedef signed long mad_fixed64hi_t;
typedef unsigned long mad_fixed64lo_t;
# endif
# if defined(_MSC_VER)
# define mad_fixed64_t signed __int64
# elif 1 || defined(__GNUC__)
# define mad_fixed64_t signed long long
# endif
# if defined(FPM_FLOAT)
typedef double mad_sample_t;
# else
typedef mad_fixed_t mad_sample_t;
# endif
/*
* Fixed-point format: 0xABBBBBBB
* A == whole part (sign + 3 bits)
* B == fractional part (28 bits)
*
* Values are signed two's complement, so the effective range is:
* 0x80000000 to 0x7fffffff
* -8.0 to +7.9999999962747097015380859375
*
* The smallest representable value is:
* 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9)
*
* 28 bits of fractional accuracy represent about
* 8.6 digits of decimal accuracy.
*
* Fixed-point numbers can be added or subtracted as normal
* integers, but multiplication requires shifting the 64-bit result
* from 56 fractional bits back to 28 (and rounding.)
*
* Changing the definition of MAD_F_FRACBITS is only partially
* supported, and must be done with care.
*/
# define MAD_F_FRACBITS 28
# if MAD_F_FRACBITS == 28
# define MAD_F(x) ((mad_fixed_t) (x##L))
# else
# if MAD_F_FRACBITS < 28
# warning "MAD_F_FRACBITS < 28"
# define MAD_F(x) ((mad_fixed_t) \
(((x##L) + \
(1L << (28 - MAD_F_FRACBITS - 1))) >> \
(28 - MAD_F_FRACBITS)))
# elif MAD_F_FRACBITS > 28
# error "MAD_F_FRACBITS > 28 not currently supported"
# define MAD_F(x) ((mad_fixed_t) \
((x##L) << (MAD_F_FRACBITS - 28)))
# endif
# endif
# define MAD_F_MIN ((mad_fixed_t) -0x80000000L)
# define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL)
# define MAD_F_ONE MAD_F(0x10000000)
# define mad_f_tofixed(x) ((mad_fixed_t) \
((x) * (double) (1L << MAD_F_FRACBITS) + 0.5))
# define mad_f_todouble(x) ((double) \
((x) / (double) (1L << MAD_F_FRACBITS)))
# define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS)
# define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1))
/* (x should be positive) */
# define mad_f_fromint(x) ((x) << MAD_F_FRACBITS)
# define mad_f_add(x, y) ((x) + (y))
# define mad_f_sub(x, y) ((x) - (y))
# if defined(FPM_FLOAT)
# error "FPM_FLOAT not yet supported"
# undef MAD_F
# define MAD_F(x) mad_f_todouble(x)
# define mad_f_mul(x, y) ((x) * (y))
# define mad_f_scale64
# undef ASO_ZEROCHECK
# elif defined(FPM_64BIT)
/*
* This version should be the most accurate if 64-bit types are supported by
* the compiler, although it may not be the most efficient.
*/
# if defined(OPT_ACCURACY)
# define mad_f_mul(x, y) \
((mad_fixed_t) \
((((mad_fixed64_t) (x) * (y)) + \
(1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS))
# else
# define mad_f_mul(x, y) \
((mad_fixed_t) (((mad_fixed64_t) (x) * (y)) >> MAD_F_SCALEBITS))
# endif
# define MAD_F_SCALEBITS MAD_F_FRACBITS
/* --- Intel --------------------------------------------------------------- */
# elif defined(FPM_INTEL)
# if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable: 4035) /* no return value */
static __forceinline
mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y)
{
enum {
fracbits = MAD_F_FRACBITS
};
__asm {
mov eax, x
imul y
shrd eax, edx, fracbits
}
/* implicit return of eax */
}
# pragma warning(pop)
# define mad_f_mul mad_f_mul_inline
# define mad_f_scale64
# else
/*
* This Intel version is fast and accurate; the disposition of the least
* significant bit depends on OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
asm ("imull %3" \
: "=a" (lo), "=d" (hi) \
: "%a" (x), "rm" (y) \
: "cc")
# if defined(OPT_ACCURACY)
/*
* This gives best accuracy but is not very fast.
*/
# define MAD_F_MLA(hi, lo, x, y) \
({ mad_fixed64hi_t __hi; \
mad_fixed64lo_t __lo; \
MAD_F_MLX(__hi, __lo, (x), (y)); \
asm ("addl %2,%0\n\t" \
"adcl %3,%1" \
: "=rm" (lo), "=rm" (hi) \
: "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \
: "cc"); \
})
# endif /* OPT_ACCURACY */
# if defined(OPT_ACCURACY)
/*
* Surprisingly, this is faster than SHRD followed by ADC.
*/
# define mad_f_scale64(hi, lo) \
({ mad_fixed64hi_t __hi_; \
mad_fixed64lo_t __lo_; \
mad_fixed_t __result; \
asm ("addl %4,%2\n\t" \
"adcl %5,%3" \
: "=rm" (__lo_), "=rm" (__hi_) \
: "0" (lo), "1" (hi), \
"ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \
: "cc"); \
asm ("shrdl %3,%2,%1" \
: "=rm" (__result) \
: "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# elif defined(OPT_INTEL)
/*
* Alternate Intel scaling that may or may not perform better.
*/
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
asm ("shrl %3,%1\n\t" \
"shll %4,%2\n\t" \
"orl %2,%1" \
: "=rm" (__result) \
: "0" (lo), "r" (hi), \
"I" (MAD_F_SCALEBITS), "I" (32 - MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# else
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
asm ("shrdl %3,%2,%1" \
: "=rm" (__result) \
: "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# endif /* OPT_ACCURACY */
# define MAD_F_SCALEBITS MAD_F_FRACBITS
# endif
/* --- ARM ----------------------------------------------------------------- */
# elif defined(FPM_ARM)
/*
* This ARM V4 version is as accurate as FPM_64BIT but much faster. The
* least significant bit is properly rounded at no CPU cycle cost!
*/
# if 1
/*
* This is faster than the default implementation via MAD_F_MLX() and
* mad_f_scale64().
*/
# define mad_f_mul(x, y) \
({ mad_fixed64hi_t __hi; \
mad_fixed64lo_t __lo; \
mad_fixed_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" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# endif
# define MAD_F_MLX(hi, lo, x, y) \
asm ("smull %0, %1, %2, %3" \
: "=&r" (lo), "=&r" (hi) \
: "%r" (x), "r" (y))
# define MAD_F_MLA(hi, lo, x, y) \
asm ("smlal %0, %1, %2, %3" \
: "+r" (lo), "+r" (hi) \
: "%r" (x), "r" (y))
# define MAD_F_MLN(hi, lo) \
asm ("rsbs %0, %2, #0\n\t" \
"rsc %1, %3, #0" \
: "=r" (lo), "=r" (hi) \
: "0" (lo), "1" (hi) \
: "cc")
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
asm ("movs %0, %1, lsr %3\n\t" \
"adc %0, %0, %2, lsl %4" \
: "=&r" (__result) \
: "r" (lo), "r" (hi), \
"M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# define MAD_F_SCALEBITS MAD_F_FRACBITS
/* --- MIPS ---------------------------------------------------------------- */
# elif defined(FPM_MIPS)
/*
* This MIPS version is fast and accurate; the disposition of the least
* significant bit depends on OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
asm ("mult %2,%3" \
: "=l" (lo), "=h" (hi) \
: "%r" (x), "r" (y))
# if defined(HAVE_MADD_ASM)
# define MAD_F_MLA(hi, lo, x, y) \
asm ("madd %2,%3" \
: "+l" (lo), "+h" (hi) \
: "%r" (x), "r" (y))
# elif defined(HAVE_MADD16_ASM)
/*
* This loses significant accuracy due to the 16-bit integer limit in the
* multiply/accumulate instruction.
*/
# define MAD_F_ML0(hi, lo, x, y) \
asm ("mult %2,%3" \
: "=l" (lo), "=h" (hi) \
: "%r" ((x) >> 12), "r" ((y) >> 16))
# define MAD_F_MLA(hi, lo, x, y) \
asm ("madd16 %2,%3" \
: "+l" (lo), "+h" (hi) \
: "%r" ((x) >> 12), "r" ((y) >> 16))
# define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo))
# endif
# if defined(OPT_SPEED)
# define mad_f_scale64(hi, lo) \
((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS)))
# define MAD_F_SCALEBITS MAD_F_FRACBITS
# endif
/* --- SPARC --------------------------------------------------------------- */
# elif defined(FPM_SPARC)
/*
* This SPARC V8 version is fast and accurate; the disposition of the least
* significant bit depends on OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
asm ("smul %2, %3, %0\n\t" \
"rd %%y, %1" \
: "=r" (lo), "=r" (hi) \
: "%r" (x), "rI" (y))
/* --- PowerPC ------------------------------------------------------------- */
# elif defined(FPM_PPC)
/*
* This PowerPC version is fast and accurate; the disposition of the least
* significant bit depends on OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
do { \
asm ("mullw %0,%1,%2" \
: "=r" (lo) \
: "%r" (x), "r" (y)); \
asm ("mulhw %0,%1,%2" \
: "=r" (hi) \
: "%r" (x), "r" (y)); \
} \
while (0)
# if defined(OPT_ACCURACY)
/*
* This gives best accuracy but is not very fast.
*/
# define MAD_F_MLA(hi, lo, x, y) \
({ mad_fixed64hi_t __hi; \
mad_fixed64lo_t __lo; \
MAD_F_MLX(__hi, __lo, (x), (y)); \
asm ("addc %0,%2,%3\n\t" \
"adde %1,%4,%5" \
: "=r" (lo), "=r" (hi) \
: "%r" (lo), "r" (__lo), \
"%r" (hi), "r" (__hi) \
: "xer"); \
})
# endif
# if defined(OPT_ACCURACY)
/*
* This is slower than the truncating version below it.
*/
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result, __round; \
asm ("rotrwi %0,%1,%2" \
: "=r" (__result) \
: "r" (lo), "i" (MAD_F_SCALEBITS)); \
asm ("extrwi %0,%1,1,0" \
: "=r" (__round) \
: "r" (__result)); \
asm ("insrwi %0,%1,%2,0" \
: "+r" (__result) \
: "r" (hi), "i" (MAD_F_SCALEBITS)); \
asm ("add %0,%1,%2" \
: "=r" (__result) \
: "%r" (__result), "r" (__round)); \
__result; \
})
# else
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
asm ("rotrwi %0,%1,%2" \
: "=r" (__result) \
: "r" (lo), "i" (MAD_F_SCALEBITS)); \
asm ("insrwi %0,%1,%2,0" \
: "+r" (__result) \
: "r" (hi), "i" (MAD_F_SCALEBITS)); \
__result; \
})
# endif
# define MAD_F_SCALEBITS MAD_F_FRACBITS
/* --- Default ------------------------------------------------------------- */
# elif defined(FPM_DEFAULT)
/*
* This version is the most portable but it loses significant accuracy.
* Furthermore, accuracy is biased against the second argument, so care
* should be taken when ordering operands.
*
* The scale factors are constant as this is not used with SSO.
*
* Pre-rounding is required to stay within the limits of compliance.
*/
# if defined(OPT_SPEED)
# define mad_f_mul(x, y) (((x) >> 12) * ((y) >> 16))
# else
# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \
(((y) + (1L << 15)) >> 16))
# endif
/* ------------------------------------------------------------------------- */
# else
# error "no FPM selected"
# endif
/* default implementations */
# if !defined(mad_f_mul)
# define mad_f_mul(x, y) \
({ register mad_fixed64hi_t __hi; \
register mad_fixed64lo_t __lo; \
MAD_F_MLX(__hi, __lo, (x), (y)); \
mad_f_scale64(__hi, __lo); \
})
# endif
# if !defined(MAD_F_MLA)
# define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y)))
# define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y)))
# define MAD_F_MLN(hi, lo) ((lo) = -(lo))
# define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
# endif
# if !defined(MAD_F_ML0)
# define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y))
# endif
# if !defined(MAD_F_MLN)
# define MAD_F_MLN(hi, lo) ((hi) = ((lo) = -(lo)) ? ~(hi) : -(hi))
# endif
# if !defined(MAD_F_MLZ)
# define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo))
# endif
# if !defined(mad_f_scale64)
# if defined(OPT_ACCURACY)
# define mad_f_scale64(hi, lo) \
((((mad_fixed_t) \
(((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \
((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1)
# else
# define mad_f_scale64(hi, lo) \
((mad_fixed_t) \
(((hi) << (32 - MAD_F_SCALEBITS)) | \
((lo) >> MAD_F_SCALEBITS)))
# endif
# define MAD_F_SCALEBITS MAD_F_FRACBITS
# endif
/* C routines */
mad_fixed_t mad_f_abs(mad_fixed_t);
mad_fixed_t mad_f_div(mad_fixed_t, mad_fixed_t);
# endif

View file

@ -1,119 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: frame.h,v 1.20 2004/01/23 09:41:32 rob Exp $
*/
# ifndef LIBMAD_FRAME_H
# define LIBMAD_FRAME_H
# include "fixed.h"
# include "timer.h"
# include "stream.h"
enum mad_layer {
MAD_LAYER_I = 1, /* Layer I */
MAD_LAYER_II = 2, /* Layer II */
MAD_LAYER_III = 3 /* Layer III */
};
enum mad_mode {
MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */
MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */
MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */
MAD_MODE_STEREO = 3 /* normal LR stereo */
};
enum mad_emphasis {
MAD_EMPHASIS_NONE = 0, /* no emphasis */
MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */
MAD_EMPHASIS_CCITT_J_17 = 3, /* CCITT J.17 emphasis */
MAD_EMPHASIS_RESERVED = 2 /* unknown emphasis */
};
struct mad_header {
enum mad_layer layer; /* audio layer (1, 2, or 3) */
enum mad_mode mode; /* channel mode (see above) */
int mode_extension; /* additional mode info */
enum mad_emphasis emphasis; /* de-emphasis to use (see above) */
unsigned long bitrate; /* stream bitrate (bps) */
unsigned int samplerate; /* sampling frequency (Hz) */
unsigned short crc_check; /* frame CRC accumulator */
unsigned short crc_target; /* final target CRC checksum */
int flags; /* flags (see below) */
int private_bits; /* private bits (see below) */
mad_timer_t duration; /* audio playing time of frame */
};
struct mad_frame {
struct mad_header header; /* MPEG audio header */
int options; /* decoding options (from stream) */
mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */
mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */
};
# define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1)
# define MAD_NSBSAMPLES(header) \
((header)->layer == MAD_LAYER_I ? 12 : \
(((header)->layer == MAD_LAYER_III && \
((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36))
enum {
MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */
MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */
MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */
MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */
MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */
MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */
MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */
MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */
MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */
MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */
MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */
MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */
};
enum {
MAD_PRIVATE_HEADER = 0x0100, /* header private bit */
MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */
};
void mad_header_init(struct mad_header *);
# define mad_header_finish(header) /* nothing */
int mad_header_decode(struct mad_header *, struct mad_stream *);
void mad_frame_init(struct mad_frame *);
void mad_frame_finish(struct mad_frame *);
int mad_frame_decode(struct mad_frame *, struct mad_stream *);
void mad_frame_mute(struct mad_frame *);
# endif

View file

@ -1,64 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: global.h,v 1.11 2004/01/23 09:41:32 rob Exp $
*/
# ifndef LIBMAD_GLOBAL_H
# define LIBMAD_GLOBAL_H
#include "rtl8195a/c_types.h"
//#include "rtl_common.h"
#include "config.h"
/* conditional debugging */
# if defined(DEBUG) && defined(NDEBUG)
# error "cannot define both DEBUG and NDEBUG"
# endif
# if defined(DEBUG)
# include <stdio.h>
# endif
/* conditional features */
# if defined(OPT_SPEED) && defined(OPT_ACCURACY)
# error "cannot optimize for both speed and accuracy"
# endif
# if defined(OPT_SPEED) && !defined(OPT_SSO)
# define OPT_SSO
# endif
# if defined(HAVE_UNISTD_H) && defined(HAVE_WAITPID) && \
defined(HAVE_FCNTL) && defined(HAVE_PIPE) && defined(HAVE_FORK)
# define USE_ASYNC
# endif
#include "platform_stdlib.h"
# if !defined(HAVE_ASSERT_H)
//# if defined(NDEBUG)
# define assert(x) /* nothing */
//# else
//# define assert(x) do { if (!(x)) abort(); } while (0)
//# endif
# endif
# endif

View file

@ -1,66 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: huffman.h,v 1.11 2004/01/23 09:41:32 rob Exp $
*/
# ifndef LIBMAD_HUFFMAN_H
# define LIBMAD_HUFFMAN_H
union huffquad {
struct {
unsigned int final : 1;
unsigned int bits : 3;
unsigned int offset : 12;
} ptr;
struct {
unsigned int final : 1;
unsigned int hlen : 3;
unsigned int v : 1;
unsigned int w : 1;
unsigned int x : 1;
unsigned int y : 1;
} value;
unsigned int final : 1;
};
union huffpair {
struct {
unsigned int final : 1;
unsigned int bits : 3;
unsigned int offset : 12;
} ptr;
struct {
unsigned int final : 1;
unsigned int hlen : 3;
unsigned int x : 4;
unsigned int y : 4;
} value;
unsigned int final : 1;
};
struct hufftable {
union huffpair const *table;
unsigned int linbits;
unsigned int startbits;
};
extern union huffquad const *const mad_huff_quad_table[2];
extern struct hufftable const mad_huff_pair_table[32];
# endif

View file

@ -1,62 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: imdct_s.dat,v 1.8 2004/01/23 09:41:32 rob Exp $
*/
/* 0 */ { MAD_F(0x09bd7ca0) /* 0.608761429 */,
-MAD_F(0x0ec835e8) /* -0.923879533 */,
-MAD_F(0x0216a2a2) /* -0.130526192 */,
MAD_F(0x0fdcf549) /* 0.991444861 */,
-MAD_F(0x061f78aa) /* -0.382683432 */,
-MAD_F(0x0cb19346) /* -0.793353340 */ },
/* 6 */ { -MAD_F(0x0cb19346) /* -0.793353340 */,
MAD_F(0x061f78aa) /* 0.382683432 */,
MAD_F(0x0fdcf549) /* 0.991444861 */,
MAD_F(0x0216a2a2) /* 0.130526192 */,
-MAD_F(0x0ec835e8) /* -0.923879533 */,
-MAD_F(0x09bd7ca0) /* -0.608761429 */ },
/* 1 */ { MAD_F(0x061f78aa) /* 0.382683432 */,
-MAD_F(0x0ec835e8) /* -0.923879533 */,
MAD_F(0x0ec835e8) /* 0.923879533 */,
-MAD_F(0x061f78aa) /* -0.382683432 */,
-MAD_F(0x061f78aa) /* -0.382683432 */,
MAD_F(0x0ec835e8) /* 0.923879533 */ },
/* 7 */ { -MAD_F(0x0ec835e8) /* -0.923879533 */,
-MAD_F(0x061f78aa) /* -0.382683432 */,
MAD_F(0x061f78aa) /* 0.382683432 */,
MAD_F(0x0ec835e8) /* 0.923879533 */,
MAD_F(0x0ec835e8) /* 0.923879533 */,
MAD_F(0x061f78aa) /* 0.382683432 */ },
/* 2 */ { MAD_F(0x0216a2a2) /* 0.130526192 */,
-MAD_F(0x061f78aa) /* -0.382683432 */,
MAD_F(0x09bd7ca0) /* 0.608761429 */,
-MAD_F(0x0cb19346) /* -0.793353340 */,
MAD_F(0x0ec835e8) /* 0.923879533 */,
-MAD_F(0x0fdcf549) /* -0.991444861 */ },
/* 8 */ { -MAD_F(0x0fdcf549) /* -0.991444861 */,
-MAD_F(0x0ec835e8) /* -0.923879533 */,
-MAD_F(0x0cb19346) /* -0.793353340 */,
-MAD_F(0x09bd7ca0) /* -0.608761429 */,
-MAD_F(0x061f78aa) /* -0.382683432 */,
-MAD_F(0x0216a2a2) /* -0.130526192 */ }

View file

@ -1,32 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: layer3.h,v 1.10 2004/01/23 09:41:32 rob Exp $
*/
# ifndef LIBMAD_LAYER3_H
# define LIBMAD_LAYER3_H
# include "stream.h"
# include "frame.h"
int mad_layer_III(struct mad_stream *, struct mad_frame *);
extern main_data_t MainData;
# endif

View file

@ -1,966 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* If you would like to negotiate alternate licensing terms, you may do
* so by contacting: Underbit Technologies, Inc. <info@underbit.com>
*/
# ifdef __cplusplus
extern "C" {
# endif
# define SIZEOF_INT 4
# define SIZEOF_LONG 4
# define SIZEOF_LONG_LONG 8
#include "config.h"
/* Id: version.h,v 1.26 2004/01/23 09:41:33 rob Exp */
# ifndef LIBMAD_VERSION_H
# define LIBMAD_VERSION_H
# define MAD_VERSION_MAJOR 0
# define MAD_VERSION_MINOR 15
# define MAD_VERSION_PATCH 1
# define MAD_VERSION_EXTRA " (beta)"
# define MAD_VERSION_STRINGIZE(str) #str
# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num)
# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \
MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \
MAD_VERSION_STRING(MAD_VERSION_PATCH) \
MAD_VERSION_EXTRA
# define MAD_PUBLISHYEAR "2000-2004"
# define MAD_AUTHOR "Underbit Technologies, Inc."
# define MAD_EMAIL "info@underbit.com"
extern char const mad_version[];
extern char const mad_copyright[];
extern char const mad_author[];
extern char const mad_build[];
# endif
/* Id: fixed.h,v 1.38 2004/02/17 02:02:03 rob Exp */
# ifndef LIBMAD_FIXED_H
# define LIBMAD_FIXED_H
# if SIZEOF_INT >= 4
typedef signed int mad_fixed_t;
typedef signed int mad_fixed64hi_t;
typedef unsigned int mad_fixed64lo_t;
# else
typedef signed long mad_fixed_t;
typedef signed long mad_fixed64hi_t;
typedef unsigned long mad_fixed64lo_t;
# endif
# if defined(_MSC_VER)
# define mad_fixed64_t signed __int64
# elif 1 || defined(__GNUC__)
# define mad_fixed64_t signed long long
# endif
# if defined(FPM_FLOAT)
typedef double mad_sample_t;
# else
typedef mad_fixed_t mad_sample_t;
# endif
/*
* Fixed-point format: 0xABBBBBBB
* A == whole part (sign + 3 bits)
* B == fractional part (28 bits)
*
* Values are signed two's complement, so the effective range is:
* 0x80000000 to 0x7fffffff
* -8.0 to +7.9999999962747097015380859375
*
* The smallest representable value is:
* 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9)
*
* 28 bits of fractional accuracy represent about
* 8.6 digits of decimal accuracy.
*
* Fixed-point numbers can be added or subtracted as normal
* integers, but multiplication requires shifting the 64-bit result
* from 56 fractional bits back to 28 (and rounding.)
*
* Changing the definition of MAD_F_FRACBITS is only partially
* supported, and must be done with care.
*/
# define MAD_F_FRACBITS 28
# if MAD_F_FRACBITS == 28
# define MAD_F(x) ((mad_fixed_t) (x##L))
# else
# if MAD_F_FRACBITS < 28
# warning "MAD_F_FRACBITS < 28"
# define MAD_F(x) ((mad_fixed_t) \
(((x##L) + \
(1L << (28 - MAD_F_FRACBITS - 1))) >> \
(28 - MAD_F_FRACBITS)))
# elif MAD_F_FRACBITS > 28
# error "MAD_F_FRACBITS > 28 not currently supported"
# define MAD_F(x) ((mad_fixed_t) \
((x##L) << (MAD_F_FRACBITS - 28)))
# endif
# endif
# define MAD_F_MIN ((mad_fixed_t) -0x80000000L)
# define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL)
# define MAD_F_ONE MAD_F(0x10000000)
# define mad_f_tofixed(x) ((mad_fixed_t) \
((x) * (double) (1L << MAD_F_FRACBITS) + 0.5))
# define mad_f_todouble(x) ((double) \
((x) / (double) (1L << MAD_F_FRACBITS)))
# define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS)
# define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1))
/* (x should be positive) */
# define mad_f_fromint(x) ((x) << MAD_F_FRACBITS)
# define mad_f_add(x, y) ((x) + (y))
# define mad_f_sub(x, y) ((x) - (y))
# if defined(FPM_FLOAT)
# error "FPM_FLOAT not yet supported"
# undef MAD_F
# define MAD_F(x) mad_f_todouble(x)
# define mad_f_mul(x, y) ((x) * (y))
# define mad_f_scale64
# undef ASO_ZEROCHECK
# elif defined(FPM_64BIT)
/*
* This version should be the most accurate if 64-bit types are supported by
* the compiler, although it may not be the most efficient.
*/
# if defined(OPT_ACCURACY)
# define mad_f_mul(x, y) \
((mad_fixed_t) \
((((mad_fixed64_t) (x) * (y)) + \
(1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS))
# else
# define mad_f_mul(x, y) \
((mad_fixed_t) (((mad_fixed64_t) (x) * (y)) >> MAD_F_SCALEBITS))
# endif
# define MAD_F_SCALEBITS MAD_F_FRACBITS
/* --- Intel --------------------------------------------------------------- */
# elif defined(FPM_INTEL)
# if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable: 4035) /* no return value */
static __forceinline
mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y)
{
enum {
fracbits = MAD_F_FRACBITS
};
__asm {
mov eax, x
imul y
shrd eax, edx, fracbits
}
/* implicit return of eax */
}
# pragma warning(pop)
# define mad_f_mul mad_f_mul_inline
# define mad_f_scale64
# else
/*
* This Intel version is fast and accurate; the disposition of the least
* significant bit depends on OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
asm ("imull %3" \
: "=a" (lo), "=d" (hi) \
: "%a" (x), "rm" (y) \
: "cc")
# if defined(OPT_ACCURACY)
/*
* This gives best accuracy but is not very fast.
*/
# define MAD_F_MLA(hi, lo, x, y) \
({ mad_fixed64hi_t __hi; \
mad_fixed64lo_t __lo; \
MAD_F_MLX(__hi, __lo, (x), (y)); \
asm ("addl %2,%0\n\t" \
"adcl %3,%1" \
: "=rm" (lo), "=rm" (hi) \
: "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \
: "cc"); \
})
# endif /* OPT_ACCURACY */
# if defined(OPT_ACCURACY)
/*
* Surprisingly, this is faster than SHRD followed by ADC.
*/
# define mad_f_scale64(hi, lo) \
({ mad_fixed64hi_t __hi_; \
mad_fixed64lo_t __lo_; \
mad_fixed_t __result; \
asm ("addl %4,%2\n\t" \
"adcl %5,%3" \
: "=rm" (__lo_), "=rm" (__hi_) \
: "0" (lo), "1" (hi), \
"ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \
: "cc"); \
asm ("shrdl %3,%2,%1" \
: "=rm" (__result) \
: "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# elif defined(OPT_INTEL)
/*
* Alternate Intel scaling that may or may not perform better.
*/
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
asm ("shrl %3,%1\n\t" \
"shll %4,%2\n\t" \
"orl %2,%1" \
: "=rm" (__result) \
: "0" (lo), "r" (hi), \
"I" (MAD_F_SCALEBITS), "I" (32 - MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# else
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
asm ("shrdl %3,%2,%1" \
: "=rm" (__result) \
: "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# endif /* OPT_ACCURACY */
# define MAD_F_SCALEBITS MAD_F_FRACBITS
# endif
/* --- ARM ----------------------------------------------------------------- */
# elif defined(FPM_ARM)
/*
* This ARM V4 version is as accurate as FPM_64BIT but much faster. The
* least significant bit is properly rounded at no CPU cycle cost!
*/
# if 1
/*
* This is faster than the default implementation via MAD_F_MLX() and
* mad_f_scale64().
*/
# define mad_f_mul(x, y) \
({ mad_fixed64hi_t __hi; \
mad_fixed64lo_t __lo; \
mad_fixed_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" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# endif
# define MAD_F_MLX(hi, lo, x, y) \
asm ("smull %0, %1, %2, %3" \
: "=&r" (lo), "=&r" (hi) \
: "%r" (x), "r" (y))
# define MAD_F_MLA(hi, lo, x, y) \
asm ("smlal %0, %1, %2, %3" \
: "+r" (lo), "+r" (hi) \
: "%r" (x), "r" (y))
# define MAD_F_MLN(hi, lo) \
asm ("rsbs %0, %2, #0\n\t" \
"rsc %1, %3, #0" \
: "=r" (lo), "=r" (hi) \
: "0" (lo), "1" (hi) \
: "cc")
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
asm ("movs %0, %1, lsr %3\n\t" \
"adc %0, %0, %2, lsl %4" \
: "=&r" (__result) \
: "r" (lo), "r" (hi), \
"M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# define MAD_F_SCALEBITS MAD_F_FRACBITS
/* --- MIPS ---------------------------------------------------------------- */
# elif defined(FPM_MIPS)
/*
* This MIPS version is fast and accurate; the disposition of the least
* significant bit depends on OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
asm ("mult %2,%3" \
: "=l" (lo), "=h" (hi) \
: "%r" (x), "r" (y))
# if defined(HAVE_MADD_ASM)
# define MAD_F_MLA(hi, lo, x, y) \
asm ("madd %2,%3" \
: "+l" (lo), "+h" (hi) \
: "%r" (x), "r" (y))
# elif defined(HAVE_MADD16_ASM)
/*
* This loses significant accuracy due to the 16-bit integer limit in the
* multiply/accumulate instruction.
*/
# define MAD_F_ML0(hi, lo, x, y) \
asm ("mult %2,%3" \
: "=l" (lo), "=h" (hi) \
: "%r" ((x) >> 12), "r" ((y) >> 16))
# define MAD_F_MLA(hi, lo, x, y) \
asm ("madd16 %2,%3" \
: "+l" (lo), "+h" (hi) \
: "%r" ((x) >> 12), "r" ((y) >> 16))
# define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo))
# endif
# if defined(OPT_SPEED)
# define mad_f_scale64(hi, lo) \
((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS)))
# define MAD_F_SCALEBITS MAD_F_FRACBITS
# endif
/* --- SPARC --------------------------------------------------------------- */
# elif defined(FPM_SPARC)
/*
* This SPARC V8 version is fast and accurate; the disposition of the least
* significant bit depends on OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
asm ("smul %2, %3, %0\n\t" \
"rd %%y, %1" \
: "=r" (lo), "=r" (hi) \
: "%r" (x), "rI" (y))
/* --- PowerPC ------------------------------------------------------------- */
# elif defined(FPM_PPC)
/*
* This PowerPC version is fast and accurate; the disposition of the least
* significant bit depends on OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
do { \
asm ("mullw %0,%1,%2" \
: "=r" (lo) \
: "%r" (x), "r" (y)); \
asm ("mulhw %0,%1,%2" \
: "=r" (hi) \
: "%r" (x), "r" (y)); \
} \
while (0)
# if defined(OPT_ACCURACY)
/*
* This gives best accuracy but is not very fast.
*/
# define MAD_F_MLA(hi, lo, x, y) \
({ mad_fixed64hi_t __hi; \
mad_fixed64lo_t __lo; \
MAD_F_MLX(__hi, __lo, (x), (y)); \
asm ("addc %0,%2,%3\n\t" \
"adde %1,%4,%5" \
: "=r" (lo), "=r" (hi) \
: "%r" (lo), "r" (__lo), \
"%r" (hi), "r" (__hi) \
: "xer"); \
})
# endif
# if defined(OPT_ACCURACY)
/*
* This is slower than the truncating version below it.
*/
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result, __round; \
asm ("rotrwi %0,%1,%2" \
: "=r" (__result) \
: "r" (lo), "i" (MAD_F_SCALEBITS)); \
asm ("extrwi %0,%1,1,0" \
: "=r" (__round) \
: "r" (__result)); \
asm ("insrwi %0,%1,%2,0" \
: "+r" (__result) \
: "r" (hi), "i" (MAD_F_SCALEBITS)); \
asm ("add %0,%1,%2" \
: "=r" (__result) \
: "%r" (__result), "r" (__round)); \
__result; \
})
# else
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
asm ("rotrwi %0,%1,%2" \
: "=r" (__result) \
: "r" (lo), "i" (MAD_F_SCALEBITS)); \
asm ("insrwi %0,%1,%2,0" \
: "+r" (__result) \
: "r" (hi), "i" (MAD_F_SCALEBITS)); \
__result; \
})
# endif
# define MAD_F_SCALEBITS MAD_F_FRACBITS
/* --- Default ------------------------------------------------------------- */
# elif defined(FPM_DEFAULT)
/*
* This version is the most portable but it loses significant accuracy.
* Furthermore, accuracy is biased against the second argument, so care
* should be taken when ordering operands.
*
* The scale factors are constant as this is not used with SSO.
*
* Pre-rounding is required to stay within the limits of compliance.
*/
# if defined(OPT_SPEED)
# define mad_f_mul(x, y) (((x) >> 12) * ((y) >> 16))
# else
# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \
(((y) + (1L << 15)) >> 16))
# endif
/* ------------------------------------------------------------------------- */
# else
# error "no FPM selected"
# endif
/* default implementations */
# if !defined(mad_f_mul)
# define mad_f_mul(x, y) \
({ register mad_fixed64hi_t __hi; \
register mad_fixed64lo_t __lo; \
MAD_F_MLX(__hi, __lo, (x), (y)); \
mad_f_scale64(__hi, __lo); \
})
# endif
# if !defined(MAD_F_MLA)
# define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y)))
# define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y)))
# define MAD_F_MLN(hi, lo) ((lo) = -(lo))
# define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
# endif
# if !defined(MAD_F_ML0)
# define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y))
# endif
# if !defined(MAD_F_MLN)
# define MAD_F_MLN(hi, lo) ((hi) = ((lo) = -(lo)) ? ~(hi) : -(hi))
# endif
# if !defined(MAD_F_MLZ)
# define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo))
# endif
# if !defined(mad_f_scale64)
# if defined(OPT_ACCURACY)
# define mad_f_scale64(hi, lo) \
((((mad_fixed_t) \
(((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \
((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1)
# else
# define mad_f_scale64(hi, lo) \
((mad_fixed_t) \
(((hi) << (32 - MAD_F_SCALEBITS)) | \
((lo) >> MAD_F_SCALEBITS)))
# endif
# define MAD_F_SCALEBITS MAD_F_FRACBITS
# endif
/* C routines */
mad_fixed_t mad_f_abs(mad_fixed_t);
mad_fixed_t mad_f_div(mad_fixed_t, mad_fixed_t);
# endif
/* Id: bit.h,v 1.12 2004/01/23 09:41:32 rob Exp */
# ifndef LIBMAD_BIT_H
# define LIBMAD_BIT_H
struct mad_bitptr {
unsigned char const *byte;
unsigned short cache;
unsigned short left;
};
void mad_bit_init(struct mad_bitptr *, unsigned char const *);
# define mad_bit_finish(bitptr) /* nothing */
unsigned int mad_bit_length(struct mad_bitptr const *,
struct mad_bitptr const *);
# define mad_bit_bitsleft(bitptr) ((bitptr)->left)
unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *);
void mad_bit_skip(struct mad_bitptr *, unsigned int);
unsigned long mad_bit_read(struct mad_bitptr *, unsigned int);
void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long);
unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short);
# endif
/* Id: timer.h,v 1.16 2004/01/23 09:41:33 rob Exp */
# ifndef LIBMAD_TIMER_H
# define LIBMAD_TIMER_H
typedef struct {
signed long seconds; /* whole seconds */
unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */
} mad_timer_t;
extern mad_timer_t const mad_timer_zero;
# define MAD_TIMER_RESOLUTION 352800000UL
enum mad_units {
MAD_UNITS_HOURS = -2,
MAD_UNITS_MINUTES = -1,
MAD_UNITS_SECONDS = 0,
/* metric units */
MAD_UNITS_DECISECONDS = 10,
MAD_UNITS_CENTISECONDS = 100,
MAD_UNITS_MILLISECONDS = 1000,
/* audio sample units */
MAD_UNITS_8000_HZ = 8000,
MAD_UNITS_11025_HZ = 11025,
MAD_UNITS_12000_HZ = 12000,
MAD_UNITS_16000_HZ = 16000,
MAD_UNITS_22050_HZ = 22050,
MAD_UNITS_24000_HZ = 24000,
MAD_UNITS_32000_HZ = 32000,
MAD_UNITS_44100_HZ = 44100,
MAD_UNITS_48000_HZ = 48000,
/* video frame/field units */
MAD_UNITS_24_FPS = 24,
MAD_UNITS_25_FPS = 25,
MAD_UNITS_30_FPS = 30,
MAD_UNITS_48_FPS = 48,
MAD_UNITS_50_FPS = 50,
MAD_UNITS_60_FPS = 60,
/* CD audio frames */
MAD_UNITS_75_FPS = 75,
/* video drop-frame units */
MAD_UNITS_23_976_FPS = -24,
MAD_UNITS_24_975_FPS = -25,
MAD_UNITS_29_97_FPS = -30,
MAD_UNITS_47_952_FPS = -48,
MAD_UNITS_49_95_FPS = -50,
MAD_UNITS_59_94_FPS = -60
};
# define mad_timer_reset(timer) ((void) (*(timer) = mad_timer_zero))
int mad_timer_compare(mad_timer_t, mad_timer_t);
# define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero)
void mad_timer_negate(mad_timer_t *);
mad_timer_t mad_timer_abs(mad_timer_t);
void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long);
void mad_timer_add(mad_timer_t *, mad_timer_t);
void mad_timer_multiply(mad_timer_t *, signed long);
signed long mad_timer_count(mad_timer_t, enum mad_units);
unsigned long mad_timer_fraction(mad_timer_t, unsigned long);
void mad_timer_string(mad_timer_t, char *, char const *,
enum mad_units, enum mad_units, unsigned long);
# endif
/* Id: stream.h,v 1.20 2004/02/05 09:02:39 rob Exp */
# ifndef LIBMAD_STREAM_H
# define LIBMAD_STREAM_H
# define MAD_BUFFER_GUARD 8
# define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD)
enum mad_error {
MAD_ERROR_NONE = 0x0000, /* no error */
MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */
MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */
MAD_ERROR_NOMEM = 0x0031, /* not enough memory */
MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */
MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */
MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */
MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */
MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */
MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */
MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */
MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */
MAD_ERROR_BADMODE = 0x0222, /* bad bitrate/mode combination */
MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */
MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */
MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */
MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */
MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */
MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */
MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */
MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */
MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */
};
# define MAD_RECOVERABLE(error) ((error) & 0xff00)
typedef unsigned char main_data_t[MAD_BUFFER_MDLEN];
struct mad_stream {
unsigned char const *buffer; /* input bitstream buffer */
unsigned char const *bufend; /* end of buffer */
unsigned long skiplen; /* bytes to skip before next frame */
int sync; /* stream sync found */
unsigned long freerate; /* free bitrate (fixed) */
unsigned char const *this_frame; /* start of current frame */
unsigned char const *next_frame; /* start of next frame */
struct mad_bitptr ptr; /* current processing bit pointer */
struct mad_bitptr anc_ptr; /* ancillary bits pointer */
unsigned int anc_bitlen; /* number of ancillary bits */
// unsigned char (*main_data)[MAD_BUFFER_MDLEN];
main_data_t *main_data;
/* Layer III main_data() */
unsigned int md_len; /* bytes in main_data */
int options; /* decoding options (see below) */
enum mad_error error; /* error code (see above) */
};
enum {
MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */
MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */
# if 0 /* not yet implemented */
MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */
MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */
MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */
# endif
};
void mad_stream_init(struct mad_stream *);
void mad_stream_finish(struct mad_stream *);
# define mad_stream_options(stream, opts) \
((void) ((stream)->options = (opts)))
void mad_stream_buffer(struct mad_stream *,
unsigned char const *, unsigned long);
void mad_stream_skip(struct mad_stream *, unsigned long);
int mad_stream_sync(struct mad_stream *);
char const *mad_stream_errorstr(struct mad_stream const *);
# endif
/* Id: frame.h,v 1.20 2004/01/23 09:41:32 rob Exp */
# ifndef LIBMAD_FRAME_H
# define LIBMAD_FRAME_H
enum mad_layer {
MAD_LAYER_I = 1, /* Layer I */
MAD_LAYER_II = 2, /* Layer II */
MAD_LAYER_III = 3 /* Layer III */
};
enum mad_mode {
MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */
MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */
MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */
MAD_MODE_STEREO = 3 /* normal LR stereo */
};
enum mad_emphasis {
MAD_EMPHASIS_NONE = 0, /* no emphasis */
MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */
MAD_EMPHASIS_CCITT_J_17 = 3, /* CCITT J.17 emphasis */
MAD_EMPHASIS_RESERVED = 2 /* unknown emphasis */
};
struct mad_header {
enum mad_layer layer; /* audio layer (1, 2, or 3) */
enum mad_mode mode; /* channel mode (see above) */
int mode_extension; /* additional mode info */
enum mad_emphasis emphasis; /* de-emphasis to use (see above) */
unsigned long bitrate; /* stream bitrate (bps) */
unsigned int samplerate; /* sampling frequency (Hz) */
unsigned short crc_check; /* frame CRC accumulator */
unsigned short crc_target; /* final target CRC checksum */
int flags; /* flags (see below) */
int private_bits; /* private bits (see below) */
mad_timer_t duration; /* audio playing time of frame */
};
struct mad_frame {
struct mad_header header; /* MPEG audio header */
int options; /* decoding options (from stream) */
mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */
mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */
};
# define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1)
# define MAD_NSBSAMPLES(header) \
((header)->layer == MAD_LAYER_I ? 12 : \
(((header)->layer == MAD_LAYER_III && \
((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36))
enum {
MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */
MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */
MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */
MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */
MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */
MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */
MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */
MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */
MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */
MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */
MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */
MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */
};
enum {
MAD_PRIVATE_HEADER = 0x0100, /* header private bit */
MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */
};
void mad_header_init(struct mad_header *);
# define mad_header_finish(header) /* nothing */
int mad_header_decode(struct mad_header *, struct mad_stream *);
void mad_frame_init(struct mad_frame *);
void mad_frame_finish(struct mad_frame *);
int mad_frame_decode(struct mad_frame *, struct mad_stream *);
void mad_frame_mute(struct mad_frame *);
# endif
/* Id: synth.h,v 1.15 2004/01/23 09:41:33 rob Exp */
# ifndef LIBMAD_SYNTH_H
# define LIBMAD_SYNTH_H
struct mad_pcm {
unsigned int samplerate; /* sampling frequency (Hz) */
unsigned short channels; /* number of channels */
unsigned short length; /* number of samples per channel */
};
struct mad_synth {
mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */
/* [ch][eo][peo][s][v] */
unsigned int phase; /* current processing phase */
struct mad_pcm pcm; /* PCM output */
};
/* single channel PCM selector */
enum {
MAD_PCM_CHANNEL_SINGLE = 0
};
/* dual channel PCM selector */
enum {
MAD_PCM_CHANNEL_DUAL_1 = 0,
MAD_PCM_CHANNEL_DUAL_2 = 1
};
/* stereo PCM selector */
enum {
MAD_PCM_CHANNEL_STEREO_LEFT = 0,
MAD_PCM_CHANNEL_STEREO_RIGHT = 1
};
void mad_synth_init(struct mad_synth *);
# define mad_synth_finish(synth) /* nothing */
void mad_synth_mute(struct mad_synth *);
void mad_synth_frame(struct mad_synth *, struct mad_frame const *);
# endif
/* Id: decoder.h,v 1.17 2004/01/23 09:41:32 rob Exp */
# ifndef LIBMAD_DECODER_H
# define LIBMAD_DECODER_H
enum mad_decoder_mode {
MAD_DECODER_MODE_SYNC = 0,
MAD_DECODER_MODE_ASYNC
};
enum mad_flow {
MAD_FLOW_CONTINUE = 0x0000, /* continue normally */
MAD_FLOW_STOP = 0x0010, /* stop decoding normally */
MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */
MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */
};
struct t_sync {
struct mad_stream stream;
struct mad_frame frame;
struct mad_synth synth;
};
struct mad_decoder {
enum mad_decoder_mode mode;
int options;
struct {
long pid;
int in;
int out;
} async;
struct t_sync *sync;
void *cb_data;
enum mad_flow (*input_func)(void *, struct mad_stream *);
enum mad_flow (*header_func)(void *, struct mad_header const *);
enum mad_flow (*filter_func)(void *,
struct mad_stream const *, struct mad_frame *);
enum mad_flow (*output_func)(void *,
struct mad_header const *, struct mad_pcm *);
enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
enum mad_flow (*message_func)(void *, void *, unsigned int *);
};
void mad_decoder_init(struct mad_decoder *, void *,
enum mad_flow (*)(void *, struct mad_stream *),
enum mad_flow (*)(void *, struct mad_header const *),
enum mad_flow (*)(void *,
struct mad_stream const *,
struct mad_frame *),
enum mad_flow (*)(void *,
struct mad_header const *,
struct mad_pcm *),
enum mad_flow (*)(void *,
struct mad_stream *,
struct mad_frame *),
enum mad_flow (*)(void *, void *, unsigned int *));
int mad_decoder_finish(struct mad_decoder *);
# define mad_decoder_options(decoder, opts) \
((void) ((decoder)->options = (opts)))
int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode);
int mad_decoder_message(struct mad_decoder *, void *, unsigned int *);
# endif
# ifdef __cplusplus
}
# endif

View file

@ -1,47 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: version.h,v 1.26 2004/01/23 09:41:33 rob Exp $
*/
# ifndef LIBMAD_VERSION_H
# define LIBMAD_VERSION_H
# define MAD_VERSION_MAJOR 0
# define MAD_VERSION_MINOR 15
# define MAD_VERSION_PATCH 1
# define MAD_VERSION_EXTRA " (beta)"
# define MAD_VERSION_STRINGIZE(str) #str
# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num)
# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \
MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \
MAD_VERSION_STRING(MAD_VERSION_PATCH) \
MAD_VERSION_EXTRA
# define MAD_PUBLISHYEAR "2000-2004"
# define MAD_AUTHOR "Underbit Technologies, Inc."
# define MAD_EMAIL "info@underbit.com"
extern char const mad_version[];
extern char const mad_copyright[];
extern char const mad_author[];
extern char const mad_build[];
# endif

View file

@ -1,31 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: layer12.h,v 1.10 2004/01/23 09:41:32 rob Exp $
*/
# ifndef LIBMAD_LAYER12_H
# define LIBMAD_LAYER12_H
# include "stream.h"
# include "frame.h"
int mad_layer_I(struct mad_stream *, struct mad_frame *);
int mad_layer_II(struct mad_stream *, struct mad_frame *);
# endif

View file

@ -1,77 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: qc_table.dat,v 1.7 2004/01/23 09:41:32 rob Exp $
*/
/*
* These are the Layer II classes of quantization.
* The table is derived from Table B.4 of ISO/IEC 11172-3.
*/
{ 3, 2, 5,
MAD_F(0x15555555) /* 1.33333333333 => 1.33333333209, e 0.00000000124 */,
MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ },
{ 5, 3, 7,
MAD_F(0x1999999a) /* 1.60000000000 => 1.60000000149, e -0.00000000149 */,
MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ },
{ 7, 0, 3,
MAD_F(0x12492492) /* 1.14285714286 => 1.14285714179, e 0.00000000107 */,
MAD_F(0x04000000) /* 0.25000000000 => 0.25000000000, e 0.00000000000 */ },
{ 9, 4, 10,
MAD_F(0x1c71c71c) /* 1.77777777777 => 1.77777777612, e 0.00000000165 */,
MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ },
{ 15, 0, 4,
MAD_F(0x11111111) /* 1.06666666666 => 1.06666666642, e 0.00000000024 */,
MAD_F(0x02000000) /* 0.12500000000 => 0.12500000000, e 0.00000000000 */ },
{ 31, 0, 5,
MAD_F(0x10842108) /* 1.03225806452 => 1.03225806355, e 0.00000000097 */,
MAD_F(0x01000000) /* 0.06250000000 => 0.06250000000, e 0.00000000000 */ },
{ 63, 0, 6,
MAD_F(0x10410410) /* 1.01587301587 => 1.01587301493, e 0.00000000094 */,
MAD_F(0x00800000) /* 0.03125000000 => 0.03125000000, e 0.00000000000 */ },
{ 127, 0, 7,
MAD_F(0x10204081) /* 1.00787401575 => 1.00787401572, e 0.00000000003 */,
MAD_F(0x00400000) /* 0.01562500000 => 0.01562500000, e 0.00000000000 */ },
{ 255, 0, 8,
MAD_F(0x10101010) /* 1.00392156863 => 1.00392156839, e 0.00000000024 */,
MAD_F(0x00200000) /* 0.00781250000 => 0.00781250000, e 0.00000000000 */ },
{ 511, 0, 9,
MAD_F(0x10080402) /* 1.00195694716 => 1.00195694715, e 0.00000000001 */,
MAD_F(0x00100000) /* 0.00390625000 => 0.00390625000, e 0.00000000000 */ },
{ 1023, 0, 10,
MAD_F(0x10040100) /* 1.00097751711 => 1.00097751617, e 0.00000000094 */,
MAD_F(0x00080000) /* 0.00195312500 => 0.00195312500, e 0.00000000000 */ },
{ 2047, 0, 11,
MAD_F(0x10020040) /* 1.00048851979 => 1.00048851967, e 0.00000000012 */,
MAD_F(0x00040000) /* 0.00097656250 => 0.00097656250, e 0.00000000000 */ },
{ 4095, 0, 12,
MAD_F(0x10010010) /* 1.00024420024 => 1.00024420023, e 0.00000000001 */,
MAD_F(0x00020000) /* 0.00048828125 => 0.00048828125, e 0.00000000000 */ },
{ 8191, 0, 13,
MAD_F(0x10008004) /* 1.00012208522 => 1.00012208521, e 0.00000000001 */,
MAD_F(0x00010000) /* 0.00024414063 => 0.00024414062, e 0.00000000000 */ },
{ 16383, 0, 14,
MAD_F(0x10004001) /* 1.00006103888 => 1.00006103888, e -0.00000000000 */,
MAD_F(0x00008000) /* 0.00012207031 => 0.00012207031, e -0.00000000000 */ },
{ 32767, 0, 15,
MAD_F(0x10002000) /* 1.00003051851 => 1.00003051758, e 0.00000000093 */,
MAD_F(0x00004000) /* 0.00006103516 => 0.00006103516, e 0.00000000000 */ },
{ 65535, 0, 16,
MAD_F(0x10001000) /* 1.00001525902 => 1.00001525879, e 0.00000000023 */,
MAD_F(0x00002000) /* 0.00003051758 => 0.00003051758, e 0.00000000000 */ }

File diff suppressed because it is too large Load diff

View file

@ -1,106 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: sf_table.dat,v 1.7 2004/01/23 09:41:33 rob Exp $
*/
/*
* These are the scalefactor values for Layer I and Layer II.
* The values are from Table B.1 of ISO/IEC 11172-3.
*
* There is some error introduced by the 32-bit fixed-point representation;
* the amount of error is shown. For 16-bit PCM output, this shouldn't be
* too much of a problem.
*
* Strictly speaking, Table B.1 has only 63 entries (0-62), thus a strict
* interpretation of ISO/IEC 11172-3 would suggest that a scalefactor index of
* 63 is invalid. However, for better compatibility with current practices, we
* add a 64th entry.
*/
MAD_F(0x20000000), /* 2.000000000000 => 2.000000000000, e 0.000000000000 */
MAD_F(0x1965fea5), /* 1.587401051968 => 1.587401051074, e 0.000000000894 */
MAD_F(0x1428a2fa), /* 1.259921049895 => 1.259921051562, e -0.000000001667 */
MAD_F(0x10000000), /* 1.000000000000 => 1.000000000000, e 0.000000000000 */
MAD_F(0x0cb2ff53), /* 0.793700525984 => 0.793700527400, e -0.000000001416 */
MAD_F(0x0a14517d), /* 0.629960524947 => 0.629960525781, e -0.000000000833 */
MAD_F(0x08000000), /* 0.500000000000 => 0.500000000000, e 0.000000000000 */
MAD_F(0x06597fa9), /* 0.396850262992 => 0.396850261837, e 0.000000001155 */
MAD_F(0x050a28be), /* 0.314980262474 => 0.314980261028, e 0.000000001446 */
MAD_F(0x04000000), /* 0.250000000000 => 0.250000000000, e 0.000000000000 */
MAD_F(0x032cbfd5), /* 0.198425131496 => 0.198425132781, e -0.000000001285 */
MAD_F(0x0285145f), /* 0.157490131237 => 0.157490130514, e 0.000000000723 */
MAD_F(0x02000000), /* 0.125000000000 => 0.125000000000, e 0.000000000000 */
MAD_F(0x01965fea), /* 0.099212565748 => 0.099212564528, e 0.000000001220 */
MAD_F(0x01428a30), /* 0.078745065618 => 0.078745067120, e -0.000000001501 */
MAD_F(0x01000000), /* 0.062500000000 => 0.062500000000, e 0.000000000000 */
MAD_F(0x00cb2ff5), /* 0.049606282874 => 0.049606282264, e 0.000000000610 */
MAD_F(0x00a14518), /* 0.039372532809 => 0.039372533560, e -0.000000000751 */
MAD_F(0x00800000), /* 0.031250000000 => 0.031250000000, e 0.000000000000 */
MAD_F(0x006597fb), /* 0.024803141437 => 0.024803142995, e -0.000000001558 */
MAD_F(0x0050a28c), /* 0.019686266405 => 0.019686266780, e -0.000000000375 */
MAD_F(0x00400000), /* 0.015625000000 => 0.015625000000, e 0.000000000000 */
MAD_F(0x0032cbfd), /* 0.012401570719 => 0.012401569635, e 0.000000001084 */
MAD_F(0x00285146), /* 0.009843133202 => 0.009843133390, e -0.000000000188 */
MAD_F(0x00200000), /* 0.007812500000 => 0.007812500000, e 0.000000000000 */
MAD_F(0x001965ff), /* 0.006200785359 => 0.006200786680, e -0.000000001321 */
MAD_F(0x001428a3), /* 0.004921566601 => 0.004921566695, e -0.000000000094 */
MAD_F(0x00100000), /* 0.003906250000 => 0.003906250000, e 0.000000000000 */
MAD_F(0x000cb2ff), /* 0.003100392680 => 0.003100391477, e 0.000000001202 */
MAD_F(0x000a1451), /* 0.002460783301 => 0.002460781485, e 0.000000001816 */
MAD_F(0x00080000), /* 0.001953125000 => 0.001953125000, e 0.000000000000 */
MAD_F(0x00065980), /* 0.001550196340 => 0.001550197601, e -0.000000001262 */
MAD_F(0x00050a29), /* 0.001230391650 => 0.001230392605, e -0.000000000955 */
MAD_F(0x00040000), /* 0.000976562500 => 0.000976562500, e 0.000000000000 */
MAD_F(0x00032cc0), /* 0.000775098170 => 0.000775098801, e -0.000000000631 */
MAD_F(0x00028514), /* 0.000615195825 => 0.000615194440, e 0.000000001385 */
MAD_F(0x00020000), /* 0.000488281250 => 0.000488281250, e 0.000000000000 */
MAD_F(0x00019660), /* 0.000387549085 => 0.000387549400, e -0.000000000315 */
MAD_F(0x0001428a), /* 0.000307597913 => 0.000307597220, e 0.000000000693 */
MAD_F(0x00010000), /* 0.000244140625 => 0.000244140625, e 0.000000000000 */
MAD_F(0x0000cb30), /* 0.000193774542 => 0.000193774700, e -0.000000000158 */
MAD_F(0x0000a145), /* 0.000153798956 => 0.000153798610, e 0.000000000346 */
MAD_F(0x00008000), /* 0.000122070313 => 0.000122070313, e 0.000000000000 */
MAD_F(0x00006598), /* 0.000096887271 => 0.000096887350, e -0.000000000079 */
MAD_F(0x000050a3), /* 0.000076899478 => 0.000076901168, e -0.000000001689 */
MAD_F(0x00004000), /* 0.000061035156 => 0.000061035156, e 0.000000000000 */
MAD_F(0x000032cc), /* 0.000048443636 => 0.000048443675, e -0.000000000039 */
MAD_F(0x00002851), /* 0.000038449739 => 0.000038448721, e 0.000000001018 */
MAD_F(0x00002000), /* 0.000030517578 => 0.000030517578, e 0.000000000000 */
MAD_F(0x00001966), /* 0.000024221818 => 0.000024221838, e -0.000000000020 */
MAD_F(0x00001429), /* 0.000019224870 => 0.000019226223, e -0.000000001354 */
MAD_F(0x00001000), /* 0.000015258789 => 0.000015258789, e -0.000000000000 */
MAD_F(0x00000cb3), /* 0.000012110909 => 0.000012110919, e -0.000000000010 */
MAD_F(0x00000a14), /* 0.000009612435 => 0.000009611249, e 0.000000001186 */
MAD_F(0x00000800), /* 0.000007629395 => 0.000007629395, e -0.000000000000 */
MAD_F(0x00000659), /* 0.000006055454 => 0.000006053597, e 0.000000001858 */
MAD_F(0x0000050a), /* 0.000004806217 => 0.000004805624, e 0.000000000593 */
MAD_F(0x00000400), /* 0.000003814697 => 0.000003814697, e 0.000000000000 */
MAD_F(0x0000032d), /* 0.000003027727 => 0.000003028661, e -0.000000000934 */
MAD_F(0x00000285), /* 0.000002403109 => 0.000002402812, e 0.000000000296 */
MAD_F(0x00000200), /* 0.000001907349 => 0.000001907349, e -0.000000000000 */
MAD_F(0x00000196), /* 0.000001513864 => 0.000001512468, e 0.000000001396 */
MAD_F(0x00000143), /* 0.000001201554 => 0.000001203269, e -0.000000001714 */
MAD_F(0x00000000) /* this compatibility entry is not part of Table B.1 */

View file

@ -1,110 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: stream.h,v 1.20 2004/02/05 09:02:39 rob Exp $
*/
# ifndef LIBMAD_STREAM_H
# define LIBMAD_STREAM_H
# include "bit.h"
# define MAD_BUFFER_GUARD 8
# define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD)
enum mad_error {
MAD_ERROR_NONE = 0x0000, /* no error */
MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */
MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */
MAD_ERROR_NOMEM = 0x0031, /* not enough memory */
MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */
MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */
MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */
MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */
MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */
MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */
MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */
MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */
MAD_ERROR_BADMODE = 0x0222, /* bad bitrate/mode combination */
MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */
MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */
MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */
MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */
MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */
MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */
MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */
MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */
MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */
};
# define MAD_RECOVERABLE(error) ((error) & 0xff00)
typedef unsigned char main_data_t[MAD_BUFFER_MDLEN];
struct mad_stream {
unsigned char const *buffer; /* input bitstream buffer */
unsigned char const *bufend; /* end of buffer */
unsigned long skiplen; /* bytes to skip before next frame */
int sync; /* stream sync found */
unsigned long freerate; /* free bitrate (fixed) */
unsigned char const *this_frame; /* start of current frame */
unsigned char const *next_frame; /* start of next frame */
struct mad_bitptr ptr; /* current processing bit pointer */
struct mad_bitptr anc_ptr; /* ancillary bits pointer */
unsigned int anc_bitlen; /* number of ancillary bits */
// unsigned char (*main_data)[MAD_BUFFER_MDLEN];
main_data_t *main_data;
/* Layer III main_data() */
unsigned int md_len; /* bytes in main_data */
int options; /* decoding options (see below) */
enum mad_error error; /* error code (see above) */
};
enum {
MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */
MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */
# if 0 /* not yet implemented */
MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */
MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */
MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */
# endif
};
void mad_stream_init(struct mad_stream *);
void mad_stream_finish(struct mad_stream *);
# define mad_stream_options(stream, opts) \
((void) ((stream)->options = (opts)))
void mad_stream_buffer(struct mad_stream *,
unsigned char const *, unsigned long);
void mad_stream_skip(struct mad_stream *, unsigned long);
int mad_stream_sync(struct mad_stream *);
char const *mad_stream_errorstr(struct mad_stream const *);
# endif

View file

@ -1,68 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: synth.h,v 1.15 2004/01/23 09:41:33 rob Exp $
*/
# ifndef LIBMAD_SYNTH_H
# define LIBMAD_SYNTH_H
# include "fixed.h"
# include "frame.h"
struct mad_pcm {
unsigned int samplerate; /* sampling frequency (Hz) */
unsigned short channels; /* number of channels */
unsigned short length; /* number of samples per channel */
};
struct mad_synth {
mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */
/* [ch][eo][peo][s][v] */
unsigned int phase; /* current processing phase */
struct mad_pcm pcm; /* PCM output */
};
/* single channel PCM selector */
enum {
MAD_PCM_CHANNEL_SINGLE = 0
};
/* dual channel PCM selector */
enum {
MAD_PCM_CHANNEL_DUAL_1 = 0,
MAD_PCM_CHANNEL_DUAL_2 = 1
};
/* stereo PCM selector */
enum {
MAD_PCM_CHANNEL_STEREO_LEFT = 0,
MAD_PCM_CHANNEL_STEREO_RIGHT = 1
};
void mad_synth_init(struct mad_synth *);
# define mad_synth_finish(synth) /* nothing */
void mad_synth_mute(struct mad_synth *);
void mad_synth_frame(struct mad_synth *, struct mad_frame const *);
# endif

View file

@ -1,100 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: timer.h,v 1.16 2004/01/23 09:41:33 rob Exp $
*/
# ifndef LIBMAD_TIMER_H
# define LIBMAD_TIMER_H
typedef struct {
signed long seconds; /* whole seconds */
unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */
} mad_timer_t;
extern mad_timer_t const mad_timer_zero;
# define MAD_TIMER_RESOLUTION 352800000UL
enum mad_units {
MAD_UNITS_HOURS = -2,
MAD_UNITS_MINUTES = -1,
MAD_UNITS_SECONDS = 0,
/* metric units */
MAD_UNITS_DECISECONDS = 10,
MAD_UNITS_CENTISECONDS = 100,
MAD_UNITS_MILLISECONDS = 1000,
/* audio sample units */
MAD_UNITS_8000_HZ = 8000,
MAD_UNITS_11025_HZ = 11025,
MAD_UNITS_12000_HZ = 12000,
MAD_UNITS_16000_HZ = 16000,
MAD_UNITS_22050_HZ = 22050,
MAD_UNITS_24000_HZ = 24000,
MAD_UNITS_32000_HZ = 32000,
MAD_UNITS_44100_HZ = 44100,
MAD_UNITS_48000_HZ = 48000,
/* video frame/field units */
MAD_UNITS_24_FPS = 24,
MAD_UNITS_25_FPS = 25,
MAD_UNITS_30_FPS = 30,
MAD_UNITS_48_FPS = 48,
MAD_UNITS_50_FPS = 50,
MAD_UNITS_60_FPS = 60,
/* CD audio frames */
MAD_UNITS_75_FPS = 75,
/* video drop-frame units */
MAD_UNITS_23_976_FPS = -24,
MAD_UNITS_24_975_FPS = -25,
MAD_UNITS_29_97_FPS = -30,
MAD_UNITS_47_952_FPS = -48,
MAD_UNITS_49_95_FPS = -50,
MAD_UNITS_59_94_FPS = -60
};
# define mad_timer_reset(timer) ((void) (*(timer) = mad_timer_zero))
int mad_timer_compare(mad_timer_t, mad_timer_t);
# define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero)
void mad_timer_negate(mad_timer_t *);
mad_timer_t mad_timer_abs(mad_timer_t);
void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long);
void mad_timer_add(mad_timer_t *, mad_timer_t);
void mad_timer_multiply(mad_timer_t *, signed long);
signed long mad_timer_count(mad_timer_t, enum mad_units);
unsigned long mad_timer_fraction(mad_timer_t, unsigned long);
void mad_timer_string(mad_timer_t, char *, char const *,
enum mad_units, enum mad_units, unsigned long);
# endif

View file

@ -1,273 +0,0 @@
/******************************************************************************
*
* FileName: i2s_freertos.c
*
* Description: I2S output routines for a FreeRTOS system.
*
* Modification history:
* 2015/10, RTL8710 kissste, pvvx
*******************************************************************************/
/*
How does this work? Basically, to get sound, you need to:
- Connect an I2S codec to the I2S pins on the RTL.
- Start up a thread that's going to do the sound output
- Call I2sInit()
- Call I2sSetRate() with the sample rate you want.
- Generate sound and call i2sPushSample() with 32-bit samples.
The 32bit samples basically are 2 16-bit signed values (the analog values for
the left and right channel) concatenated as (Rout<<16)+Lout
I2sPushSample will block when you're sending data too quickly, so you can just
generate and push data as fast as you can and I2sPushSample will regulate the
speed.
*/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "queue.h"
#include "user/playerconfig.h"
#include "osdep_api.h"
#include "i2s_api.h"
#include "driver/i2s_freertos.h"
#define USE_RTL_I2S_API 0 // speed
PI2S_OBJS pi2s[MAX_I2S_OBJS]; // I2S0, I2S1
xSemaphoreHandle I2sTxSema;
// i2s interrupt callback
static void i2s_test_tx_complete(void *data, char *pbuf)
{
i2s_t *i2s_obj = (i2s_t *)data;
int idx = i2s_obj->InitDat.I2SIdx;
#if I2S_DEBUG_LEVEL > 1
int reg = HAL_I2S_READ32(idx, REG_I2S_TX_PAGE0_OWN);
reg |= HAL_I2S_READ32(idx, REG_I2S_TX_PAGE1_OWN);
reg |= HAL_I2S_READ32(idx, REG_I2S_TX_PAGE2_OWN);
reg |= HAL_I2S_READ32(idx, REG_I2S_TX_PAGE3_OWN);
if(!(reg & BIT_PAGE_I2S_OWN_BIT)) pi2s[idx]->underrunCnt++;
#endif
if(!idx) xSemaphoreGive(I2sTxSema);
}
void i2sClose(int mask) {
int i;
for(i = 0; i < MAX_I2S_OBJS; i++) {
if(mask & (1 << i)) {
if(pi2s[i] != NULL) {
if(pi2s[i]->i2s_obj.InitDat.I2SEn != I2S_DISABLE) {
i2s_disable(&pi2s[i]->i2s_obj); // HalI2SDisable(&pi2s[i]->i2s_obj.I2SAdapter);
i2s_deinit(&pi2s[i]->i2s_obj); // HalI2SDeInit(&pi2s[i]->i2s_obj.I2SAdapter);
#if I2S_DEBUG_LEVEL > 0
DBG_8195A("I2S%d: i2s_disable (%d)\n", i, pi2s[i]->i2s_obj.InitDat.I2SEn);
#endif
}
if(pi2s[i]->i2s_obj.InitDat.I2STxData != NULL) {
vPortFree(pi2s[i]->i2s_obj.InitDat.I2STxData);
pi2s[i]->i2s_obj.InitDat.I2STxData = NULL;
}
vPortFree(pi2s[i]);
pi2s[i] = NULL;
if(i==0) {
vSemaphoreDelete(I2sTxSema);
HalPinCtrlRtl8195A(JTAG, 0, 1);
}
DBG_8195A("I2S%d: Closed.\n", i);
}
}
}
}
//Initialize I2S subsystem for DMA circular buffer use
int i2sInit(int mask, int bufsize, int word_len) { // word_len = WL_16b or WL_24b
#if I2S_DEBUG_LEVEL > 2
DBG_ERR_MSG_ON(_DBG_I2S_ | _DBG_GDMA_);
DBG_INFO_MSG_ON(_DBG_I2S_ | _DBG_GDMA_);
DBG_WARN_MSG_ON(_DBG_I2S_ | _DBG_GDMA_);
#endif
if(bufsize < I2S_DMA_PAGE_SIZE_MS_96K*2) {
DBG_8195A("I2S: Min buffer %d bytes!\n", I2S_DMA_PAGE_SIZE_MS_96K*2);
return 0;
}
int page_size = bufsize * sizeof(u32);
if(word_len != WL_16b) page_size <<= 1; //bufsize *2;
int i;
for(i = 0; i < MAX_I2S_OBJS; i++) {
if (mask & (1 << i)) {
if(pi2s[i] != NULL) i2sClose(1 << i);
PI2S_OBJS pi2s_new = pvPortMalloc(sizeof(I2S_OBJS));
if(pi2s_new == NULL) {
DBG_8195A("I2S%d: Not heap buffer %d bytes!\n", i, sizeof(i2s_t) + page_size * I2S_DMA_PAGE_NUM);
return 0;
}
rtl_memset(pi2s_new, 0, sizeof(i2s_t));
u8 * i2s_tx_buf = (u8 *) pvPortMalloc(page_size * I2S_DMA_PAGE_NUM);
if (i2s_tx_buf == NULL) {
vPortFree(pi2s_new);
DBG_8195A("I2S%d: Not heap buffer %d bytes!\n", i, sizeof(i2s_t) + page_size * I2S_DMA_PAGE_NUM);
return 0;
}
pi2s[i] = pi2s_new;
#if I2S_DEBUG_LEVEL > 1
pi2s_new->underrunCnt = 0;
#endif
pi2s[i]->sampl_err = 0;
pi2s_new->currDMABuffPos = 0;
pi2s_new->currDMABuff = NULL;
i2s_t * pi2s_obj = &pi2s_new->i2s_obj;
pi2s_obj->channel_num = CH_STEREO;
pi2s_obj->sampling_rate = SR_96KHZ;
pi2s_obj->word_length = word_len;
pi2s_obj->direction = I2S_DIR_TX; //consider switching to TX only
if(i == 0) {
HalPinCtrlRtl8195A(JTAG, 0, 0);
i2s_init(pi2s_obj, I2S0_SCLK_PIN, I2S0_WS_PIN, I2S0_SD_PIN);
// Create a Semaphone
RtlInitSema(&I2sTxSema, 1);
}
else i2s_init(pi2s_obj, I2S1_SCLK_PIN, I2S1_WS_PIN, I2S1_SD_PIN);
i2s_set_param(pi2s_obj, pi2s_obj->channel_num, pi2s_obj->sampling_rate, pi2s_obj->word_length);
i2s_set_dma_buffer(pi2s_obj, i2s_tx_buf, NULL, I2S_DMA_PAGE_NUM, page_size);
i2s_tx_irq_handler(pi2s_obj, i2s_test_tx_complete, (uint32_t)pi2s_obj);
// i2s_rx_irq_handler(pi2s_obj, (i == 0)? (i2s_irq_handler)i2s1_test_rx_complete : (i2s_irq_handler)i2s2_test_rx_complete, i); // TX only!
i2s_enable(pi2s_obj);
DBG_8195A("I2S%d: Alloc DMA buf %d bytes (%d x %d samples %d bits)\n", i, page_size * I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_NUM, bufsize, (word_len == WL_16b)? 32 : 96);
}
}
}
//Set the I2S sample rate, in HZ
char i2sSetRate(int mask, int rate) {
int sample_rate;
char result = 1;
#if defined(OVERSAMPLES) && defined(PWM_HACK96BIT)
rate <<= 1;
while (rate <= 48000) {
rate <<= 1;
result++;
}
#endif
if (rate>=96000) sample_rate = SR_96KHZ;
else if (rate>=88200) sample_rate = SR_88p2KHZ;
else if (rate>=48000) sample_rate = SR_48KHZ;
else if (rate>=44100) sample_rate = SR_44p1KHZ;
else if (rate>=32000) sample_rate = SR_32KHZ;
else if (rate>=24000) sample_rate = SR_24KHZ;
else if (rate>=22050) sample_rate = SR_22p05KHZ;
else if (rate>=16000) sample_rate = SR_16KHZ;
else if (rate>=11020) sample_rate = SR_11p02KHZ;
else if (rate>= 8000) sample_rate = SR_8KHZ;
else sample_rate = SR_7p35KHZ;
int i;
for(i = 0; i < MAX_I2S_OBJS; i++) {
if (mask & (1 << i)) {
i2s_t * pi2s_obj = &pi2s[i]->i2s_obj;
pi2s[i]->sampl_err = 0;
pi2s_obj->sampling_rate = sample_rate;
#if USE_RTL_I2S_API
i2s_set_param(pi2s_obj, pi2s_obj->channel_num, pi2s_obj->sampling_rate, pi2s_obj->word_length);
#else
pi2s_obj->I2SAdapter.pInitDat->I2SRate = sample_rate;
HalI2SSetRate(pi2s_obj->I2SAdapter.pInitDat);
#endif
}
}
DBG_8195A("I2S: Set Sample Rate %d (x%d)\n", rate, result);
return result;
}
#if defined(PWM_HACK96BIT)
//This routine pushes a single, 32-bit sample to the I2S buffers. Call this at (on average)
//at least the current sample rate. You can also call it quicker: it will suspend the calling
//thread if the buffer is full and resume when there's room again.
u32 i2sPushPWMSamples(u32 sample) {
int i;
for(i = 0; i < MAX_I2S_OBJS; i++) {
PI2S_OBJS pi2s_cur = pi2s[i];
PHAL_I2S_ADAPTER I2SAdapter = &pi2s_cur->i2s_obj.I2SAdapter;
while(pi2s_cur->currDMABuff == NULL){
#if USE_RTL_I2S_API
pi2s_cur->currDMABuff = i2s_get_tx_page(&pi2s_cur->i2s_obj);
if(pi2s_cur->currDMABuff == NULL) RtlDownSema(&I2sTxSema);
#else
u8 page_idx = HalI2SGetTxPage((VOID*)I2SAdapter->pInitDat);
if(page_idx < I2S_DMA_PAGE_NUM) pi2s_cur->currDMABuff = ((u32 *)I2SAdapter->TxPageList[page_idx]);
else xSemaphoreTake(I2sTxSema, portMAX_DELAY);
// RtlDownSema(&I2sTxSema);
#endif
pi2s_cur->currDMABuffPos = 0;
}
u32 *p = &pi2s_cur->currDMABuff[pi2s_cur->currDMABuffPos];
if(i) sample >>= 16;
s32 smp = (s16)sample + 0x8000 + pi2s_cur->sampl_err;
if (smp > 0xffff) smp = 0xffff;
else if (smp < 0) smp = 0;
u8 x = smp/(u16)(0x10000/97);
pi2s_cur->sampl_err = smp - x * (u16)(0x10000/97);
if(x < 24) {
*p++ = (1 << x) -1;
*p++ = 0;
*p++ = 0;
*p = 0;
}
else if (x < 48) {
*p++ = 0xFFFFFFFF;
*p++ = (1 << (x - 24)) -1;
*p++ = 0;
*p = 0;
}
else if (x < 72) {
*p++ = 0xFFFFFFFF;
*p++ = 0xFFFFFFFF;
*p++ = (1 << (x - 48)) -1;
*p = 0;
}
else if (x < 96) {
*p++ = 0xFFFFFFFF;
*p++ = 0xFFFFFFFF;
*p++ = 0xFFFFFFFF;
*p = (1 << (x - 72)) -1;
}
else {
*p++ = 0xFFFFFFFF;
*p++ = 0xFFFFFFFF;
*p++ = 0xFFFFFFFF;
*p = 0xFFFFFFFF;
}
pi2s_cur->currDMABuffPos += 4;
}
portENTER_CRITICAL();
for(i = 0; i < MAX_I2S_OBJS; i++) {
PI2S_OBJS pi2s_cur = pi2s[i];
if (pi2s_cur->currDMABuffPos > pi2s_cur->i2s_obj.InitDat.I2SPageSize) {
#if USE_RTL_I2S_API
i2s_send_page(&pi2s_cur->i2s_obj, pi2s_cur->currDMABuff);
#else
PHAL_I2S_ADAPTER I2SAdapter = &pi2s_cur->i2s_obj.I2SAdapter;
int n;
for (n = 0; n < I2S_DMA_PAGE_NUM; n++) {
if (I2SAdapter->TxPageList[n] == pi2s_cur->currDMABuff) {
HalI2SPageSend(I2SAdapter->pInitDat, n);
HAL_I2S_WRITE32(i, REG_I2S_TX_PAGE0_OWN + 4 * n, BIT_PAGE_I2S_OWN_BIT);
break; // break the for loop
}
}
#endif
pi2s_cur->currDMABuff = NULL;
}
}
portEXIT_CRITICAL();
}
#endif
#if I2S_DEBUG_LEVEL > 1
long i2s1GetUnderrunCnt(int num) {
return pi2s[num]->underrunCnt;
}
#endif

View file

@ -1,14 +0,0 @@
#include "rtl8195a/rtl_common.h"
/*
char unalChar(const char *adr) {
return (*((unsigned int *)((unsigned int)adr & (~3))))>>(((unsigned int)adr & 3) << 3);
}
*/
short unalShort(const short *adr) {
int *p=(int *)((int)adr&(~3));
int v=*p;
int w=((int)adr&3);
if (w==0) return v; else return (v>>16);
}

View file

@ -1,236 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: bit.c,v 1.12 2004/01/23 09:41:32 rob Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# ifdef HAVE_LIMITS_H
# include <limits.h>
# else
# define CHAR_BIT 8
# endif
# include "bit.h"
/*
* This is the lookup table for computing the CRC-check word.
* As described in section 2.4.3.1 and depicted in Figure A.9
* of ISO/IEC 11172-3, the generator polynomial is:
*
* G(X) = X^16 + X^15 + X^2 + 1
*/
static
unsigned short const ICACHE_RODATA_ATTR crc_table[256] = {
0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011,
0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022,
0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072,
0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041,
0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2,
0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1,
0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1,
0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082,
0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1,
0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1,
0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2,
0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151,
0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162,
0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132,
0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101,
0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312,
0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371,
0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342,
0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1,
0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2,
0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2,
0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381,
0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291,
0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2,
0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1,
0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252,
0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261,
0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231,
0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202
};
# define CRC_POLY 0x8005
/*
* NAME: bit->init()
* DESCRIPTION: initialize bit pointer struct
*/
void mad_bit_init(struct mad_bitptr *bitptr, unsigned char const *byte)
{
bitptr->byte = byte;
bitptr->cache = 0;
bitptr->left = CHAR_BIT;
}
/*
* NAME: bit->length()
* DESCRIPTION: return number of bits between start and end points
*/
unsigned int mad_bit_length(struct mad_bitptr const *begin,
struct mad_bitptr const *end)
{
return begin->left +
CHAR_BIT * (end->byte - (begin->byte + 1)) + (CHAR_BIT - end->left);
}
/*
* NAME: bit->nextbyte()
* DESCRIPTION: return pointer to next unprocessed byte
*/
unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *bitptr)
{
return bitptr->left == CHAR_BIT ? bitptr->byte : bitptr->byte + 1;
}
/*
* NAME: bit->skip()
* DESCRIPTION: advance bit pointer
*/
void mad_bit_skip(struct mad_bitptr *bitptr, unsigned int len)
{
bitptr->byte += len / CHAR_BIT;
bitptr->left -= len % CHAR_BIT;
if (bitptr->left > CHAR_BIT) {
bitptr->byte++;
bitptr->left += CHAR_BIT;
}
if (bitptr->left < CHAR_BIT)
bitptr->cache = *bitptr->byte;
}
/*
* NAME: bit->read()
* DESCRIPTION: read an arbitrary number of bits and return their UIMSBF value
*/
unsigned long mad_bit_read(struct mad_bitptr *bitptr, unsigned int len)
{
register unsigned long value;
if (bitptr->left == CHAR_BIT)
bitptr->cache = *bitptr->byte;
if (len < bitptr->left) {
value = (bitptr->cache & ((1 << bitptr->left) - 1)) >>
(bitptr->left - len);
bitptr->left -= len;
return value;
}
/* remaining bits in current byte */
value = bitptr->cache & ((1 << bitptr->left) - 1);
len -= bitptr->left;
bitptr->byte++;
bitptr->left = CHAR_BIT;
/* more bytes */
while (len >= CHAR_BIT) {
value = (value << CHAR_BIT) | *bitptr->byte++;
len -= CHAR_BIT;
}
if (len > 0) {
bitptr->cache = *bitptr->byte;
value = (value << len) | (bitptr->cache >> (CHAR_BIT - len));
bitptr->left -= len;
}
return value;
}
# if 0
/*
* NAME: bit->write()
* DESCRIPTION: write an arbitrary number of bits
*/
void mad_bit_write(struct mad_bitptr *bitptr, unsigned int len,
unsigned long value)
{
unsigned char *ptr;
ptr = (unsigned char *) bitptr->byte;
/* ... */
}
# endif
//extern short unalShort(const short *adr);
/*
* NAME: bit->crc()
* DESCRIPTION: compute CRC-check word
*/
unsigned short mad_bit_crc(struct mad_bitptr bitptr, unsigned int len,
unsigned short init)
{
register unsigned int crc;
for (crc = init; len >= 32; len -= 32) {
register unsigned long data;
data = mad_bit_read(&bitptr, 32);
crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 24)) & 0xff];
crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 16)) & 0xff];
crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 8)) & 0xff];
crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 0)) & 0xff];
}
switch (len / 8) {
case 3: crc = (crc << 8) ^ crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff];
case 2: crc = (crc << 8) ^ crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff];
case 1: crc = (crc << 8) ^ crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff];
len %= 8;
case 0: break;
}
while (len--) {
register unsigned int msb;
msb = mad_bit_read(&bitptr, 1) ^ (crc >> 15);
crc <<= 1;
if (msb & 1)
crc ^= CRC_POLY;
}
return crc & 0xffff;
}

View file

@ -1,577 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: decoder.c,v 1.22 2004/01/23 09:41:32 rob Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
# endif
# ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
# endif
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
# ifdef HAVE_FCNTL_H
# include <fcntl.h>
# endif
# include <stdlib.h>
# ifdef HAVE_ERRNO_H
# include <errno.h>
# endif
# include "stream.h"
# include "frame.h"
# include "synth.h"
# include "decoder.h"
/*
* NAME: decoder->init()
* DESCRIPTION: initialize a decoder object with callback routines
*/
void ICACHE_FLASH_ATTR mad_decoder_init(struct mad_decoder *decoder, void *data,
enum mad_flow (*input_func)(void *, struct mad_stream *),
enum mad_flow (*header_func)(void *, struct mad_header const *),
enum mad_flow (*filter_func)(void *, struct mad_stream const *,
struct mad_frame *),
enum mad_flow (*output_func)(void *, struct mad_header const *,
struct mad_pcm *),
enum mad_flow (*error_func)(void *, struct mad_stream *,
struct mad_frame *),
enum mad_flow (*message_func)(void *, void *, unsigned int *)) {
decoder->mode = -1;
decoder->options = 0;
decoder->async.pid = 0;
decoder->async.in = -1;
decoder->async.out = -1;
decoder->sync = 0;
decoder->cb_data = data;
decoder->input_func = input_func;
decoder->header_func = header_func;
decoder->filter_func = filter_func;
decoder->output_func = output_func;
decoder->error_func = error_func;
decoder->message_func = message_func;
}
int ICACHE_FLASH_ATTR mad_decoder_finish(struct mad_decoder *decoder) {
# if defined(USE_ASYNC)
if (decoder->mode == MAD_DECODER_MODE_ASYNC && decoder->async.pid) {
pid_t pid;
int status;
close(decoder->async.in);
do
pid = waitpid(decoder->async.pid, &status, 0);
while (pid == -1 && errno == EINTR);
decoder->mode = -1;
close(decoder->async.out);
decoder->async.pid = 0;
decoder->async.in = -1;
decoder->async.out = -1;
if (pid == -1)
return -1;
return (!WIFEXITED(status) || WEXITSTATUS(status)) ? -1 : 0;
}
# endif
return 0;
}
# if defined(USE_ASYNC)
static
enum mad_flow ICACHE_FLASH_ATTR send_io(int fd, void const *data, size_t len)
{
char const *ptr = data;
ssize_t count;
while (len) {
do
count = write(fd, ptr, len);
while (count == -1 && errno == EINTR);
if (count == -1)
return MAD_FLOW_BREAK;
len -= count;
ptr += count;
}
return MAD_FLOW_CONTINUE;
}
static
enum mad_flow ICACHE_FLASH_ATTR receive_io(int fd, void *buffer, size_t len)
{
char *ptr = buffer;
ssize_t count;
while (len) {
do
count = read(fd, ptr, len);
while (count == -1 && errno == EINTR);
if (count == -1)
return (errno == EAGAIN) ? MAD_FLOW_IGNORE : MAD_FLOW_BREAK;
else if (count == 0)
return MAD_FLOW_STOP;
len -= count;
ptr += count;
}
return MAD_FLOW_CONTINUE;
}
static
enum mad_flow ICACHE_FLASH_ATTR receive_io_blocking(int fd, void *buffer, size_t len)
{
int flags, blocking;
enum mad_flow result;
flags = fcntl(fd, F_GETFL);
if (flags == -1)
return MAD_FLOW_BREAK;
blocking = flags & ~O_NONBLOCK;
if (blocking != flags &&
fcntl(fd, F_SETFL, blocking) == -1)
return MAD_FLOW_BREAK;
result = receive_io(fd, buffer, len);
if (flags != blocking &&
fcntl(fd, F_SETFL, flags) == -1)
return MAD_FLOW_BREAK;
return result;
}
static
enum mad_flow ICACHE_FLASH_ATTR send(int fd, void const *message, unsigned int size)
{
enum mad_flow result;
/* send size */
result = send_io(fd, &size, sizeof(size));
/* send message */
if (result == MAD_FLOW_CONTINUE)
result = send_io(fd, message, size);
return result;
}
static
enum mad_flow ICACHE_FLASH_ATTR receive(int fd, void **message, unsigned int *size)
{
enum mad_flow result;
unsigned int actual;
if (*message == 0)
*size = 0;
/* receive size */
result = receive_io(fd, &actual, sizeof(actual));
/* receive message */
if (result == MAD_FLOW_CONTINUE) {
if (actual > *size)
actual -= *size;
else {
*size = actual;
actual = 0;
}
if (*size > 0) {
if (*message == 0) {
*message = malloc(*size);
if (*message == 0)
return MAD_FLOW_BREAK;
}
result = receive_io_blocking(fd, *message, *size);
}
/* throw away remainder of message */
while (actual && result == MAD_FLOW_CONTINUE) {
char sink[256];
unsigned int len;
len = actual > sizeof(sink) ? sizeof(sink) : actual;
result = receive_io_blocking(fd, sink, len);
actual -= len;
}
}
return result;
}
static
enum mad_flow ICACHE_FLASH_ATTR check_message(struct mad_decoder *decoder)
{
enum mad_flow result;
void *message = 0;
unsigned int size;
result = receive(decoder->async.in, &message, &size);
if (result == MAD_FLOW_CONTINUE) {
if (decoder->message_func == 0)
size = 0;
else {
result = decoder->message_func(decoder->cb_data, message, &size);
if (result == MAD_FLOW_IGNORE ||
result == MAD_FLOW_BREAK)
size = 0;
}
if (send(decoder->async.out, message, size) != MAD_FLOW_CONTINUE)
result = MAD_FLOW_BREAK;
}
if (message)
free(message);
return result;
}
# endif
static enum mad_flow ICACHE_FLASH_ATTR error_default(void *data,
struct mad_stream *stream, struct mad_frame *frame) {
int *bad_last_frame = data;
switch (stream->error) {
case MAD_ERROR_BADCRC:
if (*bad_last_frame)
mad_frame_mute(frame);
else
*bad_last_frame = 1;
return MAD_FLOW_IGNORE;
default:
return MAD_FLOW_CONTINUE;
}
}
static
int ICACHE_FLASH_ATTR run_sync(struct mad_decoder *decoder) {
enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
void *error_data;
int bad_last_frame = 0;
struct mad_stream *stream;
struct mad_frame *frame;
struct mad_synth *synth;
int result = 0;
int r;
// printf("run_sync\n");
if (decoder->input_func == 0)
return 0;
if (decoder->error_func) {
error_func = decoder->error_func;
error_data = decoder->cb_data;
} else {
error_func = error_default;
error_data = &bad_last_frame;
}
stream = &decoder->sync->stream;
frame = &decoder->sync->frame;
synth = &decoder->sync->synth;
mad_stream_init(stream);
mad_frame_init(frame);
mad_synth_init(synth);
mad_stream_options(stream, decoder->options);
do {
r = decoder->input_func(decoder->cb_data, stream);
// printf("Input fn: %d\n", r);
switch (r) {
case MAD_FLOW_STOP:
goto done;
case MAD_FLOW_BREAK:
goto fail;
case MAD_FLOW_IGNORE:
continue;
case MAD_FLOW_CONTINUE:
break;
}
while (1) {
# if defined(USE_ASYNC)
if (decoder->mode == MAD_DECODER_MODE_ASYNC) {
switch (check_message(decoder)) {
case MAD_FLOW_IGNORE:
case MAD_FLOW_CONTINUE:
break;
case MAD_FLOW_BREAK:
goto fail;
case MAD_FLOW_STOP:
goto done;
}
}
# endif
if (decoder->header_func) {
r = mad_header_decode(&frame->header, stream);
// printf("mad_header_decode_func: %d\n", r);
if (r != -1) {
if (!MAD_RECOVERABLE(stream->error))
break;
switch (error_func(error_data, stream, frame)) {
case MAD_FLOW_STOP:
goto done;
case MAD_FLOW_BREAK:
goto fail;
case MAD_FLOW_IGNORE:
case MAD_FLOW_CONTINUE:
default:
continue;
}
}
switch (decoder->header_func(decoder->cb_data, &frame->header)) {
case MAD_FLOW_STOP:
goto done;
case MAD_FLOW_BREAK:
goto fail;
case MAD_FLOW_IGNORE:
continue;
case MAD_FLOW_CONTINUE:
break;
}
}
r = mad_frame_decode(frame, stream);
// printf("mad_frame_decode: %d\n", r);
if (r == -1) {
if (!MAD_RECOVERABLE(stream->error))
break;
switch (error_func(error_data, stream, frame)) {
case MAD_FLOW_STOP:
goto done;
case MAD_FLOW_BREAK:
goto fail;
case MAD_FLOW_IGNORE:
break;
case MAD_FLOW_CONTINUE:
default:
continue;
}
} else
bad_last_frame = 0;
if (decoder->filter_func) {
switch (decoder->filter_func(decoder->cb_data, stream, frame)) {
case MAD_FLOW_STOP:
goto done;
case MAD_FLOW_BREAK:
goto fail;
case MAD_FLOW_IGNORE:
continue;
case MAD_FLOW_CONTINUE:
break;
}
}
mad_synth_frame(synth, frame);
// printf("Calling output fn\n");
if (decoder->output_func) {
switch (decoder->output_func(decoder->cb_data, &frame->header,
&synth->pcm)) {
case MAD_FLOW_STOP:
goto done;
case MAD_FLOW_BREAK:
goto fail;
case MAD_FLOW_IGNORE:
case MAD_FLOW_CONTINUE:
break;
}
}
}
} while (stream->error == MAD_ERROR_BUFLEN);
fail: result = -1;
done: mad_synth_finish(synth);
mad_frame_finish(frame);
mad_stream_finish(stream);
return result;
}
# if defined(USE_ASYNC)
static
int ICACHE_FLASH_ATTR run_async(struct mad_decoder *decoder)
{
pid_t pid;
int ptoc[2], ctop[2], flags;
if (pipe(ptoc) == -1)
return -1;
if (pipe(ctop) == -1) {
close(ptoc[0]);
close(ptoc[1]);
return -1;
}
flags = fcntl(ptoc[0], F_GETFL);
if (flags == -1 ||
fcntl(ptoc[0], F_SETFL, flags | O_NONBLOCK) == -1) {
close(ctop[0]);
close(ctop[1]);
close(ptoc[0]);
close(ptoc[1]);
return -1;
}
pid = fork();
if (pid == -1) {
close(ctop[0]);
close(ctop[1]);
close(ptoc[0]);
close(ptoc[1]);
return -1;
}
decoder->async.pid = pid;
if (pid) {
/* parent */
close(ptoc[0]);
close(ctop[1]);
decoder->async.in = ctop[0];
decoder->async.out = ptoc[1];
return 0;
}
/* child */
close(ptoc[1]);
close(ctop[0]);
decoder->async.in = ptoc[0];
decoder->async.out = ctop[1];
_exit(run_sync(decoder));
/* not reached */
return -1;
}
# endif
/*
* NAME: decoder->run()
* DESCRIPTION: run the decoder thread either synchronously or asynchronously
*/
int ICACHE_FLASH_ATTR mad_decoder_run(struct mad_decoder *decoder,
enum mad_decoder_mode mode) {
int result;
int (*run)(struct mad_decoder *) = 0;
// static struct sync_t decsync; //statically-allocated decoder obj
switch (decoder->mode = mode) {
case MAD_DECODER_MODE_SYNC:
run = run_sync;
break;
case MAD_DECODER_MODE_ASYNC:
# if defined(USE_ASYNC)
run = run_async;
# endif
break;
}
if (run == 0)
return -1;
decoder->sync = pvPortMalloc(sizeof(*decoder->sync));
// decoder->sync = &decsync;
if (decoder->sync == 0)
return -1;
rtl_memset(decoder->sync, 0, sizeof(*decoder->sync));
result = run(decoder);
vPortFree(decoder->sync);
decoder->sync = 0;
return result;
}
/*
* NAME: decoder->message()
* DESCRIPTION: send a message to and receive a reply from the decoder process
*/
int ICACHE_FLASH_ATTR mad_decoder_message(struct mad_decoder *decoder,
void *message, unsigned int *len) {
# if defined(USE_ASYNC)
if (decoder->mode != MAD_DECODER_MODE_ASYNC ||
send(decoder->async.out, message, *len) != MAD_FLOW_CONTINUE ||
receive(decoder->async.in, &message, len) != MAD_FLOW_CONTINUE)
return -1;
return 0;
# else
return -1;
# endif
}

View file

@ -1,81 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: fixed.c,v 1.13 2004/01/23 09:41:32 rob Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include "fixed.h"
/*
* NAME: fixed->abs()
* DESCRIPTION: return absolute value of a fixed-point number
*/
mad_fixed_t ICACHE_FLASH_ATTR mad_f_abs(mad_fixed_t x)
{
return x < 0 ? -x : x;
}
/*
* NAME: fixed->div()
* DESCRIPTION: perform division using fixed-point math
*/
mad_fixed_t ICACHE_FLASH_ATTR mad_f_div(mad_fixed_t x, mad_fixed_t y)
{
mad_fixed_t q, r;
unsigned int bits;
q = mad_f_abs(x / y);
if (x < 0) {
x = -x;
y = -y;
}
r = x % y;
if (y < 0) {
x = -x;
y = -y;
}
if (q > mad_f_intpart(MAD_F_MAX) &&
!(q == -mad_f_intpart(MAD_F_MIN) && r == 0 && (x < 0) != (y < 0)))
return 0;
for (bits = MAD_F_FRACBITS; bits && r; --bits) {
q <<= 1, r <<= 1;
if (r >= y)
r -= y, ++q;
}
/* round */
if (2 * r >= y)
++q;
/* fix sign */
if ((x < 0) != (y < 0))
q = -q;
return q << bits;
}

View file

@ -1,504 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: frame.c,v 1.29 2004/02/04 22:59:19 rob Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include <stdlib.h>
# include "bit.h"
# include "stream.h"
# include "frame.h"
# include "timer.h"
//# include "layer12.h"
# include "layer3.h"
static
unsigned long const ICACHE_RODATA_ATTR bitrate_table[5][15] = {
/* MPEG-1 */
{ 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */
256000, 288000, 320000, 352000, 384000, 416000, 448000 },
{ 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */
128000, 160000, 192000, 224000, 256000, 320000, 384000 },
{ 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */
112000, 128000, 160000, 192000, 224000, 256000, 320000 },
/* MPEG-2 LSF */
{ 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */
128000, 144000, 160000, 176000, 192000, 224000, 256000 },
{ 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */
64000, 80000, 96000, 112000, 128000, 144000, 160000 } /* II & III */
};
static
unsigned int const ICACHE_RODATA_ATTR samplerate_table[3] = { 44100, 48000, 32000 };
static
int ICACHE_RODATA_ATTR (*const decoder_table[3])(struct mad_stream *, struct mad_frame *) = {
// mad_layer_I,
// mad_layer_II,
NULL, NULL,
mad_layer_III
};
/*
* NAME: header->init()
* DESCRIPTION: initialize header struct
*/
void ICACHE_FLASH_ATTR mad_header_init(struct mad_header *header)
{
header->layer = 0;
header->mode = 0;
header->mode_extension = 0;
header->emphasis = 0;
header->bitrate = 0;
header->samplerate = 0;
header->crc_check = 0;
header->crc_target = 0;
header->flags = 0;
header->private_bits = 0;
header->duration = mad_timer_zero;
}
/*
* NAME: frame->init()
* DESCRIPTION: initialize frame struct
*/
void ICACHE_FLASH_ATTR mad_frame_init(struct mad_frame *frame)
{
mad_header_init(&frame->header);
frame->options = 0;
frame->overlap = 0;
mad_frame_mute(frame);
}
/*
* NAME: frame->finish()
* DESCRIPTION: deallocate any dynamic memory associated with frame
*/
void ICACHE_FLASH_ATTR mad_frame_finish(struct mad_frame *frame)
{
mad_header_finish(&frame->header);
if (frame->overlap) {
vPortFree(frame->overlap);
frame->overlap = 0;
}
}
/*
* NAME: decode_header()
* DESCRIPTION: read header data and following CRC word
*/
static
int ICACHE_FLASH_ATTR decode_header(struct mad_header *header, struct mad_stream *stream)
{
unsigned int index;
header->flags = 0;
header->private_bits = 0;
/* header() */
/* syncword */
mad_bit_skip(&stream->ptr, 11);
/* MPEG 2.5 indicator (really part of syncword) */
if (mad_bit_read(&stream->ptr, 1) == 0)
header->flags |= MAD_FLAG_MPEG_2_5_EXT;
/* ID */
if (mad_bit_read(&stream->ptr, 1) == 0)
header->flags |= MAD_FLAG_LSF_EXT;
else if (header->flags & MAD_FLAG_MPEG_2_5_EXT) {
stream->error = MAD_ERROR_LOSTSYNC;
return -1;
}
/* layer */
header->layer = 4 - mad_bit_read(&stream->ptr, 2);
if (header->layer == 4) {
stream->error = MAD_ERROR_BADLAYER;
return -1;
}
/* protection_bit */
if (mad_bit_read(&stream->ptr, 1) == 0) {
header->flags |= MAD_FLAG_PROTECTION;
header->crc_check = mad_bit_crc(stream->ptr, 16, 0xffff);
}
/* bitrate_index */
index = mad_bit_read(&stream->ptr, 4);
if (index == 15) {
stream->error = MAD_ERROR_BADBITRATE;
return -1;
}
if (header->flags & MAD_FLAG_LSF_EXT)
header->bitrate = bitrate_table[3 + (header->layer >> 1)][index];
else
header->bitrate = bitrate_table[header->layer - 1][index];
/* sampling_frequency */
index = mad_bit_read(&stream->ptr, 2);
if (index == 3) {
stream->error = MAD_ERROR_BADSAMPLERATE;
return -1;
}
header->samplerate = samplerate_table[index];
if (header->flags & MAD_FLAG_LSF_EXT) {
header->samplerate /= 2;
if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
header->samplerate /= 2;
}
/* padding_bit */
if (mad_bit_read(&stream->ptr, 1))
header->flags |= MAD_FLAG_PADDING;
/* private_bit */
if (mad_bit_read(&stream->ptr, 1))
header->private_bits |= MAD_PRIVATE_HEADER;
/* mode */
header->mode = 3 - mad_bit_read(&stream->ptr, 2);
/* mode_extension */
header->mode_extension = mad_bit_read(&stream->ptr, 2);
/* copyright */
if (mad_bit_read(&stream->ptr, 1))
header->flags |= MAD_FLAG_COPYRIGHT;
/* original/copy */
if (mad_bit_read(&stream->ptr, 1))
header->flags |= MAD_FLAG_ORIGINAL;
/* emphasis */
header->emphasis = mad_bit_read(&stream->ptr, 2);
# if defined(OPT_STRICT)
/*
* ISO/IEC 11172-3 says this is a reserved emphasis value, but
* streams exist which use it anyway. Since the value is not important
* to the decoder proper, we allow it unless OPT_STRICT is defined.
*/
if (header->emphasis == MAD_EMPHASIS_RESERVED) {
stream->error = MAD_ERROR_BADEMPHASIS;
return -1;
}
# endif
/* error_check() */
/* crc_check */
if (header->flags & MAD_FLAG_PROTECTION)
header->crc_target = mad_bit_read(&stream->ptr, 16);
return 0;
}
/*
* NAME: free_bitrate()
* DESCRIPTION: attempt to discover the bitstream's free bitrate
*/
static
int ICACHE_FLASH_ATTR free_bitrate(struct mad_stream *stream, struct mad_header const *header)
{
struct mad_bitptr keep_ptr;
unsigned long rate = 0;
unsigned int pad_slot, slots_per_frame;
unsigned char const *ptr = 0;
keep_ptr = stream->ptr;
pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0;
slots_per_frame = (header->layer == MAD_LAYER_III &&
(header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144;
while (mad_stream_sync(stream) == 0) {
struct mad_stream peek_stream;
struct mad_header peek_header;
peek_stream = *stream;
peek_header = *header;
if (decode_header(&peek_header, &peek_stream) == 0 &&
peek_header.layer == header->layer &&
peek_header.samplerate == header->samplerate) {
unsigned int N;
ptr = mad_bit_nextbyte(&stream->ptr);
N = ptr - stream->this_frame;
if (header->layer == MAD_LAYER_I) {
rate = (unsigned long) header->samplerate *
(N - 4 * pad_slot + 4) / 48 / 1000;
}
else {
rate = (unsigned long) header->samplerate *
(N - pad_slot + 1) / slots_per_frame / 1000;
}
if (rate >= 8)
break;
}
mad_bit_skip(&stream->ptr, 8);
}
stream->ptr = keep_ptr;
if (rate < 8 || (header->layer == MAD_LAYER_III && rate > 640)) {
stream->error = MAD_ERROR_LOSTSYNC;
return -1;
}
stream->freerate = rate * 1000;
return 0;
}
/*
* NAME: header->decode()
* DESCRIPTION: read the next frame header from the stream
*/
int ICACHE_FLASH_ATTR mad_header_decode(struct mad_header *header, struct mad_stream *stream)
{
register unsigned char const *ptr, *end;
unsigned int pad_slot, N;
ptr = stream->next_frame;
end = stream->bufend;
if (ptr == 0) {
stream->error = MAD_ERROR_BUFPTR;
goto fail;
}
/* stream skip */
if (stream->skiplen) {
if (!stream->sync)
ptr = stream->this_frame;
if (end - ptr < stream->skiplen) {
stream->skiplen -= end - ptr;
stream->next_frame = end;
stream->error = MAD_ERROR_BUFLEN;
goto fail;
}
ptr += stream->skiplen;
stream->skiplen = 0;
stream->sync = 1;
}
sync:
/* synchronize */
if (stream->sync) {
if (end - ptr < MAD_BUFFER_GUARD) {
stream->next_frame = ptr;
stream->error = MAD_ERROR_BUFLEN;
goto fail;
}
else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
/* mark point where frame sync word was expected */
stream->this_frame = ptr;
stream->next_frame = ptr + 1;
stream->error = MAD_ERROR_LOSTSYNC;
goto fail;
}
}
else {
mad_bit_init(&stream->ptr, ptr);
if (mad_stream_sync(stream) == -1) {
if (end - stream->next_frame >= MAD_BUFFER_GUARD)
stream->next_frame = end - MAD_BUFFER_GUARD;
stream->error = MAD_ERROR_BUFLEN;
goto fail;
}
ptr = mad_bit_nextbyte(&stream->ptr);
}
/* begin processing */
stream->this_frame = ptr;
stream->next_frame = ptr + 1; /* possibly bogus sync word */
mad_bit_init(&stream->ptr, stream->this_frame);
if (decode_header(header, stream) == -1)
goto fail;
/* calculate frame duration */
mad_timer_set(&header->duration, 0,
32 * MAD_NSBSAMPLES(header), header->samplerate);
/* calculate free bit rate */
if (header->bitrate == 0) {
if ((stream->freerate == 0 || !stream->sync ||
(header->layer == MAD_LAYER_III && stream->freerate > 640000)) &&
free_bitrate(stream, header) == -1)
goto fail;
header->bitrate = stream->freerate;
header->flags |= MAD_FLAG_FREEFORMAT;
}
/* calculate beginning of next frame */
pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0;
if (header->layer == MAD_LAYER_I)
N = ((12 * header->bitrate / header->samplerate) + pad_slot) * 4;
else {
unsigned int slots_per_frame;
slots_per_frame = (header->layer == MAD_LAYER_III &&
(header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144;
N = (slots_per_frame * header->bitrate / header->samplerate) + pad_slot;
}
/* verify there is enough data left in buffer to decode this frame */
if (N + MAD_BUFFER_GUARD > end - stream->this_frame) {
stream->next_frame = stream->this_frame;
stream->error = MAD_ERROR_BUFLEN;
goto fail;
}
stream->next_frame = stream->this_frame + N;
if (!stream->sync) {
/* check that a valid frame header follows this frame */
ptr = stream->next_frame;
if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
ptr = stream->next_frame = stream->this_frame + 1;
goto sync;
}
stream->sync = 1;
}
header->flags |= MAD_FLAG_INCOMPLETE;
return 0;
fail:
stream->sync = 0;
return -1;
}
/*
* NAME: frame->decode()
* DESCRIPTION: decode a single frame from a bitstream
*/
int ICACHE_FLASH_ATTR mad_frame_decode(struct mad_frame *frame, struct mad_stream *stream)
{
frame->options = stream->options;
/* header() */
/* error_check() */
if (!(frame->header.flags & MAD_FLAG_INCOMPLETE) &&
mad_header_decode(&frame->header, stream) == -1)
goto fail;
/* audio_data() */
frame->header.flags &= ~MAD_FLAG_INCOMPLETE;
if (decoder_table[frame->header.layer - 1](stream, frame) == -1) {
if (!MAD_RECOVERABLE(stream->error))
stream->next_frame = stream->this_frame;
goto fail;
}
/* ancillary_data() */
if (frame->header.layer != MAD_LAYER_III) {
struct mad_bitptr next_frame;
mad_bit_init(&next_frame, stream->next_frame);
stream->anc_ptr = stream->ptr;
stream->anc_bitlen = mad_bit_length(&stream->ptr, &next_frame);
mad_bit_finish(&next_frame);
}
return 0;
fail:
stream->anc_bitlen = 0;
return -1;
}
/*
* NAME: frame->mute()
* DESCRIPTION: zero all subband values so the frame becomes silent
*/
void ICACHE_FLASH_ATTR mad_frame_mute(struct mad_frame *frame)
{
unsigned int s, sb;
for (s = 0; s < 36; ++s) {
for (sb = 0; sb < 32; ++sb) {
frame->sbsample[0][s][sb] =
frame->sbsample[1][s][sb] = 0;
}
}
if (frame->overlap) {
for (s = 0; s < 18; ++s) {
for (sb = 0; sb < 32; ++sb) {
(*frame->overlap)[0][sb][s] =
(*frame->overlap)[1][sb][s] = 0;
}
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,91 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: version.c,v 1.15 2004/01/23 09:41:33 rob Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include "mad_version.h"
char const mad_version[] = "MPEG Audio Decoder " MAD_VERSION;
char const mad_copyright[] = "Copyright (C) " MAD_PUBLISHYEAR " " MAD_AUTHOR;
char const mad_author[] = MAD_AUTHOR " <" MAD_EMAIL ">";
char const mad_build[] = ""
# if defined(DEBUG)
"DEBUG "
# elif defined(NDEBUG)
"NDEBUG "
# endif
# if defined(EXPERIMENTAL)
"EXPERIMENTAL "
# endif
# if defined(FPM_64BIT)
"FPM_64BIT "
# elif defined(FPM_INTEL)
"FPM_INTEL "
# elif defined(FPM_ARM)
"FPM_ARM "
# elif defined(FPM_MIPS)
"FPM_MIPS "
# elif defined(FPM_SPARC)
"FPM_SPARC "
# elif defined(FPM_PPC)
"FPM_PPC "
# elif defined(FPM_DEFAULT)
"FPM_DEFAULT "
# endif
# if defined(ASO_IMDCT)
"ASO_IMDCT "
# endif
# if defined(ASO_INTERLEAVE1)
"ASO_INTERLEAVE1 "
# endif
# if defined(ASO_INTERLEAVE2)
"ASO_INTERLEAVE2 "
# endif
# if defined(ASO_ZEROCHECK)
"ASO_ZEROCHECK "
# endif
# if defined(OPT_SPEED)
"OPT_SPEED "
# elif defined(OPT_ACCURACY)
"OPT_ACCURACY "
# endif
# if defined(OPT_SSO)
"OPT_SSO "
# endif
# if defined(OPT_DCTO) /* never defined here */
"OPT_DCTO "
# endif
# if defined(OPT_STRICT)
"OPT_STRICT "
# endif
;

View file

@ -1,534 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: layer12.c,v 1.17 2004/02/05 09:02:39 rob Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# ifdef HAVE_LIMITS_H
# include <limits.h>
# else
# define CHAR_BIT 8
# endif
# include "fixed.h"
# include "bit.h"
# include "stream.h"
# include "frame.h"
# include "mad/mpg12/layer12.h"
/*
* scalefactor table
* used in both Layer I and Layer II decoding
*/
static
mad_fixed_t const ICACHE_RODATA_ATTR sf_table[64] = {
# include "sf_table.dat"
};
/* --- Layer I ------------------------------------------------------------- */
/* linear scaling table */
static
mad_fixed_t const ICACHE_RODATA_ATTR linear_table[14] = {
MAD_F(0x15555555), /* 2^2 / (2^2 - 1) == 1.33333333333333 */
MAD_F(0x12492492), /* 2^3 / (2^3 - 1) == 1.14285714285714 */
MAD_F(0x11111111), /* 2^4 / (2^4 - 1) == 1.06666666666667 */
MAD_F(0x10842108), /* 2^5 / (2^5 - 1) == 1.03225806451613 */
MAD_F(0x10410410), /* 2^6 / (2^6 - 1) == 1.01587301587302 */
MAD_F(0x10204081), /* 2^7 / (2^7 - 1) == 1.00787401574803 */
MAD_F(0x10101010), /* 2^8 / (2^8 - 1) == 1.00392156862745 */
MAD_F(0x10080402), /* 2^9 / (2^9 - 1) == 1.00195694716243 */
MAD_F(0x10040100), /* 2^10 / (2^10 - 1) == 1.00097751710655 */
MAD_F(0x10020040), /* 2^11 / (2^11 - 1) == 1.00048851978505 */
MAD_F(0x10010010), /* 2^12 / (2^12 - 1) == 1.00024420024420 */
MAD_F(0x10008004), /* 2^13 / (2^13 - 1) == 1.00012208521548 */
MAD_F(0x10004001), /* 2^14 / (2^14 - 1) == 1.00006103888177 */
MAD_F(0x10002000) /* 2^15 / (2^15 - 1) == 1.00003051850948 */
};
/*
* NAME: I_sample()
* DESCRIPTION: decode one requantized Layer I sample from a bitstream
*/
static
mad_fixed_t ICACHE_FLASH_ATTR I_sample(struct mad_bitptr *ptr, unsigned int nb)
{
mad_fixed_t sample;
sample = mad_bit_read(ptr, nb);
/* invert most significant bit, extend sign, then scale to fixed format */
sample ^= 1 << (nb - 1);
sample |= -(sample & (1 << (nb - 1)));
sample <<= MAD_F_FRACBITS - (nb - 1);
/* requantize the sample */
/* s'' = (2^nb / (2^nb - 1)) * (s''' + 2^(-nb + 1)) */
sample += MAD_F_ONE >> (nb - 1);
return mad_f_mul(sample, linear_table[nb - 2]);
/* s' = factor * s'' */
/* (to be performed by caller) */
}
/*
* NAME: layer->I()
* DESCRIPTION: decode a single Layer I frame
*/
int ICACHE_FLASH_ATTR mad_layer_I(struct mad_stream *stream, struct mad_frame *frame)
{
struct mad_header *header = &frame->header;
unsigned int nch, bound, ch, s, sb, nb;
unsigned char allocation[2][32], scalefactor[2][32];
nch = MAD_NCHANNELS(header);
bound = 32;
if (header->mode == MAD_MODE_JOINT_STEREO) {
header->flags |= MAD_FLAG_I_STEREO;
bound = 4 + header->mode_extension * 4;
}
/* check CRC word */
if (header->flags & MAD_FLAG_PROTECTION) {
header->crc_check =
mad_bit_crc(stream->ptr, 4 * (bound * nch + (32 - bound)),
header->crc_check);
if (header->crc_check != header->crc_target &&
!(frame->options & MAD_OPTION_IGNORECRC)) {
stream->error = MAD_ERROR_BADCRC;
return -1;
}
}
/* decode bit allocations */
for (sb = 0; sb < bound; ++sb) {
for (ch = 0; ch < nch; ++ch) {
nb = mad_bit_read(&stream->ptr, 4);
if (nb == 15) {
stream->error = MAD_ERROR_BADBITALLOC;
return -1;
}
allocation[ch][sb] = nb ? nb + 1 : 0;
}
}
for (sb = bound; sb < 32; ++sb) {
nb = mad_bit_read(&stream->ptr, 4);
if (nb == 15) {
stream->error = MAD_ERROR_BADBITALLOC;
return -1;
}
allocation[0][sb] =
allocation[1][sb] = nb ? nb + 1 : 0;
}
/* decode scalefactors */
for (sb = 0; sb < 32; ++sb) {
for (ch = 0; ch < nch; ++ch) {
if (allocation[ch][sb]) {
scalefactor[ch][sb] = mad_bit_read(&stream->ptr, 6);
# if defined(OPT_STRICT)
/*
* Scalefactor index 63 does not appear in Table B.1 of
* ISO/IEC 11172-3. Nonetheless, other implementations accept it,
* so we only reject it if OPT_STRICT is defined.
*/
if (scalefactor[ch][sb] == 63) {
stream->error = MAD_ERROR_BADSCALEFACTOR;
return -1;
}
# endif
}
}
}
/* decode samples */
for (s = 0; s < 12; ++s) {
for (sb = 0; sb < bound; ++sb) {
for (ch = 0; ch < nch; ++ch) {
nb = allocation[ch][sb];
frame->sbsample[ch][s][sb] = nb ?
mad_f_mul(I_sample(&stream->ptr, nb),
sf_table[scalefactor[ch][sb]]) : 0;
}
}
for (sb = bound; sb < 32; ++sb) {
if ((nb = allocation[0][sb])) {
mad_fixed_t sample;
sample = I_sample(&stream->ptr, nb);
for (ch = 0; ch < nch; ++ch) {
frame->sbsample[ch][s][sb] =
mad_f_mul(sample, sf_table[scalefactor[ch][sb]]);
}
}
else {
for (ch = 0; ch < nch; ++ch)
frame->sbsample[ch][s][sb] = 0;
}
}
}
return 0;
}
/* --- Layer II ------------------------------------------------------------ */
/* possible quantization per subband table */
static
struct {
unsigned int sblimit;
unsigned char const offsets[30];
} const ICACHE_RODATA_ATTR sbquant_table[5] = {
/* ISO/IEC 11172-3 Table B.2a */
{ 27, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, /* 0 */
3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0 } },
/* ISO/IEC 11172-3 Table B.2b */
{ 30, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, /* 1 */
3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0 } },
/* ISO/IEC 11172-3 Table B.2c */
{ 8, { 5, 5, 2, 2, 2, 2, 2, 2 } }, /* 2 */
/* ISO/IEC 11172-3 Table B.2d */
{ 12, { 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 } }, /* 3 */
/* ISO/IEC 13818-3 Table B.1 */
{ 30, { 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, /* 4 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }
};
/* bit allocation table */
static
struct {
unsigned short nbal;
unsigned short offset;
} const ICACHE_RODATA_ATTR bitalloc_table[8] = {
{ 2, 0 }, /* 0 */
{ 2, 3 }, /* 1 */
{ 3, 3 }, /* 2 */
{ 3, 1 }, /* 3 */
{ 4, 2 }, /* 4 */
{ 4, 3 }, /* 5 */
{ 4, 4 }, /* 6 */
{ 4, 5 } /* 7 */
};
/* offsets into quantization class table */
static
unsigned char const ICACHE_RODATA_ATTR offset_table[6][15] = {
{ 0, 1, 16 }, /* 0 */
{ 0, 1, 2, 3, 4, 5, 16 }, /* 1 */
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, /* 2 */
{ 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, /* 3 */
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 }, /* 4 */
{ 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 } /* 5 */
};
/* quantization class table */
static
struct quantclass {
unsigned short nlevels;
unsigned char group;
unsigned char bits;
mad_fixed_t C;
mad_fixed_t D;
} const qc_table[17] = {
# include "qc_table.dat"
};
//ICACHE_RODATA_ATTR
/*
* NAME: II_samples()
* DESCRIPTION: decode three requantized Layer II samples from a bitstream
*/
static
void ICACHE_FLASH_ATTR II_samples(struct mad_bitptr *ptr,
struct quantclass const *quantclass,
mad_fixed_t output[3])
{
unsigned int nb, s, sample[3];
if ((nb = quantclass->group)) {
unsigned int c, nlevels;
/* degrouping */
c = mad_bit_read(ptr, quantclass->bits);
nlevels = quantclass->nlevels;
for (s = 0; s < 3; ++s) {
sample[s] = c % nlevels;
c /= nlevels;
}
}
else {
nb = quantclass->bits;
for (s = 0; s < 3; ++s)
sample[s] = mad_bit_read(ptr, nb);
}
for (s = 0; s < 3; ++s) {
mad_fixed_t requantized;
/* invert most significant bit, extend sign, then scale to fixed format */
requantized = sample[s] ^ (1 << (nb - 1));
requantized |= -(requantized & (1 << (nb - 1)));
requantized <<= MAD_F_FRACBITS - (nb - 1);
/* requantize the sample */
/* s'' = C * (s''' + D) */
output[s] = mad_f_mul(requantized + quantclass->D, quantclass->C);
/* s' = factor * s'' */
/* (to be performed by caller) */
}
}
/*
* NAME: layer->II()
* DESCRIPTION: decode a single Layer II frame
*/
int ICACHE_FLASH_ATTR mad_layer_II(struct mad_stream *stream, struct mad_frame *frame)
{
struct mad_header *header = &frame->header;
struct mad_bitptr start;
unsigned int index, sblimit, nbal, nch, bound, gr, ch, s, sb;
unsigned char const *offsets;
unsigned char allocation[2][32], scfsi[2][32], scalefactor[2][32][3];
mad_fixed_t samples[3];
nch = MAD_NCHANNELS(header);
if (header->flags & MAD_FLAG_LSF_EXT)
index = 4;
else if (header->flags & MAD_FLAG_FREEFORMAT)
goto freeformat;
else {
unsigned long bitrate_per_channel;
bitrate_per_channel = header->bitrate;
if (nch == 2) {
bitrate_per_channel /= 2;
# if defined(OPT_STRICT)
/*
* ISO/IEC 11172-3 allows only single channel mode for 32, 48, 56, and
* 80 kbps bitrates in Layer II, but some encoders ignore this
* restriction. We enforce it if OPT_STRICT is defined.
*/
if (bitrate_per_channel <= 28000 || bitrate_per_channel == 40000) {
stream->error = MAD_ERROR_BADMODE;
return -1;
}
# endif
}
else { /* nch == 1 */
if (bitrate_per_channel > 192000) {
/*
* ISO/IEC 11172-3 does not allow single channel mode for 224, 256,
* 320, or 384 kbps bitrates in Layer II.
*/
stream->error = MAD_ERROR_BADMODE;
return -1;
}
}
if (bitrate_per_channel <= 48000)
index = (header->samplerate == 32000) ? 3 : 2;
else if (bitrate_per_channel <= 80000)
index = 0;
else {
freeformat:
index = (header->samplerate == 48000) ? 0 : 1;
}
}
sblimit = sbquant_table[index].sblimit;
offsets = sbquant_table[index].offsets;
bound = 32;
if (header->mode == MAD_MODE_JOINT_STEREO) {
header->flags |= MAD_FLAG_I_STEREO;
bound = 4 + header->mode_extension * 4;
}
if (bound > sblimit)
bound = sblimit;
start = stream->ptr;
/* decode bit allocations */
for (sb = 0; sb < bound; ++sb) {
nbal = bitalloc_table[offsets[sb]].nbal;
for (ch = 0; ch < nch; ++ch)
allocation[ch][sb] = mad_bit_read(&stream->ptr, nbal);
}
for (sb = bound; sb < sblimit; ++sb) {
nbal = bitalloc_table[offsets[sb]].nbal;
allocation[0][sb] =
allocation[1][sb] = mad_bit_read(&stream->ptr, nbal);
}
/* decode scalefactor selection info */
for (sb = 0; sb < sblimit; ++sb) {
for (ch = 0; ch < nch; ++ch) {
if (allocation[ch][sb])
scfsi[ch][sb] = mad_bit_read(&stream->ptr, 2);
}
}
/* check CRC word */
if (header->flags & MAD_FLAG_PROTECTION) {
header->crc_check =
mad_bit_crc(start, mad_bit_length(&start, &stream->ptr),
header->crc_check);
if (header->crc_check != header->crc_target &&
!(frame->options & MAD_OPTION_IGNORECRC)) {
stream->error = MAD_ERROR_BADCRC;
return -1;
}
}
/* decode scalefactors */
for (sb = 0; sb < sblimit; ++sb) {
for (ch = 0; ch < nch; ++ch) {
if (allocation[ch][sb]) {
scalefactor[ch][sb][0] = mad_bit_read(&stream->ptr, 6);
switch (scfsi[ch][sb]) {
case 2:
scalefactor[ch][sb][2] =
scalefactor[ch][sb][1] =
scalefactor[ch][sb][0];
break;
case 0:
scalefactor[ch][sb][1] = mad_bit_read(&stream->ptr, 6);
/* fall through */
case 1:
case 3:
scalefactor[ch][sb][2] = mad_bit_read(&stream->ptr, 6);
}
if (scfsi[ch][sb] & 1)
scalefactor[ch][sb][1] = scalefactor[ch][sb][scfsi[ch][sb] - 1];
# if defined(OPT_STRICT)
/*
* Scalefactor index 63 does not appear in Table B.1 of
* ISO/IEC 11172-3. Nonetheless, other implementations accept it,
* so we only reject it if OPT_STRICT is defined.
*/
if (scalefactor[ch][sb][0] == 63 ||
scalefactor[ch][sb][1] == 63 ||
scalefactor[ch][sb][2] == 63) {
stream->error = MAD_ERROR_BADSCALEFACTOR;
return -1;
}
# endif
}
}
}
/* decode samples */
for (gr = 0; gr < 12; ++gr) {
for (sb = 0; sb < bound; ++sb) {
for (ch = 0; ch < nch; ++ch) {
if ((index = allocation[ch][sb])) {
index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1];
II_samples(&stream->ptr, &qc_table[index], samples);
for (s = 0; s < 3; ++s) {
frame->sbsample[ch][3 * gr + s][sb] =
mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]);
}
}
else {
for (s = 0; s < 3; ++s)
frame->sbsample[ch][3 * gr + s][sb] = 0;
}
}
}
for (sb = bound; sb < sblimit; ++sb) {
if ((index = allocation[0][sb])) {
index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1];
II_samples(&stream->ptr, &qc_table[index], samples);
for (ch = 0; ch < nch; ++ch) {
for (s = 0; s < 3; ++s) {
frame->sbsample[ch][3 * gr + s][sb] =
mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]);
}
}
}
else {
for (ch = 0; ch < nch; ++ch) {
for (s = 0; s < 3; ++s)
frame->sbsample[ch][3 * gr + s][sb] = 0;
}
}
}
for (ch = 0; ch < nch; ++ch) {
for (s = 0; s < 3; ++s) {
for (sb = sblimit; sb < 32; ++sb)
frame->sbsample[ch][3 * gr + s][sb] = 0;
}
}
}
return 0;
}

View file

@ -1,2 +0,0 @@
Because of size constraints, the option to read mpg1/2 files has been
disabled.

View file

@ -1,163 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: stream.c,v 1.12 2004/02/05 09:02:39 rob Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include <stdlib.h>
# include "bit.h"
# include "stream.h"
//main_data_t MainData; //static alloc of decoder data
/*
* NAME: stream->init()
* DESCRIPTION: initialize stream struct
*/
void ICACHE_FLASH_ATTR mad_stream_init(struct mad_stream *stream)
{
stream->buffer = 0;
stream->bufend = 0;
stream->skiplen = 0;
stream->sync = 0;
stream->freerate = 0;
stream->this_frame = 0;
stream->next_frame = 0;
mad_bit_init(&stream->ptr, 0);
mad_bit_init(&stream->anc_ptr, 0);
stream->anc_bitlen = 0;
stream->main_data = 0;
stream->md_len = 0;
stream->options = 0;
stream->error = MAD_ERROR_NONE;
}
/*
* NAME: stream->finish()
* DESCRIPTION: deallocate any dynamic memory associated with stream
*/
void ICACHE_FLASH_ATTR mad_stream_finish(struct mad_stream *stream)
{
if (stream->main_data) {
vPortFree(stream->main_data);
stream->main_data = 0;
}
mad_bit_finish(&stream->anc_ptr);
mad_bit_finish(&stream->ptr);
}
/*
* NAME: stream->buffer()
* DESCRIPTION: set stream buffer pointers
*/
void ICACHE_FLASH_ATTR mad_stream_buffer(struct mad_stream *stream,
unsigned char const *buffer, unsigned long length)
{
stream->buffer = buffer;
stream->bufend = buffer + length;
stream->this_frame = buffer;
stream->next_frame = buffer;
stream->sync = 1;
mad_bit_init(&stream->ptr, buffer);
}
/*
* NAME: stream->skip()
* DESCRIPTION: arrange to skip bytes before the next frame
*/
void ICACHE_FLASH_ATTR mad_stream_skip(struct mad_stream *stream, unsigned long length)
{
stream->skiplen += length;
}
/*
* NAME: stream->sync()
* DESCRIPTION: locate the next stream sync word
*/
int ICACHE_FLASH_ATTR mad_stream_sync(struct mad_stream *stream)
{
register unsigned char const *ptr, *end;
ptr = mad_bit_nextbyte(&stream->ptr);
end = stream->bufend;
while (ptr < end - 1 &&
!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0))
++ptr;
if (end - ptr < MAD_BUFFER_GUARD)
return -1;
mad_bit_init(&stream->ptr, ptr);
return 0;
}
/*
* NAME: stream->errorstr()
* DESCRIPTION: return a string description of the current error condition
*/
char const ICACHE_FLASH_ATTR *mad_stream_errorstr(struct mad_stream const *stream)
{
switch (stream->error) {
case MAD_ERROR_NONE: return "no error";
case MAD_ERROR_BUFLEN: return "input buffer too small (or EOF)";
case MAD_ERROR_BUFPTR: return "invalid (null) buffer pointer";
case MAD_ERROR_NOMEM: return "not enough memory";
case MAD_ERROR_LOSTSYNC: return "lost synchronization";
case MAD_ERROR_BADLAYER: return "reserved header layer value";
case MAD_ERROR_BADBITRATE: return "forbidden bitrate value";
case MAD_ERROR_BADSAMPLERATE: return "reserved sample frequency value";
case MAD_ERROR_BADEMPHASIS: return "reserved emphasis value";
case MAD_ERROR_BADCRC: return "CRC check failed";
case MAD_ERROR_BADBITALLOC: return "forbidden bit allocation value";
case MAD_ERROR_BADSCALEFACTOR: return "bad scalefactor index";
case MAD_ERROR_BADMODE: return "bad bitrate/mode combination";
case MAD_ERROR_BADFRAMELEN: return "bad frame length";
case MAD_ERROR_BADBIGVALUES: return "bad big_values count";
case MAD_ERROR_BADBLOCKTYPE: return "reserved block_type";
case MAD_ERROR_BADSCFSI: return "bad scalefactor selection info";
case MAD_ERROR_BADDATAPTR: return "bad main_data_begin pointer";
case MAD_ERROR_BADPART3LEN: return "bad audio data length";
case MAD_ERROR_BADHUFFTABLE: return "bad Huffman table select";
case MAD_ERROR_BADHUFFDATA: return "Huffman data overrun";
case MAD_ERROR_BADSTEREO: return "incompatible block_type for JS";
}
return 0;
}

View file

@ -1,934 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: synth.c,v 1.25 2004/01/23 09:41:33 rob Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include "fixed.h"
# include "frame.h"
# include "synth.h"
# include "string.h"
// #define SAVED_SAMPLE_BUFF_LEN 240000
// unsigned int saved_idx = 0;
// short int saved_samples[SAVED_SAMPLE_BUFF_LEN];
/*
* The following utility routine performs simple rounding, clipping, and
* scaling of MAD's high-resolution samples down to 16 bits. It does not
* perform any dithering or noise shaping, which would be recommended to
* obtain any exceptional audio quality. It is therefore not recommended to
* use this routine if high-quality output is desired.
*/
static inline
signed int scale(mad_fixed_t sample)
{
/* round */
sample += (1L << (MAD_F_FRACBITS - 16));
/* clip */
if (sample >= MAD_F_ONE)
sample = MAD_F_ONE - 1;
else if (sample < -MAD_F_ONE)
sample = -MAD_F_ONE;
/* quantize */
return sample >> (MAD_F_FRACBITS + 1 - 16);
}
/*
* NAME: synth->init()
* DESCRIPTION: initialize synth struct
*/
void mad_synth_init(struct mad_synth *synth)
{
mad_synth_mute(synth);
synth->phase = 0;
synth->pcm.samplerate = 0;
synth->pcm.channels = 0;
synth->pcm.length = 0;
}
/*
* NAME: synth->mute()
* DESCRIPTION: zero all polyphase filterbank values, resetting synthesis
*/
void mad_synth_mute(struct mad_synth *synth)
{
unsigned int ch, s, v;
for (ch = 0; ch < 2; ++ch) {
for (s = 0; s < 16; ++s) {
for (v = 0; v < 8; ++v) {
synth->filter[ch][0][0][s][v] = synth->filter[ch][0][1][s][v] =
synth->filter[ch][1][0][s][v] = synth->filter[ch][1][1][s][v] = 0;
}
}
}
}
/*
* An optional optimization called here the Subband Synthesis Optimization
* (SSO) improves the performance of subband synthesis at the expense of
* accuracy.
*
* The idea is to simplify 32x32->64-bit multiplication to 32x32->32 such
* that extra scaling and rounding are not necessary. This often allows the
* compiler to use faster 32-bit multiply-accumulate instructions instead of
* explicit 64-bit multiply, shift, and add instructions.
*
* SSO works like this: a full 32x32->64-bit multiply of two mad_fixed_t
* values requires the result to be right-shifted 28 bits to be properly
* scaled to the same fixed-point format. Right shifts can be applied at any
* time to either operand or to the result, so the optimization involves
* careful placement of these shifts to minimize the loss of accuracy.
*
* First, a 14-bit shift is applied with rounding at compile-time to the D[]
* table of coefficients for the subband synthesis window. This only loses 2
* bits of accuracy because the lower 12 bits are always zero. A second
* 12-bit shift occurs after the DCT calculation. This loses 12 bits of
* accuracy. Finally, a third 2-bit shift occurs just before the sample is
* saved in the PCM buffer. 14 + 12 + 2 == 28 bits.
*/
/* FPM_DEFAULT without OPT_SSO will actually lose accuracy and performance */
# if defined(FPM_DEFAULT) && !defined(OPT_SSO)
# define OPT_SSO
# endif
/* second SSO shift, with rounding */
# if defined(OPT_SSO)
# define SHIFT(x) (((x) + (1L << 11)) >> 12)
# else
# define SHIFT(x) (x)
# endif
/* possible DCT speed optimization */
# if defined(OPT_SPEED) && defined(MAD_F_MLX)
# define OPT_DCTO
# define MUL(x, y) \
({ mad_fixed64hi_t hi; \
mad_fixed64lo_t lo; \
MAD_F_MLX(hi, lo, (x), (y)); \
hi << (32 - MAD_F_SCALEBITS - 3); \
})
# else
# undef OPT_DCTO
# define MUL(x, y) mad_f_mul((x), (y))
# endif
/*
* NAME: dct32()
* DESCRIPTION: perform fast in[32]->out[32] DCT
*/
static
void dct32(mad_fixed_t const in[32], unsigned int slot,
mad_fixed_t lo[16][8], mad_fixed_t hi[16][8])
{
mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7;
mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15;
mad_fixed_t t16, t17, t18, t19, t20, t21, t22, t23;
mad_fixed_t t24, t25, t26, t27, t28, t29, t30, t31;
mad_fixed_t t32, t33, t34, t35, t36, t37, t38, t39;
mad_fixed_t t40, t41, t42, t43, t44, t45, t46, t47;
mad_fixed_t t48, t49, t50, t51, t52, t53, t54, t55;
mad_fixed_t t56, t57, t58, t59, t60, t61, t62, t63;
mad_fixed_t t64, t65, t66, t67, t68, t69, t70, t71;
mad_fixed_t t72, t73, t74, t75, t76, t77, t78, t79;
mad_fixed_t t80, t81, t82, t83, t84, t85, t86, t87;
mad_fixed_t t88, t89, t90, t91, t92, t93, t94, t95;
mad_fixed_t t96, t97, t98, t99, t100, t101, t102, t103;
mad_fixed_t t104, t105, t106, t107, t108, t109, t110, t111;
mad_fixed_t t112, t113, t114, t115, t116, t117, t118, t119;
mad_fixed_t t120, t121, t122, t123, t124, t125, t126, t127;
mad_fixed_t t128, t129, t130, t131, t132, t133, t134, t135;
mad_fixed_t t136, t137, t138, t139, t140, t141, t142, t143;
mad_fixed_t t144, t145, t146, t147, t148, t149, t150, t151;
mad_fixed_t t152, t153, t154, t155, t156, t157, t158, t159;
mad_fixed_t t160, t161, t162, t163, t164, t165, t166, t167;
mad_fixed_t t168, t169, t170, t171, t172, t173, t174, t175;
mad_fixed_t t176;
/* costab[i] = cos(PI / (2 * 32) * i) */
# if defined(OPT_DCTO)
# define costab1 MAD_F(0x7fd8878e)
# define costab2 MAD_F(0x7f62368f)
# define costab3 MAD_F(0x7e9d55fc)
# define costab4 MAD_F(0x7d8a5f40)
# define costab5 MAD_F(0x7c29fbee)
# define costab6 MAD_F(0x7a7d055b)
# define costab7 MAD_F(0x78848414)
# define costab8 MAD_F(0x7641af3d)
# define costab9 MAD_F(0x73b5ebd1)
# define costab10 MAD_F(0x70e2cbc6)
# define costab11 MAD_F(0x6dca0d14)
# define costab12 MAD_F(0x6a6d98a4)
# define costab13 MAD_F(0x66cf8120)
# define costab14 MAD_F(0x62f201ac)
# define costab15 MAD_F(0x5ed77c8a)
# define costab16 MAD_F(0x5a82799a)
# define costab17 MAD_F(0x55f5a4d2)
# define costab18 MAD_F(0x5133cc94)
# define costab19 MAD_F(0x4c3fdff4)
# define costab20 MAD_F(0x471cece7)
# define costab21 MAD_F(0x41ce1e65)
# define costab22 MAD_F(0x3c56ba70)
# define costab23 MAD_F(0x36ba2014)
# define costab24 MAD_F(0x30fbc54d)
# define costab25 MAD_F(0x2b1f34eb)
# define costab26 MAD_F(0x25280c5e)
# define costab27 MAD_F(0x1f19f97b)
# define costab28 MAD_F(0x18f8b83c)
# define costab29 MAD_F(0x12c8106f)
# define costab30 MAD_F(0x0c8bd35e)
# define costab31 MAD_F(0x0647d97c)
# else
# define costab1 MAD_F(0x0ffb10f2) /* 0.998795456 */
# define costab2 MAD_F(0x0fec46d2) /* 0.995184727 */
# define costab3 MAD_F(0x0fd3aac0) /* 0.989176510 */
# define costab4 MAD_F(0x0fb14be8) /* 0.980785280 */
# define costab5 MAD_F(0x0f853f7e) /* 0.970031253 */
# define costab6 MAD_F(0x0f4fa0ab) /* 0.956940336 */
# define costab7 MAD_F(0x0f109082) /* 0.941544065 */
# define costab8 MAD_F(0x0ec835e8) /* 0.923879533 */
# define costab9 MAD_F(0x0e76bd7a) /* 0.903989293 */
# define costab10 MAD_F(0x0e1c5979) /* 0.881921264 */
# define costab11 MAD_F(0x0db941a3) /* 0.857728610 */
# define costab12 MAD_F(0x0d4db315) /* 0.831469612 */
# define costab13 MAD_F(0x0cd9f024) /* 0.803207531 */
# define costab14 MAD_F(0x0c5e4036) /* 0.773010453 */
# define costab15 MAD_F(0x0bdaef91) /* 0.740951125 */
# define costab16 MAD_F(0x0b504f33) /* 0.707106781 */
# define costab17 MAD_F(0x0abeb49a) /* 0.671558955 */
# define costab18 MAD_F(0x0a267993) /* 0.634393284 */
# define costab19 MAD_F(0x0987fbfe) /* 0.595699304 */
# define costab20 MAD_F(0x08e39d9d) /* 0.555570233 */
# define costab21 MAD_F(0x0839c3cd) /* 0.514102744 */
# define costab22 MAD_F(0x078ad74e) /* 0.471396737 */
# define costab23 MAD_F(0x06d74402) /* 0.427555093 */
# define costab24 MAD_F(0x061f78aa) /* 0.382683432 */
# define costab25 MAD_F(0x0563e69d) /* 0.336889853 */
# define costab26 MAD_F(0x04a5018c) /* 0.290284677 */
# define costab27 MAD_F(0x03e33f2f) /* 0.242980180 */
# define costab28 MAD_F(0x031f1708) /* 0.195090322 */
# define costab29 MAD_F(0x0259020e) /* 0.146730474 */
# define costab30 MAD_F(0x01917a6c) /* 0.098017140 */
# define costab31 MAD_F(0x00c8fb30) /* 0.049067674 */
# endif
t0 = in[0] + in[31]; t16 = MUL(in[0] - in[31], costab1);
t1 = in[15] + in[16]; t17 = MUL(in[15] - in[16], costab31);
t41 = t16 + t17;
t59 = MUL(t16 - t17, costab2);
t33 = t0 + t1;
t50 = MUL(t0 - t1, costab2);
t2 = in[7] + in[24]; t18 = MUL(in[7] - in[24], costab15);
t3 = in[8] + in[23]; t19 = MUL(in[8] - in[23], costab17);
t42 = t18 + t19;
t60 = MUL(t18 - t19, costab30);
t34 = t2 + t3;
t51 = MUL(t2 - t3, costab30);
t4 = in[3] + in[28]; t20 = MUL(in[3] - in[28], costab7);
t5 = in[12] + in[19]; t21 = MUL(in[12] - in[19], costab25);
t43 = t20 + t21;
t61 = MUL(t20 - t21, costab14);
t35 = t4 + t5;
t52 = MUL(t4 - t5, costab14);
t6 = in[4] + in[27]; t22 = MUL(in[4] - in[27], costab9);
t7 = in[11] + in[20]; t23 = MUL(in[11] - in[20], costab23);
t44 = t22 + t23;
t62 = MUL(t22 - t23, costab18);
t36 = t6 + t7;
t53 = MUL(t6 - t7, costab18);
t8 = in[1] + in[30]; t24 = MUL(in[1] - in[30], costab3);
t9 = in[14] + in[17]; t25 = MUL(in[14] - in[17], costab29);
t45 = t24 + t25;
t63 = MUL(t24 - t25, costab6);
t37 = t8 + t9;
t54 = MUL(t8 - t9, costab6);
t10 = in[6] + in[25]; t26 = MUL(in[6] - in[25], costab13);
t11 = in[9] + in[22]; t27 = MUL(in[9] - in[22], costab19);
t46 = t26 + t27;
t64 = MUL(t26 - t27, costab26);
t38 = t10 + t11;
t55 = MUL(t10 - t11, costab26);
t12 = in[2] + in[29]; t28 = MUL(in[2] - in[29], costab5);
t13 = in[13] + in[18]; t29 = MUL(in[13] - in[18], costab27);
t47 = t28 + t29;
t65 = MUL(t28 - t29, costab10);
t39 = t12 + t13;
t56 = MUL(t12 - t13, costab10);
t14 = in[5] + in[26]; t30 = MUL(in[5] - in[26], costab11);
t15 = in[10] + in[21]; t31 = MUL(in[10] - in[21], costab21);
t48 = t30 + t31;
t66 = MUL(t30 - t31, costab22);
t40 = t14 + t15;
t57 = MUL(t14 - t15, costab22);
t69 = t33 + t34; t89 = MUL(t33 - t34, costab4);
t70 = t35 + t36; t90 = MUL(t35 - t36, costab28);
t71 = t37 + t38; t91 = MUL(t37 - t38, costab12);
t72 = t39 + t40; t92 = MUL(t39 - t40, costab20);
t73 = t41 + t42; t94 = MUL(t41 - t42, costab4);
t74 = t43 + t44; t95 = MUL(t43 - t44, costab28);
t75 = t45 + t46; t96 = MUL(t45 - t46, costab12);
t76 = t47 + t48; t97 = MUL(t47 - t48, costab20);
t78 = t50 + t51; t100 = MUL(t50 - t51, costab4);
t79 = t52 + t53; t101 = MUL(t52 - t53, costab28);
t80 = t54 + t55; t102 = MUL(t54 - t55, costab12);
t81 = t56 + t57; t103 = MUL(t56 - t57, costab20);
t83 = t59 + t60; t106 = MUL(t59 - t60, costab4);
t84 = t61 + t62; t107 = MUL(t61 - t62, costab28);
t85 = t63 + t64; t108 = MUL(t63 - t64, costab12);
t86 = t65 + t66; t109 = MUL(t65 - t66, costab20);
t113 = t69 + t70;
t114 = t71 + t72;
/* 0 */ hi[15][slot] = SHIFT(t113 + t114);
/* 16 */ lo[ 0][slot] = SHIFT(MUL(t113 - t114, costab16));
t115 = t73 + t74;
t116 = t75 + t76;
t32 = t115 + t116;
/* 1 */ hi[14][slot] = SHIFT(t32);
t118 = t78 + t79;
t119 = t80 + t81;
t58 = t118 + t119;
/* 2 */ hi[13][slot] = SHIFT(t58);
t121 = t83 + t84;
t122 = t85 + t86;
t67 = t121 + t122;
t49 = (t67 * 2) - t32;
/* 3 */ hi[12][slot] = SHIFT(t49);
t125 = t89 + t90;
t126 = t91 + t92;
t93 = t125 + t126;
/* 4 */ hi[11][slot] = SHIFT(t93);
t128 = t94 + t95;
t129 = t96 + t97;
t98 = t128 + t129;
t68 = (t98 * 2) - t49;
/* 5 */ hi[10][slot] = SHIFT(t68);
t132 = t100 + t101;
t133 = t102 + t103;
t104 = t132 + t133;
t82 = (t104 * 2) - t58;
/* 6 */ hi[ 9][slot] = SHIFT(t82);
t136 = t106 + t107;
t137 = t108 + t109;
t110 = t136 + t137;
t87 = (t110 * 2) - t67;
t77 = (t87 * 2) - t68;
/* 7 */ hi[ 8][slot] = SHIFT(t77);
t141 = MUL(t69 - t70, costab8);
t142 = MUL(t71 - t72, costab24);
t143 = t141 + t142;
/* 8 */ hi[ 7][slot] = SHIFT(t143);
/* 24 */ lo[ 8][slot] =
SHIFT((MUL(t141 - t142, costab16) * 2) - t143);
t144 = MUL(t73 - t74, costab8);
t145 = MUL(t75 - t76, costab24);
t146 = t144 + t145;
t88 = (t146 * 2) - t77;
/* 9 */ hi[ 6][slot] = SHIFT(t88);
t148 = MUL(t78 - t79, costab8);
t149 = MUL(t80 - t81, costab24);
t150 = t148 + t149;
t105 = (t150 * 2) - t82;
/* 10 */ hi[ 5][slot] = SHIFT(t105);
t152 = MUL(t83 - t84, costab8);
t153 = MUL(t85 - t86, costab24);
t154 = t152 + t153;
t111 = (t154 * 2) - t87;
t99 = (t111 * 2) - t88;
/* 11 */ hi[ 4][slot] = SHIFT(t99);
t157 = MUL(t89 - t90, costab8);
t158 = MUL(t91 - t92, costab24);
t159 = t157 + t158;
t127 = (t159 * 2) - t93;
/* 12 */ hi[ 3][slot] = SHIFT(t127);
t160 = (MUL(t125 - t126, costab16) * 2) - t127;
/* 20 */ lo[ 4][slot] = SHIFT(t160);
/* 28 */ lo[12][slot] =
SHIFT((((MUL(t157 - t158, costab16) * 2) - t159) * 2) - t160);
t161 = MUL(t94 - t95, costab8);
t162 = MUL(t96 - t97, costab24);
t163 = t161 + t162;
t130 = (t163 * 2) - t98;
t112 = (t130 * 2) - t99;
/* 13 */ hi[ 2][slot] = SHIFT(t112);
t164 = (MUL(t128 - t129, costab16) * 2) - t130;
t166 = MUL(t100 - t101, costab8);
t167 = MUL(t102 - t103, costab24);
t168 = t166 + t167;
t134 = (t168 * 2) - t104;
t120 = (t134 * 2) - t105;
/* 14 */ hi[ 1][slot] = SHIFT(t120);
t135 = (MUL(t118 - t119, costab16) * 2) - t120;
/* 18 */ lo[ 2][slot] = SHIFT(t135);
t169 = (MUL(t132 - t133, costab16) * 2) - t134;
t151 = (t169 * 2) - t135;
/* 22 */ lo[ 6][slot] = SHIFT(t151);
t170 = (((MUL(t148 - t149, costab16) * 2) - t150) * 2) - t151;
/* 26 */ lo[10][slot] = SHIFT(t170);
/* 30 */ lo[14][slot] =
SHIFT((((((MUL(t166 - t167, costab16) * 2) -
t168) * 2) - t169) * 2) - t170);
t171 = MUL(t106 - t107, costab8);
t172 = MUL(t108 - t109, costab24);
t173 = t171 + t172;
t138 = (t173 * 2) - t110;
t123 = (t138 * 2) - t111;
t139 = (MUL(t121 - t122, costab16) * 2) - t123;
t117 = (t123 * 2) - t112;
/* 15 */ hi[ 0][slot] = SHIFT(t117);
t124 = (MUL(t115 - t116, costab16) * 2) - t117;
/* 17 */ lo[ 1][slot] = SHIFT(t124);
t131 = (t139 * 2) - t124;
/* 19 */ lo[ 3][slot] = SHIFT(t131);
t140 = (t164 * 2) - t131;
/* 21 */ lo[ 5][slot] = SHIFT(t140);
t174 = (MUL(t136 - t137, costab16) * 2) - t138;
t155 = (t174 * 2) - t139;
t147 = (t155 * 2) - t140;
/* 23 */ lo[ 7][slot] = SHIFT(t147);
t156 = (((MUL(t144 - t145, costab16) * 2) - t146) * 2) - t147;
/* 25 */ lo[ 9][slot] = SHIFT(t156);
t175 = (((MUL(t152 - t153, costab16) * 2) - t154) * 2) - t155;
t165 = (t175 * 2) - t156;
/* 27 */ lo[11][slot] = SHIFT(t165);
t176 = (((((MUL(t161 - t162, costab16) * 2) -
t163) * 2) - t164) * 2) - t165;
/* 29 */ lo[13][slot] = SHIFT(t176);
/* 31 */ lo[15][slot] =
SHIFT((((((((MUL(t171 - t172, costab16) * 2) -
t173) * 2) - t174) * 2) - t175) * 2) - t176);
/*
* Totals:
* 80 multiplies
* 80 additions
* 119 subtractions
* 49 shifts (not counting SSO)
*/
}
# undef MUL
# undef SHIFT
/* third SSO shift and/or D[] optimization preshift */
# if defined(OPT_SSO)
# if MAD_F_FRACBITS != 28
# error "MAD_F_FRACBITS must be 28 to use OPT_SSO"
# endif
# define ML0(hi, lo, x, y) ((lo) = (x) * (y))
# define MLA(hi, lo, x, y) ((lo) += (x) * (y))
# define MLN(hi, lo) ((lo) = -(lo))
# define MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
# define SHIFT(x) ((x) >> 2)
# define PRESHIFT(x) ((MAD_F(x) + (1L << 13)) >> 14)
# else
# define ML0(hi, lo, x, y) MAD_F_ML0((hi), (lo), (x), (y))
# define MLA(hi, lo, x, y) MAD_F_MLA((hi), (lo), (x), (y))
# define MLN(hi, lo) MAD_F_MLN((hi), (lo))
# define MLZ(hi, lo) MAD_F_MLZ((hi), (lo))
# define SHIFT(x) (x)
# if defined(MAD_F_SCALEBITS)
# undef MAD_F_SCALEBITS
# define MAD_F_SCALEBITS (MAD_F_FRACBITS - 12)
# define PRESHIFT(x) (MAD_F(x) >> 12)
# else
# define PRESHIFT(x) MAD_F(x)
# endif
# endif
static
mad_fixed_t const D[17][32] = {
# include "D.dat"
};
# if defined(ASO_SYNTH)
void synth_full(struct mad_synth *, struct mad_frame const *,
unsigned int, unsigned int);
# else
/*
* NAME: synth->full()
* DESCRIPTION: perform full frequency PCM synthesis
*/
static
void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
unsigned int nch, unsigned int ns)
{
unsigned int phase, ch, s, sb, pe, po;
short int *pcm1, *pcm2;
mad_fixed_t (*filter)[2][2][16][8];
mad_fixed_t (*sbsample)[36][32];
register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
register mad_fixed_t const (*Dptr)[32], *ptr ;
register mad_fixed64hi_t hi;
register mad_fixed64lo_t lo;
mad_fixed_t raw_sample;
short int short_sample_buff[2][32];
phase = synth->phase;
if (nch > 2)
return;
for (s = 0; s < ns; ++s)
{
memset (short_sample_buff, 0x00, sizeof(short_sample_buff));
for (ch = 0; ch < nch; ++ch)
{
sbsample = &frame->sbsample[ch];
filter = &synth->filter[ch];
pcm1 = short_sample_buff[ch];
dct32((*sbsample)[s], phase >> 1,
(*filter)[0][phase & 1], (*filter)[1][phase & 1]);
pe = phase & ~1;
po = ((phase - 1) & 0xf) | 1;
/* calculate 16 samples */
fe = &(*filter)[0][ phase & 1][0];
fx = &(*filter)[0][~phase & 1][0];
fo = &(*filter)[1][~phase & 1][0];
Dptr = &D[0];
ptr = *Dptr + po;
ML0(hi, lo, (*fx)[0], ptr[ 0]);
MLA(hi, lo, (*fx)[1], ptr[14]);
MLA(hi, lo, (*fx)[2], ptr[12]);
MLA(hi, lo, (*fx)[3], ptr[10]);
MLA(hi, lo, (*fx)[4], ptr[ 8]);
MLA(hi, lo, (*fx)[5], ptr[ 6]);
MLA(hi, lo, (*fx)[6], ptr[ 4]);
MLA(hi, lo, (*fx)[7], ptr[ 2]);
MLN(hi, lo);
ptr = *Dptr + pe;
MLA(hi, lo, (*fe)[0], ptr[ 0]);
MLA(hi, lo, (*fe)[1], ptr[14]);
MLA(hi, lo, (*fe)[2], ptr[12]);
MLA(hi, lo, (*fe)[3], ptr[10]);
MLA(hi, lo, (*fe)[4], ptr[ 8]);
MLA(hi, lo, (*fe)[5], ptr[ 6]);
MLA(hi, lo, (*fe)[6], ptr[ 4]);
MLA(hi, lo, (*fe)[7], ptr[ 2]);
raw_sample = SHIFT(MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm1++) += (short int)raw_sample;
pcm2 = pcm1 + 30;
for (sb = 1; sb < 16; ++sb)
{
++fe;
++Dptr;
/* D[32 - sb][i] == -D[sb][31 - i] */
ptr = *Dptr + po;
ML0(hi, lo, (*fo)[0], ptr[ 0]);
MLA(hi, lo, (*fo)[1], ptr[14]);
MLA(hi, lo, (*fo)[2], ptr[12]);
MLA(hi, lo, (*fo)[3], ptr[10]);
MLA(hi, lo, (*fo)[4], ptr[ 8]);
MLA(hi, lo, (*fo)[5], ptr[ 6]);
MLA(hi, lo, (*fo)[6], ptr[ 4]);
MLA(hi, lo, (*fo)[7], ptr[ 2]);
MLN(hi, lo);
ptr = *Dptr + pe;
MLA(hi, lo, (*fe)[7], ptr[ 2]);
MLA(hi, lo, (*fe)[6], ptr[ 4]);
MLA(hi, lo, (*fe)[5], ptr[ 6]);
MLA(hi, lo, (*fe)[4], ptr[ 8]);
MLA(hi, lo, (*fe)[3], ptr[10]);
MLA(hi, lo, (*fe)[2], ptr[12]);
MLA(hi, lo, (*fe)[1], ptr[14]);
MLA(hi, lo, (*fe)[0], ptr[ 0]);
raw_sample = SHIFT(MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm1++) += (short int)raw_sample;
ptr = *Dptr - pe;
ML0(hi, lo, (*fe)[0], ptr[31 - 16]);
MLA(hi, lo, (*fe)[1], ptr[31 - 14]);
MLA(hi, lo, (*fe)[2], ptr[31 - 12]);
MLA(hi, lo, (*fe)[3], ptr[31 - 10]);
MLA(hi, lo, (*fe)[4], ptr[31 - 8]);
MLA(hi, lo, (*fe)[5], ptr[31 - 6]);
MLA(hi, lo, (*fe)[6], ptr[31 - 4]);
MLA(hi, lo, (*fe)[7], ptr[31 - 2]);
ptr = *Dptr - po;
MLA(hi, lo, (*fo)[7], ptr[31 - 2]);
MLA(hi, lo, (*fo)[6], ptr[31 - 4]);
MLA(hi, lo, (*fo)[5], ptr[31 - 6]);
MLA(hi, lo, (*fo)[4], ptr[31 - 8]);
MLA(hi, lo, (*fo)[3], ptr[31 - 10]);
MLA(hi, lo, (*fo)[2], ptr[31 - 12]);
MLA(hi, lo, (*fo)[1], ptr[31 - 14]);
MLA(hi, lo, (*fo)[0], ptr[31 - 16]);
raw_sample = SHIFT(MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm2--) += (short int)raw_sample;
++fo;
}
Dptr++;
ptr = *Dptr + po;
ML0(hi, lo, (*fo)[0], ptr[ 0]);
MLA(hi, lo, (*fo)[1], ptr[14]);
MLA(hi, lo, (*fo)[2], ptr[12]);
MLA(hi, lo, (*fo)[3], ptr[10]);
MLA(hi, lo, (*fo)[4], ptr[ 8]);
MLA(hi, lo, (*fo)[5], ptr[ 6]);
MLA(hi, lo, (*fo)[6], ptr[ 4]);
MLA(hi, lo, (*fo)[7], ptr[ 2]);
raw_sample = SHIFT(-MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm1) += (short int)raw_sample;
} /* for di canale */
/* Render di un blocco */
if(nch < 2) memcpy(short_sample_buff[1], short_sample_buff[0], sizeof(short_sample_buff[0]));
render_sample_block(short_sample_buff, sizeof(short_sample_buff[0])/sizeof(short int));
phase = (phase + 1) % 16;
} /* for di blocco */
}
#endif
/*
* NAME: synth->half()
* DESCRIPTION: perform half frequency PCM synthesis
*/
static
void synth_half(struct mad_synth *synth, struct mad_frame const *frame,
unsigned int nch, unsigned int ns)
{
unsigned int phase, ch, s, sb, pe, po;
short int *pcm1, *pcm1v, *pcm2v;
mad_fixed_t (*filter)[2][2][16][8];
mad_fixed_t (*sbsample)[36][32];
register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
register mad_fixed_t const (*Dptr)[32], *ptr ;
register mad_fixed64hi_t hi;
register mad_fixed64lo_t lo;
mad_fixed_t raw_sample;
short int short_sample_buff[2][16];
phase = synth->phase;
if (nch > 2)
return;
for (s = 0; s < ns; ++s)
{
memset (short_sample_buff, 0x00, sizeof(short_sample_buff));
for (ch = 0; ch < nch; ++ch)
{
sbsample = &frame->sbsample[ch];
filter = &synth->filter[ch];
pcm1 = pcm1v = short_sample_buff;
dct32((*sbsample)[s], phase >> 1,
(*filter)[0][phase & 1], (*filter)[1][phase & 1]);
pe = phase & ~1;
po = ((phase - 1) & 0xf) | 1;
/* calculate 16 samples */
fe = &(*filter)[0][ phase & 1][0];
fx = &(*filter)[0][~phase & 1][0];
fo = &(*filter)[1][~phase & 1][0];
Dptr = &D[0];
ptr = *Dptr + po;
ML0(hi, lo, (*fx)[0], ptr[ 0]);
MLA(hi, lo, (*fx)[1], ptr[14]);
MLA(hi, lo, (*fx)[2], ptr[12]);
MLA(hi, lo, (*fx)[3], ptr[10]);
MLA(hi, lo, (*fx)[4], ptr[ 8]);
MLA(hi, lo, (*fx)[5], ptr[ 6]);
MLA(hi, lo, (*fx)[6], ptr[ 4]);
MLA(hi, lo, (*fx)[7], ptr[ 2]);
MLN(hi, lo);
ptr = *Dptr + pe;
MLA(hi, lo, (*fe)[0], ptr[ 0]);
MLA(hi, lo, (*fe)[1], ptr[14]);
MLA(hi, lo, (*fe)[2], ptr[12]);
MLA(hi, lo, (*fe)[3], ptr[10]);
MLA(hi, lo, (*fe)[4], ptr[ 8]);
MLA(hi, lo, (*fe)[5], ptr[ 6]);
MLA(hi, lo, (*fe)[6], ptr[ 4]);
MLA(hi, lo, (*fe)[7], ptr[ 2]);
raw_sample = SHIFT(MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm1v++) += (short int)raw_sample;
pcm2v = pcm1v + 14;
for (sb = 1; sb < 16; ++sb)
{
++fe;
++Dptr;
/* D[32 - sb][i] == -D[sb][31 - i] */
ptr = *Dptr + po;
ML0(hi, lo, (*fo)[0], ptr[ 0]);
MLA(hi, lo, (*fo)[1], ptr[14]);
MLA(hi, lo, (*fo)[2], ptr[12]);
MLA(hi, lo, (*fo)[3], ptr[10]);
MLA(hi, lo, (*fo)[4], ptr[ 8]);
MLA(hi, lo, (*fo)[5], ptr[ 6]);
MLA(hi, lo, (*fo)[6], ptr[ 4]);
MLA(hi, lo, (*fo)[7], ptr[ 2]);
MLN(hi, lo);
ptr = *Dptr + pe;
MLA(hi, lo, (*fe)[7], ptr[ 2]);
MLA(hi, lo, (*fe)[6], ptr[ 4]);
MLA(hi, lo, (*fe)[5], ptr[ 6]);
MLA(hi, lo, (*fe)[4], ptr[ 8]);
MLA(hi, lo, (*fe)[3], ptr[10]);
MLA(hi, lo, (*fe)[2], ptr[12]);
MLA(hi, lo, (*fe)[1], ptr[14]);
MLA(hi, lo, (*fe)[0], ptr[ 0]);
raw_sample = SHIFT(MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm1v++) += (short int)raw_sample;
ptr = *Dptr - pe;
ML0(hi, lo, (*fe)[0], ptr[31 - 16]);
MLA(hi, lo, (*fe)[1], ptr[31 - 14]);
MLA(hi, lo, (*fe)[2], ptr[31 - 12]);
MLA(hi, lo, (*fe)[3], ptr[31 - 10]);
MLA(hi, lo, (*fe)[4], ptr[31 - 8]);
MLA(hi, lo, (*fe)[5], ptr[31 - 6]);
MLA(hi, lo, (*fe)[6], ptr[31 - 4]);
MLA(hi, lo, (*fe)[7], ptr[31 - 2]);
ptr = *Dptr - po;
MLA(hi, lo, (*fo)[7], ptr[31 - 2]);
MLA(hi, lo, (*fo)[6], ptr[31 - 4]);
MLA(hi, lo, (*fo)[5], ptr[31 - 6]);
MLA(hi, lo, (*fo)[4], ptr[31 - 8]);
MLA(hi, lo, (*fo)[3], ptr[31 - 10]);
MLA(hi, lo, (*fo)[2], ptr[31 - 12]);
MLA(hi, lo, (*fo)[1], ptr[31 - 14]);
MLA(hi, lo, (*fo)[0], ptr[31 - 16]);
raw_sample = SHIFT(MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm2v--) += (short int)raw_sample;
++fo;
}
Dptr++;
ptr = *Dptr + po;
ML0(hi, lo, (*fo)[0], ptr[ 0]);
MLA(hi, lo, (*fo)[1], ptr[14]);
MLA(hi, lo, (*fo)[2], ptr[12]);
MLA(hi, lo, (*fo)[3], ptr[10]);
MLA(hi, lo, (*fo)[4], ptr[ 8]);
MLA(hi, lo, (*fo)[5], ptr[ 6]);
MLA(hi, lo, (*fo)[6], ptr[ 4]);
MLA(hi, lo, (*fo)[7], ptr[ 2]);
raw_sample = SHIFT(-MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm1v) += (short int)raw_sample;
} /* for di canale */
/* Render di un blocco */
if(nch < 2) memcpy(short_sample_buff[1], short_sample_buff[0], sizeof(short_sample_buff[0]));
render_sample_block(short_sample_buff, sizeof(short_sample_buff[0])/sizeof(short int));
pcm1 = pcm1v + 8;
phase = (phase + 1) % 16;
} /* for di blocco */
}
/*
* NAME: synth->frame()
* DESCRIPTION: perform PCM synthesis of frame subband samples
*/
void mad_synth_frame(struct mad_synth *synth, struct mad_frame const *frame)
{
unsigned int nch, ns;
void (*synth_frame)(struct mad_synth *, struct mad_frame const *,
unsigned int, unsigned int);
nch = MAD_NCHANNELS(&frame->header);
ns = MAD_NSBSAMPLES(&frame->header);
synth->pcm.samplerate = frame->header.samplerate;
synth->pcm.channels = nch;
// synth->pcm.length = 32 * ns;
synth->pcm.length = 64 * ns;
synth_frame = synth_full;
if (frame->options & MAD_OPTION_HALFSAMPLERATE) {
synth->pcm.samplerate /= 2;
synth->pcm.length /= 2;
synth_frame = synth_half;
}
set_dac_sample_rate(synth->pcm.samplerate, nch);
synth_frame(synth, frame, nch, ns);
synth->phase = (synth->phase + ns) % 16;
}

View file

@ -1,929 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: synth.c,v 1.25 2004/01/23 09:41:33 rob Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include "fixed.h"
# include "frame.h"
# include "synth.h"
# include "string.h"
/*
* The following utility routine performs simple rounding, clipping, and
* scaling of MAD's high-resolution samples down to 16 bits. It does not
* perform any dithering or noise shaping, which would be recommended to
* obtain any exceptional audio quality. It is therefore not recommended to
* use this routine if high-quality output is desired.
*/
static inline
signed short scale(mad_fixed_t sample)
{
/* round */
sample += (1L << (MAD_F_FRACBITS - 16));
/* clip */
if (sample >= MAD_F_ONE) sample = MAD_F_ONE - 1;
else if (sample < -MAD_F_ONE) sample = -MAD_F_ONE;
/* quantize */
//The original nxp code had
//return sample >> (MAD_F_FRACBITS + 1 - 16);
//but somehow that clipped and distorted on loud sounds...
//This seems to be OK:
return sample >> (MAD_F_FRACBITS + 2 - 16);
}
/*
* NAME: synth->init()
* DESCRIPTION: initialize synth struct
*/
void ICACHE_FLASH_ATTR mad_synth_init(struct mad_synth *synth)
{
mad_synth_mute(synth);
synth->phase = 0;
synth->pcm.samplerate = 0;
synth->pcm.channels = 0;
synth->pcm.length = 0;
}
/*
* NAME: synth->mute()
* DESCRIPTION: zero all polyphase filterbank values, resetting synthesis
*/
void ICACHE_FLASH_ATTR mad_synth_mute(struct mad_synth *synth)
{
unsigned int ch, s, v;
for (ch = 0; ch < 2; ++ch) {
for (s = 0; s < 16; ++s) {
for (v = 0; v < 8; ++v) {
synth->filter[ch][0][0][s][v] = synth->filter[ch][0][1][s][v] =
synth->filter[ch][1][0][s][v] = synth->filter[ch][1][1][s][v] = 0;
}
}
}
}
/*
* An optional optimization called here the Subband Synthesis Optimization
* (SSO) improves the performance of subband synthesis at the expense of
* accuracy.
*
* The idea is to simplify 32x32->64-bit multiplication to 32x32->32 such
* that extra scaling and rounding are not necessary. This often allows the
* compiler to use faster 32-bit multiply-accumulate instructions instead of
* explicit 64-bit multiply, shift, and add instructions.
*
* SSO works like this: a full 32x32->64-bit multiply of two mad_fixed_t
* values requires the result to be right-shifted 28 bits to be properly
* scaled to the same fixed-point format. Right shifts can be applied at any
* time to either operand or to the result, so the optimization involves
* careful placement of these shifts to minimize the loss of accuracy.
*
* First, a 14-bit shift is applied with rounding at compile-time to the D[]
* table of coefficients for the subband synthesis window. This only loses 2
* bits of accuracy because the lower 12 bits are always zero. A second
* 12-bit shift occurs after the DCT calculation. This loses 12 bits of
* accuracy. Finally, a third 2-bit shift occurs just before the sample is
* saved in the PCM buffer. 14 + 12 + 2 == 28 bits.
*/
/* FPM_DEFAULT without OPT_SSO will actually lose accuracy and performance */
# if defined(FPM_DEFAULT) && !defined(OPT_SSO)
# define OPT_SSO
# endif
/* second SSO shift, with rounding */
# if defined(OPT_SSO)
# define SHIFT(x) (((x) + (1L << 11)) >> 12)
# else
# define SHIFT(x) (x)
# endif
/* possible DCT speed optimization */
# if defined(OPT_SPEED) && defined(MAD_F_MLX)
# define OPT_DCTO
# define MUL(x, y) \
({ mad_fixed64hi_t hi; \
mad_fixed64lo_t lo; \
MAD_F_MLX(hi, lo, (x), (y)); \
hi << (32 - MAD_F_SCALEBITS - 3); \
})
# else
# undef OPT_DCTO
# define MUL(x, y) mad_f_mul((x), (y))
# endif
/*
* NAME: dct32()
* DESCRIPTION: perform fast in[32]->out[32] DCT
*/
static
void ICACHE_FLASH_ATTR dct32(mad_fixed_t const in[32], unsigned int slot,
mad_fixed_t lo[16][8], mad_fixed_t hi[16][8])
{
mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7;
mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15;
mad_fixed_t t16, t17, t18, t19, t20, t21, t22, t23;
mad_fixed_t t24, t25, t26, t27, t28, t29, t30, t31;
mad_fixed_t t32, t33, t34, t35, t36, t37, t38, t39;
mad_fixed_t t40, t41, t42, t43, t44, t45, t46, t47;
mad_fixed_t t48, t49, t50, t51, t52, t53, t54, t55;
mad_fixed_t t56, t57, t58, t59, t60, t61, t62, t63;
mad_fixed_t t64, t65, t66, t67, t68, t69, t70, t71;
mad_fixed_t t72, t73, t74, t75, t76, t77, t78, t79;
mad_fixed_t t80, t81, t82, t83, t84, t85, t86, t87;
mad_fixed_t t88, t89, t90, t91, t92, t93, t94, t95;
mad_fixed_t t96, t97, t98, t99, t100, t101, t102, t103;
mad_fixed_t t104, t105, t106, t107, t108, t109, t110, t111;
mad_fixed_t t112, t113, t114, t115, t116, t117, t118, t119;
mad_fixed_t t120, t121, t122, t123, t124, t125, t126, t127;
mad_fixed_t t128, t129, t130, t131, t132, t133, t134, t135;
mad_fixed_t t136, t137, t138, t139, t140, t141, t142, t143;
mad_fixed_t t144, t145, t146, t147, t148, t149, t150, t151;
mad_fixed_t t152, t153, t154, t155, t156, t157, t158, t159;
mad_fixed_t t160, t161, t162, t163, t164, t165, t166, t167;
mad_fixed_t t168, t169, t170, t171, t172, t173, t174, t175;
mad_fixed_t t176;
/* costab[i] = cos(PI / (2 * 32) * i) */
# if defined(OPT_DCTO)
# define costab1 MAD_F(0x7fd8878e)
# define costab2 MAD_F(0x7f62368f)
# define costab3 MAD_F(0x7e9d55fc)
# define costab4 MAD_F(0x7d8a5f40)
# define costab5 MAD_F(0x7c29fbee)
# define costab6 MAD_F(0x7a7d055b)
# define costab7 MAD_F(0x78848414)
# define costab8 MAD_F(0x7641af3d)
# define costab9 MAD_F(0x73b5ebd1)
# define costab10 MAD_F(0x70e2cbc6)
# define costab11 MAD_F(0x6dca0d14)
# define costab12 MAD_F(0x6a6d98a4)
# define costab13 MAD_F(0x66cf8120)
# define costab14 MAD_F(0x62f201ac)
# define costab15 MAD_F(0x5ed77c8a)
# define costab16 MAD_F(0x5a82799a)
# define costab17 MAD_F(0x55f5a4d2)
# define costab18 MAD_F(0x5133cc94)
# define costab19 MAD_F(0x4c3fdff4)
# define costab20 MAD_F(0x471cece7)
# define costab21 MAD_F(0x41ce1e65)
# define costab22 MAD_F(0x3c56ba70)
# define costab23 MAD_F(0x36ba2014)
# define costab24 MAD_F(0x30fbc54d)
# define costab25 MAD_F(0x2b1f34eb)
# define costab26 MAD_F(0x25280c5e)
# define costab27 MAD_F(0x1f19f97b)
# define costab28 MAD_F(0x18f8b83c)
# define costab29 MAD_F(0x12c8106f)
# define costab30 MAD_F(0x0c8bd35e)
# define costab31 MAD_F(0x0647d97c)
# else
# define costab1 MAD_F(0x0ffb10f2) /* 0.998795456 */
# define costab2 MAD_F(0x0fec46d2) /* 0.995184727 */
# define costab3 MAD_F(0x0fd3aac0) /* 0.989176510 */
# define costab4 MAD_F(0x0fb14be8) /* 0.980785280 */
# define costab5 MAD_F(0x0f853f7e) /* 0.970031253 */
# define costab6 MAD_F(0x0f4fa0ab) /* 0.956940336 */
# define costab7 MAD_F(0x0f109082) /* 0.941544065 */
# define costab8 MAD_F(0x0ec835e8) /* 0.923879533 */
# define costab9 MAD_F(0x0e76bd7a) /* 0.903989293 */
# define costab10 MAD_F(0x0e1c5979) /* 0.881921264 */
# define costab11 MAD_F(0x0db941a3) /* 0.857728610 */
# define costab12 MAD_F(0x0d4db315) /* 0.831469612 */
# define costab13 MAD_F(0x0cd9f024) /* 0.803207531 */
# define costab14 MAD_F(0x0c5e4036) /* 0.773010453 */
# define costab15 MAD_F(0x0bdaef91) /* 0.740951125 */
# define costab16 MAD_F(0x0b504f33) /* 0.707106781 */
# define costab17 MAD_F(0x0abeb49a) /* 0.671558955 */
# define costab18 MAD_F(0x0a267993) /* 0.634393284 */
# define costab19 MAD_F(0x0987fbfe) /* 0.595699304 */
# define costab20 MAD_F(0x08e39d9d) /* 0.555570233 */
# define costab21 MAD_F(0x0839c3cd) /* 0.514102744 */
# define costab22 MAD_F(0x078ad74e) /* 0.471396737 */
# define costab23 MAD_F(0x06d74402) /* 0.427555093 */
# define costab24 MAD_F(0x061f78aa) /* 0.382683432 */
# define costab25 MAD_F(0x0563e69d) /* 0.336889853 */
# define costab26 MAD_F(0x04a5018c) /* 0.290284677 */
# define costab27 MAD_F(0x03e33f2f) /* 0.242980180 */
# define costab28 MAD_F(0x031f1708) /* 0.195090322 */
# define costab29 MAD_F(0x0259020e) /* 0.146730474 */
# define costab30 MAD_F(0x01917a6c) /* 0.098017140 */
# define costab31 MAD_F(0x00c8fb30) /* 0.049067674 */
# endif
t0 = in[0] + in[31]; t16 = MUL(in[0] - in[31], costab1);
t1 = in[15] + in[16]; t17 = MUL(in[15] - in[16], costab31);
t41 = t16 + t17;
t59 = MUL(t16 - t17, costab2);
t33 = t0 + t1;
t50 = MUL(t0 - t1, costab2);
t2 = in[7] + in[24]; t18 = MUL(in[7] - in[24], costab15);
t3 = in[8] + in[23]; t19 = MUL(in[8] - in[23], costab17);
t42 = t18 + t19;
t60 = MUL(t18 - t19, costab30);
t34 = t2 + t3;
t51 = MUL(t2 - t3, costab30);
t4 = in[3] + in[28]; t20 = MUL(in[3] - in[28], costab7);
t5 = in[12] + in[19]; t21 = MUL(in[12] - in[19], costab25);
t43 = t20 + t21;
t61 = MUL(t20 - t21, costab14);
t35 = t4 + t5;
t52 = MUL(t4 - t5, costab14);
t6 = in[4] + in[27]; t22 = MUL(in[4] - in[27], costab9);
t7 = in[11] + in[20]; t23 = MUL(in[11] - in[20], costab23);
t44 = t22 + t23;
t62 = MUL(t22 - t23, costab18);
t36 = t6 + t7;
t53 = MUL(t6 - t7, costab18);
t8 = in[1] + in[30]; t24 = MUL(in[1] - in[30], costab3);
t9 = in[14] + in[17]; t25 = MUL(in[14] - in[17], costab29);
t45 = t24 + t25;
t63 = MUL(t24 - t25, costab6);
t37 = t8 + t9;
t54 = MUL(t8 - t9, costab6);
t10 = in[6] + in[25]; t26 = MUL(in[6] - in[25], costab13);
t11 = in[9] + in[22]; t27 = MUL(in[9] - in[22], costab19);
t46 = t26 + t27;
t64 = MUL(t26 - t27, costab26);
t38 = t10 + t11;
t55 = MUL(t10 - t11, costab26);
t12 = in[2] + in[29]; t28 = MUL(in[2] - in[29], costab5);
t13 = in[13] + in[18]; t29 = MUL(in[13] - in[18], costab27);
t47 = t28 + t29;
t65 = MUL(t28 - t29, costab10);
t39 = t12 + t13;
t56 = MUL(t12 - t13, costab10);
t14 = in[5] + in[26]; t30 = MUL(in[5] - in[26], costab11);
t15 = in[10] + in[21]; t31 = MUL(in[10] - in[21], costab21);
t48 = t30 + t31;
t66 = MUL(t30 - t31, costab22);
t40 = t14 + t15;
t57 = MUL(t14 - t15, costab22);
t69 = t33 + t34; t89 = MUL(t33 - t34, costab4);
t70 = t35 + t36; t90 = MUL(t35 - t36, costab28);
t71 = t37 + t38; t91 = MUL(t37 - t38, costab12);
t72 = t39 + t40; t92 = MUL(t39 - t40, costab20);
t73 = t41 + t42; t94 = MUL(t41 - t42, costab4);
t74 = t43 + t44; t95 = MUL(t43 - t44, costab28);
t75 = t45 + t46; t96 = MUL(t45 - t46, costab12);
t76 = t47 + t48; t97 = MUL(t47 - t48, costab20);
t78 = t50 + t51; t100 = MUL(t50 - t51, costab4);
t79 = t52 + t53; t101 = MUL(t52 - t53, costab28);
t80 = t54 + t55; t102 = MUL(t54 - t55, costab12);
t81 = t56 + t57; t103 = MUL(t56 - t57, costab20);
t83 = t59 + t60; t106 = MUL(t59 - t60, costab4);
t84 = t61 + t62; t107 = MUL(t61 - t62, costab28);
t85 = t63 + t64; t108 = MUL(t63 - t64, costab12);
t86 = t65 + t66; t109 = MUL(t65 - t66, costab20);
t113 = t69 + t70;
t114 = t71 + t72;
/* 0 */ hi[15][slot] = SHIFT(t113 + t114);
/* 16 */ lo[ 0][slot] = SHIFT(MUL(t113 - t114, costab16));
t115 = t73 + t74;
t116 = t75 + t76;
t32 = t115 + t116;
/* 1 */ hi[14][slot] = SHIFT(t32);
t118 = t78 + t79;
t119 = t80 + t81;
t58 = t118 + t119;
/* 2 */ hi[13][slot] = SHIFT(t58);
t121 = t83 + t84;
t122 = t85 + t86;
t67 = t121 + t122;
t49 = (t67 * 2) - t32;
/* 3 */ hi[12][slot] = SHIFT(t49);
t125 = t89 + t90;
t126 = t91 + t92;
t93 = t125 + t126;
/* 4 */ hi[11][slot] = SHIFT(t93);
t128 = t94 + t95;
t129 = t96 + t97;
t98 = t128 + t129;
t68 = (t98 * 2) - t49;
/* 5 */ hi[10][slot] = SHIFT(t68);
t132 = t100 + t101;
t133 = t102 + t103;
t104 = t132 + t133;
t82 = (t104 * 2) - t58;
/* 6 */ hi[ 9][slot] = SHIFT(t82);
t136 = t106 + t107;
t137 = t108 + t109;
t110 = t136 + t137;
t87 = (t110 * 2) - t67;
t77 = (t87 * 2) - t68;
/* 7 */ hi[ 8][slot] = SHIFT(t77);
t141 = MUL(t69 - t70, costab8);
t142 = MUL(t71 - t72, costab24);
t143 = t141 + t142;
/* 8 */ hi[ 7][slot] = SHIFT(t143);
/* 24 */ lo[ 8][slot] =
SHIFT((MUL(t141 - t142, costab16) * 2) - t143);
t144 = MUL(t73 - t74, costab8);
t145 = MUL(t75 - t76, costab24);
t146 = t144 + t145;
t88 = (t146 * 2) - t77;
/* 9 */ hi[ 6][slot] = SHIFT(t88);
t148 = MUL(t78 - t79, costab8);
t149 = MUL(t80 - t81, costab24);
t150 = t148 + t149;
t105 = (t150 * 2) - t82;
/* 10 */ hi[ 5][slot] = SHIFT(t105);
t152 = MUL(t83 - t84, costab8);
t153 = MUL(t85 - t86, costab24);
t154 = t152 + t153;
t111 = (t154 * 2) - t87;
t99 = (t111 * 2) - t88;
/* 11 */ hi[ 4][slot] = SHIFT(t99);
t157 = MUL(t89 - t90, costab8);
t158 = MUL(t91 - t92, costab24);
t159 = t157 + t158;
t127 = (t159 * 2) - t93;
/* 12 */ hi[ 3][slot] = SHIFT(t127);
t160 = (MUL(t125 - t126, costab16) * 2) - t127;
/* 20 */ lo[ 4][slot] = SHIFT(t160);
/* 28 */ lo[12][slot] =
SHIFT((((MUL(t157 - t158, costab16) * 2) - t159) * 2) - t160);
t161 = MUL(t94 - t95, costab8);
t162 = MUL(t96 - t97, costab24);
t163 = t161 + t162;
t130 = (t163 * 2) - t98;
t112 = (t130 * 2) - t99;
/* 13 */ hi[ 2][slot] = SHIFT(t112);
t164 = (MUL(t128 - t129, costab16) * 2) - t130;
t166 = MUL(t100 - t101, costab8);
t167 = MUL(t102 - t103, costab24);
t168 = t166 + t167;
t134 = (t168 * 2) - t104;
t120 = (t134 * 2) - t105;
/* 14 */ hi[ 1][slot] = SHIFT(t120);
t135 = (MUL(t118 - t119, costab16) * 2) - t120;
/* 18 */ lo[ 2][slot] = SHIFT(t135);
t169 = (MUL(t132 - t133, costab16) * 2) - t134;
t151 = (t169 * 2) - t135;
/* 22 */ lo[ 6][slot] = SHIFT(t151);
t170 = (((MUL(t148 - t149, costab16) * 2) - t150) * 2) - t151;
/* 26 */ lo[10][slot] = SHIFT(t170);
/* 30 */ lo[14][slot] =
SHIFT((((((MUL(t166 - t167, costab16) * 2) -
t168) * 2) - t169) * 2) - t170);
t171 = MUL(t106 - t107, costab8);
t172 = MUL(t108 - t109, costab24);
t173 = t171 + t172;
t138 = (t173 * 2) - t110;
t123 = (t138 * 2) - t111;
t139 = (MUL(t121 - t122, costab16) * 2) - t123;
t117 = (t123 * 2) - t112;
/* 15 */ hi[ 0][slot] = SHIFT(t117);
t124 = (MUL(t115 - t116, costab16) * 2) - t117;
/* 17 */ lo[ 1][slot] = SHIFT(t124);
t131 = (t139 * 2) - t124;
/* 19 */ lo[ 3][slot] = SHIFT(t131);
t140 = (t164 * 2) - t131;
/* 21 */ lo[ 5][slot] = SHIFT(t140);
t174 = (MUL(t136 - t137, costab16) * 2) - t138;
t155 = (t174 * 2) - t139;
t147 = (t155 * 2) - t140;
/* 23 */ lo[ 7][slot] = SHIFT(t147);
t156 = (((MUL(t144 - t145, costab16) * 2) - t146) * 2) - t147;
/* 25 */ lo[ 9][slot] = SHIFT(t156);
t175 = (((MUL(t152 - t153, costab16) * 2) - t154) * 2) - t155;
t165 = (t175 * 2) - t156;
/* 27 */ lo[11][slot] = SHIFT(t165);
t176 = (((((MUL(t161 - t162, costab16) * 2) -
t163) * 2) - t164) * 2) - t165;
/* 29 */ lo[13][slot] = SHIFT(t176);
/* 31 */ lo[15][slot] =
SHIFT((((((((MUL(t171 - t172, costab16) * 2) -
t173) * 2) - t174) * 2) - t175) * 2) - t176);
/*
* Totals:
* 80 multiplies
* 80 additions
* 119 subtractions
* 49 shifts (not counting SSO)
*/
}
# undef MUL
# undef SHIFT
/* third SSO shift and/or D[] optimization preshift */
# if defined(OPT_SSO)
# if MAD_F_FRACBITS != 28
# error "MAD_F_FRACBITS must be 28 to use OPT_SSO"
# endif
# define ML0(hi, lo, x, y) ((lo) = (x) * (y))
# define MLA(hi, lo, x, y) ((lo) += (x) * (y))
# define MLN(hi, lo) ((lo) = -(lo))
# define MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
# define SHIFT(x) ((x) >> 2)
# define PRESHIFT(x) ((MAD_F(x) + (1L << 13)) >> 14)
# else
# define ML0(hi, lo, x, y) MAD_F_ML0((hi), (lo), (x), (y))
# define MLA(hi, lo, x, y) MAD_F_MLA((hi), (lo), (x), (y))
# define MLN(hi, lo) MAD_F_MLN((hi), (lo))
# define MLZ(hi, lo) MAD_F_MLZ((hi), (lo))
# define SHIFT(x) (x)
# if defined(MAD_F_SCALEBITS)
# undef MAD_F_SCALEBITS
# define MAD_F_SCALEBITS (MAD_F_FRACBITS - 12)
# define PRESHIFT(x) (MAD_F(x) >> 12)
# else
# define PRESHIFT(x) MAD_F(x)
# endif
# endif
static
mad_fixed_t ICACHE_RODATA_ATTR const D[17][32] = {
# include "D.dat"
};
# if defined(ASO_SYNTH)
void ICACHE_FLASH_ATTR synth_full(struct mad_synth *, struct mad_frame const *,
unsigned int, unsigned int);
# else
/*
* NAME: synth->full()
* DESCRIPTION: perform full frequency PCM synthesis
*/
static
void ICACHE_FLASH_ATTR synth_full(struct mad_synth *synth, struct mad_frame const *frame,
unsigned int nch, unsigned int ns)
{
unsigned int phase, ch, s, sb, pe, po;
short int *pcm1, *pcm2;
mad_fixed_t (*filter)[2][2][16][8];
mad_fixed_t (*sbsample)[36][32];
register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
register mad_fixed_t const (*Dptr)[32], *ptr ;
register mad_fixed64hi_t hi;
register mad_fixed64lo_t lo;
mad_fixed_t raw_sample;
short int short_sample_buff[64]; //32];
phase = synth->phase;
for (s = 0; s < ns; ++s)
{
memset(short_sample_buff, 0x00, sizeof(short_sample_buff));
for (ch = 0; ch < nch; ++ch)
{
sbsample = (void*)&frame->sbsample[ch];
filter = &synth->filter[ch];
pcm1 = short_sample_buff;
dct32((*sbsample)[s], phase >> 1,
(*filter)[0][phase & 1], (*filter)[1][phase & 1]);
pe = phase & ~1;
po = ((phase - 1) & 0xf) | 1;
/* calculate 16 samples */
fe = &(*filter)[0][ phase & 1][0];
fx = &(*filter)[0][~phase & 1][0];
fo = &(*filter)[1][~phase & 1][0];
Dptr = &D[0];
ptr = *Dptr + po;
ML0(hi, lo, (*fx)[0], ptr[ 0]);
MLA(hi, lo, (*fx)[1], ptr[14]);
MLA(hi, lo, (*fx)[2], ptr[12]);
MLA(hi, lo, (*fx)[3], ptr[10]);
MLA(hi, lo, (*fx)[4], ptr[ 8]);
MLA(hi, lo, (*fx)[5], ptr[ 6]);
MLA(hi, lo, (*fx)[6], ptr[ 4]);
MLA(hi, lo, (*fx)[7], ptr[ 2]);
MLN(hi, lo);
ptr = *Dptr + pe;
MLA(hi, lo, (*fe)[0], ptr[ 0]);
MLA(hi, lo, (*fe)[1], ptr[14]);
MLA(hi, lo, (*fe)[2], ptr[12]);
MLA(hi, lo, (*fe)[3], ptr[10]);
MLA(hi, lo, (*fe)[4], ptr[ 8]);
MLA(hi, lo, (*fe)[5], ptr[ 6]);
MLA(hi, lo, (*fe)[6], ptr[ 4]);
MLA(hi, lo, (*fe)[7], ptr[ 2]);
raw_sample = SHIFT(MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm1++) += (short int)raw_sample;
pcm2 = pcm1 + 30;
for (sb = 1; sb < 16; ++sb)
{
++fe;
++Dptr;
/* D[32 - sb][i] == -D[sb][31 - i] */
ptr = *Dptr + po;
ML0(hi, lo, (*fo)[0], ptr[ 0]);
MLA(hi, lo, (*fo)[1], ptr[14]);
MLA(hi, lo, (*fo)[2], ptr[12]);
MLA(hi, lo, (*fo)[3], ptr[10]);
MLA(hi, lo, (*fo)[4], ptr[ 8]);
MLA(hi, lo, (*fo)[5], ptr[ 6]);
MLA(hi, lo, (*fo)[6], ptr[ 4]);
MLA(hi, lo, (*fo)[7], ptr[ 2]);
MLN(hi, lo);
ptr = *Dptr + pe;
MLA(hi, lo, (*fe)[7], ptr[ 2]);
MLA(hi, lo, (*fe)[6], ptr[ 4]);
MLA(hi, lo, (*fe)[5], ptr[ 6]);
MLA(hi, lo, (*fe)[4], ptr[ 8]);
MLA(hi, lo, (*fe)[3], ptr[10]);
MLA(hi, lo, (*fe)[2], ptr[12]);
MLA(hi, lo, (*fe)[1], ptr[14]);
MLA(hi, lo, (*fe)[0], ptr[ 0]);
raw_sample = SHIFT(MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm1++) += (short int)raw_sample;
ptr = *Dptr - pe;
ML0(hi, lo, (*fe)[0], ptr[31 - 16]);
MLA(hi, lo, (*fe)[1], ptr[31 - 14]);
MLA(hi, lo, (*fe)[2], ptr[31 - 12]);
MLA(hi, lo, (*fe)[3], ptr[31 - 10]);
MLA(hi, lo, (*fe)[4], ptr[31 - 8]);
MLA(hi, lo, (*fe)[5], ptr[31 - 6]);
MLA(hi, lo, (*fe)[6], ptr[31 - 4]);
MLA(hi, lo, (*fe)[7], ptr[31 - 2]);
ptr = *Dptr - po;
MLA(hi, lo, (*fo)[7], ptr[31 - 2]);
MLA(hi, lo, (*fo)[6], ptr[31 - 4]);
MLA(hi, lo, (*fo)[5], ptr[31 - 6]);
MLA(hi, lo, (*fo)[4], ptr[31 - 8]);
MLA(hi, lo, (*fo)[3], ptr[31 - 10]);
MLA(hi, lo, (*fo)[2], ptr[31 - 12]);
MLA(hi, lo, (*fo)[1], ptr[31 - 14]);
MLA(hi, lo, (*fo)[0], ptr[31 - 16]);
raw_sample = SHIFT(MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm2--) += (short int)raw_sample;
++fo;
}
Dptr++;
ptr = *Dptr + po;
ML0(hi, lo, (*fo)[0], ptr[ 0]);
MLA(hi, lo, (*fo)[1], ptr[14]);
MLA(hi, lo, (*fo)[2], ptr[12]);
MLA(hi, lo, (*fo)[3], ptr[10]);
MLA(hi, lo, (*fo)[4], ptr[ 8]);
MLA(hi, lo, (*fo)[5], ptr[ 6]);
MLA(hi, lo, (*fo)[6], ptr[ 4]);
MLA(hi, lo, (*fo)[7], ptr[ 2]);
raw_sample = SHIFT(-MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm1) += (short int)raw_sample;
} /* Channel For */
/* Render di un blocco */
render_sample_block(short_sample_buff, sizeof(short_sample_buff)/sizeof(short int));
phase = (phase + 1) % 16;
} /* Block for */
}
#endif
/*
* NAME: synth->half()
* DESCRIPTION: perform half frequency PCM synthesis
*/
static
void ICACHE_FLASH_ATTR synth_half(struct mad_synth *synth, struct mad_frame const *frame,
unsigned int nch, unsigned int ns)
{
unsigned int phase, ch, s, sb, pe, po;
short int *pcm1, *pcm2;
mad_fixed_t (*filter)[2][2][16][8];
mad_fixed_t (*sbsample)[36][32];
register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
register mad_fixed_t const (*Dptr)[32], *ptr ;
register mad_fixed64hi_t hi;
register mad_fixed64lo_t lo;
mad_fixed_t raw_sample;
short int short_sample_buff[16];
phase = synth->phase;
for (s = 0; s < ns; ++s)
{
memset (short_sample_buff, 0x00, sizeof(short_sample_buff));
for (ch = 0; ch < nch; ++ch)
{
sbsample = (void *)&frame->sbsample[ch];
filter = &synth->filter[ch];
pcm1 = short_sample_buff;
dct32((*sbsample)[s], phase >> 1,
(*filter)[0][phase & 1], (*filter)[1][phase & 1]);
pe = phase & ~1;
po = ((phase - 1) & 0xf) | 1;
/* calculate 16 samples */
fe = &(*filter)[0][ phase & 1][0];
fx = &(*filter)[0][~phase & 1][0];
fo = &(*filter)[1][~phase & 1][0];
Dptr = &D[0];
ptr = *Dptr + po;
ML0(hi, lo, (*fx)[0], ptr[ 0]);
MLA(hi, lo, (*fx)[1], ptr[14]);
MLA(hi, lo, (*fx)[2], ptr[12]);
MLA(hi, lo, (*fx)[3], ptr[10]);
MLA(hi, lo, (*fx)[4], ptr[ 8]);
MLA(hi, lo, (*fx)[5], ptr[ 6]);
MLA(hi, lo, (*fx)[6], ptr[ 4]);
MLA(hi, lo, (*fx)[7], ptr[ 2]);
MLN(hi, lo);
ptr = *Dptr + pe;
MLA(hi, lo, (*fe)[0], ptr[ 0]);
MLA(hi, lo, (*fe)[1], ptr[14]);
MLA(hi, lo, (*fe)[2], ptr[12]);
MLA(hi, lo, (*fe)[3], ptr[10]);
MLA(hi, lo, (*fe)[4], ptr[ 8]);
MLA(hi, lo, (*fe)[5], ptr[ 6]);
MLA(hi, lo, (*fe)[6], ptr[ 4]);
MLA(hi, lo, (*fe)[7], ptr[ 2]);
raw_sample = SHIFT(MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm1++) += (short int)raw_sample;
pcm2 = pcm1 + 14;
for (sb = 1; sb < 16; ++sb)
{
++fe;
++Dptr;
/* D[32 - sb][i] == -D[sb][31 - i] */
ptr = *Dptr + po;
ML0(hi, lo, (*fo)[0], ptr[ 0]);
MLA(hi, lo, (*fo)[1], ptr[14]);
MLA(hi, lo, (*fo)[2], ptr[12]);
MLA(hi, lo, (*fo)[3], ptr[10]);
MLA(hi, lo, (*fo)[4], ptr[ 8]);
MLA(hi, lo, (*fo)[5], ptr[ 6]);
MLA(hi, lo, (*fo)[6], ptr[ 4]);
MLA(hi, lo, (*fo)[7], ptr[ 2]);
MLN(hi, lo);
ptr = *Dptr + pe;
MLA(hi, lo, (*fe)[7], ptr[ 2]);
MLA(hi, lo, (*fe)[6], ptr[ 4]);
MLA(hi, lo, (*fe)[5], ptr[ 6]);
MLA(hi, lo, (*fe)[4], ptr[ 8]);
MLA(hi, lo, (*fe)[3], ptr[10]);
MLA(hi, lo, (*fe)[2], ptr[12]);
MLA(hi, lo, (*fe)[1], ptr[14]);
MLA(hi, lo, (*fe)[0], ptr[ 0]);
raw_sample = SHIFT(MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm1++) += (short int)raw_sample;
ptr = *Dptr - pe;
ML0(hi, lo, (*fe)[0], ptr[31 - 16]);
MLA(hi, lo, (*fe)[1], ptr[31 - 14]);
MLA(hi, lo, (*fe)[2], ptr[31 - 12]);
MLA(hi, lo, (*fe)[3], ptr[31 - 10]);
MLA(hi, lo, (*fe)[4], ptr[31 - 8]);
MLA(hi, lo, (*fe)[5], ptr[31 - 6]);
MLA(hi, lo, (*fe)[6], ptr[31 - 4]);
MLA(hi, lo, (*fe)[7], ptr[31 - 2]);
ptr = *Dptr - po;
MLA(hi, lo, (*fo)[7], ptr[31 - 2]);
MLA(hi, lo, (*fo)[6], ptr[31 - 4]);
MLA(hi, lo, (*fo)[5], ptr[31 - 6]);
MLA(hi, lo, (*fo)[4], ptr[31 - 8]);
MLA(hi, lo, (*fo)[3], ptr[31 - 10]);
MLA(hi, lo, (*fo)[2], ptr[31 - 12]);
MLA(hi, lo, (*fo)[1], ptr[31 - 14]);
MLA(hi, lo, (*fo)[0], ptr[31 - 16]);
raw_sample = SHIFT(MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm2--) += (short int)raw_sample;
++fo;
}
Dptr++;
ptr = *Dptr + po;
ML0(hi, lo, (*fo)[0], ptr[ 0]);
MLA(hi, lo, (*fo)[1], ptr[14]);
MLA(hi, lo, (*fo)[2], ptr[12]);
MLA(hi, lo, (*fo)[3], ptr[10]);
MLA(hi, lo, (*fo)[4], ptr[ 8]);
MLA(hi, lo, (*fo)[5], ptr[ 6]);
MLA(hi, lo, (*fo)[6], ptr[ 4]);
MLA(hi, lo, (*fo)[7], ptr[ 2]);
raw_sample = SHIFT(-MLZ(hi, lo));
raw_sample = scale(raw_sample);
(*pcm1) += (short int)raw_sample;
} /* Channel For */
/* Block render */
render_sample_block(short_sample_buff, sizeof(short_sample_buff)/sizeof(short int));
phase = (phase + 1) % 16;
}/* Block For */
}
/*
* NAME: synth->frame()
* DESCRIPTION: perform PCM synthesis of frame subband samples
*/
void ICACHE_FLASH_ATTR mad_synth_frame(struct mad_synth *synth, struct mad_frame const *frame)
{
unsigned int nch, ns;
void (*synth_frame)(struct mad_synth *, struct mad_frame const *,
unsigned int, unsigned int);
nch = MAD_NCHANNELS(&frame->header);
ns = MAD_NSBSAMPLES(&frame->header);
synth->pcm.samplerate = frame->header.samplerate;
synth->pcm.channels = nch;
// synth->pcm.length = 32 * ns;
synth->pcm.length = 128 * ns;
synth_frame = synth_full;
if (frame->options & MAD_OPTION_HALFSAMPLERATE) {
synth->pcm.samplerate /= 2;
synth->pcm.length /= 2;
synth_frame = synth_half;
}
set_dac_sample_rate(synth->pcm.samplerate);
synth_frame(synth, frame, nch, ns);
synth->phase = (synth->phase + ns) % 16;
}

View file

@ -1,485 +0,0 @@
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: timer.c,v 1.18 2004/01/23 09:41:33 rob Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include <stdio.h>
# ifdef HAVE_ASSERT_H
# include <assert.h>
# endif
# include "timer.h"
mad_timer_t const mad_timer_zero = { 0, 0 };
/*
* NAME: timer->compare()
* DESCRIPTION: indicate relative order of two timers
*/
int ICACHE_FLASH_ATTR mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2)
{
signed long diff;
diff = timer1.seconds - timer2.seconds;
if (diff < 0)
return -1;
else if (diff > 0)
return +1;
diff = timer1.fraction - timer2.fraction;
if (diff < 0)
return -1;
else if (diff > 0)
return +1;
return 0;
}
/*
* NAME: timer->negate()
* DESCRIPTION: invert the sign of a timer
*/
void ICACHE_FLASH_ATTR mad_timer_negate(mad_timer_t *timer)
{
timer->seconds = -timer->seconds;
if (timer->fraction) {
timer->seconds -= 1;
timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction;
}
}
/*
* NAME: timer->abs()
* DESCRIPTION: return the absolute value of a timer
*/
mad_timer_t mad_timer_abs(mad_timer_t timer)
{
if (timer.seconds < 0)
mad_timer_negate(&timer);
return timer;
}
/*
* NAME: reduce_timer()
* DESCRIPTION: carry timer fraction into seconds
*/
static
void ICACHE_FLASH_ATTR reduce_timer(mad_timer_t *timer)
{
timer->seconds += timer->fraction / MAD_TIMER_RESOLUTION;
timer->fraction %= MAD_TIMER_RESOLUTION;
}
/*
* NAME: gcd()
* DESCRIPTION: compute greatest common denominator
*/
static
unsigned long ICACHE_FLASH_ATTR gcd(unsigned long num1, unsigned long num2)
{
unsigned long tmp;
while (num2) {
tmp = num2;
num2 = num1 % num2;
num1 = tmp;
}
return num1;
}
/*
* NAME: reduce_rational()
* DESCRIPTION: convert rational expression to lowest terms
*/
static
void ICACHE_FLASH_ATTR reduce_rational(unsigned long *numer, unsigned long *denom)
{
unsigned long factor;
factor = gcd(*numer, *denom);
//assert(factor != 0);
*numer /= factor;
*denom /= factor;
}
/*
* NAME: scale_rational()
* DESCRIPTION: solve numer/denom == ?/scale avoiding overflowing
*/
static
unsigned long ICACHE_FLASH_ATTR scale_rational(unsigned long numer, unsigned long denom,
unsigned long scale)
{
reduce_rational(&numer, &denom);
reduce_rational(&scale, &denom);
//assert(denom != 0);
if (denom < scale)
return numer * (scale / denom) + numer * (scale % denom) / denom;
if (denom < numer)
return scale * (numer / denom) + scale * (numer % denom) / denom;
return numer * scale / denom;
}
/*
* NAME: timer->set()
* DESCRIPTION: set timer to specific (positive) value
*/
void ICACHE_FLASH_ATTR mad_timer_set(mad_timer_t *timer, unsigned long seconds,
unsigned long numer, unsigned long denom)
{
timer->seconds = seconds;
if (numer >= denom && denom > 0) {
timer->seconds += numer / denom;
numer %= denom;
}
switch (denom) {
case 0:
case 1:
timer->fraction = 0;
break;
case MAD_TIMER_RESOLUTION:
timer->fraction = numer;
break;
case 1000:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 1000);
break;
case 8000:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 8000);
break;
case 11025:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025);
break;
case 12000:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000);
break;
case 16000:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000);
break;
case 22050:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050);
break;
case 24000:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000);
break;
case 32000:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000);
break;
case 44100:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100);
break;
case 48000:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000);
break;
default:
timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION);
break;
}
if (timer->fraction >= MAD_TIMER_RESOLUTION)
reduce_timer(timer);
}
/*
* NAME: timer->add()
* DESCRIPTION: add one timer to another
*/
void ICACHE_FLASH_ATTR mad_timer_add(mad_timer_t *timer, mad_timer_t incr)
{
timer->seconds += incr.seconds;
timer->fraction += incr.fraction;
if (timer->fraction >= MAD_TIMER_RESOLUTION)
reduce_timer(timer);
}
/*
* NAME: timer->multiply()
* DESCRIPTION: multiply a timer by a scalar value
*/
void ICACHE_FLASH_ATTR mad_timer_multiply(mad_timer_t *timer, signed long scalar)
{
mad_timer_t addend;
unsigned long factor;
factor = scalar;
if (scalar < 0) {
factor = -scalar;
mad_timer_negate(timer);
}
addend = *timer;
*timer = mad_timer_zero;
while (factor) {
if (factor & 1)
mad_timer_add(timer, addend);
mad_timer_add(&addend, addend);
factor >>= 1;
}
}
/*
* NAME: timer->count()
* DESCRIPTION: return timer value in selected units
*/
signed long ICACHE_FLASH_ATTR mad_timer_count(mad_timer_t timer, enum mad_units units)
{
switch (units) {
case MAD_UNITS_HOURS:
return timer.seconds / 60 / 60;
case MAD_UNITS_MINUTES:
return timer.seconds / 60;
case MAD_UNITS_SECONDS:
return timer.seconds;
case MAD_UNITS_DECISECONDS:
case MAD_UNITS_CENTISECONDS:
case MAD_UNITS_MILLISECONDS:
case MAD_UNITS_8000_HZ:
case MAD_UNITS_11025_HZ:
case MAD_UNITS_12000_HZ:
case MAD_UNITS_16000_HZ:
case MAD_UNITS_22050_HZ:
case MAD_UNITS_24000_HZ:
case MAD_UNITS_32000_HZ:
case MAD_UNITS_44100_HZ:
case MAD_UNITS_48000_HZ:
case MAD_UNITS_24_FPS:
case MAD_UNITS_25_FPS:
case MAD_UNITS_30_FPS:
case MAD_UNITS_48_FPS:
case MAD_UNITS_50_FPS:
case MAD_UNITS_60_FPS:
case MAD_UNITS_75_FPS:
return timer.seconds * (signed long) units +
(signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION,
units);
case MAD_UNITS_23_976_FPS:
case MAD_UNITS_24_975_FPS:
case MAD_UNITS_29_97_FPS:
case MAD_UNITS_47_952_FPS:
case MAD_UNITS_49_95_FPS:
case MAD_UNITS_59_94_FPS:
return (mad_timer_count(timer, -units) + 1) * 1000 / 1001;
}
/* unsupported units */
return 0;
}
/*
* NAME: timer->fraction()
* DESCRIPTION: return fractional part of timer in arbitrary terms
*/
unsigned long ICACHE_FLASH_ATTR mad_timer_fraction(mad_timer_t timer, unsigned long denom)
{
timer = mad_timer_abs(timer);
switch (denom) {
case 0:
return timer.fraction ?
MAD_TIMER_RESOLUTION / timer.fraction : MAD_TIMER_RESOLUTION + 1;
case MAD_TIMER_RESOLUTION:
return timer.fraction;
default:
return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom);
}
}
/*
* NAME: timer->string()
* DESCRIPTION: write a string representation of a timer using a template
*/
void ICACHE_FLASH_ATTR mad_timer_string(mad_timer_t timer,
char *dest, char const *format, enum mad_units units,
enum mad_units fracunits, unsigned long subparts)
{
unsigned long hours, minutes, seconds, sub;
unsigned int frac;
timer = mad_timer_abs(timer);
seconds = timer.seconds;
frac = sub = 0;
switch (fracunits) {
case MAD_UNITS_HOURS:
case MAD_UNITS_MINUTES:
case MAD_UNITS_SECONDS:
break;
case MAD_UNITS_DECISECONDS:
case MAD_UNITS_CENTISECONDS:
case MAD_UNITS_MILLISECONDS:
case MAD_UNITS_8000_HZ:
case MAD_UNITS_11025_HZ:
case MAD_UNITS_12000_HZ:
case MAD_UNITS_16000_HZ:
case MAD_UNITS_22050_HZ:
case MAD_UNITS_24000_HZ:
case MAD_UNITS_32000_HZ:
case MAD_UNITS_44100_HZ:
case MAD_UNITS_48000_HZ:
case MAD_UNITS_24_FPS:
case MAD_UNITS_25_FPS:
case MAD_UNITS_30_FPS:
case MAD_UNITS_48_FPS:
case MAD_UNITS_50_FPS:
case MAD_UNITS_60_FPS:
case MAD_UNITS_75_FPS:
{
unsigned long denom;
denom = MAD_TIMER_RESOLUTION / fracunits;
frac = timer.fraction / denom;
sub = scale_rational(timer.fraction % denom, denom, subparts);
}
break;
case MAD_UNITS_23_976_FPS:
case MAD_UNITS_24_975_FPS:
case MAD_UNITS_29_97_FPS:
case MAD_UNITS_47_952_FPS:
case MAD_UNITS_49_95_FPS:
case MAD_UNITS_59_94_FPS:
/* drop-frame encoding */
/* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */
{
unsigned long frame, cycle, d, m;
frame = mad_timer_count(timer, fracunits);
cycle = -fracunits * 60 * 10 - (10 - 1) * 2;
d = frame / cycle;
m = frame % cycle;
frame += (10 - 1) * 2 * d;
if (m > 2)
frame += 2 * ((m - 2) / (cycle / 10));
frac = frame % -fracunits;
seconds = frame / -fracunits;
}
break;
}
switch (units) {
case MAD_UNITS_HOURS:
minutes = seconds / 60;
hours = minutes / 60;
sprintf(dest, format,
hours,
(unsigned int) (minutes % 60),
(unsigned int) (seconds % 60),
frac, sub);
break;
case MAD_UNITS_MINUTES:
minutes = seconds / 60;
sprintf(dest, format,
minutes,
(unsigned int) (seconds % 60),
frac, sub);
break;
case MAD_UNITS_SECONDS:
sprintf(dest, format,
seconds,
frac, sub);
break;
case MAD_UNITS_23_976_FPS:
case MAD_UNITS_24_975_FPS:
case MAD_UNITS_29_97_FPS:
case MAD_UNITS_47_952_FPS:
case MAD_UNITS_49_95_FPS:
case MAD_UNITS_59_94_FPS:
if (fracunits < 0) {
/* not yet implemented */
sub = 0;
}
/* fall through */
case MAD_UNITS_DECISECONDS:
case MAD_UNITS_CENTISECONDS:
case MAD_UNITS_MILLISECONDS:
case MAD_UNITS_8000_HZ:
case MAD_UNITS_11025_HZ:
case MAD_UNITS_12000_HZ:
case MAD_UNITS_16000_HZ:
case MAD_UNITS_22050_HZ:
case MAD_UNITS_24000_HZ:
case MAD_UNITS_32000_HZ:
case MAD_UNITS_44100_HZ:
case MAD_UNITS_48000_HZ:
case MAD_UNITS_24_FPS:
case MAD_UNITS_25_FPS:
case MAD_UNITS_30_FPS:
case MAD_UNITS_48_FPS:
case MAD_UNITS_50_FPS:
case MAD_UNITS_60_FPS:
case MAD_UNITS_75_FPS:
sprintf(dest, format, mad_timer_count(timer, units), sub);
break;
}
}

View file

@ -1,354 +0,0 @@
#include <platform_opts.h>
#ifdef CONFIG_AT_USR
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "at_cmd/log_service.h"
#include "at_cmd/atcmd_wifi.h"
#include <lwip_netconf.h>
#include "tcpip.h"
#include <dhcp/dhcps.h>
#include <wifi/wifi_conf.h>
#include <wifi/wifi_util.h>
#include "tcm_heap.h"
#include "user/atcmd_user.h"
#include "sleep_ex_api.h"
#include "lwip/tcp_impl.h"
extern char str_rom_57ch3Dch0A[]; // "=========================================================\n" 57
#define printf rtl_printf // DiagPrintf
/* RAM/TCM/Heaps info */
extern void ShowMemInfo(void);
/*
void ShowMemInfo(void)
{
printf("\nCLK CPU\t\t%d Hz\nRAM heap\t%d bytes\nTCM heap\t%d bytes\n",
HalGetCpuClk(), xPortGetFreeHeapSize(), tcm_heap_freeSpace());
}
*/
//------------------------------------------------------------------------------
// Mem, Tasks info
//------------------------------------------------------------------------------
LOCAL void fATST(int argc, char *argv[]) {
ShowMemInfo();
#if 0 //CONFIG_DEBUG_LOG > 1
dump_mem_block_list();
tcm_heap_dump();
#endif;
printf("\n");
#if (configGENERATE_RUN_TIME_STATS == 1)
char *cBuffer = pvPortMalloc(512);
if(cBuffer != NULL) {
vTaskGetRunTimeStats((char *)cBuffer);
printf("%s", cBuffer);
}
vPortFree(cBuffer);
#endif
#if defined(configUSE_TRACE_FACILITY) && (configUSE_TRACE_FACILITY == 1) && (configUSE_STATS_FORMATTING_FUNCTIONS == 1)
{
char * pcWriteBuffer = malloc(1024);
if(pcWriteBuffer) {
vTaskList((char*)pcWriteBuffer);
printf("\nTask List:\n");
printf(&str_rom_57ch3Dch0A[7]); // "==========================================\n"
printf("Name\t Status Priority HighWaterMark TaskNumber\n%s\n", pcWriteBuffer);
free(pcWriteBuffer);
}
}
#endif
}
/*-------------------------------------------------------------------------------------
Копирует данные из области align(4) (flash, registers, ...) в область align(1) (ram)
--------------------------------------------------------------------------------------*/
extern void copy_align4_to_align1(unsigned char * pd, void * ps, unsigned int len);
/*
static void copy_align4_to_align1(unsigned char * pd, void * ps, unsigned int len)
{
union {
unsigned char uc[4];
unsigned int ud;
}tmp;
unsigned int *p = (unsigned int *)((unsigned int)ps & (~3));
unsigned int xlen = (unsigned int)ps & 3;
// unsigned int size = len;
if(xlen) {
tmp.ud = *p++;
while (len) {
len--;
*pd++ = tmp.uc[xlen++];
if(xlen & 4) break;
}
}
xlen = len >> 2;
while(xlen) {
tmp.ud = *p++;
*pd++ = tmp.uc[0];
*pd++ = tmp.uc[1];
*pd++ = tmp.uc[2];
*pd++ = tmp.uc[3];
xlen--;
}
if(len & 3) {
tmp.ud = *p;
pd[0] = tmp.uc[0];
if(len & 2) {
pd[1] = tmp.uc[1];
if(len & 1) {
pd[2] = tmp.uc[2];
}
}
}
// return size;
}
*/
int print_hex_dump(uint8_t *buf, int len, unsigned char k) {
uint32_t ss[2];
ss[0] = 0x78323025; // "%02x"
ss[1] = k; // ","...'\0'
uint8_t * ptr = buf;
int result = 0;
while (len--) {
if (len == 0)
ss[1] = 0;
result += printf((uint8_t *) &ss, *ptr++);
}
return result;
}
extern char str_rom_hex_addr[]; // in *.ld "[Addr] .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F\n"
void dump_bytes(uint32 addr, int size)
{
uint8 buf[17];
u32 symbs_line = sizeof(buf)-1;
printf(str_rom_hex_addr);
while (size) {
if (symbs_line > size) symbs_line = size;
printf("%08X ", addr);
copy_align4_to_align1(buf, addr, symbs_line);
print_hex_dump(buf, symbs_line, ' ');
int i;
for(i = 0 ; i < symbs_line ; i++) {
if(buf[i] < 0x20 || buf[i] > 0x7E) {
buf[i] = '.';
}
}
buf[symbs_line] = 0;
i = (sizeof(buf)-1) - symbs_line;
while(i--) printf(" ");
printf(" %s\r\n", buf);
addr += symbs_line;
size -= symbs_line;
}
}
//------------------------------------------------------------------------------
// Dump byte register
//------------------------------------------------------------------------------
LOCAL void fATSB(int argc, char *argv[])
{
int size = 16;
uint32 addr = Strtoul(argv[1],0,16);
if (argc > 2) {
size = Strtoul(argv[2],0,10);
if (size <= 0 || size > 16384)
size = 16;
}
dump_bytes(addr, size);
}
//------------------------------------------------------------------------------
// Dump dword register
//------------------------------------------------------------------------------
extern u32 CmdDumpWord(IN u16 argc, IN u8 *argv[]);
LOCAL void fATSD(int argc, char *argv[])
{
/*
if (argc > 2) {
int size = Strtoul(argv[2],0,10);
if (size <= 0 || size > 16384)
argv[2] = "16";
}
*/
CmdDumpWord(argc-1, (unsigned char**)(argv+1));
}
//------------------------------------------------------------------------------
// Write dword register
//------------------------------------------------------------------------------
extern u32 CmdWriteWord(IN u16 argc, IN u8 *argv[]);
LOCAL void fATSW(int argc, char *argv[])
{
CmdWriteWord(argc-1, (unsigned char**)(argv+1));
}
/* Get one byte from the 4-byte address */
#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0])
#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1])
#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2])
#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3])
/* These are cast to u16_t, with the intent that they are often arguments
* to printf using the U16_F format from cc.h. */
#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr))
#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr))
#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr))
#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr))
#define IP2STR(ipaddr) ip4_addr1_16(ipaddr), \
ip4_addr2_16(ipaddr), \
ip4_addr3_16(ipaddr), \
ip4_addr4_16(ipaddr)
#define IPSTR "%d.%d.%d.%d"
extern const char * const tcp_state_str[];
/*
static const char * const tcp_state_str[] = {
"CLOSED",
"LISTEN",
"SYN_SENT",
"SYN_RCVD",
"ESTABLISHED",
"FIN_WAIT_1",
"FIN_WAIT_2",
"CLOSE_WAIT",
"CLOSING",
"LAST_ACK",
"TIME_WAIT"
};
*/
/******************************************************************************
* FunctionName : debug
* Parameters :
* Returns :
*******************************************************************************/
void print_udp_pcb(void)
{
struct udp_pcb *pcb;
bool prt_none = true;
rtl_printf("UDP pcbs:\n");
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
rtl_printf("flg:%02x\t" IPSTR ":%d\t" IPSTR ":%d\trecv:%p\n", pcb->flags, IP2STR(&pcb->local_ip), pcb->local_port, IP2STR(&pcb->remote_ip), pcb->remote_port, pcb->recv );
prt_none = false;
};
if(prt_none) rtl_printf("none\n");
}
/******************************************************************************
* FunctionName : debug
* Parameters :
* Returns :
*******************************************************************************/
void print_tcp_pcb(void)
{
struct tcp_pcb *pcb;
rtl_printf("Active PCB states:\n");
bool prt_none = true;
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]);
prt_none = false;
};
if(prt_none) rtl_printf("none\n");
rtl_printf("Listen PCB states:\n");
prt_none = true;
for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]);
prt_none = false;
};
if(prt_none) rtl_printf("none\n");
rtl_printf("TIME-WAIT PCB states:\n");
prt_none = true;
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]);
prt_none = false;
};
if(prt_none) rtl_printf("none\n");
}
/******************************************************************************
* FunctionName : debug
* Parameters :
* Returns :
*******************************************************************************/
LOCAL void fATLW(int argc, char *argv[]) // Info Lwip
{
print_udp_pcb();
print_tcp_pcb();
}
//------------------------------------------------------------------------------
// Deep sleep
//------------------------------------------------------------------------------
LOCAL void fATDS(int argc, char *argv[])
{
uint32 sleep_ms = 10000;
if(argc > 1) sleep_ms = atoi(argv[1]);
#if 0
if(argc > 2) {
printf("%u ms waiting low level on PB_1 before launching Deep-Sleep...\n", sleep_ms);
// turn off log uart
HalDeinitLogUart(); // sys_log_uart_off();
// initialize wakeup pin
gpio_t gpio_wake;
gpio_init(&gpio_wake, PB_1);
gpio_dir(&gpio_wake, PIN_INPUT);
gpio_mode(&gpio_wake, PullDown);
TickType_t sttime = xTaskGetTickCount();
do {
if(gpio_read(&gpio_wake) == 0) {
// Enter deep sleep... Wait give rising edge at PB_1 to wakeup system.
deepsleep_ex(DSLEEP_WAKEUP_BY_GPIO, 0);
};
vTaskDelay(1);
} while(xTaskGetTickCount() - sttime < sleep_ms);
HalInitLogUart(); // sys_log_uart_on();
printf("No set pin low in deep sleep!\n");
}
else {
printf("Deep-Sleep %u ms\n", sleep_ms);
HalLogUartWaitTxFifoEmpty();
// Enter deep sleep... Wait timer ms
deepsleep_ex(DSLEEP_WAKEUP_BY_TIMER, sleep_ms);
}
#else
HalLogUartWaitTxFifoEmpty();
deepsleep_ex(DSLEEP_WAKEUP_BY_TIMER, sleep_ms);
#endif
}
/*------------------------------------------------------------------------------
* power saving mode
*----------------------------------------------------------------------------*/
LOCAL void fATSP(int argc, char *argv[])
{
if(argc > 2) {
switch (argv[1][0]) {
case 'a': // acquire
{
acquire_wakelock(atoi(argv[2]));
break;
}
case 'r': // release
{
release_wakelock(atoi(argv[2]));
break;
}
};
};
printf("WakeLock Status %d\n", get_wakelock_status());
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_at[] = {
{"ATST", 0, fATST, ": Memory info"},
{"ATLW", 0, fATLW, ": LwIP Info"},
{"ATSB", 1, fATSB, "=<ADDRES(hex)>[,COUNT(dec)]: Dump byte register"},
{"ATSD", 1, fATSD, "=<ADDRES(hex)>[,COUNT(dec)]: Dump dword register"},
{"ATSW", 2, fATSW, "=<ADDRES(hex)>,<DATA(hex)>: Set register"},
{"ATDS", 0, fATDS, "=[TIME(ms)]: Deep sleep"},
{"ATSP", 0, fATSP, "=<a,r>,<wakelock_status:1|2|4|8>: Power"}
};
#endif //#ifdef CONFIG_AT_USR

View file

@ -1,619 +1,50 @@
/****************************************************************************** /*
* Routines to access hardware
* *
* FileName: user_main.c * Copyright (c) 2013 Realtek Semiconductor Corp.
* *
*******************************************************************************/ * This module is a confidential and proprietary property of RealTek and
#include "rtl8195a/rtl_common.h" * possession or use of this module requires written permission of RealTek.
#include "rtl8195a.h" */
#include "hal_log_uart.h"
#include "FreeRTOS.h" #include "device.h"
#include "task.h" #include "gpio_api.h" // mbed
//#include "diag.h"
#include "osdep_service.h"
#include "device_lock.h"
#include "semphr.h"
#include "queue.h"
#include <wifi/wifi_conf.h>
#include <wifi/wifi_util.h>
#include "lwip/sockets.h"
#include "lwip/err.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "dhcp/dhcps.h"
#include "mad/mad.h"
#include "mad/stream.h"
#include "mad/frame.h"
#include "mad/synth.h"
#include "driver/i2s_freertos.h"
#include "user/spiram_fifo.h"
#include "user/playerconfig.h"
#include "user/atcmd_user.h"
#include "main.h" #include "main.h"
#include "wifi_api.h"
#include "rtl8195a/rtl_libc.h" #define GPIO_LED_PIN PC_5
/* --------------------------------------------------- /* ---------------------------------------------------
* Customized Signature (Image Name) * Customized Signature (Image Name)
* ---------------------------------------------------*/ * ---------------------------------------------------*/
#include "section_config.h" #include "section_config.h"
SECTION(".custom.validate.rodata") SECTION(".custom.validate.rodata")
const unsigned char cus_sig[32] = "MP3 Stereo"; const unsigned char cus_sig[32] = "Blinky";
#define DEBUG_MAIN_LEVEL 1
//Priorities of the reader and the decoder thread. Higher = higher prio.
#define PRIO_MAD (tskIDLE_PRIORITY + 3 + PRIORITIE_OFFSET)
#define PRIO_READER (PRIO_MAD)
#define mMIN(a, b) ((a < b)? a : b)
//The mp3 read buffer size. 2106 bytes should be enough for up to 48KHz mp3s according to the sox sources. Used by libmad.
#define READBUFSZ (2106)
#define MAX_FIFO_SIZE (16*1024) // min 4*1024 (CPU CLK 166), min 8*1024 (CPU CLK 83MHz), absolute work min = 3*READBUFSZ
#define MIN_FIFO_HEAP (8*1024)
#define SOCK_READ_BUF (256)
unsigned char *readBuf;
char oversampling = 1;
volatile char tskmad_enable, tskreader_enable;
static long bufUnderrunCt;
// void (*sampToOut)(u32) = i2sPushPWMSamples;
#define sampToOut i2sPushPWMSamples
#ifdef ADD_DEL_SAMPLES // correct smpr
static char sampCntAdd;
static char sampDelCnt;
static int sampCnt;
#endif
#define ID_FEEP_MP3 0x5000
mp3_server_setings mp3_serv = {0,{0}}; //{ PLAY_PORT, { PLAY_SERVER }};
LOCAL int mp3_cfg_read(void)
{
rtl_memset(&mp3_serv, 0, sizeof(mp3_serv));
if(flash_read_cfg(&mp3_serv, ID_FEEP_MP3, sizeof(mp3_serv.port) + 2) >= sizeof(mp3_serv.port) + 2) {
mp3_serv.port = PLAY_PORT;
strcpy(mp3_serv.url, PLAY_SERVER);
}
return mp3_serv.port;
}
// Called by the NXP modifications of libmad. It passes us (for the mono synth)
// 32 16-bit samples.
void render_sample_block(short *short_sample_buff, int no_samples) {
int i;
for (i = 0; i < no_samples; i++) {
int x = oversampling;
#ifdef ADD_DEL_SAMPLES // correct smpr
if(++sampCnt > 150) {
sampCnt = 0;
if (sampDelCnt < 0) {
//...and don't output an i2s sample
sampDelCnt--;
x = 0;
}
else if (sampDelCnt > 0) {
//..and output 2 samples instead of one.
sampDelCnt++;
x++;
}
}
#endif
while(x--) sampToOut((short_sample_buff[i] << 16) | (u16)short_sample_buff[i+no_samples]);
}
}
//Called by the NXP modifications of libmad. Sets the needed output sample rate.
static int oldRate = 0;
void set_dac_sample_rate(int rate, int chls) {
if (rate == oldRate) return;
oldRate = rate;
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MAD: Rate %d, channels %d\n", rate, chls);
#endif
oversampling = i2sSetRate(-1, rate);
}
static enum mad_flow input(struct mad_stream *stream) {
int n, i;
int rem; //, fifoLen;
//Shift remaining contents of buf to the front
rem = stream->bufend - stream->next_frame;
memmove(readBuf, stream->next_frame, rem);
while (rem < READBUFSZ) {
n = (READBUFSZ - rem); // Calculate amount of bytes we need to fill buffer.
i = RamFifoFill();
if (i < n) n = i; // If the fifo can give us less, only take that amount
if (n == 0) { // Can't take anything?
// Wait until there is enough data in the buffer. This only happens when the data feed
// rate is too low, and shouldn't normally be needed!
// DBG_8195A("Buf uflow, need %d bytes.\n", sizeof(readBuf)-rem);
bufUnderrunCt++;
// We both silence the output as well as wait a while by pushing silent samples into the i2s system.
// This waits for about 200mS
#if DEBUG_MAIN_LEVEL > 1
// DBG_8195A("FIFO: Buffer Underrun\n");
#endif
for (n = 0; n < 441*2; n++) sampToOut(0);
} else {
//Read some bytes from the FIFO to re-fill the buffer.
RamFifoRead(&readBuf[rem], n);
rem += n;
}
#ifdef ADD_DEL_SAMPLES
if(i < READBUFSZ) {
sampCntAdd = 10; // add samples
}
else if(RamFifoLen() - i < SOCK_READ_BUF) { // fifo free < SOCK_READ_BUF
sampCntAdd = -1; // del samples
}
else {
sampCntAdd++; // add samples
}
sampDelCnt += sampCntAdd;
#endif
}
//Okay, let MAD decode the buffer.
mad_stream_buffer(stream, readBuf, READBUFSZ);
return MAD_FLOW_CONTINUE;
}
//Routine to print out an error
LOCAL enum mad_flow error(void *data, struct mad_stream *stream,
struct mad_frame *frame) {
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MAD: Dec err 0x%04x (%s)\n", stream->error,
mad_stream_errorstr(stream));
#endif
return MAD_FLOW_CONTINUE;
}
LOCAL void tskreader(void *pvParameters);
//This is the main mp3 decoding task. It will grab data from the input buffer FIFO in the SPI ram and
//output it to the I2S port.
LOCAL void tskmad(void *pvParameters) {
//Initialize I2S
if (i2sInit(-1, I2S_DMA_PAGE_WAIT_MS_MIN * I2S_DMA_PAGE_SIZE_MS_96K, WL_24b)) { // min 2 ms x I2S_DMA_PAGE_SIZE buffers
//Allocate structs needed for mp3 decoding
char * mad_bufs = pvPortMalloc(
sizeof(struct mad_stream) + sizeof(struct mad_frame)
+ sizeof(struct mad_synth) + READBUFSZ);
if (mad_bufs == NULL) {
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MAD: Alloc failed\n");
#endif
goto exit;
}
rtl_memset(mad_bufs, 0,
sizeof(struct mad_stream) + sizeof(struct mad_frame)
+ sizeof(struct mad_synth));
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MAD: Alloc %d bytes at %p\n",
sizeof(struct mad_stream) + sizeof(struct mad_frame) + sizeof(struct mad_synth) + READBUFSZ,
mad_bufs);
#endif
struct mad_stream *stream = mad_bufs;
struct mad_frame *frame = &mad_bufs[sizeof(struct mad_stream)];
struct mad_synth *synth = &mad_bufs[sizeof(struct mad_stream)
+ sizeof(struct mad_frame)];
readBuf = &mad_bufs[sizeof(struct mad_stream) + sizeof(struct mad_frame)
+ sizeof(struct mad_synth)];
bufUnderrunCt = 0;
oldRate = 0;
oversampling = 1;
#ifdef ADD_DEL_SAMPLES
sampCntAdd = 0;
sampCnt = 0;
sampDelCnt = 0;
#endif
//Initialize mp3 parts
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MAD: Decoder start.\n");
#endif
mad_stream_init(stream);
mad_frame_init(frame);
mad_synth_init(synth);
while (tskmad_enable == 1) {
input(stream); //calls mad_stream_buffer internally
while (tskmad_enable == 1) {
#if DEBUG_MAIN_LEVEL > 3
DBG_8195A("MAD: Frame decode.\n");
#endif
int r = mad_frame_decode(frame, stream);
if (r == -1) {
#if DEBUG_MAIN_LEVEL > 2
DBG_8195A("MAD: Frame error.\n");
#endif
if (!MAD_RECOVERABLE(stream->error)) {
//We're most likely out of buffer and need to call input() again
break;
}
error(NULL, stream, frame);
continue;
}
#if DEBUG_MAIN_LEVEL > 3
DBG_8195A("MAD: Frame synth.\n");
#endif
mad_synth_frame(synth, frame);
}
};
mad_synth_finish(synth);
mad_frame_finish(frame);
mad_stream_finish(stream);
vTaskDelay(10);
vPortFree(mad_bufs);
}
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MAD: Closed.\n");
#endif
exit:
i2sClose(-1);
tskreader_enable = 0;
tskmad_enable = -1;
vTaskDelete(NULL);
}
LOCAL int getIpForHost(const char *host, struct sockaddr_in *ip) {
struct hostent *he;
struct in_addr **addr_list;
he = gethostbyname(host);
if (he == NULL) return 0;
addr_list = (struct in_addr **) he->h_addr_list;
if (addr_list[0] == NULL) return 0;
ip->sin_family = AF_INET;
memcpy(&ip->sin_addr, addr_list[0], sizeof(ip->sin_addr));
return 1;
}
//Open a connection to a webserver and request an URL. Yes, this possibly is one of the worst ways to do this,
//but RAM is at a premium here, and this works for most of the cases.
LOCAL int openConn(const char *streamHost, const char *streamPath, int streamPort) {
int n = 5;
while (tskreader_enable == 1) {
struct sockaddr_in remote_ip;
rtl_memset(&remote_ip, 0, sizeof(struct sockaddr_in));
if (!getIpForHost(streamHost, &remote_ip)) {
vTaskDelay(1000 / portTICK_RATE_MS);
if(n--) continue;
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MP3: Not get IP server <%s>!\n", streamHost);
#endif
return -1;
}
int sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock == -1) {
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MP3: Not open socket!\n");
#endif
// tskreader_enable = 0;
return -1;
}
remote_ip.sin_port = htons(streamPort);
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MP3: Connecting to server %s...\n",
ipaddr_ntoa((const ip_addr_t* )&remote_ip.sin_addr.s_addr));
#endif
if (connect(sock, (struct sockaddr * )(&remote_ip),
sizeof(struct sockaddr)) != 00) {
close(sock);
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MP3: Connect error!\n");
#endif
// vTaskDelay(1000 / portTICK_RATE_MS);
// continue;
return -1;
}
//Cobble together HTTP request
write(sock, "GET ", 4);
write(sock, streamPath, strlen(streamPath));
write(sock, " HTTP/1.0\r\nHost: ", 17);
write(sock, streamHost, strlen(streamHost));
write(sock, "\r\n\r\n", 4);
//We ignore the headers that the server sends back... it's pretty dirty in general to do that,
//but it works here because the MP3 decoder skips it because it isn't valid MP3 data.
return sock;
}
return -1;
}
LOCAL int http_head_read(unsigned char *buf, int len, int ff) {
int flg_head = 0;
int n, ret = 0;
if ((n = read(ff, buf, len)) <= 0) return 0;
if(n > 11 && *((u32 *)buf) == 0x50545448) { // "HTTP" // HTTP/1.0 200 OK
int x;
for(x = 3; x < n && buf[x] != ' '; x++);
while(x < n && buf[x] == ' ') x++;
if(x < n) ret = atoi(&buf[x]);
int cnt = 0;
x = 0;
while(ret) {
int z = 0;
while (x < n) {
if (cnt++ > 16384) return 600; // Header Too Large
if (buf[x++] == ((flg_head & 1) ? 0x0a : 0x0d)) {
if ((flg_head & 3) == 1) {
#if DEBUG_MAIN_LEVEL > 0
buf[x-1] = 0;
DBG_8195A("%s\n", &buf[z]);
#endif
z = x;
}
if (flg_head >= 3) {
if (n - x > 0) RamFifoWrite(&buf[x], n - x);
#if DEBUG_MAIN_LEVEL > 1
DBG_8195A("MP3: Skip HTTP head in %d bytes\n\n", cnt);
#endif
return ret;
}
flg_head++;
}
else flg_head = 0;
}
x = 0;
while(z < n) buf[x++] = buf[z++];
if ((n = read(ff, &buf[x], len - x)) <= 0) return 601; // content ??
n += x;
};
}
else RamFifoWrite(buf, n);
return ret;
}
//Reader task. This will try to read data from a TCP socket into the SPI fifo buffer.
LOCAL void tskreader(void *pvParameters) {
char wbuf[SOCK_READ_BUF];
int n;
if (RamFifoInit(mMIN(xPortGetFreeHeapSize() - MIN_FIFO_HEAP, MAX_FIFO_SIZE))) {
#if I2S_DEBUG_LEVEL > 1
unsigned int t = xTaskGetTickCount();
#endif
while (tskreader_enable == 1) {
n = strlen(mp3_serv.url);
int i;
u8 * uri = NULL;
for(i = 0; i < n; i++) {
wbuf[i] = mp3_serv.url[i];
if(wbuf[i] == '/') {
wbuf[i] = 0;
uri = &mp3_serv.url[i];
break;
}
}
if(uri == NULL) {
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MP3: Error url <%s>!\n", mp3_serv.url);
#endif
tskreader_enable = 0;
break;
}
int fd = openConn(wbuf, uri, mp3_serv.port);
if(fd < 0) {
tskreader_enable = 0;
break;
}
if ((n = http_head_read(wbuf, sizeof(wbuf), fd)) != 200) {
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MP3: HTTP error %d\n", n);
#endif
tskreader_enable = 0;
break;
}
else do {
n = read(fd, wbuf, sizeof(wbuf));
// DBG_8195A("Socket read %d bytes\n", n);
if (n > 0) RamFifoWrite(wbuf, n);
if ((tskmad_enable != 1) && (RamFifoFree() < RamFifoLen() / 2)) {
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("FIFO: Start Buffer fill %d\n", RamFifoFill());
#endif
// Buffer is filled. Start up the MAD task. Yes, the 2100 words of stack is a fairly large amount but MAD seems to need it.
tskmad_enable = 1;
if (xTaskCreate(tskmad, "tskmad", 2100, NULL, PRIO_MAD, NULL) != pdPASS) {
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MP3: Error creating MAD task! Out of memory?\n");
#endif
tskmad_enable = 0;
tskreader_enable = 0;
break;
}
}
#if I2S_DEBUG_LEVEL > 1
if (xTaskGetTickCount() - t > 3000) {
t = xTaskGetTickCount();
DBG_8195A("MP3: Buffer fill %d, DMA underrun ct %d, buff underrun ct %d\n", RamFifoFill(), (int )i2sGetUnderrunCnt(), bufUnderrunCt);
}
#endif
} while (n > 0 && (tskreader_enable == 1));
if(fd >= 0) {
#if DEBUG_MAIN_LEVEL > 1
if(n == 0) {
u32 err;
socklen_t slen = sizeof(err);
if(!lwip_getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &slen)) {
DBG_8195A("MP3: Socket error %d\n", err);
}
}
#endif
close(fd);
}
}
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MP3: Connection closed.\n");
#endif
}
if(tskmad_enable == 1) {
tskmad_enable = 0;
while (tskmad_enable == 0) vTaskDelay(2);
}
RamFifoClose();
#if DEBUG_MAIN_LEVEL > 2
DBG_8195A("\nMP3: Task reader closed.\n");
#endif
tskreader_enable = -1;
vTaskDelete(NULL);
}
//We need this to tell the OS we're running at a higher clock frequency.
//sk//extern void os_update_cpu_frequency(int mhz);
void connect_close(void) {
if (tskreader_enable == 1) {
tskreader_enable = 0;
while(tskreader_enable == 0) vTaskDelay(2);
tskreader_enable = 0;
}
}
void connect_start(void) {
connect_close();
if(mp3_serv.port != 0 && strlen(mp3_serv.url) > 2) {
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MP3: Connect url: %s:%d\n", mp3_serv.url, mp3_serv.port);
// DBG_8195A("Waiting for network.\n");
#endif
//Fire up the reader task. The reader task will fire up the MP3 decoder as soon
//as it has read enough MP3 data.
tskreader_enable = 1;
if (xTaskCreate(tskreader, "tskreader", 320, NULL, PRIO_READER, NULL) != pdPASS) {
#if DEBUG_MAIN_LEVEL > 0
DBG_8195A("\n%s xTaskCreate(tskreader) failed!\n", __FUNCTION__);
#endif
tskreader_enable = 0;
}
}
#if DEBUG_MAIN_LEVEL > 0
else {
DBG_8195A("MP3: No set url!\n");
}
#endif
}
/* RAM/TCM/Heaps info */
void ShowMemInfo(void)
{
printf("\nCLK CPU\t\t%d Hz\nRAM heap\t%d bytes\nTCM heap\t%d bytes\n",
HalGetCpuClk(), xPortGetFreeHeapSize(), tcm_heap_freeSpace());
}
LOCAL void user_init_thrd(void) {
mp3_cfg_read();
wifi_init();
/* Initilaize the console stack */
console_init();
/* Kill init thread after all init tasks done */
vTaskDelete(NULL);
}
/** /**
* @brief Main program. * @brief Main program.
* @param None * @param None
* @retval None * @retval None
*/ */
//int main_app(IN u16 argc, IN u8 *argv[])
void main(void) void main(void)
{ {
#if DEBUG_MAIN_LEVEL > 3 gpio_t gpio_led;
ConfigDebugErr = -1; gpio_t gpio_btn;
ConfigDebugInfo = ~(_DBG_SPI_FLASH_);//|_DBG_TCM_HEAP_);
ConfigDebugWarn = -1;
CfgSysDebugErr = -1;
CfgSysDebugInfo = -1;
CfgSysDebugWarn = -1;
#endif
#ifdef CONFIG_WDG_ON_IDLE // Init LED control pin
HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & 0x1FFFFF); gpio_init(&gpio_led, GPIO_LED_PIN);
WDGInitial(CONFIG_WDG_ON_IDLE * 1000); // 5 s gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output
WDGStart(); gpio_mode(&gpio_led, PullNone); // No pull
#endif
#if (defined(CONFIG_CRYPTO_STARTUP) && (CONFIG_CRYPTO_STARTUP)) while(1){
if(rtl_cryptoEngine_init() != 0 ) { // turn on LED
DBG_8195A("Crypto engine init failed!\n"); gpio_write(&gpio_led, 1);
}
#endif
#if DEBUG_MAIN_LEVEL > 0 printf("Hello World\n");
vPortFree(pvPortMalloc(4)); // Init RAM heap HalDelayUs(100000);
ShowMemInfo(); // RAM/TCM/Heaps info
#endif
/* wlan & user_start intialization */ // turn off LED
xTaskCreate(user_init_thrd, "user_init", 1024, NULL, tskIDLE_PRIORITY + 0 + PRIORITIE_OFFSET, NULL); gpio_write(&gpio_led, 0);
}
/*Enable Schedule, Start Kernel*/
#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED
#ifdef PLATFORM_FREERTOS
vTaskStartScheduler();
#endif
#else
RtlConsolTaskRom(NULL);
#endif
} }
//================================
//--- CONSOLE ---
// MP3 Set server, Close/Open connect
LOCAL void fATWS(int argc, char *argv[]){
if (argc == 2) {
StrUpr(argv[1]);
if(argv[1][0] == '?') {
printf("ATWS: %s,%d\n", mp3_serv.url, mp3_serv.port);
return;
}
else if(argv[1][0] == 'O') { // strcmp(argv[1], "open") == 0
printf("ATWS: open %s:%d\n", mp3_serv.url, mp3_serv.port);
connect_close();
return;
}
else if(argv[1][0] == 'C') { // strcmp(argv[1], "close") == 0
printf("ATWS: close\n");
connect_close();
return;
}
else if(argv[1][0] == 'R') { // strcmp(argv[1], "read") == 0
mp3_cfg_read();
connect_start();
return;
}
else if(argv[1][0] == 'S') { // strcmp(argv[1], "save") == 0
printf("%s: %s,%d\n", argv[0], mp3_serv.url, mp3_serv.port);
if(flash_write_cfg(&mp3_serv, ID_FEEP_MP3, strlen(mp3_serv.port) + strlen(mp3_serv.url)))
printf("ATWS: saved\n", mp3_serv.url, mp3_serv.port);
return;
}
}
else if (argc >= 3 ) {
strcpy((char *)mp3_serv.url, (char*)argv[1]);
mp3_serv.port = atoi((char*)argv[2]);
printf("%s: %s,%d\r\n", argv[0], mp3_serv.url, mp3_serv.port);
connect_start();
return;
}
}
MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_main[] = {
{"ATWS", 1, fATWS, "=<URL,PORT>: MP3 Connect to URL\nATWS=<c>: Close MP3\nATWS=<r>: Read MP3 URL\nATWS=<s>: Save MP3 URL\nATWS=<?>: URL Info"}
};

View file

@ -1,181 +0,0 @@
/******************************************************************************
*
* FileName: spiram_fifo.c
*
*******************************************************************************/
#include "rtl8195a/rtl_common.h"
#include "diag.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "queue.h"
#include "user/spiram_fifo.h"
#include "user/playerconfig.h"
typedef struct _sBUF_FIFO_ {
xSemaphoreHandle mux;
xSemaphoreHandle semCanRead;
xSemaphoreHandle semCanWrite;
int fifoRpos, fifoWpos, fifoFill, fifoSize;
long fifoOvfCnt, fifoUdrCnt;
unsigned char * buf;
} BUF_FIFO, * PBUF_FIFO;
PBUF_FIFO pbuf_fifo;
#define FIFO_REZSIZE 2048
void RamFifoClose(void) {
if(pbuf_fifo != NULL) {
if(pbuf_fifo->mux != NULL) vSemaphoreDelete(pbuf_fifo->mux); // xSemaphoreTake(mux, portMAX_DELAY);
if(pbuf_fifo->semCanRead != NULL) vSemaphoreDelete(pbuf_fifo->semCanRead);
if(pbuf_fifo->semCanWrite != NULL) vSemaphoreDelete(pbuf_fifo->semCanWrite);
if(pbuf_fifo->buf != NULL) vPortFree(pbuf_fifo->buf);
vPortFree(pbuf_fifo);
pbuf_fifo = NULL;
DBG_8195A("FIFO: Closed.\n");
}
}
static int RamFifoAlloc(int size) {
pbuf_fifo = (PBUF_FIFO) pvPortMalloc(sizeof(BUF_FIFO));
if(pbuf_fifo == NULL) return 0;
pbuf_fifo->mux = NULL;
pbuf_fifo->semCanRead = NULL;
pbuf_fifo->semCanWrite = NULL;
pbuf_fifo->fifoSize = 0;
pbuf_fifo->buf = pvPortMalloc(size);
if(pbuf_fifo->buf == NULL) return 0;
pbuf_fifo->fifoSize = size;
vSemaphoreCreateBinary(pbuf_fifo->semCanRead);
if(pbuf_fifo->semCanRead == NULL) return 0;
vSemaphoreCreateBinary(pbuf_fifo->semCanWrite);
if(pbuf_fifo->semCanWrite == NULL) return 0;
pbuf_fifo->mux = xSemaphoreCreateMutex();
if(pbuf_fifo->mux == NULL) return 0;
return 1;
}
//Initialize the FIFO
int RamFifoInit(int size) {
if(size < 2*FIFO_REZSIZE) {
DBG_8195A("FIFO: Buffer size < %d?", 2*FIFO_REZSIZE);
return 0;
}
if(pbuf_fifo == NULL) {
if (!RamFifoAlloc(size)) {
RamFifoClose();
DBG_8195A("FIFO: Low Heap!\n");
return 0;
}
}
xSemaphoreTake(pbuf_fifo->mux, portMAX_DELAY);
pbuf_fifo->fifoRpos = 0;
pbuf_fifo->fifoWpos = 0;
pbuf_fifo->fifoFill = 0;
pbuf_fifo->fifoOvfCnt = 0;
pbuf_fifo->fifoUdrCnt = 0;
if (pbuf_fifo->fifoSize != size) {
vPortFree(pbuf_fifo->buf);
pbuf_fifo->buf = pvPortMalloc(size);
if(pbuf_fifo->buf == NULL) {
pbuf_fifo->fifoSize = 0;
xSemaphoreGive(pbuf_fifo->mux);
DBG_8195A("FIFO: Low Heap!\n");
return 0;
}
pbuf_fifo->fifoSize = size;
}
DBG_8195A("FIFO: Alloc %d bytes at %p\n", pbuf_fifo->fifoSize, pbuf_fifo->buf);
xSemaphoreGive(pbuf_fifo->mux);
return 1;
}
// Read bytes from the FIFO
void RamFifoRead(char *buff, int len) {
while (len>0) {
int n = len;
// if (n > FIFO_REZSIZE) n = FIFO_REZSIZE; //don't read more than SPIREADSIZE
if (n > (pbuf_fifo->fifoSize - pbuf_fifo->fifoRpos)) n = pbuf_fifo->fifoSize - pbuf_fifo->fifoRpos; //don't read past end of buffer
xSemaphoreTake(pbuf_fifo->mux, portMAX_DELAY);
if (pbuf_fifo->fifoFill < n) {
// DBG_8195A("FIFO empty.\n");
//Drat, not enough data in FIFO. Wait till there's some written and try again.
pbuf_fifo->fifoUdrCnt++;
xSemaphoreGive(pbuf_fifo->mux);
if (pbuf_fifo->fifoFill < pbuf_fifo->fifoSize - FIFO_REZSIZE) xSemaphoreTake(pbuf_fifo->semCanRead, portMAX_DELAY);
} else {
//Read the data.
memcpy(buff, &pbuf_fifo->buf[pbuf_fifo->fifoRpos], n);
buff += n;
len -= n;
pbuf_fifo->fifoFill -= n;
pbuf_fifo->fifoRpos += n;
if (pbuf_fifo->fifoRpos >= pbuf_fifo->fifoSize) pbuf_fifo->fifoRpos = 0;
xSemaphoreGive(pbuf_fifo->mux);
xSemaphoreGive(pbuf_fifo->semCanWrite); //Indicate writer thread there's some free room in the fifo
}
}
}
//Write bytes to the FIFO
void RamFifoWrite(char *buff, int len) {
while (len > 0) {
int n = len;
// if (n > FIFO_REZSIZE) n = FIFO_REZSIZE; //don't read more than SPIREADSIZE
if (n > (pbuf_fifo->fifoSize - pbuf_fifo->fifoWpos)) n = pbuf_fifo->fifoSize - pbuf_fifo->fifoWpos; //don't read past end of buffer
xSemaphoreTake(pbuf_fifo->mux, portMAX_DELAY);
if ((pbuf_fifo->fifoSize - pbuf_fifo->fifoFill) < n) {
// DBG_8195A("FIFO full.\n");
//Drat, not enough free room in FIFO. Wait till there's some read and try again.
pbuf_fifo->fifoOvfCnt++;
xSemaphoreGive(pbuf_fifo->mux);
xSemaphoreTake(pbuf_fifo->semCanWrite, portMAX_DELAY);
} else {
// Write the data.
memcpy(&pbuf_fifo->buf[pbuf_fifo->fifoWpos], buff, n);
buff += n;
len -= n;
pbuf_fifo->fifoFill += n;
pbuf_fifo->fifoWpos += n;
if (pbuf_fifo->fifoWpos >= pbuf_fifo->fifoSize) pbuf_fifo->fifoWpos = 0;
xSemaphoreGive(pbuf_fifo->mux);
xSemaphoreGive(pbuf_fifo->semCanRead); //Tell reader thread there's some data in the fifo.
}
}
}
//Get amount of bytes in use
int RamFifoFill() {
xSemaphoreTake(pbuf_fifo->mux, portMAX_DELAY);
int ret = pbuf_fifo->fifoFill;
xSemaphoreGive(pbuf_fifo->mux);
return ret;
}
int RamFifoFree() {
return (pbuf_fifo->fifoSize - RamFifoFill());
}
int RamFifoLen() {
return pbuf_fifo->fifoSize;
}
long RamGetOverrunCt() {
xSemaphoreTake(pbuf_fifo->mux, portMAX_DELAY);
long ret = pbuf_fifo->fifoOvfCnt;
xSemaphoreGive(pbuf_fifo->mux);
return ret;
}
long RamGetUnderrunCt() {
xSemaphoreTake(pbuf_fifo->mux, portMAX_DELAY);
long ret = pbuf_fifo->fifoUdrCnt;
xSemaphoreGive(pbuf_fifo->mux);
return ret;
}

View file

@ -1,324 +0,0 @@
/*
* wifi_console.c
*
* Created on: 03/04/2017
* Author: pvvx
*/
#include <autoconf.h>
#include "FreeRTOS.h"
#include "diag.h"
#include "wifi_api.h"
#include "wifi_conf.h"
#include "rtl8195a/rtl_libc.h"
#include "hal_platform.h"
#include "section_config.h"
#include "hal_diag.h"
#include "lwip/netif.h"
extern struct netif xnetif[NET_IF_NUM];
//==========================================================
//--- CONSOLE --------------------------
// ATPN=<SSID>[,password[,encryption[,auto reconnect[,reconnect pause]]]: WIFI Connect to AP
LOCAL void fATPN(int argc, char *argv[]){
if(argc > 1) {
if(argv[1][0] == '?') {
show_wifi_st_cfg();
}
else {
strncpy(wifi_st_cfg.ssid, argv[1], NDIS_802_11_LENGTH_SSID);
int pswlen;
if(argc > 2) {
pswlen = strlen(wifi_st_cfg.password);
strncpy(wifi_st_cfg.password, argv[2], NDIS_802_11_LENGTH_SSID);
if(pswlen > 7) {
wifi_st_cfg.security = IDX_SECURITY_WPA2_AES_PSK;
}
else if(!pswlen) {
wifi_st_cfg.security = IDX_SECURITY_OPEN;
}
else {
printf("password len < 8!\n");
wifi_st_cfg.security = IDX_SECURITY_OPEN;
}
}
else {
// default
wifi_st_cfg.password[0] = 0;
wifi_st_cfg.security = IDX_SECURITY_OPEN;
}
if(argc > 3) {
if(pswlen > 7) {
wifi_st_cfg.security = atoi(argv[3]);
}
else {
printf("password len < 8!\n");
wifi_st_cfg.security = IDX_SECURITY_OPEN;
}
}
if(argc > 4) {
wifi_st_cfg.autoreconnect = atoi(argv[4]);
}
else wifi_st_cfg.autoreconnect = 0;
if(argc > 5) {
wifi_st_cfg.reconnect_pause = atoi(argv[5]);
}
else wifi_st_cfg.reconnect_pause = 5;
show_wifi_st_cfg();
#if CONFIG_WLAN_CONNECT_CB
connect_close();
#endif
wifi_run(wifi_run_mode | RTW_MODE_STA);
}
}
}
// ATPA=<SSID>[,password[,encryption[,channel[,hidden[,max connections]]]]]: Start WIFI AP
LOCAL void fATPA(int argc, char *argv[]){
if(argc > 1) {
if(argv[1][0] == '?') {
show_wifi_ap_cfg();
}
else {
strncpy(wifi_ap_cfg.ssid, argv[1], NDIS_802_11_LENGTH_SSID);
if(argc > 2) {
strncpy(wifi_ap_cfg.password, argv[2], NDIS_802_11_LENGTH_SSID);
int i = strlen(wifi_ap_cfg.password);
if(i > 7) {
wifi_ap_cfg.security = 1; // IDX_SECURITY_WPA2_AES_PSK;
}
else if(i == 0) {
wifi_ap_cfg.security = 0; // IDX_SECURITY_OPEN;
}
else {
printf("password len < 8!\n");
wifi_ap_cfg.security = 0; // IDX_SECURITY_OPEN;
}
}
else {
wifi_ap_cfg.password[0] = 0;
wifi_ap_cfg.security = 0; // IDX_SECURITY_OPEN;
}
if(argc > 3) {
wifi_ap_cfg.security = (argv[3][0] == '0')? 0 : 1; //RTW_SECURITY_OPEN : RTW_SECURITY_WPA2_AES_PSK;
}
if(argc > 4) {
wifi_ap_cfg.channel = atoi(argv[4]);
}
else wifi_ap_cfg.channel = 1;
if(argc > 5) {
wifi_ap_cfg.ssid_hidden = atoi(argv[5]);
}
else wifi_ap_cfg.ssid_hidden = 0;
if(argc > 6) {
wifi_ap_cfg.max_sta = atoi(argv[6]);
}
else wifi_ap_cfg.max_sta = 3;
show_wifi_ap_cfg();
#if CONFIG_WLAN_CONNECT_CB
connect_close();
#endif
wifi_run(wifi_run_mode | RTW_MODE_AP);
}
}
}
// WIFI Connect, Disconnect
LOCAL void fATWR(int argc, char *argv[]){
rtw_mode_t mode = RTW_MODE_NONE;
if(argc > 1) mode = atoi(argv[1]);
#if CONFIG_WLAN_CONNECT_CB
connect_close();
#endif
wifi_run(mode);
}
#if CONFIG_WLAN_CONNECT_CB
// Close connections
LOCAL void fATOF(int argc, char *argv[]){
connect_close();
}
// Open connections
LOCAL void fATON(int argc, char *argv[]){
connect_start();
}
#endif
LOCAL void fATWI(int argc, char *argv[]) {
#if 1
if(argc > 2) {
uint8_t c = argv[1][0] | 0x20;
if(c == 's') {
int i = atoi(argv[2]);
printf("Save configs(%d)..\n", i);
write_wifi_cfg(atoi(argv[2]));
}
else if(c == 'l') {
wifi_cfg.load_flg = atoi(argv[2]);
}
else if(c == 'm') {
wifi_cfg.mode = atoi(argv[2]);
}
}
#endif
rtw_wifi_setting_t Setting;
if((wifi_run_mode & RTW_MODE_AP)
&& wifi_get_setting(wlan_ap_name, &Setting) == 0) {
wifi_show_setting(wlan_ap_name, &Setting);
// show_wifi_ap_ip();
printf("\tIP: " IPSTR "\n", IP2STR(&xnetif[WLAN_AP_NETIF_NUM].ip_addr));
}
if((wifi_run_mode & RTW_MODE_STA)
&& wifi_get_setting(wlan_st_name, &Setting) == 0) {
wifi_show_setting(wlan_st_name, &Setting);
// show_wifi_st_ip();
printf("\tIP: " IPSTR "\n", IP2STR(&xnetif[WLAN_ST_NETIF_NUM].ip_addr));
}
printf("\nWIFI config:\n");
printf(&str_rom_57ch3Dch0A[25]); // "================================\n"
show_wifi_cfg();
printf("\nWIFI AP config:\n");
printf(&str_rom_57ch3Dch0A[25]); // "================================\n"
show_wifi_ap_cfg();
printf("\nWIFI ST config:\n");
printf(&str_rom_57ch3Dch0A[25]); // "================================\n"
show_wifi_st_cfg();
printf("\n");
}
extern uint8_t rtw_power_percentage_idx;
LOCAL void fATWT(int argc, char *argv[]) {
if(argc > 1) {
int txpwr = atoi(argv[1]);
debug_printf("set tx power (%d)...\n", txpwr);
if(rltk_set_tx_power_percentage(txpwr) != RTW_SUCCESS) {
error_printf("Error set tx power (%d)!", wifi_cfg.tx_pwr);
}
}
printf("TX power = %d\n", rtw_power_percentage_idx);
}
//-- Test tsf (64-bits counts, 1 us step) ---
#include "hal_com_reg.h"
#define ReadTSF_Lo32() (*((volatile unsigned int *)(WIFI_REG_BASE + REG_TSFTR)))
#define ReadTSF_Hi32() (*((volatile unsigned int *)(WIFI_REG_BASE + REG_TSFTR1)))
LOCAL uint64_t get_tsf(void)
{
return *((uint64_t *)(WIFI_REG_BASE + REG_TSFTR));
}
LOCAL void fATSF(int argc, char *argv[])
{
uint64_t tsf = get_tsf();
printf("\nTSF: %08x%08x\n", (uint32_t)(tsf>>32), (uint32_t)(tsf));
}
LOCAL void fATWP(int argc, char *argv[]) {
if(argc > 1) {
release_wakelock(0xffff);
wifi_set_power_mode(1, 1);
wifi_set_lps_dtim(atoi(argv[1]));
}
else {
unsigned char x;
if(wifi_get_lps_dtim(&x) >= 0) {
printf("DTIM: %d\n", x);
}
}
}
/* -------- WiFi Scan ------------------------------- */
LOCAL void scan_result_handler(internal_scan_handler_t* ap_scan_result)
{
if (ap_scan_result) {
if(ap_scan_result->scan_cnt) {
printf("\nScan networks:\n\n");
printf("N\tType\tMAC\t\t\tSignal\tCh\tWPS\tSecyrity\tSSID\n\n");
for(int i = 0 ; i < ap_scan_result->scan_cnt; i++) {
rtw_scan_result_t* record = &ap_scan_result->ap_details[i];
printf("%d\t", i+1);
printf("%s\t", (record->bss_type == RTW_BSS_TYPE_ADHOC)? "Adhoc": "Infra");
printf(MAC_FMT, MAC_ARG(record->BSSID.octet));
printf("\t%d\t", record->signal_strength);
printf("%d\t", record->channel);
printf("%d\t", record->wps_type);
{
uint8 * s = rtw_security_to_str(record->security);
printf("%s\t", s);
if(strlen(s) < 8) printf("\t");
}
record->SSID.val[record->SSID.len] = '\0';
printf("%s\n", record->SSID.val);
}
}
} else {
printf("Scan networks: None!\n");
}
}
/* -------- WiFi Scan ------------------------------- */
LOCAL void fATSN(int argc, char *argv[])
{
api_wifi_scan(scan_result_handler);
}
#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP
extern void cmd_ap_wps(int argc, char **argv);
extern void cmd_wps(int argc, char **argv);
//extern void cmd_wifi_on(int argc, char **argv);
#endif
#if CONFIG_ENABLE_P2P
extern void cmd_wifi_p2p_start(int argc, char **argv);
extern void cmd_wifi_p2p_stop(int argc, char **argv);
extern void cmd_p2p_listen(int argc, char **argv);
extern void cmd_p2p_find(int argc, char **argv);
extern void cmd_p2p_peers(int argc, char **argv);
extern void cmd_p2p_info(int argc, char **argv);
extern void cmd_p2p_disconnect(int argc, char **argv);
extern void cmd_p2p_connect(int argc, char **argv);
extern void cmd_wifi_p2p_auto_go_start(int argc, char **argv);
extern void cmd_p2p_peers(int argc, char **argv);
#endif //CONFIG_ENABLE_P2P
MON_RAM_TAB_SECTION COMMAND_TABLE console_cmd_wifi_api[] = {
{"ATPN", 1, fATPN, "=<SSID>[,password[,encryption[,auto-reconnect[,reconnect pause]]]: WIFI Connect to AP"},
{"ATPA", 1, fATPA, "=<SSID>[,password[,encryption[,channel[,hidden[,max connections]]]]]: Start WIFI AP"},
#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP
{"WPS_AP", 1, cmd_ap_wps, "=<pbc/pin>[,pin]: WiFi AP WPS"},
{"WPS_ST", 1, cmd_wps, "=<pbc/pin>[,pin]: WiFi Station WPS"},
#endif
#if CONFIG_ENABLE_P2P
{"P2P_START", 0, cmd_wifi_p2p_start, ": p2p start" },
{"P2P_ASTART", 0, cmd_wifi_p2p_auto_go_start, ": p2p auto go start" },
{"P2P_STOP", 0, cmd_wifi_p2p_stop, ": p2p stop"},
{"P2P_PEERS", 0, cmd_p2p_peers, ": p2p peers" },
{"P2P_FIND", 0, cmd_p2p_find, ": p2p find"},
{"P2P_INFO", 0, cmd_p2p_info, ": p2p info"},
{"P2P_DISCCONNECT", 0, cmd_p2p_disconnect, ": p2p disconnect"},
{"P2P_CONNECT", 0, cmd_p2p_connect, ": p2p connect"},
#endif
{"ATWR", 0, fATWR, ": WIFI Connect, Disconnect"},
#if CONFIG_WLAN_CONNECT_CB
{"ATON", 0, fATON, ": Open connections"},
{"ATOFF", 0, fATOF, ": Close connections"},
#endif
{"ATWI", 0, fATWI, ": WiFi Info"},
#if CONFIG_DEBUG_LOG > 3
{"ATWT", 1, fATWT, "=<tx_power>: WiFi tx power: 0 - 100%, 1 - 75%, 2 - 50%, 3 - 25%, 4 - 12.5%"},
{"ATSF", 0, fATSF, ": Test TSF value"},
#endif
{"ATWP", 0, fATWP, ": WiFi power"},
{"ATSN", 0, fATSN, ": Scan networks"}
};

View file

@ -4,7 +4,8 @@ include userset.mk
include $(SDK_PATH)paths.mk include $(SDK_PATH)paths.mk
#--------------------------- #---------------------------
#FLASHER = stlink-v2-1 #FLASHER = stlink-v2-1
FLASHER = stlink-v2 #FLASHER = stlink-v2
FLASHER = cmsis-dap
#FLASHER ?= Jlink #FLASHER ?= Jlink
#JLINK_PATH ?= D:/MCU/SEGGER/JLink_V612i/ #JLINK_PATH ?= D:/MCU/SEGGER/JLink_V612i/
#--------------------------- #---------------------------
@ -60,10 +61,15 @@ ifeq ($(FLASHER),stlink-v2)
# stlink-v2 FLASHER_SPEED ..1800 kHz # stlink-v2 FLASHER_SPEED ..1800 kHz
FLASHER_SPEED = 1800 FLASHER_SPEED = 1800
else else
ifeq ($(FLASHER),cmsis-dap)
# stlink-v2 FLASHER_SPEED ..1800 kHz
FLASHER_SPEED = 1800
else
# over FLASHER_SPEED ..500 kHz ? # over FLASHER_SPEED ..500 kHz ?
FLASHER_SPEED = 500 FLASHER_SPEED = 500
endif endif
endif endif
endif
# COMPILED_BOOT if defined -> extract image1, boot head in elf # COMPILED_BOOT if defined -> extract image1, boot head in elf
COMPILED_BOOT=1 COMPILED_BOOT=1

View file

@ -2,10 +2,6 @@
# OpenOCD script for RTL8710 # OpenOCD script for RTL8710
# Copyright (C) 2016 Rebane, rebane@alkohol.ee # Copyright (C) 2016 Rebane, rebane@alkohol.ee
# #
set CHIPNAME rtl8195a
set CHIPSERIES ameba1
# Adapt based on what transport is active.
source [find target/swj-dp.tcl] source [find target/swj-dp.tcl]
@ -40,11 +36,11 @@ target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAM
$_TARGETNAME configure -work-area-phys 0x10001000 -work-area-size $_WORKAREASIZE -work-area-backup 0 $_TARGETNAME configure -work-area-phys 0x10001000 -work-area-size $_WORKAREASIZE -work-area-backup 0
# adapter_khz 500 adapter_khz 500
adapter_nsrst_delay 100 adapter_nsrst_delay 100
if {![using_hla]} { if {![using_hla]} {
cortex_m reset_config sysresetreq vectreset cortex_m reset_config sysresetreq
} }
set rtl8710_flasher_firmware_ptr 0x10001000 set rtl8710_flasher_firmware_ptr 0x10001000
@ -53,49 +49,46 @@ set rtl8710_flasher_buffer_size 262144
set rtl8710_flasher_sector_size 4096 set rtl8710_flasher_sector_size 4096
array set rtl8710_flasher_code { array set rtl8710_flasher_code {
0 0xB671B57F 1 0x25FF4B58 2 0x6B196B1A 3 0x7040F042 4 0x69D96318 5 0xF4414E55 0 0x41FFE92D 1 0x4B52B671 2 0x6B1A4C52 3 0xF0424F52 4 0x631A7240 5 0x4E5169DA
6 0x69D97480 7 0xF8D361DC 8 0xF8C32120 9 0xF8D35120 10 0xF8C31124 11 0x47B05124 6 0x7280F442 7 0x22FF61DA 8 0x2120F8C3 9 0x2124F8C3 10 0x47984B4D 11 0x47B847A0
12 0x47B04E4F 13 0x47984B4F 14 0x60104A4F 15 0x484F47B0 16 0x60012100 17 0x2C006804 12 0x47A06030 13 0x22004B4B 14 0x681A601A 15 0xD0FC2A00 16 0x681A4B49 17 0x6032B91A
18 0x4D4DD0FC 19 0xB93E682E 20 0x60264C49 21 0x47B04E46 22 0x47984B46 23 0xE7ED6020 18 0x47B847A0 19 0x681AE7F0 20 0xD1082A01 21 0x4D4547A0 22 0x47A82006 23 0x47984B44
24 0x2B01682B 25 0x4E42D109 26 0x4C4647B0 27 0x47A02006 28 0x47904A45 29 0x47A020C7 24 0x47A820C7 25 0x681AE00C 26 0xD10D2A02 27 0x4D3F47A0 28 0x47A82006 29 0x47984B3E
30 0x682AE00D 31 0xD10E2A02 32 0x47B04E3B 33 0x20064C3F 34 0x483F47A0 35 0x493F4780 30 0x68184B3E 31 0x47984B3E 32 0x200447A0 33 0xE7D447A8 34 0x2A03681A 35 0x47A0D111
36 0x68084D3F 37 0x47B047A8 38 0x47A02004 39 0x6828E7CE 40 0xD1132803 41 0x47A04C32 36 0x25004B38 37 0x8000F8D3 38 0xEB054B38 39 0x681B0008 40 0xD2C6429D 41 0x22104936
42 0x24004838 43 0x4E396805 44 0x68311960 45 0xD206428C 46 0x4B384A37 47 0x221018A1 42 0x4B364429 43 0x35104798 44 0x681AE7F2 45 0xD11B2A04 46 0x4B302500 47 0x429D681B
48 0x34104798 49 0x4D2AE7F3 50 0xE7B847A8 51 0x29046829 52 0x2400D11B 53 0x6806482F 48 0x47A0D2B8 49 0x80A4F8DF 50 0x47C02006 51 0x47984B28 52 0x492B4B28 53 0x44296818
54 0xD2B042B4 55 0x47A84D24 56 0x20064E28 57 0x4B2847B0 58 0x49284798 59 0x680A4B2A 54 0x7280F44F 55 0x44284B2A 56 0x47A04798 57 0x47C02004 58 0x7580F505 59 0xE7E447A0
60 0x18A018E1 61 0xF44F4B2A 62 0x47987280 63 0x200447A8 64 0xF50447B0 65 0x47A87480 60 0x2B05681B 61 0x47A0D120 62 0xF8DF2500 63 0xF8D88080 64 0x429D3000 65 0x4B1BD296
66 0x682CE7E4 67 0xD1232C05 68 0x47984B17 69 0x4D1F2400 70 0x4294682A 71 0x481BD28F 66 0x68184669 67 0x4B1D2210 68 0x47984428 69 0x1000F8D8 70 0x1B492300 71 0xBF282910
72 0x68012210 73 0x18604E1D 74 0x47B04669 75 0x1B19682B 76 0xBF282910 77 0x23002110 72 0x428B2110 73 0x4A16D011 74 0x0003F81D 75 0x5CD2442A 76 0xD1054290 77 0xE7F43301
78 0xD011428B 79 0xF81D4A16 80 0x18A05003 81 0x42B55CC6 82 0x3301D101 83 0x4A15E7F4 78 0x22014B14 79 0xE779601A 80 0x22014B12 81 0x6035601A 82 0x47A0E774 83 0xE7D43510
84 0x60112101 85 0xE7726054 86 0x25014E12 87 0xE76E6035 88 0x47A84D03 89 0xE7D63410 84 0x40000200 85 0x1000138D 86 0x10001255 87 0x1000800C 88 0x100011A9 89 0x10008000
90 0x40000200 91 0x100011BD 92 0x100013DD 93 0x10001289 94 0x1000800C 95 0x10008000 90 0x10008004 91 0x100012C9 92 0x1000139D 93 0x10008010 94 0x100012ED 95 0x10008014
96 0x10008004 97 0x1000130D 98 0x100013ED 99 0x10008010 100 0x10001335 101 0x10008014 96 0x10008020 97 0x100011F1 98 0x10001329 99 0x10008008 100 0x6A5A4B04 101 0x020BF3C2
102 0x10008020 103 0x10001221 104 0x10001375 105 0x10008008 106 0x6A5A4B03 107 0xD0FB0512 102 0xD0F92A00 103 0x0060F893 104 0xBF004770 105 0x40006000 106 0x21014B10 107 0xF4426B1A
108 0x0060F893 109 0xBF004770 110 0x40006000 111 0x6B194B17 112 0xF4416B1A 113 0x63187040 108 0x631A7240 109 0xF042691A 110 0x611A0210 111 0x20C0F8D3 112 0x0206F022 113 0x20C0F8C3
114 0x69186919 115 0x0110F041 116 0xF8D36119 117 0x220000C0 118 0x0106F020 119 0x00C0F8D3 114 0x20C0F8D3 115 0x0201F042 116 0x20C0F8C3 117 0x43BCF503 118 0x609A2200 119 0x611962DA
120 0x10C0F8C3 121 0x00C0F8D3 122 0x0101F040 123 0x00C0F8D3 124 0x10C0F8C3 125 0x43BCF503 120 0x61592102 121 0x61DA619A 122 0x477064DA 123 0x40000200 124 0x460EB570 125 0x4B15B342
126 0x609A6899 127 0x20016AD9 128 0x691962DA 129 0x69596118 130 0x61592102 131 0x619A6999 126 0xBF342A10 127 0x25104615 128 0x7240F44F 129 0x2203601A 130 0xF883605D 131 0xF3C02060
132 0x61DA69D9 133 0x64DA6CD9 134 0xBF004770 135 0x40000200 136 0x460EB570 137 0xB34A4614 132 0xF8834207 133 0xF3C02060 134 0xF8832207 135 0xB2C02060 136 0xF8832201 137 0x24000060
138 0xF3C04B15 139 0x681A4507 140 0x7240F44F 141 0x685A601A 142 0xF3C02103 143 0x2C102207 138 0x4B09609A 139 0x55304798 140 0xB2A33401 141 0xD3F842AB 142 0x6A9A4B04 143 0x0201F012
144 0x2410BF28 145 0x605CB2C0 146 0x1060F883 147 0x5060F883 148 0xF8832101 149 0xF8832060 144 0x609AD1FA 145 0xBD704628 146 0xBD704610 147 0x40006000 148 0x10001191 149 0x4C0EB5F8
150 0x689A0060 151 0x60992500 152 0x47984B08 153 0x35015570 154 0x42A2B2AA 155 0x4804D3F8 150 0x7340F44F 151 0x23036023 152 0x23016063 153 0x239F60A3 154 0x3060F884 155 0x47A84D09
156 0xF0116A81 157 0xD1FA0301 158 0x60836881 159 0xBD704620 160 0x40006000 161 0x100011A9 156 0x47A84606 157 0x47A84607 158 0xEA400400 159 0xEA472707 160 0x6AA30006 161 0x0301F013
162 0x4C10B5F8 163 0x68232003 164 0x7340F44F 165 0x68636023 166 0x60602101 167 0x68A3229F 162 0x4A01D1FB 163 0xBDF86093 164 0x40006000 165 0x10001191 166 0x4C09B510 167 0x7340F44F
168 0x60A14D0B 169 0x2060F884 170 0x460647A8 171 0x460747A8 172 0x040347A8 173 0x2707EA43 168 0x23016023 169 0x60A36063 170 0xF8842305 171 0x4B053060 172 0x6AA34798 173 0x0301F013
174 0x0006EA47 175 0x4B036AA1 176 0x0201F011 177 0x6899D1FA 178 0xBDF8609A 179 0x40006000 174 0x4A01D1FB 175 0xBD106093 176 0x40006000 177 0x10001191 178 0xF44F4B07 179 0x601A7280
180 0x100011A9 181 0x4C0BB510 182 0x68232001 183 0x7340F44F 184 0x68636023 185 0x60602105 180 0x609A2201 181 0x0060F883 182 0xF0126A9A 183 0xD1FB0201 184 0x609A4B01 185 0xBF004770
186 0x60A068A2 187 0xF8844A06 188 0x47901060 189 0x4B036AA1 190 0x0201F011 191 0x6899D1FA 186 0x40006000 187 0xF44F4B0D 188 0x601A7280 189 0x609A2201 190 0xF8832220 191 0xF3C02060
192 0xBD10609A 193 0x40006000 194 0x100011A9 195 0x21014B08 196 0xF44F681A 197 0x601A7280 192 0xF8834207 193 0xF3C02060 194 0xB2C02207 195 0x2060F883 196 0x0060F883 197 0xF0126A9A
198 0x6099689A 199 0x0060F883 200 0x48036A9A 201 0x0101F012 202 0x6883D1FA 203 0x47706081 198 0xD1FB0201 199 0x609A4B01 200 0xBF004770 201 0x40006000 202 0xB352B530 203 0xF44F4B16
204 0x40006000 205 0x21014B0E 206 0xF44F681A 207 0x601A7280 208 0x2220689A 209 0xF8836099 204 0x601C7480 205 0x609C2401 206 0xF8832402 207 0xF3C04060 208 0xF8834407 209 0xF3C04060
210 0xF3C02060 211 0xF3C04107 212 0xB2C02207 213 0x1060F883 214 0x2060F883 215 0x0060F883 210 0xB2C02407 211 0x4060F883 212 0x7F80F5B2 213 0xF44FBF28 214 0xF8837280 215 0x24000060
216 0x4A036A99 217 0x0001F011 218 0x6893D1FA 219 0x47706090 220 0x40006000 221 0xB36AB530 216 0x48095D0D 217 0xF8803401 218 0xB2A55060 219 0xD3F74295 220 0x07496A99 221 0x6A83D5FC
222 0x25014B17 223 0xF44F681C 224 0x601C7480 225 0x2402689C 226 0xF883609D 227 0xF3C04060 222 0x0301F013 223 0x4902D1FB 224 0x4610608B 225 0xBF00BD30 226 0x40006000 227 0x4B02B508
228 0xF3C04507 229 0xB2C02407 230 0x5060F883 231 0x7F80F5B2 232 0xF44FBF28 233 0xF8837280 228 0x07C34798 229 0xBD08D4FB 230 0x10001299 231 0x4B02B508 232 0x07834798 233 0xBD08D5FB
234 0xF8834060 235 0x20000060 236 0x4C095C0D 237 0xF8843001 238 0xB2855060 239 0xD3F74295 234 0x10001299
240 0x07496A99 241 0x6AA0D5FC 242 0xF0104B03 243 0xD1FA0101 244 0x60996898 245 0xBD304610
246 0x40006000 247 0x4B02B508 248 0x07C04798 249 0xBD08D4FB 250 0x100012D5 251 0x4B04B508
252 0xF0004798 253 0xB2C10002 254 0xD0F82900 255 0xBF00BD08 256 0x100012D5
} }
set rtl8710_flasher_command_read_id 0 set rtl8710_flasher_command_read_id 0
@ -105,6 +98,8 @@ set rtl8710_flasher_command_read 3
set rtl8710_flasher_command_write 4 set rtl8710_flasher_command_write 4
set rtl8710_flasher_command_verify 5 set rtl8710_flasher_command_verify 5
set rtl8710_flasher_mac_address_offset 0xA088
set rtl8710_flasher_ready 0 set rtl8710_flasher_ready 0
set rtl8710_flasher_capacity 0 set rtl8710_flasher_capacity 0
set rtl8710_flasher_auto_erase 0 set rtl8710_flasher_auto_erase 0
@ -249,8 +244,8 @@ proc rtl8710_flash_read {local_filename loc size} {
set flash_offset [expr {$loc + $offset}] set flash_offset [expr {$loc + $offset}]
echo "read offset $flash_offset" echo "read offset $flash_offset"
rtl8710_flasher_read_block $flash_offset $len rtl8710_flasher_read_block $flash_offset $len
dump_image _rtl8710_flasher.bin [expr {$rtl8710_flasher_buffer + 0x20}] $len dump_image /tmp/_rtl8710_flasher.bin [expr {$rtl8710_flasher_buffer + 0x20}] $len
exec dd conv=notrunc if=_rtl8710_flasher.bin "of=$local_filename" bs=1 "seek=$offset" exec dd conv=notrunc if=/tmp/_rtl8710_flasher.bin "of=$local_filename" bs=1 "seek=$offset"
echo "read $len bytes" echo "read $len bytes"
} }
} }
@ -308,6 +303,23 @@ proc rtl8710_flash_verify {local_filename loc} {
} }
} }
proc rtl8710_flash_read_mac {} {
global rtl8710_flasher_mac_address_offset
global rtl8710_flasher_buffer
rtl8710_flasher_init
rtl8710_flasher_read_block $rtl8710_flasher_mac_address_offset 6
set mac ""
mem2array mac 8 [expr {$rtl8710_flasher_buffer + 0x20}] 6
set res "MAC address: "
append res [format %02X $mac(0)]
append res ":" [format %02X $mac(1)]
append res ":" [format %02X $mac(2)]
append res ":" [format %02X $mac(3)]
append res ":" [format %02X $mac(4)]
append res ":" [format %02X $mac(5)]
echo $res
}
proc rtl8710_flash_auto_erase {on} { proc rtl8710_flash_auto_erase {on} {
global rtl8710_flasher_auto_erase global rtl8710_flasher_auto_erase
if {[expr {$on != 0}]} { if {[expr {$on != 0}]} {
@ -331,10 +343,6 @@ proc rtl8710_flash_auto_verify {on} {
} }
proc rtl8710_reboot {} { proc rtl8710_reboot {} {
echo "# Set processor clock to default before system reset"
mww 0x40000014 0x00000021
sleep 10
echo "# Reboot (system reset)"
mww 0xE000ED0C 0x05FA0007 mww 0xE000ED0C 0x05FA0007
} }