ref: cca5d94e30aec54182ae28141b2ca1915de9e278
dir: /syro.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "korg_syro_volcasample.h" int parsepath(char *spec, char **path, int *id) { int n; char *p, *q; if((p = strchr(spec, ':')) != nil && p != spec){ if((n = strtol(spec, &q, 10)) == 0 || q != p++) goto error; if(n < 0 || n >= VOLCASAMPLE_NUM_OF_SAMPLE) goto error; *id = n; }else p = spec; if(*p == 0) goto error; *path = p; return 0; error: werrstr("invalid format"); return -1; } void usage(void) { fprint(2, "usage: %s [-e] [ID:]FILE [[ID:]FILE..]\n", argv0); exits("usage"); } /* audio/wavdec < in.wav > in.pcm * audio/syro *.pcm >/dev/audio → sync in */ void threadmain(int argc, char **argv) { int pfd[2], type, id; char *path; uchar s[4], *buf; s16int l, r; u32int nf; vlong n, off, nbuf; SyroHandle sh; SyroData dat[VOLCASAMPLE_NUM_OF_SAMPLE], *dp; Biobuf *bf; type = DataType_Sample_Compress; ARGBEGIN{ case 'e': type = DataType_Sample_Erase; break; case 'l': type = DataType_Sample_Liner; break; /* uncompressed? */ default: usage(); }ARGEND if(*argv == nil) usage(); for(dp=dat; *argv!=nil && dp<dat+nelem(dat); dp++, argv++){ id = dp - dat; if(parsepath(*argv, &path, &id) < 0) sysfatal("parsepath: %r"); if(pipe(pfd) < 0) sysfatal("pipe: %r"); if(rfork(RFPROC|RFFDG) == 0){ close(pfd[1]); close(0); if(open(path, OREAD) < 0) sysfatal("open: %r"); dup(pfd[0], 1); close(pfd[0]); execl("/bin/audio/pcmconv", "pcmconv", "-i", "r44100c2s16", "-o", "r31250c1s16", nil); sysfatal("execl: %r"); } close(pfd[0]); off = 0; nbuf = IOUNIT * 4; if((buf = malloc(nbuf)) == nil) sysfatal("malloc: %r"); while((n = readn(pfd[1], buf+off, nbuf-off)) > 0){ off += n; if((buf = realloc(buf, nbuf*2)) == nil) sysfatal("realloc: %r"); nbuf *= 2; } if(n < 0) sysfatal("read: %r"); close(pfd[1]); if((buf = realloc(buf, off)) == nil) sysfatal("realloc: %r"); dp->Size = off; dp->pData = buf; dp->DataType = type; dp->Number = id; dp->Quality = 16; dp->Fs = 31250; dp->SampleEndian = LittleEndian; fprint(2, "[%zd] %s size %lld → sample %d\n", dp-dat, path, off, id); } if((n = SyroVolcaSample_Start(&sh, dat, dp - dat, 0, &nf)) != Status_Success) sysfatal("SyroVolcaSample_Start %lld", n); fprint(2, "%ud total samples, %ud total size\n", nf, nf*4); if((bf = Bfdopen(1, OWRITE)) == nil) sysfatal("Bfdopen: %r"); while(nf-- > 0){ SyroVolcaSample_GetSample(sh, &l, &r); s[0] = l; s[1] = l >> 8; s[2] = r; s[3] = r >> 8; Bwrite(bf, s, sizeof s); } Bterm(bf); SyroVolcaSample_End(sh); exits(nil); }