plugged a large memory leak, there still seems to be a small one - added a program reset as workaround for now

This commit is contained in:
langolierz
2018-05-11 00:18:10 +00:00
parent bd1bf41db1
commit c001cb10f6
6 changed files with 23 additions and 269 deletions

View File

@@ -1,5 +1,8 @@
import subprocess import subprocess
import tracemalloc
import data_centre.length_setter as length_setter import data_centre.length_setter as length_setter
import sys
import os
class Actions(object): class Actions(object):
def __init__(self, tk, message_handler, data, video_driver, capture, display): def __init__(self, tk, message_handler, data, video_driver, capture, display):
@@ -232,7 +235,7 @@ class Actions(object):
def check_and_set_output_mode_on_boot(self): def check_and_set_output_mode_on_boot(self):
#### checking if pi display mode is composite #### checking if pi display mode is composite
response = str(subprocess.check_output(['tvservice', '-s'])) response = str(subprocess.check_output(['tvservice', '-s']))
if '0x80002' in response or '0x40002' in response: if 'PAL' in response or 'NTSC' in response:
self.data.update_setting_value('video', 'OUTPUT', 'composite') self.data.update_setting_value('video', 'OUTPUT', 'composite')
else: else:
self.data.update_setting_value('video', 'OUTPUT', 'hdmi') self.data.update_setting_value('video', 'OUTPUT', 'hdmi')
@@ -333,6 +336,11 @@ class Actions(object):
self.toggle_x_autorepeat() self.toggle_x_autorepeat()
self.tk.destroy() self.tk.destroy()
def restart_the_program(self):
self.quit_the_program()
os.execv('/usr/bin/python3', [sys.argv[0],'/home/pi/r_e_c_u_r/r_e_c_u_r.py'])
def set_fixed_length(self, value): def set_fixed_length(self, value):
self.data.control_mode = 'LENGTH_SET' self.data.control_mode = 'LENGTH_SET'
self.message_handler.set_message('INFO', 'tap: ■ ; < > : back') self.message_handler.set_message('INFO', 'tap: ■ ; < > : back')

View File

@@ -7,6 +7,7 @@ class Display(object):
MENU_HEIGHT = 10 MENU_HEIGHT = 10
SELECTOR_WIDTH = 0.47 SELECTOR_WIDTH = 0.47
ROW_OFFSET = 6.0 ROW_OFFSET = 6.0
TITLE = '================== r_e_c_u_r =================='
def __init__(self, tk, video_driver, capture, message_handler, data): def __init__(self, tk, video_driver, capture, message_handler, data):
self.tk = tk self.tk = tk
@@ -26,7 +27,7 @@ class Display(object):
@staticmethod @staticmethod
def _create_display_text(tk): def _create_display_text(tk):
return Text(tk, bg="black", fg="white", font=('Liberation Mono', 13)) return Text(tk, bg="black", fg="white", font=('Liberation Mono', 13), undo=False)
def _add_tags(self): def _add_tags(self):
self.display_text.tag_configure("SELECT", background="white", foreground="black") self.display_text.tag_configure("SELECT", background="white", foreground="black")
@@ -45,10 +46,11 @@ class Display(object):
self._load_player() self._load_player()
self._load_display_body() self._load_display_body()
self._load_message() self._load_message()
#print('the number of tags are {}'.format(len(self.display_text.tag_names())))
self.display_text.pack() self.display_text.pack()
def _load_title(self): def _load_title(self):
self.display_text.insert(END, '================== r_e_c_u_r ================== \n') self.display_text.insert(END, self.TITLE + ' \n')
self.display_text.tag_add("TITLE", 1.19, 1.28) self.display_text.tag_add("TITLE", 1.19, 1.28)
def _load_player(self): def _load_player(self):

View File

