audio/vocdec: Creative Voice File decoder

slight correction in file.c from previous commit
This commit is contained in:
Jacob Moody 2023-02-09 02:41:21 +00:00
parent 8af84630a8
commit 89cb83a426
6 changed files with 151 additions and 3 deletions

View file

@ -69,6 +69,8 @@ fn play1 {
midi
case *audio/mus*
games/mus | midi
case *audio/x-voc*
audio/vocdec
case *pls*
awk 'BEGIN {FS="="} /^File/{print $2}' | play1 list plain
case *

View file

@ -1,6 +1,6 @@
.TH AUDIO 1
.SH NAME
mp3dec, mp3enc, oggdec, oggenc, flacdec, flacenc, sundec, wavdec, pcmconv, mixfs \- decode and encode audio files
mp3dec, mp3enc, oggdec, oggenc, flacdec, flacenc, sundec, wavdec, vocdec, pcmconv, mixfs \- decode and encode audio files
.SH SYNOPSIS
.B audio/mp3dec
[
@ -29,6 +29,8 @@ mp3dec, mp3enc, oggdec, oggenc, flacdec, flacenc, sundec, wavdec, pcmconv, mixfs
]
.br
.B audio/sundec
.br
.B audio/vocdec
.PP
.B audio/oggenc
.br

View file

@ -1,7 +1,7 @@
</$objtype/mkfile
LIBS=libogg libvorbis libFLAC libtags
PROGS=pcmconv oggdec oggenc mp3dec mp3enc flacdec flacenc wavdec sundec mixfs readtags zuke scream
PROGS=pcmconv oggdec oggenc mp3dec mp3enc flacdec flacenc wavdec sundec vocdec mixfs readtags zuke scream
#libs must be made first
DIRS=$LIBS $PROGS

View file

@ -0,0 +1,8 @@
</$objtype/mkfile
<../config
OFILES=vocdec.$O
TARG=vocdec
</sys/src/cmd/mkone

View file

@ -0,0 +1,136 @@
#include <u.h>
#include <libc.h>
uchar
get(void)
{
uchar b;
if(read(0, &b, 1) != 1)
sysfatal("read: %r");
return b;
}
uint
get2(void)
{
uchar b[2];
if(readn(0, b, 2) != 2)
sysfatal("read: %r");
return (b[0]<<0) | (b[1]<<8);
}
uint
get3(void)
{
uchar b[3];
if(readn(0, b, 3) != 3)
sysfatal("read: %r");
return (b[0]<<0) | (b[1]<<8) | (b[2]<<16);
}
uint
get4(void)
{
uchar b[4];
if(readn(0, b, 4) != 4)
sysfatal("read: %r");
return (b[0]<<0) | (b[1]<<8) | (b[2]<<16) | (b[3]<<24);
}
typedef struct Block Block;
struct Block {
uchar type;
uint size;
uint freq;
uint codec;
uchar chan;
uint bits;
};
char*
codec(int c)
{
switch(c){
case 0x00:
return "u8";
case 0x04:
return "s16";
case 0x06:
return "µ8";
case 0x07:
return "a8";
default:
sysfatal("unsupported");
}
return nil;
}
void
usage(void)
{
fprint(2, "usage: %s", argv0);
exits("usage");
}
void
main(int argc, char **argv)
{
Block b;
uchar buf[20];
char fmt[32], size[32];
ushort chksum, ver;
ARGBEGIN{
default:
usage();
break;
}ARGEND;
if(readn(0, buf, 20) != 20 || memcmp(buf, "Creative Voice File\x1a", 20) != 0)
sysfatal("not a voc file");
get2(); /* gulp */
ver = get2();
chksum = get2();
if(~ver + 0x1234 != chksum)
sysfatal("invalid checksum");
for(;;){
b.type = get();
if(b.type == 0)
break;
b.size = get3();
switch(b.type){
case 1:
b.freq = 1000000 / (256 - get());
b.codec = get();
b.chan = 1;
b.size -= 2;
break;
case 9:
b.freq = get4();
b.bits = get();
b.chan = get();
b.codec = get2();
get(); /* reserved */
b.size -= 4+1+1+2+1;
break;
default:
sysfatal("unsupported blocktype");
break;
}
snprint(fmt, sizeof fmt, "%sc%dr%d", codec(b.codec), b.chan, b.freq);
snprint(size, sizeof size, "%d", b.size);
if(fork() == 0){
execl("/bin/audio/pcmconv", "pcmconv", "-i", fmt, "-l", size, nil);
sysfatal("exec: %r");
}
waitpid();
}
}

View file

@ -913,7 +913,7 @@ struct FILE_STRING
"Extended module: ", "XM audio", 17, "audio/xm",
"MThd", "midi audio", 4, "audio/midi",
"MUS\x1a", "mus audio", 4, "audio/mus",
"Creative Voice File\x1a\x1a", "voc audio", 22, "auxio/x-voc",
"Creative Voice File\x1a", "voc audio", 20, "audio/x-voc",
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\x00\x00\x00\xbb\x11\x22\x00\x44\xff\xff\xff\xff\xff\xff\xff\xff"