Browse Source

stuff

master
Nils 5 years ago
parent
commit
9f55bb5e55
  1. BIN
      desktop/icon32x32.png
  2. 21
      engine/api.py
  3. 8
      engine/main.py
  4. 20
      engine/pattern.py
  5. 7
      engine/track.py
  6. 26
      qtgui/pattern_grid.py
  7. 7455
      qtgui/resources.py
  8. BIN
      qtgui/resources/aboutlogo.png
  9. BIN
      qtgui/resources/icon.png

BIN
desktop/icon32x32.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 942 B

After

Width:  |  Height:  |  Size: 575 B

21
engine/api.py

@ -168,19 +168,21 @@ def startEngine(nsmClient):
callbacks._subdivisionsChanged()
callbacks._quarterNotesPerMinuteChanged()
session.eventLoop.fastConnect(cbox.call_on_idle)
for track in session.data.tracks:
callbacks._trackMetaDataChanged(track) #for colors, scale and noteNames
callbacks._trackMetaDataChanged(track) #for colors, scale and simpleNoteNames
session.data.buildAllTracks()
updatePlayback()
cbox.Transport.stop()
seek(0)
def toggleLoop():
"""Plays the current measure as loop.
Current measure is where the playback cursor is"""
Current measure is where the playback cursor is
session.inLoopMode is a tuple (start, end)
"""
if session.inLoopMode:
session.data.buildSongDuration() #no parameter removes the loop
updatePlayback()
@ -189,6 +191,7 @@ def toggleLoop():
else:
now = loopMeasureAroundPpqn=cbox.Transport.status().pos_ppqn
loopStart, loopEnd = session.data.buildSongDuration(now)
updatePlayback()
session.inLoopMode = (loopStart, loopEnd)
@ -211,7 +214,7 @@ def seek(value):
cbox.Transport.seek_ppqn(value)
##Score
def set_quarterNotesPerMinute(value):
def set_quarterNotesPerMinute(value:int):
if value is None:
session.data.tempoMap.isTransportMaster = False #triggers rebuild
elif value == "on":
@ -300,7 +303,7 @@ def createSiblingTrack(trackId):
(if any)"""
track = session.data.trackById(trackId)
assert type(track.pattern.scale) == tuple
newTrack = session.data.addTrack(name=track.sequencerInterface.name, scale=track.pattern.scale, color=track.color, noteNames=track.pattern.noteNames) #track name increments itself from "Track A" to "Track B" or "Track 1" -> "Track 2"
newTrack = session.data.addTrack(name=track.sequencerInterface.name, scale=track.pattern.scale, color=track.color, simpleNoteNames=track.pattern.simpleNoteNames) #track name increments itself from "Track A" to "Track B" or "Track 1" -> "Track 2"
newTrack.pattern.averageVelocity = track.pattern.averageVelocity
jackConnections = cbox.JackIO.get_connected_ports(track.sequencerInterface.cboxPortName())
for port in jackConnections:
@ -511,11 +514,11 @@ def setScale(trackId, scale):
updatePlayback()
callbacks._trackMetaDataChanged(track)
def setNoteNames(trackId, noteNames):
def setSimpleNoteNames(trackId, simpleNoteNames):
"""note names is a list of strings with length 128. One name for each midi note.
It is saved to file"""
track = session.data.trackById(trackId)
track.pattern.noteNames = noteNames
track.pattern.simpleNoteNames = simpleNoteNames
callbacks._trackMetaDataChanged(track)
def transposeHalftoneSteps(trackId, steps):

8
engine/main.py

@ -31,7 +31,7 @@ from calfbox import cbox
from template.engine.data import Data as TemplateData
import template.engine.sequencer
from template.engine.duration import D4
from template.engine.pitch import noteNames
from template.engine.pitch import simpleNoteNames
#Our modules
from .track import Track
@ -56,7 +56,7 @@ class Data(template.engine.sequencer.Score):
self.numberOfMeasures = 64
self.measuresPerGroup = 8 # meta data, has no effect on playback.
self.subdivisions = 1
self.lastUsedNotenames = noteNames["English"] #The default value for new tracks/patterns. Changed each time the user picks a new representation via api.setNoteNames . noteNames are saved with the patterns.
self.lastUsedNotenames = simpleNoteNames["English"] #The default value for new tracks/patterns. Changed each time the user picks a new representation via api.setNoteNames . noteNames are saved with the patterns.
self.addTrack(name="Melody A", color="#ffff00")
self.tracks[0].structure=set((0,)) #Already have the first pattern activated, so 'play' after startup already produces sounding notes. This is less confusing for a new user.
@ -68,9 +68,9 @@ class Data(template.engine.sequencer.Score):
def _processAfterInit(self):
pass
def addTrack(self, name="", scale=None, color=None, noteNames=None):
def addTrack(self, name="", scale=None, color=None, simpleNoteNames=None):
"""Overrides the simpler template version"""
track = Track(parentScore=self, name=name, scale=scale, color=color, noteNames=noteNames)
track = Track(parentScore=self, name=name, scale=scale, color=color, simpleNoteNames=simpleNoteNames)
self.tracks.append(track)
return track

20
engine/pattern.py

@ -48,12 +48,12 @@ class Pattern(object):
The pattern has always its maximum length.
"""
def __init__(self, parentTrack, data:List[dict]=None, scale:Tuple[int]=None, noteNames:List[str]=None):
def __init__(self, parentTrack, data:List[dict]=None, scale:Tuple[int]=None, simpleNoteNames:List[str]=None):
self._prepareBeforeInit()
self.parentTrack = parentTrack
self.scale = scale if scale else (72, 71, 69, 67, 65, 64, 62, 60) #Scale needs to be set first because on init/load data already depends on it, at least the default scale. The scale is part of the track meta callback.
self.data = data if data else list() #For content see docstring. this cannot be the default parameter because we would set the same list for all instances.
self.noteNames = noteNames if noteNames else self.parentTrack.parentScore.lastUsedNotenames #This is mostly for the GUI or other kinds of representation instead midi notes
self.simpleNoteNames = simpleNoteNames if simpleNoteNames else self.parentTrack.parentScore.lastUsedNotenames #This is mostly for the GUI or other kinds of representation instead midi notes
self._processAfterInit()
def _prepareBeforeInit(self):
@ -81,13 +81,13 @@ class Pattern(object):
self.createCachedTonalRange()
@property
def noteNames(self):
return self._noteNames
def simpleNoteNames(self):
return self._simpleNoteNames
@noteNames.setter
def noteNames(self, value):
self._noteNames = tuple(value) #we keep it immutable, this is safer to avoid accidental linked structures when creating a clone.
self.parentTrack.parentScore.lastUsedNotenames = self._noteNames #new default for new tracks
@simpleNoteNames.setter
def simpleNoteNames(self, value):
self._simpleNoteNames = tuple(value) #we keep it immutable, this is safer to avoid accidental linked structures when creating a clone.
self.parentTrack.parentScore.lastUsedNotenames = self._simpleNoteNames #new default for new tracks
def fill(self):
"""Create a 2 dimensional array"""
@ -221,7 +221,7 @@ class Pattern(object):
return {
"scale": self.scale,
"data": self.data,
"noteNames": self.noteNames,
"simpleNoteNames": self.simpleNoteNames,
}
@classmethod
@ -233,7 +233,7 @@ class Pattern(object):
#Use setters to trigger side effects like createCachedTonalRange()
self.scale = serializedData["scale"] #Scale needs to be set first because on init/load data already depends on it, at least the default scale. The scale is part of the track meta callback.
self.data = serializedData["data"] #For content see docstring.
self.noteNames = serializedData["noteNames"] #This is mostly for the GUI or other kinds of representation instead midi notes
self.simpleNoteNames = serializedData["simpleNoteNames"] #This is mostly for the GUI or other kinds of representation instead midi notes
self._processAfterInit()
return self

7
engine/track.py

@ -44,13 +44,12 @@ class Track(object): #injection at the bottom of this file!
color:str=None,
whichPatternsAreScaleTransposed:Dict[int,int]=None,
whichPatternsAreHalftoneTransposed:Dict[int,int]=None,
noteNames:List[str]=None):
simpleNoteNames:List[str]=None):
self.parentScore = parentScore
self.sequencerInterface = template.engine.sequencer.SequencerInterface(parentTrack=self, name=name) #needs parentScore
self.color = color if color else "#00FFFF" # "#rrggbb" in hex. no alpha. a convenience slot for the GUI to save a color.
self.pattern = Pattern(parentTrack=self, scale=scale, noteNames=noteNames)
self.pattern = Pattern(parentTrack=self, scale=scale, simpleNoteNames=simpleNoteNames)
self.structure = structure if structure else set() #see buildTrack(). This is the main track data structure besides the pattern. Just integers (starts at 0) as switches which are positions where to play the patterns. In between are automatic rests.
self.whichPatternsAreScaleTransposed = whichPatternsAreScaleTransposed if whichPatternsAreScaleTransposed else {} #position:integers between -7 and 7. Reversed pitch, row based: -7 is higher than 7!!
self.whichPatternsAreHalftoneTransposed = whichPatternsAreHalftoneTransposed if whichPatternsAreHalftoneTransposed else {} #position:integers between -7 and 7. Reversed pitch, row based: -7 is higher than 7!!
@ -122,7 +121,7 @@ class Track(object): #injection at the bottom of this file!
"structure" : sorted(self.structure),
"pattern": self.pattern.exportCache,
"scale": self.pattern.scale,
"noteNames": self.pattern.noteNames,
"simpleNoteNames": self.pattern.simpleNoteNames,
"numberOfMeasures": self.parentScore.numberOfMeasures,
"whichPatternsAreScaleTransposed": self.whichPatternsAreScaleTransposed,
"whichPatternsAreHalftoneTransposed": self.whichPatternsAreHalftoneTransposed,

26
qtgui/pattern_grid.py

@ -171,7 +171,7 @@ class PatternGrid(QtWidgets.QGraphicsScene):
self._steps[(x,y)].on(velocityAndFactor=velocityAndFactor, exceedsPlayback=noteDict["exceedsPlayback"])
self.scale.setScale(exportDict["scale"])
self.scale.setNoteNames(exportDict["noteNames"])
self.scale.setNoteNames(exportDict["simpleNoteNames"])
self.parentView.setViewportUpdateMode(updateMode)
@ -578,13 +578,13 @@ class Scale(QtWidgets.QGraphicsRectItem):
super().__init__(0,0,0,0)
self.parentScene = parentScene
self.pitchWidgets = [] #sorted from top to bottom in Step Rect and scene coordinates
self.noteNames = [] #list of 128 notes. use index with note name. Can be changed at runtime.
self.simpleNoteNames = [] #list of 128 notes. use index with note name. Can be changed at runtime.
api.callbacks.trackMetaDataChanged.append(self.callback_trackMetaDataChanged)
self.buildScale() #also sets the positions of the buttons above
def callback_trackMetaDataChanged(self, exportDict):
#Order matters. We need to set the notenames before the scale.
self.setNoteNames(exportDict["noteNames"])
self.setNoteNames(exportDict["simpleNoteNames"])
self.setScale(exportDict["scale"])
def buildScale(self):
@ -608,9 +608,9 @@ class Scale(QtWidgets.QGraphicsRectItem):
def setNoteNames(self, pNoteNames):
"""A list of 128 strings. Gets only called by the callback."""
#if pNoteNames in pitch.notenames.keys():
# self.noteNames = pitch.notenames[pNoteNames]
# self.simpleNoteNames = pitch.notenames[pNoteNames]
#else:
self.noteNames = pNoteNames
self.simpleNoteNames = pNoteNames
for pitchWidget in self.pitchWidgets:
pitchWidget.spinBoxValueChanged() #change all current pitchWidgets
@ -680,7 +680,7 @@ class TransposeControls(QtWidgets.QWidget):
self._comboBoxNoteNames = QtWidgets.QComboBox()
translatedNotenames = [QtCore.QCoreApplication.translate("Scale", scheme) for scheme in sorted(list(pitch.noteNames.keys()))]
translatedNotenames = [QtCore.QCoreApplication.translate("Scale", scheme) for scheme in sorted(list(pitch.simpleNoteNames.keys()))]
self._comboBoxNoteNames.addItems([QtCore.QCoreApplication.translate("TransposeControls","Set Notenames to:")] + translatedNotenames)
self._comboBoxNoteNames.activated.connect(self._changeNoteNamesByDropdown) #activated, not changend. even when choosing the same item
self._comboBoxNoteNames.setToolTip(QtCore.QCoreApplication.translate("TransposeControls", "Use this scheme as note names."))
@ -690,10 +690,10 @@ class TransposeControls(QtWidgets.QWidget):
if index > 0:
index -= 1 # we inserted our "Set NoteNames to" at index 0 shifting the real values +1.
schemes = sorted(pitch.noteNames.keys())
noteNamesAsString = sorted(pitch.noteNames.keys())[index]
noteNames = pitch.noteNames[noteNamesAsString]
api.setNoteNames(trackId=self.parentScene.parentView.parentMainWindow.currentTrackId, noteNames=noteNames)
schemes = sorted(pitch.simpleNoteNames.keys())
noteNamesAsString = sorted(pitch.simpleNoteNames.keys())[index]
simpleNoteNames = pitch.simpleNoteNames[noteNamesAsString]
api.setSimpleNoteNames(trackId=self.parentScene.parentView.parentMainWindow.currentTrackId, simpleNoteNames=simpleNoteNames)
self._comboBoxNoteNames.blockSignals(True)
self._comboBoxNoteNames.setCurrentIndex(0)
self._comboBoxNoteNames.blockSignals(False)
@ -773,12 +773,12 @@ class PitchWidget(QtWidgets.QGraphicsProxyWidget):
#self.spinBox.setStyleSheet(arrowsLeftStylesheet)
def midiToNotename(self, midipitch):
assert self.parentItem.noteNames, self.parentItem.noteNames
assert self.parentItem.simpleNoteNames, self.parentItem.simpleNoteNames
try:
return self.parentItem.noteNames[midipitch] #includes octave names
return self.parentItem.simpleNoteNames[midipitch] #includes octave names
except IndexError:
print (midipitch)
print (self.parentItem.noteNames)
print (self.parentItem.simpleNoteNames)
exit()
def spinBoxValueChanged(self):

7455
qtgui/resources.py

File diff suppressed because it is too large

BIN
qtgui/resources/aboutlogo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 57 KiB

BIN
qtgui/resources/icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 942 B

After

Width:  |  Height:  |  Size: 575 B

Loading…
Cancel
Save