diff --git a/NEWS b/NEWS index 14fdccf38..e48fff686 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,11 @@ * A new "-q" command line switch for the import command suppresses all prompts for input; it pessimistically skips all albums that the importer is not completely confident about. +* Added support for the WavPack and Musepack formats. Unfortunately, + due to a limitation in the Mutagen library (used by beets for + metadata manipulation), Musepack SV8 is not yet supported. Here's + the upstream bug in question: + http://code.google.com/p/mutagen/issues/detail?id=7 * BPD now uses a pure-Python socket library and no longer requires eventlet/greenlet (the latter of which is a C extension). For the curious, the socket library in question is called Bluelet: diff --git a/beets/mediafile.py b/beets/mediafile.py index dd5fef428..9221bce06 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -59,6 +59,8 @@ TYPES = { 'ogg': 'OGG', 'flac': 'FLAC', 'ape': 'APE', + 'wv': 'WavPack', + 'mpc': 'Musepack', } @@ -244,8 +246,8 @@ class MediaField(object): def __init__(self, out_type = unicode, **kwargs): """Creates a new MediaField. - out_type: The field's semantic (exterior) type. - - kwargs: A hash whose keys are 'mp3', 'mp4', 'flac', 'ogg', - and 'ape' and whose values are StorageStyle instances + - kwargs: A hash whose keys are 'mp3', 'mp4', and 'etc' + and whose values are StorageStyle instances parameterizing the field's storage for each type. """ self.out_type = out_type @@ -503,6 +505,10 @@ class MediaFile(object): self.type = 'ogg' elif type(self.mgfile).__name__ == 'MonkeysAudio': self.type = 'ape' + elif type(self.mgfile).__name__ == 'WavPack': + self.type = 'wv' + elif type(self.mgfile).__name__ == 'Musepack': + self.type = 'mpc' else: raise FileTypeError('file type %s unsupported by MediaFile' % type(self.mgfile).__name__) @@ -685,6 +691,9 @@ class MediaFile(object): #fixme: The utility of this guess is questionable. return self.mgfile.info.sample_rate * \ self.mgfile.info.bits_per_sample + elif self.type == 'wv': + # Mutagen doesn't provide enough information. + return 0 else: return self.mgfile.info.bitrate diff --git a/test/rsrc/full.mpc b/test/rsrc/full.mpc new file mode 100644 index 000000000..428d13042 Binary files /dev/null and b/test/rsrc/full.mpc differ diff --git a/test/rsrc/full.wv b/test/rsrc/full.wv new file mode 100644 index 000000000..4e8fb27b1 Binary files /dev/null and b/test/rsrc/full.wv differ diff --git a/test/test_mediafile_basic.py b/test/test_mediafile_basic.py index 005c54a43..3aab06131 100644 --- a/test/test_mediafile_basic.py +++ b/test/test_mediafile_basic.py @@ -203,7 +203,6 @@ correct_dicts = { } read_only_correct_dicts = { - 'full.mp3': { 'length': 1.0, 'bitrate': 80000, @@ -234,6 +233,17 @@ read_only_correct_dicts = { 'format': 'APE', }, + 'full.wv': { + 'length': 1.0, + 'bitrate': 0, + 'format': 'WavPack', + }, + + 'full.mpc': { + 'length': 1.0, + 'bitrate': 23, + 'format': 'Musepack', + }, } def suite_for_file(path, correct_dict, writing=True): @@ -253,6 +263,8 @@ test_files = { 'flac': ['full', 'partial', 'min'], 'ogg': ['full'], 'ape': ['full'], + 'wv': ['full'], + 'mpc': ['full'], } def suite():