jwdj / EasyABC

EasyABC
GNU General Public License v2.0
90 stars 37 forks source link

Fails to run on Python 3.11 #78

Open topchyan opened 12 months ago

topchyan commented 12 months ago

On this new machine running MX-Linux 23 (based on Debian GNU/Linux 12 (bookworm)) trying to install EasyABC and run it, but getting this error:

 python3 easy_abc.py 
Traceback (most recent call last):
  File "/home/avetik/EasyABC/easy_abc.py", line 118, in <module>
    from abc_search import abc_matches_iter
  File "/home/avetik/EasyABC/abc_search.py", line 8, in <module>
    remove_non_notes = re.compile(r'(?xm)' + '|'.join([
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/re/__init__.py", line 227, in compile
    return _compile(pattern, flags)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/re/__init__.py", line 294, in _compile
    p = _compiler.compile(pattern, flags)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/re/_compiler.py", line 743, in compile
    p = _parser.parse(p, flags)
        ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/re/_parser.py", line 980, in parse
    p = _parse_sub(source, state, flags & SRE_FLAG_VERBOSE, 0)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/re/_parser.py", line 455, in _parse_sub
    itemsappend(_parse(source, state, verbose, nested + 1,
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/re/_parser.py", line 841, in _parse
    raise source.error('global flags not at the start '
re.error: global flags not at the start of the expression at position 78

This doesn't happen on my other machine which runs 3.9.2

topchyan commented 12 months ago

https://github.com/scipy/scipy/issues/16988

revad commented 12 months ago

There's one change to re in Py11 which looks like it might relate to the long regex starting on line 8 of abc_search.py and seems to match the error: https://docs.python.org/3.11/library/re.html https://github.com/jwdj/EasyABC/blob/master/abc_search.py

I wonder if it's those ?(m) entries in two of the lines?

topchyan commented 12 months ago

Definitely a bug in Python 3.11

https://github.com/python/cpython/issues/98740

Wonder if this code could be simplified and/or re-written in a way to avoid this bug going forward.

revad commented 11 months ago

I don't have Python 3.11 but I have Python 3.10:

Python 3.10.13 (main, Sep 05 2023, 11:46:10) [GCC] on linux Type "help", "copyright", "credits" or "license" for more information.

import re remove_non_notes = re.compile(r'(?xm)' + '|'.join([ ... r'\%\%beginps(.|\s)+?\%\%endps', # remove embedded postscript ... r'\%\%begintext(.|\s)+?\%\%endtext', # remove text ... r'[\w:.?]', # remove embedded fields ... r'(?m)^\w:.?$', # remove normal fields ... r'(?m)%.$', # remove comments ... r'[\w:.?]', # remove embedded fields ... r'\"', # remove escaped " characters ... r'".?"', # remove strings ... r'\"', # remove escaped quote characters ... r'{.?}', # remove grace notes ... r'!.+?!', # remove ornaments like eg. !pralltriller! ... r'+.+?+', # remove ornaments like eg. +pralltriller+ ... r'{.*?}', # remove grace notes ... ]))

:1: DeprecationWarning: Flags not at the start of the expression '(?xm)\\%\\%beginps(.|\\' (truncated) but at position 78 :1: DeprecationWarning: Flags not at the start of the expression '(?xm)\\%\\%beginps(.|\\' (truncated) but at position 91

Try removing those two ?(m) in the middle. Would the initial ?(m) not apply to the entire expression, in which case they're redundant?

bomm commented 11 months ago

Assuming that the initial (?xm) will apply to all sub-expressions, removing the later (?m) would not change the behavior. Open questions: Was the behavior always the same or was it possible to set flags for sub-expressions in older Python versions? Or would the intention of the expression require different flags for sub-expressions?

topchyan commented 11 months ago

Try removing those two ?(m) in the middle. Would the initial ?(m) not apply to the entire expression, in which case they're redundant?

I tried just that and ended up with a lot more errors on other places (easy_abc.py line 8772 OnInit event is now at fault. Anyway, probably something maintainer should take a look at.

revad commented 11 months ago

This was seen on Windows: https://sourceforge.net/p/easyabc/tickets/54 See Lars' error log

mmehl commented 9 months ago

I made two changes to adapt the code for python 3.11.6 on ubuntu:

  1. Removed (?m) in middle of regex:

    diff --git a/abc_search.py b/abc_search.py
    index 70c3756..4c6487c 100644
    --- a/abc_search.py
    +++ b/abc_search.py
    @@ -9,8 +9,8 @@ remove_non_notes = re.compile(r'(?xm)' + '|'.join([
                r'\%\%beginps(.|\s)+?\%\%endps',  # remove embedded postscript
                r'\%\%begintext(.|\s)+?\%\%endtext',   # remove text
                r'\[\w:.*?\]',    # remove embedded fields
    -               r'(?m)^\w:.*?$',  # remove normal fields
    -               r'(?m)%.*$',      # remove comments
    +               r'^\w:.*?$',  # remove normal fields
    +               r'%.*$',      # remove comments
                r'\[\w:.*?\]',    # remove embedded fields
                r'\\"',           # remove escaped " characters
                r'".*?"',         # remove strings
  2. removed "U" in io.open:

    diff --git a/tune_elements.py b/tune_elements.py
    index c8aef80..1221833 100644
    --- a/tune_elements.py
    +++ b/tune_elements.py
    @@ -1081,7 +1081,7 @@ class AbcStructure(object):
     @staticmethod
     def get_sections(cwd):
         # [1.3.6.2 [JWDJ] bugfix This fixes 'str>ng' in Fields and Command Reference
    -        reference_content = io.open(os.path.join(cwd, 'reference.txt'), 'rU', encoding='latin-1').read()
    +        reference_content = io.open(os.path.join(cwd, 'reference.txt'), 'r', encoding='latin-1').read()
         if AbcStructure.replace_regexes is None:
             AbcStructure.replace_regexes = [
                 (re.compile(r'\bh((?:bass/chord|length|logical|string|int|fl-?\n?oat\s?|command|str|text|vol|h|n|char|clef|bass|chord)\d*\s?(?: (?:string|int|float)\d*?)*)i\b'), r'<\1>'),  # enclose types with < and >
topchyan commented 9 months ago

I tried it on MX Linux (Debian) using your suggestions and though the program opened, the ABC settings tab looked really weird: only 2 tabs were visible okay, others had all controls mashed together (I couldn't take a picture, tried it on a live USB just to see how it would work). I launched it form the terminal and saw a lot of errors pointing to rcsizer.py

mmehl commented 9 months ago

About rcsizer.py there is a hint to migrate to wx.GridBagSizer: https://discuss.wxpython.org/t/facing-an-error-in-wx-library-file-rcsizer-py/36685

revad commented 9 months ago

I get the mis-sized settings window in python 3.10 on SuSE. I haven't bothered to diagnose it - I just make them bigger to use them, and they work OK. I have more important problems to solve!

@mmehl - is it using fluidsynth? (#79)? What version of wxPython?

mmehl commented 9 months ago

here is the change to replace rcsizer with GridBagSizer:

diff --git a/easy_abc.py b/easy_abc.py
index d0fe505..cc662e8 100644
--- a/easy_abc.py
+++ b/easy_abc.py
@@ -92,7 +92,6 @@ from wx.lib.scrolledpanel import ScrolledPanel
 import wx.html
 import wx.stc as stc
 import wx.lib.agw.aui as aui
-import wx.lib.rcsizer as rcs
 # import wx.lib.filebrowsebutton as filebrowse # 1.3.6.3 [JWdJ] 2015-04-22
 import wx.lib.platebtn as platebtn
 import wx.lib.mixins.listctrl as listmix
@@ -1924,7 +1923,7 @@ class IncipitsFrame(wx.Dialog):
         wx.Dialog.__init__(self, parent, wx.ID_ANY, _('Generate incipits file...'), wx.DefaultPosition, wx.Size(530, 260))
         self.SetBackgroundColour(dialog_background_colour)
         border = control_margin
-        sizer = box1 = rcs.RowColSizer()
+        sizer = box1 = wx.GridBagSizer()
         lb1 = wx.StaticText(self, wx.ID_ANY, _('Number of bars to extract:'))
         lb2 = wx.StaticText(self, wx.ID_ANY, _('Maximum number of repeats to extract:'))
         lb3 = wx.StaticText(self, wx.ID_ANY, _('Maximum number of titles/subtitles to extract:'))
@@ -1940,17 +1939,17 @@ class IncipitsFrame(wx.Dialog):
         for c in [self.edNumBars, self.edNumRepeats, self.edNumTitles, self.edNumRows, self.edSortFields]:
             c.SetValue(c.GetValue()) # this seems to be needed on OSX

-        sizer.Add(lb1,                  row=0, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        sizer.Add(self.edNumBars,       row=0, col=1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        sizer.Add(lb2,                  row=1, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        sizer.Add(self.edNumRepeats,    row=1, col=1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        sizer.Add(lb3,                  row=2, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        sizer.Add(self.edNumTitles,     row=2, col=1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        sizer.Add(lb4,                  row=3, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        sizer.Add(self.edSortFields,    row=3, col=1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        sizer.Add(self.chkTwoColumns,   row=4, col=1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        sizer.Add(lb5,                  row=5, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        sizer.Add(self.edNumRows,       row=5, col=1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        sizer.Add(lb1,                  pos=(0,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        sizer.Add(self.edNumBars,       pos=(0,1), flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        sizer.Add(lb2,                  pos=(1,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        sizer.Add(self.edNumRepeats,    pos=(1,1), flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        sizer.Add(lb3,                  pos=(2,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        sizer.Add(self.edNumTitles,     pos=(2,1), flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        sizer.Add(lb4,                  pos=(3,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        sizer.Add(self.edSortFields,    pos=(3,1), flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        sizer.Add(self.chkTwoColumns,   pos=(4,1), flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        sizer.Add(lb5,                  pos=(5,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        sizer.Add(self.edNumRows,       pos=(5,1), flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)

         # ok, cancel buttons
         self.ok = wx.Button(self, wx.ID_ANY, _('&Ok'))
@@ -2076,9 +2075,9 @@ class AbcFileSettingsFrame(wx.Panel):
         else:
             self.exe_file_mask = '*'

-        sizer = rcs.RowColSizer()
+        sizer = wx.GridBagSizer()
         if wx.Platform == "__WXMAC__":
-            sizer.Add(wx.StaticText(self, wx.ID_ANY, _('File paths to required executables') + ':'), row=0, col=0, colspan=2, flag=wx.ALL, border=border)
+            sizer.Add(wx.StaticText(self, wx.ID_ANY, _('File paths to required executables') + ':'), pos=(0,0), span=(0,2), flag=wx.ALL, border=border)
             r = 1
         else:
             r = 0
@@ -2110,9 +2109,9 @@ class AbcFileSettingsFrame(wx.Panel):
             browse_button = wx.Button(self, wx.ID_ANY, _('Browse...'))
             self.browsebutton_to_control[browse_button] = control
             self.browsebutton_to_wildcard[browse_button] = entry.wildcard
-            sizer.Add(wx.StaticText(self, wx.ID_ANY, entry.display_name), row=r, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-            sizer.Add(control, row=r, col=1, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-            sizer.Add(browse_button, row=r, col=2, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+            sizer.Add(wx.StaticText(self, wx.ID_ANY, entry.display_name), pos=(r,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+            sizer.Add(control, pos=(r,1), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+            sizer.Add(browse_button, pos=(r,2), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)

             browse_button.Bind(wx.EVT_BUTTON, self.OnBrowse, browse_button)

@@ -2132,10 +2131,10 @@ class AbcFileSettingsFrame(wx.Panel):
         extraplayerparam = wx.StaticText(self, wx.ID_ANY, _("Extra MIDI player parameters"))
         self.extras = wx.TextCtrl(self, wx.ID_ANY, size=(200, 22))

-        midiplayer_params_sizer = rcs.RowColSizer()
-        midiplayer_params_sizer.Add(self.chkIncludeHeader, row=0, col=0, colspan=2, flag=wx.ALL, border=border)
-        midiplayer_params_sizer.Add(extraplayerparam, row=1, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midiplayer_params_sizer.Add(self.extras, row=1, col=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midiplayer_params_sizer = wx.GridBagSizer()
+        midiplayer_params_sizer.Add(self.chkIncludeHeader, pos=(0,0), span=(0,2), flag=wx.ALL, border=border)
+        midiplayer_params_sizer.Add(extraplayerparam, pos=(1,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midiplayer_params_sizer.Add(self.extras, pos=(1,1), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)

         self.restore_settings = wx.Button(self, wx.ID_ANY, _('Restore settings')) # 1.3.6.3 [JWDJ] 2015-04-25 renamed
         check_toolTip = _('Restore default file paths to abcm2ps, abc2midi, abc2abc, ghostscript when blank')
@@ -2272,7 +2271,7 @@ class MyChordPlayPage (wx.Panel):
         self.SetBackgroundColour(dialog_background_colour) # 1.3.6.3 [JWDJ] 2014-04-28 same background for all tabs
         gridsizer = wx.FlexGridSizer(20, 4, 2, 2)
         # midi_box to set default instrument for playback
-        midi_box = rcs.RowColSizer()
+        midi_box = wx.GridBagSizer()
         border = control_margin
         self.settings = settings

@@ -2319,38 +2318,38 @@ class MyChordPlayPage (wx.Panel):
         gchordchoices = ['default', 'f', 'fzfz', 'gi', 'gihi', 'f4c2', 'ghihgh', 'g2hg2h']
         self.SetGchordChoices(gchordchoices)

-        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _('Instrument for playback') + ': '), row=0, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.sliderVol, row=0, col=2, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.Voltxt, row=0, col=3, flag=wx.ALL| wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.cmbMidiProgram, row=0, col=1, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _("Instrument for chord's playback") + ': '), row=1, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.cmbMidiChordProgram, row=1, col=1, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.sliderChordVol, row=1, col=2, flag=wx.ALL| wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.ChordVoltxt, row=1, col=3, flag=wx.ALL| wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _("Instrument for bass chord's playback") + ': '), row=2, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.cmbMidiBassProgram, row=2, col=1, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.sliderBassVol, row=2, col=2, flag=wx.ALL| wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.BassVoltxt, row=2, col=3, flag=wx.ALL| wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _('Instrument for playback') + ': '), pos=(0,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.sliderVol, pos=(0,2), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.Voltxt, pos=(0,3), flag=wx.ALL| wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.cmbMidiProgram, pos=(0,1), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _("Instrument for chord's playback") + ': '), pos=(1,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.cmbMidiChordProgram, pos=(1,1), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.sliderChordVol, pos=(1,2), flag=wx.ALL| wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.ChordVoltxt, pos=(1,3), flag=wx.ALL| wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _("Instrument for bass chord's playback") + ': '), pos=(2,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.cmbMidiBassProgram, pos=(2,1), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.sliderBassVol, pos=(2,2), flag=wx.ALL| wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.BassVoltxt, pos=(2,3), flag=wx.ALL| wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)

         # 1.3.6.4 [SS] 2015-06-10
-        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _("Default Tempo") + ': '), row=3, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.sliderbeatsperminute, row=3, col=1, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.beatsperminutetxt, row=3, col=2, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _("Transposition") + ': '), row=4, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.slidertranspose, row=4, col=1, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.transposetxt, row=4, col=2, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _("Tuning") + ': '), row=5, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.slidertuning, row=5, col=1, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.tuningtxt, row=5, col=2, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-
-        midi_box.Add(self.chkPlayChords, row=6, col=0, flag=wx.ALL | wx.EXPAND, border=border)
-        midi_box.Add(self.nodynamics, row=6, col=1, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.nofermatas, row=7, col=0, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.nograce, row=7, col=1, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.barfly, row=8, col=0, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.midi_intro, row=8, col=1, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(gchordtxt, row=9, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(self.gchordcombo, row=9, col=1, flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _("Default Tempo") + ': '), pos=(3,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.sliderbeatsperminute, pos=(3,1), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.beatsperminutetxt, pos=(3,2), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _("Transposition") + ': '), pos=(4,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.slidertranspose, pos=(4,1), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.transposetxt, pos=(4,2), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _("Tuning") + ': '), pos=(5,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.slidertuning, pos=(5,1), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.tuningtxt, pos=(5,2), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+
+        midi_box.Add(self.chkPlayChords, pos=(6,0), flag=wx.ALL | wx.EXPAND, border=border)
+        midi_box.Add(self.nodynamics, pos=(6,1), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.nofermatas, pos=(7,0), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.nograce, pos=(7,1), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.barfly, pos=(8,0), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.midi_intro, pos=(8,1), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(gchordtxt, pos=(9,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(self.gchordcombo, pos=(9,1), flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, border=border)

         self.chkPlayChords.SetValue(self.settings.get('play_chords', False))
         self.slidertranspose.SetValue(self.settings.get('transposition', 0))
@@ -2542,10 +2541,10 @@ class MyVoicePage(wx.Panel):
         separate_defaults_per_voice = settings.get('separate_defaults_per_voice', False)
         self.chkPerVoice.Value = separate_defaults_per_voice
         self.chkPerVoice.Bind(wx.EVT_CHECKBOX, self.OnToggleDefaultsPerVoice)
-        midi_box = rcs.RowColSizer()
-        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _('Default instrument:')), row=0, col=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _('Main Volume:')), row=0, col=3, colspan=2, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _('L/R Balance:')), row=0, col=6, colspan=2, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box = wx.GridBagSizer()
+        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _('Default instrument:')), pos=(0,1), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _('Main Volume:')), pos=(0,3), span=(0,2), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        midi_box.Add(wx.StaticText(self, wx.ID_ANY, _('L/R Balance:')), pos=(0,6), span=(0,2), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)

         # For each of the 16th voice, instrument, volume and balance can be set separately
         if PY3:
@@ -2578,18 +2577,18 @@ class MyVoicePage(wx.Panel):
                                                                 wx.ST_NO_AUTORESIZE, size=(30, 20))
             self.textValueMidiControlPanCh_list[channel] = panText

-            midi_box.Add(wx.StaticText(self, wx.ID_ANY, _('Voice n.%d: ') % channel), row=channel, col=0,
+            midi_box.Add(wx.StaticText(self, wx.ID_ANY, _('Voice n.%d: ') % channel), pos=(channel,0),
                          flag=wx.ALIGN_CENTER_VERTICAL, border=border)
-            midi_box.Add(cmbMidiProgram, row=channel, col=1, flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND)
+            midi_box.Add(cmbMidiProgram, pos=(channel,1), flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND)
             #3rd column (col=2) is unused on purpose to leave some space (maybe replaced with some other spacer option later on)
-            midi_box.Add(volumeSlider, row=channel, col=3,
+            midi_box.Add(volumeSlider, pos=(channel,3),
                          flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL)
-            midi_box.Add(volumeText, row=channel, col=4,
+            midi_box.Add(volumeText, pos=(channel,4),
                          flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL)
             #6th column (col=5) is unused on purpose to leave some space (maybe replaced with some other spacer option later on)
-            midi_box.Add(panSlider, row=channel, col=6,
+            midi_box.Add(panSlider, pos=(channel,6),
                          flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL)
-            midi_box.Add(panText, row=channel, col=7,
+            midi_box.Add(panText, pos=(channel,7),
                          flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL)
             #Some properties are added to the slider to be able to update the associated text field with value when slider is moved
             volumeSlider.currentchannel=channel
@@ -3133,7 +3132,7 @@ class ColorSettingsFrame(wx.Panel):
         self.SetBackgroundColour(dialog_background_colour)
         border = control_margin

-        grid_sizer = rcs.RowColSizer()
+        grid_sizer = wx.GridBagSizer()

         note_highlight_color = self.settings.get('note_highlight_color', default_note_highlight_color)
         note_highlight_color_label = wx.StaticText(self, wx.ID_ANY, _("Note highlight color"))
@@ -3145,8 +3144,8 @@ class ColorSettingsFrame(wx.Panel):
             b = int(note_highlight_color[5:7], 16)
             self.note_highlight_color_picker = wx.ColourPickerCtrl(self, wx.ID_ANY, wx.Colour(r, g, b))

-        grid_sizer.Add(note_highlight_color_label, row=0, col=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
-        grid_sizer.Add(self.note_highlight_color_picker, row=0, col=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        grid_sizer.Add(note_highlight_color_label, pos=(0,0), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)
+        grid_sizer.Add(self.note_highlight_color_picker, pos=(0,1), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=border)

         note_highlight_color_tooltip = _('Color of selected note or currently playing note')
         self.note_highlight_color_picker.SetToolTip(wx.ToolTip(note_highlight_color_tooltip))
mmehl commented 9 months ago

I get the mis-sized settings window in python 3.10 on SuSE. I haven't bothered to diagnose it - I just make them bigger to use them, and they work OK. I have more important problems to solve!

@mmehl - is it using fluidsynth? (#79)? What version of wxPython?

I'm using Ubuntu 23.10 and fluidsynth

$ python3 -c "import wx;print(wx.version)" 4.2.1

topchyan commented 9 months ago

I get the mis-sized settings window in python 3.10 on SuSE. I haven't bothered to diagnose it - I just make them bigger to use them, and they work OK.

Could you please explain how do you make them bigger? My controls seem to have been running into each other, but their sizes were okay, I think. This happened on some tabs in the settings dialog, but not on all of them.

topchyan commented 9 months ago

I applied all 3 patches listed here and the tool worked for me.

$ /usr/bin/python3 -V
Python 3.11.2

$ /usr/bin/python3 -c "import wx;print (wx.__version__)"
4.2.0
topchyan commented 9 months ago

image

The toolbar buttons layout and more importantly behavior after successful launch of the tool is problematic.

The "Play" button when not playing often is flipped to "Pause" image rather than "Play" which is confusing. This goes away when "Stop" button pressed a few times, but not always.

Zoom slider works, but looks off

Play Position slider doesn't work at all.

mmehl commented 9 months ago

problem with zoom slider (see ) shows ticks, which is not really needed /useful.

remove command wx_slider_set_tick_freq(self.zoom_slider, 10)

diff --git a/easy_abc.py b/easy_abc.py
index cc662e8..112e3f0 100644
--- a/easy_abc.py
+++ b/easy_abc.py
@@ -4807,9 +4807,8 @@ class MainFrame(wx.Frame):

         self.toolbar.AddSeparator()

-        self.zoom_slider = self.add_slider_to_toolbar(_('Zoom'), False, value=1000, minValue=500, maxValue=3000, size=(130, -1), style=wx.SL_HORIZONTAL)
+        self.zoom_slider = self.add_slider_to_toolbar(_('Zoom'), False, value=1000, minValue=500, maxValue=3000, size=(130, -1))

-        wx_slider_set_tick_freq(self.zoom_slider, 10)
         self.Bind(wx.EVT_SLIDER, self.OnZoomSlider, self.zoom_slider)
         self.zoom_slider.Bind(wx.EVT_LEFT_DOWN, self.OnZoomSliderClick)
topchyan commented 9 months ago

This does fix zoom slider issue. Thanks. Could you also check the Play button and Play Position slider misbehavior?

mmehl commented 9 months ago

The play button problem is more complicated. It seems to be a issue in libfluidsynth:

I'll try to investigate this further.

See https://github.com/FluidSynth/fluidsynth/issues/1296

mmehl commented 9 months ago

Problem with stop/pause is fixed in fluidsynth 2.3.4 (see https://github.com/FluidSynth/fluidsynth/issues/1272). New version of fluidsynth for Ubuntu Mantic 23.10 will be delivered with https://bugs.launchpad.net/ubuntu/+source/fluidsynth/+bug/2047656

topchyan commented 9 months ago

I built from sources just now

$ fluidsynth -V FluidSynth runtime version 2.3.1 Copyright (C) 2000-2023 Peter Hanappe and others. Distributed under the LGPL license. SoundFont(R) is a registered trademark of Creative Technology Ltd.

FluidSynth executable version 2.3.4 Sample type=double

Not sure why there is a difference between runtime and executable. Perhaps I should have removed the package first prior to installing. The problem with play button still exists

topchyan commented 9 months ago

had to run sudo ldconfig and now they are in sync

$ fluidsynth -V FluidSynth runtime version 2.3.4 Copyright (C) 2000-2023 Peter Hanappe and others. Distributed under the LGPL license. SoundFont(R) is a registered trademark of Creative Technology Ltd.

FluidSynth executable version 2.3.4 Sample type=double

Still the library is in the old version... need to find out how to build that $ sudo apt show libfluidsynth3 Package: libfluidsynth3 Version: 2.3.1-2 Priority: optional Section: libs Source: fluidsynth Maintainer: Debian Multimedia Maintainers debian-multimedia@lists.debian.org Installed-Size: 607 kB

mmehl commented 9 months ago

It should be sufficient to copy the freshly compiled libfluidsynth into the EasyABC because the following search path is used:

lib_locations = ['./libfluidsynth.so.3', 'libfluidsynth.so.3', './libfluidsynth.so.2', 'libfluidsynth.so.2']

topchyan commented 9 months ago

Copied the files, but no change in behavior of play button

topchyan commented 8 months ago

@jwdj, are there any plans to integrate any of these recent changes to the code?

markblinkhorn commented 8 months ago

Just a note to confirm I have the same issue with Python 3.11.2 on a Raspberry Pi 5. @topchyan Your mods have now been applied and work. I had managed to sort the regex and rU issues on my own, but thank you @mmehl for the GridBag work!

I haven't got Fluidsynth to work yet, but that is mainly because they removed the analog audio connector from the RPi 5 - waiting for a USB DAC to be delivered...

markblinkhorn commented 6 months ago

I have made some modifications to fluidsynth.py, mainly to correct a problem affecting it running on 64-bit Windows, but it might just help with any 'Unpredictable Behaviours' that you may come across. The modified version is in the repo at https://github.com/jwdj/EasyABC/blob/master/fluidsynth.py

topchyan commented 6 months ago

@markblinkhorn since that change is already integrated in the master branch, which I'm running on Linux, I could say that it works. That said, I am running this using pyenv with the version 3.8.18. The newer pythons don't like EasyABC in it's current state. Using pyenv is not the most straightforward, but once configured it does the job well.

markblinkhorn commented 6 months ago

@topchyan that's good to hear. Just for the record; I'm running Python 3.11.2 on Bookworm on an R-Pi5 and Python 312.2 on Windows 11 on a laptop PC. Both seem to be running without any major problems - especially after the input from your good self and others. I see several grumbles from Gtk-CRITICAL **: 21:49:37.432: gtk_box_gadget_distribute: assertion 'size >= 0' failed in GtkScrollbar but it doesn't seem to be fatal, so I'm ignoring it.

topchyan commented 6 months ago

@markblinkhorn are you running the freshly cloned master branch from the repo or using a modified version? Just curious. None of my attempts to run it under 3.11 and and even earlier versions were successful. Only 3.8.18 seems to work for me with pyenv and custom install of wxPython within it. I'm also using Bookworm (MX-Linux distro)

markblinkhorn commented 6 months ago

I have heavily modified the EasyABC code from the repo.

I started with a new R-Pi5 with PCIe NVME drive. I used the RaspberryPi-Imager to write the 2023-12-06 version of Raspberry Pi OS with desktop 64bit Debian 12 (bookworm) and then upgraded that to the current version using apt (I note a 2024-03-12 version is currently available). I haven't yet done a full documentation of the installation process (I will get around to it one day) but do note that I try not to use pip to install any of the Python 3 pre-requisites for EasyABC unless I have no choice, - you can usually use apt install python3-xxxxx - I have had problems in the past with version incompatabilities between Python2, Python3 and pip so I don't trust it any more.

I cloned the EasyABC master repo (back in February) and also, whenever an external program was required (notably the abc2xxx suite, ffmpeg and fluidsynth), I cloned and/or built the latest available version from their respective repos.

Then, I made all of the modifications documented by @mmehl earlier in this thread:

Regex and io.open fixes https://github.com/jwdj/EasyABC/issues/78#issuecomment-1865022291

GridBag Sizer fixes https://github.com/jwdj/EasyABC/issues/78#issuecomment-1866130190

I also made the changes to the Barfly parameter ordering that I have documented here: https://github.com/jwdj/EasyABC/issues/86#issuecomment-1959666858

And finally added in my modified vesion of fluidsynth.py which is now included in the repo. (This would be an unnecessary step if you were to take a new clone of the EasyAbc repo.)

When I came around to building the Windows version I simply installed all the pre-reqs and then cloned the running EasyABC code from the R-Pi to my Windows laptop.

Both of the installations run ok - not entirely bugfree - but without crashing out.