⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp3play.c

📁 Application (fix point) for playing MP3 data on embedded systems. mp3play is designed to be able to
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************//* *	mp3play.c -- Play MP3 data files * *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com) *      (C) Copyright 1997-1997, St閜hane TAVENARD *          All Rights Reserved * *	This code is a derivitive of Stephane Tavenard's mpegdev_demo.c. * * *	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., 675 Mass Ave, Cambridge, MA 02139, USA. *//****************************************************************************/#include "defs.h"#include "mpegdec.h"#include "genre.h"#include <sys/types.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/uio.h>#include <sys/file.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>#include <getopt.h>#include <signal.h>#include <linux/soundcard.h>#include <sys/resource.h>#include <linux/config.h>#ifdef CONFIG_KEY#include <linux/key.h>#endif/****************************************************************************/int	verbose;int	quiet;int	http_streaming;int	lcd_line, lcd_time;int	prebuflimit;int	lcdfd = -1;int	gotsigusr1;char	key[128];/* *	Keep track of start and end times. */struct timeval	tvstart, tvend;/* *	Global settings per decode stream. Used to control the final *	PCM to raw driver data conversion. */static int	stereo;static int	bits;static int	testtone;static int	quality;/****************************************************************************//* *	Master MP3 decoder settings. */static MPEGDEC_STREAM	*mps = NULL;static MPEGDEC_CTRL	mpa_ctrl;static MPEGDEC_CTRL	mpa_defctrl = {	NULL,    // Bitstream access is default file I/O	// Layers I & II settings (#3)	{ FALSE, { 1, 2, 48000 }, { 1, 2, 48000 } },	// Layer III settings (#3)	{ FALSE, { 1, 2, 48000 }, { 1, 2, 48000 } },	0,		// #2: Don't check mpeg validity at start			// (needed for mux stream)	2048		// #2: Stream Buffer size};static char *modes[] = { "stereo", "j-stereo", "dual", "mono" };/****************************************************************************//* *	MP3 data stream support (could be file or http stream). */#define MP3_BUF_SIZE	(4*1024)static char	*mp3_filename;static int	mp3_fd;static INT8	*mp3_buffer;static UINT32	mp3_buffer_size;static UINT32	mp3_buffer_offset;static UINT32	mp3_buffer_next_block;static UINT32	mp3_stream_size;static char	*rawbuf;static char	*prebuffer;int		prebufsize;int		prebufcnt;int		prebufnow;/****************************************************************************//* *	MP3 file TAG info. Output when in verbose mode. This structure is *	designed to match the in-file structure, don't change it! *	Nice printable strings are generated in the other vars below. */struct mp3tag {	char		tag[3];	char		title[30];	char		artist[30];	char		album[30];	char		year[4];	char		comments[30];	unsigned char	genre;};static struct mp3tag	mp3_tag;static int		mp3_gottag;static char		mp3_title[32];static char		mp3_artist[32];static char		mp3_year[8];static char		mp3_album[32];static char		mp3_comments[32];static char		*mp3_genre;/****************************************************************************//* *	Trivial signal handler, processing is done from the main loop. */void usr1_handler(int ignore){	gotsigusr1 = 1;}/****************************************************************************//* *	Get stream size (just file size). */static int getstreamsize(void){	struct stat	st;	if (stat(mp3_filename, &st) < 0)		return(0);	return(st.st_size);}/****************************************************************************//* *	Get another chunk of data into RAM. */static UINT32 getnextbuffer(){	int	rc;	lseek(mp3_fd, mp3_buffer_next_block, SEEK_SET);	rc = read(mp3_fd, mp3_buffer, MP3_BUF_SIZE);	mp3_buffer_size = (rc < 0) ? 0 : rc;	mp3_buffer_next_block += mp3_buffer_size;	return(mp3_buffer_size);}/****************************************************************************//* *	Start our own bitstream access routines. */INT32 bs_open(char *stream_name, INT32 buffer_size, INT32 *stream_size){#if 0	printf("bs_open: '%s'\n", stream_name);#endif	if (!mp3_buffer)		return(0);	mp3_buffer_offset = 0;	/* We know total size, we can set it */	*stream_size = mp3_stream_size;	/* Just return a dummy handle (not NULL) */	return(1);}/****************************************************************************/void bs_close(INT32 handle){#if 0	printf("bs_close\n");#endif	/* Don't need to do anything... */}/****************************************************************************/INT32 bs_read(INT32 handle, void *buffer, INT32 num_bytes){	INT32 read_size;	if (!handle )		return(-1);tryagain:	read_size = mp3_buffer_size - mp3_buffer_offset;	if (read_size > num_bytes)		read_size = num_bytes;	if (read_size > 0) {		if(!buffer)			return(-1);		memcpy(buffer, &mp3_buffer[mp3_buffer_offset], read_size);		mp3_buffer_offset += read_size;	} else {		if (getnextbuffer() > 0) {			mp3_buffer_offset = 0;			goto tryagain;		}		read_size = -1; /* End of stream */	}	return(read_size);}/****************************************************************************/int bs_seek(INT32 handle, INT32 abs_byte_seek_pos){	if (!handle)		return(-1);	if (abs_byte_seek_pos <= 0)		mp3_buffer_offset = 0;	else if (abs_byte_seek_pos >= mp3_buffer_size)		return(-1);	else		mp3_buffer_offset = abs_byte_seek_pos;	return(0);}/****************************************************************************/MPEGDEC_ACCESS bs_access = { bs_open, bs_close, bs_read, bs_seek };/****************************************************************************/void mkstring(char *str, char *buf, int size){    int i, j = 0;	char save;	for (i = size - 1; i >= 0; i--) {		if (buf[i] != ' ') {			while (buf[j] == ' ')				j++;			strncpy(str, &buf[j], i - j + 1);			str[i-j+1] = '\0';			return;		}	}}/****************************************************************************//* *	Get TAG info from mp3 file, if it is present. No point doing a *	fatal exit on errors, just assume no tag info is present. */void getmp3taginfo(void){	long	pos;	int	size;	mp3_gottag = 0;	size = sizeof(mp3_tag);	pos = mp3_stream_size - size;	if (pos < 0)		return;	if (lseek(mp3_fd, pos, SEEK_SET) < 0)		return;	if (read(mp3_fd, &mp3_tag, size) != size)		return;	if (strncmp(&mp3_tag.tag[0], "TAG", 3) != 0)		return;	/* Return file pointer to start of file */	lseek(mp3_fd, 0, SEEK_SET);	/* Construct fill NULL terminated strings */	mkstring(&mp3_title[0], &mp3_tag.title[0], sizeof(mp3_tag.title));	mkstring(&mp3_artist[0], &mp3_tag.artist[0], sizeof(mp3_tag.artist));	mkstring(&mp3_album[0], &mp3_tag.album[0], sizeof(mp3_tag.album));	mkstring(&mp3_year[0], &mp3_tag.year[0], sizeof(mp3_tag.year));	mkstring(&mp3_comments[0], &mp3_tag.comments[0], sizeof(mp3_tag.comments));	mp3_genre = (mp3_tag.genre >= genre_count) ? "Unknown" :		genre_table[mp3_tag.genre];	mp3_gottag = 1;}/****************************************************************************//* *	Print out everything we know about the MP3 stream. */void printmp3info(void){	if (quiet)		return;	if (verbose == 0) {		printf("%s: MPEG%d-%s (%ld ms)\n", mp3_filename, mps->norm,			(mps->layer == 1)?"I":(mps->layer == 2)?"II":"III",			mps->ms_duration);		return;	}	/* This is the verbose output */	printf("%s:\n", mp3_filename);	printf("    MPEG%d-%s %s %dkbps %dHz (%ld ms)\n", mps->norm,		(mps->layer == 1) ? "I" : (mps->layer == 2) ? "II" : "III",		modes[mps->mode], mps->bitrate, mps->frequency,		mps->ms_duration );	printf("    Decoding: Channels=%d Quality=%d Frequency=%dHz\n",		mps->dec_channels, mps->dec_quality, mps->dec_frequency ); 	if (mp3_gottag) {		printf("    Title:    %s\n", mp3_title);		printf("    Artist:   %s\n", mp3_artist);		printf("    Album:    %s\n", mp3_album );		printf("    Year:     %s\n", mp3_year);		printf("    Comments: %s\n", mp3_comments);		printf("    Genre:    %s\n", mp3_genre);	}}/****************************************************************************//* *	Print out the name on a display device if present. */void lcdtitle(void){	char	ctrl, *name;	int	ivp;	struct  iovec iv[4];	char	prebuf[10];	char	postbuf;	char	*p;	int	namelen;	/* Install a signal handler to allow updates to be forced */	signal(SIGUSR1, usr1_handler);	/* Determine the name to display.  We use the tag if it is	 * present and the basename of the file if not.	 */	if (mp3_gottag) {		name = mp3_title;		namelen = strlen(name);	} else {		name = strrchr(mp3_filename, '/');		if (name == NULL)			name = mp3_filename;		else			name++;		p = strchr(name, '.');		if (p == NULL)			namelen = strlen(name);		else			namelen = p - name;	}	if (lcd_line) {		/* Lock the file so we can access it... */		if (flock(lcdfd, LOCK_SH | LOCK_NB) == -1)			return;		if (lcd_line == 0) {			prebuf[0] = '\f';			prebuf[1] = '\0';		} else if (lcd_line == 1) {			strcpy(prebuf, "\003\005");		} else if (lcd_line == 2) {			strcpy(prebuf, "\003\v\005");		}		/*		 * Now we'll write the title out.  We'll do this atomically		 * just in case two players decide to coexecute...		 */		ivp = 0;		iv[ivp].iov_len = strlen(prebuf) * sizeof(char);		iv[ivp++].iov_base = prebuf;				iv[ivp].iov_len = namelen * sizeof(char);		iv[ivp++].iov_base = name;				//postbuf = '\n';		//iv[ivp].iov_len = sizeof(char);		//iv[ivp++].iov_base = &postbuf;		writev(lcdfd, iv, ivp);		/* Finally, unlock it since we've finished. */		flock(lcdfd, LOCK_UN);	}}/****************************************************************************//* *	Output time info to display device. */void lcdtime(time_t sttime){	static time_t	lasttime;	time_t		t;	char		buf[15], *p;	int		m, s;	t = time(NULL) - sttime;	if (t != lasttime && flock(lcdfd, LOCK_SH | LOCK_NB) == 0) {		p = buf;		*p++ = '\003';		if (lcd_time == 2)			*p++ = '\v';		*p++ = '\005';		m = t / 60;		s = t % 60;		if (s < 0) s += 60;		sprintf(p, "%02d:%02d", m, s);		write(lcdfd, buf, strlen(buf));		flock(lcdfd, LOCK_UN);	}	lasttime = t;}/****************************************************************************//* *	Configure DSP engine settings for playing this track. */ void setdsp(int fd, int playstereo, int playbits)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -