(i) I don't see clearly the interest of the header (not in APE 1.000); the only thing that I found is that you can get the lenght of the tag without reading it in the header/footer. But the lenght is still in the head/foot in ape 2... About tag size, Frank Klemm said: 'to be as compatible as possible with 1.000' ???? knowing that the 'ape info' cannot read ape 2, what's the point? Here it seems that backward compatibility shall be assumed by the app that read the tag; what did I miss? Token without a header can't be parsed by a L1 grammar lexer, if they have arbitrary size they can't be parsed by any Ln grammar lexer. (ii) What's the point in storing binary data in a tag? I don't think storing images in files is a good idea (and Klemm seems to agree that 'long' tags is not a good idea). So what's the use? Text data and binary data can have a size from 0 bytes up to 2^32-1 bytes. This is the restriction of the tag format itself. There's another restriction of 8 KByte for all tags to avoid too much trouble when streaming data. An 8 Kbyte tag is the limit for a 112 kbps MPEG-4 AAC stream over an ADSL connection with a buffer delay of 3 seconds. (iii) Ape 2 is free in specifying fields; but again is it really a good thing to store a large number of information in a file? You can store 1 tag item with a length of 1 byte in the tag. What's wrong with a flexible file format and what's better with a castated file format? JPEG2000 can be store images from 1 x 1 pixel up to 4294967295 x 4294967295 pixel. (iv) I wrote a php (the only 'modern' langage I know) script that read/write/erase ape tag 1/2 (text only) in files. If anybody wants it just ask; and if anybody wants to rewrite it 'professional', I would be glad. I didn't have much problems to do it, so I'm waiting with much impatience for mac info to deal with ape 2. Is there a difficulty here? I don't know at all how to write a winamp plug... C++ ?? but would gladly learn or contribute if I can. (v) Again, Frank Klemm said: "the items should be sorted by importance/byte, but this is not feasible." Why??? And why is this not feasible??? I'm confused... Sorted in the tag? It's feasible... I don't understand at all. Tags should be sorted by importance. To evaluate this is impossible for a computer, may be even for a human, because it's also a question of personal taste. So the easiest and handy approximation of that is to store tag items in ascending order of their size. A streamserver has to drop tag items when it can't be guaranteed that the tag items do not generate a drop out. Dropping should drop only lesser important tag items. (vi) I didn't understand what Klemm explains about 'storing cd information'; I developped my own solution, again with php: I'm storing discographical informations (including images) in a mysql db, and the script automatically fill the tag from these informations. The point of the whole project is to have a php/html front-end that dynamically manage a cd collection (rip-encode-identify/drop/edit-infos/display/send play-order); I'm interested in knowing what other solution shall be used in order to manage large amount of cds, and if using an external database is the good way to proceed. CD related information should be stored in a CD releated container, not in track related container. (vii) Does anybody know where to find the id3v2 specs (does www.id3.org disappeared??) DIC. Documented in C and changes from time to time. There's a documentation, but a parser written with the help of this documentation didn't work. (viii) Why is the id3v2 tag stored at the beginning of the file (for streaming reasons?), and why is it 'unrecommended' for APE? ID3V2.4 tags can be stored at the beginning and at the end of the file. Tags at the beginning of a _file_: 1) break compatibility, see the trouble with ID3V2 and AAC, MPEG-4, AAC, OGG. Tags at the beginning must be a part of the file format specification, if they are not a part of the file format specification, files have not to be tagged with it. 2) generate a lot of file I/O when tagging (there are some methods to reduce this, but these increases complexity and make _verification_ nearly impossible). 3) need a lot of free space when tagging large files (most implementation use a in-place tagging mechanism which destory the file when the computer crashs or there is not enough disk space). Points 2) and 3) deappears when file systems are generally supporting inserting and removing drom inside a file. (ix) I don't see the use of the 'item number' in the foot/head. If we got the tag lenght (deducing it from the position of the header or reading it in the footer), and the lenght of each item value, we don't need it (ape 1 or 2)... ?? or am I lost somewhere (x) I disagree. I store images and other goodies in the tags. There's no reason to be afraid of 30kb of extra data with a modern computer ... images should never be added to an audio file. - if the data is important for the audio-visual representation, an additional container format should be used to store data and relations between the data. A well designed example is the MPEG-4 system stream. Tags should be tags and not the worst possible concept of a container format. - file format for images is *.PNG or *.JPG. These are the only format external programs can understand. I don't want to have tons of special programs to edit embedded data in tags. I want to use general purpose programs available on all platforms. This should include old computers which are still in use. - Where I should store the front image of a CD? On track 1? On track 2? On track 17? On every track? - My front images have typically 500 Kbyte...1 Mbyte per image. There are 2 to 17 images per CD. (xi) Is the delay in releasing an Ape2-able-plug related to the utf-8 encode? A utf-8 encoder and decoder is written with 5 minutes. So utf-8 delays release by about 5 minutes. ----------------------------------------------------------------------------- static unsigned char* utf8char ( unsigned char* dst, unsigned long value ) { if ( value == '\r' || value == 0xFFFE || value == 0xFFFF ) { ; } else if ( value < 0x80 ) { *dst++ = value; } else if ( value < 0x800 ) { *dst++ = 0xC0 + ((value >> 6) & 0x1F); *dst++ = 0x80 + ((value >> 0) & 0x3F); } else if ( value < 0x10000 ) { *dst++ = 0xE0 + ((value >> 12) & 0x0F); *dst++ = 0x80 + ((value >> 6) & 0x3F); *dst++ = 0x80 + ((value >> 0) & 0x3F); } else if ( value < 0x200000 ) { *dst++ = 0xF0 + ((value >> 18) & 0x07); *dst++ = 0x80 + ((value >> 12) & 0x3F); *dst++ = 0x80 + ((value >> 6) & 0x3F); *dst++ = 0x80 + ((value >> 0) & 0x3F); } else if ( value < 0x4000000 ) { *dst++ = 0xF8 + ((value >> 24) & 0x03); *dst++ = 0x80 + ((value >> 18) & 0x3F); *dst++ = 0x80 + ((value >> 12) & 0x3F); *dst++ = 0x80 + ((value >> 6) & 0x3F); *dst++ = 0x80 + ((value >> 0) & 0x3F); } else if ( value < 0x80000000 ) { *dst++ = 0xFC + ((value >> 30) & 0x01); *dst++ = 0x80 + ((value >> 24) & 0x3F); *dst++ = 0x80 + ((value >> 18) & 0x3F); *dst++ = 0x80 + ((value >> 12) & 0x3F); *dst++ = 0x80 + ((value >> 6) & 0x3F); *dst++ = 0x80 + ((value >> 0) & 0x3F); } return dst; } -----------------------------------------------------------------------------