/*
 *
 *  Bluetooth low-complexity, subband codec (SBC) library
 *
 *  Copyright (C) 2004-2009  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, num;
	unsigned int count;

	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 < (int) 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;
}
