1# Copyright 2004-2005 Joe Wreschnig, Michael Urman
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7
8import os
9import ctypes
10
11from quodlibet.util import load_library
12
13from ._audio import AudioFile, translate_errors
14
15
16extensions = [
17    '.669', '.amf', '.ams', '.dsm', '.far', '.it', '.med', '.mod', '.mt2',
18    '.mtm', '.okt', '.s3m', '.stm', '.ult', '.gdm', '.xm']
19
20try:
21    _modplug = load_library(
22        ["libmodplug.so.1", "libmodplug.so.0", "libmodplug-1.dll"])[0]
23except OSError:
24    extensions = []
25else:
26    _modplug.ModPlug_GetName.argtypes = [ctypes.c_void_p]
27    _modplug.ModPlug_GetName.restype = ctypes.c_char_p
28
29    _modplug.ModPlug_Load.argtypes = [ctypes.c_void_p, ctypes.c_int]
30    _modplug.ModPlug_Load.restype = ctypes.c_void_p
31
32    _modplug.ModPlug_GetLength.argtypes = [ctypes.c_void_p]
33    _modplug.ModPlug_GetLength.restype = ctypes.c_int
34
35    _modplug.ModPlug_Unload.argtypes = [ctypes.c_void_p]
36    _modplug.ModPlug_Unload.restype = None
37
38
39class ModFile(AudioFile):
40
41    format = "MOD/XM/IT"
42
43    def __init__(self, filename):
44        with translate_errors():
45            data = open(filename, "rb").read()
46            f = _modplug.ModPlug_Load(data, len(data))
47            if not f:
48                raise IOError("%r not a valid MOD file" % filename)
49            self["~#length"] = _modplug.ModPlug_GetLength(f) // 1000
50            title = _modplug.ModPlug_GetName(f) or os.path.basename(filename)
51            try:
52                self["title"] = title.decode('utf-8')
53            except UnicodeError:
54                self["title"] = title.decode("iso-8859-1")
55            _modplug.ModPlug_Unload(f)
56
57        self.sanitize(filename)
58
59    def write(self):
60        pass
61
62    def reload(self, *args):
63        artist = self.get("artist")
64        super(ModFile, self).reload(*args)
65        if artist is not None:
66            self.setdefault("artist", artist)
67
68    def can_change(self, k=None):
69        if k is None:
70            return ["artist"]
71        else:
72            return k == "artist"
73
74loader = ModFile
75types = [ModFile]
76