1Meta Data Formats
2=================
3
4Although it's more convenient to manipulate the high-level
5:class:`audiotools.MetaData` base class, one sometimes needs to be
6able to view and modify the low-level implementation also.
7
8ApeTag
9------
10
11.. class:: ApeTag(tags[, contains_header][, contains_footer])
12
13   This is an APEv2_ tag used by the WavPack, Monkey's Audio
14   and Musepack formats, among others.
15   During initialization, it takes a list of :class:`ApeTagItem` objects
16   and optional ``contains_header``, ``contains_footer`` booleans.
17   It can then be manipulated like a regular Python dict
18   with keys as strings and values as :class:`ApeTagItem` objects.
19   Note that this is also a :class:`audiotools.MetaData` subclass
20   with all of the same methods.
21
22   For example:
23
24   >>> tag = ApeTag([ApeTagItem(0, False, 'Title', u'Track Title'.encode('utf-8'))])
25   >>> tag.track_name
26   u'Track Title'
27   >>> tag['Title']
28   ApeTagItem(0, False, 'Title', 'Track Title')
29   >>> tag['Title'] = ApeTagItem(0, False, 'Title', u'New Title'.encode('utf-8'))
30   >>> tag.track_name
31   u'New Title'
32   >>> tag.track_name = u'Yet Another Title'
33   >>> tag['Title']
34   ApeTagItem(0, False, 'Title', 'Yet Another Title')
35
36   The fields are mapped between :class:`ApeTag` and
37   :class:`audiotools.MetaData` as follows:
38
39   =============== ================================
40   APEv2           Metadata
41   --------------- --------------------------------
42   ``Title``       ``track_name``
43   ``Track``       ``track_number``/``track_total``
44   ``Media``       ``album_number``/``album_total``
45   ``Album``       ``album_name``
46   ``Artist``      ``artist_name``
47   ``Performer``   ``performer_name``
48   ``Composer``    ``composer_name``
49   ``Conductor``   ``conductor_name``
50   ``ISRC``        ``ISRC``
51   ``Catalog``     ``catalog``
52   ``Copyright``   ``copyright``
53   ``Publisher``   ``publisher``
54   ``Year``        ``year``
55   ``Record Date`` ``date``
56   ``Comment``     ``comment``
57   =============== ================================
58
59   Note that ``Track`` and ``Media`` may be "/"-separated integer values
60   where the first is the current number and the second is the total number.
61
62   >>> tag = ApeTag([ApeTagItem(0, False, 'Track', u'1'.encode('utf-8'))])
63   >>> tag.track_number
64   1
65   >>> tag.track_total  # None
66   >>> tag = ApeTag([ApeTagItem(0, False, 'Track', u'2/3'.encode('utf-8'))])
67   >>> tag.track_number
68   2
69   >>> tag.track_total
70   3
71
72.. classmethod:: ApeTag.read(file)
73
74   Takes an open file object and returns an :class:`ApeTag` object
75   of that file's APEv2 data, or ``None`` if the tag cannot be found.
76
77.. method:: ApeTag.build(writer)
78
79   Given a :class:`audiotools.bitstream.BitstreamWriter`
80   object positioned at the end of the file,
81   this writes the ApeTag to that stream.
82
83.. method:: ApeTag.total_size()
84
85   Returns the minimum size of the entire APEv2 tag, in bytes.
86
87.. class:: ApeTagItem(item_type, read_only, key, data)
88
89   This is the container for :class:`ApeTag` data.
90   ``item_type`` is an integer with one of the following values:
91
92   = =============
93   1 UTF-8 data
94   2 binary data
95   3 external data
96   4 reserved
97   = =============
98
99   ``read_only`` is a boolean set to ``True`` if the tag-item is read-only.
100   ``key`` is an ASCII string.
101   ``data`` is a regular Python string (not Unicode).
102
103.. method:: ApeTagItem.build()
104
105   Returns this tag item's data as a string.
106
107.. classmethod:: ApeTagItem.binary(key, data)
108
109   A convenience classmethod which takes strings of key and value data
110   and returns a populated :class:`ApeTagItem` object of the
111   appropriate type.
112
113.. classmethod:: ApeTagItem.external(key, data)
114
115   A convenience classmethod which takes strings of key and value data
116   and returns a populated :class:`ApeTagItem` object of the
117   appropriate type.
118
119.. classmethod:: ApeTagItem.string(key, unicode)
120
121   A convenience classmethod which takes a key string and value Unicode
122   and returns a populated :class:`ApeTagItem` object of the
123   appropriate type.
124
125FLAC
126----
127
128.. class:: FlacMetaData(blocks)
129
130   This is a FLAC_ tag which is prepended to FLAC and Ogg FLAC files.
131   It is initialized with a list of FLAC metadata block
132   objects which it stores internally as a list.
133   It also supports all :class:`audiotools.MetaData` methods.
134
135   For example:
136
137   >>> tag = FlacMetaData([Flac_VORBISCOMMENT(
138   ...                     [u'TITLE=Track Title'], u'Vendor String')])
139   >>> tag.track_name
140   u'Track Title'
141   >>> tag.get_block(Flac_VORBISCOMMENT.BLOCK_ID)
142   Flac_VORBISCOMMENT([u'TITLE=Track Title'], u'Vendor String')
143   >>> tag.replace_blocks(Flac_VORBISCOMMENT.BLOCK_ID,
144   ...                    [Flac_VORBISCOMMENT([u'TITLE=New Track Title'], u'Vendor String')])
145   >>> tag.track_name
146   u'New Track Title'
147
148.. method:: FlacMetaData.has_block(block_id)
149
150   Returns ``True`` if the given block ID integer is present
151   in this metadata's list of blocks.
152
153.. method:: FlacMetaData.add_block(block)
154
155   Adds the given block to this metadata's list of blocks.
156   Blocks are added such that STREAMINFO will always be first.
157
158.. method:: FlacMetaData.get_block(block_id)
159
160   Returns the first instance of the given block ID.
161   May raise :exc:`IndexError` if the block ID is not present.
162
163.. method:: FlacMetaData.get_blocks(block_id)
164
165   Returns all instances of the given block ID as a list,
166   which may be empty if no matching blocks are present.
167
168.. method:: FlacMetaData.replace_blocks(block_id, blocks)
169
170   Replaces all instances of the given block ID
171   with those taken from the list of blocks.
172   If insufficient blocks are found to replace,
173   this uses :meth:`FlacMetaData.add_block` to populate the remainder.
174   If additional blocks are found, they are removed.
175
176.. method:: FlacMetaData.blocks()
177
178   Yields a set of all blocks this metadata contains.
179
180.. classmethod:: FlacMetaData.parse(reader)
181
182   Given a :class:`audiotools.bitstream.BitstreamReader`
183   positioned past the FLAC file's ``"fLaC"`` file header,
184   returns a parsed :class:`FlacMetaData` object.
185   May raise :exc:`IOError` or :exc:`ValueError` if
186   some error occurs parsing the metadata.
187
188.. method:: FlacMetaData.raw_info()
189
190   Returns this metadata as a human-readable Unicode string.
191
192.. method:: FlacMetaData.size()
193
194   Returns the size of all metadata blocks
195   including the 32-bit block headers
196   but not including the file's 4-byte ``"fLaC"`` ID.
197
198STREAMINFO
199^^^^^^^^^^
200
201.. class:: Flac_STREAMINFO(minimum_block_size, maximum_block_size, minimum_frame_size, maximum_frame_size, sample_rate, channels, bits_per_sample, total_samples, md5sum)
202
203   All values are non-negative integers except for ``md5sum``,
204   which is a 16-byte binary string.
205   All are stored in this metadata block as-is.
206
207.. data:: Flac_STREAMINFO.BLOCK_ID
208
209   This metadata's block ID as a non-negative integer.
210
211.. method:: Flac_STREAMINFO.copy()
212
213   Returns a copy of this metadata block.
214
215.. method:: Flac_STREAMINFO.raw_info()
216
217   Returns this metadata block as a human-readable Unicode string.
218
219.. classmethod:: Flac_STREAMINFO.parse(reader)
220
221   Given a :class:`audiotools.bitstream.BitstreamReader`, returns a parsed :class:`Flac_STREAMINFO` object.
222   This presumes its 32-bit metadata header has already been read.
223
224.. method:: Flac_STREAMINFO.build(writer)
225
226   Writes this metadata block to the given :class:`audiotools.bitstream.BitstreamWriter`,
227   not including its 32-bit metadata header.
228
229.. method:: Flac_STREAMINFO.size()
230
231   Returns the size of the metadata block,
232   not including its 32-bit metadata header.
233
234PADDING
235^^^^^^^
236
237.. class:: Flac_PADDING(length)
238
239   Length is the length of the padding, in bytes.
240
241.. data:: Flac_PADDING.BLOCK_ID
242
243   This metadata's block ID as a non-negative integer.
244
245.. method:: Flac_PADDING.copy()
246
247   Returns a copy of this metadata block.
248
249.. method:: Flac_PADDING.raw_info()
250
251   Returns this metadata block as a human-readable Unicode string.
252
253.. classmethod:: Flac_PADDING.parse(reader)
254
255   Given a :class:`audiotools.bitstream.BitstreamReader`, returns a parsed :class:`Flac_PADDING` object.
256   This presumes its 32-bit metadata header has already been read.
257
258.. method:: Flac_PADDING.build(writer)
259
260   Writes this metadata block to the given :class:`audiotools.bitstream.BitstreamWriter`,
261   not including its 32-bit metadata header.
262
263.. method:: Flac_PADDING.size()
264
265   Returns the size of the metadata block,
266   not including its 32-bit metadata header.
267
268APPLICATION
269^^^^^^^^^^^
270
271.. class:: Flac_APPLICATION(application_id, data)
272
273   ``application_id`` is a 4-byte binary string.
274   ``data`` is a binary string.
275
276.. data:: Flac_APPLICATION.BLOCK_ID
277
278   This metadata's block ID as a non-negative integer.
279
280.. method:: Flac_APPLICATION.copy()
281
282   Returns a copy of this metadata block.
283
284.. method:: Flac_APPLICATION.raw_info()
285
286   Returns this metadata block as a human-readable Unicode string.
287
288.. classmethod:: Flac_APPLICATION.parse(reader)
289
290   Given a :class:`audiotools.bitstream.BitstreamReader`, returns a parsed :class:`Flac_APPLICATION` object.
291   This presumes its 32-bit metadata header has already been read.
292
293.. method:: Flac_APPLICATION.build(writer)
294
295   Writes this metadata block to the given :class:`audiotools.bitstream.BitstreamWriter`,
296   not including its 32-bit metadata header.
297
298.. method:: Flac_APPLICATION.size()
299
300   Returns the size of the metadata block,
301   not including its 32-bit metadata header.
302
303SEEKTABLE
304^^^^^^^^^
305
306.. class:: Flac_SEEKTABLE(seekpoints)
307
308   ``seekpoints`` is a list of
309   ``(PCM frame offset, byte offset, PCM frame count)`` tuples
310   for each seek point in the seektable.
311
312.. data:: Flac_SEEKTABLE.BLOCK_ID
313
314   This metadata's block ID as a non-negative integer.
315
316.. method:: Flac_SEEKTABLE.copy()
317
318   Returns a copy of this metadata block.
319
320.. method:: Flac_SEEKTABLE.raw_info()
321
322   Returns this metadata block as a human-readable Unicode string.
323
324.. classmethod:: Flac_SEEKTABLE.parse(reader)
325
326   Given a :class:`audiotools.bitstream.BitstreamReader`, returns a parsed :class:`Flac_SEEKTABLE` object.
327   This presumes its 32-bit metadata header has already been read.
328
329.. method:: Flac_SEEKTABLE.build(writer)
330
331   Writes this metadata block to the given :class:`audiotools.bitstream.BitstreamWriter`,
332   not including its 32-bit metadata header.
333
334.. method:: Flac_SEEKTABLE.size()
335
336   Returns the size of the metadata block,
337   not including its 32-bit metadata header.
338
339.. method:: Flac_SEEKTABLE.clean(fixes_performed)
340
341   Returns a fixed FLAC seektable with empty seek points removed
342   and ``byte offset`` / ``PCM frame count`` values reordered
343   to be incrementing.
344   Any fixes performed are appended to the ``fixes_performed``
345   list as Unicode strings.
346
347VORBISCOMMENT
348^^^^^^^^^^^^^
349
350.. class:: Flac_VORBISCOMMENT(comment_strings, vendor_string)
351
352   ``comment_strings`` is a list of Unicode strings
353   and ``vendor_string`` is a Unicode string.
354
355   See :class:`VorbisComment` on how to map strings to attributes.
356
357   >>> Flac_VORBISCOMMENT([u"TITLE=Foo", u"ARTIST=Bar"], u"Python Audio Tools")
358
359.. data:: Flac_VORBISCOMMENT.BLOCK_ID
360
361   This metadata's block ID as a non-negative integer.
362
363.. method:: Flac_VORBISCOMMENT.copy()
364
365   Returns a copy of this metadata block.
366
367.. method:: Flac_VORBISCOMMENT.raw_info()
368
369   Returns this metadata block as a human-readable Unicode string.
370
371.. classmethod:: Flac_VORBISCOMMENT.parse(reader)
372
373   Given a :class:`audiotools.bitstream.BitstreamReader`, returns a parsed :class:`Flac_VORBISCOMMENT` object.
374   This presumes its 32-bit metadata header has already been read.
375
376.. method:: Flac_VORBISCOMMENT.build(writer)
377
378   Writes this metadata block to the given :class:`audiotools.bitstream.BitstreamWriter`,
379   not including its 32-bit metadata header.
380
381.. method:: Flac_VORBISCOMMENT.size()
382
383   Returns the size of the metadata block,
384   not including its 32-bit metadata header.
385
386.. classmethod:: Flac_VORBISCOMMENT.converted(metadata)
387
388   Given a :class:`audiotools.MetaData`-compatible object,
389   returns a :class:`Flac_VORBISCOMMENT` object.
390
391CUESHEET
392^^^^^^^^
393
394.. class:: Flac_CUESHEET(catalog_number, lead_in_samples, is_cdda, tracks)
395
396   ``catalog_number`` is a 128 byte binary string.
397   ``lead_in_samples`` is a non-negative integer.
398   ``is_cdda`` is 1 if the cuesheet is from an audio CD, 0 if not.
399   ``tracks`` is a list of :class:`Flac_CUESHEET_track` objects.
400
401.. data:: Flac_CUESHEET.BLOCK_ID
402
403   This metadata's block ID as a non-negative integer.
404
405.. method:: Flac_CUESHEET.copy()
406
407   Returns a copy of this metadata block.
408
409.. method:: Flac_CUESHEET.raw_info()
410
411   Returns this metadata block as a human-readable Unicode string.
412
413.. classmethod:: Flac_CUESHEET.parse(reader)
414
415   Given a :class:`audiotools.bitstream.BitstreamReader`, returns a parsed :class:`Flac_CUESHEET` object.
416   This presumes its 32-bit metadata header has already been read.
417
418.. method:: Flac_CUESHEET.build(writer)
419
420   Writes this metadata block to the given :class:`audiotools.bitstream.BitstreamWriter`,
421   not including its 32-bit metadata header.
422
423.. method:: Flac_CUESHEET.size()
424
425   Returns the size of the metadata block,
426   not including its 32-bit metadata header.
427
428.. classmethod:: Flac_CUESHEET.converted(cuesheet, total_frames[, sample rate])
429
430   Given a :class:`audiotools.Sheet`-compatible object,
431   total length of the file in PCM frames and an optional sample rate,
432   returns a new :class:`Flac_CUESHEET` object.
433
434.. method:: Flac_CUESHEET.track_numbers()
435
436   Returns a list of all track numbers in the sheet,
437   typically starting from 1.
438
439.. method:: Flac_CUESHEET.track(track_number)
440
441   Given a track number, returns the corresponnding
442   :class:`Flac_CUESHEET_track` object, or raises :exc:`KeyError`
443   if the track is not found.
444
445.. method:: Flac_CUESHEET.pre_gap()
446
447   Returns the pre-gap of the entire disc as a :class:`Fraction`
448   number of seconds.
449
450.. method:: Flac_CUESHEET.track_offset(track_number)
451
452   Given a track number, returns the offset to track track
453   from the start of the stream as a :class:`Fraction` number of seconds.
454
455   May raise :exc:`KeyError` if the track is not found.
456
457.. method:: Flac_CUESHEET.track_length(track_number)
458
459   Given a track number, returns the length of that track
460   as a :class:`Fraction` number of seconds.
461
462.. note::
463
464   Unlike with regular :class:`audiotools.Sheet` objects
465   in which the final track's length may be ``None``,
466   the lengths of all valid FLAC cuesheet tracks will be known.
467
468.. method:: Flac_CUESHEET.image_formatted()
469
470   Always returns ``True`` for FLAC cuesheets.
471
472.. method:: Flac_CUESHEET.get_metadata()
473
474   Returns a :class:`audiotools.MetaData` object
475   for sheet-specific metadata embedded in the cuesheet.
476   For FLAC cuesheets, this will only contain the catalog number
477   as a Unicode string.
478
479CUESHEET track
480^^^^^^^^^^^^^^
481
482.. class:: Flac_CUESHEET_track(offset, number, ISRC, track_type, pre_emphasis, index_points)
483
484   ``offset`` is the track's first index point offset from the start of the stream, in PCM frames.
485   ``number`` number is the track's number on the CD, typically starting from 1.
486   ``ISRC`` is the track's ISRC number as a 12 byte binary string.
487   ``track_type`` is 0 for audio, 1 for non-audio.
488   ``pre_emphasis`` is 0 for tracks with no pre-emphasis, 1 for tracks with pre-emphasis.
489   ``index_points`` is a list of :class:`Flac_CUESHEET_index` objects.
490
491.. method:: Flac_CUESHEET_track.copy()
492
493   Returns a copy of this cuesheet track.
494
495.. method:: Flac_CUESHEET_track.raw_info()
496
497   Returns this cuesheet track as a human-readable Unicode string.
498
499.. classmethod:: Flac_CUESHEET_track.parse(reader)
500
501   Given a :class:`audiotools.bitstream.BitstreamReader`,
502   returns a parsed :class:`Flac_CUESHEET_track` object.
503
504.. method:: Flac_CUESHEET_track.build(writer)
505
506   Writes this cuesheet track to the given :class:`audiotools.bitstream.BitstreamWriter`.
507
508.. method:: Flac_CUESHEET_track.number()
509
510   Returns the track's number, typically starting from 1.
511
512.. method:: Flac_CUESHEET_track.indexes()
513
514   Returns a list of all index points numbers in the track.
515   A point number of 0 indicates a pre-gap index point.
516
517.. method:: Flac_CUESHEET_track.index(index_number)
518
519   Given an index number, returns a :class:`Flac_CUESHEET_index` object.
520
521   May raise :exc:`KeyError` if the index point is not found.
522
523.. method:: Flac_CUESHEET_track.get_metadata()
524
525   Returns a :class:`audiotools.MetaData` object of the
526   track's metadata.
527   For FLAC cuesheets, this will be limited to the ISRC.
528
529.. method:: Flac_CUESHEET_track.filename()
530
531   Returns the track's filename as a string.
532   For FLAC cuesheets, this will always be the FLAC file
533   which contains the cuesheet.
534
535.. method:: Flac_CUESHEET_track.is_audio()
536
537   Always returns ``True``.
538
539.. method:: Flac_CUESHEET_track.pre_emphasis()
540
541   Returns ``True`` if the track has pre-emphasis.
542
543.. method:: Flac_CUESHEET_track.copy_permitted()
544
545   Always returns ``True``.
546
547CUESHEET index
548^^^^^^^^^^^^^^
549
550.. class:: Flac_CUESHEET_index(offset, number)
551
552   ``offset`` is the index point's offset.
553   ``number`` is the index point's number in the set.
554
555.. method:: Flac_CUESHEET_index.copy()
556
557   Returns a copy of this cuesheet index.
558
559.. classmethod:: Flac_CUESHEET_index.parse(reader)
560
561   Given a :class:`audiotools.bitstream.BitstreamReader`,
562   returns a parsed :class:`Flac_CUESHEET_index` object.
563
564.. method:: Flac_CUESHEET_index.build(writer)
565
566   Writes this index point to the given :class:`audiotools.bitstream.BitstreamWriter`.
567
568.. method:: Flac_CUESHEET_index.number()
569
570   Returns this index point's number where 0 indicates a pre-gap index.
571
572.. method:: Flac_CUESHEET_index.offset()
573
574   Returns this index point's offset from the start of the stream
575   as a :class:`Fraction` number of seconds.
576
577PICTURE
578^^^^^^^
579
580.. class:: Flac_PICTURE(picture_type, mime_type, description, width, height, color_depth, color_count, data)
581
582   ``picture_type`` is one of the following:
583
584   == ===================================
585   0  Other
586   1  32x32 pixels 'file icon' (PNG only)
587   2  Other file icon
588   3  Cover (front)
589   4  Cover (back)
590   5  Leaflet page
591   6  Media (e.g. label side of CD)
592   7  Lead artist/lead performer/soloist
593   8  Artist/performer
594   9  Conductor
595   10 Band/Orchestra
596   11 Composer
597   12 Lyricist/text writer
598   13 Recording Location
599   14 During recording
600   15 During performance
601   16 Movie/video screen capture
602   17 A bright colored fish
603   18 Illustration
604   19 Band/artist logotype
605   20 Publisher/Studio logotype
606   == ===================================
607
608   ``mime_type`` and ``description`` are Unicode strings.
609   ``width`` and ``height`` are integer number of pixels.
610   ``color_depth`` is an integer number of bits per pixel.
611   ``color_count`` is an integer number of colors for images
612   with indexed colors, or 0 for formats such as JPEG with no indexed colors.
613   ``data`` is a binary string of raw image data.
614
615   This is a subclass of :class:`audiotools.Image`
616   which shares all the same methods and attributes.
617
618.. data:: Flac_IMAGE.BLOCK_ID
619
620   This metadata's block ID as a non-negative integer.
621
622.. method:: Flac_IMAGE.copy()
623
624   Returns a copy of this metadata block.
625
626.. method:: Flac_IMAGE.raw_info()
627
628   Returns this metadata block as a human-readable Unicode string.
629
630.. classmethod:: Flac_IMAGE.parse(reader)
631
632   Given a :class:`audiotools.bitstream.BitstreamReader`,
633   returns a parsed :class:`Flac_IMAGE` object.
634   This presumes its 32-bit metadata header has already been read.
635
636.. method:: Flac_IMAGE.build(writer)
637
638   Writes this metadata block to the given :class:`audiotools.bitstream.BitstreamWriter`,
639   not including its 32-bit metadata header.
640
641.. method:: Flac_IMAGE.size()
642
643   Returns the size of the metadata block,
644   not including its 32-bit metadata header.
645
646.. method:: Flac_IMAGE.converted(image)
647
648   Given an :class:`Flac_IMAGE`-compatible object,
649   returns a new :class:`Flac_IMAGE` block.
650
651.. method:: Flac_IMAGE.clean(fixes_performed)
652
653   Returns a new :class:`Flac_IMAGE` block with
654   metadata fields cleaned up according to the metrics
655   of the contained raw image data.
656   Any fixes are appended to the ``fixes_performed`` list
657   as Unicode strings.
658
659ID3v1
660-----
661
662.. class:: ID3v1Comment([track_name][, artist_name][, album_name][, year][, comment][, track_number][, genre])
663
664   All fields are binary strings with a fixed length:
665
666   ============= ======
667   field         length
668   ------------- ------
669   track_name        30
670   artist_name       30
671   album_name        30
672   year               4
673   comment           28
674   track_number       1
675   genre              1
676   ============= ======
677
678   >>> tag = ID3v1Comment(track_name='Track Title' + chr(0) * 19,  # note the NULL byte padding
679   ...                    track_number=chr(1))
680   >>> tag.track_name
681   u'Track Title'
682   >>> tag.track_name = u'New Track Name'
683   >>> tag.track_name
684   u'New Track Name'
685
686   Undefined fields are filled with NULL bytes.
687   Attempting to initialize a field with an incorrect size
688   will raise a :exc:`ValueError`.
689
690.. method:: ID3v1Comment.raw_info()
691
692   Returns this metadata as a human-readable Unicode string.
693
694.. classmethod:: ID3v1Comment.parse(mp3_file)
695
696   Given a seekable file object of an MP3 file,
697   returns an :class:`ID3v1Comment` object.
698   Raises :exc:`ValueError` if the comment is invalid.
699
700.. method:: ID3v1Comment.build(mp3_file)
701
702   Given a file object positioned at the end of an MP3 file,
703   appends this ID3v1 comment to that file.
704
705ID3v2.2
706-------
707
708.. class:: ID3v22Comment(frames[, total_size])
709
710   This is an ID3v2.2_ tag, one of the three ID3v2 variants used by MP3 files.
711   During initialization, it takes a list of :class:`ID3v22_Frame`-compatible
712   objects.
713   It can then be manipulated like a regular Python dict with keys
714   as 3 character frame identifiers and values as lists of :class:`ID3v22_Frame`
715   objects - since each frame identifier may occur multiple times.
716
717   For example:
718
719   >>> tag = ID3v22Comment([ID3v22_T__Frame('TT2', 0, u'Track Title')])
720   >>> tag.track_name
721   u'Track Title'
722   >>> tag['TT2']
723   [<audiotools.__id3__.ID3v22_T__Frame instance at 0x1004c17a0>]
724   >>> tag['TT2'] = [ID3v22_T__Frame('TT2', 0, u'New Track Title')]
725   >>> tag.track_name
726   u'New Track Title'
727
728   Fields are mapped between ID3v2.2 frame identifiers,
729   :class:`audiotools.MetaData` and :class:`ID3v22Frame` objects as follows:
730
731   ========== ================================ ========================
732   Identifier MetaData                         Object
733   ---------- -------------------------------- ------------------------
734   ``TT2``    ``track_name``                   :class:`ID3v22_T__Frame`
735   ``TRK``    ``track_number``/``track_total`` :class:`ID3v22_T__Frame`
736   ``TPA``    ``album_number``/``album_total`` :class:`ID3v22_T__Frame`
737   ``TAL``    ``album_name``                   :class:`ID3v22_T__Frame`
738   ``TP1``    ``artist_name``                  :class:`ID3v22_T__Frame`
739   ``TP2``    ``performer_name``               :class:`ID3v22_T__Frame`
740   ``TP3``    ``conductor_name``               :class:`ID3v22_T__Frame`
741   ``TCM``    ``composer_name``                :class:`ID3v22_T__Frame`
742   ``TMT``    ``media``                        :class:`ID3v22_T__Frame`
743   ``TRC``    ``ISRC``                         :class:`ID3v22_T__Frame`
744   ``TCR``    ``copyright``                    :class:`ID3v22_T__Frame`
745   ``TPB``    ``publisher``                    :class:`ID3v22_T__Frame`
746   ``TYE``    ``year``                         :class:`ID3v22_T__Frame`
747   ``TRD``    ``date``                         :class:`ID3v22_T__Frame`
748   ``COM``    ``comment``                      :class:`ID3v22_COM_Frame`
749   ``PIC``    ``images()``                     :class:`ID3v22_PIC_Frame`
750   ========== ================================ ========================
751
752   The optional ``total_size`` field is the total size of the tag,
753   not including the 6 byte ID3 header.
754   If the total size is larger than the size of all tags,
755   the remaining space will be padded with NULL bytes.
756
757ID3v2.2 Frame
758^^^^^^^^^^^^^
759
760.. class:: ID3v22_Frame(frame_id, data)
761
762   This is the base class for the various ID3v2.2 frames.
763   ``frame_id`` is a 3 character string and ``data`` is
764   the frame's contents as a string.
765
766.. method:: ID3v22Frame.copy()
767
768   Returns a new copy of this frame.
769
770.. method:: ID3v22Frame.raw_info()
771
772   Returns this frame as a human-readable Unicode string.
773
774.. classmethod:: ID3v22Frame.parse(frame_id, frame_size, reader)
775
776   Given a 3 byte frame ID, frame size and
777   :class:`audiotools.bitstream.BitstreamReader`
778   (positioned past the 6 byte frame header)
779   returns a parsed :class:`ID3v22Frame` object.
780
781.. method:: ID3v22Frame.build(writer)
782
783   Writes frame to the given
784   :class:`audiotools.bitstream.BitstreamWriter`,
785   not including its 6 byte frame header.
786
787.. method:: ID3v22Frame.size()
788
789   Returns the frame's size, not including its 6 byte frame header.
790
791.. method:: ID3v22Frame.clean(fixes_performed)
792
793   Returns a new :class:`ID3v22Frame` object that's been cleaned
794   of any problems.
795   Any fixes performed are appended to ``fixes_performed``
796   as Unicode strings.
797
798ID3v2.2 Text Frames
799^^^^^^^^^^^^^^^^^^^
800
801.. class:: ID3v22_T__Frame(frame_id, encoding, data)
802
803   This :class:`ID3v22_Frame`-compatible object is a container
804   for textual data.
805   ``frame_id`` is a 3 character string, ``data`` is a binary string
806   and ``encoding`` is one of the following integers representing a
807   text encoding:
808
809   = ========
810   0 Latin-1_
811   1 UCS-2_
812   = ========
813
814.. method:: ID3v22_T__Frame.number()
815
816   Returns the first integer portion of the frame data as an int
817   if the frame is container for numerical data such as
818   ``TRK`` or ``TPA``.
819
820.. method:: ID3v22_T__Frame.total()
821
822   Returns the second integer portion of the frame data as an int
823   if the frame is a numerical container and has a "total" field.
824   For example:
825
826   >>> f = ID3v22_T__Frame('TRK', 0, '1/2')
827   >>> f.number()
828   1
829   >>> f.total()
830   2
831
832.. classmethod:: ID3v22_T__Frame.converted(frame_id, unicode_string)
833
834   Given a 3 byte frame ID and Unicode string,
835   returns a new :class:`ID3v22_T__Frame` object.
836
837.. class:: ID3v22_TXX_Frame(encoding, description, data)
838
839   This subclass of :class:`ID3v22_T__Frame` contains
840   an additional ``description`` binary string field
841   to hold user-defined textual data.
842
843ID3v2.2 Web Frames
844^^^^^^^^^^^^^^^^^^
845
846.. class:: ID3v22_W__Frame(frame_id, url)
847
848   This :class:`ID3v22_Frame`-compatible object is a container
849   for web links.
850   ``frame_id`` is a 3 character string, ``url`` is a binary string.
851
852.. class:: ID3v22_WXX_Frame(encoding, description, url)
853
854   This subclass of :class:`ID3v22_W__Frame` contains
855   an additional ``description`` binary string field
856   to hold user-defined web link data.
857
858ID3v2.2 COM Frame
859^^^^^^^^^^^^^^^^^
860
861.. class:: ID3v22_COM_Frame(encoding, language, short_description, data)
862
863   This :class:`ID3v22_Frame`-compatible object is for holding
864   a potentially large block of comment data.
865   ``encoding`` is the same as in text frames:
866
867   = ========
868   0 Latin-1_
869   1 UCS-2_
870   = ========
871
872   ``language`` is a 3 character string, such as ``"eng"`` for English.
873   ``short_description`` is a :class:`C_string` object.
874   ``data`` is a binary string.
875
876.. classmethod:: ID3v22_COM_Frame.converted(frame_id, unicode_string)
877
878   Given a 3 byte ``"COM"`` frame ID and Unicode string,
879   returns a new :class:`ID3v22_COM_Frame` object.
880
881ID3v2.2 PIC Frame
882^^^^^^^^^^^^^^^^^
883
884.. class:: ID3v22_PIC_Frame(image_format, picture_type, description, data)
885
886   This is a subclass of :class:`audiotools.Image`, in addition
887   to being a :class:`ID3v22_Frame`-compatible object.
888   ``image_format`` is one of the following:
889
890   ========== ======
891   ``"PNG"``  PNG
892   ``"JPG"``  JPEG
893   ``"BMP"``  Bitmap
894   ``"GIF"``  GIF
895   ``"TIF"``  TIFF
896   ========== ======
897
898   ``picture_type`` is an integer representing one of the following:
899
900   == ======================================
901   0  Other
902   1  32x32 pixels 'file icon' (PNG only)
903   2  Other file icon
904   3  Cover (front)
905   4  Cover (back)
906   5  Leaflet page
907   6  Media (e.g. label side of CD)
908   7  Lead artist / Lead performer / Soloist
909   8  Artist / Performer
910   9  Conductor
911   10 Band / Orchestra
912   11 Composer
913   12 Lyricist / Text writer
914   13 Recording Location
915   14 During recording
916   15 During performance
917   16 Movie / Video screen capture
918   17 A bright colored fish
919   18 Illustration
920   19 Band / Artist logotype
921   20 Publisher / Studio logotype
922   == ======================================
923
924   ``description`` is a :class:`C_string`.
925   ``data`` is a string of binary image data.
926
927.. method:: ID3v22_PIC_Frame.type_string()
928
929   Returns the ``picture_type`` as a plain string.
930
931.. classmethod:: ID3v22_PIC_Frame.converted(frame_id, image)
932
933   Given an :class:`audiotools.Image` object,
934   returns a new :class:`ID3v22_PIC_Frame` object.
935
936
937ID3v2.3
938-------
939
940.. class:: ID3v23Comment(frames[, total_size])
941
942   This is an ID3v2.3_ tag, one of the three ID3v2 variants used by MP3 files.
943   During initialization, it takes a list of :class:`ID3v23_Frame`-compatible
944   objects.
945   It can then be manipulated like a regular Python dict with keys
946   as 4 character frame identifiers and values as lists of :class:`ID3v23_Frame`
947   objects - since each frame identifier may occur multiple times.
948
949   For example:
950
951   >>> tag = ID3v23Comment([ID3v23_T___Frame('TIT2', 0, u'Track Title')])
952   >>> tag.track_name
953   u'Track Title'
954   >>> tag['TIT2']
955   [ID3v23_T___Frame('TIT2', 0, u'Track Title')]
956   >>> tag['TIT2'] = [ID3v23_T___Frame('TIT2', 0, u'New Track Title')]
957   >>> tag.track_name
958   u'New Track Title'
959
960   Fields are mapped between ID3v2.3 frame identifiers,
961   :class:`audiotools.MetaData` and :class:`ID3v23_Frame` objects as follows:
962
963   ========== ================================ ==========================
964   Identifier MetaData                         Object
965   ---------- -------------------------------- --------------------------
966   ``TIT2``   ``track_name``                   :class:`ID3v23_T___Frame`
967   ``TRCK``   ``track_number``/``track_total`` :class:`ID3v23_T___Frame`
968   ``TPOS``   ``album_number``/``album_total`` :class:`ID3v23_T___Frame`
969   ``TALB``   ``album_name``                   :class:`ID3v23_T___Frame`
970   ``TPE1``   ``artist_name``                  :class:`ID3v23_T___Frame`
971   ``TPE2``   ``performer_name``               :class:`ID3v23_T___Frame`
972   ``TPE3``   ``conductor_name``               :class:`ID3v23_T___Frame`
973   ``TCOM``   ``composer_name``                :class:`ID3v23_T___Frame`
974   ``TMED``   ``media``                        :class:`ID3v23_T___Frame`
975   ``TSRC``   ``ISRC``                         :class:`ID3v23_T___Frame`
976   ``TCOP``   ``copyright``                    :class:`ID3v23_T___Frame`
977   ``TPUB``   ``publisher``                    :class:`ID3v23_T___Frame`
978   ``TYER``   ``year``                         :class:`ID3v23_T___Frame`
979   ``TRDA``   ``date``                         :class:`ID3v23_T___Frame`
980   ``COMM``   ``comment``                      :class:`ID3v23_COMM_Frame`
981   ``APIC``   ``images()``                     :class:`ID3v23_APIC_Frame`
982   ========== ================================ ==========================
983
984   The optional ``total_size`` field is the total size of the tag,
985   not including the 6 byte ID3 header.
986   If the total size is larger than the size of all tags,
987   the remaining space will be padded with NULL bytes.
988
989ID3v2.3 Frame
990^^^^^^^^^^^^^
991
992.. class:: ID3v23_Frame(frame_id, data)
993
994   This is the base class for the various ID3v2.3 frames.
995   ``frame_id`` is a 4 character string and ``data`` is
996   the frame's contents as a string.
997
998.. method:: ID3v23_Frame.copy()
999
1000   Returns a new copy of this frame.
1001
1002.. method:: ID3v23_Frame.raw_info()
1003
1004   Returns this frame as a human-readable Unicode string.
1005
1006.. classmethod:: ID3v23_Frame.parse(frame_id, frame_size, reader)
1007
1008   Given a 4 byte frame ID, frame size and
1009   :class:`audiotools.bitstream.BitstreamReader`
1010   (positioned past the 10 byte frame header)
1011   returns a parsed :class:`ID3v23_Frame` object.
1012
1013.. method:: ID3v23_Frame.build(writer)
1014
1015   Writes frame to the given
1016   :class:`audiotools.bitstream.BitstreamWriter`,
1017   not including its 10 byte frame header.
1018
1019.. method:: ID3v23_Frame.size()
1020
1021   Returns the frame's size, not including its 10 byte frame header.
1022
1023.. method:: ID3v23_Frame.clean(fixes_performed)
1024
1025   Returns a new :class:`ID3v23_Frame` object that's been cleaned
1026   of any problems.
1027   Any fixes performed are appended to ``fixes_performed``
1028   as Unicode strings.
1029
1030ID3v2.3 Text Frames
1031^^^^^^^^^^^^^^^^^^^
1032
1033.. class:: ID3v23_T___Frame(frame_id, encoding, data)
1034
1035   This :class:`ID3v23_Frame`-compatible object is a container
1036   for textual data.
1037   ``frame_id`` is a 3 character string, ``data`` is a binary string
1038   and ``encoding`` is one of the following integers representing a
1039   text encoding:
1040
1041   = ========
1042   0 Latin-1_
1043   1 UCS-2_
1044   = ========
1045
1046.. method:: ID3v23_T___Frame.number()
1047
1048   Returns the first integer portion of the frame data as an int
1049   if the frame is container for numerical data such as
1050   ``TRCK`` or ``TPOS``.
1051
1052.. method:: ID3v23_T___Frame.total()
1053
1054   Returns the second integer portion of the frame data as an int
1055   if the frame is a numerical container and has a "total" field.
1056   For example:
1057
1058   >>> f = ID3v23_T___Frame('TRCK', 0, '1/2')
1059   >>> f.number()
1060   1
1061   >>> f.total()
1062   2
1063
1064.. classmethod:: ID3v23_T___Frame.converted(frame_id, unicode_string)
1065
1066   Given a 4 byte frame ID and Unicode string,
1067   returns a new :class:`ID3v23_T___Frame` object.
1068
1069.. class:: ID3v23_TXXX_Frame(encoding, description, data)
1070
1071   This subclass of :class:`ID3v23_T___Frame` contains
1072   an additional ``description`` binary string field
1073   to hold user-defined textual data.
1074
1075ID3v2.3 Web Frames
1076^^^^^^^^^^^^^^^^^^
1077
1078.. class:: ID3v23_W___Frame(frame_id, url)
1079
1080   This :class:`ID3v23_Frame`-compatible object is a container
1081   for web links.
1082   ``frame_id`` is a 4 character string, ``url`` is a binary string.
1083
1084.. class:: ID3v23_WXXX_Frame(encoding, description, url)
1085
1086   This subclass of :class:`ID3v23_W___Frame` contains
1087   an additional ``description`` binary string field
1088   to hold user-defined web link data.
1089
1090ID3v2.3 COMM Frame
1091^^^^^^^^^^^^^^^^^^
1092
1093.. class:: ID3v23_COMM_Frame(encoding, language, short_description, data)
1094
1095   This :class:`ID3v23_Frame`-compatible object is for holding
1096   a potentially large block of comment data.
1097   ``encoding`` is the same as in text frames:
1098
1099   = ========
1100   0 Latin-1_
1101   1 UCS-2_
1102   = ========
1103
1104   ``language`` is a 3 character string, such as ``"eng"`` for English.
1105   ``short_description`` is a :class:`C_string` object.
1106   ``data`` is a binary string.
1107
1108.. classmethod:: ID3v23_COMM_Frame.converted(frame_id, unicode_string)
1109
1110   Given a 4 byte ``"COMM"`` frame ID and Unicode string,
1111   returns a new :class:`ID3v23_COMM_Frame` object.
1112
1113ID3v2.3 APIC Frame
1114^^^^^^^^^^^^^^^^^^
1115
1116.. class:: ID3v23_APIC_Frame(mime_type, picture_type, description, data)
1117
1118   This is a subclass of :class:`audiotools.Image`, in addition
1119   to being a :class:`ID3v23_Frame`-compatible object.
1120   ``mime_type`` is a :class:`C_string`.
1121   ``picture_type`` is an integer representing one of the following:
1122
1123   == ======================================
1124   0  Other
1125   1  32x32 pixels 'file icon' (PNG only)
1126   2  Other file icon
1127   3  Cover (front)
1128   4  Cover (back)
1129   5  Leaflet page
1130   6  Media (e.g. label side of CD)
1131   7  Lead artist / Lead performer / Soloist
1132   8  Artist / Performer
1133   9  Conductor
1134   10 Band / Orchestra
1135   11 Composer
1136   12 Lyricist / Text writer
1137   13 Recording Location
1138   14 During recording
1139   15 During performance
1140   16 Movie / Video screen capture
1141   17 A bright colored fish
1142   18 Illustration
1143   19 Band / Artist logotype
1144   20 Publisher / Studio logotype
1145   == ======================================
1146
1147   ``description`` is a :class:`C_string`.
1148   ``data`` is a string of binary image data.
1149
1150.. method:: ID3v23_APIC_Frame.type_string()
1151
1152   Returns the ``picture_type`` as a plain string.
1153
1154.. classmethod:: ID3v23_APIC_Frame.converted(frame_id, image)
1155
1156   Given an :class:`audiotools.Image` object,
1157   returns a new :class:`ID3v23_APIC_Frame` object.
1158
1159ID3v2.4
1160-------
1161
1162.. class:: ID3v24Comment(frames[, total_size])
1163
1164   This is an ID3v2.4_ tag, one of the three ID3v2 variants used by MP3 files.
1165   During initialization, it takes a list of :class:`ID3v24_Frame`-compatible
1166   objects.
1167   It can then be manipulated like a regular Python dict with keys
1168   as 4 character frame identifiers and values as lists of :class:`ID3v24_Frame`
1169   objects - since each frame identifier may occur multiple times.
1170
1171   For example:
1172
1173   >>> tag = ID3v24Comment([ID3v24_T___Frame('TIT2', 0, u'Track Title')])
1174   >>> tag.track_name
1175   u'Track Title'
1176   >>> tag['TIT2']
1177   [ID3v24_T___Frame('TIT2', 0, u'Track Title')]
1178   >>> tag['TIT2'] = [ID3v24_T___Frame('TIT2', 0, u'New Track Title')]
1179   >>> tag.track_name
1180   u'New Track Title'
1181
1182   Fields are mapped between ID3v2.4 frame identifiers,
1183   :class:`audiotools.MetaData` and :class:`ID3v24_Frame` objects as follows:
1184
1185   ========== ================================ ==========================
1186   Identifier MetaData                         Object
1187   ---------- -------------------------------- --------------------------
1188   ``TIT2``   ``track_name``                   :class:`ID3v24_T___Frame`
1189   ``TRCK``   ``track_number``/``track_total`` :class:`ID3v24_T___Frame`
1190   ``TPOS``   ``album_number``/``album_total`` :class:`ID3v24_T___Frame`
1191   ``TALB``   ``album_name``                   :class:`ID3v24_T___Frame`
1192   ``TPE1``   ``artist_name``                  :class:`ID3v24_T___Frame`
1193   ``TPE2``   ``performer_name``               :class:`ID3v24_T___Frame`
1194   ``TPE3``   ``conductor_name``               :class:`ID3v24_T___Frame`
1195   ``TCOM``   ``composer_name``                :class:`ID3v24_T___Frame`
1196   ``TMED``   ``media``                        :class:`ID3v24_T___Frame`
1197   ``TSRC``   ``ISRC``                         :class:`ID3v24_T___Frame`
1198   ``TCOP``   ``copyright``                    :class:`ID3v24_T___Frame`
1199   ``TPUB``   ``publisher``                    :class:`ID3v24_T___Frame`
1200   ``TYER``   ``year``                         :class:`ID3v24_T___Frame`
1201   ``TRDA``   ``date``                         :class:`ID3v24_T___Frame`
1202   ``COMM``   ``comment``                      :class:`ID3v24_COMM_Frame`
1203   ``APIC``   ``images()``                     :class:`ID3v24_APIC_Frame`
1204   ========== ================================ ==========================
1205
1206   The optional ``total_size`` field is the total size of the tag,
1207   not including the 6 byte ID3 header.
1208   If the total size is larger than the size of all tags,
1209   the remaining space will be padded with NULL bytes.
1210
1211ID3v2.4 Frame
1212^^^^^^^^^^^^^
1213
1214.. class:: ID3v24_Frame(frame_id, data)
1215
1216   This is the base class for the various ID3v2.4 frames.
1217   ``frame_id`` is a 4 character string and ``data`` is
1218   the frame's contents as a string.
1219
1220.. method:: ID3v24_Frame.copy()
1221
1222   Returns a new copy of this frame.
1223
1224.. method:: ID3v24_Frame.raw_info()
1225
1226   Returns this frame as a human-readable Unicode string.
1227
1228.. classmethod:: ID3v24_Frame.parse(frame_id, frame_size, reader)
1229
1230   Given a 4 byte frame ID, frame size and
1231   :class:`audiotools.bitstream.BitstreamReader`
1232   (positioned past the 10 byte frame header)
1233   returns a parsed :class:`ID3v24_Frame` object.
1234
1235.. method:: ID3v24_Frame.build(writer)
1236
1237   Writes frame to the given
1238   :class:`audiotools.bitstream.BitstreamWriter`,
1239   not including its 10 byte frame header.
1240
1241.. method:: ID3v24_Frame.size()
1242
1243   Returns the frame's size, not including its 10 byte frame header.
1244
1245.. method:: ID3v24_Frame.clean(fixes_performed)
1246
1247   Returns a new :class:`ID3v24_Frame` object that's been cleaned
1248   of any problems.
1249   Any fixes performed are appended to ``fixes_performed``
1250   as Unicode strings.
1251
1252ID3v2.4 Text Frames
1253^^^^^^^^^^^^^^^^^^^
1254
1255.. class:: ID3v24_T___Frame(frame_id, encoding, data)
1256
1257   This :class:`ID3v24_Frame`-compatible object is a container
1258   for textual data.
1259   ``frame_id`` is a 3 character string, ``data`` is a binary string
1260   and ``encoding`` is one of the following integers representing a
1261   text encoding:
1262
1263   = =========
1264   0 Latin-1_
1265   1 UTF-16_
1266   2 UTF-16BE_
1267   3 UTF-8_
1268   = =========
1269
1270.. method:: ID3v24_T___Frame.number()
1271
1272   Returns the first integer portion of the frame data as an int
1273   if the frame is container for numerical data such as
1274   ``TRCK`` or ``TPOS``.
1275
1276.. method:: ID3v24_T___Frame.total()
1277
1278   Returns the second integer portion of the frame data as an int
1279   if the frame is a numerical container and has a "total" field.
1280   For example:
1281
1282   >>> f = ID3v24_T___Frame('TRCK', 0, '1/2')
1283   >>> f.number()
1284   1
1285   >>> f.total()
1286   2
1287
1288.. classmethod:: ID3v24_T___Frame.converted(frame_id, unicode_string)
1289
1290   Given a 4 byte frame ID and Unicode string,
1291   returns a new :class:`ID3v24_T___Frame` object.
1292
1293.. class:: ID3v24_TXXX_Frame(encoding, description, data)
1294
1295   This subclass of :class:`ID3v24_T___Frame` contains
1296   an additional ``description`` binary string field
1297   to hold user-defined textual data.
1298
1299ID3v2.4 Web Frames
1300^^^^^^^^^^^^^^^^^^
1301
1302.. class:: ID3v24_W___Frame(frame_id, url)
1303
1304   This :class:`ID3v24_Frame`-compatible object is a container
1305   for web links.
1306   ``frame_id`` is a 4 character string, ``url`` is a binary string.
1307
1308.. class:: ID3v24_WXXX_Frame(encoding, description, url)
1309
1310   This subclass of :class:`ID3v24_W___Frame` contains
1311   an additional ``description`` binary string field
1312   to hold user-defined web link data.
1313
1314ID3v2.4 COMM Frame
1315^^^^^^^^^^^^^^^^^^
1316
1317.. class:: ID3v24_COMM_Frame(encoding, language, short_description, data)
1318
1319   This :class:`ID3v24_Frame`-compatible object is for holding
1320   a potentially large block of comment data.
1321   ``encoding`` is the same as in text frames:
1322
1323   = =========
1324   0 Latin-1_
1325   1 UTF-16_
1326   2 UTF-16BE_
1327   3 UTF-8_
1328   = =========
1329
1330   ``language`` is a 3 character string, such as ``"eng"`` for English.
1331   ``short_description`` is a :class:`C_string` object.
1332   ``data`` is a binary string.
1333
1334.. classmethod:: ID3v24_COMM_Frame.converted(frame_id, unicode_string)
1335
1336   Given a 4 byte ``"COMM"`` frame ID and Unicode string,
1337   returns a new :class:`ID3v23_COMM_Frame` object.
1338
1339ID3v2.4 APIC Frame
1340^^^^^^^^^^^^^^^^^^
1341
1342.. class:: ID3v24_APIC_Frame(mime_type, picture_type, description, data)
1343
1344   This is a subclass of :class:`audiotools.Image`, in addition
1345   to being a :class:`ID3v24_Frame`-compatible object.
1346   ``mime_type`` is a :class:`C_string`.
1347   ``picture_type`` is an integer representing one of the following:
1348
1349   == ======================================
1350   0  Other
1351   1  32x32 pixels 'file icon' (PNG only)
1352   2  Other file icon
1353   3  Cover (front)
1354   4  Cover (back)
1355   5  Leaflet page
1356   6  Media (e.g. label side of CD)
1357   7  Lead artist / Lead performer / Soloist
1358   8  Artist / Performer
1359   9  Conductor
1360   10 Band / Orchestra
1361   11 Composer
1362   12 Lyricist / Text writer
1363   13 Recording Location
1364   14 During recording
1365   15 During performance
1366   16 Movie / Video screen capture
1367   17 A bright colored fish
1368   18 Illustration
1369   19 Band / Artist logotype
1370   20 Publisher / Studio logotype
1371   == ======================================
1372
1373   ``description`` is a :class:`C_string`.
1374   ``data`` is a string of binary image data.
1375
1376.. method:: ID3v24_APIC_Frame.type_string()
1377
1378   Returns the ``picture_type`` as a plain string.
1379
1380.. classmethod:: ID3v24_APIC_Frame.converted(frame_id, image)
1381
1382   Given an :class:`audiotools.Image` object,
1383   returns a new :class:`ID3v24_APIC_Frame` object.
1384
1385ID3 Comment Pair
1386----------------
1387
1388Often, MP3 files are tagged with both an ID3v2 comment and an ID3v1 comment
1389for maximum compatibility.
1390This class encapsulates both comments into a single class.
1391
1392.. class:: ID3CommentPair(id3v2_comment, id3v1_comment)
1393
1394   ``id3v2_comment`` is an :class:`ID3v22Comment`, :class:`ID3v23Comment`
1395   or :class:`ID3v24Comment`.
1396   ``id3v1_comment`` is an :class:`ID3v1Comment`.
1397   When getting :class:`audiotools.MetaData` attributes,
1398   the ID3v2 comment is used by default.
1399   Set attributes are propagated to both.
1400   For example:
1401
1402   >>> tag = ID3CommentPair(ID3v23Comment([ID3v23_T___Frame('TIT2', 0, 'Title 1')]),
1403   ...                      ID3v1Comment(u'Title 2',u'',u'',u'',u'',1, 0))
1404   >>> tag.track_name
1405   u'Title 1'
1406   >>> tag.track_name = u'New Track Title'
1407   >>> unicode(tag.id3v2['TIT2'][0])
1408   u'New Track Title'
1409   >>> tag.id3v1.track_name
1410   u'New Track Title'
1411
1412.. data:: ID3CommentPair.id3v2
1413
1414   The embedded :class:`ID3v22Comment`, :class:`ID3v23Comment`
1415   or :class:`ID3v24Comment`
1416
1417.. data:: ID3CommentPair.id3v1
1418
1419   The embedded :class:`ID3v1Comment`
1420
1421M4A
1422---
1423
1424.. class:: M4A_META_Atom(version, flags, leaf_atoms)
1425
1426   This is the metadata format used by QuickTime-compatible formats such as
1427   M4A and Apple Lossless.
1428   ``version`` and ``flags`` are integers (typically 0)
1429   and ``leaf_atoms`` is a list of atom objects,
1430   one of which should be an ``ilst`` tree atom.
1431   In addition to being a :class:`audiotools.MetaData` subclass,
1432   this is also a :class:`M4A_Tree_Atom` subclass
1433   with several methods specific for metadata.
1434   As an example:
1435
1436   >>> tag = M4A_META_Atom(0, 0,
1437   ...                     [M4A_Tree_Atom('ilst',
1438   ...                                    [M4A_ILST_Leaf_Atom('\xa9nam',
1439   ...                                                        [M4A_ILST_Unicode_Data_Atom(0, 1, "Track Name")])])])
1440   >>> tag.track_name
1441   u'Track Name'
1442   >>> tag['ilst']['\xa9nam']
1443   ... M4A_ILST_Leaf_Atom('\xa9nam', [M4A_ILST_Unicode_Data_Atom(0, 1, 'Track Name')])
1444   >>> tag['ilst'].replace_child(M4A_ILST_Leaf_Atom('\xa9nam',
1445   ...                                              [M4A_ILST_Unicode_Data_Atom(0, 1, 'New Track Name')])
1446   >>> tag.track_name
1447   u'New Track Name'
1448
1449   Fields are mapped between :class:`M4AMetaData`,
1450   :class:`audiotools.MetaData` and iTunes as follows:
1451
1452   ============= ================================ ============
1453   M4AMetaData   MetaData                         iTunes
1454   ------------- -------------------------------- ------------
1455   ``"\xA9nam"`` ``track_name``                   Name
1456   ``"\xA9ART"`` ``artist_name``                  Artist
1457   ``"\xA9day"`` ``year``                         Year
1458   ``"trkn"``    ``track_number``/``track_total`` Track Number
1459   ``"disk"``    ``album_number``/``album_total`` Album Number
1460   ``"\xA9alb"`` ``album_name``                   Album
1461   ``"\xA9wrt"`` ``composer_name``                Composer
1462   ``"\xA9cmt"`` ``comment``                      Comment
1463   ``"cprt"``    ``copyright``
1464   ============= ================================ ============
1465
1466   Note that several of the 4 character keys are prefixed by
1467   the non-ASCII byte ``0xA9``.
1468
1469.. method:: M4A_META_Atom.has_ilst_atom()
1470
1471   Returns ``True`` if the atom has an ``ilst`` child atom.
1472
1473.. method:: M4A_META_Atom.ilst_atom()
1474
1475   Returns the first ``ilst`` child atom,
1476   or ``None`` if no ``ilst`` atom is present.
1477
1478.. method:: M4A_META_Atom.add_ilst_atom()
1479
1480   Appends a new, empty ``ilst`` atom after
1481   the first ``hdlr`` atom, if any.
1482
1483.. method:: M4A_META_Atom.raw_info()
1484
1485   Returns atom data as a human-readable Unicode string.
1486
1487.. classmethod:: M4A_META_Atom.parse(name, data_size, reader, parsers)
1488
1489   Given a 4 byte atom name, size of the entire atom in bytes,
1490   a :class:`audiotools.bitstream.BitstreamReader`,
1491   and a dict of atom name strings -> atom classes,
1492   returns a new :class:`M4A_META_Atom` object.
1493
1494   When parsing sub atoms, any atom name in the parsers dict
1495   is handled recursively via its value's ``parse`` classmethod.
1496   If the atom name is not present, the atom is treated as
1497   a generic :class:`M4A_Leaf_Atom`.
1498
1499.. method:: M4A_META_Atom.build(writer)
1500
1501   Writes the atom's contents to the given
1502   :class:`audiotools.bitstream.BitstreamWriter`
1503   recursively via its sub-atoms' ``build`` methods.
1504   This does *not* include the atom's 64-bit size / name header.
1505
1506.. method:: M4A_META_Atom.size()
1507
1508   Returns the size of the atom data in bytes,
1509   not including its 64-bit size / name header.
1510
1511M4A Leaf Atom
1512^^^^^^^^^^^^^
1513
1514.. class:: M4A_Leaf_Atom(name, data)
1515
1516   ``name`` is a 4 byte atom name string.
1517   ``data`` is a string of raw atom data.
1518
1519.. method:: M4A_Leaf_Atom.copy()
1520
1521   Returns a duplicate copy of the atom.
1522
1523.. method:: M4A_Leaf_Atom.raw_info()
1524
1525   Returns atom data as a human-readable Unicode string.
1526
1527.. method:: M4A_Leaf_Atom.parse(name, size, reader, parsers)
1528
1529   Given a 4 byte atom name, size of the entire atom in bytes,
1530   a :class:`audiotools.bitstream.BitstreamReader`
1531   and an unused dict of atom name strings -> atom classes,
1532   returns a new :class:`M4A_Leaf_Atom` object.
1533
1534.. method:: M4A_Leaf_Atom.build(writer)
1535
1536   Writes the atom's contents to the given
1537   :class:`audiotools.bitstream.BitstreamWriter`.
1538   This does *not* include the atom's 64-bit size / name header.
1539
1540.. method:: M4A_Leaf_Atom.size()
1541
1542   Returns the size of the atom data in bytes,
1543   not including its 64-bit size / name header.
1544
1545M4A Tree Atom
1546^^^^^^^^^^^^^
1547
1548.. class:: M4A_Tree_Atom(name, leaf_atoms)
1549
1550   ``name`` is a 4 byte atom name string.
1551   ``leaf_atoms`` is a list of atom-compatible objects,
1552   typically :class:`M4A_Leaf_Atom`, :class:`M4A_Tree_Atom`
1553   or subclasses of either.
1554
1555.. method:: M4A_Tree_Atom.copy()
1556
1557   Returns a duplicate copy of the atom.
1558
1559.. method:: M4A_Tree_Atom.raw_info()
1560
1561   Returns atom data as a human-readable Unicode string.
1562
1563.. method:: M4A_Tree_Atom.parse(name, data_size, reader, parsers)
1564
1565   Given a 4 byte atom name, size of the entire atom in bytes,
1566   a :class:`audiotools.bitstream.BitstreamReader`,
1567   and a dict of atom name strings -> atom classes,
1568   returns a new :class:`M4A_META_Atom` object.
1569
1570   When parsing sub atoms, any atom name in the parsers dict
1571   is handled recursively via its value's ``parse`` classmethod.
1572   If the atom name is not present, the atom is treated as
1573   a generic :class:`M4A_Leaf_Atom`.
1574
1575.. method:: M4A_Tree_Atom.build(writer)
1576
1577   Writes the atom's contents to the given
1578   :class:`audiotools.bitstream.BitstreamWriter`
1579   recursively via its sub-atoms' ``build`` methods.
1580   This does *not* include the atom's 64-bit size / name header.
1581
1582.. method:: M4A_Tree_Atom.size()
1583
1584   Returns the size of the atom data in bytes,
1585   not including its 64-bit size / name header.
1586
1587.. method:: M4A_Tree_Atom.get_child(atom_name)
1588
1589   Given a 4 byte atom name string,
1590   returns the first instance of that child atom.
1591   Raises :exc:`KeyError` if the child is not found.
1592
1593.. method:: M4A_Tree_Atom.has_child(atom_name)
1594
1595   Given a 4 byte atom name string,
1596   returns ``True`` if that child atom is present.
1597
1598.. method:: M4A_Tree_Atom.add_child(atom_object)
1599
1600   Appends an atom-compatible object,
1601   to this atom's list of children.
1602
1603.. method:: M4A_Tree_Atom.remove_child(atom_name)
1604
1605   Given a 4 byte atom name string,
1606   removes the first instance of that child, if any.
1607
1608.. method:: M4A_Tree_Atom.replace_child(atom_object)
1609
1610   Replaces the first child atom with the same name
1611   with the given atom-compatible object.
1612
1613.. method:: M4A_Tree_Atom.child_offset(*child_path)
1614
1615   Given a list of 4 byte atom name strings,
1616   recursively searches :class:`M4A_Tree_Atom`-compatible
1617   sub-children and returns the byte offset
1618   of the final child atom.
1619   Raises :exc:`KeyError` if the child atom cannot be found.
1620
1621M4A ILST Leaf Atom
1622^^^^^^^^^^^^^^^^^^
1623
1624This atom is a subclass of :class:`M4A_Tree_Atom`
1625specialized for holding M4A metadata fields
1626and mapping them to Python values.
1627
1628.. class:: M4A_ILST_Leaf_Atom(name, leaf_atoms)
1629
1630   ``name`` is a 4 byte atom name string.
1631   ``leaf_atoms`` is a list of atom-compatible objects,
1632
1633.. method:: M4A_ILST_Leaf_Atom.__unicode__()
1634
1635   Returns the Unicode value of this leaf's first ``data`` child atom.
1636
1637   >>> nam = M4A_ILST_Leaf_Atom("\xa9nam",
1638   ...                          [M4A_ILST_Unicode_Data_Atom(0, 1, "Track Name")])
1639   >>> unicode(nam)
1640   u"Track Name"
1641
1642.. method:: M4A_ILST_Leaf_Atom.__int__()
1643
1644   Returns the integer value of this leaf's first ``data`` child atom.
1645
1646   >>> trkn = M4A_ILST_Leaf_Atom("trkn",
1647   ...                           [M4A_ILST_TRKN_Data_Atom(1, 2)])
1648   >>> int(trkn)
1649   1
1650
1651.. method:: M4A_ILST_Leaf_Atom.total()
1652
1653   Returns the total integer value of this leaf's first ``data`` child atom.
1654
1655   >>> trkn = M4A_ILST_Leaf_Atom("trkn",
1656   ...                           [M4A_ILST_TRKN_Data_Atom(1, 2)])
1657   >>> trkn.total()
1658   2
1659
1660M4A ILST Unicode Data Atom
1661^^^^^^^^^^^^^^^^^^^^^^^^^^
1662
1663This atom is a subclass of :class:`M4A_Leaf_Atom`
1664specialized for holding Unicode data.
1665
1666.. class:: M4A_ILST_Unicode_Data_Atom(type, flags, data)
1667
1668   ``type`` is an integer (typically 0),
1669   ``flags`` is an integer (typically 1),
1670   ``data`` is a binary string of UTF-8-encoded data.
1671   The atom's ``name`` field is always ``"data"``.
1672
1673.. method:: M4A_ILST_Unicode_Data_Atom.__unicode__()
1674
1675   Returns the Unicode value of this atom's data.
1676
1677   >>> nam = M4A_ILST_Unicode_Data_Atom(0, 1, "Track Name")
1678   >>> unicode(nam)
1679   u"Track Name"
1680
1681M4A ILST Track Number Atom
1682^^^^^^^^^^^^^^^^^^^^^^^^^^
1683
1684This atom is a subclass of :class:`M4A_Leaf_Atom`
1685specialized for holding track number data.
1686
1687.. class:: M4A_ILST_TRKN_Data_Atom(track_number, track_total)
1688
1689   ``track_number`` and ``track_total`` are both integers.
1690   Its ``name`` field is always ``"data"``.
1691
1692.. method:: M4A_ILST_TRKN_Data_Atom.__int__()
1693
1694   Returns this atom's ``track_number`` value.
1695
1696   >>> trkn = M4A_ILST_TRKN_Data_Atom(1, 2)
1697   >>> int(trkn)
1698   1
1699
1700.. method:: M4A_ILST_TRKN_Data_Atom.total()
1701
1702   Returns this atom's ``track_total`` value.
1703
1704   >>> trkn = M4A_ILST_TRKN_Data_Atom(1, 2)
1705   >>> trkn.total()
1706   2
1707
1708M4A ILST Disc Number Atom
1709^^^^^^^^^^^^^^^^^^^^^^^^^
1710
1711This atom is a subclass of :class:`M4A_Leaf_Atom`
1712specialized for holding disc number data.
1713
1714.. class:: M4A_ILST_DISK_Data_Atom(disc_number, disc_total)
1715
1716   ``disc_number`` and ``disc_total`` are both integers.
1717   Its ``name`` field is always ``"data"``.
1718
1719.. method:: M4A_ILST_DISK_Data_Atom.__int__()
1720
1721   Returns this atom's ``disc_number`` value.
1722
1723   >>> disk = M4A_ILST_DISK_Data_Atom(3, 4)
1724   >>> int(disk)
1725   3
1726
1727.. method:: M4A_ILST_DISK_Data_Atom.total()
1728
1729   Returns this atom's ``disc_total`` value.
1730
1731   >>> disk = M4A_ILST_DISK_Data_Atom(3, 4)
1732   >>> disk.total()
1733   4
1734
1735M4A ILST Cover Art Atom
1736^^^^^^^^^^^^^^^^^^^^^^^
1737
1738This atom is a subclass of :class:`M4A_Leaf_Atom` and of
1739:class:`audiotools.Image`.
1740
1741.. class:: M4A_ILST_COVR_Data_Atom(version, flags, image_data)
1742
1743   ``version`` is an integer (typically 0).
1744   ``flags`` is an integer (typically 0).
1745   ``image_data`` is a binary string of cover art data.
1746   Its ``name`` field is always ``"data"``.
1747
1748   This atom parses its raw image data to populate
1749   its :class:`audiotools.Image`-specific methods and fields.
1750
1751Vorbis Comment
1752--------------
1753
1754.. class:: VorbisComment(comment_strings, vendor_string)
1755
1756   This is a VorbisComment_ tag used by FLAC, Ogg FLAC, Ogg Vorbis,
1757   Ogg Speex and other formats in the Ogg family.
1758   ``comment_strings`` is a list of Unicode strings.
1759   ``vendor_string`` is a Unicode string.
1760   Once initialized, :class:`VorbisComment` can be manipulated like a
1761   regular Python dict in addition to its standard
1762   :class:`audiotools.MetaData` methods.
1763
1764   For example:
1765
1766   >>> tag = VorbisComment([u'TITLE=Track Title'], u'Vendor String')
1767   >>> tag.track_name
1768   u'Track Title'
1769   >>> tag[u'TITLE']
1770   [u'New Title']
1771   >>> tag[u'TITLE'] = [u'New Title']
1772   >>> tag.track_name
1773   u'New Title'
1774
1775   Fields are mapped between :class:`VorbisComment` and
1776   :class:`audiotools.MetaData` as follows:
1777
1778   ================= ==================
1779   VorbisComment     Metadata
1780   ----------------- ------------------
1781   ``TITLE``         ``track_name``
1782   ``TRACKNUMBER``   ``track_number``
1783   ``TRACKTOTAL``    ``track_total``
1784   ``DISCNUMBER``    ``album_number``
1785   ``DISCTOTAL``     ``album_total``
1786   ``ALBUM``         ``album_name``
1787   ``ARTIST``        ``artist_name``
1788   ``PERFORMER``     ``performer_name``
1789   ``COMPOSER``      ``composer_name``
1790   ``CONDUCTOR``     ``conductor_name``
1791   ``SOURCE MEDIUM`` ``media``
1792   ``ISRC``          ``ISRC``
1793   ``CATALOG``       ``catalog``
1794   ``COPYRIGHT``     ``copyright``
1795   ``PUBLISHER``     ``publisher``
1796   ``DATE``          ``year``
1797   ``COMMENT``       ``comment``
1798   ================= ==================
1799
1800   Note that if the same key is used multiple times,
1801   the metadata attribute only indicates the first one:
1802
1803   >>> tag = VorbisComment([u"TITLE=Title1", u"TITLE=Title2"], u"Vendor String")
1804   >>> tag.track_name
1805   u'Title1'
1806
1807Opus Tags
1808---------
1809
1810.. class:: OpusTags(comment_strings, vendor_string)
1811
1812   OpusTags is a subclass of :class:`VorbisComment`
1813   which supports the same field/metadata mapping.
1814
1815.. _APEv2: http://wiki.hydrogenaudio.org/index.php?title=APEv2
1816
1817.. _ID3v1: http://www.id3.org/ID3v1
1818
1819.. _FLAC: http://flac.sourceforge.net/format.html#metadata_block
1820
1821.. _VorbisComment: http://www.xiph.org/vorbis/doc/v-comment.html
1822
1823.. _ID3v2.2: http://www.id3.org/id3v2-00
1824
1825.. _ID3v2.3: http://www.id3.org/d3v2.3.0
1826
1827.. _ID3v2.4: http://www.id3.org/id3v2.4.0-structure
1828
1829.. _Latin-1: http://en.wikipedia.org/wiki/Latin-1
1830
1831.. _UCS-2: http://en.wikipedia.org/wiki/UTF-16
1832
1833.. _UTF-16: http://en.wikipedia.org/wiki/UTF-16
1834
1835.. _UTF-16BE: http://en.wikipedia.org/wiki/UTF-16
1836
1837.. _UTF-8: http://en.wikipedia.org/wiki/UTF-8
1838