Skip to content

Commit

Permalink
try new test
Browse files Browse the repository at this point in the history
  • Loading branch information
gesellkammer committed Feb 20, 2024
1 parent 828cd21 commit b41d7ec
Show file tree
Hide file tree
Showing 20 changed files with 1,099 additions and 765 deletions.
30 changes: 26 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,19 @@ jobs:
run: |
$Env:Path = $Env:Path + ";C:\Program Files\csound-binaries\build\Release"
cd test
python test-rec.py -o test-rec--windows-${{ matrix.install-method }}.wav
python test-dependencies.py
python test-notation.py -o 'test-notation-windows-${{ matrix.install-method }}-${{ matrix.python-version }}.pdf'
cp *.wav ../artifacts
cp *.pdf ../artifacts
# new tests
python test-clip-chords.py
python rosita-centroid.py
cp output/* ../artifacts
- uses: actions/upload-artifact@v3
with:
path: artifacts
Expand Down Expand Up @@ -85,8 +92,12 @@ jobs:
python test-notation.py -o 'test-notation-linux-${{ matrix.python-version }}.pdf'
cp *.wav ../artifacts
cp *.pdf ../artifacts
cd ..
pip uninstall -y maelzel
# new tests
python test-clip-chords.py
python rosita-centroid.py
cp output/* ../artifacts
- uses: actions/upload-artifact@v3
with:
Expand Down Expand Up @@ -129,8 +140,13 @@ jobs:
python test-notation.py -o 'test-notation-linux-${{ matrix.python-version }}.pdf'
cp *.wav ../artifacts
cp *.pdf ../artifacts
cd ..
deactivate
# new tests
python test-clip-chords.py
python rosita-centroid.py
cp output/* ../artifacts
- uses: actions/upload-artifact@v3
with:
Expand Down Expand Up @@ -177,6 +193,12 @@ jobs:
cp *.wav ../artifacts
cp *.pdf ../artifacts
# new tests
python test-clip-chords.py
python rosita-centroid.py
cp output/* ../artifacts
cd ..
pip uninstall -y maelzel
Expand Down
85 changes: 85 additions & 0 deletions .github/workflows/test2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
on: [push]


jobs:
alltests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: ["windows-latest", "macos-latest", "ubuntu-latest"]
python-version: ["3.9", "3.10", "3.11"]
install-method: ["git", "pip"]
steps:
- uses: actions/checkout@v3

- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: windows setup
if: runner.os == 'windows'
run: |
curl -L -o csound-binaries.zip https://github.com/csound/csound/releases/download/6.18.1/Csound-6.18.1-windows-x64-binaries.zip
Expand-Archive csound-binaries.zip -DestinationPath "C:\Program Files\csound-binaries"
ls -r "C:\Program Files\csound-binaries"
[Environment]::SetEnvironmentVariable("PATH", $Env:PATH + ";C:\Program Files\csound-binaries\build\Release", [EnvironmentVariableTarget]::Machine)
$Env:Path = $Env:Path + ";C:\Program Files\csound-binaries\build\Release"
Write-Output $Env:PATH
csound.exe --version
mkdir artifacts
- name: linux setup
if: runner.os == 'linux'
run: |
set -x
# sudo apt update
# sudo apt install lilypond
sudo apt install csound libcsnd-dev
csound --version
# lilypond --version
- name: macos setup
if: runner.os == 'macOs'
run: |
set -x
curl -L -o csound6.18.dmg https://github.com/csound/csound/releases/download/6.18.1/Csound-MacOS-universal-6.18.1.dmg
brew install p7zip
7z x csound6.18.dmg
cd Csound-universal-6.18.1
sudo installer -pkg csound-MacOS-universal-6.18.1.pkg -target /
csound --version
cd ..
# brew install lilypond
# lilypond --version
- name: install from repo
if: ${{ matrix.install-method == 'git' }}
run: |
pip install .
- name: install from pip
if: ${{ matrix.install-method == 'pip' }}
run: |
pip install maelzel
- name: test
run: |
cd test
python test-rec.py -o test-rec--windows-${{ matrix.install-method }}.wav
python test-dependencies.py
python test-notation.py -o 'test-notation-${{ matrix.os }}-${{ matrix.install-method }}-${{ matrix.python-version }}.pdf'
cp *.wav ../artifacts
cp *.pdf ../artifacts
# new tests
python test-clip-chords.py
python rosita-centroid.py
cp output/* ../artifacts
- uses: actions/upload-artifact@v3
with:
path: artifacts

17 changes: 17 additions & 0 deletions maelzel/core/_configtools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""
Utils used by coreconfig. Cannot import from anything within maelzel.core
"""

from maelzel.common import F


def isValidFraction(obj) -> bool:
"""
True if obj can be interpreted as Fraction
"""
try:
frac = F(obj)
return True
except Exception:
return False

1 change: 0 additions & 1 deletion maelzel/core/_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,4 +555,3 @@ def _interpolateBreakpoints(t: float, bp0: Sequence[num_t], bp1: Sequence[num_t]
bp.append(v0 + (v1-v0)*delta)
return bp


27 changes: 27 additions & 0 deletions maelzel/core/configdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from maelzel.textstyle import TextStyle
from maelzel import dynamiccurve
from numbers import Rational
from ._configtools import isValidFraction


defaultdict = {
Expand Down Expand Up @@ -59,6 +60,9 @@
'show.referenceStaffsize': 12.0,
'show.musicxmlFontScaling': 1.0,
'show.autoClefChanges': True,
'show.proportionalSpacing': False,
'show.proportionalSpacingKind': 'strict',
'show.proportionalNotationDuration': '1/24',
'.show.autoClefChangesWindow': 1,
'.show.keepClefBiasFactor': 2.0,

Expand Down Expand Up @@ -162,6 +166,8 @@
'show.clipNoteheadShape::choices': ('', 'square', 'normal', 'cross', 'harmonic', 'triangle',
'xcircle', 'rhombus', 'rectangle', 'slash', 'diamond',
'cluster'),
'show.proportionalNotationDuration': lambda cfg, key, val: isValidFraction(val),
'show.proportionalSpacingKind::choices': ('strict', 'uniform', ''),
'dynamicCurveShape': lambda cfg, key, val: val.split("(")[0] in ('linear', 'expon', 'halfcos'),
'dynamicCurveMindb::range': (-160, 0),
'dynamicCurveMaxdb::range': (-160, 0),
Expand Down Expand Up @@ -556,6 +562,27 @@
'If True, add clef changes to a quantized part if needed. Otherwise, one clef '
'is determined for each part and is not changed along the part.',

'show.proportionalSpacing':
'Output notation using proportional spacing, a type of horizontal spacing '
'in which each note consumes an amount of horizontal space exactly equivalent '
'to its rhythmic duration. At the moment this is only supported by the lilypond '
'backend. See ``show.proportionalNotationDuration`` to customize the actual '
'horizontal spacing',

'show.proportionalSpacingKind':
'The spacing used for proportional spacing. This is only valid for lilypond. '
'One of "strict", "uniform" or "". Strict spacing places notes horizontally '
'only taking the duration into account; any clef changes or other symbols '
'are not used for horizontal spacing. This is needed if alignment with '
'a fixed timeline (like some kind of plot) is needed. Uniform spacing assigns '
'some horizontal space to clefs and time signatures, offsetting the music to '
'the right by some amount. ',

'show.proportionalNotationDuration':
'The lower this value, the longer the space taken by each note. At the moment, '
'this corresponds 1:1 to the value as used by lilypond. See also: '
'https://lilypond.org/doc/v2.23/Documentation/notation/proportional-notation',

'.show.keepClefBiasFactor':
'The higher this value, the more priority is given to keeping the previous '
'clef during automatic clef changes',
Expand Down
6 changes: 5 additions & 1 deletion maelzel/core/notation.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ def makeRenderOptionsFromConfig(cfg: CoreConfig = None,
keepClefBiasFactor=cfg['.show.keepClefBiasFactor'],
autoClefChangesWindow=cfg['.show.autoClefChangesWindow'],
musicxmlFontScaling=cfg['show.musicxmlFontScaling'],
centsAnnotationSnap=cfg['show.centsAnnotationSnap']
centsAnnotationSnap=cfg['show.centsAnnotationSnap'],
proportionalSpacing=cfg['show.proportionalSpacing'],
proportionalNotationDuration=cfg['show.proportionalNotationDuration'],
proportionalSpacingKind=cfg['show.proportionalSpacingKind']

)
return renderOptions

Expand Down
40 changes: 39 additions & 1 deletion maelzel/scoring/lilypondsnippets.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from string import Template
from functools import cache


prelude = r"""
Expand Down Expand Up @@ -277,4 +278,41 @@


def glissandoMinimumLength(length: int) -> str:
return _glissandoMinLengthTemplate.substitute(length=length)
return _glissandoMinLengthTemplate.substitute(length=length)


def proportionalSpacing(num=1, den=20, strict=True, uniform=True
) -> str:
"""
Creates the snippet for proportional spacing
https://lilypond.org/doc/v2.23/Documentation/notation/proportional-notation
Args:
num: numerator for horizontal resolution
den: denominator for horizontal resolution
strict: use strict spacing
uniform: use uniform spacing
Returns:
the lilypond snippet
"""
spacings = []
if strict:
spacings.append(r" \override SpacingSpanner.strict-note-spacing = ##t")

if uniform:
spacings.append(r" \override SpacingSpanner.uniform-stretching = ##t")

spacing = "\n".join(spacings) if spacings else ' '

return fr"""
\layout {{
\context {{
\Score
proportionalNotationDuration = #(ly:make-moment {num}/{den})
{spacing}
}}
}}
"""

11 changes: 11 additions & 0 deletions maelzel/scoring/renderlily.py
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,17 @@ def _(s, dedent=False, indent=0):
indents -= 1

_(r">>")
if options.proportionalSpacing:
dur = asF(options.proportionalNotationDuration)
if options.proportionalSpacingKind == 'strict':
strict, uniform = True, True
elif options.proportionalSpacingKind == 'uniform':
strict, uniform = False, True
else:
strict, uniform = False, False
_(lilypondsnippets.proportionalSpacing(num=dur.numerator, den=dur.denominator,
strict=strict, uniform=uniform))

if midi:
_(" "*indentSize + r"\midi { }")
_(r"} % end score") # end \score
Expand Down
8 changes: 8 additions & 0 deletions maelzel/scoring/renderoptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@ class RenderOptions:
A small denominator depends on tempo
"""

proportionalSpacing: bool = False
"""Use proportional spacing"""

proportionalNotationDuration: str = '1/20'
"""A lower value results in a note taking more horizontal space"""

proportionalSpacingKind: str = 'strict'

@classmethod
def keys(cls) -> set[str]:
return {f.name for f in _dataclassfields(cls)}
Expand Down
36 changes: 18 additions & 18 deletions notebooks/test/centroid.ipynb

Large diffs are not rendered by default.

Loading

0 comments on commit b41d7ec

Please sign in to comment.