2 # -*- coding: utf-8 -*-
5 # Copyright (C) 2013-2020 Filipe Coelho <falktx@falktx.com>
7 # This program is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU General Public License as
9 # published by the Free Software Foundation; either version 2 of
10 # the License, or any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # For a full copy of the GNU General Public License see the doc/GPL.txt file.
19 # ------------------------------------------------------------------------------------------------------------
20 # Imports (Custom Stuff)
22 from carla_backend
import charPtrToString
23 from carla_shared
import *
25 # ------------------------------------------------------------------------------------------------------------
28 class ExternalUI(object):
32 self
.fQuitReceived
= False
35 self
.fSampleRate
= float(sys
.argv
[1])
36 self
.fUiName
= sys
.argv
[2]
37 self
.fPipeClient
= gCarla
.utils
.pipe_client_new(lambda s
,msg
: self
.msgCallback(msg
))
39 self
.fSampleRate
= 44100.0
40 self
.fUiName
= "TestUI"
41 self
.fPipeClient
= None
43 # -------------------------------------------------------------------
47 if self
.fPipeClient
is None:
48 # testing, show UI only
52 if self
.fPipeClient
is not None:
53 return gCarla
.utils
.pipe_client_is_running(self
.fPipeClient
)
56 def idleExternalUI(self
):
57 if self
.fPipeClient
is not None:
58 gCarla
.utils
.pipe_client_idle(self
.fPipeClient
)
60 def closeExternalUI(self
):
61 if self
.fPipeClient
is None:
65 if not self
.fQuitReceived
:
66 self
.send(["exiting"])
68 gCarla
.utils
.pipe_client_destroy(self
.fPipeClient
)
69 self
.fPipeClient
= None
71 # -------------------------------------------------------------------
74 def getSampleRate(self
):
75 return self
.fSampleRate
77 def sendControl(self
, index
, value
):
78 self
.send(["control", index
, value
])
80 def sendProgram(self
, channel
, bank
, program
):
81 self
.send(["program", channel
, bank
, program
])
83 def sendConfigure(self
, key
, value
):
84 self
.send(["configure", key
, value
])
86 # -------------------------------------------------------------------
89 def dspParameterChanged(self
, index
, value
):
92 def dspProgramChanged(self
, channel
, bank
, program
):
95 def dspStateChanged(self
, key
, value
):
98 def dspNoteReceived(self
, onOff
, channel
, note
, velocity
):
101 # -------------------------------------------------------------------
102 # ExternalUI Callbacks
114 self
.closeExternalUI()
116 def uiTitleChanged(self
, uiTitle
):
119 # -------------------------------------------------------------------
122 def msgCallback(self
, msg
):
123 msg
= charPtrToString(msg
)
129 index
= self
.readlineblock_int()
130 value
= self
.readlineblock_float()
131 self
.dspParameterChanged(index
, value
)
133 elif msg
== "program":
134 channel
= self
.readlineblock_int()
135 bank
= self
.readlineblock_int()
136 program
= self
.readlineblock_int()
137 self
.dspProgramChanged(channel
, bank
, program
)
139 elif msg
== "configure":
140 key
= self
.readlineblock()
141 value
= self
.readlineblock()
142 self
.dspStateChanged(key
, value
)
145 onOff
= self
.readlineblock_bool()
146 channel
= self
.readlineblock_int()
147 note
= self
.readlineblock_int()
148 velocity
= self
.readlineblock_int()
149 self
.dspNoteReceived(onOff
, channel
, note
, velocity
)
161 self
.fQuitReceived
= True
164 elif msg
== "uiTitle":
165 uiTitle
= self
.readlineblock()
166 self
.uiTitleChanged(uiTitle
)
169 print("unknown message: \"" + msg
+ "\"")
171 # -------------------------------------------------------------------
174 def readlineblock(self
):
175 if self
.fPipeClient
is None:
178 return gCarla
.utils
.pipe_client_readlineblock(self
.fPipeClient
, 5000)
180 def readlineblock_bool(self
):
181 if self
.fPipeClient
is None:
184 return gCarla
.utils
.pipe_client_readlineblock_bool(self
.fPipeClient
, 5000)
186 def readlineblock_int(self
):
187 if self
.fPipeClient
is None:
190 return gCarla
.utils
.pipe_client_readlineblock_int(self
.fPipeClient
, 5000)
192 def readlineblock_float(self
):
193 if self
.fPipeClient
is None:
196 return gCarla
.utils
.pipe_client_readlineblock_float(self
.fPipeClient
, 5000)
198 def send(self
, lines
):
199 if self
.fPipeClient
is None or len(lines
) == 0:
203 gCarla
.utils
.pipe_client_lock(self
.fPipeClient
)
209 elif isinstance(line
, str):
210 line2
= line
.replace("\n", "\r")
211 elif isinstance(line
, bool):
212 line2
= "true" if line
else "false"
213 elif isinstance(line
, int):
215 elif isinstance(line
, float):
216 line2
= "%.10f" % line
218 print("unknown data type to send:", type(line
))
222 if not gCarla
.utils
.pipe_client_write_msg(self
.fPipeClient
, line2
+ "\n"):
227 return gCarla
.utils
.pipe_client_flush_and_unlock(self
.fPipeClient
) and not hasError