Path: blob/master/tools/sdk-tools/adpcm/vadpcm_dec.c
7861 views
#include <unistd.h>1#include <assert.h>2#include <string.h>3#include <stdio.h>4#include <stdlib.h>5#include <signal.h>6#include <fcntl.h>7#include "vadpcm.h"89static void int_handler(s32 sig)10{11s32 flags;1213flags = fcntl(STDIN_FILENO, F_GETFL, 0);14flags &= ~FNDELAY;15fcntl(STDIN_FILENO, F_SETFL, flags);16exit(0);17}1819static char usage[] = "bitfile";2021#ifdef __sgi2223// Declaring a sigaction like this is wildly unportable; you're supposed to24// assign members one by one in code. We do that in the non-SGI case.25static struct sigaction int_act = {26/* sa_flags = */ SA_RESTART,27/* sa_handler = */ &int_handler,28/* sa_mask = */ 0,29};3031#endif3233s32 main(s32 argc, char **argv)34{35s32 c;36u8 cc;37u8 doloop = 0;38s16 order;39s16 version;40s16 nloops;41s16 npredictors;42s32 flags;43s32 ***coefTable = NULL;44s32 i;45s32 j;46s32 *outp;47s32 *state;48s32 done = 0;49s32 num;50u32 ts;51s32 soundPointer;52s32 cType;53s32 offset;54s32 currPos = 0;55s32 nSamples;56s32 framePos;57s32 loopBegin;58s32 left;59ALADPCMloop *aloops;60Chunk FormChunk;61ChunkHeader Header;62CommonChunk CommChunk;63SoundDataChunk SndDChunk;64char *ChunkName;65FILE *ifile;66char *progname = argv[0];6768#ifndef __sgi69nloops = 0;70#endif7172if (argc < 2)73{74fprintf(stderr, "%s %s\n", progname, usage);75exit(1);76}7778while ((c = getopt(argc, argv, "l")) != -1)79{80switch (c)81{82case 'l':83doloop = 1;84break;85}86}8788argv += optind - 1;89if ((ifile = fopen(argv[1], MODE_READ)) == NULL)90{91fprintf(stderr, "%s: bitstream file [%s] could not be opened\n", progname, argv[1]);92exit(1);93}9495state = malloc(16 * sizeof(int));96for (i = 0; i < 16; i++)97{98state[i] = 0;99}100101fread(&FormChunk, sizeof(FormChunk), 1, ifile);102BSWAP32(FormChunk.ckID)103BSWAP32(FormChunk.formType)104if ((FormChunk.ckID != 0x464f524d) || (FormChunk.formType != 0x41494643)) // FORM, AIFC105{106fprintf(stderr, "%s: [%s] is not an AIFF-C File\n", progname, argv[1]);107exit(1);108}109110while (!done)111{112num = fread(&Header, sizeof(Header), 1, ifile);113if (num <= 0)114{115done = 1;116break;117}118BSWAP32(Header.ckID)119BSWAP32(Header.ckSize)120121Header.ckSize++, Header.ckSize &= ~1;122switch (Header.ckID)123{124case 0x434f4d4d: // COMM125offset = ftell(ifile);126num = fread(&CommChunk, sizeof(CommChunk), 1, ifile);127if (num <= 0)128{129fprintf(stderr, "%s: error parsing file [%s]\n", progname, argv[1]);130done = 1;131}132BSWAP16(CommChunk.numChannels)133BSWAP16(CommChunk.numFramesH)134BSWAP16(CommChunk.numFramesL)135BSWAP16(CommChunk.sampleSize)136BSWAP16(CommChunk.compressionTypeH)137BSWAP16(CommChunk.compressionTypeL)138cType = (CommChunk.compressionTypeH << 16) + CommChunk.compressionTypeL;139if (cType != 0x56415043) // VAPC140{141fprintf(stderr, "%s: file [%s] is of the wrong compression type.\n", progname, argv[1]);142exit(1);143}144if (CommChunk.numChannels != 1)145{146fprintf(stderr, "%s: file [%s] contains %ld channels, only 1 channel supported.\n", progname, argv[1], (long) CommChunk.numChannels);147exit(1);148}149if (CommChunk.sampleSize != 16)150{151fprintf(stderr, "%s: file [%s] contains %ld bit samples, only 16 bit samples supported.\n", progname, argv[1], (long) CommChunk.sampleSize);152exit(1);153}154nSamples = (CommChunk.numFramesH << 16) + CommChunk.numFramesL;155fseek(ifile, offset + Header.ckSize, SEEK_SET);156break;157158case 0x53534e44: // SSND159offset = ftell(ifile);160fread(&SndDChunk, sizeof(SndDChunk), 1, ifile);161BSWAP32(SndDChunk.offset)162BSWAP32(SndDChunk.blockSize)163// The assert error messages specify line numbers 165/166. Match164// that using a #line directive.165#ifdef __sgi166# line 164167#endif168assert(SndDChunk.offset == 0);169assert(SndDChunk.blockSize == 0);170soundPointer = ftell(ifile);171fseek(ifile, offset + Header.ckSize, SEEK_SET);172break;173174case 0x4150504c: // APPL175offset = ftell(ifile);176fread(&ts, sizeof(u32), 1, ifile);177BSWAP32(ts)178if (ts == 0x73746f63) // stoc179{180ChunkName = ReadPString(ifile);181if (strcmp("VADPCMCODES", ChunkName) == 0)182{183fread(&version, sizeof(s16), 1, ifile);184BSWAP16(version)185if (version != 1)186{187fprintf(stderr, "Non-identical codebook chunk versions\n");188}189readaifccodebook(ifile, &coefTable, &order, &npredictors);190}191else if (strcmp("VADPCMLOOPS", ChunkName) == 0)192{193fread(&version, sizeof(s16), 1, ifile);194BSWAP16(version)195if (version != 1)196{197fprintf(stderr, "Non-identical loop chunk versions\n");198}199aloops = readlooppoints(ifile, &nloops);200}201}202fseek(ifile, offset + Header.ckSize, SEEK_SET);203break;204205default:206// We don't understand this chunk. Skip it.207fseek(ifile, Header.ckSize, SEEK_CUR);208break;209}210}211212if (coefTable == NULL)213{214// @bug should use progname; argv[0] may be an option215fprintf(stderr, "%s: Codebook missing from bitstream [%s]\n", argv[0], argv[1]);216exit(1);217}218219outp = malloc(16 * sizeof(s32));220for (i = 0; i < order; i++)221{222outp[15 - i] = 0;223}224225fseek(ifile, soundPointer, SEEK_SET);226if (doloop && nloops > 0)227{228#ifndef __sgi229struct sigaction int_act;230int_act.sa_flags = SA_RESTART;231int_act.sa_handler = int_handler;232sigemptyset(&int_act.sa_mask);233#endif234235sigaction(SIGINT, &int_act, NULL);236flags = fcntl(STDIN_FILENO, F_GETFL, 0);237flags |= FNDELAY;238fcntl(STDIN_FILENO, F_SETFL, flags);239for (i = 0; i < nloops; i++)240{241while (currPos < aloops[i].end)242{243left = aloops[i].end - currPos;244vdecodeframe(ifile, outp, order, coefTable);245writeout(stdout, left < 16 ? left : 16, outp, outp, 1);246currPos += 16;247}248249while (read(STDIN_FILENO, &cc, 1) == 0)250{251framePos = (aloops[i].start >> 4) + 1;252fseek(ifile, (framePos * 9) + soundPointer, SEEK_SET);253for (j = 0; j < 16; j++)254{255outp[j] = aloops[i].state[j];256}257loopBegin = aloops[i].start & 0xf;258writeout(stdout, 16 - loopBegin, outp + loopBegin, outp + loopBegin, 1);259currPos = framePos * 16;260while (currPos < aloops[i].end)261{262left = aloops[i].end - currPos;263vdecodeframe(ifile, outp, order, coefTable);264writeout(stdout, left < 16 ? left : 16, outp, outp, 1);265currPos += 16;266}267}268269left = 16 - left;270if (left != 0)271{272writeout(stdout, left, &outp[left], &outp[left], 1);273}274275while (currPos < nSamples)276{277vdecodeframe(ifile, outp, order, coefTable);278left = nSamples - currPos;279writeout(stdout, left < 16 ? left : 16, outp, outp, 1);280currPos += 16;281}282283flags = fcntl(STDIN_FILENO, F_GETFL, 0);284flags &= ~FNDELAY;285fcntl(STDIN_FILENO, F_SETFL, flags);286}287}288else289{290while (currPos < nSamples)291{292vdecodeframe(ifile, outp, order, coefTable);293writeout(stdout, 16, outp, outp, 1);294currPos += 16;295}296}297298fclose(ifile);299return 0;300}301302303