Skip to content

Commit d8dbdf7

Browse files
committed
Lmms support
1 parent 7f9d023 commit d8dbdf7

19 files changed

+521
-425
lines changed

daw/__init__.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ def dawFor(projectFile):
44
"""
55
Picks the daw class that is best suited for opening projectFile.
66
"""
7-
from flstudio import FlStudio
8-
from dummy import Dummy
7+
from .flstudio import FlStudio
8+
from .lmms import Lmms
9+
from .dummy import Dummy
910

10-
_class_list = (
11+
class_tuple = (
1112
FlStudio,
13+
Lmms,
1214
)
1315

14-
for item in _class_list:
16+
for item in class_tuple:
1517
if item.isValid(projectFile):
1618
return item
1719

daw/dummy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from exceptions import LoadError
1+
from .exceptions import LoadError
22

33
class Dummy():
44
"the interface used for a daw object"

daw/flstudio.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from exceptions import LoadError
2-
from dummy import Dummy
1+
from .exceptions import LoadError
2+
from .dummy import Dummy
33
import flp
44

55
class FlStudio(Dummy):

daw/lmms.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,108 @@
1+
from .dummy import Dummy
2+
from .exceptions import LoadError
3+
from xml.dom import minidom
4+
import zlib
5+
import struct
6+
7+
def _uncompress(data):
8+
return zlib.decompress(data[4:])
9+
10+
def _compress(data):
11+
return zlib.compress(struct.pack(">i", len(data)) + data)
12+
13+
def _getdoc(projectFile):
14+
f = open(projectFile, 'rb')
15+
data = f.read()
16+
f.close()
17+
18+
# try to parse as xml
19+
try:
20+
doc = minidom.parseString(data)
21+
except:
22+
# try to decompress
23+
try:
24+
data = _uncompress(data)
25+
except zlib.error:
26+
return None
27+
# try to parse result as xml
28+
try:
29+
doc = minidom.parseString(data)
30+
except:
31+
return None
32+
33+
return doc
34+
35+
class Lmms(Dummy):
36+
canReadFile = True
37+
canMerge = False
38+
canRender = False
39+
fileExtensions = ('mmp', 'mmpz')
40+
identifier = 'lmms'
41+
42+
@staticmethod
43+
def isValid(inProject):
44+
doc = _getdoc(inProject)
45+
if doc is None:
46+
return False
47+
48+
# cool, we have an xml document. now make sure it's lmms
49+
if doc.doctype.name != u'multimedia-project':
50+
return False
51+
52+
doms = doc.getElementsByTagName('multimedia-project')
53+
if len(doms) != 1:
54+
return False
55+
56+
dom = doms[0]
57+
if dom.getAttribute('creator') != u'Linux MultiMedia Studio (LMMS)':
58+
return False
59+
60+
if dom.getAttribute('type') != u'song':
61+
return False
62+
63+
return True
64+
65+
def load(self, inProject):
66+
self.doc = _getdoc(inProject)
67+
assert self.doc is not None
68+
69+
def save(self, outProject):
70+
f = open(outProject, 'w')
71+
f.write(_compress(self.doc.toxml()))
72+
f.close()
73+
74+
def extension(self):
75+
return 'mmpz'
76+
77+
def samples(self):
78+
doms = self.doc.getElementsByTagName('audiofileprocessor')
79+
return list(set([dom.getAttribute('src') for dom in doms]))
80+
81+
def effects(self):
82+
def effectName(dom):
83+
name = dom.getAttribute('name')
84+
if name == u'ladspaeffect':
85+
children = dom.getElementsByTagName('key')
86+
assert len(children) == 1
87+
child = children[0]
88+
children = child.getElementsByTagName('attribute')
89+
for node in children:
90+
if node.getAttribute('name') == u'plugin':
91+
name = node.getAttribute('value')
92+
break
93+
return name
94+
doms = self.doc.getElementsByTagName('effect')
95+
return list(set([effectName(dom) for dom in doms]))
96+
97+
def generators(self):
98+
doms = self.doc.getElementsByTagName('instrument')
99+
return list(set([dom.getAttribute('name') for dom in doms]))
100+
101+
def tempo(self):
102+
doms = self.doc.getElementsByTagName('head')
103+
for dom in doms:
104+
if dom.parentNode.localName == u'multimedia-project':
105+
return int(dom.getAttribute('bpm'))
106+
break
107+
raise LoadError("Project does not contain <head/>")
1108

Binary file not shown.

sample/cpr/info

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Cubase project file:
2+
http://www.steinberg.net/en/home.html
Binary file not shown.

sample/cwp/info

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Cakewalk Sonar Project
2+
http://www.cakewalk.com/

sample/flp/info

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
FL Studio Project
2+
http://flstudio.image-line.com/

sample/lmms/1-blank.mmpz

1.59 KB
Binary file not shown.

0 commit comments

Comments
 (0)