/*
 *
 *  Bluetooth low-complexity, subband codec (SBC) library
 *
 *  Copyright (C) 2004-2008  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 <stdint.h>
#include <string.h>
#include <libgen.h>

#if __BYTE_ORDER == __LITTLE_ENDIAN
struct sbc_frame_hdr {
	uint8_t syncword:8;		/* Sync word */
	uint8_t subbands:1;		/* Subbands */
	uint8_t allocation_method:1;	/* Allocation method */
	uint8_t channel_mode:2;		/* Channel mode */
	uint8_t blocks:2;		/* Blocks */
	uint8_t sampling_frequency:2;	/* Sampling frequency */
	uint8_t bitpool:8;		/* Bitpool */
	uint8_t crc_check:8;		/* CRC check */
} __attribute__ ((packed));
#elif __BYTE_ORDER == __BIG_ENDIAN
struct sbc_frame_hdr {
	uint8_t syncword:8;		/* Sync word */
	uint8_t sampling_frequency:2;	/* Sampling frequency */
	uint8_t blocks:2;		/* Blocks */
	uint8_t channel_mode:2;		/* Channel mode */
	uint8_t allocation_method:1;	/* Allocation method */
	uint8_t subbands:1;		/* Subbands */
	uint8_t bitpool:8;		/* Bitpool */
	uint8_t crc_check:8;		/* CRC check */
} __attribute__ ((packed));
#else
#error "Unknown byte order"
#endif

static int calc_frame_len(struct sbc_frame_hdr *hdr)
{
	int tmp, nrof_subbands, nrof_blocks;

	nrof_subbands = (hdr->subbands + 1) * 4;
	nrof_blocks = (hdr->blocks + 1) * 4;

	switch (hdr->channel_mode) {
	case 0x00:
		nrof_subbands /= 2;
		tmp = nrof_blocks * hdr->bitpool;
		break;
	case 0x01:
		tmp = nrof_blocks * hdr->bitpool * 2;
		break;
	case 0x02:
		tmp = nrof_blocks * hdr->bitpool;
		break;
	case 0x03:
		tmp = nrof_blocks * hdr->bitpool + nrof_subbands;
		break;
	default:
		return 0;
	}

	return (nrof_subbands + ((tmp + 7) / 8));
}

static double calc_bit_rate(struct sbc_frame_hdr *hdr)
{
	int nrof_subbands, nrof_blocks;
	double f;

	nrof_subbands = (hdr->subbands + 1) * 4;
	nrof_blocks = (hdr->blocks + 1) * 4;

	switch (hdr->sampling_frequency) {
	case 0:
		f = 16;
		break;
	case 1:
		f = 32;
		break;
	case 2:
		f = 44.1;
		break;
	case 3:
		f = 48;
		break;
	default:
		return 0;
	}

	return ((8 * (calc_frame_len(hdr) + 4) * f) /
			(nrof_subbands * nrof_blocks));
}

static char *freq2str(uint8_t freq)
{
	switch (freq) {
	case 0:
		return "16 kHz";
	case 1:
		return "32 kHz";
	case 2:
		return "44.1 kHz";
	case 3:
		return "48 kHz";
	default:
		return "Unknown";
	}
}

static char *mode2str(uint8_t mode)
{
	switch (mode) {
	case 0:
		return "Mono";
	case 1:
		return "Dual Channel";
	case 2:
		return "Stereo";
	case 3:
		return "Joint Stereo";
	default:
		return "Unknown";
	}
}

static ssize_t __read(int fd, void *buf, size_t count)
{
	ssize_t len, pos = 0;

	while (count > 0) {
		len = read(fd, buf + pos, count);
		if (len <= 0)
			return len;

		count -= len;
		pos   += len;
	}

	return pos;
}

#define SIZE 32

