Compare commits

...

29 commits

Author SHA1 Message Date
db72dc4a7d Revert "added optimization for 64-bit shift and clip to 16-bits, nets 5-6% speed increase"
This reverts commit ca216de68b.
2020-06-17 12:07:05 -05:00
270f830f1a Revert "Added x86 version of SAR64_Clip for completeness"
This reverts commit 6a7ba6d2dc.
2020-06-17 12:07:01 -05:00
4bcc30ac07 Revert "Slightly improved version with constant shifts"
This reverts commit f3088fdbe9.
2020-06-17 12:06:53 -05:00
ce2e7e8d26 Revert "Settled on making the SAR64_Clip function use a fixed value of 26 bits and fixed the x86 target"
This reverts commit 1b1f774b1e.
2020-06-17 12:06:49 -05:00
3f0980686a standalone: Print info about likely overflows 2020-06-17 12:01:43 -05:00
c987356420 Build the standalone example 2020-05-19 10:37:15 -05:00
3c94393c3a assembly: Implement SAR64_clip for generic version 2020-05-19 10:36:39 -05:00
Lady Ada
cf6fee3dd2 Merge branch 'master' of github.com:adafruit/Adafruit_MP3 2019-12-25 15:38:14 -05:00
Lady Ada
6a88d40a5c add deps 2019-12-25 15:38:09 -05:00
Limor "Ladyada" Fried
da1f4359ba
Merge pull request #10 from jepler/standalone-encoder
assembly: add a fully generic implementation and a standalone decoder
2019-12-24 12:20:17 -05:00
afe0e5fb5a assembly: add a fully generic implementation and a standalone decoder
The standalone decoder can be built on Linux with "make" and the
files it creates can be played with "aplay -c2 -r 44100 -f S16_LE"
2019-12-24 10:57:06 -06:00
siddacious
c3c664bf4d
Update library.properties 2019-12-17 13:08:46 -08:00
Jeff Epler
4024ab6e07
Merge pull request #9 from bitbank2/master
added optimization for 64-bit shift and clip to 16-bits, nets 5-6% improvement
2019-12-17 09:02:01 -06:00
Larry Bank
1b1f774b1e Settled on making the SAR64_Clip function use a fixed value of 26 bits and fixed the x86 target 2019-12-17 15:51:36 +01:00
Larry Bank
f3088fdbe9 Slightly improved version with constant shifts 2019-12-16 12:56:01 +01:00
Lady Ada
8686130675 deps 2019-12-15 02:28:28 -05:00
Lady Ada
90656e5227 only test m4 2019-12-15 02:19:27 -05:00
Lady Ada
d997d0ce2d cache on! 2019-12-15 02:18:11 -05:00
Lady Ada
9b10dba1c2 fix qspi example 2019-12-15 02:12:33 -05:00
Larry Bank
6a7ba6d2dc Added x86 version of SAR64_Clip for completeness 2019-12-13 00:59:38 +01:00
Larry Bank
ca216de68b added optimization for 64-bit shift and clip to 16-bits, nets 5-6% speed increase 2019-12-12 22:14:42 +01:00
ladyada
6002b14aee add QSPI demo 2019-12-11 17:52:44 -05:00
siddacious
dcfefa866c
Update library.properties 2019-12-06 11:53:08 -08:00
Limor "Ladyada" Fried
e3dd728a25
Merge pull request #8 from jepler/circuitpython
Make Adafruit_MP3 usable in CircuitPython, too
2019-11-29 13:09:57 -05:00
2a3cc7873b buffers: Allow an allocator to be specified
This will help enable CircuitPython to use the Adafruit_MP3 library
to implement its MP3File functionality, including the creation of
multiple MP3 playback objects at the same time.

This does not intentionally change any behavior on Arduino.

Testing performed:
 * In Arduino, verified the "play_from_header" example still worked
   on a PyPortal (SAMD51)
 * In WIP CircuitPython, verified that playback (including 2 simultaneous
   mp3 files) functioned on nRF52840 Feather

