Blame src/mp3.c

Packit Service 102f81
/* -*- c-basic-offset: 8; -*- */
Packit Service 102f81
/* mp3.c: libshout MP3 format handler
Packit Service 102f81
 * $Id: mp3.c 7259 2004-07-22 18:49:41Z brendan $
Packit Service 102f81
 *
Packit Service 102f81
 *  Copyright (C) 2002-2003 the Icecast team <team@icecast.org>
Packit Service 102f81
 *
Packit Service 102f81
 *  This library is free software; you can redistribute it and/or
Packit Service 102f81
 *  modify it under the terms of the GNU Library General Public
Packit Service 102f81
 *  License as published by the Free Software Foundation; either
Packit Service 102f81
 *  version 2 of the License, or (at your option) any later version.
Packit Service 102f81
 *
Packit Service 102f81
 *  This library is distributed in the hope that it will be useful,
Packit Service 102f81
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 102f81
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 102f81
 *  Library General Public License for more details.
Packit Service 102f81
 *
Packit Service 102f81
 *  You should have received a copy of the GNU Library General Public
Packit Service 102f81
 *  License along with this library; if not, write to the Free
Packit Service 102f81
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit Service 102f81
 */
Packit Service 102f81
Packit Service 102f81
#include <stdio.h>
Packit Service 102f81
#include <stdlib.h>
Packit Service 102f81
#include <string.h>
Packit Service 102f81
Packit Service 102f81
#include <shout/shout.h>
Packit Service 102f81
#include "shout_private.h"
Packit Service 102f81
Packit Service 102f81
/*
Packit Service 102f81
 * MP3 frame handling courtesy of Scott Manley - may he always be Manley.
Packit Service 102f81
 */
