⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rpxx.cpp

📁 Enc 压 缩 wav文件为 A16格式的 文件
💻 CPP
字号:
// $Revision: 1.1.1.1 $

#include "wavestream.h"
#include "rpxx.h"

#define fOSC 5068800.0

/* fS = fOSC / TA / TB / 2                             */
/* if (iA <= 9) TA = 9                                 */
/*    else      TA = iA                                */

#define  NO_SAMPLE_RATE  41

uint RP20fS[NO_SAMPLE_RATE] = {
 4340,  4735,  4883,  5208,  5580,  5788,  6010,  6510,
 6945,  7102,  7441,  7813,  8013,  8681,  9470,  9765,
10417, 11160, 11575, 12019, 13021, 13890, 14205, 14882,
15625, 16027, 17361, 18940, 19531, 20835, 22321, 23150,
24038, 26042, 28409, 29764, 31250, 34723, 39623, 41670,
44643
};

uint RP8fS[19][3] = {
0x1203FA,  0,  3472,  0x2203FA,  0,  3721,  0x3203FA,  0,  4007,
0x4203FA,  0,  4341,  0x5203FA,  1,  4735,  0x6203FA,  3,  5209,
0x7203FA,  5,  5787,  0x8203FA,  7,  6510,  0x1203FC,  8,  6945,
0x2203FC, 10,  7441,  0x3203FC, 12,  8013,  0x4203FC, 13,  8681,
0x5203FC, 14,  9470,  0x6203FC, 16, 10417,  0x7203FC, 18, 11575,
0x8203FC, 20, 13022,  0x1203F8, 21, 13890,  0x2203F8, 23, 14822,
0x3203F8, 25, 16027
};

word RP14fS[][3] = {
  4855,  9, 58,    4873, 13, 40,    4892, 14, 37,    4902, 11, 47,
  4911, 12, 43,    4940,  9, 57,    4969, 10, 51,    4998, 13, 39,
  5008, 11, 46,    5028,  9, 56,    5068, 10, 50,    5120,  9, 55,
  5130, 13, 38,    5151, 12, 41,    5172, 14, 35,    5214,  9, 54,
  5236, 11, 44,    5269, 13, 37,    5280, 12, 40,    5313,  9, 53,
  5324, 14, 34,    5358, 11, 43,    5392, 10, 47,    5415, 13, 36,
  5485, 11, 42,    5509, 10, 46,    5521,  9, 51,    5557, 12, 38,
  5570, 13, 35,    5619, 11, 41,    5632,  9, 50,    5657, 14, 32,
  5708, 12, 37,    5733, 13, 34,    5746,  9, 49,    5760, 11, 40,
  5839, 14, 31,    5866, 12, 36,    5893, 10, 43,    5907, 11, 39,
  5991,  9, 47,    6034, 14, 30,    6063, 11, 38,    6092, 13, 32,
  6121,  9, 46,    6181, 10, 41,    6211, 12, 34,    6227, 11, 37,
  6242, 14, 29,    6257,  9, 45,    6288, 13, 31,    6336, 10, 40,
  6400, 12, 33,    6465, 14, 28,    6498, 13, 30,    6548,  9, 43,
  6582, 11, 35,    6600, 12, 32,    6669, 10, 38,    6704,  9, 42,
  6704, 14, 27,    6722, 13, 29,    6776, 11, 34,    6812, 12, 31,
  6849, 10, 37,    6868,  9, 41,    6962, 14, 26,    6981, 11, 33,
  7040, 12, 30,    7200, 11, 32,    7220,  9, 39,    7241, 10, 35,
  7282, 12, 29,    7410,  9, 38,    7432, 11, 31,    7454, 10, 34,
  7498, 13, 26,    7542, 14, 24,    7610,  9, 37,    7680, 10, 33,
  7798, 13, 25,    7822,  9, 36,    7870, 14, 23,    7920, 10, 32,
  7944, 11, 29,    8045,  9, 35,    8123, 12, 26,    8175, 10, 31,
  8228, 11, 28,    8282,  9, 34,    8448, 12, 25,    8476, 13, 23,
  8533, 11, 27,    8620, 14, 21,    8739, 10, 29,    8800, 12, 24,
  8861, 11, 26,    9051, 10, 28,    9083,  9, 31,    9182, 12, 23,
  9216, 11, 25,    9283, 13, 21,    9386, 10, 27,    9527, 14, 19,
  9600, 12, 22,    9710,  9, 29,    9747, 10, 26,   10017, 11, 23,
 10057, 12, 21,   10137, 10, 25,   10260, 13, 19,   10429,  9, 27,
 10472, 11, 22,   10560, 12, 20,   10648, 14, 17,   10830,  9, 26,
 10971, 11, 21,   11019, 10, 23,   11115, 12, 19,   11264,  9, 25,
 11314, 14, 16,   11467, 13, 17,   11520, 10, 22,   11733, 12, 18,
 12068, 10, 21,   12126, 11, 19,   12184, 13, 16,   12243,  9, 23,
 12423, 12, 17,   12672, 10, 20,   12800, 11, 18,   12996, 13, 15,
 13200, 12, 16,   13338, 10, 19,   13409,  9, 21,   13552, 11, 17,
 14080, 12, 15,   14400, 11, 16,   14821,  9, 19,   14908, 10, 17,
 15360, 11, 15,   15644,  9, 18,   15840, 10, 16,   16564,  9, 17,
 16896, 10, 15,   17600,  9, 16,   18773,  9, 15
};

