ref: 71bcced2e52c711bf56e1afb6bb9899e0dcfa843
dir: /frontend/aacenc.c/
/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2001 Menno Bakker * Copyright (C) 2002-2017 Krzysztof Nikiel * Copyright (C) 2004 Dan Villiom P. Christiansen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include <u.h> #include <libc.h> #include <bio.h> #include <faac.h> static Biobuf out; static int done(void*, char*) { Bflush(&out); return 0; } static void usage(void) { fprint(2, "usage: %s [-b] [-c CHAN] [-q QUANT] [-r RATE] [-t low|main|ltp] [-B BITRATE]\n", argv0); exits("usage"); } void main(int argc, char **argv) { int nch, srate, type, brate, sz, n, r, q, nobuffer; ulong insamples, outsz, insz; faacEncConfigurationPtr fmt; faacEncHandle e; u8int *obuf; s16int *pcm; Biobuf in; char *s; nobuffer = 0; brate = 0; srate = 44100; nch = 2; type = LOW; q = 0; ARGBEGIN{ case 'b': nobuffer = 1; break; case 'B': if((brate = atoi(EARGF(usage()))) < 0) sysfatal("invalid bitrate %d", brate); break; case 'c': if((nch = atoi(EARGF(usage()))) < 1 || nch > 64) sysfatal("invalid number of channels %d", nch); break; case 'r': if((srate = atoi(EARGF(usage()))) < 1) sysfatal("invalid samplerate %d", srate); break; case 'q': if((q = atoi(EARGF(usage()))) < 1) sysfatal("invalid quantization quality %d", q); break; case 't': s = EARGF(usage()); if(cistrcmp(s, "low") == 0) type = LOW; else if(cistrcmp(s, "main") == 0) type = MAIN; else if(cistrcmp(s, "ltp") == 0) type = LTP; else sysfatal("invalid type %s", s); break; default: usage(); }ARGEND if(argc != 0) usage(); if(Binit(&in, 0, OREAD) != 0 || Binit(&out, 1, OWRITE) != 0) sysfatal("io init failed"); setfcr(getfcr() & ~(FPINVAL|FPOVFL)); if((e = faacEncOpen(srate, nch, &insamples, &outsz)) == nil) sysfatal("faacEncOpen"); insz = insamples * sizeof(*pcm); if((pcm = malloc(insz)) == nil) sysfatal("memory"); if((obuf = malloc(outsz + 32)) == nil) /* a bit extra for DSE */ sysfatal("memory"); fmt = faacEncGetCurrentConfiguration(e); fmt->inputFormat = FAAC_INPUT_16BIT; fmt->mpegVersion = MPEG2; fmt->outputFormat = ADTS_STREAM; fmt->aacObjectType = type; if(brate > 0) fmt->bitRate = brate / nch; if(q > 0) fmt->quantqual = q; if(!faacEncSetConfiguration(e, fmt)) sysfatal("invalid encoder configuration"); atnotify(done, 1); for(;;){ for(n = 0; n == 0 || (n & (sizeof(*pcm)-1)) != 0; n += r){ if((r = Bread(&in, pcm+n, insz-n)) < 0) sysfatal("read: %r"); if(r == 0) break; } if(n == 0) break; if((sz = faacEncEncode(e, pcm, n/sizeof(*pcm), obuf, outsz)) < 0) sysfatal("faacEncEncode"); else if(sz == 0) continue; n = Bwrite(&out, obuf, sz); if((nobuffer && Bflush(&out) < 0) || n != sz) break; } Bflush(&out); exits(nil); }