@@ -1,264 +0,0 @@
from tkinter import Text, END
import math
import time
import display_centre.menu as menu
class Display(object):
MENU_HEIGHT = 10
SELECTOR_WIDTH = 0.47
ROW_OFFSET = 6.0
VIDEO_DISPLAY_BANNER_TEXT = ' {} {} {}'
def __init__(self, tk, video_driver, capture, message_handler, data):
self.tk = tk
self.video_driver = video_driver
self.capture = capture
self.message_handler = message_handler
self.data = data
self.browser_menu = menu.BrowserMenu(self.data, self.MENU_HEIGHT)
self.settings_menu = menu.SettingsMenu(self.data, self.MENU_HEIGHT)
#self.top_menu_index = 0
#self.selected_list_index = self.top_menu_index
self.display_text = self._create_display_text(self.tk)
self._add_tags()
self._update_screen_every_second()
@staticmethod
def _create_display_text(tk):
return Text(tk, bg="black", fg="white", font=('Liberation Mono', 13))
def _add_tags(self):
self.display_text.tag_configure("SELECT", background="white", foreground="black")
self.display_text.tag_configure("TITLE", background="black", foreground="red")
self.display_text.tag_configure("DISPLAY_MODE", background="black", foreground="magenta")
self.display_text.tag_configure("ERROR_MESSAGE", background="red", foreground="white")
self.display_text.tag_configure("INFO_MESSAGE", background="blue", foreground="white")
self.display_text.tag_configure("PLAYER_INFO", background="black", foreground="yellow")
self.display_text.tag_configure("COLUMN_NAME", background="black", foreground="cyan")
self.display_text.tag_configure("FUNCTION", background="cyan", foreground="black")
self.display_text.tag_configure("BROKEN_PATH", background="black", foreground="gray")
def _load_display(self):
self._load_title()
self._load_player()
self._load_display_body()
self._load_message()
self.display_text.pack()
def _load_title(self):
self.display_text.insert(END, '================== r_e_c_u_r ================== \n')
self.display_text.tag_add("TITLE", 1.19, 1.28)
def _load_player(self):
text, banner = self._get_info_for_player()
end_of_text = float("3." + str(len(text)))
end_of_banner = float("3." + str(len(banner)))
self.display_text.insert(END, text + '\n')
self.display_text.tag_add("PLAYER_INFO", 2.0, end_of_text)
self.display_text.insert(END, banner + '\n')
self.display_text.tag_add("PLAYER_INFO", 3.0, end_of_banner)
def _load_display_body(self):
if self.data.display_mode == 'BROWSER':
self._load_browser()
elif self.data.display_mode == 'SETTINGS':
self._load_settings()
else:
self._load_sampler()
self.display_text.tag_add("COLUMN_NAME", 5.0, 6.0)
def _load_sampler(self):
bank_data = self.data.bank_data[self.data.bank_number]
self.display_text.insert(END, '------------------ <SAMPLER> ------------------ \n')
self.display_text.tag_add("DISPLAY_MODE", 4.19, 4.29)
self.display_text.insert(END, '{:^6} {:<16} {:<4} {:<4} {:<4} \n'.format(
'{}-slot'.format(self.data.bank_number), 'name', 'length', 'start', 'end'))
for index, slot in enumerate(bank_data):
name_without_extension = slot['name'].rsplit('.',1)[0]
self.display_text.insert(END, '{:^4} {:<18} {:<4} {:<4} {:<4} \n'.format(
index, name_without_extension[0:22], self.format_time_value(slot['length']),
self.format_time_value(slot['start']), self.format_time_value(slot['end'])))
if self.data.is_this_path_broken(slot['location']):
self.display_text.tag_add("BROKEN_PATH", self.ROW_OFFSET + index,
self.ROW_OFFSET + self.SELECTOR_WIDTH + index)
current_bank , current_slot = self.data.split_bankslot_number(self.video_driver.current_player.bankslot_number)
if current_bank is self.data.bank_number:
self.selected_list_index = current_slot
else:
self.selected_list_index = 0
def _load_browser(self):
browser_list = self.browser_menu.menu_list
number_of_lines_displayed = 0
self.display_text.insert(END, '------------------ <BROWSER> ------------------ \n')
self.display_text.tag_add("DISPLAY_MODE", 4.19, 4.29)
self.display_text.insert(END, '{:40} {:5} \n'.format('path', 'slot'))
number_of_browser_items = len(browser_list)
for index in range(number_of_browser_items):
if number_of_lines_displayed >= self.MENU_HEIGHT:
break
if index >= self.browser_menu.top_menu_index:
path = browser_list[index]
self.display_text.insert(END, '{:40} {:5} \n'.format(path['name'][0:35], path['slot']))
number_of_lines_displayed = number_of_lines_displayed + 1
for index in range(self.MENU_HEIGHT - number_of_browser_items):
self.display_text.insert(END, '\n')
self._highlight_this_row(self.browser_menu.selected_list_index - self.browser_menu.top_menu_index)
def _load_settings(self):
line_count = 0
settings_list = self.settings_menu.menu_list
self.display_text.insert(END, '------------------ <SETTINGS> ----------------- \n')
self.display_text.tag_add("DISPLAY_MODE", 4.19, 4.29)
self.display_text.insert(END, '{:^23} {:^22} \n'.format('SETTING', 'VALUE'))
number_of_settings_items = len(settings_list)
for index in range(number_of_settings_items):
if line_count >= self.MENU_HEIGHT:
break
if index >= self.settings_menu.top_menu_index:
setting = settings_list[index]
self.display_text.insert(END, '{:<23} {:<22} \n'.format(setting['name'], setting['value']))
line_count = line_count + 1
for index in range(self.MENU_HEIGHT - number_of_settings_items):
self.display_text.insert(END, '\n')
self._highlight_this_row(self.settings_menu.selected_list_index - self.settings_menu.top_menu_index)
def _load_message(self):
if self.message_handler.current_message[1]:
self.display_text.insert(END, '{:5} {:38}'.format(
self.message_handler.current_message[0], self.message_handler.current_message[1][0:38]))
self.display_text.tag_add('{}_MESSAGE'.format(
self.message_handler.current_message[0]), 16.0,16.0 + self.SELECTOR_WIDTH)
if self.message_handler.current_message[2]:
self.message_handler.current_message[2] = False
message_length = 4000
self.tk.after(message_length, self.message_handler.clear_message)
elif self.data.function_on:
self.display_text.insert(END, '{:^45}'.format('< FUNCTION KEY ON >'))
self.display_text.tag_add('FUNCTION', 16.0,16.0 + self.SELECTOR_WIDTH)
else:
self.display_text.insert(END, '{:8} {:<10}'.format('CONTROL:', self.data.control_mode))
self.display_text.tag_add('TITLE', 16.0,16.0 + self.SELECTOR_WIDTH)
def _highlight_this_row(self, row):
self.display_text.tag_add("SELECT", self.ROW_OFFSET + row,
self.ROW_OFFSET + self.SELECTOR_WIDTH + row)
def _unhighlight_this_row(self, row):
self.display_text.tag_remove("SELECT", self.ROW_OFFSET + row,
self.ROW_OFFSET + self.SELECTOR_WIDTH + row)
def _get_info_for_player(self):
now_slot, now_status, next_slot, next_status, position, crop_length, start, end = self.video_driver.get_info_for_player_display()
banner = self.create_video_display_banner(start, end, crop_length, position)
time_been = self.format_time_value(position - start)
time_left = self.format_time_value(end - position)
capture_status = self._generate_capture_status()
now_info = 'NOW [{}] {}'.format(now_slot, now_status)
next_info = 'NEXT [{}] {}'.format(next_slot, next_status)
capture_info = '{}'.format(capture_status)
return self.VIDEO_DISPLAY_BANNER_TEXT.format(time_been, banner, time_left), \
'{:17} {:10} {:17}'.format(now_info[:17], capture_info[:10], next_info[:18])
def _generate_capture_status(self):
is_previewing = self.capture.is_previewing
is_recording = self.capture.is_recording
rec_time = -1
if is_recording == True:
rec_time = self.capture.get_recording_time()
capture_status = ''
if is_previewing and is_recording == True:
capture_status = '<{}>'.format('REC'+ self.format_time_value(rec_time))
elif is_previewing and is_recording == 'saving':
capture_status = '<{}>'.format('_saving_')
elif is_previewing:
capture_status = '<{}>'.format('_preview')
elif is_recording == True:
capture_status = '[{}]'.format('REC'+ self.format_time_value(rec_time))
elif is_recording == 'saving':
capture_status = '[{}]'.format('_saving_')
else:
capture_status = ''
return capture_status
@staticmethod
def create_video_display_banner(start, end, crop_length, position):
banner_list = ['[', '-', '-', '-', '-', '-', '-', '-', '-',
'-', '-', '-', '-', '-', '-', '-', '-', '-',
'-', '-', '-', '-', '-', '-', '-', '-', '-',
'-', '-', '-', '-', '-',
']']
max = len(banner_list) - 1
if position < start:
banner_list[0] = '<'
elif position > end:
banner_list[max] = '>'
elif crop_length != 0:
marker = int(math.floor(float(position - start) /
float(crop_length) * (max - 1)) + 1)
banner_list[marker] = '*'
return ''.join(banner_list)
def _update_screen_every_second(self):
self.refresh_display()
self.tk.after(500, self._update_screen_every_second)
def refresh_display(self):
self.display_text.configure(state='normal')
self.display_text.delete(1.0, END)
self._load_display()
self.display_text.configure(state='disable')
self.display_text.focus_set()
def navigate_menu(self, move_direction, number_items_in_list):
last_list_index = number_items_in_list - 1
bottom_menu_index = self.top_menu_index + self.MENU_HEIGHT - 1
##self._unhighlight_this_row(self.selected_list_index - self.top_menu_index)
if move_direction == 'down':
if self.selected_list_index != last_list_index:
if self.selected_list_index == bottom_menu_index:
self.top_menu_index += 1
self.selected_list_index += 1
else:
self.top_menu_index = 0
self.selected_list_index = self.top_menu_index
elif move_direction == 'up':
if self.selected_list_index != 0:
if self.selected_list_index == self.top_menu_index:
self.top_menu_index -= 1
self.selected_list_index -= 1
else:
self.selected_list_index = last_list_index
self.top_menu_index = last_list_index - (self.MENU_HEIGHT - 1)
if self.top_menu_index < 0:
self.top_menu_index = 0
##self._highlight_this_row(self.selected_list_index - self.top_menu_index)
return
@staticmethod
def format_time_value(time_in_seconds):
if time_in_seconds < 0:
return ''
elif time_in_seconds >= 6000:
return '99:99'
else:
return time.strftime("%M:%S", time.gmtime(time_in_seconds))

View File

@@ -95,6 +95,11 @@
], ],
"value": "off" "value": "off"
}, },
"RESTART_PROGRAM": {
"action": "restart_the_program",
"options": [],
"value": null
},
"QUIT": { "QUIT": {
"action": "quit_the_program", "action": "quit_the_program",
"options": [], "options": [],

3
r_e_c_u_r.py Normal file → Executable file
View File

@@ -1,6 +1,9 @@
#!/usr/bin/python
import traceback import traceback
from tkinter import Tk, Frame from tkinter import Tk, Frame
import sys import sys
import tracemalloc
from actions import Actions from actions import Actions
from data_centre.data import Data from data_centre.data import Data

View File

@@ -16,7 +16,7 @@ class MidiInput(object):
def try_open_port(self): def try_open_port(self):
midi_setting = self.data.settings['midi']['INPUT']['value'] midi_setting = self.data.settings['midi']['INPUT']['value']
print('try open port : midi setting is {}'.format(midi_setting)) #print('try open port : midi setting is {}'.format(midi_setting))
if midi_setting == 'enabled': if midi_setting == 'enabled':
midi_ports = mido.get_input_names() midi_ports = mido.get_input_names()
midi_device_on_port_20 = [s for s in midi_ports if '20:0' in s] midi_device_on_port_20 = [s for s in midi_ports if '20:0' in s]