v2m.py 60 KB

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