📄 fileio.c
字号:
#include "fileio.h"int get_cf_parms(){ unsigned long pstart; unsigned int reserved, fatcount, rootentries; // various fat parameters, neccessary unsigned char numfats; // to locate files, browse directory etc. if (CFIdentify()) // get CHS from cf card return 1; numfats = CFReadSector(0); if (numfats) // read MBR return 5+numfats; pstart = (((((unsigned int) secbuf[0x1c0] & 0xc0) << 2) + secbuf[0x1c1])* heads * sectors_per_track) + (secbuf[0x1bf] * sectors_per_track) + (secbuf[0x1c0] & 0x3f) -1; if (CFReadSector(pstart)) // read first fat sector return 3; fatstart = pstart + ((((unsigned int) secbuf[0x0f]) << 8) + secbuf[0x0e]); fatcount = (((unsigned int) secbuf[0x17]) << 8) + secbuf[0x16]; // # of sectors per fat numfats = secbuf[0x10]; // # of copies of fat rootentries = ((((unsigned int) secbuf[0x12]) << 8) + secbuf[0x11]); // # of root dir entries secpercluster = (secbuf[0x0d]); rootdir = fatstart + ((unsigned long) fatcount * numfats); // start of root dir data = rootdir + (rootentries >> 4); // start of data area (Cluster area) return(0);}unsigned int get_next_cluster(unsigned int lastcl){// unsigned int res; lastcl += 2;// res = CFReadSector((unsigned long) fatstart + (lastcl >> 8));// if (res) return 0xffff; if (CFReadSector((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){ register unsigned int direntry, numsave; register unsigned int res; register unsigned char i; unsigned char *p; unsigned long sect, lastsec; numsave = num; sect = lastsec = 0; attrib = 1; do { wdt_reset(); 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) { res = CFReadSector(sect); lastsec = sect; } direntry = (num << 5) - ((num >> 4) * 512); // start of directory entry attrib = secbuf[direntry+11]; // get file attribute; if ((secbuf[direntry] == 0) && (dir > 0)) break; // end of dir if ((type == TYPE_DIR) && !(attrib & 0x10)) continue; // we're looking for a directory -> continue if ((attrib & 0x10) && (secbuf[direntry]=='.') && (secbuf[direntry+1]==' ')) continue; // current directory -> continue if ((attrib != 0x0f) && ((secbuf[direntry] != 0xe5) && (secbuf[direntry] != 0x00))) // valid file! { p = filename; // set stringbuffer pointer to filename for (i=0;i<11;i++) // 8+3, 11 characters { *p++ = secbuf[direntry+i]; if (i==7) *p++ = '.'; // add the dot } *p='\0'; // terminate string filecluster = (((unsigned int) secbuf[direntry+27]) << 8) + secbuf[direntry+26]; if (filecluster != 0) filecluster -= 2; dirfilesize = (unsigned long) (((unsigned long) secbuf[direntry+31] << 24) + (((unsigned long) secbuf[direntry+30]) << 16) + (((unsigned long) secbuf[direntry+29]) << 8) + (((unsigned long) secbuf[direntry+28]))); if (!(attrib & 0x10) && (filecluster == 0 && dirfilesize == 0)) continue; // empty file -> continue if (!(strncmp_P(filename+9, PSTR("MP3"), 3) == 0) && type==TYPE_MP3) continue; // file extension doesn't if (!(strncmp_P(filename+9, PSTR("M3U"), 3) == 0) && type==TYPE_M3U) continue; // match requested type 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);// lcd_clrscr();// lcd_upd = LCDUPDATEFREQ; return num; } } while (((num > 0) && (dir < 0)) || ((num < 512) && (dir > 0))); beep(60,100); return 0xffff;// return num;}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; wdt_reset(); if ((dir < 0) && playlistptr > 1) playlistptr--; // remove trailing linefeed if direction is rewind readcl = playlistcl; i = playlistptr / ((unsigned int) secpercluster * 512); // determine right cluster for playlistptr for (ii = 0;ii < i; ii++) readcl = get_next_cluster(readcl); // fetch cluster... readsect = (playlistptr - ((unsigned int) secpercluster * 512 * i)) / 512; // determine sector inside cluster CFReadSector(data + (unsigned long) readcl * secpercluster + readsect); i = playlistptr - ((unsigned int) secpercluster * 512 * i) - (readsect * 512); artalb[0] = '\0'; if (dir > 0) p = artalb; else { artalb[49] = '\0'; p = artalb+48; } while (((dir > 0) && (playlistptr < playlistlength)) || ((dir < 0) && (playlistptr > 0))) { wdt_reset(); lcd_upd = 0; if (secbuf[i] == 0x0a) { if (dir > 0) { *p++ = '\0'; break; } else { memmove(artalb, p, artalb+49-p+1); break; } } if ((p-artalb) < 49) { if (dir > 0) *p++ = secbuf[i]; else *p-- = secbuf[i]; } else if (dir > 0) playlistptr++; else playlistptr--; if (dir > 0) { i++; if (i == 512) { i = 0; playlistptr++; readsect++; if (readsect == secpercluster) { readsect = 0; readcl = get_next_cluster(readcl); } wdt_reset(); CFReadSector(data + (unsigned long) readcl * secpercluster + readsect); } } else { i--; if (i < 0) { i = 511; playlistptr--; readsect--; if (readsect < 0) { readsect = secpercluster - 1; readcl = filecluster; for (ii = 0; ii<(playlistptr / ((unsigned int) secpercluster * 512)); ii++) readcl = get_next_cluster(readcl); } wdt_reset(); CFReadSector(data + (unsigned long) readcl * secpercluster + readsect); } } } if (dir > 0) playlistptr += strlen(artalb)+1; else playlistptr -= strlen(artalb)+1; if ((p-artalb) > 48) artalb[49] = '\0'; if (strlen(artalb) == 0) return 0xff; readcl = 0; lcd_clrscr(); cli(); // finding song may take som time, so no interrupts until then (i.e., disable timer) while (strncmp(filename, artalb, 48) && (readcl != 0xffff)) { readcl = get_next_direntry(dircluster, readcl, 1, TYPE_MP3, NOID3); } sei(); if (readcl != 0xffff) { get_id3_info(filecluster); return 0; } else return 0xfe; 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 = CFReadSector(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 lfs 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]; artalb[0]='\0'; artalbpos = titlepos = 0; artalbdir = titledir = 1; scrolltimer = SCROLLSPEED; lcd_upd = 0; tagsize = 0; wdt_reset(); id = CFReadSector(data + (unsigned long) cl * secpercluster);// read next sector if (secbuf[0]=='I' && secbuf[1]=='D' && secbuf[2]=='3') { filename[0]='\0'; // clear filename, we've got a 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 1: p2 = artalb; case 3: if (p2== NULL) p2 = filename; if (strlen(p2)==0) { strncpy(p2, charbuf, 30);} else { length = strlen(charbuf)+3; if ((strlen(p2)+length)>49) length = 46-strlen(p2); memmove(p2+length, p2, strlen(p2)); memcpy(p2, charbuf, length-3); strncpy_P(p2+length-3, PSTR(" - "), 3); } *(p2+49)='\0'; break; case 2: p2 = artalb; case 4: 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 = CFReadSector(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;}char parse_tag(unsigned long * offs, unsigned char * buffer){ unsigned long tsize; char encoding, numid; char div; register int i; char *p; static char valid_tags[] PROGMEM = "TPE1TALBTRCKTIT2"; wdt_reset(); numid = 0; p=valid_tags; for (i=0; i<4; i++) { if (strncmp_P(&secbuf[*offs], p, 4) == 0) { numid = i+1; 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]; if (tsize == 0) return -1; // length zero -> last frame *offs += 6; // jump over flags... if (numid != 0) { encoding = secbuf[*offs]; if (encoding == 0) {*offs += 1; tsize -= 1; div = 1; } else {*offs += 3; tsize -= 3; div = 2; } for (i=0; i<tsize; i++) { if (i>29) { buffer[29]='\0'; i=tsize; } buffer[i/div]=secbuf[*offs+i]; if (encoding != 0) i++; } if (i<=29) buffer[i/div]='\0'; } *offs += tsize; return numid;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -