The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Release Name: 0.9706
=======================

The weaken()ing code was failing since weaken() does not return TRUE.  (Tested
for no obvious memory leaks.)

Allow for backwacked \[ \] \\ in descriptor of, e.g., COMM[descriptor].

New configuration options:
		   encode_encoding_v1 decode_encoding_v1 decode_encoding_v2
		   decode_encoding_filename
		   decode_encoding_inf decode_encoding_cddb_file
		   decode_encoding_files encode_encoding_files
	(en/decode_encoding_files for ParseData; applicable to non-binary i/o).
Initialized from corresponding environment variables

Document environment variables.

translate_title_collection etc configuration values were not settable
(neither were they documented...).

New methods of ID3v2: frame_select_by_descr(), frame_have_by_descr(),
frame_list_by_descr(), frame_select_by_descr_simple().

New methods have_id3v2_frame_by_descr(), select_id3v2_frame_by_descr(),
frame_translate(), frames_translate(), shorten_person() in MP3::Tag.
interpolate() significantly simplified; new interpolation %{shP{NAME}}.

New type of interpolation: frame ids connected by &.  Slightly more readable
documentation of interpolate() and parse_rex().

New configuration settings: person_frames, and translate_person
(supported only by select_id3v2_frame_by_descr()).

Music_Translate_Fields.pm: much better detection of non-canonical names
(e.g., year removal), support for person names shortening.  New method
check_persons() for checking consistency of translation/shortening.
Piecewise translation for multiple authors in a field (separated by ', ',
'; ', or ' - ').  Will translate title_collection and other CDDB fields.

Music_Translate_Fields-rus.lst: better list of persons for bard repertoire
and audiobooks; allow "fixing" wrong years too; handle "translated" and
many more separators of multi-names; cursory support for cases (genitive);
support for disabling translation (#keep).

audio_rename.pl: transliterate cyrillic with unicode too.

New options -d, -e, -F for the script mp3info2; brush up the docs.

typeset_audio_dir: new option -c; new generated file *_backcover.tex; slightly
better conversion of ASCII to TeX; use 'textcomp' (another incompatible LaTeX
change...); new macros for skips about second-level headings; encapsulate
\addOnRight; ornaments in *_text.tex and *_cdbooklet.tex; commented out
support for title; begin merging together the code to generate different
documents; consistent columnseprule; better positioning of hrule's; template
to merge several lists into one document; document latex, dvips etc.

audio_rename.pl: support unicode cyrillic.

Release Name: 0.9705
=======================

New environment variables MP3TAG_DECODE_V1_DEFAULT, MP3TAG_DECODE_DEFAULT,
MP3TAG_ENCODE_V1_DEFAULT, MP3TAG_ENCODE_DEFAULT (0 or encoding name).
XXXX Not documented yet; does not cover all aspects (filenames, external
     files, Inf, CDDB files).
	v2 ENCODE (to illegal encodings) is not implemented yet.

Default for MP3TAG_DECODE_UTF8 is 1 (used for encoding too).

Encoding argument for v2->add_frame() is (finally!) implemented.

Text field of TXXX, USER, USLT, OWNE were wrongly marked as not encoded.

Setting lang=XXX via frame_select() or id3v2_select_frame() would result
in lang=xxx.

frame_select() returns the count of found frames if it is used for removal
of frames.

New parameter value 'hash' for get_frame().

New method frames_list() (variant of frame_select()).

Sanity check for tag size parameter in ID3v2.

Sanity check for wide characters in the prepared raw tag.

New method ->size for ::File.

More examples for update_tags().

Music_Translate_Fields: only the parsing logic remains; the data is
moved into separate files (encoding supported) Music_Translate_Fields*.lst
(should live alongside the .pm file).

typeset_audio_dir: new option -e; unify the charset logic; add utf8.

Add example/empty.mp3 (some MP3 applications do not accept "really empty"
MP3s; this one is "almost empty").

Release Name: 0.9704
=======================

Document why using "encoding" and "TPE1" mindlessly is a bad idea.

Cleaning up read support of v2.4.

Better error message for version mismatch.

Do not warn "not supported" any more if the footer is found (how could it be
"supported" anyway, except for skipping, which is already done, [was wrong]?).
(untested)

Extended header parsed for v2.4 too.	(untested)

Footer was treated wrong...  Apparently frame flags were extracted very wrong
as well... (untested)  Unknown frame flags are mapped to 'unknown_<letter>'.

Rename 'padding_size' field to 'buggy_padding_size' to avoid confusion with
ID3v2 padding (it is the padding after the tag [unrelated to the standard],
not the padding inside tag).

fits_tag(): return FALSE if data contains chars above 255.
update_tags(): better docs, new argument $force2.

mp3info2: in the standard report, "artist" was offset by one space.  New option
   -2.  README.shrink updated correspondingly.

typeset_audio_dir: more comments on duplex output.

eat_wav_mp3_header: new options -D for dry run, -M for finding .mp3 files.

Release Name: 0.9703
=======================
typeset_audio_dir: would not work without -B switch
	Add generation of cdbooklet with -B.
mp3info2: when reporting contents, print "Composer" and "Text" lines too.
	Without -I and -p, writes "Performer" line if TXXX{TPE1} is present.
	New option -r.
method interpolate() could return '' when ID3v2 tag was missing even if
	the tag would affect only a part of the output.
There was no way to inform the parser that it is OK if the parse data
	is coming from file, and the file does not exist.  Add 'F' flag...


Release Name: 0.9702
=======================
examples/type_mp3_dir.pl:
	new name typeset_audio_dir.pl;
	Fully document;
	Change the semantic of numbers in .top_heading files by 1;
	New option -n;
	Generate 1st level header for all "toplevel" dirs;
	TeXify ", ` and ';
	Add \hrule's for default toplevel headings.
	-@ was not working;
Correct rounding of total_secs_int().
Truncated version in total_secs_int_trunc().
Rename total_millisecs_int() to total_millisecs_int_fetch(),
	likewise for total_secs_fetch().
New method total_millisecs_int() (with caching).
Cache duration in ms.
New escape: %M (total millisecs, integer).
New confiration variable: update_length.
Will update TLEN field if needed (governed by `update_length').
Alternation inside escapes implemented.
New file README.shrink with recommendations on how to fix results of
the bug with extra unmarked 0-padding.
Remove trailing .pl from names of typeset_audio_dir, mp3info2.
Install typeset_audio_dir, mp3info2 unless one of options -n or LIB=
is given to Makefile.PL.

Release Name: 0.9701
=======================

-P option of mp3info2 would ignore trailing empty parse patterns
  (not very restrictive, since to succeed, pattern should have a set-field,
  or match-exactly field; workaround: append @={U0}, and do not set U0).

When updating ID3v2 tag without growing the file, the tag length would
not include padding; thus the following update would not use the padding ==>
tag size leak.

New configuration options: id3v2_minpadding, id3v2_sizemult, id3v2_shrink,
id3v2_mergepadding (the first two have new defaults: 128 and 512; was 2K and
4K).

Close file for write of ID3v2 tag as early as possible.

Release Name: 0.97
=======================

Better docs for add_frame(), set_id3v2_frame(), for configuration parameter
id3v2_frame_empty_ok, parse_minmatch.

frame_select() now returns undef if no frame is found; likewise for
select_id3v2_frame(); better behaviour with very low number of arguments.

When interpolating %{COMM[text]}, use lang='', not undef (otherwise
answer is returned as hash).

Interpolation would interpret second % in '%%02n' as fill character.

Flag 'b' of ParseData would disable whitespace stripping from the data to
match, but not from matches.

->get_config() would not work as class method.

Ask MP3::Info to 'try_harder'; needed with very long ID3v2 headers...

Decoding Unicode was not flexible enough: now configured by two environment
variables: MP3TAG_DECODE_UNICODE (default 1) to enable decoding; the
target of decoding is determined by MP3TAG_DECODE_UTF8: if 0 (default), decoded
values are byte-encoded UTF-8 (every Perl character contains a byte of
UTF-8 encoded string); otherwise it is a native Perl Unicode string.

Language=XXX is the *official* designation of unknown language.

Make dependency for ID3v2-Data.pod on Tag/ID3v2.pm.

Warn in mp3info2 if -P is used without ParseData in autoinfo.  Document
example of attaching lyrics to audio file.

CDDB_File could generate warnings for files without DGENRE field.

type_mp3_dir: new macro \hourmark, exchange ' and '' for minutes/sec.

Release Name: 0.96
=======================

A bug fix by Ben Bennett for 2.4 support.

Having a genre of the form '(2345)Some new type' would emit a warning.

UTF encoded fields are decoded by default.  Set MP3TAG_ENCODING=0 in
environment to disable.

Add ID3v2-Data.pod to MANIFEST to avoid circular dependency (XXXX bug:
it is generated using the installed version of ID3v2.pm, not the
current version).

Release Name: 0.95
=======================

After removing several of repeated frames, get_frame(s) could get confused.
So could the code using get_frame(s).  Now better documented, and fixed.

New method ->is_modified() of ID3v2.

New method ->as_bin() of ID3v1 and ID3v2.

New methods ->is_id3v2_modified(), ->get_id3v2_frames(), ->select_id3v2_frame(),
->have_id3v2_frame(), ->get_id3v2_frame_ids() of MP3::Tag.

Some `next's needed to be replaced by `return' in mp3info2 and audio_rename.

mp3info2 would not decide that an edit is not needed if an ID3v2 frame was
modified directly.

Avoid re-parsing by ParseData more aggressively (10x speedup in one complicated
real-life example).

set_id3v2_frame() and update_tags() were assuming that get_tags() was already
called.

File->write() could lead to disaster with -l.		!!!!

New options 'b', 'B', 'o', 'O', 'D' for ParseData.  With 'n', 'l' ParseData
does not ignore empty trailing lines any more.

New %-interpolations: %{ID3v1} for the tag as a whole, same for ID3v2.

Be more strict during interpolation: do not recognize WORD1 as a valid short
name of ID3v2 frame.

Two new example scripts: mp3_total_time.pl, eat_wav_mp3_header.pl.

Mention example scripts in documentation of MP3::Tag.

Release Name: 0.94
=======================

The example of the "long" form of ID3v2-comment setting API has arguments swapped.

New methods ->frame_select(), ->frame_have() of ID3v2.

New methods ->pure_filetags() and ->update_tags() of MP3::Tag.

New config variables id3v2_missing_fatal (it was as if it was defaulting to
TRUE; now defaults to FALSE), parse_minmatch.

New test files in t/: v2_comments.t update_tags.t parser.t 

New escape %{COMM(rus,eng,xxx,#4)[short_description]} (chooses a comment with
"short_description" descriptor in the specified list of languages; #4 means
4th comment field, or COMM03; empty language means any language.)  Works
as a condition for conditional interpolation too, and as a target of parsing
and ParseData.  Similarly for other frames which have 'Language' and/or
'Description' fields.

Some POD formatting fixed.

Setting "extra" ID3v2 frames was not immediately visible (only after write
and re-read from the file).

COMM's short-description was not marked as 'encoded' (due to a misprint).

UNCOMPATIBLE CHANGEs:

COMM's frame short-description now sits on the key "Description", not "short".
[If you want backward compatibility, check both keys.]

get_frame() considers frames the only content of which is a URL as a "simple
frame"; likewise for frame_select(), but it also considers frames with _Data
only as "simple frames".

Release Name: 0.93
=======================

More robust processing of "Recorded..." in CDDB_File.

Better error message when parse expression has some `=' omitted.

When parsing with nothing to set, would emit "Unsupported reg..." (regmatch
would return 1 elt if no capturing parens present).

When rewriting id3v2 tag, protect against $\ being set.

Move test.pl to t/mp3tags.t, add t/set_v2.t

Allow arbitrary escapes of the form %{ABCD} or %{ABCD03} in the method parse()
etc; here ABCD is a 4-letter word.

New config parameter id3v2_frame_empty_ok.

It is possible to set individual id3v2 frames via ParseData; use %{TIT1} or
some such.  Setting to an empty string deletes the frame if config
parameter id3v2_frame_empty_ok is true.

Uses TCOM or TPE3 to find "artist" ($mp3->artist) too.

New option -R (recurse into directories) for example scripts.

New example script type_mp3_dir to produce a TeX file with contents of
directories.  (Put files `.content_comment' into a directory to include comments
specific for the directory layout.)

Connect parts of comment by \n if \n is already present there.

`Recorded: 1980,1985,1992' was not recognized.

Allow date only at start/end of the comment.

Release Name: 0.92
=======================

Include a fix by Marco Moreno of Cwd::abspath() not working on files (on
some architectures).

Release Name: 0.91
=======================

CDDB_File was removing whitespace on the boundary of continuation fields.

get_user() calls ParseData->parse() to populate the userdata

if $ENV{MP3TAG_TEST_WEAKEN}, will not have a workaround against broken weakrefs
	(currently tests fail!)

New %-escapes v L r q Q S m s C p o u (require MP3::Info module).

New methods mpeg_version() mpeg_layer() mpeg_layer_roman() is_stereo()
is_vbr() bitrate_kbps() frequency_Hz() frequency_kHz() size_bytes()
total_secs() total_secs_int() total_mins() leftover_secs()
leftover_msec() time_mm_ss() is_copyrighted() is_copyrighted_YN()
frames_padded() frames_padded_YN() channel_mode_int() frames()
frame_len() vbr_scale() (require MP3::Info module).

The year() method of ID3v2 takes/returns timestamps in human-readable form;
parse() recognizes the same formats for %y if option year_is_timestamp is TRUE
(default).

New option 'intact' to get_frame() of ID3v2.

Support YEAR, ID3Y, ID3G in EXTD, EXTT* fields of CDDB_File.  Support also
an alternative syntax "Recorded"/"Recorded on"/"Recorded in"/ with the format
of the date recognized by ID3v2::year(), or just a date field without a prefix.
The declarations of the former form are stripped from the returned comment.

New fields artist_collection, title_track, comment_collection, comment_track
in CDDB_File and corresponding accessor methods in MP3::Tag, and corresponding
escapes aC, tT, cC, cT for interpolate().

New configuration variables 'year_is_timestamp', 'comment_remove_date',
'translate_*' (for different values of *).

New handler module LastResort; currently it uses artist_collection() as comment
if comment is not otherwise defined.

New example scripts audio_rename and mod/Music_Translate_Fields.pm.

The example script mp3info2 will use Music_Translate_Fields.pm (if found)
to postprocess the resulting tag fields via translate_*() methods.

Do not load Compress::Zlib unless when processing compressed data.

Release Name: 0.9
=======================

Revision history for Perl modules MP3::Tag, MP3::Tag::ID3v1, MP3::Tag::ID3v2, MP3::Tag::File,
             and for Perl program tk-tag

Changes:

* Bugfix for ID3v2.pm:
  - Added support for reading ID3v2.2 and ID3v2.4 tags (alpha stage!!) and converting them to ID3v2.3
  - Bugfix for unsynchronization (thanks to Ian Beckwith)
  - Bugfix for number-handling in frames
  - Bugfix for frame compression
  - Set unsynchronization flag only, if unsynchronization was done and changed anything

* Bugfix for ID3v1.pm:
  - genres didn't return the id if the genre name was passed as parameter, but returned
    the same name

* Makefile.PL:
  - overriding the manifypods() function in MakeMaker to add ID3v2-Data.pod to the MAN3PODS hash
    (thanks to Dagfinn Ilmari Mannsaker)

* Added copyright text, using Perl Artistic License

Thanks to Ilya Zakharevich for the following changes:

* Three new modules MP3::Tag::Inf, MP3::Tag::ParseData, and
  MP3::Tag::CDDB_File added

* Tag.pm:
  - autoinfo() method returns the info for all ID3v1 tags;
  - autoinfo() method may return the info which tag is obtained from
    which source;
  - Methods title(), author() etc (one per each ID3v1 tag) exist and
    have uniform interface through all the subpackages;
  - method song() is renamed to title(); method read_filename() is
    renamed to parse_filename(); backward compatible name still
    preserved;
  - config() subroutine can now change all the arbitrary decisions;
  - new methods interpolate() for tag interpolation into strings and
    parse(), parse_rex() for an inverse operation;
  - new subpackage `__hasparent' to treat cyclic object dependencies;
  - per-object configuration;
  - new configuration options extension, parse_data, parse_split,
    parse_filename_ignore_case, parse_filename_merge_dots, parse_join;
  - a way to store and query user-supplied data inside the object (may
    be used as scratch space when parsing);
  - new methods get_config(), get_user(), set_user(), parse_prepare(),
    parse_rex_prepare(), parse_rex_match(), filename(), abs_filename(),
    filename_nodir(), filename_noextension(), filename_nodir_noextension(),
    abs_filename_noextension(), dirname(), filename_extension(),
    filename_extension_nodot(), dir_component().

* ID3v1.pm:
  - new ID3v1 method fits_tags() to check whether the info can be
    placed into an ID3v1 tag
  - If no track given use automatically ID3v1.0 tag with longer comment
  - open() file if needed; do not close() close during new().

* ID3v2.pm:
  - allow multiple frames to be returned by get_frame() in ID3v2;
  - new method get_frames() with better order of returned values (comparing
    to get_frame);
  - get_frame_ids() in ID3v2 improved to take new argument 'truename' to
    simplify looping over repeated frames;
  - simpler treatement of sync; fix uncorrect calculation of padding length;
  - overwrite the tail of the previously present tag with 0s;
  - a couple of new v2.4 field names added.

* File.pm:
  - more robust parsing of filenames; year can be read from filename if
    appended (in parentheses) to author or title; filename can be
    F<.wav> as well.
  - support file names starting with track numbers as in 03_This_is_the_title.mp3
  - support track_title.ext and title_track.ext formats with one-word title too.
  - new method filename();
  - use the 'extension' configuration variable to strip extension.

* misprints in the docs corrected and some general harmonization of function and
  field names in the different modules

* new example script mp3info2 (which provides most of functionality of the
  "standard" mp3info utility, and much more).

Release Name: 0.40
==================
Changes:

* Updated documentation for MP3::Tag, MP3::Tag::ID3v1, MP3::Tag::ID3v2 and MP3::Tag::ID3v2-Data 

* Renamed some functions. The old names will still work, but try to use the new names.
  The following names were changed: 

  - MP3::Tag::getTags() to MP3::Tag::get_tags() 
  - MP3::Tag::newTag() to MP3::Tag::new_tag() 
  - MP3::Tag::ID3v1::removeTag() to MP3::Tag::ID3v1::remove_tag() 
  - MP3::Tag::ID3v1::writeTag() to MP3::Tag::ID3v1::write_tag() 
  - MP3::Tag::ID2v2::getFrameIDs() to MP3::Tag::ID3v2::get_frame_ids() 
  - MP3::Tag::ID2v2::getFrame() to MP3::Tag::ID3v2::get_frame() 
  
* Bugfix for ID3v2.pm:
  - getFrame() returned "undef" as a string instead of simple undef
  - artist() produced an error when TPE1 is missing in TAG
 
* Bugfix for Tag.pm:
  - DESTROY() checked only if $mp3->obj{filename} exists and not if it is defined before trying to 
    close it  

* Bugfix for ID3v1.pm:
  - genres() expected an id3v1-object as first parameter and a genre
    only as second parameter. Now the object can be omitted as in a call like
    MP3::Tag::ID3v1->genres($genre) used by Tag.pm and ID3v2.pm

* bugfix for File.pm:
  - Filenames may contain surrounding whitespaces now

Release Name: 0.30
==================
Changes:
* Tag.pm
  - autoinfo() function added. This returns artist/songtitle/track/album.
    It tries to find this information in an ID3v1 or ID3v2 tag or tries 
    to extract it from the filename. The order in which this happens
    can be configured with the new config() function.
* ID3v2.pm
  - four new functions: artist(), song(), track() and album(). These
    are included for compability with the ID3v1 and filename module.
* Tag.pm / Tag::File.pm
  - All file access routines are collected in an extra modul now.
    This prevents circular references between Tag.pm and the ID3v..pm
    modules. These circular references prevented Perl from calling
    the destructor for mp3-objects.
* tk-tag
  - Loading/Saving of binary data in frame-fields is supported now
  - tk-tag uses now the new what_data functionally of ID3v2 to offer 
    BrowseEntrys for TCON and TFLT and also for parts of APIC and COMR
  - Set Filename uses now the actual contents of the Tags not the old 
    saved one
  - Set Filename from ID3v2-Tag works now at least with Artist (%a),
    Album(%l) and Song (%s)
* ID3v2::what_data returns now also information about possible restricted
  input for some frame fields (APIC; TCON; COMR; TFLT are supported yet).

Release Name: 0.25
==================
Changes:

* Bug-fix for MP3::Tag
  If you created several mp3-objects for different files, the filehandles
  for each file were not used correctly. Thanks to hakimian for reporting
  this bug.
* Bug-fix for ID3v2::remove_tag()
  It was tried twice to rename one temp-file after removing the tag.
  Thanks to Brent Sarten <bsarten@bigfoot.com> for reporting this.
* Bug-fix for ID3v2::add_tag()
  When adding a second (or third, ...) frame of a kind, a wrong header
  could be written for this frame
* Bug-fix for tk-tag 
  When opening a new file, the contents of the ID3v2 tag of the last file
  would be copied to the ID3v2 tag of the new file for all frames which
  existed in the last file, but not in the new one.

Release Name: 0.21
==================
Changes:

* tk-tag has lots of new functions (see tk-tag README)
* getFrameIDs returns now always a hash ref of all existing frames, not only
  when called the first time
* Some minor problems in documentation are corrected.
* ID3v2::add_frame returns the name of the newly created frame, which can
  differ from the short name when already such a frame exists.

Release Name: 0.20 (beta)
========================
Changes:

--due to problems when run at windows:
  * Added a second seek to ID3v1::write_tag, as windows writes at a wrong 
    position otherwise
  * Setting Filehandle to binmode after opening a mp3 file 
  * ID3v2: write_tag creates a temp file (if neccessary) now in the same
    directory where the original mp3 files is located and not in /tmp

* Added tk-tag.pl, a graphical interface for MP3::Tag. tk-tag.pl is a alpha
  version
* Added a new manpage MP3::Tag::ID3v2-Data which contains information about
  the ID3v2 frames and the data returned by MP3::Tag::Id3v2::getFrame() 
* Frames RVRB ("Reverb"), COMR ("Commercial frame"), AENC ("Audio encryption"),
  GRID ("Group identification registration"), RBUF ("Recommended buffer size")
  and SYTC ("Synchronized lyric/text") are now supported	
* Added some test to test.pl for creating new tags
* ID3v2::getFrameIDs returns now a hash reference, which contains the found
  frames. The keys are the 4 byte codes of the frames, which are needed for
  getFrame . The according values are the english (long) names of the frames.
* ID3v2::write_tag - Updating tagsize after writing tag 
* ID3v1::all() returns in array context all fields, otherwise only the song
* MP3::ID3v1::write_tag didn't returned an error if a file couldn't be opened
  for writing. Now it does.
* Renamed MP3::TAG to MP3::Tag following a suggestion of ANDK from CPAN
* Makefile.PL : Added that Compress::Zlib and File::Basename is needed for 
  installation of MP3::Tag

Release Name: 0.1 (beta)
========================
Changes:
* Added documentation to the modules

* Writing/removing of ID3v2.3 tags is supported now 
* Adding, changing, removing frames of ID3v2.3 is supported

* Changed directory structure
* Added file for proper install of modules


Release Name: 0.2-alpha
=======================
Changes: 
* ID3v2.3 compressed frames are supported now 
* changed directory structure, support librarys for MP3::Tag are now in a
  subdirectory 
* tagged.pl calls xview to show pictures, which were found in ID3v2 tags
  (sorry, not configurable at the moment, but easy to change in tagged.pl)

Release Name: 0.1-alpha
=======================
This is the first alpha version. It contains perl modules to
read ID3v1/ID3v2 tags, but they are still lacking a lot of
features. 

* Reading / Writing ID3v1 works
* Reading of most frames of ID3v2.3 works

Included is a demo program tagged.pl, and a program to change ID3v1
tags and to set automatically the filename of a mp3 file: tagit.pl See
README.txt for details. More documentation is still lacking. Sorry.



MP3::Tag can be found at http://sourceforge.net/projects/tagged