Test błędnego XMLa.
[wolnelektury.git] / lib / mutagen / monkeysaudio.py
1 # A Monkey's Audio (APE) reader/tagger
2 #
3 # Copyright 2006 Lukas Lalinsky <lalinsky@gmail.com>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License version 2 as
7 # published by the Free Software Foundation.
8 #
9 # $Id: monkeysaudio.py 4275 2008-06-01 06:32:37Z piman $
10
11 """Monkey's Audio streams with APEv2 tags.
12
13 Monkey's Audio is a very efficient lossless audio compressor developed
14 by Matt Ashland.
15
16 For more information, see http://www.monkeysaudio.com/.
17 """
18
19 __all__ = ["MonkeysAudio", "Open", "delete"]
20
21 import struct
22
23 from mutagen.apev2 import APEv2File, error, delete
24 from mutagen._util import cdata
25
26 class MonkeysAudioHeaderError(error): pass
27
28 class MonkeysAudioInfo(object):
29     """Monkey's Audio stream information.
30
31     Attributes:
32     channels -- number of audio channels
33     length -- file length in seconds, as a float
34     sample_rate -- audio sampling rate in Hz
35     bits_per_sample -- bits per sample
36     version -- Monkey's Audio stream version, as a float (eg: 3.99)
37     """
38
39     def __init__(self, fileobj):
40         header = fileobj.read(76)
41         if len(header) != 76 or not header.startswith("MAC "):
42             raise MonkeysAudioHeaderError("not a Monkey's Audio file")
43         self.version = cdata.ushort_le(header[4:6])
44         if self.version >= 3980:
45             (blocks_per_frame, final_frame_blocks, total_frames,
46              self.bits_per_sample, self.channels,
47              self.sample_rate) = struct.unpack("<IIIHHI", header[56:76])
48         else:
49             compression_level = cdata.ushort_le(header[6:8])
50             self.channels, self.sample_rate = struct.unpack(
51                 "<HI", header[10:16])
52             total_frames, final_frame_blocks = struct.unpack(
53                 "<II", header[24:32])
54             if self.version >= 3950:
55                 blocks_per_frame = 73728 * 4
56             elif self.version >= 3900 or (self.version >= 3800 and
57                                           compression_level == 4):
58                 blocks_per_frame = 73728
59             else:
60                 blocks_per_frame = 9216
61         self.version /= 1000.0
62         self.length = 0.0
63         if self.sample_rate != 0 and total_frames > 0:
64             total_blocks = ((total_frames - 1) * blocks_per_frame +
65                             final_frame_blocks)
66             self.length = float(total_blocks) / self.sample_rate
67
68     def pprint(self):
69         return "Monkey's Audio %.2f, %.2f seconds, %d Hz" % (
70             self.version, self.length, self.sample_rate)
71
72 class MonkeysAudio(APEv2File):
73     _Info = MonkeysAudioInfo
74     _mimes = ["audio/ape", "audio/x-ape"]
75
76     def score(filename, fileobj, header):
77         return header.startswith("MAC ") + filename.lower().endswith(".ape")
78     score = staticmethod(score)
79
80 Open = MonkeysAudio