v2m.py 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676
  1. #!/usr/bin/env python3
  2. # by svsd_val
  3. # jabber : svsd_val@jabber.ru
  4. # mail to: svsdval@gmail.com
  5. import sys
  6. import os
  7. import re
  8. filepath=''
  9. if ( len(sys.argv) < 2 ):
  10. if sys.platform.startswith('win'):
  11. from tkinter import Tk
  12. from tkinter import filedialog as fd
  13. root=Tk()
  14. root.withdraw()
  15. filepath= fd.askopenfilename(filetypes=(("Video Files", ".mpg .mkv .avi .webm .mp4"), ("All Files", "*.*")))
  16. root.destroy()
  17. print("get file [" + filepath +"]")
  18. else:
  19. print("halt, no args")
  20. sys.exit( 0 )
  21. else:
  22. filepath = sys.argv[1]
  23. if not os.path.exists( filepath ):
  24. has_pytube = False
  25. try:
  26. from pytube import YouTube
  27. has_pytube = True
  28. except:
  29. pass
  30. if has_pytube:
  31. print("Downloading video by url: %s ..." % filepath)
  32. yt = YouTube( filepath )
  33. videos = [ { 'itag' : i.itag, 'res' : int(re.sub('[^0-9]','', i.resolution)), 'progressive' : int(i.is_progressive) } for i in yt.streams.filter(file_extension='mp4') if i.mime_type.find("video") != -1 ]
  34. print(videos)
  35. videos = sorted( videos , key = lambda d : ( -d['progressive'], - d['res']) )
  36. print('sorted by progressive (has video & audio in same file) and video resolution')
  37. for i in videos:
  38. print('processing: %s' % i)
  39. filepath = "%s_%s_%s.mp4" % ( re.sub(r'[\W_]','_', yt.title), i['itag'], i['res'])
  40. yt.streams.get_by_itag(i['itag']).download( "./" , filepath, skip_existing=True)
  41. break
  42. else:
  43. print("file not exists [" + filepath +"], and no pytube has installed..., exit.")
  44. sys.exit( 0 )
  45. import math
  46. import ntpath
  47. import time
  48. from os.path import expanduser
  49. import cv2
  50. import pygame
  51. from midiutil.MidiFile import MIDIFile
  52. from OpenGL.GL import *
  53. from OpenGL.GLU import *
  54. from pygame.locals import *
  55. print(f'open file [{filepath}]')
  56. vidcap = cv2.VideoCapture( filepath )
  57. outputmid= ntpath.basename( filepath ) + '_output.mid'
  58. settingsfile= filepath + '.ini'
  59. import datetime
  60. import video2midi.settings as settings
  61. from video2midi.gl import *
  62. from video2midi.midi import *
  63. from video2midi.prefs import prefs
  64. width=640
  65. height=480
  66. mpos = [0,0]
  67. keygrab=0
  68. keygrabid=-1
  69. lastkeygrabid=-1
  70. frame= 0
  71. printed_for_frame=0
  72. convertCvtColor=1
  73. # For OpenCV 2.X ..
  74. CAP_PROP_FRAME_COUNT =0
  75. CAP_PROP_POS_FRAMES =0
  76. CAP_PROP_POS_MSEC =0
  77. CAP_PROP_FRAME_WIDTH =0
  78. CAP_PROP_FRAME_HEIGHT=0
  79. CAP_PROP_FPS =0
  80. COLOR_BGR2RGB =0
  81. print("OpenCV version:" + cv2.__version__ )
  82. if cv2.__version__.startswith('2.'):
  83. CAP_PROP_FRAME_COUNT = cv2.cv.CV_CAP_PROP_FRAME_COUNT
  84. CAP_PROP_POS_FRAMES = cv2.cv.CV_CAP_PROP_POS_FRAMES
  85. CAP_PROP_POS_MSEC = cv2.cv.CV_CAP_PROP_POS_MSEC
  86. CAP_PROP_FRAME_WIDTH = cv2.cv.CV_CAP_PROP_FRAME_WIDTH
  87. CAP_PROP_FRAME_HEIGHT = cv2.cv.CV_CAP_PROP_FRAME_HEIGHT
  88. CAP_PROP_FPS = cv2.cv.CV_CAP_PROP_FPS
  89. else:
  90. # 3, 4 , etc ...
  91. CAP_PROP_FRAME_COUNT = cv2.CAP_PROP_FRAME_COUNT
  92. CAP_PROP_POS_FRAMES = cv2.CAP_PROP_POS_FRAMES
  93. CAP_PROP_POS_MSEC = cv2.CAP_PROP_POS_MSEC
  94. CAP_PROP_FRAME_WIDTH = cv2.CAP_PROP_FRAME_WIDTH
  95. CAP_PROP_FRAME_HEIGHT = cv2.CAP_PROP_FRAME_HEIGHT
  96. CAP_PROP_FPS = cv2.CAP_PROP_FPS
  97. COLOR_BGR2RGB = cv2.COLOR_BGR2RGB
  98. vidcap.set(CAP_PROP_POS_FRAMES, frame)
  99. vidcap.set(cv2.CAP_PROP_BUFFERSIZE, 2)
  100. success,image = vidcap.read()
  101. debug_keys = 0
  102. length = int(vidcap.get(CAP_PROP_FRAME_COUNT))
  103. video_width = int(vidcap.get(CAP_PROP_FRAME_WIDTH))
  104. video_height = int(vidcap.get(CAP_PROP_FRAME_HEIGHT))
  105. fps = float(vidcap.get(CAP_PROP_FPS))
  106. width = video_width
  107. height = video_height
  108. def fit_to_the_screen() -> None:
  109. global width, height
  110. infoObject = pygame.display.Info()
  111. if (width > infoObject.current_w) or ( height > infoObject.current_h):
  112. print("try fit window to the screen")
  113. print("current window size: %sx%s" %(width,height))
  114. print("current screen size: %sx%s" %(infoObject.current_w, infoObject.current_h))
  115. ratio = ( width / infoObject.current_w)
  116. width = int(width / ratio * 0.9 )
  117. height = int(height / ratio *0.9)
  118. print("new window size: %sx%s" %(width,height))
  119. pygame.init()
  120. fit_to_the_screen()
  121. endframe = length
  122. showoutputpath = 0
  123. def resize_window() -> None:
  124. global screen, width, height
  125. if prefs.resize:
  126. width = prefs.resize_width
  127. height = prefs.resize_height
  128. else:
  129. width = video_width
  130. height = video_height
  131. fit_to_the_screen()
  132. screen = pygame.display.set_mode((width,height), DOUBLEBUF|OPENGL|pygame.RESIZABLE)
  133. doinit()
  134. # set start frame
  135. def getFrame(framenum:int = -1) -> None:
  136. global image
  137. global success
  138. global width
  139. global height
  140. global convertCvtColor
  141. global fps
  142. if ( fps == 0 ):
  143. return
  144. if ( framenum != -1 ):
  145. #vidcap.set(CAP_PROP_POS_FRAMES, int(framenum) )
  146. # problems with mpeg formats ...
  147. oldframenum = int(round(vidcap.get(1)))
  148. frametime = framenum * 1000.0 / fps
  149. print("go to frame time :" + str(frametime))
  150. success = vidcap.set(CAP_PROP_POS_MSEC, frametime)
  151. if not success:
  152. print("Cannot set frame position from video file at " + str(framenum))
  153. success = vidcap.set(CAP_PROP_POS_FRAMES, int(oldframenum) )
  154. curframe = vidcap.get(CAP_PROP_POS_FRAMES)
  155. if (curframe != framenum ):
  156. print("OpenCV bug, Requesting frame " + str(framenum) + " but get position on " +str(curframe))
  157. success,image = vidcap.read()
  158. # if ( resize == 1 ):
  159. # image = cv2.resize(image, (resize_width , resize_height))
  160. # print "resize to "+str(resize_width) + "x"+ str(resize_height)
  161. getFrame()
  162. print("video " + str(width) + "x" + str(height) +" fps: " + str(fps))
  163. # add some notes
  164. channel = 0
  165. volume = 100
  166. basenote = prefs.octave * 12
  167. notes=[]
  168. notes_db=[]
  169. notes_de=[]
  170. notes_channel=[]
  171. notes_tmp=[]
  172. notes_pressed_color=[]
  173. colorWindow_colorBtns_channel_labels=[]
  174. colorWindow_colorBtns_channel_btns=[]
  175. separate_note_id=-1
  176. screen=0
  177. colorBtns = []
  178. #quantized notes to the grid.
  179. use_snap_notes_to_grid = False
  180. notes_grid_size=32
  181. midi_file_format = 0
  182. line_height = 20
  183. running = 1
  184. #cfg
  185. home = expanduser("~")
  186. inifile = os.path.join( home, '.v2m.ini')
  187. if os.path.exists( 'v2m.ini' ):
  188. inifile="v2m.ini"
  189. print("local config file exists.")
  190. def update_size() -> None:
  191. global width, height
  192. if ( prefs.resize == 1 ):
  193. width = prefs.resize_width
  194. height = prefs.resize_height
  195. else:
  196. fit_to_the_screen()
  197. def loadsettings(cfgfile: str) -> None:
  198. global colorBtns, colorWindow_colorBtns_channel_labels
  199. settings.loadsettings(cfgfile)
  200. settings.compatibleColors(colorBtns)
  201. if len(colorWindow_colorBtns_channel_labels) > 0:
  202. for i in range(len(colorBtns)):
  203. colorWindow_colorBtns_channel_labels[i].text = "Ch:" + str(prefs.keyp_colors_channel[i]+1)
  204. update_size
  205. if 'glwindows' in globals():
  206. glBindTexture(GL_TEXTURE_2D, Gl.bgImgGL)
  207. loadImage(prefs.startframe)
  208. settingsWindow_slider1.setvalue(prefs.keyp_delta)
  209. settingsWindow_slider2.setvalue(prefs.minimal_duration * 100)
  210. settingsWindow_slider3.setvalue(prefs.tempo)
  211. sparks_switch.switch_status = prefs.use_sparks
  212. sparks_slider_delta.value = 0
  213. sparks_slider_delta.id =-1
  214. settingsWindow_rollcheck_button.switch_status = prefs.rollcheck
  215. settingsWindow_rollcheck_priority_button.switch_status = prefs.rollcheck_priority
  216. use_percolor_delta.switch_status = prefs.use_percolor_delta
  217. notes_overlap_btn.switch_status = prefs.notes_overlap
  218. ignore_notes_with_minimal_duration_btn.switch_status = prefs.ignore_minimal_duration
  219. update_size
  220. for i in range(144):
  221. notes.append(0)
  222. notes_db.append(0)
  223. notes_de.append(0)
  224. notes_channel.append(0)
  225. notes_tmp.append(0)
  226. notes_pressed_color.append([0,0,0])
  227. prefs.keyp_colors_alternate.append([0,0,0])
  228. prefs.keyp_colors_alternate_sensitivity.append(0)
  229. def v_rotate(v, ang):
  230. radAng = ang * math.pi/180
  231. return [ (v[1] * math.cos(radAng)) - (v[0] * math.sin(radAng)), (v[1] * math.sin(radAng)) + (v[0] * math.cos(radAng)) ]
  232. def updatekeys( append=0 ):
  233. xx=0
  234. for i in range(12):
  235. for j in range(12):
  236. if (append == 1) or (i*12+j > len(prefs.keys_pos)-1):
  237. prefs.keys_pos.append( [0,0] )
  238. prefs.keys_pos[i*12+j][0] = int(round( xx ))
  239. prefs.keys_pos[i*12+j][1] = 0
  240. if (j == 1) or ( j ==3 ) or ( j == 6 ) or ( j == 8) or ( j == 10 ):
  241. prefs.keys_pos[i*12+j][1] = prefs.yoffset_blackkeys
  242. xx += -prefs.whitekey_width
  243. # keys_pos[i*12+j][0] = int(round( xx + whitekey_width *0.5 ))
  244. # tune by wuzhuoqing
  245. if (j == 1) or ( j == 6 ):
  246. prefs.keys_pos[i*12+j][0] = int(round( xx + prefs.whitekey_width * prefs.blackkey_relative_position ))
  247. if (j == 8 ):
  248. prefs.keys_pos[i*12+j][0] = int(round( xx + prefs.whitekey_width * 0.5 ))
  249. if ( j ==3 ) or ( j == 10 ):
  250. prefs.keys_pos[i*12+j][0] = int(round( xx + prefs.whitekey_width * (1.0 - prefs.blackkey_relative_position) ))
  251. xx += prefs.whitekey_width
  252. for i in range(len(prefs.keys_pos)):
  253. prefs.keys_pos[i] = v_rotate( prefs.keys_pos[i] , prefs.keys_angle )
  254. prefs.keys_pos[i][0] = - prefs.keys_pos[i][0]
  255. updatekeys( 1 )
  256. loadsettings(inifile)
  257. tStart = t0 = time.time()-1
  258. frames = 0
  259. def snap_to_grid( input_value , input_grid_size ):
  260. quantized = int( (input_value - int(input_value)) * input_grid_size ) / input_grid_size
  261. result = (quantized + int(input_value))
  262. #print ("value before:", input_value , " after :", result)
  263. return result
  264. def framerate():
  265. global t0, frames
  266. t = time.time()
  267. frames += 1
  268. if t - t0 >= 1.0:
  269. seconds = t - t0
  270. if ( seconds != 0) :
  271. fps = frames / seconds
  272. print("%.0f frames in %3.1f seconds = %6.3f FPS" % (frames,seconds,fps))
  273. t0 = t
  274. frames = 0
  275. def loadImage(idframe=130):
  276. global image
  277. global convertCvtColor
  278. if running != 0:
  279. getFrame(idframe)
  280. #image2=cv2.resize(image, (int(video_width/4) , int(video_height/4)))
  281. print("load image from video " + str(width) + "x" + str(height) + " frame: "+ str(idframe))
  282. glPixelStorei(GL_UNPACK_ALIGNMENT,1)
  283. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
  284. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
  285. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
  286. error_on_load=False
  287. try:
  288. if ( convertCvtColor == 1 ):
  289. #print ("Loading RGB texture")
  290. glTexImage2D(GL_TEXTURE_2D, 0, 3, video_width, video_height, 0, GL_RGB, GL_UNSIGNED_BYTE, cv2.cvtColor(image,COLOR_BGR2RGB) )
  291. else:
  292. #print ("Loading BGR texture")
  293. glTexImage2D(GL_TEXTURE_2D, 0, 3, video_width, video_height, 0, GL_BGR, GL_UNSIGNED_BYTE, image )
  294. return
  295. except Exception as E:
  296. error_on_load=True
  297. print("Can't load image from video to OpenGL: %s" % E);
  298. if error_on_load:
  299. rvideo_width, rvideo_height = 512, 512
  300. print("Trying resize video image to %sx%s" % (rvideo_width, rvideo_height));
  301. try:
  302. rimage = cv2.resize(image , (rvideo_width, rvideo_height))
  303. if ( convertCvtColor == 1 ):
  304. glTexImage2D(GL_TEXTURE_2D, 0, 3, rvideo_width, rvideo_height, 0, GL_RGB, GL_UNSIGNED_BYTE, cv2.cvtColor(rimage,COLOR_BGR2RGB) )
  305. else:
  306. glTexImage2D(GL_TEXTURE_2D, 0, 3, rvideo_width, rvideo_height, 0, GL_BGR, GL_UNSIGNED_BYTE, rimage )
  307. except Exception as E:
  308. print("Can't load image from video to OpenGL: %s" % E);
  309. def update_channels(sender):
  310. print( 'update_channels...' +str(sender.index))
  311. i=abs(sender.index) -1
  312. if (sender.index > 0):
  313. prefs.keyp_colors_channel[i]= prefs.keyp_colors_channel[i] + 1
  314. else:
  315. prefs.keyp_colors_channel[i]= prefs.keyp_colors_channel[i] - 1
  316. if (prefs.keyp_colors_channel[i] > 15):
  317. prefs.keyp_colors_channel[i] = 15
  318. if (prefs.keyp_colors_channel[i] < 0):
  319. prefs.keyp_colors_channel[i] = 0
  320. colorWindow_colorBtns_channel_labels[i].text = "Ch:" + str(prefs.keyp_colors_channel[i]+1)
  321. def disable_color(sender):
  322. print( 'disabled color...' +str(sender.index))
  323. if sender.index < len(prefs.keyp_colors):
  324. prefs.keyp_colors[ sender.index ] = [0,0,0]
  325. # prefs.keyp_colors_channel[i]= prefs.keyp_colors_channel[i] + 1
  326. def readkeycolor(i):
  327. pixx=int(prefs.xoffset_whitekeys + prefs.keys_pos[i][0])
  328. pixy=int(prefs.yoffset_whitekeys + prefs.keys_pos[i][1])
  329. if ( pixx >= width ) or ( pixy >= height ) or ( pixx < 0 ) or ( pixy < 0 ): return
  330. if ( prefs.resize == 1 ):
  331. pixxo=pixx
  332. pixyo=pixy
  333. pixx= int(round( pixx * ( video_width / float(prefs.resize_width) )))
  334. pixy= int(round( pixy * ( video_height / float(prefs.resize_height) )))
  335. if ( pixx > video_width -1 ): pixx = video_width-1
  336. if ( pixy > video_height-1 ): pixy= video_height-1
  337. # print "original x:"+str(pixxo) + "x" +str(pixyo) + " mapped :" +str(pixx) +"x"+str(pixy)
  338. keybgr=image[pixy,pixx]
  339. key=[ keybgr[2], keybgr[1],keybgr[0] ]
  340. prefs.keyp_colors_alternate[i] = key
  341. def readcolors(sender):
  342. for i in range( len(prefs.keys_pos) ):
  343. readkeycolor(i)
  344. def update_alternate_sensitivity(sender,value):
  345. global lastkeygrabid
  346. if ( lastkeygrabid != -1 ):
  347. prefs.keyp_colors_alternate_sensitivity[ lastkeygrabid ] = value
  348. def update_sparks_delta(sender,value):
  349. if (sender.id == -1):
  350. return
  351. if (sender.id < len(prefs.keyp_colors)) :
  352. prefs.keyp_colors_sparks_sensitivity[sender.id] = sender.value
  353. #print("keyp_colors_sparks_sensitivity["+str(sender.id)+"] = "+ str(sender.value) )
  354. def update_blackkey_relative_position(sender,value):
  355. prefs.blackkey_relative_position = value * 0.001
  356. updatekeys()
  357. def update_sync_notes_start_pos_time_delta(sender,value):
  358. prefs.sync_notes_start_pos_time_delta = value *0.001
  359. def change_use_alternate_keys(sender):
  360. global extra_label1
  361. prefs.use_alternate_keys = not prefs.use_alternate_keys
  362. update_alternate_label()
  363. def update_alternate_label():
  364. extra_label1.text = "Use alternate:"+str(prefs.use_alternate_keys)
  365. def change_use_sparks(sender):
  366. prefs.use_sparks = sender.switch_status
  367. # sender.text = "use sparks:"+str(use_sparks)
  368. def change_rollcheck(sender):
  369. prefs.rollcheck = sender.switch_status
  370. def change_rollcheck_priority(sender):
  371. prefs.rollcheck_priority = sender.switch_status
  372. def updatecolor(sender):
  373. if (lastkeygrabid != -1):
  374. readkeycolor(lastkeygrabid)
  375. def update_sparks_y_pos (sender):
  376. if (sender.text == 'y+'):
  377. prefs.keyp_spark_y_pos = prefs.keyp_spark_y_pos -1
  378. else:
  379. prefs.keyp_spark_y_pos = prefs.keyp_spark_y_pos +1
  380. def update_line_height(sender,value):
  381. global line_height
  382. line_height = value
  383. def snap_notes_to_the_grid(sender):
  384. global use_snap_notes_to_grid
  385. use_snap_notes_to_grid = sender.switch_status
  386. def raise_octave(*args):
  387. global basenote
  388. prefs.octave += 1
  389. if (prefs.octave > 7): prefs.octave = 7
  390. basenote = prefs.octave * 12
  391. def lower_octave(*args):
  392. global basenote
  393. prefs.octave -= 1
  394. if (prefs.octave < 0): prefs.octave = 0
  395. basenote = prefs.octave * 12
  396. def onPallete_click(sender, index):
  397. selected_color_delta.color = sender.color
  398. if index < len(prefs.percolor_delta):
  399. selected_color_delta.setvalue( prefs.percolor_delta[ index ] )
  400. sparks_slider_delta.id = Gl.keyp_colormap_id
  401. sparks_slider_delta.color = prefs.keyp_colors[Gl.keyp_colormap_id]
  402. sparks_slider_delta.setvalue( prefs.keyp_colors_sparks_sensitivity[Gl.keyp_colormap_id] )
  403. def change_use_percolor_delta(sender):
  404. prefs.use_percolor_delta = sender.switch_status
  405. def update_percolor_delta(sender,value):
  406. if (Gl.keyp_colormap_id == -1):
  407. return
  408. if (Gl.keyp_colormap_id < len(prefs.percolor_delta)):
  409. prefs.percolor_delta[ Gl.keyp_colormap_id ] = sender.value
  410. #print("changed percolor delta for color with id ["+str(sender.id)+"] = "+ str(sender.value) )
  411. def showOrhideallwindows(sender):
  412. if sender is None:
  413. ShowHideButton.switch_status = not ShowHideButton.switch_status
  414. print('switch hidden for all windows')
  415. for i in glwindows:
  416. #print("i.type =%s" % (str(type(i))) )
  417. if isinstance(i, GLWindow ):
  418. i.fullhidden = ShowHideButton.switch_status
  419. def start_recreate_midi(sender):
  420. global running
  421. if prefs.autoclose == 1:
  422. running = 0
  423. else:
  424. reconstruct()
  425. def set_start_frame_to_current_frame(sender):
  426. if sender.index == 0:
  427. prefs.startframe = int(round(vidcap.get(1)))
  428. else:
  429. prefs.startframe = 0
  430. print("set start frame = "+ str(prefs.startframe))
  431. def sef_end_frame_to_current_frame(sender):
  432. global endframe
  433. if sender.index == 0:
  434. endframe = int(round(vidcap.get(1)))
  435. else:
  436. endframe = length
  437. print("set end frame = "+ str(endframe), sender.index)
  438. def switch_notes_overlap(sender):
  439. if sender is None:
  440. prefs.notes_overlap = not prefs.notes_overlap
  441. notes_overlap_btn.switch_status = prefs.notes_overlap
  442. else:
  443. prefs.notes_overlap = notes_overlap_btn.switch_status
  444. def switch_sync_notes_start_pos(sender):
  445. prefs.sync_notes_start_pos = sender.switch_status
  446. def change_save_to_disk_per_channel(sender):
  447. prefs.save_to_disk_per_channel = sender.switch_status
  448. def switch_ignore_notes_with_minimal_duration(sender):
  449. if sender is None:
  450. prefs.ignore_minimal_duration = not prefs.ignore_minimal_duration
  451. ignore_notes_with_minimal_duration_btn.switch_status = prefs.ignore_minimal_duration
  452. else:
  453. prefs.ignore_minimal_duration = ignore_notes_with_minimal_duration_btn.switch_status
  454. def switch_resize_windows(sender):
  455. prefs.resize = not prefs.resize
  456. resize_window()
  457. def scroll_by_steps( steps ):
  458. global frame
  459. frame+=steps
  460. if (frame > length *0.99):
  461. frame=math.trunc(length *0.99)
  462. if (frame < 1):
  463. frame=1
  464. glBindTexture(GL_TEXTURE_2D, Gl.bgImgGL)
  465. loadImage(frame)
  466. def scroll_forward_by_frame(sender):
  467. scroll_by_steps(1)
  468. def scroll_fast_forward(sender):
  469. scroll_by_steps(100)
  470. def scroll_prev_by_frame(sender):
  471. scroll_by_steps(-1)
  472. def scroll_fast_prev(sender):
  473. scroll_by_steps(-100)
  474. def scroll_to_start(sender):
  475. global frame
  476. frame=0
  477. glBindTexture(GL_TEXTURE_2D, Gl.bgImgGL)
  478. loadImage(frame)
  479. def scroll_to_end(sender):
  480. global frame
  481. frame=length-100
  482. glBindTexture(GL_TEXTURE_2D, Gl.bgImgGL)
  483. loadImage(frame)
  484. def btndown_save_settings(sender):
  485. settings.savesettings(settingsfile)
  486. def btndown_load_settings(sender):
  487. old_resize = prefs.resize
  488. loadsettings( settingsfile )
  489. update_alternate_label()
  490. if (prefs.resize != old_resize):
  491. resize_window()
  492. def change_autoclose(sender):
  493. prefs.autoclose = sender.switch_status
  494. def rotate_cw(sender):
  495. prefs.keys_angle -= 5
  496. updatekeys()
  497. def rotate_ccw(sender):
  498. prefs.keys_angle += 5
  499. updatekeys()
  500. wh = ( (len(prefs.keyp_colors) // 2)+2 ) * 24 - 24
  501. colorWindow = GLWindow(24, 50, 274, wh, "color map")
  502. settingsWindow = GLWindow(24+275, 80, 550, 340, "Settings")
  503. helpWindow = GLWindow(24+270, 50, 750, 490, "help")
  504. extraWindow = GLWindow(24+270+550+6, 80, 510, 250, "extra/experimental")
  505. sparksWindow = GLWindow(24+270+550+6, 300, 510, 185, "sparks & color settings")
  506. glwindows = []
  507. ShowHideButton = GLButton(0,0 ,13,13, 1, [128,128,128], "" , showOrhideallwindows ,switch=1, switch_status=0 )
  508. ShowHideButton.active = 2
  509. glwindows.append(ShowHideButton)
  510. glwindows.append(colorWindow)
  511. glwindows.append(settingsWindow)
  512. glwindows.append(helpWindow)
  513. glwindows.append(extraWindow)
  514. glwindows.append(sparksWindow)
  515. helpWindow.hidden=1
  516. helpWindow_label1 = GLLabel(0,0, """h - on window title, show/hide the window
  517. q - begin to recreate midi
  518. s - set start frame, (mods : shift, set processing start frame to the beginning)
  519. e - set end frame, (mods : shift, set processing end frame to the ending)
  520. p - if key is set, force separate to 2 channels (on single color video)
  521. o - enable or disable overlap notes
  522. i - enable or disable ignore/lengthening of notes with minimal duration
  523. r - enable or disable resize function
  524. Mouse wheel - keys adjustment
  525. Left mouse button - dragging the selected key / select color from the color map
  526. CTRL + Left mouse button - update selected color in the color map
  527. CTRL + 0 - disable selected color in the color map
  528. Right mouse button - dragging all keys, if the key is selected, the transfer is carried out relative to it.
  529. Arrows - keys adjustment (mods : shift) ( Atl+Arrows UP/Down - sparks position adjustment )
  530. +(PLUS) / - (MINUS) - rotate keys by 5*
  531. PageUp/PageDown - scrolling video (mods : shift)
  532. Home/End - go to the beginning or end of the video
  533. [ / ] - change base octave
  534. F2 / F3 - save / load settings, F4 - move all windows to the mouse point
  535. Escape - quit, TAB - Show/Hide all windows
  536. Space - abort re-creation and save midi file to disk""")
  537. settingsWindow.appendChild( GLButton(260, 20 ,140,20,0 , [128,128,128], "start recreate midi" , start_recreate_midi , hint = "q - hot key") )
  538. settingsWindow.appendChild( GLButton(260, 40 ,140,20,0 , [128,128,128], "set start frame" , set_start_frame_to_current_frame, hint = "s - hot key, (mods : shift + s, set processing start frame to the beginning)" ) )
  539. settingsWindow.appendChild( GLButton(260+141, 40 ,140,20,0, [128,128,128], "set end frame" , sef_end_frame_to_current_frame , hint = "e - hot key, (mods : shift + e, set processing end frame to the ending)" ) )
  540. notes_overlap_btn = GLButton(260, 80 ,140,20,0, [128,128,128], "notes overlap" , switch_notes_overlap , hint = "o - hot key", switch=1, switch_status=0)
  541. ignore_notes_with_minimal_duration_btn = GLButton(260,100 ,272,20,0, [128,128,128], "ignore notes with minimal duration", switch_ignore_notes_with_minimal_duration, hint = "i - hot key", switch=1, switch_status=0)
  542. settingsWindow.appendChild( notes_overlap_btn )
  543. settingsWindow.appendChild( ignore_notes_with_minimal_duration_btn )
  544. settingsWindow.appendChild( GLButton(260+141, 80 ,140,20,0, [128,128,128], "sync notes" , switch_sync_notes_start_pos , hint = "sync notes start pos", switch=1, switch_status=0) )
  545. settingsWindow.appendChild( GLButton(260,120 ,140,20,0, [128,128,128], "resize window" , switch_resize_windows , hint = "r - hot key") )
  546. exit_switch = GLButton(260+141, 120 ,140,20,1, [128,128,128], "auto-close" ,change_autoclose,switch=1, switch_status= prefs.autoclose, hint = "exit after the completion of the midi reconstruction" )
  547. settingsWindow.appendChild( exit_switch )
  548. settingsWindow.appendChild( GLButton(260 , 140 ,140,20,0, [128,128,128], "save settings" , btndown_save_settings , hint = "F2 - hot key, save current settings" ) )
  549. settingsWindow.appendChild( GLButton(260+141, 140 ,140,20,0, [128,128,128], "load settings" , btndown_load_settings , hint = "F3 - hot key, load saved settings" ) )
  550. navbtns_info = [
  551. {'name' : "[<", 'hint' : 'Home - hot key, go to first frame',
  552. 'func' : scroll_to_start },
  553. {'name' : "<<", 'hint' : 'PageDown - hot key, fast scroll backward',
  554. 'func' : scroll_fast_prev },
  555. {'name' : " <", 'hint' : 'Shift+PageDown - shortcut, scroll backward by frame',
  556. 'func' : scroll_prev_by_frame },
  557. {'name' : " >", 'hint' : 'Shift+PageUp - shortcut, scroll forward by frame',
  558. 'func' : scroll_forward_by_frame },
  559. {'name' : ">>", 'hint' : 'PageUp - hot key,fast scroll forward',
  560. 'func' : scroll_fast_forward },
  561. {'name' : " >]", 'hint' : 'End - hot key, go to last frame',
  562. 'func' : scroll_to_end },
  563. {'name' : "R+", 'hint' : 'rotate the keys clockwise, hot key +',
  564. 'func' : rotate_cw },
  565. {'name' : "R-", 'hint' : 'rotate the keys counterclockwise, hot key -',
  566. 'func' : rotate_ccw }
  567. ]
  568. #btnfuncs = [ None, None, None, None, None, None ]
  569. for i in range(len( navbtns_info )):
  570. settingsWindow.appendChild( GLButton(260 + i * 32,230 ,32,20,0, [128,128,128], navbtns_info[i]['name'] , navbtns_info[i]['func'], hint = navbtns_info[i]['hint']) )
  571. helpWindow.appendChild(helpWindow_label1)
  572. settingsWindow_label1 = GLLabel(1,0, "base octave: " + str(prefs.octave))
  573. # + "\nnotes overlap: " + str(prefs.notes_overlap) + "\nignore minimal duration: " + str(prefs.ignore_minimal_duration))
  574. settingsWindow.appendChild(settingsWindow_label1)
  575. settingsWindow.appendChild( GLButton(130,0 ,20,20,1, [128,128,128], "+", raise_octave, hint = "] - hot key, move up base octave (+12 tones)" ) )
  576. settingsWindow.appendChild( GLButton(150,0 ,20,20,1, [128,128,128], " -", lower_octave, hint = "[ - hot key, move down base octave (-12 tones)" ) )
  577. settingsWindow_slider1 = GLSlider(1,40, 240,18, 0,130,prefs.keyp_delta,label="Sensitivity")
  578. settingsWindow_slider1.round=1
  579. settingsWindow.appendChild(settingsWindow_slider1)
  580. settingsWindow_slider2 = GLSlider(1,90, 240,18, 0,200,prefs.minimal_duration*100,label="Minimal note duration (sec)")
  581. settingsWindow_slider2.round=0
  582. settingsWindow.appendChild(settingsWindow_slider2)
  583. settingsWindow_slider3 = GLSlider(1,133, 240,18, 30,240,prefs.tempo,label="Output tempo for midi")
  584. settingsWindow_slider3.round=0
  585. settingsWindow.appendChild(settingsWindow_slider3)
  586. settingsWindow_slider4 = GLSlider(1,175, 240,18, 0,2,midi_file_format,label="Output midi format")
  587. settingsWindow_slider4.round=0
  588. settingsWindow.appendChild(settingsWindow_slider4)
  589. settingsWindow_slider5 = GLSlider(1,215, 240,18, 0,1000,prefs.blackkey_relative_position * 1000, update_blackkey_relative_position, label="black key relative pos")
  590. settingsWindow_slider5.round=0
  591. settingsWindow.appendChild(settingsWindow_slider5)
  592. settingsWindow_slider6 = GLSlider(1,255, 240,18, 0,1000,prefs.sync_notes_start_pos_time_delta, update_sync_notes_start_pos_time_delta, label="sync notes time delta (ms)")
  593. settingsWindow_slider6.round=0
  594. settingsWindow.appendChild(settingsWindow_slider6)
  595. settingsWindow_rollcheck_button = GLButton(260,160 ,140,22,1, [128,128,128], "roll check" ,change_rollcheck,switch=1, switch_status=prefs.rollcheck )
  596. settingsWindow.appendChild(settingsWindow_rollcheck_button)
  597. settingsWindow.appendChild( GLButton(260+141, 160 ,140,20,1, [128,128,128], "per channel save" ,change_save_to_disk_per_channel,switch=1, switch_status= prefs.save_to_disk_per_channel, hint = "split the output midi per channels" ) )
  598. settingsWindow_rollcheck_priority_button = GLButton(260,180 ,222,22,1, [128,128,128], "rollcheck white keys priority" ,change_rollcheck_priority,switch=1, switch_status=prefs.rollcheck_priority )
  599. settingsWindow.appendChild(settingsWindow_rollcheck_priority_button)
  600. # for i in range( len( keyp_colors ) ):
  601. #keyp_colormap_colors_pos.append ([ (i % 2) * 32, ( i // 2 ) * 20 ])
  602. print ('creating new colors '+str(len( prefs.keyp_colors )))
  603. sparks_slider_delta = GLSlider(6,25, 150,18, -50,150,50,update_sparks_delta, label="Sparks delta")
  604. for i in range( len( prefs.keyp_colors ) ):
  605. cx,cy = (i % 2) * 130, ( i // 2 ) * 20
  606. offsetx,offsety=4,4
  607. colorBtns.append( GLColorButton(offsetx+cx,offsety+cy ,20,20,i, prefs.keyp_colors[i], onPallete_click ) )
  608. colorWindow.appendChild(colorBtns[i])
  609. colorWindow_label1 = GLLabel(offsetx+25+cx,offsety+cy , "Ch:" + str(prefs.keyp_colors_channel[i]+1) )
  610. colorWindow_colorBtns_channel_labels.append( colorWindow_label1 )
  611. colorWindow.appendChild(colorWindow_label1)
  612. colorWindow_colorBtns_channel_btns.append( GLButton(offsetx+cx+70,offsety+cy ,20,20,(i+1), [128,128,128], "+" ,update_channels) )
  613. colorWindow_colorBtns_channel_btns.append( GLButton(offsetx+cx+70+20,offsety+cy ,20,20,-(i+1), [128,128,128], "-" ,update_channels) )
  614. colorWindow_colorBtns_channel_btns.append( GLButton(offsetx+cx+70+40,offsety+cy ,20,20,i, [128,128,128], "x" ,disable_color, hint="ctrl+0 - shortcut, disable selected color") )
  615. for i in colorWindow_colorBtns_channel_btns:
  616. colorWindow.appendChild( i )
  617. extraWindow.appendChild( GLButton(5, 20 ,128,25,1, [128,128,128], "read colors" ,readcolors) )
  618. extraWindow.appendChild( GLButton(135,20 ,128,25,1, [128,128,128], "update color" ,updatecolor) )
  619. extraWindow.appendChild( GLButton(265,20 ,138,25,1, [128,128,128], "enable/disable" ,change_use_alternate_keys) )
  620. extraWindow.appendChild( GLButton(265,45 ,155,22,1, [96 ,96 ,128], "snap notes to grid" ,snap_notes_to_the_grid,switch=1, switch_status=use_snap_notes_to_grid) )
  621. extra_label1 = GLLabel(6,0, "Use alternate:"+str(prefs.use_alternate_keys) )
  622. extraWindow.appendChild( extra_label1 )
  623. #extra_label2 = GLLabel(0,67, "Selected key sensitivity:"+str(0) )
  624. extra_slider1 = GLSlider(6,65, 240,18, -100,100,0,update_alternate_sensitivity, label="Selected key sensitivity")
  625. #extra_slider1.showvalue=True
  626. #showvaluesinlabel=0
  627. extraWindow.appendChild(extra_slider1)
  628. extra_label3 = GLLabel( 6,90, """to select the key press ctrl + left mouse button on the key rect.
  629. to deselect the key press ctrl + left mouse button on empty space.""" )
  630. extraWindow.appendChild( extra_label3 )
  631. extraWindow_slider2 = GLSlider(5,155, 240,18, 0,2000, line_height, update_line_height, label="length of vertical key lines")
  632. extraWindow_slider2.round=0
  633. extraWindow.appendChild(extraWindow_slider2)
  634. sparks_slider_height = GLSlider(160,25, 150,18, 1,60,1,None, label="Sparks height")
  635. sparks_slider_height.round=0
  636. sparks_switch = GLButton(313,24 ,100,22,1, [128,128,128], "use sparks" ,change_use_sparks,switch=1, switch_status=prefs.use_sparks )
  637. sparksWindow.appendChild( sparks_slider_delta )
  638. sparksWindow.appendChild( sparks_slider_height )
  639. sparksWindow.appendChild( sparks_switch )
  640. #
  641. sparksWindow.appendChild( GLButton(413 ,24 ,32,22,1, [96,96,128], "y+" ,update_sparks_y_pos, hint="move sparks higher") )
  642. sparksWindow.appendChild( GLButton(413+33,24 ,32,22,1, [96,96,128], "y-" ,update_sparks_y_pos, hint="move sparks lower") )
  643. sparksWindow.appendChild( GLLabel( 6,50, "alt + up / down - move sparks label up or down " ))
  644. selected_color_delta = GLSlider(6,100, 200,18, 0,130,50,update_percolor_delta, label="percolor sensitivity")
  645. selected_color_delta.round=1
  646. use_percolor_delta = GLButton(313,100 ,190,22,1, [128,128,128], "use percolor sensitivity" ,change_use_percolor_delta,switch=1, switch_status=prefs.use_sparks )
  647. sparksWindow.appendChild( selected_color_delta )
  648. sparksWindow.appendChild( use_percolor_delta )
  649. #colorSettingsWindow.appendChild( GLButton(413 ,24 ,64,22,1, [96,96,128], "Pallette" , None ) )
  650. #
  651. #extra_slider2.showvalue=True
  652. #extra.appendChild(extra_label2)
  653. #loadsettings( settingsfile )
  654. #frame=801
  655. def getkeyp_pixel_pos( x:int, y:int ) -> list[int]:
  656. pixx=int(prefs.xoffset_whitekeys + x)
  657. pixy=int(prefs.yoffset_whitekeys + y)
  658. if ( pixx >= width ) or ( pixy >= height ) or ( pixx < 0 ) or ( pixy < 0 ):
  659. return [-1,-1]
  660. #if ( prefs.resize == 1 ):
  661. if 1==1: #disabled
  662. pixx= int(round( pixx * ( video_width / float(width) )))
  663. pixy= int(round( pixy * ( video_height / float(height) )))
  664. if ( pixx > video_width -1 ): pixx = video_width-1
  665. if ( pixy > video_height-1 ): pixy= video_height-1
  666. return [pixx,pixy]
  667. def iswhitekey( key_num: int ) -> int:
  668. j = key_num % 12
  669. if (j == 1) or ( j ==3 ) or ( j == 6 ) or ( j == 8) or ( j == 10 ):
  670. return 1
  671. return 0
  672. def drawframe( lastimage = None):
  673. global pyfont
  674. global helptext
  675. global mousex, mousey
  676. global keyp_colormap_colors_pos
  677. global keyp_colormap_pos
  678. global frame
  679. global printed_for_frame
  680. global notes_tmp
  681. global notes_pressed_color
  682. #global old_spark_color
  683. #global cur_spark_color
  684. print_for_frame_debug = False
  685. if printed_for_frame != frame:
  686. print_for_frame_debug = True
  687. printed_for_frame = frame
  688. scale=1.0
  689. mousex, mousey = pygame.mouse.get_pos()
  690. glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
  691. glViewport (0, 0, width, height)
  692. glMatrixMode (GL_PROJECTION)
  693. glLoadIdentity ()
  694. glOrtho(0, width, height, 0, -1, 100)
  695. glMatrixMode(GL_MODELVIEW)
  696. glLoadIdentity()
  697. glDisable(GL_DEPTH_TEST)
  698. glScale(scale,scale,1)
  699. glColor4f(1.0, 1.0, 1.0, 1.0)
  700. glBindTexture(GL_TEXTURE_2D, Gl.bgImgGL)
  701. glEnable(GL_TEXTURE_2D)
  702. DrawQuad(0,0,width,height)
  703. glEnable(GL_BLEND)
  704. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
  705. glColor4f(1.0, 0.5, 1.0, 0.5)
  706. glPushMatrix()
  707. glTranslatef(prefs.xoffset_whitekeys,prefs.yoffset_whitekeys,0)
  708. glDisable(GL_TEXTURE_2D)
  709. for i in range( len( prefs.keys_pos) ):
  710. pixpos = getkeyp_pixel_pos(prefs.keys_pos[i][0],prefs.keys_pos[i][1])
  711. if (pixpos[0] == -1) and (pixpos[1] == -1):
  712. continue
  713. if lastimage is not None:
  714. keybgr=lastimage[ pixpos[1], pixpos[0] ]
  715. else:
  716. keybgr=image[ pixpos[1], pixpos[0] ]
  717. key= [ keybgr[2], keybgr[1],keybgr[0] ]
  718. keybgr=[0,0,0]
  719. sparkkey=[0,0,0]
  720. if prefs.use_sparks:
  721. sh = int(sparks_slider_height.value)
  722. if sh == 0:
  723. sh = 1
  724. for spark_y_add_pos in range (sh):
  725. sparkpixpos = getkeyp_pixel_pos(prefs.keys_pos[i][0],prefs.keyp_spark_y_pos - spark_y_add_pos )
  726. if not ((sparkpixpos[0] == -1) and (sparkpixpos[1] == -1)):
  727. keybgr = image[ sparkpixpos[1], sparkpixpos[0] ]
  728. sparkkey = [ sparkkey[0] + keybgr[2],
  729. sparkkey[1] + keybgr[1],
  730. sparkkey[2] + keybgr[0] ]
  731. sparkkey = [ sparkkey[0] / sh, sparkkey[1] / sh,sparkkey[2] / sh]
  732. #cur_spark_color[i] = sparkkey
  733. else:
  734. sparkkey = [0,0,0]
  735. note=i
  736. if ( note > 144 ):
  737. print("skip note > 144")
  738. continue
  739. keypressed=0
  740. pressedcolor=[0,0,0]
  741. if prefs.use_alternate_keys:
  742. delta = prefs.keyp_delta + prefs.keyp_colors_alternate_sensitivity[i]
  743. if ( abs( int(key[0]) - prefs.keyp_colors_alternate[i][0] ) > delta ) and ( abs( int(key[1]) - prefs.keyp_colors_alternate[i][1] ) > delta ) and ( abs( int(key[2]) - prefs.keyp_colors_alternate[i][2] ) > delta ):
  744. keypressed=1
  745. pressedcolor=prefs.keyp_colors_alternate[i]
  746. else:
  747. for key_id in range( len(prefs.keyp_colors) ):
  748. keyc = prefs.keyp_colors[key_id]
  749. spark_delta = prefs.keyp_colors_sparks_sensitivity[key_id]
  750. delta = prefs.keyp_delta
  751. if prefs.use_percolor_delta:
  752. if key_id < len( prefs.percolor_delta ):
  753. delta = prefs.percolor_delta[ key_id ]
  754. if (keyc[0] != 0 ) or (keyc[1] != 0 ) or (keyc[2] != 0 ) :
  755. if ( abs( int(key[0]) - keyc[0] ) < delta ) and ( abs( int(key[1]) - keyc[1] ) < delta ) and ( abs( int(key[2]) - keyc[2] ) < delta ):
  756. keypressed=1
  757. pressedcolor = keyc
  758. notes_pressed_color[i] = keyc
  759. if prefs.use_sparks:
  760. #unpressed_by_spark_delta = ( abs( int(sparkkey[0]) - keyc[0] ) < spark_delta ) and ( abs( int(sparkkey[1]) - keyc[1] ) < spark_delta ) and ( abs( int(sparkkey[2]) - keyc[2] ) < spark_delta )
  761. has_spark_delta = ((sparkkey[0] - keyc[0] ) > spark_delta ) or ((sparkkey[1] - keyc[1] ) > spark_delta ) or ((sparkkey[2] - keyc[2] ) > spark_delta )
  762. #unpressed_by_spark_fade = ( cur_spark_color[i][0] < old_spark_color[i][0]) and ( cur_spark_color[i][1] < old_spark_color[i][1]) and ( cur_spark_color[i][2] < old_spark_color[i][2])
  763. #unpressed_by_spark_fade_delta = ( abs( cur_spark_color[i][0] - old_spark_color[i][0]) > 20 )
  764. if print_for_frame_debug:
  765. print("note %d key_id %d spark_delta %d sparkkey vs keyc %d %d, %d %d, %d %d" % (note, key_id, spark_delta, sparkkey[0], keyc[0], sparkkey[1], keyc[1], sparkkey[2], keyc[2]))
  766. if ( not has_spark_delta ):
  767. keypressed=2
  768. notes_tmp[i] = keypressed
  769. if prefs.rollcheck:
  770. for i in range(1, len( prefs.keys_pos) -1 ):
  771. if prefs.rollcheck_priority == 0:
  772. if not iswhitekey(i):
  773. # Priority on Black keys
  774. if notes_tmp[i+1] >0: notes_tmp[i] = 0
  775. if notes_tmp[i-1] >0: notes_tmp[i] = 0
  776. else:
  777. if iswhitekey(i):
  778. # Priority on White keys
  779. if notes_tmp[i+1] >0: notes_tmp[i] = 0
  780. if notes_tmp[i-1] >0: notes_tmp[i] = 0
  781. for i in range( len( prefs.keys_pos) ):
  782. keypressed = notes_tmp[i]
  783. pressedcolor = notes_pressed_color[i]
  784. glPushMatrix()
  785. glTranslatef(prefs.keys_pos[i][0],prefs.keys_pos[i][1],0)
  786. glColor4f(1,1,1,0.5)
  787. if iswhitekey(i):
  788. glColor4f(0.57,0.57,0.57,0.55)
  789. DrawQuad(-0.5,-line_height,0.5, line_height )
  790. if ( keypressed != 0 ):
  791. #glColor4f(1.0, 0.5, 1.0, 0.9)
  792. glColor4f(pressedcolor[0]/255.0,pressedcolor[1]/255.0,pressedcolor[2]/255.0,0.9)
  793. DrawQuad(-6,-7,6,7)
  794. glColor4f(0,0,0,1)
  795. if ( keypressed == 1):
  796. DrawRect(-7,-9,7,9,3)
  797. else:
  798. DrawRect(-5,-7,5,7,3)
  799. else:
  800. glColor4f(0,0,0,1)
  801. DrawRect(-7,-7,7,7,1)
  802. glColor4f(0.5, 1, 1.0, 0.7)
  803. DrawQuad(-5,-5,5,5)
  804. if ( lastkeygrabid == i ):
  805. glColor4f(0.0, 0.5, 1.0, 0.7)
  806. DrawQuad(-4,-4,4,4)
  807. if ( separate_note_id == i ):
  808. glColor4f(0,1,0,1)
  809. DrawRect(-7,-12,7,12,2)
  810. if prefs.octave * 12 == i:
  811. glColor4f(1,0,0,1)
  812. DrawRect(-9,9,9,12,3)
  813. DrawQuad(-1,-1,1,1)
  814. glPopMatrix()
  815. glColor4f(0.0, 1.0, 1.0, 0.7)
  816. # Sparks
  817. if prefs.use_sparks:
  818. glPushMatrix()
  819. glTranslatef(prefs.keys_pos[i][0], prefs.keyp_spark_y_pos ,0)
  820. glColor4f(0.5, 1, 1.0, 0.7)
  821. DrawQuad(-1,-1,1,1)
  822. DrawQuad(-0.5,-sparks_slider_height.value ,0.5,0)
  823. glPopMatrix()
  824. glPopMatrix()
  825. glDisable(GL_BLEND)
  826. glDisable(GL_TEXTURE_2D)
  827. for i in range(len(glwindows)):
  828. glwindows[i].draw()
  829. # drawing hints over all windows
  830. for i in range(len(glwindows)):
  831. glwindows[i].drawhint()
  832. prefs.keyp_delta = int(settingsWindow_slider1.value)
  833. prefs.minimal_duration = settingsWindow_slider2.value *0.01
  834. prefs.tempo = int(settingsWindow_slider3.value)
  835. settingsWindow_label1.text = "base octave: " + str(prefs.octave)
  836. # + "\nnotes overlap: " + str(prefs.notes_overlap) + "\nignore minimal duration: " + str(prefs.ignore_minimal_duration)
  837. #settingsWindow_label2.text = "Sensitivity:"+str(keyp_delta)+"\n\nMinimal note duration (sec):"+format(minimal_duration,'.2f' ) + "\n\nOutput tempo for midi:" + str(tempo)
  838. for i in range(len(prefs.keyp_colors)):
  839. colorBtns[i].color = prefs.keyp_colors[i]
  840. glPushMatrix()
  841. glTranslatef(mousex,mousey,0)
  842. glColor4f(0.2, 0.5, 1, 0.9)
  843. DrawQuad(-1,-1,1,1)
  844. glPopMatrix()
  845. if showoutputpath > time.time():
  846. drawHint( width *0.5, height -20, prefs.save_to_disk_message, True)
  847. def processmidi():
  848. global frame
  849. global width
  850. global height
  851. global length
  852. global fps
  853. global notes
  854. global notes_db
  855. global notes_de
  856. global notes_channel
  857. global success,image
  858. global separate_note_id
  859. global outputmid
  860. global basenote
  861. print("video " + str(width) + "x" + str(height))
  862. basenote = prefs.octave * 12
  863. mf = midinotes( int(midi_file_format))
  864. track = 0 # the only track
  865. time = 0 # start at the beginning
  866. mf.setup_track(time, prefs.miditrackname, prefs.tempo)
  867. first_note_time=0
  868. channel_has_note = [ 0 for x in range(16) ]
  869. for i in range(len(prefs.keyp_colors_channel)):
  870. mf.addProgramChange(track, prefs.keyp_colors_channel[i], prefs.keyp_colors_channel_prog[i])
  871. print("starting from frame:" + str(prefs.startframe))
  872. getFrame( prefs.startframe )
  873. notecnt=0
  874. lastimage = image
  875. while success:
  876. if (frame % 10 == 0):
  877. glBindTexture(GL_TEXTURE_2D, Gl.bgImgGL)
  878. if (frame % 200 == 0):
  879. loadImage(frame)
  880. lastimage = image
  881. #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
  882. #glTexImage2D(GL_TEXTURE_2D, 0, 3, video_width, video_height, 0, GL_BGR, GL_UNSIGNED_BYTE, image )
  883. #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
  884. glEnable(GL_TEXTURE_2D)
  885. drawframe( lastimage )
  886. glColor4f(1.0, 0.5, 1.0, 0.5)
  887. glDisable(GL_TEXTURE_2D)
  888. p= frame / float( length )
  889. DrawQuad(0,height *0.5 -10, p * width ,height *0.5 +10)
  890. # glPopMatrix();:
  891. pygame.display.flip()
  892. # if (frame % 100 == 0):
  893. print("processing frame: " + str(frame) + " / " + str(length) + " % " + str( math.trunc(p * 100)))
  894. # if ( resize == 1 ):
  895. # image=cv2.resize(image, (width , height))
  896. # processing white keys
  897. for i in range( len(prefs.keys_pos) ):
  898. pixpos = getkeyp_pixel_pos(prefs.keys_pos[i][0],prefs.keys_pos[i][1])
  899. if (pixpos[0] == -1) and (pixpos[1] == -1):
  900. continue
  901. keybgr=image[ pixpos[1], pixpos[0] ]
  902. key= [ keybgr[2], keybgr[1],keybgr[0] ]
  903. keybgr=[0,0,0]
  904. sparkkey=[0,0,0]
  905. if prefs.use_sparks:
  906. sh = int(sparks_slider_height.value)
  907. if sh == 0:
  908. sh = 1
  909. for spark_y_add_pos in range (sh):
  910. sparkpixpos = getkeyp_pixel_pos(prefs.keys_pos[i][0],prefs.keyp_spark_y_pos - spark_y_add_pos )
  911. if not ((sparkpixpos[0] == -1) and (sparkpixpos[1] == -1)):
  912. keybgr = image[ sparkpixpos[1], sparkpixpos[0] ]
  913. sparkkey = [ sparkkey[0] + keybgr[2],
  914. sparkkey[1] + keybgr[1],
  915. sparkkey[2] + keybgr[0] ]
  916. sparkkey = [ sparkkey[0] / sh, sparkkey[1] / sh,sparkkey[2] / sh]
  917. else:
  918. sparkkey = [0,0,0]
  919. note=i
  920. if ( note > 144 ):
  921. print("skip note > 144")
  922. continue
  923. keypressed=0
  924. note_channel=0
  925. # deltaclr = abs( int(key[0]) - keyp_colors[0][0] ) + abs( int(key[1]) - keyp_colors[0][1] ) + abs( int(key[2]) - keyp_colors[0][2] )
  926. deltaclr = prefs.keyp_delta*prefs.keyp_delta*prefs.keyp_delta
  927. deltaid = 0
  928. if prefs.use_alternate_keys:
  929. delta = prefs.keyp_delta + prefs.keyp_colors_alternate_sensitivity[i]
  930. if ( abs( int(key[0]) - prefs.keyp_colors_alternate[i][0] ) > delta ) and ( abs( int(key[1]) - prefs.keyp_colors_alternate[i][1] ) > delta ) and ( abs( int(key[2]) - prefs.keyp_colors_alternate[i][2] ) > delta ):
  931. keypressed = 1
  932. pressedcolor = prefs.keyp_colors_alternate[i]
  933. else:
  934. for j in range(len(prefs.keyp_colors)):
  935. delta = prefs.keyp_delta
  936. if prefs.use_percolor_delta:
  937. if j < len( prefs.percolor_delta ):
  938. delta = prefs.percolor_delta[ j ]
  939. deltaclr = delta*delta*delta
  940. if (prefs.keyp_colors[j][0] != 0 ) or ( prefs.keyp_colors[j][1] != 0 ) or ( prefs.keyp_colors[j][2] != 0 ):
  941. if ( abs( int(key[0]) - prefs.keyp_colors[j][0] ) < delta ) and ( abs( int(key[1]) - prefs.keyp_colors[j][1] ) < delta ) and ( abs( int(key[2]) - prefs.keyp_colors[j][2] ) < delta ):
  942. delta = abs( int(key[0]) - prefs.keyp_colors[j][0] ) + abs( int(key[1]) - prefs.keyp_colors[j][1] ) + abs( int(key[2]) - prefs.keyp_colors[j][2] )
  943. if ( delta < deltaclr ):
  944. deltaclr = delta
  945. deltaid = j
  946. keypressed=1
  947. if prefs.use_sparks:
  948. has_spark_delta = ((sparkkey[0] - prefs.keyp_colors[j][0] ) > prefs.keyp_colors_sparks_sensitivity[j] ) or ((sparkkey[1] - prefs.keyp_colors[j][1] ) > prefs.keyp_colors_sparks_sensitivity[j] ) or ((sparkkey[2] - prefs.keyp_colors[j][2] ) > prefs.keyp_colors_sparks_sensitivity[j] )
  949. #if ( abs( int(sparkkey[0]) - keyp_colors[j][0] ) < keyp_colors_sparks_sensitivity[j] ) and ( abs( int(sparkkey[1]) - keyp_colors[j][1] ) < keyp_colors_sparks_sensitivity[j] ) and ( abs( int(sparkkey[2]) - keyp_colors[j][2] ) < keyp_colors_sparks_sensitivity[j] ):
  950. if ( not has_spark_delta ):
  951. keypressed=0
  952. if ( keypressed != 0 ):
  953. note_channel=prefs.keyp_colors_channel[ deltaid ]
  954. if ( prefs.debug == 1 ):
  955. if (keypressed == 1 ):
  956. cv2.rectangle(image, (pixx-5,pixy-5), (pixx+5,pixy+5), (128,128,255), -1 )
  957. cv2.putText(image, str(note_channel), (pixx-5,pixy-10), 0, 0.3, (64,128,255))
  958. # cv2.rectangle(image, (pixx-5,pixy-5), (pixx+5,pixy+5), (255,0,255))
  959. cv2.rectangle(image, (pixx-1,pixy-1), (pixx+1,pixy+1), (255,0,255))
  960. # cv2.putText(image, str(note), (pixx-5,pixy+20), 0, 0.5, (255,0,255))
  961. # reg pressed key; when keypressed==2 and previous keypressed state is 0 or 2 we should also goes here
  962. if keypressed==1 or (keypressed==2 and notes[note] != 1):
  963. # if key is not pressed
  964. if ( notes[note] == 0 ):
  965. if ( debug_keys == 1 ):
  966. print("note pressed on :" + str( note ))
  967. notes_db[ note ] = frame
  968. if (first_note_time == 0):
  969. first_note_time = frame / fps
  970. notes_channel[ note ] = note_channel
  971. if ( separate_note_id != -1 ):
  972. if ( separate_note_id < note ):
  973. notes_channel[ note ] = 0
  974. else:
  975. notes_channel[ note ] = 1
  976. # always update to last press state
  977. notes[ note ] = keypressed
  978. notes_tmp[ note] = keypressed
  979. # save fall notes and then we can check for a near keys with priority...
  980. if prefs.rollcheck:
  981. for i in range(1, len( prefs.keys_pos)-1 ):
  982. if notes[ i ] != 0:
  983. if prefs.rollcheck_priority == 0:
  984. if not iswhitekey(i):
  985. # Priority on Black keys
  986. if notes[i+1] >0 and notes_tmp[i] >0: notes[i] = 0
  987. if notes[i-1] >0 and notes_tmp[i] >0: notes[i] = 0
  988. else:
  989. if iswhitekey(i):
  990. # Priority on White keys
  991. if notes[i+1] >0 and notes_tmp[i] >0: notes[i] = 0
  992. if notes[i-1] >0 and notes_tmp[i] >0: notes[i] = 0
  993. #
  994. for i in range( len( prefs.keys_pos) ):
  995. note=i
  996. keypressed = notes[ note ]
  997. if notes_tmp[ i ] != 0:
  998. if ( notes[note] != 0 ) and ( notes_channel[ note ] != note_channel ) and ( prefs.notes_overlap == 1 ):
  999. # case if one key over other
  1000. time = notes_db[note] / fps
  1001. duration = ( frame - notes_db[note] ) / fps
  1002. if (use_snap_notes_to_grid == 1):
  1003. #print ("1 time:", time , "first_note_time:",first_note_time)
  1004. time = snap_to_grid( time - first_note_time , notes_grid_size ) + 1
  1005. duration = snap_to_grid( duration , notes_grid_size )
  1006. #print ("1 time after:", time , "after before:",duration)
  1007. ignore = 0
  1008. if ( duration < prefs.minimal_duration ):
  1009. if ( debug_keys == 1 ):
  1010. print(" duration:" + str(duration) + " < minimal_duration:" + str(prefs.minimal_duration))
  1011. duration = prefs.minimal_duration
  1012. if ( prefs.ignore_minimal_duration == 1 ):
  1013. ignore=1
  1014. if ( debug_keys == 1 ):
  1015. print("keys (one over other), note released :" + str(note) + " de = " + str(notes_de[note]) + "- db =" + str(notes_db[note]))
  1016. print("midi add white keys, note : " +str(note) + " time:" +str(time) + " duration:" + str(duration))
  1017. if ( not ignore ):
  1018. mf.addNote(track, notes_channel[note] , basenote + note, time * prefs.tempo / 60.0 , duration * prefs.tempo / 60.0 , volume )
  1019. channel_has_note[ note_channel ] = 1
  1020. notecnt+=1
  1021. notes_db[ note ] = frame
  1022. notes_channel[ note ] = note_channel
  1023. else:
  1024. # if key been presed and released: two cases goes here keypressed==0 or (keypressed==2 and previous state is keypressed==1)
  1025. if ( notes[note] != 0):
  1026. notes[ note ] = 0
  1027. notes_de[ note ] = frame
  1028. time = notes_db[note] / fps
  1029. duration = ( notes_de[note] - notes_db[note] ) / fps
  1030. if (use_snap_notes_to_grid):
  1031. if (first_note_time == 0):
  1032. first_note_time = time
  1033. #print ("2 time:", time , "first_note_time:",first_note_time)
  1034. time = snap_to_grid( time - first_note_time , notes_grid_size ) + 1
  1035. duration = snap_to_grid( duration , notes_grid_size )
  1036. ignore=0
  1037. if ( duration < prefs.minimal_duration ):
  1038. if ( debug_keys == 1 ):
  1039. print(" duration:" + str(duration) + " < minimal_duration:" + str(prefs.minimal_duration))
  1040. duration = prefs.minimal_duration
  1041. if ( prefs.ignore_minimal_duration == 1 ):
  1042. ignore=1
  1043. if ( debug_keys == 1 ):
  1044. print("keys, note released :" + str(note ) + " de = " + str(notes_de[note]) + "- db =" + str(notes_db[note]))
  1045. print("midi add white keys, note : " +str(note) + " time:" +str(time) + " duration:" + str(duration))
  1046. if ( not ignore ):
  1047. mf.addNote(track, notes_channel[note] , basenote+ note, time * prefs.tempo / 60.0 , duration * prefs.tempo / 60.0 , volume )
  1048. channel_has_note[ note_channel ] = 1
  1049. notecnt+=1
  1050. # coming here when use sparks is true and previous state is keypressed==1. We consider the key is released and then pressed again
  1051. if (keypressed==2):
  1052. notes[ note ] = keypressed
  1053. notes_db[ note ] = frame
  1054. notes_channel[ note ] = note_channel
  1055. xapp=0
  1056. if ( prefs.debug == 1 ):
  1057. cv2.imwrite("/tmp/frame%d.jpg" % frame, image) # save frame as JPEG file
  1058. # success,image = vidcap.read()
  1059. getFrame()
  1060. frame += 1
  1061. framerate()
  1062. if ( frame > endframe ):
  1063. success = False
  1064. for event in pygame.event.get():
  1065. if event.type == pygame.QUIT:
  1066. success = False
  1067. pygame.quit()
  1068. quit()
  1069. elif event.type == pygame.KEYDOWN:
  1070. if event.key == pygame.K_SPACE:
  1071. success = False
  1072. if event.key == pygame.K_ESCAPE:
  1073. running = 0
  1074. pygame.quit()
  1075. quit()
  1076. print("saved notes: " + str(notecnt))
  1077. #search free id for name ...
  1078. fileid=0
  1079. while os.path.exists( outputmid ):
  1080. outputmid = ntpath.basename( filepath ) + "_"+str(fileid)+ "_output.mid"
  1081. fileid+=1
  1082. if ( fileid > 999 ): break
  1083. if prefs.sync_notes_start_pos:
  1084. mf.sync_start_pos(prefs.sync_notes_start_pos_time_delta, False)
  1085. if prefs.save_to_disk_per_channel:
  1086. status, prefs.save_to_disk_message = mf.save_to_disk_per_channel(outputmid)
  1087. else:
  1088. status, prefs.save_to_disk_message = mf.save_to_disk(outputmid)
  1089. return status
  1090. def doinit():
  1091. doinitGl()
  1092. loadImage()
  1093. GenFontTexture()
  1094. def reconstruct():
  1095. global frame
  1096. global showoutputpath
  1097. helpWindow.hidden=1
  1098. frame=prefs.startframe
  1099. t1 = datetime.datetime.now()
  1100. processmidi()
  1101. t2 = datetime.datetime.now()
  1102. print(""" processing time: {} / {} = {}; """.format( t1,t2, t2-t1 ))
  1103. frame=prefs.startframe
  1104. getFrame(frame)
  1105. showoutputpath = time.time() + 5
  1106. def main():
  1107. global pyfont
  1108. global mousex, mousey
  1109. global keyp_colormap_colors_pos
  1110. global keyp_colormap_pos
  1111. global success,image
  1112. global endframe
  1113. global basenote
  1114. global glwindows
  1115. global separate_note_id
  1116. global frame
  1117. global width,height
  1118. global screen
  1119. global lastkeygrabid
  1120. global running
  1121. #global old_spark_color, cur_spark_color
  1122. keygrab=0
  1123. keygrabid=-1
  1124. keygrabaddx=0
  1125. lastkeygrabid=-1
  1126. #pyfont = pygame.font.SysFont('Sans', 20)
  1127. #pygame.RESIZABLE
  1128. screen = pygame.display.set_mode( (width,height) , DOUBLEBUF|OPENGL|pygame.RESIZABLE)
  1129. pygame.display.set_caption(filepath)
  1130. doinit()
  1131. clock = pygame.time.Clock()
  1132. # set start frame
  1133. vidcap.set(CAP_PROP_POS_FRAMES, frame)
  1134. while running==1:
  1135. mouseOnWindows = False
  1136. # mousex, mousey = pygame.mouse.get_pos()
  1137. drawframe()
  1138. mods = pygame.key.get_mods()
  1139. for event in pygame.event.get():
  1140. if event.type == pygame.QUIT:
  1141. running = 0
  1142. pygame.quit()
  1143. quit()
  1144. elif event.type == pygame.VIDEORESIZE:
  1145. prefs.resize = 1
  1146. prefs.resize_width = event.w
  1147. prefs.resize_height = event.h
  1148. width = prefs.resize_width
  1149. height = prefs.resize_height
  1150. screen = pygame.display.set_mode( (width,height) , DOUBLEBUF|OPENGL|pygame.RESIZABLE)
  1151. elif event.type == pygame.KEYUP:
  1152. for wnd in glwindows:
  1153. wnd.update_key_up(event.key)
  1154. elif event.type == pygame.KEYDOWN:
  1155. for wnd in glwindows:
  1156. wnd.update_key_down(event.key)
  1157. # print event.key
  1158. if event.key == pygame.K_q:
  1159. if prefs.autoclose == 1:
  1160. running = 0
  1161. else:
  1162. reconstruct()
  1163. if event.key == pygame.K_o:
  1164. #prefs.notes_overlap = not prefs.notes_overlap
  1165. switch_notes_overlap(None)
  1166. if event.key == pygame.K_i:
  1167. #prefs.ignore_minimal_duration = not prefs.ignore_minimal_duration
  1168. switch_ignore_notes_with_minimal_duration(None)
  1169. if event.key == pygame.K_s:
  1170. if mods & pygame.KMOD_SHIFT:
  1171. prefs.startframe = 0
  1172. else:
  1173. prefs.startframe = int(round(vidcap.get(1)))
  1174. print("set start frame = "+ str(prefs.startframe))
  1175. if event.key == pygame.K_e:
  1176. if mods & pygame.KMOD_SHIFT:
  1177. endframe = length
  1178. else:
  1179. endframe = int(round(vidcap.get(1)))
  1180. print("set end frame = "+ str(endframe))
  1181. if event.key == pygame.K_ESCAPE:
  1182. running = 0
  1183. pygame.quit()
  1184. quit()
  1185. if event.key == pygame.K_F2:
  1186. btndown_save_settings(None)
  1187. if event.key == pygame.K_F3:
  1188. btndown_load_settings(None)
  1189. if event.key == pygame.K_F4:
  1190. for i in range(len(glwindows)):
  1191. # if isinstance(glwindows[i],GLButton):
  1192. # continue
  1193. glwindows[i].x = mousex;
  1194. glwindows[i].y = mousey;
  1195. if event.key == pygame.K_r:
  1196. switch_resize_windows(None)
  1197. if event.key == pygame.K_RIGHTBRACKET:
  1198. raise_octave()
  1199. if event.key == pygame.K_LEFTBRACKET:
  1200. lower_octave()
  1201. if event.key == pygame.K_PLUS or event.key == pygame.K_KP_PLUS or event.key == pygame.K_EQUALS:
  1202. prefs.keys_angle -= 5
  1203. updatekeys()
  1204. if event.key == pygame.K_MINUS or event.key == pygame.K_KP_MINUS:
  1205. prefs.keys_angle += 5
  1206. updatekeys()
  1207. if event.key == pygame.K_UP:
  1208. if mods & pygame.KMOD_ALT:
  1209. prefs.keyp_spark_y_pos -= 1
  1210. else:
  1211. if mods & pygame.KMOD_SHIFT:
  1212. prefs.yoffset_blackkeys -= 1
  1213. else:
  1214. prefs.yoffset_blackkeys -= 2
  1215. updatekeys( )
  1216. if event.key == pygame.K_DOWN:
  1217. if mods & pygame.KMOD_ALT:
  1218. prefs.keyp_spark_y_pos += 1
  1219. else:
  1220. if mods & pygame.KMOD_SHIFT:
  1221. prefs.yoffset_blackkeys += 1
  1222. else:
  1223. prefs.yoffset_blackkeys += 2
  1224. updatekeys( )
  1225. if event.key == pygame.K_TAB:
  1226. showOrhideallwindows(None)
  1227. if event.key == pygame.K_LEFT:
  1228. if mods & pygame.KMOD_SHIFT:
  1229. prefs.whitekey_width-=0.1
  1230. else:
  1231. prefs.whitekey_width-=1.0
  1232. updatekeys( )
  1233. if event.key == pygame.K_RIGHT:
  1234. if mods & pygame.KMOD_SHIFT:
  1235. prefs.whitekey_width+=0.1
  1236. else:
  1237. prefs.whitekey_width+=1.0
  1238. updatekeys( )
  1239. if event.key == pygame.K_HOME:
  1240. scroll_to_start(None)
  1241. if event.key == pygame.K_END:
  1242. scroll_to_end(None)
  1243. if event.key == pygame.K_0:
  1244. if mods & pygame.KMOD_CTRL and Gl.keyp_colormap_id != -1:
  1245. prefs.keyp_colors[Gl.keyp_colormap_id][0] = 0
  1246. prefs.keyp_colors[Gl.keyp_colormap_id][1] = 0
  1247. prefs.keyp_colors[Gl.keyp_colormap_id][2] = 0
  1248. if event.key == pygame.K_PAGEUP:
  1249. if mods & pygame.KMOD_SHIFT:
  1250. scroll_forward_by_frame(None)
  1251. else:
  1252. scroll_fast_forward(None)
  1253. if event.key == pygame.K_PAGEDOWN:
  1254. if mods & pygame.KMOD_SHIFT:
  1255. scroll_prev_by_frame(None)
  1256. else:
  1257. scroll_fast_prev(None)
  1258. if event.key == pygame.K_p:
  1259. size=5
  1260. separate_note_id=-1
  1261. for i in range( len( prefs.keys_pos) ):
  1262. if (abs( mousex - (prefs.keys_pos[i][0] + prefs.xoffset_whitekeys) )< size) and (abs( mousey - (prefs.keys_pos[i][1] + prefs.yoffset_whitekeys) )< size):
  1263. separate_note_id=i
  1264. elif event.type == pygame.MOUSEBUTTONUP:
  1265. for i in range( len(glwindows)-1, -1 , -1):
  1266. #print("process mouse up on windiws id: ", i)
  1267. if glwindows[i].update_mouse_up(mousex,mousey,event.button) == 1:
  1268. mouseOnWindows=True
  1269. resort=True
  1270. break
  1271. if ( event.button == 1 ):
  1272. keygrab = 0
  1273. keygrabid = -1
  1274. if ( event.button == 3 ):
  1275. keygrab = 0
  1276. elif event.type == pygame.MOUSEBUTTONDOWN:
  1277. resort=False
  1278. for i in range( len(glwindows)-1, -1 , -1):
  1279. #print("process mouse down on windiws id: ", i)
  1280. if glwindows[i].update_mouse_down(mousex,mousey,event.button) == 1:
  1281. mouseOnWindows=True
  1282. resort=True
  1283. break
  1284. if resort:
  1285. glwindows.sort(key=lambda x: x.active, reverse=False)
  1286. # print event.button
  1287. if ( event.button == 4 ):
  1288. prefs.whitekey_width+=0.05
  1289. # print "whitekey_width="+str(whitekey_width)
  1290. updatekeys( )
  1291. # scale+=0.1
  1292. if ( event.button == 5 ):
  1293. prefs.whitekey_width-=0.05
  1294. # print "whitekey_width="+str(whitekey_width)
  1295. updatekeys( )
  1296. if ( event.button == 1 ):
  1297. if mods & pygame.KMOD_CTRL and Gl.keyp_colormap_id != -1:
  1298. pixx = int(mousex)
  1299. pixy = int(mousey)
  1300. if not (( pixx >= width ) or ( pixy >= height ) or ( pixx < 0 ) or ( pixy < 0 )):
  1301. if ( prefs.resize == 1 ):
  1302. pixx= int(round( pixx * ( video_width / float(prefs.resize_width) )))
  1303. pixy= int(round( pixy * ( video_height / float(prefs.resize_height) )))
  1304. if ( pixx > video_width -1 ): pixx = video_width-1
  1305. if ( pixy > video_height-1 ): pixy = video_height-1
  1306. print("original mouse x:"+str(mousex) + "x" +str(mousey) + " mapped :" +str(pixx) +"x"+str(pixy))
  1307. keybgr=image[pixy,pixx]
  1308. prefs.keyp_colors[Gl.keyp_colormap_id][0] = keybgr[2]
  1309. prefs.keyp_colors[Gl.keyp_colormap_id][1] = keybgr[1]
  1310. prefs.keyp_colors[Gl.keyp_colormap_id][2] = keybgr[0]
  1311. else:
  1312. # if not (mods & pygame.KMOD_CTRL):
  1313. if not colorWindow.active and not mouseOnWindows:
  1314. Gl.keyp_colormap_id = -1
  1315. #keyp_colormap_id = -1
  1316. size=5
  1317. if (mods & pygame.KMOD_CTRL):
  1318. lastkeygrabid=-1
  1319. for i in range( len( prefs.keys_pos) ):
  1320. if (abs( mousex - (prefs.keys_pos[i][0] + prefs.xoffset_whitekeys) )< size) and (abs( mousey - (prefs.keys_pos[i][1] + prefs.yoffset_whitekeys) )< size):
  1321. keygrab=1
  1322. if not ( mods & pygame.KMOD_CTRL ):
  1323. keygrabid=i
  1324. lastkeygrabid=i
  1325. extra_slider1.setvalue( prefs.keyp_colors_alternate_sensitivity[i] )
  1326. print("ok click found on : "+str(keygrabid))
  1327. break
  1328. # if ( event.button == 2 ):
  1329. # lastkeygrabid=-1
  1330. if ( event.button == 3 ):
  1331. keygrab = 2
  1332. size=5
  1333. print("x offset " + str(prefs.xoffset_whitekeys) + " y offset: " +str(prefs.yoffset_whitekeys))
  1334. keygrabaddx=0
  1335. for i in range( len( prefs.keys_pos) ):
  1336. if (abs( mousex - (prefs.keys_pos[i][0] + prefs.xoffset_whitekeys) )< size) and (abs( mousey - (prefs.keys_pos[i][1] + prefs.yoffset_whitekeys) )< size):
  1337. keygrab=2
  1338. keygrabaddx=prefs.keys_pos[i][0]
  1339. print("ok click found on : "+str(keygrabid))
  1340. break
  1341. if ( keygrab == 1) and ( keygrabid >-1 ):
  1342. # print "moving keyid = " + str(keygrabid)
  1343. prefs.keys_pos[ keygrabid ][0] = mousex - prefs.xoffset_whitekeys
  1344. prefs.keys_pos[ keygrabid ][1] = mousey - prefs.yoffset_whitekeys
  1345. if ( keygrab == 2):
  1346. # print "moving offsets : "+ str(mousex) + " x " + str(mousey)
  1347. prefs.xoffset_whitekeys = mousex - keygrabaddx
  1348. prefs.yoffset_whitekeys = mousey
  1349. for wnd in glwindows:
  1350. wnd.update_mouse_move(mousex,mousey)
  1351. pygame.display.flip()
  1352. #framerate()
  1353. #limit fps to 60 and get the frame time in milliseconds
  1354. ms = clock.tick(60)
  1355. main()
  1356. if prefs.autoclose == 1:
  1357. reconstruct()
  1358. print ('done...')