• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

kaikai向前走

转职任务完成。崭新fn诞生
  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

[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.0, 0.0 },
    
{ 60.0 / 64.0, 0.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, 
2, sizeof(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, 
0x20, 1, 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, 
1, 44, 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, 
16, 1, 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, 
2, 28, 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 < -32768) return -32768; 
    
if (a > 32767) return 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];
}

posted on 2005-07-10 16:31  kaikai  阅读(1310)  评论(2)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3