/*
short slope[2][8][8] = {
    {
        0,   1,   2,   3,   4,   5,   7,   9,
        1,   2,   3,   4,   5,   7,   9,  13,
        2,   3,   5,   8,  12,  17,  23,  30,
        3,   6,  11,  18,  27,  38,  51,  66,
        4,   9,  14,  24,  34,  44,  64,  84,
        5,  11,  17,  29,  41,  53,  77, 101,
        6,  13,  20,  34,  48,  62,  90, 118,
        7,  15,  23,  39,  55,  71, 103, 125
    },
    {
        0,   1,   2,   4,   6,   8,  12,  16,
        1,   3,   5,   9,  13,  17,  25,  33,
        2,   5,   8,  14,  20,  26,  38,  50,
        3,   7,  11,  19,  27,  35,  41,  67,
        4,   9,  14,  24,  34,  44,  64,  84,
        5,  11,  17,  29,  41,  53,  77, 111,
        6,  13,  20,  34,  48,  62,  90, 118,
        7,  15,  23,  39,  55,  71, 103, 125
    }
};

short steps[2][8][8] = {
    {
        0,   0,   0,   0,   0,   0,   1,   1,
        0,   0,   1,   1,   1,   1,   2,   2,
        1,   1,   2,   2,   2,   2,   3,   3,
        2,   2,   2,   3,   3,   4,   4,   5,
        3,   3,   3,   4,   4,   5,   5,   6,
        4,   4,   5,   5,   5,   5,   6,   7,
        5,   5,   6,   6,   6,   6,   7,   7,
        6,   6,   7,   7,   7,   7,   7,   7
    },
    {
       00,  00,  00,  00,  02,  02,  03,  04,
       00,  00,  01,  01,  03,  03,  04,  05,
       01,  01,  02,  02,  04,  04,  05,  06,
       02,  02,  03,  03,  05,  05,  06,  07,
       03,  03,  04,  04,  06,  06,  07,  07,
       04,  04,  05,  05,  07,  07,  07,  07,
       05,  05,  06,  06,  07,  07,  07,  07,
       06,  06,  07,  07,  07,  07,  07,  07
    }
};
*/


uint flength(FILE *stream)
{
    long pos,end;

    pos = ftell(stream);
    fseek(stream,0,SEEK_END);
    end = ftell(stream);
    fseek(stream,pos,SEEK_SET);   
    return end;
}

int  crpxx::start_read()
{
    uint   i;
    int    TA,TB;

    info->ch     = 1;
    info->read_write = 0; // read
    info->types  = 1;     // LSB first

    ::fseek(info->pf,0,SEEK_SET);
    ::fread((void*)&head,1,48,info->pf);
    // Check file Sunplus RP8 8 bits format
    if(strcmp(head.name,"SUNPLUS SPEECH")!=0) {
        info->fs = 8013;
        for (i = 0; i < 19; i++) {
            if (*(unsigned long*)(head.name) == RP8fS[i][0]) {
                info->fs = RP8fS[i][2]; break;
            };
        }
        info->bits   = 8;
        info->offset = 0x80;
        adpcm = 0;
    } else {
        info->bits   = (head.bits > 8) ? 16 : 8;
        info->offset = (head.bits > 8) ? 0x8000 : 0x80;
        if(head.Class == 0){
            info->fs = RP20fS[head.ifS];
        } else {
            TB = head.TB;
            TA = head.iA;
            if(TA <= 9) TA = 9;
            info->fs = (int)(fOSC /(TA*TB*2));
        };
        adpcm = 1;
        switch(info->types) {
        case 0x00 : // SUNPLUS PCM DATA
                    adpcm = 0;
		    break;
        case 0x10 : // ADPCM64 without end code
		    endcode = 0; table = 0; hardlimit = 1;
                    break;
        case 0x11 : // ADPCM64 with end code
		    endcode = 1; table = 0; hardlimit = 1;
                    break;
        case 0x12 : // ADPCM64 without end code and no hardlimit
		    endcode = 0; table = 0; hardlimit = 0;
                    break;
        case 0x13 : // ADPCM64 with end code and no hardlimit
		    endcode = 1; table = 0; hardlimit = 0;
                    break;

        case 0x19 : // ADPCM66 without end code
       		    endcode = 0; table = 1; hardlimit = 1;
                    break;
        case 0x1A : // ADPCM66 with end code
       		    endcode = 1; table = 1; hardlimit = 1;
                    break;
        case 0x1B : // ADPCM66 without end code and no hardlimit
 		    endcode = 0; table = 1; hardlimit = 0;
                    break;
        case 0x1C : // ADPCM66 with end code and no hardlimit
 		    endcode = 1; table = 1; hardlimit = 0;
        default   : break;
        }
    };
    
    // Set length of data
    info->length = ::flength(info->pf)-0x30;
    if(info->bits > 8) info->length /= 2;

    return 0;
}

int  crpxx::start_write(uint format)
{
    int    i,index;
    double err,merr;

    head.ifC  = 1;
    head.ifS = 12;
    merr = 44100.;
    index = 0;
    for(i=0;i<sizeof(RP14fS)/6;i++) {
      err = (double)(info->fs-RP14fS[i][0]);
      err *= (err < 0.) ? -1. : 1.;
      if(err < merr) {
        merr = err;
        head.ifS = i;
      };
    };

    head.Class = 1;
    head.iA = (char)RP14fS[head.ifS][1];
    head.TB = (char)RP14fS[head.ifS][2];

    head.mark = 0x00FF00FF;
    strcpy(head.name, "SUNPLUS SPEECH");
    head.type=0;
    head.bits = info->bits;
    head.inp_vol = 0;
    head.checksuml = 0;
    head.checksumh = 0;
    
    ::fwrite((void*)&head,48,1,info->pf);
    return 0;
}

void crpxx::end_read()
{
}

void crpxx::end_write()
{
}

int crpxx::read(void* buffer,int samples)
{
    if(info->decode == 0) return cwavefile::read(buffer,samples);
    else {
        if( adpcm == 0 ) {
            return cwavefile::read(buffer,samples);
        } else {
            // decode adpcm to buffer
            return cwavefile::read(buffer,samples);
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -