• [psp][lumines]vag解码程序


    vag是dvd音频格式,lumines中使用的略有不同,不分512块的左右声道,而是左右各一个文件。单个声道内连续存放数据块。
    修改后可以解为wav.

    #include <stdio.h>
    #include 
    <string.h>
    #include 
    <stdlib.h>

    struct VAGState
    {
        VAGState() 
    { Reset(); }
        
        
    void Reset() { s[0= s[1= 0; }
        
        
    double s[2];
    }
    ;

    void DecodeVAGBlock(const unsigned char in[16], short out[28], VAGState* state);

    const double filter[5][2=
    {
        
    0.00.0 },
        
    60.0 / 64.00.0 },
        
    115.0 / 64.0-52.0 / 64.0 },
        
    98.0 / 64.0-55.0 / 64.0 },
        
    122.0 / 64.0-60.0 / 64.0 }
    }
    ;

    const unsigned char wavhdr[44=
    {
        
    'R','I','F','F',
            
    0,0,0,0,  // length of file - 8
            'W','A','V','E',
            
            
    'f','m','t',' ',
            
    0x10,0,0,0,
            
    1,0,2,0,
            
    0,0,0,0,  // sample rate
            0,0xF4,1,0,
            
    4,0,0x10,0,
            
            
    'd','a','t','a',
            
    0,0,0,0,  // length of file - 0x2C
    }
    ;

    int main(int argc, char *argv[])
    {
        
    int rate = 32000;
        
        argc
    --;
        argv
    ++;
        
        
    while (argc && (argv[0][0== '-'))
        
    {
            
    char parm = argv[0][1];
            
            
    if (parm == 'r')
            
    {
                
    if (argv[0][2])
                
    {
                    rate 
    = atoi(argv[0+ 2);
                }

                
    else
                
    {
                    argc
    --;
                    argv
    ++;
                    rate 
    = atoi(argv[0]);
                }

                
                printf(
    "Sample rate : %d\n", rate);
            }

            
            argc
    --;
            argv
    ++;
        }

        
        
    char src[256];
        
    char dst[256];
        
        
    if (argc == 1)
        
    {
            sprintf(src, 
    "%s", argv[0]);
            sprintf(dst, 
    "%s.WAV", argv[0]);
        }

        
    else if (argc == 2)
        
    {
            strcpy(src, argv[
    0]);
            strcpy(dst, argv[
    1]);
        }

        
    else
        
    {
            printf(
    "Usage: Decode [-r | []\n");
            
    return -1;
        }

        
        FILE
    * vag = fopen(src, "rb");
        
    if (!vag)
        
    {
            printf(
    "Can't open source file %s\n", src);
            
    return -1;
        }

        
        
    // find number of blocks
        fseek(vag, 0, SEEK_END);
        
    int length = (ftell(vag) - 0x40/ 16;
        fseek(vag, 
    0x0c, SEEK_SET);
        unsigned 
    char buf[8];
        fread(buf, 
    2sizeof(unsigned long), vag);
        length 
    = ((unsigned int)buf[0]<<24+ ((unsigned int)buf[1]<<16+ ((unsigned int)buf[2]<<8+ (unsigned int)buf[3];
        length 
    -= 0x20;
        rate 
    = ((unsigned int)buf[4]<<24+ ((unsigned int)buf[5]<<16+ ((unsigned int)buf[6]<<8+ (unsigned int)buf[7];
        rate
    /=2;
        fseek(vag, 
    0x20, SEEK_SET);
        fread(dst, 
    0x201, vag);
        fseek(vag, 
    0x40, SEEK_SET);
        
    const int size = 1;

        
    //length /= size*2;
        
        FILE
    * wav = fopen(dst, "wb");
        
    if (!wav)
        
    {
            printf(
    "Can't open destination file %s\n", dst);
            
    return -1;
        }

        
        printf(
    "Length : %d blocks\n", length);
        
        unsigned 
    char hdr[44];
        
    int*  ihdr = (int*)hdr;
        memcpy(hdr, wavhdr, 
    44);
        ihdr[
    1= length * 28 * size * 2 + 0x24;
        ihdr[
    10= length * 28 * size * 2;
        ihdr[
    6= rate;
        
        fwrite(hdr, 
    144, wav);
        
        VAGState st[
    2];
        unsigned 
    char bl[size * 16];
        
    short out[size * 28 * 2];
        
        
    extern int vag_depack(unsigned char *entree, unsigned char *sortie );
        
        
    for (int blk = 0; blk < length; blk+=16)
        
    {
            
    short obuf[28];
            fread(bl, 
    161, vag);
            
    int flags = (bl[1>> 4 ) & 0x0f;
            
    if (flags == 7)
                
    break;
            
    if (flags ==3)
                
    break;
            
    if (flags ==4)
                
    break;
            
    if (flags ==6)
                
    break;
            DecodeVAGBlock(bl, obuf, 
    &st[0]);
            fwrite(obuf, 
    228, wav);
        }

        fclose(wav);
        fclose(vag);
        
        
    return 0;
    }


    int highnibble(int a) return (a >> 4& 15; }
    int lownibble(int a) return a & 15; }

    short quantize(double sample)
    {
        
    int a = int(sample + 0.5);
        
        
    if (a < -32768return -32768
        
    if (a > 32767return 32767;
        
        
    return short(a);
    }


    void DecodeVAGBlock(const unsigned char in[16], short out[28], VAGState* state)
    {
        
    double s[2];
        
        s[
    0= state->s[0];
        s[
    1= state->s[1];
        
        
    int predictor = highnibble(in[0]);
        
    int shift = lownibble(in[0]);
        
    int flags = in[1];
        
        
    if (predictor > 4)
        
    {
            
    // this should never happen in a valid VAG block
            printf("Predictor %d!\n", predictor);
            predictor 
    = 0;
        }

        
    int ii;
        
    for (ii = 0; ii < 14; ii++)
        
    {
            
    int byte = in[ii + 2];
            
            
    out[ii * 2= short(lownibble(byte<< 12>> shift;
            
    out[ii * 2 + 1= short(highnibble(byte<< 12>> shift;
        }

        
        
    for (ii = 0; ii < 28; ii++)
        
    {
            
    double filt = out[ii] + s[0* filter[predictor][0+ s[1* filter[predictor][1];
            s[
    1= s[0];
            s[
    0= filt;
            
            
    out[ii] = quantize(filt);
        }

        
        state
    ->s[0= s[0];
        state
    ->s[1= s[1];
    }

  • 相关阅读:
    将后台返回的 xml replace
    程序员数学的重要性
    .net里生成的 checkboxlist 至少要选择一个
    关于如何坚持目标,网上偶然看到的,转载一下
    犹豫不决(收集)
    CSS中Padding参数说明及使用指南
    IE地址栏小图标问题
    常用sql语句集锦
    ie9怎么开兼容模式
    一台MySql服务器不同数据库之间数据同步_解决方案(Java)
  • 原文地址:https://www.cnblogs.com/kaikai/p/189997.html
Copyright © 2020-2023  润新知