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

📄 fileio.c

📁 e1c0df5d-c8bc-48a5-bc02-a2b7c51c0dbf是做mp3的源代码
💻 C
字号:
#include "fileio.h"#ifdef MMCunsigned char MMC_Read_Wrapper(unsigned long lba){	if (lba <= maxsect)		return MMC_Read(lba);	else		return 1;		// return error code}#endifint get_disk_parms(){	unsigned long pstart;	struct boot_record *bs;#ifndef MMC	if (CFIdentify())							// get CHS from cf card	return 1;#else//	if(MMC_Check())//	{//		if(MMC_Reset())//			return 1;//	}	MMC_Check();	MMC_Reset();	maxsect = MMC_Capacity();#endif		if (ReadSector(0))								// read MBR	return 5;#ifndef MMC	pstart = (((((unsigned int) secbuf[0x1c0] & 0xc0) << 2) + secbuf[0x1c1])* heads * sectors_per_track) +		(secbuf[0x1bf] * sectors_per_track) + (secbuf[0x1c0] & 0x3f) -1;#else	pstart = (unsigned int)secbuf [0x1c7] << 8  | secbuf[0x1c6];#endif	if (ReadSector(pstart))					// read first fat sector	return 3;	bs = secbuf;	fatstart = pstart + bs->reserved_sectors;	secpercluster = bs->sectors_per_cluster;	rootdir = fatstart + (bs->sec_per_fat * bs->number_of_fats);	// start of root dir	data = rootdir + (bs->root_direntries >> 4);			// start of data area (Cluster area)	return(0);}unsigned int get_next_cluster(unsigned int lastcl){	lastcl += 2;	if (ReadSector((unsigned long) fatstart + (lastcl >> 8))) return 0xffff;	return (unsigned int) secbuf[(((unsigned int) lastcl & 0xff) << 1)] - 2	+ (((unsigned int) secbuf[(((unsigned int) lastcl & 0xff) << 1)+1]) << 8);	// fetch next cluster}unsigned int get_next_direntry(unsigned int dircluster, unsigned int num, char dir, unsigned char type, unsigned char get_id3){	unsigned long sect, lastsec;	struct entry *de;	static char file_types[] PROGMEM = "MP3M3URGB";			// strings for file extensions	sect = lastsec = 0;	attrib = 1;	do	{		num += dir;		if (dircluster == 0)					// is this the root directory?		{			sect = rootdir + (num >> 4);			// yes, right after fat		}		else		{			sect = data + ((unsigned long) dircluster * secpercluster) + (num >> 4);	// no, add offset		}		if (sect != lastsec)					// did we already read sector?		{			ReadSector(sect);				// no, get it			lastsec = sect;					// save read sector		}			de = secbuf + ((num << 5) - ((num >> 4) * 512));	// fill direntry structure		attrib = de->attribute;					// save attribute for main program		if ((de->filename[0] == 0) && (dir > 0)) break;		// empty filename -> last direntry		if ((type == TYPE_DIR) && !(attrib & 0x10)) continue;	// it`s not a directory but we`re looking for one		if ((attrib & 0x10) && strncmp_P(de->filename, PSTR(". "), 2)) continue;		// skip current directory		if ((attrib != 0x0f) && ((de->filename[0] != 0xe5) && (de->filename[0] != 0x00)))	// "normal" directory entry, go on!		{			if ((attrib & 0x10) && (de->filecluster == 0 && de->filesize == 0)) continue;	// empty file -> continue			strncpy(filename, de->filename, 8);		// copy filename			filename[8] = '.';				// set the dot			strncpy(filename+9, de->ext, 3);		// copy extension			filename[12] = '\0';				// properly terminate			filecluster = de->filecluster;			// get first cluster			if (filecluster != 0) filecluster -= 2;		// correct cluster number			dirfilesize = de->filesize;			// get filesize			if ((type < TYPE_ANY) && (strncmp_P(de->ext, file_types + (type*3), 3))) continue;	// file extension doesn't 			get_lfn(num);					// get long file name			if ((attrib & 0x10) && (filecluster == 0) && (dirfilesize == 0))	// parent directory				strncpy_P(filename, PSTR("<dir up>"), 10);			else if (attrib & 0x10)							// mark as folder				strncpy_P(artalb, PSTR("<folder>"), 9);			else if (get_id3)							// mp3 file, get ID3 info				get_id3_info(filecluster);				return num;		}	} while (((num > 0) && (dir < 0)) || ((num < 512) && (dir > 0)));	beep(80,100);			// no suitable file found - hear it!	return 0xffff;			// return error value}unsigned char get_next_playlist_entry(unsigned char playlistid, char dir){	unsigned char ibuf[6];	unsigned char *p;	register unsigned int readcl;	register int i;	register unsigned char ii;	register char readsect, flag;		artalb[0] = '\0';	p = artalb;	readcl = playlistcl;	i = playlistptr / ((unsigned int) secpercluster * 512);				// determine cluster for playlistptr	for (ii = 0;ii < i; ii++)		readcl = get_next_cluster(readcl);					// fetch that cluster...	readsect = (playlistptr - ((unsigned int) secpercluster * 512 * i)) / 512;	// determine sector inside cluster...	ReadSector(data + (unsigned long) readcl * secpercluster + readsect);		// and get it	i = playlistptr - ((unsigned int) secpercluster * 512 * i) - (readsect * 512);	if ((dir < 0) && (playlistptr > 0))						// direction back, rewind file two lines	{		i--;									// jump over trailing linefeed		playlistptr--;		flag = 0;		while (playlistptr > 0)		{			i--;					// go back...			if (i < 0)				// bottom of sector buffer reached?			{				i = 511;			// yes, set buffer				readsect--;			// get next sector				if (readsect < 0)				{					readsect = secpercluster - 1;	// new cluster needed					readcl = filecluster;					for (ii = 0; ii<(playlistptr / ((unsigned int) secpercluster * 512)); ii++)						readcl = get_next_cluster(readcl);				}				ReadSector(data + (unsigned long) readcl * secpercluster + readsect);	// finally get the sector			}			if (secbuf[i] == 0x0a)						// linefeed, got the previous line			{				if (!flag)						// jump back one more line					flag = 1;				else				{					i++;			// here we are, two lines back					break;			// go ahead!				}			}			playlistptr--;				// rewind file pointer		}	}	while (playlistptr < playlistlength)			// now we`re going forward	{		lcd_upd = 0;					// debugging stuff		if (secbuf[i] == 0x0a)				// line end?		{			*p++ = '\0';				// yes, terminate string			break;					// and out		}		if ((p-artalb) < 49)				// some space left in line buffer?		{			*p++ = secbuf[i];			// yes, get next char		}		playlistptr++;					// advance file pointer		i++;		if (i == 512)					// new sector, same as above but forward		{			i = 0;//			playlistptr++;			readsect++;			if (readsect == secpercluster)		// new cluster...			{				readsect = 0;				readcl = get_next_cluster(readcl);			}			ReadSector(data + (unsigned long) readcl * secpercluster + readsect);		}	}	playlistptr++;						// jump over linefeed	if ((p-artalb) > 48) artalb[49] = '\0';			// terminate	if (strlen(artalb) == 0)		return 0xff;	readcl = 0;	cli();				// finding song may take som time, so no interrupts until then (i.e., disable timer)	while (ii = strncmp(filename, artalb, 48) && (readcl != 0xffff))	// filename matching	{		readcl = get_next_direntry(dircluster, readcl, 1, TYPE_MP3, NOID3);	}	sei();					// re-enable interrupts		if (readcl != 0xffff)			// we got the file	{		get_id3_info(filecluster);	// fetch ID3 tag		return 0;	}	else		return 0xfe;			// not found :-(	return 0;		}unsigned char get_lfn(unsigned int dirid){	register unsigned long sect, lastsec;	register unsigned int res, lfnentry;	register unsigned char i;	unsigned char *p;	p = filename;	lastsec = (0);	while ((dirid > 0) && (p < (&filename[0] + 48)))	{		dirid--;		if (dircluster == 0)		// is this the root directory?		{			sect = rootdir + (dirid >> 4);		// yes, right after fat		}		else		{			sect = data + ((unsigned long) dircluster * secpercluster) + (dirid >> 4);	// no, add offset		}		if (sect != lastsec)		{			lastsec = sect;			res = ReadSector(sect);		}		lfnentry = (dirid << 5) - ((dirid >> 4) * 512);		if (secbuf[lfnentry+11] = 0x0f)		{			if (secbuf[lfnentry] & 0x40) dirid = 0;		// last lfn entry			for (i=1;i<32;i+=2)			{				if (p > (&filename[0]+48)) continue;				if (i==11) i += 3;			// attribute, type, checksum				if (i==26) i += 2;			// cluster				*p++ = secbuf[lfnentry+i];			}		}		else return(0xff);						// this is not an lfn entry	}	*p++='\0';	return 0;}void get_id3_info(unsigned int cl){	unsigned long tagsize, offset;	unsigned int cluster;	char id, length;	unsigned char *p, *p2;	register int i;	char charbuf[30];	memset(artalb, 0, 30);	artalbpos = titlepos = 0;	artalbdir = titledir = 1;	scrolltimer = SCROLLSPEED;	lcd_upd = 0;	tagsize = 0;	id = ReadSector(data + (unsigned long) cl * secpercluster);// read next sector	if (secbuf[0]=='I' && secbuf[1]=='D' && secbuf[2]=='3')	{		memset (filename, 0, 30);	// clear filename, we've got an ID3 tag!		tagsize = ((unsigned long ) secbuf[6]) << 21 | ((unsigned long) secbuf[7]) << 14		| ((unsigned long) secbuf[8]) << 7 | secbuf[9];		offset = 10;		while ((offset < 502) && (id != -1))		{			charbuf[0]='\0';			id = parse_tag(&offset, charbuf);			if (strlen(charbuf) > 0)			{				p2 = NULL;				switch (id)				{					case TPE1:						p2 = artalb;					case TRCK:						if (p2== NULL) p2 = filename;												if (strlen(p2)==0)			// first part of concatennated string, nothing special						{							strncpy(p2, charbuf, 30);						}						else						{							length = strlen(charbuf)+3;			// part1 + part2 > 50?							if ((strlen(p2)+length)>49)								length = 46-strlen(p2);			// yes, cut string							memmove(p2+length, p2, strlen(p2+1)); 		// move string to the end of new string							memcpy(p2, charbuf, length-3);			// prepend new string							strncpy_P(p2+length-3, PSTR(" - "), 3);		// insert separator						}						*(p2+49)='\0';						break;						case TALB:						p2 = artalb;					case TIT2:						if (p2 == NULL) p2 = filename;												if (strlen(p2)==0)						{							strncpy(p2, charbuf, 30);						}						else						{//							length = 30;//							if (strlen(p2)+strlen(charbuf)>46)//								length = 46-strlen(p2);							if (strlen(p2)>0) strlcat_P(p2, PSTR(" - "), 50);							strlcat(p2, charbuf, 50);						}						*(p2+49)='\0';						break;				}			}		}	}	cluster = cl;	if (tagsize > 512)	{		for (i = 0;i < (tagsize / 512);i++)		{			cluster = get_next_cluster(cluster);		}	}	tagsize = tagsize % 512;	id = ReadSector(data + (unsigned long) cluster * secpercluster);	// read next sector	id =6 * ((secbuf[tagsize+2] >> 4) -1) + 3 * (1-((secbuf[tagsize+1] >> 3) & 0x01))+ (3- ((secbuf[tagsize+1] >> 1) & 0x03));	file_bitrate = PRG_RDB(&bitrate[id]);	if (file_bitrate < 12)		file_bitrate = 16;}// this routine parses a id3 tag// currently only artist, title, album and track no are implementedchar parse_tag(unsigned long * offs, unsigned char * buffer){	unsigned long tsize;	char encoding, numid;	char div;	register int i, ii;	char *p;	static char valid_tags[] PROGMEM = "TPE1TALBTRCKTIT2";			// strings for tag types	numid = 0;	p=valid_tags;	for (i=0; i<4; i++)							// tag that we are aware of?	{		if (strncmp_P(&secbuf[*offs], p, 4) == 0)		{			numid = i+1;						// yes!			break;		}		p+=4;	}	*offs += 4;	tsize = ((unsigned long) secbuf[*offs]) << 21 | ((unsigned long) secbuf[*offs+1]) << 14 |		 ((unsigned long) secbuf[*offs+2]) << 7 | (unsigned long) secbuf[*offs+3];	// fetch tag size	if (tsize == 0) return -1;								// length zero -> last frame	*offs += 6;										// jump over flags...	ii = 0;	if (numid != 0)	{		encoding = secbuf[*offs];					// tags might have different encodings...		if (encoding == 0)		{*offs += 1; tsize -= 1; div = 1; }				// 1 byte per char		else		{*offs += 3; tsize -= 3; div = 2; }				// 2 bytes per char (div=2)		for (i=0; i<tsize; i++)						// save tag info		{			if (ii >= 29)						// sorry, no more than 29 chars...			{					i=tsize;			}			*buffer++ = secbuf[*offs+i];			if (encoding != 0) i++;		}		*buffer++='\0';							// terminate string properly	}	*offs += tsize;	return numid;}

⌨️ 快捷键说明

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