Sigrid Solveig Haflínudóttirupdate plan 9 build4a953463 years agoHistory
217 lines · 5.1 KB · C
RawDownload
/*** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program 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 General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.**** Any non-GPL usage of this software or parts of this software is strictly** forbidden.**** The "appropriate copyright message" mentioned in section 2c of the GPLv2** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"**** Commercial non-GPL licensing of this software is possible.** For more info contact Nero AG through Mpeg4AAClicense@nero.com.**** $Id: main.c,v 1.89 2015/01/19 09:46:12 knik Exp $**/ #include <u.h>#include <libc.h>#include <bio.h>#include <neaacdec.h> #define min(a,b) ((a)<=(b)?(a):(b)) #define MAX_CHANNELS 6 /* make this higher to support files with more channels */ /* FAAD file buffering routines */typedef struct {	long bytes_into_buffer;	long bytes_consumed;	long file_offset;	unsigned char *buffer;	int at_eof;}aac_buffer; static Biobuf stdin, stdout; static intfill_buffer(aac_buffer *b){	int bread; 	if(b->bytes_consumed > 0){		if(b->bytes_into_buffer)			memmove(b->buffer, b->buffer + b->bytes_consumed, b->bytes_into_buffer); 		if(!b->at_eof){			bread = Bread(&stdin, (void*)(b->buffer + b->bytes_into_buffer), b->bytes_consumed);			if(bread != b->bytes_consumed)				b->at_eof = 1;			b->bytes_into_buffer += bread;		} 		b->bytes_consumed = 0; 		if(b->bytes_into_buffer > 3 && memcmp(b->buffer, "TAG", 3) == 0)			b->bytes_into_buffer = 0;		if(b->bytes_into_buffer > 11 && memcmp(b->buffer, "LYRICSBEGIN", 11) == 0)			b->bytes_into_buffer = 0;		if(b->bytes_into_buffer > 8 && memcmp(b->buffer, "APETAGEX", 8) == 0)			b->bytes_into_buffer = 0;	} 	return 1;} static voidadvance_buffer(aac_buffer *b, int bytes){	while(b->bytes_into_buffer > 0 && bytes > 0){		int chunk = min(bytes, b->bytes_into_buffer); 		bytes -= chunk;		b->file_offset += chunk;		b->bytes_consumed = chunk;		b->bytes_into_buffer -= chunk; 		if(b->bytes_into_buffer == 0)			fill_buffer(b);	}} static intdecode(void){	NeAACDecHandle hDecoder;	NeAACDecFrameInfo frameInfo;	NeAACDecConfigurationPtr config;	unsigned long samplerate;	unsigned char channels;	void *sample_buffer;	int bread;	aac_buffer b; 	memset(&b, 0, sizeof(b));	if((b.buffer = malloc(FAAD_MIN_STREAMSIZE*MAX_CHANNELS)) == nil)		return -1;	memset(b.buffer, 0, FAAD_MIN_STREAMSIZE*MAX_CHANNELS); 	bread = Bread(&stdin, b.buffer, FAAD_MIN_STREAMSIZE*MAX_CHANNELS);	b.bytes_into_buffer = bread;	b.bytes_consumed = 0;	b.file_offset = 0; 	if(bread != FAAD_MIN_STREAMSIZE*MAX_CHANNELS)		b.at_eof = 1; 	hDecoder = NeAACDecOpen(); 	config = NeAACDecGetCurrentConfiguration(hDecoder);	config->defSampleRate = 44100;	config->defObjectType = LC;	config->outputFormat = FAAD_FMT_16BIT;	config->downMatrix = 0;	config->useOldADTSFormat = 0;	NeAACDecSetConfiguration(hDecoder, config); 	fill_buffer(&b);	if((bread = NeAACDecInit(hDecoder, b.buffer, b.bytes_into_buffer, &samplerate, &channels)) < 0){		sysfatal("NeAACDecInit failed: %d", bread);		if(b.buffer)			free(b.buffer);		NeAACDecClose(hDecoder);		return -1;	}	advance_buffer(&b, bread);	fill_buffer(&b); 	if(samplerate != 44100 || channels != 2){		int pfd[2], pid;		char fmt[32]; 		pid = -1;		if(pipe(pfd) < 0 || (pid = fork()) < 0)			sysfatal("%r");		if(pid == 0){			dup(pfd[1], 0);			close(pfd[1]);			close(pfd[0]);			snprint(fmt, sizeof(fmt), "s16c%dr%ld", channels, samplerate);			execl("/bin/audio/pcmconv", "pcmconv", "-i", fmt, nil);			sysfatal("%r");		}		close(pfd[1]);		Binit(&stdout, pfd[0], OWRITE);	} 	for(;;){		sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, b.buffer, b.bytes_into_buffer); 		/* update buffer indices */		advance_buffer(&b, frameInfo.bytesconsumed); 		if(frameInfo.error != 0)			sysfatal("%s: %d", NeAACDecGetErrorMessage(frameInfo.error), frameInfo.error); 		if(frameInfo.samples > 0 && Bwrite(&stdout, sample_buffer, frameInfo.samples*2) != frameInfo.samples*2)			break; 		fill_buffer(&b); 		if(b.bytes_into_buffer == 0)			break;	} 	NeAACDecClose(hDecoder); 	if(b.buffer)		free(b.buffer); 	return frameInfo.error;} static voidusage(void){	fprint(2, "usage: %s\n", argv0);	exits("usage");} voidmain(int argc, char **argv){	int n; 	ARGBEGIN{	case 's': /* FIXME seeking isn't implemented yet */		break;	default:		usage();	}ARGEND 	if(argc != 0)		usage(); 	Binit(&stdin, 0, OREAD);	Binit(&stdout, 1, OWRITE); 	n = decode();	Bterm(&stdout);	waitpid(); 	exits(n == 0 ? nil : "failed");}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t