📄 voc.c
字号:
wlshort(ft, 0x1129); /* checksum of version number */ if (ft->info.size == BYTE) ft->info.style = UNSIGNED; else ft->info.style = SIGN2; if (ft->info.channels == -1) ft->info.channels = 1;}void vocwrite(ft, buf, len) ft_t ft;LONG *buf, len;{ vs_t v = (vs_t) ft->priv; unsigned char uc; int sw; if (v->samples == 0) { /* No silence packing yet. */ v->silent = 0; blockstart(ft); } v->samples += len; while(len--) { if (ft->info.size == BYTE) { uc = RIGHT(*buf++, 24); uc ^= 0x80; putc(uc, ft->fp); } else { sw = (int) RIGHT(*buf++, 16); wlshort(ft,sw); } }}void vocstopwrite(ft) ft_t ft;{ blockstop(ft);}/* Voc-file handlers *//* Read next block header, save info, leave position at start of data */voidgetblock(ft)ft_t ft;{ vs_t v = (vs_t) ft->priv; unsigned char uc, block; ULONG sblen; LONG new_rate; int i; v->silent = 0; while (v->rest == 0) { if (feof(ft->fp)) return; block = getc(ft->fp); if (block == VOC_TERM) return; if (feof(ft->fp)) return; uc = getc(ft->fp); sblen = uc; uc = getc(ft->fp); sblen |= ((LONG) uc) << 8; uc = getc(ft->fp); sblen |= ((LONG) uc) << 16; switch(block) { case VOC_DATA: uc = getc(ft->fp); /* When DATA block preceeded by an EXTENDED */ /* block, the DATA blocks rate value is invalid */ if (!v->extended) { if (uc == 0) fail("File %s: Sample rate is zero?"); if ((v->rate != -1) && (uc != v->rate)) fail("File %s: sample rate codes differ: %d != %d", ft->filename,v->rate, uc); v->rate = uc; ft->info.rate = 1000000.0/(256 - v->rate); v->channels = 1; } uc = getc(ft->fp); if (uc != 0) fail("File %s: only interpret 8-bit data!", ft->filename); v->extended = 0; v->rest = sblen - 2; v->size = BYTE; return; case VOC_DATA_16: new_rate = rllong(ft); if (new_rate == 0) fail("File %s: Sample rate is zero?",ft->filename); if ((v->rate != -1) && (new_rate != v->rate)) fail("File %s: sample rate codes differ: %d != %d", ft->filename, v->rate, new_rate); v->rate = new_rate; ft->info.rate = new_rate; uc = getc(ft->fp); switch (uc) { case 8: v->size = BYTE; break; case 16: v->size = WORD; break; default: fail("Don't understand size %d", uc); } v->channels = getc(ft->fp); getc(ft->fp); /* unknown1 */ getc(ft->fp); /* notused */ getc(ft->fp); /* notused */ getc(ft->fp); /* notused */ getc(ft->fp); /* notused */ getc(ft->fp); /* notused */ v->rest = sblen - 12; return; case VOC_CONT: v->rest = sblen; return; case VOC_SILENCE: { unsigned short period; period = rlshort(ft); uc = getc(ft->fp); if (uc == 0) fail("File %s: Silence sample rate is zero"); /* * Some silence-packed files have gratuitously * different sample rate codes in silence. * Adjust period. */ if ((v->rate != -1) && (uc != v->rate)) period = (period * (256 - uc))/(256 - v->rate); else v->rate = uc; v->rest = period; v->silent = 1; return; } case VOC_MARKER: uc = getc(ft->fp); uc = getc(ft->fp); /* Falling! Falling! */ case VOC_TEXT: { int i; /* Could add to comment in SF? */ for(i = 0; i < sblen; i++) getc(ft->fp); } continue; /* get next block */ case VOC_LOOP: case VOC_LOOPEND: report("File %s: skipping repeat loop"); for(i = 0; i < sblen; i++) getc(ft->fp); break; case VOC_EXTENDED: /* An Extended block is followed by a data block */ /* Set this byte so we know to use the rate */ /* value from the extended block and not the */ /* data block. */ v->extended = 1; new_rate = rlshort(ft); if (new_rate == 0) fail("File %s: Sample rate is zero?"); if ((v->rate != -1) && (new_rate != v->rate)) fail("File %s: sample rate codes differ: %d != %d", ft->filename, v->rate, new_rate); v->rate = new_rate; uc = getc(ft->fp); if (uc != 0) fail("File %s: only interpret 8-bit data!", ft->filename); uc = getc(ft->fp); if (uc) ft->info.channels = 2; /* Stereo */ /* Needed number of channels before finishing compute for rate */ ft->info.rate = (256000000L/(65536L - v->rate))/ft->info.channels; /* An extended block must be followed by a data */ /* block to be valid so loop back to top so it */ /* can be grabed. */ continue; default: report("File %s: skipping unknown block code %d", ft->filename, block); for(i = 0; i < sblen; i++) getc(ft->fp); } }}/* Start an output block. */void blockstart(ft)ft_t ft;{ vs_t v = (vs_t) ft->priv; v->blockseek = ftell(ft->fp); if (v->silent) { putc(VOC_SILENCE, ft->fp); /* Silence block code */ putc(0, ft->fp); /* Period length */ putc(0, ft->fp); /* Period length */ putc((int) v->rate, ft->fp); /* Rate code */ } else { if (ft->info.size == BYTE) { /* 8-bit sample section. By always setting the correct */ /* rate value in the DATA block (even when its preceeded */ /* by an EXTENDED block) old software can still play stereo */ /* files in mono by just skipping over the EXTENDED block. */ /* Prehaps the rate should be doubled though to make up for */ /* double amount of samples for a given time???? */ if (ft->info.channels > 1) { putc(VOC_EXTENDED, ft->fp); /* Voice Extended block code */ putc(4, ft->fp); /* block length = 4 */ putc(0, ft->fp); /* block length = 4 */ putc(0, ft->fp); /* block length = 4 */ v->rate = 65536L - (256000000.0/(2*(float)ft->info.rate)); wlshort(ft,v->rate); /* Rate code */ putc(0, ft->fp); /* File is not packed */ putc(1, ft->fp); /* samples are in stereo */ } putc(VOC_DATA, ft->fp); /* Voice Data block code */ putc(0, ft->fp); /* block length (for now) */ putc(0, ft->fp); /* block length (for now) */ putc(0, ft->fp); /* block length (for now) */ v->rate = 256 - (1000000.0/(float)ft->info.rate); putc((int) v->rate, ft->fp);/* Rate code */ putc(0, ft->fp); /* 8-bit raw data */ } else { putc(VOC_DATA_16, ft->fp); /* Voice Data block code */ putc(0, ft->fp); /* block length (for now) */ putc(0, ft->fp); /* block length (for now) */ putc(0, ft->fp); /* block length (for now) */ v->rate = ft->info.rate; wllong(ft, v->rate); /* Rate code */ putc(16, ft->fp); /* Sample Size */ putc(ft->info.channels, ft->fp); /* Sample Size */ putc(0, ft->fp); /* Unknown */ putc(0, ft->fp); /* Unused */ putc(0, ft->fp); /* Unused */ putc(0, ft->fp); /* Unused */ putc(0, ft->fp); /* Unused */ putc(0, ft->fp); /* Unused */ } }}/* End the current data or silence block. */void blockstop(ft) ft_t ft;{ vs_t v = (vs_t) ft->priv; LONG datum; putc(0, ft->fp); /* End of file block code */ fseek(ft->fp, v->blockseek, 0); /* seek back to block length */ fseek(ft->fp, 1, 1); /* seek forward one */ if (v->silent) { datum = (v->samples) & 0xff; putc((int)datum, ft->fp); /* low byte of length */ datum = (v->samples >> 8) & 0xff; putc((int)datum, ft->fp); /* high byte of length */ } else { if (ft->info.size == BYTE) { if (ft->info.channels > 1) { fseek(ft->fp, 8, 1); /* forward 7 + 1 for new block header */ } } v->samples += 2; /* adjustment: SBDK pp. 3-5 */ datum = (v->samples) & 0xff; putc((int)datum, ft->fp); /* low byte of length */ datum = (v->samples >> 8) & 0xff; putc((int)datum, ft->fp); /* middle byte of length */ datum = (v->samples >> 16) & 0xff; putc((int)datum, ft->fp); /* high byte of length */ }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -