diff src/demac/ape.h @ 2182:cc5e9ec110a4

Added initial version of Monkey's Audio plugin
author Eugene Zagidullin <e.asphyx@gmail.com>
date Thu, 22 Nov 2007 02:54:06 +0300
parents
children 80d7ab8f2ec5
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demac/ape.h	Thu Nov 22 02:54:06 2007 +0300
@@ -0,0 +1,299 @@
+/*
+ * Monkey's Audio lossless audio decoder, common header,
+ * some libav* compatibility stuff
+ * Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
+ *  based upon libdemac from Dave Chapman.
+ * Copyright (c) 2007 Eugene Zagidullin <e.asphyx@gmail.com>
+ *   Cleanup libav* depending code, Audacious stuff.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
+ */
+
+#ifndef APE_H
+#define APE_H
+
+#define FFMIN(a,b) ((a) < (b) ? (a) : (b))
+
+#ifdef DEBUG
+#define av_log(a, b, ...) fprintf(stderr, __VA_ARGS__)
+#else
+#define av_log(a, b, ...) ;
+#endif
+
+#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
+#define AV_TIME_BASE 1000
+#define AV_WL16(a,b) { \
+          ((uint8_t*)(a))[0] =  (uint16_t)(b) & 0x00ff;        \
+          ((uint8_t*)(a))[1] = ((uint16_t)(b) & 0xff00) >> 8; \
+	}
+#define AV_WL32(a,b) { \
+          ((uint8_t*)(a))[0] = ((uint32_t)(b) & 0x000000ff);       \
+          ((uint8_t*)(a))[1] = ((uint32_t)(b) & 0x0000ff00) >> 8;  \
+          ((uint8_t*)(a))[2] = ((uint32_t)(b) & 0x00ff0000) >> 16; \
+          ((uint8_t*)(a))[3] = ((uint32_t)(b) & 0xff000000) >> 24; \
+	}
+
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+#define BLOCKS_PER_LOOP     4608
+#define MAX_CHANNELS        2
+//#define MAX_BYTESPERSAMPLE  3
+
+#define APE_FRAMECODE_MONO_SILENCE    1
+#define APE_FRAMECODE_STEREO_SILENCE  3
+#define APE_FRAMECODE_PSEUDO_STEREO   4
+
+#define HISTORY_SIZE 512
+#define PREDICTOR_ORDER 8
+/** Total size of all predictor histories */
+#define PREDICTOR_SIZE 50
+
+#define YDELAYA (18 + PREDICTOR_ORDER*4)
+#define YDELAYB (18 + PREDICTOR_ORDER*3)
+#define XDELAYA (18 + PREDICTOR_ORDER*2)
+#define XDELAYB (18 + PREDICTOR_ORDER)
+
+#define YADAPTCOEFFSA 18
+#define XADAPTCOEFFSA 14
+#define YADAPTCOEFFSB 10
+#define XADAPTCOEFFSB 5
+
+#define APE_FILTER_LEVELS 3
+
+#define AVERROR_IO -1
+#define AVERROR_NOMEM -1
+
+typedef struct {
+    int64_t pos;
+    int nblocks;
+    int size;
+    int skip;
+    int64_t pts;
+} APEFrame;
+
+typedef struct {
+    /* Derived fields */
+    uint32_t junklength;
+    uint32_t firstframe;
+    uint32_t totalsamples;
+    int currentframe;
+    APEFrame *frames;
+
+    /* Info from Descriptor Block */
+    char magic[4];
+    int16_t fileversion;
+    int16_t padding1;
+    uint32_t descriptorlength;
+    uint32_t headerlength;
+    uint32_t seektablelength;
+    uint32_t wavheaderlength;
+    uint32_t audiodatalength;
+    uint32_t audiodatalength_high;
+    uint32_t wavtaillength;
+    uint8_t md5[16];
+
+    /* Info from Header Block */
+    uint16_t compressiontype;
+    uint16_t formatflags;
+    uint32_t blocksperframe;
+    uint32_t finalframeblocks;
+    uint32_t totalframes;
+    uint16_t bps;
+    uint16_t channels;
+    uint32_t samplerate;
+
+    /* Seektable */
+    uint32_t *seektable;
+
+    /* Added by Eugene: */
+    uint32_t frame_size;
+    //uint64_t total_blocks;
+    uint64_t duration;
+    uint32_t max_packet_size;
+} APEContext;
+
+/** Filters applied to the decoded data */
+typedef struct APEFilter {
+    int16_t *coeffs;        ///< actual coefficients used in filtering
+    int16_t *adaptcoeffs;   ///< adaptive filter coefficients used for correcting of actual filter coefficients
+    int16_t *historybuffer; ///< filter memory
+    int16_t *delay;         ///< filtered values
+
+    int avg;
+} APEFilter;
+
+typedef struct APERice {
+    uint32_t k;
+    uint32_t ksum;
+} APERice;
+
+typedef struct APERangecoder {
+    uint32_t low;           ///< low end of interval
+    uint32_t range;         ///< length of interval
+    uint32_t help;          ///< bytes_to_follow resp. intermediate value
+    unsigned int buffer;    ///< buffer for input/output
+} APERangecoder;
+
+/** Filter histories */
+typedef struct APEPredictor {
+    int32_t *buf;
+
+    int32_t lastA[2];
+
+    int32_t filterA[2];
+    int32_t filterB[2];
+
+    int32_t coeffsA[2][4];  ///< adaption coefficients
+    int32_t coeffsB[2][5];  ///< adaption coefficients
+    int32_t historybuffer[HISTORY_SIZE + PREDICTOR_SIZE];
+} APEPredictor;
+
+/** Decoder context */
+typedef struct APEDecoderContext {
+    //AVCodecContext *avctx;
+    APEContext *apectx;
+    //DSPContext dsp;
+    int channels;
+    int samples;                             ///< samples left to decode in current frame
+
+    int fileversion;                         ///< codec version, very important in decoding process
+    int compression_level;                   ///< compression levels
+    int fset;                                ///< which filter set to use (calculated from compression level)
+    int flags;                               ///< global decoder flags
+
+    uint32_t CRC;                            ///< frame CRC
+    int frameflags;                          ///< frame flags
+    int currentframeblocks;                  ///< samples (per channel) in current frame
+    int blocksdecoded;                       ///< count of decoded samples in current frame
+    APEPredictor predictor;                  ///< predictor used for final reconstruction
+
+    int32_t decoded0[BLOCKS_PER_LOOP];       ///< decoded data for the first channel
+    int32_t decoded1[BLOCKS_PER_LOOP];       ///< decoded data for the second channel
+
+    int16_t* filterbuf[APE_FILTER_LEVELS];   ///< filter memory
+
+    APERangecoder rc;                        ///< rangecoder used to decode actual values
+    APERice riceX;                           ///< rice code parameters for the second channel
+    APERice riceY;                           ///< rice code parameters for the first channel
+    APEFilter filters[APE_FILTER_LEVELS][2]; ///< filters used for reconstruction
+
+    uint8_t *data;                           ///< current frame data
+    uint8_t *data_end;                       ///< frame data end
+    uint8_t *ptr;                            ///< current position in frame data
+    uint8_t *last_ptr;                       ///< position where last 4608-sample block ended
+    /*Eugene:*/
+    unsigned int max_packet_size;            // Avoid multiply realloc calls
+} APEDecoderContext;
+
+
+static inline uint8_t bytestream_get_byte(uint8_t** ptr) {
+  uint8_t tmp;
+  tmp = **ptr;
+  *ptr += 1;
+  return tmp;
+}
+
+/*static inline uint32_t bytestream_get_be32(uint8_t** ptr) {
+  uint32_t tmp;
+  tmp = *((uint32_t*)*ptr);
+  *ptr += 4;
+  return tmp;
+}*/
+
+static inline uint32_t bytestream_get_be32(uint8_t** ptr) {
+  uint32_t tmp;
+  tmp = (*ptr)[3] | ((*ptr)[2] << 8) | ((*ptr)[1] << 16) | ((*ptr)[0] << 24);
+  *ptr += 4;
+  return tmp;
+}
+
+static inline uint32_t bswap_32(uint32_t x)
+{
+#if defined(ARCH_X86)
+#if __CPU__ != 386
+ __asm("bswap   %0":
+      "=r" (x)     :
+#else
+ __asm("xchgb   %b0,%h0\n"
+      "         rorl    $16,%0\n"
+      "         xchgb   %b0,%h0":
+      LEGACY_REGS (x)                :
+#endif
+      "0" (x));
+#elif defined(ARCH_SH4)
+        __asm__(
+        "swap.b %0,%0\n"
+        "swap.w %0,%0\n"
+        "swap.b %0,%0\n"
+        :"=r"(x):"0"(x));
+#elif defined(ARCH_ARM)
+    uint32_t t;
+    __asm__ (
+      "eor %1, %0, %0, ror #16 \n\t"
+      "bic %1, %1, #0xFF0000   \n\t"
+      "mov %0, %0, ror #8      \n\t"
+      "eor %0, %0, %1, lsr #8  \n\t"
+      : "+r"(x), "+r"(t));
+#elif defined(ARCH_BFIN)
+    unsigned tmp;
+    asm("%1 = %0 >> 8 (V);\n\t"
+        "%0 = %0 << 8 (V);\n\t"
+        "%0 = %0 | %1;\n\t"
+        "%0 = PACK(%0.L, %0.H);\n\t"
+        : "+d"(x), "=&d"(tmp));
+#else
+    x= ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF);
+    x= (x>>16) | (x<<16);
+#endif
+    return x;
+}
+
+static inline void bswap_buf(uint32_t *dst, uint32_t *src, int w){
+    int i;
+
+    for(i=0; i+8<=w; i+=8){
+        dst[i+0]= bswap_32(src[i+0]);
+        dst[i+1]= bswap_32(src[i+1]);
+        dst[i+2]= bswap_32(src[i+2]);
+        dst[i+3]= bswap_32(src[i+3]);
+        dst[i+4]= bswap_32(src[i+4]);
+        dst[i+5]= bswap_32(src[i+5]);
+        dst[i+6]= bswap_32(src[i+6]);
+        dst[i+7]= bswap_32(src[i+7]);
+    }
+    for(;i<w; i++){
+        dst[i+0]= bswap_32(src[i+0]);
+    }
+}
+
+static inline int16_t av_clip_int16(int a) {
+    if ((a+32768) & ~65535) return (a>>31) ^ 32767;
+    else                    return a;
+}
+
+int ape_read_header(APEContext *ape, VFSFile *pb, int probe_only);
+int ape_read_packet(APEContext *ape, VFSFile *pb, uint8_t *pkt, int *pkt_size);
+int ape_read_close(APEContext *ape);
+
+int ape_decode_init(APEDecoderContext *s, APEContext *ctx);
+int ape_decode_frame(APEDecoderContext *s,
+                            void *data, int *data_size,
+                            uint8_t * buf, int buf_size);
+
+int ape_decode_close(APEDecoderContext *s);
+
+#endif // APE_H