split_keyboard.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #!/usr/bin/python3
  2. import mido
  3. import sys,os,time
  4. import _thread
  5. #timidity -iA -B4,8 -OsSu1 --resample=l -a --voice-lpf=d --noise-shaping=0 --default-program=2 -s 44kHz
  6. # -V 0.3 --output-mono --volume=255 -V 0.3
  7. print("out put ports:")
  8. for i in mido.get_output_names():
  9. print(i)
  10. print("input ports")
  11. for i in mido.get_input_names():
  12. print(i)
  13. outport, inport = None,None
  14. default_output= "TiMidity:TiMidity port 0"
  15. default_input = "AXELVOX KEY49J:AXELVOX KEY49J MIDI 1 32:0"
  16. import tkinter as tk
  17. from tkinter import ttk
  18. from tkinter import *
  19. vSplitTheKeybaord = False
  20. vSplitTheKeybaordFromNum = 55
  21. vProgram1Num = 81
  22. vProgram2Num = 10 # 45 82 88 91 92 96 94 98 | 103 105 114
  23. vSplitKeyBoardTransponse1 = -12
  24. vSplitKeyBoardTransponse2 = 0
  25. vVelocityControl = False;
  26. vReplaceValue = 127;
  27. def stopAll():
  28. if outport == None:
  29. return
  30. print(vProgram1Num,vProgram2Num)
  31. for i in range(127):
  32. outport.send( mido.Message('note_off',channel=0, note=i ) )
  33. outport.send( mido.Message('note_off',channel=1, note=i ) )
  34. def apply():
  35. global vSplitTheKeybaord, vSplitTheKeybaordFromNum, vProgram1Num, vProgram2Num, vSplitKeyBoardTransponse1, vSplitKeyBoardTransponse2,vVelocityControl
  36. if outport == None:
  37. return
  38. #
  39. stopAll()
  40. #
  41. vSplitTheKeybaord = fvsplitkeyboard.get()
  42. vSplitTheKeybaordFromNum = int(fvSplitKeyBoardFromNum.get())
  43. vSplitKeyBoardTransponse1 = int(fvSplitKeyBoardTransponse1.get())
  44. vSplitKeyBoardTransponse2 = int(fvSplitKeyBoardTransponse2.get())
  45. vVelocityControl = fvVelocityControl.get();
  46. vProgram1Num = int(Programm1.get())
  47. vProgram2Num = int(Programm2.get())
  48. outport.send( mido.Message('program_change', channel=0, program=vProgram1Num) )
  49. #time.sleep(0.25)
  50. outport.send( mido.Message('program_change', channel=1, program=vProgram2Num) )
  51. print('clicked')
  52. #control_change channel=0 control=7 value=48 t
  53. def mainloop():
  54. global outport, inport,vReplaceValue
  55. try:
  56. outport = mido.open_output( voutput.get() )
  57. inport = mido.open_input( vinput.get() )
  58. fbConnect["text"] = "disconnect"
  59. except:
  60. return;
  61. apply()
  62. for msg in inport:
  63. if msg.type in ['note_on', 'note_off']:
  64. if vSplitTheKeybaord:
  65. if msg.note > vSplitTheKeybaordFromNum:
  66. msg.channel=1
  67. msg.note+= vSplitKeyBoardTransponse2
  68. else:
  69. msg.channel=0
  70. msg.note+= vSplitKeyBoardTransponse1
  71. if vVelocityControl:
  72. msg.velocity = vReplaceValue;
  73. if msg.type == 'control_change':
  74. vReplaceValue = msg.value
  75. value_var.set( vReplaceValue );
  76. print(msg)
  77. outport.send(msg)
  78. def connect():
  79. global outport,inport;
  80. #fbConnect["state"] = "disabled"
  81. if outport != None:
  82. outport.close()
  83. inport.close()
  84. fbConnect["text"] = "connect"
  85. time.sleep(0.25)
  86. outport = None;
  87. inport = None;
  88. return
  89. try:
  90. _thread.start_new_thread(mainloop, ())
  91. except:
  92. print ("Error: unable to start thread")
  93. return
  94. root = Tk()
  95. root.geometry('320x200')
  96. #root.configure(background='#F0F8FF')
  97. root.title('Split midi keyboard for timidity')
  98. deffont=('arial', 12, 'normal')
  99. Button(root, text='Apply', font=deffont, command=apply ).place(x=220, y=30)
  100. fbConnect = Button(root, text="Connect", font=deffont, command=connect )
  101. fbConnect.place(x=220, y=60)
  102. Button(root, text='StopNotes', font=deffont, command=stopAll ).place(x=220, y=90)
  103. fvProgramm1 = IntVar(root)
  104. fvProgramm1.set(vProgram1Num)
  105. fvProgramm2 = IntVar(root)
  106. fvProgramm2.set(vProgram2Num)
  107. fvsplitkeyboard = BooleanVar(root)
  108. fvsplitkeyboard.set(True)
  109. fvSplitKeyBoardFromNum = IntVar(root)
  110. fvSplitKeyBoardFromNum.set(vSplitTheKeybaordFromNum)
  111. fvSplitKeyBoardTransponse1 = IntVar(root)
  112. fvSplitKeyBoardTransponse1.set(vSplitKeyBoardTransponse1)
  113. fvSplitKeyBoardTransponse2 = IntVar(root)
  114. fvSplitKeyBoardTransponse2.set(vSplitKeyBoardTransponse2)
  115. Label(root, text='Ch1 Prgm:', font=deffont).place(x=10, y=10)
  116. Label(root, text='Ch2 Prgm:', font=deffont).place(x=100, y=10)
  117. Programm1= Spinbox(root, textvariable=fvProgramm1, from_=0, to=128, font=deffont, width=3, command=apply)
  118. Programm1.place(x=10, y=30)
  119. Programm2= Spinbox(root, textvariable=fvProgramm2, from_=0, to=128, font=deffont, width=3, command=apply)
  120. Programm2.place(x=100, y=30)
  121. Checkbutton(root, text='Split the keyboard', variable=fvsplitkeyboard, font=deffont, command=apply).place(x=10, y=52)
  122. Label(root, text='Split from:', font=deffont).place(x=10, y=70)
  123. Label(root, text='Transpose:', font=deffont).place(x=10, y=90)
  124. Spinbox(root, textvariable=fvSplitKeyBoardFromNum, from_=1, to=128, font=deffont, width=4, command=apply).place(x=80, y=70)
  125. Spinbox(root, textvariable=fvSplitKeyBoardTransponse1, from_=-127, to=128, font=deffont, width=4, command=apply).place(x=80, y=90)
  126. Spinbox(root, textvariable=fvSplitKeyBoardTransponse2, from_=-127, to=128, font=deffont, width=4, command=apply).place(x=130, y=90)
  127. #scrollbar = Scrollbar(root, orient='horizontal').place(200,100);
  128. value_var = IntVar(value=30)
  129. fvVelocityControl = BooleanVar(root)
  130. fvVelocityControl.set(False)
  131. Checkbutton(root, text='Replace velocity', variable=fvVelocityControl, font=deffont, command=apply).place(x=180, y=10)
  132. ttk.Progressbar(orient="vertical", variable=value_var, maximum=127).place(width=20,height=80,x=190,y=30)
  133. voutput = StringVar(root)
  134. vinput = StringVar(root)
  135. Label(root, text='Output:', font=deffont).place(x=10, y=120)
  136. Label(root, text='Input:', font=deffont).place(x=10, y=150)
  137. fvoutput = OptionMenu(root, voutput, *mido.get_output_names() )
  138. fvoutput.place(x=60, y=120)
  139. fvinput = OptionMenu(root, vinput, *mido.get_output_names() )
  140. fvinput.place(x=60, y=150)
  141. voutput.set(default_output)
  142. vinput.set(default_input)
  143. root.mainloop()