Packit Service 102f81
Packit Service 102f81
#define MPEG_MODE_MONO 3
Packit Service 102f81
Packit Service 102f81
/* -- local datatypes -- */
Packit Service 102f81
typedef struct {
Packit Service 102f81
	unsigned int frames;
Packit Service 102f81
	/* the number of samples for the current frame */
Packit Service 102f81
	int frame_samples;
Packit Service 102f81
	/* the samplerate of the current frame */
Packit Service 102f81
	int frame_samplerate;
Packit Service 102f81
	/* how many bytes for the rest of this frame */
Packit Service 102f81
	unsigned int frame_left;
Packit Service 102f81
	/* is the header bridged?? */
Packit Service 102f81
	int header_bridges;
Packit Service 102f81
	/* put part of header here if it spans a boundary */
Packit Service 102f81
	unsigned char header_bridge[3];
Packit Service 102f81
} mp3_data_t;
Packit Service 102f81
Packit Service 102f81
typedef struct {
Packit Service 102f81
	int syncword;
Packit Service 102f81
	int layer;
Packit Service 102f81
	int version;
Packit Service 102f81
	int error_protection;
Packit Service 102f81
	int bitrate_index;
Packit Service 102f81
	int samplerate_index;
Packit Service 102f81
	int padding;
Packit Service 102f81
	int extension;
Packit Service 102f81
	int mode;
Packit Service 102f81
	int mode_ext;
Packit Service 102f81
	int copyright;
Packit Service 102f81
	int original;
Packit Service 102f81
	int emphasis;
Packit Service 102f81
	int stereo;
Packit Service 102f81
	int bitrate;
Packit Service 102f81
	unsigned int samplerate;
Packit Service 102f81
	unsigned int samples;
Packit Service 102f81
	unsigned int framesize;
Packit Service 102f81
} mp3_header_t;
Packit Service 102f81
Packit Service 102f81
/* -- const data -- */
Packit Service 102f81
static const unsigned int bitrate[3][3][16] =
Packit Service 102f81
{
Packit Service 102f81
	{
Packit Service 102f81
		{ 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0 },
Packit Service 102f81
		{ 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0 },
Packit Service 102f81
		{ 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 }
Packit Service 102f81
	}, {
Packit Service 102f81
		{ 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 },
Packit Service 102f81
		{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 },
Packit Service 102f81
		{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }
Packit Service 102f81
	}, {
Packit Service 102f81
		{ 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 },
Packit Service 102f81
		{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 },
Packit Service 102f81
		{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }
Packit Service 102f81
	}
Packit Service 102f81
};
Packit Service 102f81
Packit Service 102f81
static const unsigned int samplerate[3][4] =
Packit Service 102f81
{
Packit Service 102f81
	{ 44100, 48000, 32000, 0 },
Packit Service 102f81
	{ 22050, 24000, 16000, 0 },
Packit Service 102f81
	{ 11025, 8000, 8000, 0 }
Packit Service 102f81
};
Packit Service 102f81
Packit Service 102f81
/* -- static prototypes -- */
Packit Service 102f81
static int send_mp3(shout_t *self, const unsigned char *data, size_t len);
Packit Service 102f81
static void close_mp3(shout_t *self);
Packit Service 102f81
Packit Service 102f81
static void parse_header(mp3_header_t *mh, uint32_t header);
Packit Service 102f81
static int mp3_header(uint32_t head, mp3_header_t *mh);
Packit Service 102f81
Packit Service 102f81
int shout_open_mp3(shout_t *self)
Packit Service 102f81
{
Packit Service 102f81
	mp3_data_t *mp3_data;
Packit Service 102f81
Packit Service 102f81
	if (!(mp3_data = (mp3_data_t *)calloc(1, sizeof(mp3_data_t))))
Packit Service 102f81
		return SHOUTERR_MALLOC;
Packit Service 102f81
	self->format_data = mp3_data;
Packit Service 102f81
Packit Service 102f81
	self->send = send_mp3;
Packit Service 102f81
	self->close = close_mp3;
Packit Service 102f81
Packit Service 102f81
	return SHOUTERR_SUCCESS;
Packit Service 102f81
}
Packit Service 102f81
Packit Service 102f81
static int send_mp3(shout_t* self, const unsigned char* buff, size_t len)
Packit Service 102f81
{
Packit Service 102f81
	mp3_data_t* mp3_data = (mp3_data_t*) self->format_data;
Packit Service 102f81
	unsigned long pos;
Packit Service 102f81
	uint32_t head;
Packit Service 102f81
	int ret, count;
Packit Service 102f81
	int start, end, error, i;
Packit Service 102f81
	unsigned char *bridge_buff;
Packit Service 102f81
	mp3_header_t mh;
Packit Service 102f81
Packit Service 102f81
	bridge_buff = NULL;
Packit Service 102f81
	pos = 0;
Packit Service 102f81
	start = 0;
Packit Service 102f81
	error = 0;
Packit Service 102f81
	end = len - 1;
Packit Service 102f81
	memset(&mh, 0, sizeof(mh));
Packit Service 102f81
Packit Service 102f81
	/* finish the previous frame */
Packit Service 102f81
	if (mp3_data->frame_left > 0) {
Packit Service 102f81
		/* is the rest of the frame here? */
Packit Service 102f81
		if (mp3_data->frame_left <= len) {
Packit Service 102f81
			self->senttime += (int64_t)((double)mp3_data->frame_samples / (double)mp3_data->frame_samplerate * 1000000);
Packit Service 102f81
			mp3_data->frames++;
Packit Service 102f81
			pos += mp3_data->frame_left;
Packit Service 102f81
			mp3_data->frame_left = 0;
Packit Service 102f81
		} else {
Packit Service 102f81
			mp3_data->frame_left -= len;
Packit Service 102f81
			pos = len;
Packit Service 102f81
		}
Packit Service 102f81
	}
Packit Service 102f81
Packit Service 102f81
	/* header was over the boundary, so build a new build a new buffer */
Packit Service 102f81
	if (mp3_data->header_bridges) {
Packit Service 102f81
		bridge_buff = (unsigned char *)malloc(len + mp3_data->header_bridges);
Packit Service 102f81
		if (bridge_buff == NULL) {
Packit Service 102f81
			return self->error = SHOUTERR_MALLOC;
Packit Service 102f81
		}
Packit Service 102f81
Packit Service 102f81
		bridge_buff[0] = mp3_data->header_bridge[0];
Packit Service 102f81
		bridge_buff[1] = mp3_data->header_bridge[1];
Packit Service 102f81
		bridge_buff[2] = mp3_data->header_bridge[2];
Packit Service 102f81
Packit Service 102f81
		memcpy(&bridge_buff[mp3_data->header_bridges], buff, len);
Packit Service 102f81
Packit Service 102f81
		buff = bridge_buff;
Packit Service 102f81
		len += mp3_data->header_bridges;
Packit Service 102f81
		end = len - 1;
Packit Service 102f81
Packit Service 102f81
		mp3_data->header_bridges = 0;
Packit Service 102f81
	}
Packit Service 102f81
Packit Service 102f81
	/** this is the main loop
Packit Service 102f81
	*** we handle everything but the last 4 bytes...
Packit Service 102f81
	**/
Packit Service 102f81
	while ((pos + 4) <= len) {
Packit Service 102f81
		/* find mp3 header */
Packit Service 102f81
		head = (buff[pos] << 24) | 
Packit Service 102f81
			(buff[pos + 1] << 16) |
Packit Service 102f81
			(buff[pos + 2] << 8) |
Packit Service 102f81
			(buff[pos + 3]);
Packit Service 102f81
Packit Service 102f81
		/* is this a valid header? */
Packit Service 102f81
		if (mp3_header(head, &mh)) {
Packit Service 102f81
			if (error) {
Packit Service 102f81
				start = pos;
Packit Service 102f81
				end = len - 1;
Packit Service 102f81
				error = 0;
Packit Service 102f81
			}
Packit Service 102f81
Packit Service 102f81
			mp3_data->frame_samples = mh.samples;
Packit Service 102f81
			mp3_data->frame_samplerate = mh.samplerate;
Packit Service 102f81
Packit Service 102f81
			/* do we have a complete frame in this buffer? */
Packit Service 102f81
			if (len - pos >= mh.framesize) {
Packit Service 102f81
				self->senttime += (int64_t)((double)mp3_data->frame_samples / (double)mp3_data->frame_samplerate * 1000000);
Packit Service 102f81
				mp3_data->frames++;
Packit Service 102f81
				pos += mh.framesize;
Packit Service 102f81
			} else {
Packit Service 102f81
				mp3_data->frame_left = mh.framesize - (len - pos);
Packit Service 102f81
				pos = len;
Packit Service 102f81
			}
Packit Service 102f81
		} else {
Packit Service 102f81
			/* there was an error
Packit Service 102f81
			** so we send all the valid data up to this point 
Packit Service 102f81
			*/
Packit Service 102f81
			if (!error) {
Packit Service 102f81
				error = 1;
Packit Service 102f81
				end = pos - 1;
Packit Service 102f81
				count = end - start + 1;
Packit Service 102f81
				if (count > 0)
Packit Service 102f81
					ret = shout_send_raw(self, (char *)&buff[start], count);
Packit Service 102f81
				else
Packit Service 102f81
					ret = 0;
Packit Service 102f81
Packit Service 102f81
				if (ret != count) {
Packit Service 102f81
					if (bridge_buff != NULL)
Packit Service 102f81
						free(bridge_buff);
Packit Service 102f81
					return self->error = SHOUTERR_SOCKET;
Packit Service 102f81
				}
Packit Service 102f81
			}
Packit Service 102f81
			pos++;
Packit Service 102f81
		}
Packit Service 102f81
	}
Packit Service 102f81
Packit Service 102f81
	/* catch the tail if there is one */
Packit Service 102f81
	if ((pos > (len - 4)) && (pos < len)) {
Packit Service 102f81
		end = pos - 1;
Packit Service 102f81
Packit Service 102f81
		i = 0;
Packit Service 102f81
		while (pos < len) {
Packit Service 102f81
			mp3_data->header_bridge[i] = buff[pos];
Packit Service 102f81
			pos++;
Packit Service 102f81
			i++;
Packit Service 102f81
		} 
Packit Service 102f81
		mp3_data->header_bridges = i;
Packit Service 102f81
	}
Packit Service 102f81
Packit Service 102f81
	if (!error) {
Packit Service 102f81
		/* if there's no errors, lets send the frames */
Packit Service 102f81
		count = end - start + 1;
Packit Service 102f81
		if (count > 0)
Packit Service 102f81
			ret = shout_send_raw(self, (char *)&buff[start], count);
Packit Service 102f81
		else
Packit Service 102f81
			ret = 0;
Packit Service 102f81
Packit Service 102f81
		if (bridge_buff != NULL)
Packit Service 102f81
			free(bridge_buff);
Packit Service 102f81
Packit Service 102f81
		if (ret == count) {
Packit Service 102f81
			return self->error = SHOUTERR_SUCCESS;
Packit Service 102f81
		} else {
Packit Service 102f81
			return self->error = SHOUTERR_SOCKET;
Packit Service 102f81
		}
Packit Service 102f81
	}
Packit Service 102f81
Packit Service 102f81
	if (bridge_buff != NULL)
Packit Service 102f81
		free(bridge_buff);
Packit Service 102f81
Packit Service 102f81
	return self->error = SHOUTERR_SUCCESS;
Packit Service 102f81
}
Packit Service 102f81
Packit Service 102f81
static void parse_header(mp3_header_t *mh, uint32_t header)
Packit Service 102f81
{
Packit Service 102f81
	mh->syncword = (header >> 20) & 0x0fff;
Packit Service 102f81
	mh->version = ((header >> 19) & 0x01) ? 0 : 1;
Packit Service 102f81
	if ((mh->syncword & 0x01) == 0)
Packit Service 102f81
		mh->version = 2;
Packit Service 102f81
	mh->layer = 3 - ((header >> 17) & 0x03);
Packit Service 102f81
	mh->error_protection = ((header >> 16) & 0x01) ? 0 : 1;
Packit Service 102f81
	mh->bitrate_index = (header >> 12) & 0x0F;
Packit Service 102f81
	mh->samplerate_index = (header >> 10) & 0x03;
Packit Service 102f81
	mh->padding = (header >> 9) & 0x01;
Packit Service 102f81
	mh->extension = (header >> 8) & 0x01;
Packit Service 102f81
	mh->mode = (header >> 6) & 0x03;
Packit Service 102f81
	mh->mode_ext = (header >> 4) & 0x03;
Packit Service 102f81
	mh->copyright = (header >> 3) & 0x01;
Packit Service 102f81
	mh->original = (header >> 2) & 0x01;
Packit Service 102f81
	mh->emphasis = header & 0x03;
Packit Service 102f81
Packit Service 102f81
	mh->stereo = (mh->mode == MPEG_MODE_MONO) ? 1 : 2;
Packit Service 102f81
	mh->bitrate = bitrate[mh->version][mh->layer][mh->bitrate_index];
Packit Service 102f81
	mh->samplerate = samplerate[mh->version][mh->samplerate_index];
Packit Service 102f81
Packit Service 102f81
	if (mh->version == 0)
Packit Service 102f81
		mh->samples = 1152;
Packit Service 102f81
	else
Packit Service 102f81
		mh->samples = 576;
Packit Service 102f81
Packit Service 102f81
	if(mh->samplerate)
Packit Service 102f81
		mh->framesize = (mh->samples * mh->bitrate * 1000 / mh->samplerate) / 8 + mh->padding;
Packit Service 102f81
}
Packit Service 102f81
Packit Service 102f81
/* mp3 frame parsing stuff */
Packit Service 102f81
static int mp3_header(uint32_t head, mp3_header_t *mh)
Packit Service 102f81
{
Packit Service 102f81
	/* fill out the header struct */
Packit Service 102f81
	parse_header(mh, head);
Packit Service 102f81
Packit Service 102f81
	/* check for syncword */
Packit Service 102f81
	if ((mh->syncword & 0x0ffe) != 0x0ffe)
Packit Service 102f81
		return 0;
Packit Service 102f81
Packit Service 102f81
	/* check for the right layer */
Packit Service 102f81
	if (mh->layer != 2)
Packit Service 102f81
		return 0;
Packit Service 102f81
Packit Service 102f81
	/* make sure bitrate is sane */
Packit Service 102f81
	if (mh->bitrate == 0)
Packit Service 102f81
		return 0;
Packit Service 102f81
Packit Service 102f81
	/* make sure samplerate is sane */
Packit Service 102f81
	if (mh->samplerate == 0)
Packit Service 102f81
		return 0;
Packit Service 102f81
Packit Service 102f81
	return 1;
Packit Service 102f81
}
Packit Service 102f81
Packit Service 102f81
static void close_mp3(shout_t *self)
Packit Service 102f81
{
Packit Service 102f81
	mp3_data_t *mp3_data = (mp3_data_t *)self->format_data;
Packit Service 102f81
Packit Service 102f81
	free(mp3_data);
Packit Service 102f81
}