static int analyze_file(char *filename)
{
	struct sbc_frame_hdr hdr;
	unsigned char buf[64];
	double rate;
	int bitpool[SIZE], frame_len[SIZE];
	int subbands, blocks, freq, mode, method;
	int n, p1, p2, fd, len, size, count, num;

	if (strcmp(filename, "-")) {
		printf("Filename\t\t%s\n", basename(filename));

		fd = open(filename, O_RDONLY);
		if (fd < 0) {
			perror("Can't open file");
			return -1;
		}
	} else
		fd = fileno(stdin);

	len = __read(fd, &hdr, sizeof(hdr));
	if (len != sizeof(hdr) || hdr.syncword != 0x9c) {
		fprintf(stderr, "Not a SBC audio file\n");
		return -1;
	}

	subbands = (hdr.subbands + 1) * 4;
	blocks = (hdr.blocks + 1) * 4;
	freq = hdr.sampling_frequency;
	mode = hdr.channel_mode;
	method = hdr.allocation_method;

	count = calc_frame_len(&hdr);

	bitpool[0] = hdr.bitpool;
	frame_len[0] = count + 4;

	for (n = 1; n < SIZE; n++) {
		bitpool[n] = 0;
		frame_len[n] = 0;
	}

	if (lseek(fd, 0, SEEK_SET) < 0) {
		num = 1;
		rate = calc_bit_rate(&hdr);
		while (count) {
			size = count > sizeof(buf) ? sizeof(buf) : count;
			len = __read(fd, buf, size);
			if (len < 0)
				break;
			count -= len;
		}
	} else {
		num = 0;
		rate = 0;
	}

	while (1) {
		len = __read(fd, &hdr, sizeof(hdr));
		if (len < 0) {
			fprintf(stderr, "Unable to read frame header"
					" (error %d)\n", errno);
			break;
		}

		if (len == 0)
			break;

		if (len < sizeof(hdr) || hdr.syncword != 0x9c) {
			fprintf(stderr, "Corrupted SBC stream "
					"(len %d syncword 0x%02x)\n",
					len, hdr.syncword);
			break;
		}

		count = calc_frame_len(&hdr);
		len = count + 4;

		p1 = -1;
		p2 = -1;
		for (n = 0; n < SIZE; n++) {
			if (p1 < 0 && (bitpool[n] == 0 || bitpool[n] == hdr.bitpool))
				p1 = n;
			if (p2 < 0 && (frame_len[n] == 0 || frame_len[n] == len))
				p2 = n;
		}
		if (p1 >= 0)
			bitpool[p1] = hdr.bitpool;
		if (p2 >= 0)
			frame_len[p2] = len;

		while (count) {
			size = count > sizeof(buf) ? sizeof(buf) : count;

			len = __read(fd, buf, size);
			if (len != size) {
				fprintf(stderr, "Unable to read frame data "
						"(error %d)\n", errno);
				break;
			}

			count -= len;
		}

		rate += calc_bit_rate(&hdr);
		num++;
	}

	printf("Subbands\t\t%d\n", subbands);
	printf("Block length\t\t%d\n", blocks);
	printf("Sampling frequency\t%s\n", freq2str(freq));
	printf("Channel mode\t\t%s\n", mode2str(hdr.channel_mode));
	printf("Allocation method\t%s\n", method ? "SNR" : "Loudness");
	printf("Bitpool\t\t\t%d", bitpool[0]);
	for (n = 1; n < SIZE; n++)
		if (bitpool[n] > 0)
			printf(", %d", bitpool[n]);
	printf("\n");
	printf("Number of frames\t%d\n", num);
	printf("Frame length\t\t%d", frame_len[0]);
	for (n = 1; n < SIZE; n++)
		if (frame_len[n] > 0)
			printf(", %d", frame_len[n]);
	printf(" Bytes\n");
	if (num > 0)
		printf("Bit rate\t\t%.3f kbps\n", rate / num);

	if (fd > fileno(stderr))
		close(fd);

	printf("\n");

	return 0;
}

int main(int argc, char *argv[])
{
	int i;

	if (argc < 2) {
		fprintf(stderr, "Usage: sbcinfo <file>\n");
		exit(1);
	}

	for (i = 0; i < argc - 1; i++)
		if (analyze_file(argv[i + 1]) < 0)
			exit(1);

	return 0;
}
