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

📄 yadl.h

📁 DIY自己的MP3的参考价值极高的代码。含有详细的解释
💻 H
字号:
/************************************************************************
*************************************************************************
**
**  Revision History
**
**  when         what  who   why
**
**  2002-09-01   1.0   Uli   initial public release
**
************************************************************************/
#ifndef __YADL_H__
#define __YADL_H__
//定义一种类型的别名
#ifdef _MSC_VER
  typedef unsigned char  u08;
  typedef unsigned short u16;
  typedef unsigned long  u32;
  typedef char  s08;
  typedef short s16;
  typedef long  s32;
  #pragma pack(1)
#endif

typedef unsigned long  SECTOR;   /* u32 sector number */
typedef unsigned long  CLUSTER;  /* u32 cluster number  (max 27 bits used */
typedef unsigned long  FLENGTH;  /* u32 File length */
typedef unsigned long  FOFFSET;  /* u32 offset inside file from start of file */

/* globalisms *********************************************************************/
#define SECTORSIZE                0x200     /* ever gonna change ???? ;-) */

/* our CLUSTERSIZE is fixed to 0x40000 or 2^18 or 256 k or 512*512 or 0x200*0x200 */ 
#define YADL_CLUSTERSIZE          0x40000

/* so this will remain always 512 */
#define YADL_SECTORS_PER_CLUSTER  (YADL_CLUSTERSIZE / SECTORSIZE)

/* fixed sector numbers in ROOT_AREA  these are NOT not change*/
#define YADL_SEC_ROOT         0
#define YADL_SEC_ARTIST_INDEX 1
#define YADL_SEC_TITLE_INDEX  2
#define YADL_SEC_APPL_STORAGE 3 /* place for generic application storage */
#define YADL_SEC_SCRATCH      4
#define YADL_SEC_SONG_BASE    5


/********************************************************************************
**
** these fixed sectors lead to the following DISK LAYOUT
**
********************************************************************************
SecNum
0:     Root Sector
1:     Artist Index (structure see below)   (NOT FILLED YET -> now set to 0xFFFF)
2:     Title Index (structure see below)    (NOT FILLED YET -> now set to 0xFFFF)
3:     Application Storage                  (NOT USED YET)
4:     Spare / Scratch
5:     start of songbase - the length of the songbase depends on the physical size of the disk
       a simple guess is made here for the maximium number of song_base_entries:
                        song_base_entries   = ((num_clusters >> 3) &0xFFFFFFF0) + 10;
xx     FAT  variable secno, pointed to fat_start: begin of FAT
yy     DATA variable secno, to reach cluster 0 -> take "sector_cluster_offset"
zz     after all data, there may (!) be some spare room
       this is identified by (secnum) wasteland_start and (u16) wasteland_length


*******************************************************************************
Artist and Track Indices: (please note: NOT FILLED IN YET !!!)
*******************************************************************************

each song contains the following info in its songbase slot:

u16 next_artist;          pointer into songbase to (alphabetically) next title of this artist or new artist
u16 next_artist_grouped;  pointer into songbase to (alphabetically) next artist in unique(grouped) list 
u16 next_title;           pointer into songbase to (alphabetically) next song  

these fields provide a means to browse the songs either alphabetically by song titles or artists
meaning that all songs titles/artists inside the base can be accessed via an ordered list
"end of list reached" indicated with 0xFFFF

the two additional sectors Artist/Title Index contain start values to go with them into the song base

you have to consider the sector as being the following array

u16 artist_index[0x100]  (one sector in size)

artist_index[0] will always point to the VERY FIRST artist name in the current songbase

if you want to present the user with a list of all artists, eg. starting with 'S'
go inside the index to lookup the first songbase entry (if any)
note that it will be treated case insensitive, thus 'S' will be == 's'

first song starting with 'S' in base  --> artist_index['S']

*************************************************************************
**
** The yaDL R O O T Sector
**
*************************************************************************/


/* STRINGS THAT THE FIRMWARE FILLS IN  - note:  all need a \0 termination except for the ID */
#define YADL_LEN_MODEL            30   /* eg yampp 4,5,6 etc */
#define YADL_LEN_BUILD_TIMESTAMP  32   /* compile timestamp of firmware */ 
#define YADL_LEN_DISK_INFO        80   /* Disk manuf name etc from atapi identify drive */ 

/* STRINGS THAT THE HOST APP FILLS IN */
#define YADL_LEN_IDENTIFIER 20   /* must be UNIQUE !! identifier for that particular yampp - used as subdir name on PC */

/* Values for the "unmount_state" field */
#define YADL_STATE_MOUNTED   0  /* Pc APP wrote to yampp and made it "dirty" */
#define YADL_STATE_OK     0x10  /* PC APP logged off normally , all data written , CLEAN state */
#define YADL_STATE_NEW    0xFF  /* FRESH DISK */


#define YADL_MEDIA_UNKNOWN 0    /* type of storage yampp uses */
#define YADL_MEDIA_DISK    1 
#define YADL_MEDIA_FLASH   2


typedef struct
{
/*************/
/* SECTION 1 */
/*************/
  /* data the yampp firmware fills in ONCE upon new disk detection */
  u08  id[4];                         /* always "YADL" */

  u32  disk_size;                     /* size in sectors of 512 byte - TRUE u32 here !!! */

  u08  unmount_state;                 /* == YADL_STATE_OK       -> fine, yaPC was exited cleanly  
                                            YADL_STATE_MOUNTED  -> ERROR possibly corruption, disk not closed by yaPC!
                                         firmware MUST NEVER touch this field except for new disk detection 
                                         -> then set to YADL_STATE_NEW */

  u08  media_type;                    /* for now, only YADL_MEDIA_DISK, YADL_MEDIA_FLASH,  YADL_MEDIA_UNKNOWN */

  u08  disk_version_major;            /* start with 1.0 */
  u08  disk_version_minor;

  u08  model[YADL_LEN_MODEL];         /* yampp 3,4,5,6,7 etc ... */             
  u08  disk_info[YADL_LEN_DISK_INFO]; /* ATAPI IDENTIFY DRIVE infos... */             


/*************/
/* SECTION 2 */
/*************/

  /* data the yampp firmware checks on startup and fills in new values after each FW update */
  u08  build_timestamp[YADL_LEN_BUILD_TIMESTAMP];  /* to be filled in by __DATE__ __TIME__ macros */
  u08  firmware_version_major;                
  u08  firmware_version_minor;


/*************/
/* SECTION 3 */
/*************/
  /* data the Host APP fills in */
  u08  identifier [YADL_LEN_IDENTIFIER]; /* must be unique and a valid PC subdirname */
  u16  t_year;                           /* last PC access time */
  u08  t_month;
  u08  t_day;
  u08  t_hour;
  u08  t_minute;
  u08  t_second;
  u08  z_dummy00;


  /* misc ADRESSING + DATA STUFF */  
  u32      sector_cluster_offset; /* add this offset value to all cluster values out of FAT */
  u32      free_cluster_count;    /* informational only */

  SECTOR   wasteland_start;       /* unused room AFTER last cluster, if any , else NULL */ 
  u16      wasteland_length ;     /* length of waste in sectors */ 

  /* songbase will always be consecutive on disk ! */
  SECTOR  songbase_start;         /* although a pointer here -> it is hardcoded to YADL_SEC_SONG_BASE) */
  u16     songbase_qty;           /* nr of songbase entries */

  u16     first_artist;           /* "pointer"/index into the songbase to the alphabetically sorted artist list */
  u16     first_title;            /* "pointer"/index into the songbase to the alphabetically sorted title list */

  /* FAT will always be consecutive on disk, right after songbase ! */
  SECTOR  fat_start;
  u32     fat_qty;                /* nr of fat ENTRIES, not sectors */

  /* playlist F_I_L_E */
  CLUSTER  playlist_start;        /* structured file (this is a "normal" file inside the FAT chain
                                     not necessarily consecutive contains playlist data 
                                     no list exists -> marked with YADL_FAT_INVALID */
  FLENGTH  playlist_file_length;  /* real filelength */
  u16      playlist_qty;          /* nr of playlists stored in that file - NULL indicates no playlist */
  
  u16      playlist_first;        /* if playlists are chained, this is the first to be played */
  
  /* misc system data */
  SECTOR  text_data;              /* if == NULL -> not supported yet */
  u16     text_qty;               /* nr of texts */
  u08     text_version_major;     /* start with 1.0 */
  u08     text_version_minor;

  CLUSTER snd_system;             /* if == NULL -> not supported yet */
  u16     snd_qty;                /* nr of system sounds */
  u08     snd_version_major;      /* start with 1.0 */
  u08     snd_version_minor;

/*************/
/* SECTION 4 */
/*************/
  SECTOR  option_00;            /* future use ... == NULL -> not used */
  SECTOR  option_01; 
  SECTOR  option_02;
  SECTOR  option_03;
  SECTOR  option_04;
  SECTOR  option_05;
  SECTOR  option_06;
  SECTOR  option_07;
  SECTOR  option_08;
  SECTOR  option_09;

/*************/
/* SECTION 5 */
/*************/
  u08      z_dummy01[228];
}YADL_ROOT_SECTOR;