# Conflicts:
#	src/buffers.c
2019-11-29 10:22:42 -06:00
3668c862fb Support "generic little endian ARM" MCUs
Hopefully all intended architectures support the smlal instruction;
this is supported on "ARM architecture v3M, and ARM architecture v4
and above except xM variants", and missing support should be caught
as an assembler error.
2019-11-29 10:22:42 -06:00
656ca5b2ff various: remove unused-but-set variables
These are treated as compile errors by CircuitPython, and we'd like
to keep it that way.
2019-11-29 10:22:27 -06:00
e9558241f1 various: include <stdint.h> for standard integer typedefs 2019-11-29 10:17:50 -06:00
25c1f2b4d2 Prepare for use of this code from CircuitPython
* Treat most files as "C" files
 * add "extern C" guards to C-ish headers
   for when they are included from C++ files
 * Make Arduino.h inclusion optional,
   not available in CircuitPython
2019-11-29 10:17:47 -06:00
25 changed files with 419 additions and 67 deletions

View file

@ -1,5 +1,12 @@
language: c
sudo: false
cache:
directories:
- ~/arduino_ide
- ~/.arduino15/packages/
git:
depth: false
quiet: true
# Blacklist
branches:
@ -14,7 +21,8 @@ before_install:
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh)
script:
- build_main_platforms
- build_platform m4
- make -C examples/standalone
# Generate and deploy documentation
after_success:

View file

@ -0,0 +1,113 @@
#include "Adafruit_MP3.h"
#include <SPI.h>
#include <SdFat.h>
#include <Adafruit_SPIFlash.h>
#if defined(__SAMD51__) || defined(NRF52840_XXAA)
Adafruit_FlashTransport_QSPI flashTransport(PIN_QSPI_SCK, PIN_QSPI_CS, PIN_QSPI_IO0, PIN_QSPI_IO1, PIN_QSPI_IO2, PIN_QSPI_IO3);
#else
#if (SPI_INTERFACES_COUNT == 1 || defined(ADAFRUIT_CIRCUITPLAYGROUND_M0))
Adafruit_FlashTransport_SPI flashTransport(SS, &SPI);
#else
Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
// file system object from SdFat
FatFileSystem fatfs;
//set this to a value between 0 and 4095 to raise/lower volume
#define VOLUME_MAX 1023
const char *filename = "test.mp3";
File dataFile;
Adafruit_MP3 player;
void writeDacs(int16_t l, int16_t r){
uint16_t vall = map(l, -32768, 32767, 0, VOLUME_MAX);
uint16_t valr = map(r, -32768, 32767, 0, VOLUME_MAX);
#if defined(__SAMD51__) // feather/metro m4
analogWrite(A0, vall);
analogWrite(A1, valr);
#elif defined(__MK66FX1M0__) // teensy 3.6
analogWrite(A21, vall);
analogWrite(A22, valr);
#elif defined(NRF52)
analogWrite(27, vall);
#elif defined(__MK20DX256__) //teensy 3.2
analogWrite(A14, vall); //this board only has one dac, so play only left channel (or mono)
#endif
}
int getMoreData(uint8_t *writeHere, int thisManyBytes){
int bytesRead = 0;
int toRead = min(thisManyBytes, 768); //limit the number of bytes we can read at a time so the file isn't interrupted
while(dataFile.available() && bytesRead < toRead){
*writeHere = dataFile.read();
writeHere++;
bytesRead++;
}
return bytesRead;
}
// the setup routine runs once when you press reset:
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
analogWriteResolution(12);
#if defined(__SAMD51__)
analogWrite(A0, 2048);
analogWrite(A1, 2048);
#endif
Serial.println("Native MP3 decoding!");
Serial.print("Initializing QSPI storage...");
// Initialize flash library and check its chip ID.
if (!flash.begin()) {
Serial.println("Error, failed to initialize flash chip!");
while(1);
}
Serial.println("QSPI initialized.");
Serial.print("Flash chip JEDEC ID: 0x"); Serial.println(flash.getJEDECID(), HEX);
// First call begin to mount the filesystem. Check that it returns true
// to make sure the filesystem was mounted.
if (!fatfs.begin(&flash)) {
Serial.println("Error, failed to mount newly formatted filesystem!");
Serial.println("Was the flash chip formatted with the fatfs_format example?");
while(1);
}
Serial.println("Mounted filesystem!");
dataFile = fatfs.open(filename);
if(!dataFile){
Serial.println("could not open file!");
while(1);
}
player.begin();
//do this when there are samples ready
player.setSampleReadyCallback(writeDacs);
//do this when more data is required
player.setBufferCallback(getMoreData);
player.play();
}
// the loop routine runs over and over again forever:
void loop() {
player.tick();
}

2
examples/standalone/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
decoder
decoder.exe

View file

@ -0,0 +1,6 @@
decoder: $(wildcard ../../src/*.c) main.c $(wildcard ../../src/*.h) Makefile
gcc -Og -ggdb -g3 -iquote ../../src -o $@ $(filter %.c, $^) \
-DMPDEC_ALLOCATOR=malloc -DMPDEC_FREE=free -include stdlib.h
.PHONY: clean
clean:
rm -f decoder

128
examples/standalone/main.c Normal file
View file

@ -0,0 +1,128 @@
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "mp3dec.h"
#define MAX_BUFFER_LEN (MAX_NSAMP * MAX_NGRAN * MAX_NCHAN)
int16_t audiodata[MAX_BUFFER_LEN];
typedef struct {
char *ptr, *end;
} stream;
#define READ_PTR(stream) ((void*)((stream)->ptr))
#define BYTES_LEFT(stream) ((stream)->end - (stream)->ptr)
#define CONSUME(stream, n) ((stream)->ptr += n)
void skip_id3v2(stream* self) {
if (BYTES_LEFT(self) < 10) {
return;
}
uint8_t *data = READ_PTR(self);
if (!(
data[0] == 'I' &&
data[1] == 'D' &&
data[2] == '3' &&
data[3] != 0xff &&
data[4] != 0xff &&
(data[5] & 0x1f) == 0 &&
(data[6] & 0x80) == 0 &&
(data[7] & 0x80) == 0 &&
(data[8] & 0x80) == 0 &&
(data[9] & 0x80) == 0)) {
return;
}
uint32_t size = (data[6] << 21) | (data[7] << 14) | (data[8] << 7) | (data[9]);
size += 10; // size excludes the "header" (but not the "extended header")
CONSUME(self, size + 10);
}
bool mp3file_find_sync_word(stream* self) {
int offset = MP3FindSyncWord(READ_PTR(self), BYTES_LEFT(self));
if (offset >= 0) {
CONSUME(self, offset);
return true;
}
return false;
}
void fatal(const char *msg) { fprintf(stderr, "%s\n", msg); exit(1); }
void perror_fatal(const char *msg) { perror(msg); exit(1); }
bool probable_overflow(int16_t a, int16_t b) {
if(a > 32700 && b < -32700) {
return true;
} else if(b > 32700 && a < -32700) {
return true;
} else {
return false;
}
}
void look_for_overflow(int16_t *ptr, size_t os, int frame) {
for(size_t i=2; i<os; i+=2) {
int16_t l_old = ptr[i-2];
int16_t l_new = ptr[i];
int16_t r_old = ptr[i-1];
int16_t r_new = ptr[i+1];
if(probable_overflow(l_old, l_new)) {
printf("probable overflow, left channel, frame %5d sample %5d, %5d\n", frame, (i/2)-1, i/2);
printf("Consecutive sample values: %5d %5d\n", l_old, l_new);
}
if(probable_overflow(r_old, r_new)) {
printf("probable overflow, right channel, frame %5d sample %5d, %5d\n", frame, (i/2)-1, i/2);
printf("Consecutive sample values: %5d %5d\n", r_old, r_new);
}
}
}
int main(int argc, char **argv) {
if(argc != 3) {
fprintf(stderr, "Decode MP3 into headerless LE16 stereo\n");
fprintf(stderr, "Usage: %s input.mp3 output.bin\n", argv[0]);
exit(99);
}
HMP3Decoder decoder = MP3InitDecoder();
FILE *fi = fopen(argv[1], "rb");
if(!fi) perror_fatal("open");
struct stat st;
if(fstat(fileno(fi), &st) < 0) perror_fatal("fstat");
stream s;
s.ptr = malloc(st.st_size);
if(!s.ptr) perror_fatal("malloc");
s.end = s.ptr + st.st_size;
if(fread(s.ptr, 1, st.st_size, fi) != st.st_size) perror_fatal("fread");
FILE *fo = fopen(argv[2], "wb");
if(!fo) perror_fatal("open");
skip_id3v2(&s);
int frame=0;
while(mp3file_find_sync_word(&s)) {
MP3FrameInfo fi;
int err = MP3GetNextFrameInfo(decoder, &fi, READ_PTR(&s));
if(err != ERR_MP3_NONE) fatal("MP3GetNextFrameInfo");
int bytes_left = (int)BYTES_LEFT(&s);
uint8_t *inbuf = READ_PTR(&s);
err = MP3Decode(decoder, &inbuf, &bytes_left,
audiodata, 0);
if(err != ERR_MP3_NONE) fatal("MP3Decode");
look_for_overflow(audiodata, fi.outputSamps, ++frame);
if(fwrite(audiodata, 1, fi.outputSamps*sizeof(int16_t), fo)
!= fi.outputSamps*sizeof(int16_t))
perror_fatal("fwrite");
CONSUME(&s, BYTES_LEFT(&s) - bytes_left);
}
return 0;
}

View file

@ -1,5 +1,5 @@
name=Adafruit_mp3
version=1.0.5
version=1.1.2
author=Dean Miller <dean@adafruit.com>
maintainer=Dean Miller <dean@adafruit.com>
sentence=mp3 decoder
@ -7,3 +7,4 @@ paragraph=
category=Data Processing
url=https://github.com/adafruit/Adafruit_MP3
architectures=*
depends=Adafruit SPIFlash, SdFat - Adafruit Fork

View file

@ -56,6 +56,10 @@
#ifndef _ASSEMBLY_H
#define _ASSEMBLY_H
#ifdef __cplusplus
extern "C" {
#endif
#if (defined _WIN32 && !defined _WIN32_WCE) || (defined __WINS__ && defined _SYMBIAN) || defined(_OPENWAVE_SIMULATOR) || defined(WINCE_EMULATOR) /* Symbian emulator for Ix86 */
#pragma warning( disable : 4035 ) /* complains about inline asm not returning a value */
@ -267,7 +271,7 @@ static __inline int CLZ(int x)
return numZeros;
}
#elif defined(__GNUC__) && defined(ARM)
#elif defined(__GNUC__) && (defined(ARM) || defined(__ARMEL__))
static __inline int MULSHIFT32(int x, int y)
{
@ -317,6 +321,42 @@ static __inline int CLZ(int x)
return numZeros;
}
typedef signed long long int Word64; // 64-bit signed integer.
typedef union _U64 {
Word64 w64;
struct {
/* ARM ADS = little endian */
unsigned int lo32;
signed int hi32;
} r;
} U64;
static __inline Word64 MADD64(Word64 sum64, int x, int y)
{
U64 u;
u.w64 = sum64;
__asm__ volatile ("smlal %0,%1,%2,%3" : "+&r" (u.r.lo32), "+&r" (u.r.hi32) : "r" (x), "r" (y) : "cc");
return u.w64;
}
__attribute__((__always_inline__)) static __inline Word64 SAR64(Word64 x, int n)
{
unsigned int xLo = (unsigned int) x;
int xHi = (int) (x >> 32);
int nComp = 32-n;
int tmp;
// Shortcut: n is always < 32.
__asm__ __volatile__( "lsl %2, %0, %3\n\t" // tmp <- xHi<<(32-n)
"asr %0, %0, %4\n\t" // xHi <- xHi>>n
"lsr %1, %1, %4\n\t" // xLo <- xLo>>n
"orr %1, %2\n\t" // xLo <= xLo || tmp
: "+&r" (xHi), "+r" (xLo), "=&r" (tmp)
: "r" (nComp), "r" (n) );
x = xLo | ((Word64)xHi << 32);
return( x );
}
#elif defined(__GNUC__) && defined(__AVR32_UC__)
typedef signed long long int Word64; // 64-bit signed integer.
@ -469,8 +509,44 @@ __attribute__((__always_inline__)) static __inline Word64 SAR64(Word64 x, int n)
#else
#error Unsupported platform in assembly.h
#include <stdint.h>
#warning "Using generic implementation of intrinsics"
typedef int64_t Word64;
static inline int MULSHIFT32(int x, int y) {
return ((int64_t)x * y) >> 32;
}
static inline int FASTABS(int x) {
int sign = x >> 31;
return (x ^ sign) - sign;
}
static inline int CLZ(int x) {
return __builtin_clz(x);
}
static inline Word64 MADD64(Word64 sum, int x, int y) {
return sum + (int64_t)x * y;
}
static inline Word64 SHL64(Word64 x, int n) {
return x << n;
}
static inline Word64 SAR64(Word64 x, int n) {
return x >> n;
}
static inline short SAR64_Clip(Word64 x) {
return SAR64(x, 26);
}
#endif /* platforms */
#ifdef __cplusplus
}
#endif
#endif /* _ASSEMBLY_H */

View file

@ -67,6 +67,7 @@
*
* Notes: slow, platform-independent equivalent to memset(buf, 0, nBytes)
**************************************************************************************/
#ifndef MPDEC_ALLOCATOR
static void ClearBuffer(void *buf, int nBytes)
{
int i;
@ -77,6 +78,7 @@ static void ClearBuffer(void *buf, int nBytes)
return;
}
#endif
/**************************************************************************************
* Function: AllocateBuffers
@ -97,7 +99,7 @@ static void ClearBuffer(void *buf, int nBytes)
MP3DecInfo *AllocateBuffers(void)
{
MP3DecInfo *mp3DecInfo;
/*
#ifdef MPDEC_ALLOCATOR
FrameHeader *fh;
SideInfo *si;
ScaleFactorInfo *sfi;
@ -105,20 +107,8 @@ MP3DecInfo *AllocateBuffers(void)
DequantInfo *di;
IMDCTInfo *mi;
SubbandInfo *sbi;
*/
// Buffers:
static char s_mp3DecInfo[sizeof(MP3DecInfo)];
static char fh[sizeof(FrameHeader)];
static char si[sizeof(SideInfo)];
static char sfi[sizeof(ScaleFactorInfo)];
static char hi[sizeof(HuffmanInfo)];
static char di[sizeof(DequantInfo)];
static char mi[sizeof(IMDCTInfo)];
static char sbi[sizeof(SubbandInfo)];
//mp3DecInfo = (MP3DecInfo *)malloc(sizeof(MP3DecInfo));
mp3DecInfo = (MP3DecInfo *)s_mp3DecInfo;
mp3DecInfo = (MP3DecInfo *)MPDEC_ALLOCATOR(sizeof(MP3DecInfo));
if (!mp3DecInfo)
{
#ifndef _WIN32
@ -129,27 +119,15 @@ MP3DecInfo *AllocateBuffers(void)
#endif
return 0;
}
ClearBuffer(mp3DecInfo, sizeof(MP3DecInfo));
/* Switched to static allocations.
hi = (HuffmanInfo *) malloc(sizeof(HuffmanInfo));
sbi = (SubbandInfo *) malloc(sizeof(SubbandInfo));
mi = (IMDCTInfo *) malloc(sizeof(IMDCTInfo));
di = (DequantInfo *) malloc(sizeof(DequantInfo));
si = (SideInfo *) malloc(sizeof(SideInfo));
sfi = (ScaleFactorInfo *) malloc(sizeof(ScaleFactorInfo));
fh = (FrameHeader *) malloc(sizeof(FrameHeader));
*/
hi = (HuffmanInfo *) MPDEC_ALLOCATOR(sizeof(HuffmanInfo));
sbi = (SubbandInfo *) MPDEC_ALLOCATOR(sizeof(SubbandInfo));
mi = (IMDCTInfo *) MPDEC_ALLOCATOR(sizeof(IMDCTInfo));
di = (DequantInfo *) MPDEC_ALLOCATOR(sizeof(DequantInfo));
si = (SideInfo *) MPDEC_ALLOCATOR(sizeof(SideInfo));
sfi = (ScaleFactorInfo *) MPDEC_ALLOCATOR(sizeof(ScaleFactorInfo));
fh = (FrameHeader *) MPDEC_ALLOCATOR(sizeof(FrameHeader));
mp3DecInfo->FrameHeaderPS = (void *)fh;
mp3DecInfo->SideInfoPS = (void *)si;
mp3DecInfo->ScaleFactorInfoPS = (void *)sfi;
mp3DecInfo->HuffmanInfoPS = (void *)hi;
mp3DecInfo->DequantInfoPS = (void *)di;
mp3DecInfo->IMDCTInfoPS = (void *)mi;
mp3DecInfo->SubbandInfoPS = (void *)sbi;
/* Removed; static allocation guarantees success.
if (!fh || !si || !sfi || !hi || !di || !mi || !sbi) {
#ifndef _WIN32
#ifdef DEMO_HELIX_FOOTPRINT
@ -165,7 +143,39 @@ MP3DecInfo *AllocateBuffers(void)
FreeBuffers(mp3DecInfo); // safe to call - only frees memory that was successfully allocated
return 0;
}
*/
#else
// Buffers:
static char s_mp3DecInfo[sizeof(MP3DecInfo)];
static char fh[sizeof(FrameHeader)];
static char si[sizeof(SideInfo)];
static char sfi[sizeof(ScaleFactorInfo)];
static char hi[sizeof(HuffmanInfo)];
static char di[sizeof(DequantInfo)];
static char mi[sizeof(IMDCTInfo)];
static char sbi[sizeof(SubbandInfo)];
mp3DecInfo = (MP3DecInfo *)s_mp3DecInfo;
ClearBuffer(mp3DecInfo, sizeof(MP3DecInfo));
/* important to do this - DSP primitives assume a bunch of state variables are 0 on first use */
ClearBuffer(fh, sizeof(FrameHeader));
ClearBuffer(si, sizeof(SideInfo));
ClearBuffer(sfi, sizeof(ScaleFactorInfo));
ClearBuffer(hi, sizeof(HuffmanInfo));
ClearBuffer(di, sizeof(DequantInfo));
ClearBuffer(mi, sizeof(IMDCTInfo));
ClearBuffer(sbi, sizeof(SubbandInfo));
#endif
mp3DecInfo->FrameHeaderPS = (void *)fh;
mp3DecInfo->SideInfoPS = (void *)si;
mp3DecInfo->ScaleFactorInfoPS = (void *)sfi;
mp3DecInfo->HuffmanInfoPS = (void *)hi;
mp3DecInfo->DequantInfoPS = (void *)di;
mp3DecInfo->IMDCTInfoPS = (void *)mi;
mp3DecInfo->SubbandInfoPS = (void *)sbi;
#ifndef _WIN32
#ifdef DEMO_HELIX_FOOTPRINT
@ -177,19 +187,14 @@ MP3DecInfo *AllocateBuffers(void)
#endif
#endif
/* important to do this - DSP primitives assume a bunch of state variables are 0 on first use */
ClearBuffer(fh, sizeof(FrameHeader));
ClearBuffer(si, sizeof(SideInfo));
ClearBuffer(sfi, sizeof(ScaleFactorInfo));
ClearBuffer(hi, sizeof(HuffmanInfo));
ClearBuffer(di, sizeof(DequantInfo));
ClearBuffer(mi, sizeof(IMDCTInfo));
ClearBuffer(sbi, sizeof(SubbandInfo));
return mp3DecInfo;
}
#define SAFE_FREE(x) {if (x) free(x); (x) = 0;} /* helper macro */
#ifdef MPDEC_FREE
#define SAFE_FREE(x) {if (x) MPDEC_FREE(x); (x) = 0;} /* helper macro */
#else
#define SAFE_FREE(x) { (x) = 0; }
#endif
/**************************************************************************************
* Function: FreeBuffers
@ -209,7 +214,6 @@ void FreeBuffers(MP3DecInfo *mp3DecInfo)
if (!mp3DecInfo)
return;
/* Switched to static allocations.
SAFE_FREE(mp3DecInfo->FrameHeaderPS);
SAFE_FREE(mp3DecInfo->SideInfoPS);
SAFE_FREE(mp3DecInfo->ScaleFactorInfoPS);
@ -219,5 +223,4 @@ void FreeBuffers(MP3DecInfo *mp3DecInfo)
SAFE_FREE(mp3DecInfo->SubbandInfoPS);
SAFE_FREE(mp3DecInfo);
*/
}

View file

@ -46,6 +46,10 @@
#include "mp3common.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(ASSERT)
#undef ASSERT
#endif
@ -304,4 +308,7 @@ extern const int csa[8][2];
extern const int coef32[31];
extern const int polyCoef[264];
#ifdef __cplusplus
}
#endif
#endif /* _CODER_H */

View file

@ -43,6 +43,7 @@
#include "coder.h"
#include "assembly.h"
#include <stdint.h>
typedef int ARRAY3[3]; /* for short-block reordering */
@ -245,7 +246,7 @@ static const int pow2frac[8] = {
ScaleFactorInfoSub *sfis, CriticalBandInfo *cbi)
{
int i, j, w, cb;
int cbStartL, cbEndL, cbStartS, cbEndS;
int cbEndL, cbStartS, cbEndS;
int nSamps, nonZero, sfactMultiplier, gbMask;
int globalGain, gainI;
int cbMax[3];
@ -253,7 +254,6 @@ static const int pow2frac[8] = {
/* set default start/end points for short/long blocks - will update with non-zero cb info */
if (sis->blockType == 2) {
cbStartL = 0;
if (sis->mixedBlock) {
cbEndL = (fh->ver == MPEG1 ? 8 : 6);
cbStartS = 3;
@ -264,7 +264,6 @@ static const int pow2frac[8] = {
cbEndS = 13;
} else {
/* long block */
cbStartL = 0;
cbEndL = 22;
cbStartS = 13;
cbEndS = 13;

View file

@ -388,7 +388,6 @@ int DecodeHuffman(MP3DecInfo *mp3DecInfo, unsigned char *buf, int *bitOffset, in
FrameHeader *fh;
SideInfo *si;
SideInfoSub *sis;
ScaleFactorInfo *sfi;
HuffmanInfo *hi;
/* validate pointers */
@ -398,7 +397,6 @@ int DecodeHuffman(MP3DecInfo *mp3DecInfo, unsigned char *buf, int *bitOffset, in
fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS));
si = ((SideInfo *)(mp3DecInfo->SideInfoPS));
sis = &si->sis[gr][ch];
sfi = ((ScaleFactorInfo *)(mp3DecInfo->ScaleFactorInfoPS));
hi = (HuffmanInfo*)(mp3DecInfo->HuffmanInfoPS);
if (huffBlockBits < 0)

View file

@ -44,6 +44,7 @@
#include "coder.h"
#include "assembly.h"
#include <stdint.h>
/**************************************************************************************
* Function: AntiAlias

View file

@ -47,6 +47,10 @@
#include "mp3dec.h"
#include "statname.h" /* do name-mangling for static linking */
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_SCFBD 4 /* max scalefactor bands per channel */
#define NGRANS_MPEG1 2
#define NGRANS_MPEG2 1
@ -120,4 +124,8 @@ extern const short sideBytesTab[3][2];
extern const short slotTab[3][3][15];
extern const SFBandTable sfBandTable[3][3];
#ifdef __cplusplus
}
#endif
#endif /* _MP3COMMON_H */

View file

@ -44,7 +44,9 @@
#ifndef _MP3DEC_H
#define _MP3DEC_H
#ifdef ARDUINO
#include <Arduino.h>
#endif
#if defined(_WIN32) && !defined(_WIN32_WCE)
#
@ -58,8 +60,12 @@
#
#elif defined(__GNUC__) && defined(ARM)
#
#elif defined(__GNUC__) && defined(__ARMEL__)
#
#elif defined(__GNUC__) && defined(__i386__)
#
#elif defined(__GNUC__) && defined(__amd64__)
#
#elif defined(_OPENWAVE_SIMULATOR) || defined(_OPENWAVE_ARMULATOR)
#
#elif defined(__GNUC__) && defined(__AVR32_UC__)

View file

@ -208,7 +208,7 @@ static const char NRTab[6][3][4] = {
static void UnpackSFMPEG2(BitStreamInfo *bsi, SideInfoSub *sis, ScaleFactorInfoSub *sfis, int gr, int ch, int modeExt, ScaleFactorJS *sfjs)
{
int i, sfb, sfcIdx, btIdx, nrIdx, iipTest;
int i, sfb, sfcIdx, btIdx, nrIdx;
int slen[4], nr[4];
int sfCompress, preFlag, intensityScale;
@ -298,7 +298,6 @@ static void UnpackSFMPEG2(BitStreamInfo *bsi, SideInfoSub *sis, ScaleFactorInfoS
if(sis->blockType == 2) {
if(sis->mixedBlock) {
/* do long block portion */
iipTest = (1 << slen[0]) - 1;
for (sfb=0; sfb < 6; sfb++) {
sfis->l[sfb] = (char)GetBits(bsi, slen[0]);
}
@ -312,7 +311,6 @@ static void UnpackSFMPEG2(BitStreamInfo *bsi, SideInfoSub *sis, ScaleFactorInfoS
/* remaining short blocks, sfb just keeps incrementing */
for ( ; nrIdx <= 3; nrIdx++) {
iipTest = (1 << slen[nrIdx]) - 1;
for (i=0; i < nr[nrIdx]; i++, sfb++) {
sfis->s[sfb][0] = (char)GetBits(bsi, slen[nrIdx]);
sfis->s[sfb][1] = (char)GetBits(bsi, slen[nrIdx]);
@ -325,7 +323,6 @@ static void UnpackSFMPEG2(BitStreamInfo *bsi, SideInfoSub *sis, ScaleFactorInfoS
/* long blocks */
sfb = 0;
for (nrIdx = 0; nrIdx <= 3; nrIdx++) {
iipTest = (1 << slen[nrIdx]) - 1;
for(i=0; i < nr[nrIdx]; i++, sfb++) {
sfis->l[sfb] = (char)GetBits(bsi, slen[nrIdx]);
}

View file

@ -60,7 +60,6 @@
int Subband(MP3DecInfo *mp3DecInfo, short *pcmBuf)
{
int b;
HuffmanInfo *hi;
IMDCTInfo *mi;
SubbandInfo *sbi;
@ -68,7 +67,6 @@ int Subband(MP3DecInfo *mp3DecInfo, short *pcmBuf)
if (!mp3DecInfo || !mp3DecInfo->HuffmanInfoPS || !mp3DecInfo->IMDCTInfoPS || !mp3DecInfo->SubbandInfoPS)
return -1;
hi = (HuffmanInfo *)mp3DecInfo->HuffmanInfoPS;
mi = (IMDCTInfo *)(mp3DecInfo->IMDCTInfoPS);
sbi = (SubbandInfo*)(mp3DecInfo->SubbandInfoPS);

View file

@ -44,6 +44,7 @@
// constants in RAM are not significantly faster
#include "coder.h"
#include <stdint.h>
/* post-IMDCT window, win[blockType][i]
* format = Q31