📄 player.c
字号:
ToContinue = 0;
}
//Dump data to DMA Memory
if (DMACS1 == 0x0001) //DMA0STB is working. fill Page A.
{
for (i = 0; i < 256; i++)
{
dci1TxBuffA[2*i]=(WORD)playbuffer[2*i] + (((WORD)playbuffer[2*i+1]) << 8) ; //data
dci1TxBuffA[2*i+1]=0x0000; //Padding
}
}
if (DMACS1 == 0x0000) //DMA0STA is working. fill Page B.
{
for (i = 0; i < 256; i++)
{
dci1TxBuffB[2*i]=(WORD)playbuffer[2*i] + (((WORD)playbuffer[2*i+1]) << 8) ; //data
dci1TxBuffB[2*i+1]=0x0000; //Padding
}
}
if (ToContinue == 1)
{
//move to next sector.
SectorCounter += 1; // counting 00 to 63 (when 64 sectors in cluster)
PlayedSect += 1; // Total Played Sector
RemainingSect -= 1; // Remaining Sector
//Check Sector is in Cluster
if (SectorCounter > (SectPerClust - 1) ) // when 63+1 > 64-1
{
//go to next cluster.
CurrentClust = GetnextCluster(CurrentClust);
if (CurrentClust != 0)
{
StartSectofClust = (CurrentClust -2) * SectPerClust + DataStartSect;
CurrentSectinClust = StartSectofClust;
SectorCounter = 0;
}
else
{
ToContinue = 0; //end of cluster
}
}
else
//just step to next sector. it will be used next time.
{
CurrentSectinClust += 1;
}
}
return ToContinue;
}
ULONG GetnextCluster(ULONG CurrentClust)
{
ULONG NextClust = 0;
if (CurrentClust < CBs[CurrentCBIndex].End_Cluster)
{
NextClust = CurrentClust + 1;
}
else
{
CurrentCBIndex++;
NextClust = CBs[CurrentCBIndex].Start_Clust;
}
return NextClust;
}
WORD GetnextClusterByFAT(WORD CurrentClust)
{
ULONG SectAddr = 0;
BYTE ret = 0;
WORD NextClust = 0;
WORD indexofClust = 0;
//there are 256 cluster in one FAT table.
SectAddr = (FATStartSect + (CurrentClust >> 8)) * 512;
if (CachedSectorAddress == SectAddr)
{
//databuffer already containes same information.
}
else
{
//read FAT Sector and,
ret = SD_Read_Single_Block(SectAddr, databuffer);
//remember address
CachedSectorAddress = SectAddr;
}
indexofClust = CurrentClust & 0x00FF; //tail 8bit = 0 to 256
NextClust = (WORD)databuffer[indexofClust*2] + (((WORD)databuffer[indexofClust*2 + 1])<<8);
if (NextClust >= 0xFFF8) NextClust = 0xFFFF; //end of cluster chain
return NextClust;
}
BYTE read_FAT_info(void)
{
ULONG bpb; // Bios Parameter Block Sector Number.
ULONG sectlen; // Byte Length per Sector, should be 512.
ULONG FATSects; // FAT system starting Sector number.
BYTE ret; // return value from other function
ULONG ROOTSects; // How many sectors in Root Directory Entry structures
bpb = 0;
sectlen = 0;
FATSects = 0;
ret = 0;
ROOTSects = 0;
//Read MBR
ret = SD_Read_Single_Block(0, databuffer);
CachedSectorAddress = 0;
if (ret == 0)
{
//read Bios Parameter Block sector number
bpb = (ULONG)databuffer[MBR_START+MBR_BPP1] + (((ULONG)databuffer[MBR_START+MBR_BPP1+1])<<8);
}
else
{ return ret; }
FATType = 0;
if (databuffer[MBR_START + 4] == 0x06) FATType = 1;
// Read Bios Parameter Block
ret = SD_Read_Single_Block(bpb * 512, databuffer);
CachedSectorAddress = bpb * 512;
if (ret == 0)
{
//read Sector Length
sectlen = (ULONG)databuffer[BPB_SECTLEN] + ((ULONG)databuffer[BPB_SECTLEN+1]<<8);
}
else
{ return ret; }
if (sectlen != 512) return 2; //not 512 Bytes per sector. error.
//read other information in Bios Parameter Block
SectPerClust = (ULONG)databuffer[BPB_SECTPERCLUST];
//Cluster is 4KByte when you see harddisk, unit of smallest file area.
FATStartSect = bpb + (ULONG)databuffer[BPB_RESVDSECT]+(((ULONG)databuffer[BPB_RESVDSECT+1])<<8);
//FAT Sector
FATSects = (ULONG)databuffer[BPB_FATSIZE]+(((ULONG)databuffer[BPB_FATSIZE+1])<<8);
//How many FAT sector exist
if (FATSects ==0) return 2; //not FAT16
DIRStartSect = FATStartSect + (ULONG)databuffer[BPB_NUMOFFATS] * FATSects;
// Root directory startinc sector
RootDirEntrys = (ULONG)databuffer[BPB_ROOTENT]+(((ULONG)databuffer[BPB_ROOTENT+1])<<8);
// normally this is fixed, 512 (files, dirs in root directory can be exist)
ROOTSects = RootDirEntrys / (512 / 32);
// it should be 32.
DataStartSect = DIRStartSect + ROOTSects;
// User data starting sector number
return 0;
}
BYTE search_WAV(UINT MaxCount) // Upper Limit to search WAV files
{
ULONG EntrySector=0; //Sector Number for Directory Entry
ULONG sectaddr=0; //Actual Sector Address
ULONG MusicFound=0; //How many WAV found
ULONG EntryNum=0; //There are 16 structure(32bytes) in one sector(512bytes)
BYTE ret=0; //return value from other function
ULONG FirstClust=0; //First Cluster number of found ***.WAV file
ULONG FirstSect=0; //First Sector number of found ***.WAV file
for (EntrySector = 0 ; EntrySector < RootDirEntrys/(512 / 32); EntrySector++)
{
//DIRStartSect is calculated at read_FAT_info
sectaddr = (DIRStartSect + EntrySector) * 512;
//Read Sector Data
ret = SD_Read_Single_Block(sectaddr, databuffer);
CachedSectorAddress = sectaddr;
//Search Directory Entry in Sector. There are 16 entry in one sector.
for (EntryNum = 0; EntryNum < 16; EntryNum++)
{
//Directory Entry structure
//0-10 File name, 8.3
//11 File attribute
//12 reserved
//13-19 time stamps
//20-21 first cluster, upper 2 byte. always 0 for FAT16
//22-25 time stamps
//26-27 first cluster, lower 2 byte.
//28-31 file size in ULONG
//Check attribute. 0x10: directory flag, 0x80: volume flag
if ( !(databuffer[EntryNum * 32 + 11] & 0x18))
{
//Check Cluster number:
FirstClust = (ULONG)databuffer[EntryNum * 32 + 26] + (((ULONG)databuffer[EntryNum * 32 + 27])<<8);
if ( ( FirstClust > 0 ) && //start cluster not = 0,
( databuffer[EntryNum * 32 + 0] != 0xE5) && // filename first byte is not deleted flag,
( databuffer[EntryNum * 32 + 8]='W')&&
( databuffer[EntryNum * 32 + 9]='A')&&
( databuffer[EntryNum * 32 + 10]='V') // extention is WAV
)
{
//Check Initial Sector for WAV format.44100/16/Stereo only.
FirstSect = (FirstClust - 2) * SectPerClust + DataStartSect;
ret = SD_Read_Single_Block(FirstSect * 512, playbuffer);
if ( ( memcmp( playbuffer, "RIFF",4) == 0) && // start with RIFF
( memcmp( &playbuffer[8], "WAVEfmt ", 8) ==0 ) && // Format is WAVE
( playbuffer[20] == 1 ) && // Linear PCM
( playbuffer[22] == 2 ) && // Stereo
( playbuffer[24] == 0x44 ) &&
( playbuffer[25] == 0xAC ) && // 0xAC44 = 44100
( playbuffer[32] == 4 ) && // 4 byte / sample
( playbuffer[34] == 16 )) // 16 bit
{
// this is wave file.
// Store File information.
WAVFiles[MusicFound].fsize = (DWORD)databuffer[EntryNum * 32 + 28] +
((DWORD)databuffer[EntryNum * 32 + 29]<<8) +
((DWORD)databuffer[EntryNum * 32 + 30]<<16) +
((DWORD)databuffer[EntryNum * 32 + 31]<<24);
WAVFiles[MusicFound].org_clust = FirstClust;
WAVFiles[MusicFound].WaveSize = (DWORD)playbuffer[40] +
((DWORD)playbuffer[41]<<8) +
((DWORD)playbuffer[42]<<16) +
((DWORD)playbuffer[43]<<24);
memcpy(WAVFiles[MusicFound].fname, (char *)&(databuffer[EntryNum * 32 + 0]), 8);
MusicFound++; // incremented after stored, so this value is [0 indexed] + 1
MaxCount--;
}
if (MaxCount == 0) break;
} // File, Cluster check IF
} // not (directory or volume) check
} // Entry in Sector LOOP
} // Sector for Entry group LOOP
return MusicFound;
}
void SortMusic(void)
{
//Simple Sort algorithm, sort FILINFO by File Name
FILEINFO tempInfo; // temp area to keep copy
int i,j;
// for 0 to Musics - 1, ex: if 1-10 musics found, i = 0 to 9.
for (i = 0; i < TotalMusics; i++)
{
// if 10 music found, j = 1 to 9.
for (j = i + 1; j < TotalMusics; j++)
{
if ( ( strncmp(WAVFiles[j].fname, WAVFiles[i].fname, 8) ) < 0 )
// if [j] filename smaller than [i] filename
{
//[j] and [i] exchanged. [i] -> temp, [j] -> [i], temp -> [i]
memcpy((FILEINFO *)&tempInfo, (FILEINFO *)&WAVFiles[i],sizeof(FILEINFO));
memcpy((FILEINFO *)&WAVFiles[i],(FILEINFO *)&WAVFiles[j],sizeof(FILEINFO));
memcpy((FILEINFO *)&WAVFiles[j],(FILEINFO *)&tempInfo, sizeof(FILEINFO));
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -