/*
 *
 *  Bluetooth low-complexity, subband codec (SBC) decoder
 *
 *  Copyright (C) 2004-2007  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>

#include "sbc.h"

#define BUF_SIZE 8192

static void decode(char *filename, char *audiodevice, int tofile)
{
	unsigned char buf[BUF_SIZE], *stream;
	struct stat st;
	off_t filesize;
	sbc_t sbc;
	int fd, ad, pos, streamlen, framelen, count, written, format = AFMT_S16_BE;

	if (stat(filename, &st) < 0) {
		fprintf(stderr, "Can't get size of file %s: %s\n",
						filename, strerror(errno));
		return;
	}

	filesize = st.st_size;
	stream = malloc(st.st_size);

	if (!stream) {
		fprintf(stderr, "Can't allocate memory for %s: %s\n",
						filename, strerror(errno));
		return;
	}

	fd = open(filename, O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "Can't open file %s: %s\n",
						filename, strerror(errno));
		goto free;
	}

	if (read(fd, stream, st.st_size) != st.st_size) {
		fprintf(stderr, "Can't read content of %s: %s\n",
						filename, strerror(errno));
		close(fd);
		goto free;
	}

	close(fd);

	pos = 0;
	streamlen = st.st_size;

	ad = open(audiodevice, O_WRONLY | (tofile ? (O_CREAT | O_TRUNC) : 0), tofile ? 0644 : 0);
	if (ad < 0) {
		fprintf(stderr, "Can't open audio device %s: %s\n",
						audiodevice, strerror(errno));
		goto free;
	}

	sbc_init(&sbc, 0L);

	framelen = sbc_decode(&sbc, stream, streamlen);
	printf("%d Hz, %d channels\n", sbc.rate, sbc.channels);
	if (!tofile) {
		if (ioctl(ad, SNDCTL_DSP_SETFMT, &format) < 0) {
			fprintf(stderr, "Can't set audio format on %s: %s\n",
							audiodevice, strerror(errno));
			goto close;
		}
		if (ioctl(ad, SNDCTL_DSP_CHANNELS, &sbc.channels) < 0) {
			fprintf(stderr, "Can't set number of channels on %s: %s\n",
							audiodevice, strerror(errno));
			goto close;
		}

		if (ioctl(ad, SNDCTL_DSP_SPEED, &sbc.rate) < 0) {
			fprintf(stderr, "Can't set audio rate on %s: %s\n",
							audiodevice, strerror(errno));
			goto close;
		}
	}

	count = 0;
	while (framelen > 0) {
		// we have completed an sbc_decode at this point
		// sbc.len is the length of the frame we just decoded
		// count is the number of decoded bytes yet to be written

		if (count + sbc.len > BUF_SIZE) {
			// buffer is too full to stuff decoded audio in
			// so it must be written to the device
			written = write(ad, buf, count);
			if (written > 0)
				count -= written;
		}

		// sanity check
		if (count + sbc.len > BUF_SIZE) {
			fprintf(stderr, "buffer size of %d is too small for decoded data (%d)\n", BUF_SIZE, sbc.len + count);
			exit(1);
		}

		// move the latest decoded data into buf and increase the count
		memcpy(buf + count, sbc.data, sbc.len);
		count += sbc.len;

		// push the pointer in the file forward to the next bit to be decoded
		// tell the decoder to decode up to the remaining length of the file (!)
		pos += framelen;
		framelen = sbc_decode(&sbc, stream + pos, streamlen - pos);
	}

	if (count > 0) {
		written = write(ad, buf, count);
		if (written > 0)
			count -= written;
	}

close:
	sbc_finish(&sbc);

	close(ad);

free:
	free(stream);
}

static void usage(void)
{
	printf("SBC decoder utility ver %s\n", VERSION);
	printf("Copyright (c) 2004  Marcel Holtmann\n\n");

	printf("Usage:\n"
		"\tsbcdec [options] file(s)\n"
		"\n");

	printf("Options:\n"
		"\t-h, --help           Display help\n"
		"\t-d, --device <dsp>   Sound device\n"
		"\t-v, --verbose        Verbose mode\n"
		"\t-f, --file           Decode to a file\n"
		"\n");
}

static struct option main_options[] = {
	{ "help",	0, 0, 'h' },
	{ "device",	1, 0, 'd' },
	{ "verbose",	0, 0, 'v' },
	{ "file",	1, 0, 'f' },
	{ 0, 0, 0, 0 }
};

int main(int argc, char *argv[])
{
	char *device = NULL;
	char *file = NULL;
	int i, opt, verbose = 0, tofile = 0;

	while ((opt = getopt_long(argc, argv, "+hd:vf:", main_options, NULL)) != -1) {
		switch(opt) {
		case 'h':
			usage();
			exit(0);

		case 'd':
			device = strdup(optarg);
			break;

		case 'v':
			verbose = 1;
			break;
		case 'f' :
			file = strdup(optarg);
			tofile = 1;
			break;

		default:
			exit(1);
		}
	}

	argc -= optind;
	argv += optind;
	optind = 0;

	if (argc < 1) {
		usage();
		exit(1);
	}

	for (i = 0; i < argc; i++)
		decode(argv[i], device ? device : file ? file : "/dev/dsp", tofile);

	if (device)
		free(device);

	return 0;
}