/************************************************************************
**
** F A T
**
** starts at sector:   ROOT_SECTOR->fat_start
** nr of fat-entries:  ROOT_SECTOR->fat_qty 
**
**
** maximum disk size supported (2048 GB = 2 TB) 
** (only in conjunction with MAXTORS big drive technology - to be implemented later ;-)
**
** 2048 GB / 256 kb clusters --> gives a maximum of 0x800000 clusters (8388608d)
** -> upper byte in FAT values is free
** we code there the extra states
**
**
**
** adress calculation:
**
** to convert a cluster number into a sector address:
**
** shift left cluster number by 9
** add (u32) ROOT_SECTOR->sector_cluster_offset
**
*************************************************************************/

/* predefined FAT values */

#define YADL_FAT_INVALID  0xFFFFFFFF  /* dont change */ 
#define YADL_FAT_EMPTY    0xFE000000
#define YADL_FAT_FAULTY   0xFD000000
#define YADL_FAT_SYSTEM   0xFC000000

#define YADL_FAT_LAST     0xF0000000




/************************************************************************
**
** The S O N G B A S E  Structure
**
** note that there is a maximum of 0xFFFF songs inside a songbase,
** with array indices ranging from 0 to 0xFFFE
**
** so a songbase pointer of 0xFFFF is always guaranteed to be
** invalid / not set / not supported 
**
** songbase start is fixed, always at YADL_SEC_SONG_BASE 
** length is variable, nr of entries (not sectors!) is ROOT_SECTOR->songbase_qty
**
**
*************************************************************************/
#define YADL_LEN_ARTIST  44    /* ensure that sum of both is a multiple of 4 - to keep 80x86 happy*/
#define YADL_LEN_TITLE   44  

/* states needed inside yaPC */
#define YADL_STATE_EMPTY         0
#define YADL_STATE_TO_LOAD       2
#define YADL_STATE_LOADING       3
#define YADL_STATE_READY         0x10
#define YADL_STATE_NOT_LOADED    0x11

typedef struct
{
  u08      artist[YADL_LEN_ARTIST];
  u08      title[YADL_LEN_TITLE]; 
  
  CLUSTER  start;
  FLENGTH  length;              /* original filelength */
  u32      timestamp;           /* PC - Filetimestamp - not inserted yet*/

  u16      ref_ctr;             /* nr of playlists using that song */
  u16      play_time;           /* in seconds */

  u16      bitrate;             /* MP3 bitrate , if BIT 15 set == VBR  */
  u08      genre;               /* as stated in MP3 file - not filled or used yet ! */
  u08      state;               /* 0 slot free , 0x10 valid, (for PC only) 2 to be loaded / 3 loading */
  u16      next_artist;         /* pointer into songbase to (alphabetically) next title of this artist or new artist */
  u16      next_artist_grouped; /* pointer into songbase to (alphabetically) next artist in unique(grouped) list */
  u16      next_title;          /* pointer into songbase to (alphabetically) next song  */
  u16      start_offset;        /* leading Header part in MP3 file to be skipped */
  u08      z_dummy00[12];       /* not used yet */
}YADL_SONG_BASE_ENTRY;

/*************************************************************************
**
** OPTIONS inside bitrate field
**
**************************************************************************/

#define OPTION_BR_VBR     0x8000 /* this is a VBR file */ 
#define OPTION_BR_ID1_TAG 0x4000 /* this file has an MP3 tag at its end -> subtract 128 bytes from length for playback */

#define BITRATE_MASK 0x1FF       /* mask to extract "pure" bitrate */


/************************************************************************
**
** The P L A Y L I S T Structure
**
** all playlist functionality is placed in one file
**
** the startcluster and the number of embedded lists are stored in ROOT_SECTOR
** but the number of embedded playlists can be obtained from within the file itself 
** too by reading all playlists until the first list comes up with an empty name file
** empty =>  name[0] == 0
** 
** note that the playlist are stored here alphabetically
** 
** in case that there should be one day a sequence of playlists to be played
** (who knows) the playlists contain a pointer (index) to the next playlist to be played.
** note that there is a maximum of 0xFFFF playlists too so the index value of
** 0xffff has to be interpreted as "not set" or end of list
**
**
**
*************************************************************************/

#define YADL_LEN_PLAYLIST 32

typedef struct
{
  u08      name[YADL_LEN_PLAYLIST];

  u16      length_hours;        /* Length of playlist */
  u08      length_minutes;
  u08      length_seconds;
  
  FOFFSET  offset;              /* fileoffset of this list within the playlistfile */
  u16      entry_qty;           /* nr of entries in that particular list */
  u16      next_playlist;       /* -1 = STOP , else index of next list to be played */
  
  FOFFSET  system_sound_start;  /* corresponding relative FILE Offset in System Sound File */
  FLENGTH  system_sound_length; /* length of that file chunk inside the sys sound file */
  u08      z_dummy00[12];        /* not used yet */
}YADL_PLAY_LIST_ENTRY;


#endif

⌨️ 快捷键说明

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