1# -*- coding: utf-8 -*- 2 3import os 4 5from mutagen.id3 import ID3, TIT2 6from mutagen.musepack import Musepack, MusepackInfo, MusepackHeaderError 7from mutagen._compat import cBytesIO 8from tests import TestCase, DATA_DIR, get_temp_copy 9 10 11class TMusepack(TestCase): 12 13 def setUp(self): 14 self.sv8 = Musepack(os.path.join(DATA_DIR, "sv8_header.mpc")) 15 self.sv7 = Musepack(os.path.join(DATA_DIR, "click.mpc")) 16 self.sv5 = Musepack(os.path.join(DATA_DIR, "sv5_header.mpc")) 17 self.sv4 = Musepack(os.path.join(DATA_DIR, "sv4_header.mpc")) 18 19 def test_bad_header(self): 20 self.failUnlessRaises( 21 MusepackHeaderError, 22 Musepack, os.path.join(DATA_DIR, "almostempty.mpc")) 23 24 def test_channels(self): 25 self.failUnlessEqual(self.sv8.info.channels, 2) 26 self.failUnlessEqual(self.sv7.info.channels, 2) 27 self.failUnlessEqual(self.sv5.info.channels, 2) 28 self.failUnlessEqual(self.sv4.info.channels, 2) 29 30 def test_sample_rate(self): 31 self.failUnlessEqual(self.sv8.info.sample_rate, 44100) 32 self.failUnlessEqual(self.sv7.info.sample_rate, 44100) 33 self.failUnlessEqual(self.sv5.info.sample_rate, 44100) 34 self.failUnlessEqual(self.sv4.info.sample_rate, 44100) 35 36 def test_bitrate(self): 37 self.failUnlessEqual(self.sv8.info.bitrate, 609) 38 self.failUnlessEqual(self.sv7.info.bitrate, 194530) 39 self.failUnlessEqual(self.sv5.info.bitrate, 39) 40 self.failUnlessEqual(self.sv4.info.bitrate, 39) 41 42 def test_length(self): 43 self.failUnlessAlmostEqual(self.sv8.info.length, 1.49, 1) 44 self.failUnlessAlmostEqual(self.sv7.info.length, 0.07, 2) 45 self.failUnlessAlmostEqual(self.sv5.info.length, 26.3, 1) 46 self.failUnlessAlmostEqual(self.sv4.info.length, 26.3, 1) 47 48 def test_gain(self): 49 self.failUnlessAlmostEqual(self.sv8.info.title_gain, -4.668, 3) 50 self.failUnlessAlmostEqual(self.sv8.info.title_peak, 0.5288, 3) 51 self.failUnlessEqual( 52 self.sv8.info.title_gain, self.sv8.info.album_gain) 53 self.failUnlessEqual( 54 self.sv8.info.title_peak, self.sv8.info.album_peak) 55 self.failUnlessAlmostEqual(self.sv7.info.title_gain, 9.27, 6) 56 self.failUnlessAlmostEqual(self.sv7.info.title_peak, 0.1149, 4) 57 self.failUnlessEqual( 58 self.sv7.info.title_gain, self.sv7.info.album_gain) 59 self.failUnlessEqual( 60 self.sv7.info.title_peak, self.sv7.info.album_peak) 61 self.failUnlessRaises(AttributeError, getattr, self.sv5, 'title_gain') 62 63 def test_not_my_file(self): 64 self.failUnlessRaises( 65 MusepackHeaderError, Musepack, 66 os.path.join(DATA_DIR, "empty.ogg")) 67 self.failUnlessRaises( 68 MusepackHeaderError, Musepack, 69 os.path.join(DATA_DIR, "emptyfile.mp3")) 70 71 def test_almost_my_file(self): 72 self.failUnlessRaises( 73 MusepackHeaderError, MusepackInfo, cBytesIO(b"MP+" + b"\x00" * 32)) 74 self.failUnlessRaises( 75 MusepackHeaderError, 76 MusepackInfo, 77 cBytesIO(b"MP+" + b"\x00" * 100)) 78 self.failUnlessRaises( 79 MusepackHeaderError, 80 MusepackInfo, 81 cBytesIO(b"MPCK" + b"\x00" * 100)) 82 83 def test_pprint(self): 84 self.sv8.pprint() 85 self.sv7.pprint() 86 self.sv5.pprint() 87 self.sv4.pprint() 88 89 def test_mime(self): 90 self.failUnless("audio/x-musepack" in self.sv7.mime) 91 92 def test_zero_padded_sh_packet(self): 93 # https://github.com/quodlibet/mutagen/issues/198 94 data = (b"MPCKSH\x10\x95 Q\xa2\x08\x81\xb8\xc9T\x00\x1e\x1b" 95 b"\x00RG\x0c\x01A\xcdY\x06?\x80Z\x06EI") 96 97 fileobj = cBytesIO(data) 98 info = MusepackInfo(fileobj) 99 self.assertEqual(info.channels, 2) 100 self.assertEqual(info.samples, 3024084) 101 102 103class TMusepackWithID3(TestCase): 104 105 def setUp(self): 106 self.filename = get_temp_copy(os.path.join(DATA_DIR, "click.mpc")) 107 108 def tearDown(self): 109 os.unlink(self.filename) 110 111 def test_ignore_id3(self): 112 id3 = ID3() 113 id3.add(TIT2(encoding=0, text='id3 title')) 114 id3.save(self.filename) 115 f = Musepack(self.filename) 116 f['title'] = 'apev2 title' 117 f.save() 118 id3 = ID3(self.filename) 119 self.failUnlessEqual(id3['TIT2'], 'id3 title') 120 f = Musepack(self.filename) 121 self.failUnlessEqual(f['title'], 'apev2 title') 122