- Merge the base/client/server model class trees into a single tree. - Move the model into the UI process. - Autogenerate model boilerplate code. - Replace commands by arbitrary mutations directly from the UI. - Assorted other cleanups.looper
parent
6cd4d024d8
commit
accff25ed0
@ -1,64 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# @begin:license
|
||||
#
|
||||
# Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# @end:license
|
||||
|
||||
from typing import Sequence
|
||||
|
||||
from noisicaa.core.typing_extra import down_cast
|
||||
from noisicaa import audioproc
|
||||
from noisicaa import model
|
||||
from noisicaa.music import project_client_model
|
||||
from . import model as beat_track_model
|
||||
|
||||
|
||||
class Beat(
|
||||
project_client_model.ProjectChild,
|
||||
beat_track_model.Beat,
|
||||
project_client_model.ObjectBase):
|
||||
@property
|
||||
def time(self) -> audioproc.MusicalDuration:
|
||||
return audioproc.MusicalDuration.from_proto(self.get_property_value('time'))
|
||||
|
||||
@property
|
||||
def velocity(self) -> int:
|
||||
return self.get_property_value('velocity')
|
||||
|
||||
@property
|
||||
def measure(self) -> 'BeatMeasure':
|
||||
return down_cast(BeatMeasure, super().measure)
|
||||
|
||||
|
||||
class BeatMeasure(
|
||||
project_client_model.Measure,
|
||||
beat_track_model.BeatMeasure,
|
||||
project_client_model.ObjectBase):
|
||||
@property
|
||||
def beats(self) -> Sequence[Beat]:
|
||||
return self.get_property_value('beats')
|
||||
|
||||
|
||||
class BeatTrack(
|
||||
project_client_model.MeasuredTrack,
|
||||
beat_track_model.BeatTrack,
|
||||
project_client_model.ObjectBase):
|
||||
@property
|
||||
def pitch(self) -> model.Pitch:
|
||||
return self.get_property_value('pitch')
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* @begin:license
|
||||
*
|
||||
* Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* @end:license
|
||||
*/
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
import "noisicaa/audioproc/public/musical_time.proto";
|
||||
import "noisicaa/model/project.proto";
|
||||
|
||||
package noisicaa.pb;
|
||||
|
||||
message UpdateBeatTrack {
|
||||
required uint64 track_id = 1;
|
||||
optional Pitch set_pitch = 2;
|
||||
}
|
||||
|
||||
message CreateBeat {
|
||||
required uint64 measure_id = 1;
|
||||
optional MusicalDuration time = 2;
|
||||
optional uint32 velocity = 3;
|
||||
}
|
||||
|
||||
message UpdateBeat {
|
||||
required uint64 beat_id = 1;
|
||||
optional uint32 set_velocity = 2;
|
||||
}
|
||||
|
||||
message DeleteBeat {
|
||||
optional uint64 beat_id = 1;
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# @begin:license
|
||||
#
|
||||
# Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# @end:license
|
||||
|
||||
from noisicaa import audioproc
|
||||
from noisicaa import model
|
||||
from noisicaa import music
|
||||
from noisicaa.builtin_nodes import commands_registry_pb2
|
||||
from . import client_impl
|
||||
|
||||
|
||||
def update(
|
||||
track: client_impl.BeatTrack, *, set_pitch: model.Pitch = None) -> music.Command:
|
||||
cmd = music.Command(command='update_beat_track')
|
||||
pb = cmd.Extensions[commands_registry_pb2.update_beat_track]
|
||||
pb.track_id = track.id
|
||||
if set_pitch is not None:
|
||||
pb.set_pitch.CopyFrom(set_pitch.to_proto())
|
||||
return cmd
|
||||
|
||||
def create_beat(
|
||||
measure: client_impl.BeatMeasure, *,
|
||||
time: audioproc.MusicalTime,
|
||||
velocity: int = None
|
||||
) -> music.Command:
|
||||
cmd = music.Command(command='create_beat')
|
||||
pb = cmd.Extensions[commands_registry_pb2.create_beat]
|
||||
pb.measure_id = measure.id
|
||||
pb.time.CopyFrom(time.to_proto())
|
||||
if velocity is not None:
|
||||
pb.velocity = velocity
|
||||
return cmd
|
||||
|
||||
def update_beat(
|
||||
beat: client_impl.Beat, *, set_velocity: int = None) -> music.Command:
|
||||
cmd = music.Command(command='update_beat')
|
||||
pb = cmd.Extensions[commands_registry_pb2.update_beat]
|
||||
pb.beat_id = beat.id
|
||||
if set_velocity is not None:
|
||||
pb.set_velocity = set_velocity
|
||||
return cmd
|
||||
|
||||
def delete_beat(beat: client_impl.Beat) -> music.Command:
|
||||
cmd = music.Command(command='delete_beat')
|
||||
pb = cmd.Extensions[commands_registry_pb2.delete_beat]
|
||||
pb.beat_id = beat.id
|
||||
return cmd
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* @begin:license
|
||||
*
|
||||
* Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* @end:license
|
||||
*/
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
import "noisicaa/audioproc/public/musical_time.proto";
|
||||
import "noisicaa/model/project.proto";
|
||||
|
||||
package noisicaa.pb;
|
||||
|
||||
message Beat {
|
||||
optional MusicalDuration time = 1;
|
||||
optional uint32 velocity = 2;
|
||||
}
|
||||
|
||||
message BeatMeasure {
|
||||
repeated uint64 beats = 1;
|
||||
}
|
||||
|
||||
message BeatTrack {
|
||||
optional Pitch pitch = 1;
|
||||
}
|
@ -1,203 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# @begin:license
|
||||
#
|
||||
# Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# @end:license
|
||||
|
||||
import logging
|
||||
from typing import Any, MutableSequence, Optional, Iterator, Callable
|
||||
|
||||
from noisicaa.core.typing_extra import down_cast
|
||||
from noisicaa import audioproc
|
||||
from noisicaa import model
|
||||
from noisicaa.music import commands
|
||||
from noisicaa.music import pmodel
|
||||
from noisicaa.music import base_track
|
||||
from noisicaa.builtin_nodes import commands_registry_pb2
|
||||
from . import commands_pb2
|
||||
from . import model as beat_track_model
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class UpdateBeatTrack(commands.Command):
|
||||
proto_type = 'update_beat_track'
|
||||
proto_ext = commands_registry_pb2.update_beat_track
|
||||
|
||||
def run(self) -> None:
|
||||
pb = down_cast(commands_pb2.UpdateBeatTrack, self.pb)
|
||||
track = down_cast(BeatTrack, self.pool[pb.track_id])
|
||||
|
||||
if pb.HasField('set_pitch'):
|
||||
track.pitch = model.Pitch.from_proto(pb.set_pitch)
|
||||
|
||||
|
||||
class CreateBeat(commands.Command):
|
||||
proto_type = 'create_beat'
|
||||
proto_ext = commands_registry_pb2.create_beat
|
||||
|
||||
def run(self) -> None:
|
||||
pb = down_cast(commands_pb2.CreateBeat, self.pb)
|
||||
measure = down_cast(BeatMeasure, self.pool[pb.measure_id])
|
||||
|
||||
time = audioproc.MusicalDuration.from_proto(pb.time)
|
||||
assert audioproc.MusicalDuration(0, 1) <= time < measure.duration
|
||||
|
||||
if pb.HasField('velocity'):
|
||||
velocity = pb.velocity
|
||||
else:
|
||||
velocity = 100
|
||||
|
||||
beat = self.pool.create(
|
||||
Beat,
|
||||
time=time,
|
||||
velocity=velocity)
|
||||
measure.beats.append(beat)
|
||||
|
||||
|
||||
class UpdateBeat(commands.Command):
|
||||
proto_type = 'update_beat'
|
||||
proto_ext = commands_registry_pb2.update_beat
|
||||
|
||||
def run(self) -> None:
|
||||
pb = down_cast(commands_pb2.UpdateBeat, self.pb)
|
||||
beat = down_cast(Beat, self.pool[pb.beat_id])
|
||||
|
||||
if pb.HasField('set_velocity'):
|
||||
beat.velocity = pb.set_velocity
|
||||
|
||||
|
||||
class DeleteBeat(commands.Command):
|
||||
proto_type = 'delete_beat'
|
||||
proto_ext = commands_registry_pb2.delete_beat
|
||||
|
||||
def run(self) -> None:
|
||||
pb = down_cast(commands_pb2.DeleteBeat, self.pb)
|
||||
beat = down_cast(Beat, self.pool[pb.beat_id])
|
||||
|
||||
measure = beat.measure
|
||||
del measure.beats[beat.index]
|
||||
|
||||
|
||||
class Beat(pmodel.ProjectChild, beat_track_model.Beat, pmodel.ObjectBase):
|
||||
def create(
|
||||
self, *,
|
||||
time: Optional[audioproc.MusicalDuration] = None,
|
||||
velocity: Optional[int] = None,
|
||||
**kwargs: Any) -> None:
|
||||
super().create(**kwargs)
|
||||
|
||||
self.time = time
|
||||
self.velocity = velocity
|
||||
|
||||
@property
|
||||
def time(self) -> audioproc.MusicalDuration:
|
||||
return audioproc.MusicalDuration.from_proto(self.get_property_value('time'))
|
||||
|
||||
@time.setter
|
||||
def time(self, value: audioproc.MusicalDuration) -> None:
|
||||
self.set_property_value('time', value.to_proto())
|
||||
|
||||
@property
|
||||
def velocity(self) -> int:
|
||||
return self.get_property_value('velocity')
|
||||
|
||||
@velocity.setter
|
||||
def velocity(self, value: int) -> None:
|
||||
self.set_property_value('velocity', value)
|
||||
|
||||
@property
|
||||
def measure(self) -> 'BeatMeasure':
|
||||
return down_cast(BeatMeasure, super().measure)
|
||||
|
||||
|
||||
class BeatMeasure(base_track.Measure, beat_track_model.BeatMeasure, pmodel.ObjectBase):
|
||||
@property
|
||||
def beats(self) -> MutableSequence[Beat]:
|
||||
return self.get_property_value('beats')
|
||||
|
||||
@property
|
||||
def empty(self) -> bool:
|
||||
return len(self.beats) == 0
|
||||
|
||||
|
||||
class BeatTrackConnector(base_track.MeasuredTrackConnector):
|
||||
_node = None # type: BeatTrack
|
||||
|
||||
def _add_track_listeners(self) -> None:
|
||||
self._listeners['pitch'] = self._node.pitch_changed.add(self.__pitch_changed)
|
||||
|
||||
def _add_measure_listeners(self, mref: pmodel.MeasureReference) -> None:
|
||||
measure = down_cast(BeatMeasure, mref.measure)
|
||||
self._listeners['measure:%s:beats' % mref.id] = measure.content_changed.add(
|
||||
lambda _=None: self.__measure_beats_changed(mref)) # type: ignore
|
||||
|
||||
def _remove_measure_listeners(self, mref: pmodel.MeasureReference) -> None:
|
||||
self._listeners.pop('measure:%s:beats' % mref.id).remove()
|
||||
|
||||
def _create_events(
|
||||
self, time: audioproc.MusicalTime, measure: pmodel.Measure
|
||||
) -> Iterator[base_track.PianoRollInterval]:
|
||||
measure = down_cast(BeatMeasure, measure)
|
||||
for beat in measure.beats:
|
||||
beat_time = time + beat.time
|
||||
event = base_track.PianoRollInterval(
|
||||
beat_time, beat_time + audioproc.MusicalDuration(1, 4),
|
||||
self._node.pitch, 127)
|
||||
yield event
|
||||
|
||||
def __pitch_changed(self, change: model.PropertyChange) -> None:
|
||||
self._update_measure_range(0, len(self._node.measure_list))
|
||||
|
||||
def __measure_beats_changed(self, mref: pmodel.MeasureReference) -> None:
|
||||
self._update_measure_range(mref.index, mref.index + 1)
|
||||
|
||||
|
||||
class BeatTrack(base_track.MeasuredTrack, beat_track_model.BeatTrack, pmodel.ObjectBase):
|
||||
measure_cls = BeatMeasure
|
||||
|
||||
def create(
|
||||
self, *,
|
||||
pitch: Optional[model.Pitch] = None,
|
||||
num_measures: int = 1, **kwargs: Any) -> None:
|
||||
super().create(**kwargs)
|
||||
|
||||
if pitch is None:
|
||||
self.pitch = model.Pitch('B2')
|
||||
else:
|
||||
self.pitch = pitch
|
||||
|
||||
for _ in range(num_measures):
|
||||
self.append_measure()
|
||||
|
||||
@property
|
||||
def pitch(self) -> model.Pitch:
|
||||
return self.get_property_value('pitch')
|
||||
|
||||
@pitch.setter
|
||||
def pitch(self, value: model.Pitch) -> None:
|
||||
self.set_property_value('pitch', value)
|
||||
|
||||
def create_node_connector(
|
||||
self,
|
||||
message_cb: Callable[[audioproc.ProcessorMessage], None],
|
||||
audioproc_client: audioproc.AbstractAudioProcClient,
|
||||
) -> BeatTrackConnector:
|
||||
return BeatTrackConnector(
|
||||
node=self, message_cb=message_cb, audioproc_client=audioproc_client)
|
@ -1,63 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# @begin:license
|
||||
#
|
||||
# Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# @end:license
|
||||
|
||||
from noisicaa import audioproc
|
||||
from noisicaa import model
|
||||
from noisicaa.music import pmodel_test
|
||||
from . import server_impl
|
||||
|
||||
T0 = audioproc.MusicalDuration(0, 4)
|
||||
|
||||
|
||||
class BeatTrackTest(pmodel_test.MeasuredTrackMixin, pmodel_test.ModelTest):
|
||||
cls = server_impl.BeatTrack
|
||||
create_args = {'name': 'test'}
|
||||
measure_cls = server_impl.BeatMeasure
|
||||
|
||||
def test_pitch(self):
|
||||
track = self.pool.create(self.cls, **self.create_args)
|
||||
|
||||
track.pitch = model.Pitch('F4')
|
||||
self.assertEqual(track.pitch, model.Pitch('F4'))
|
||||
|
||||
|
||||
class BeatMeasureTest(pmodel_test.ModelTest):
|
||||
def test_beats(self):
|
||||
measure = self.pool.create(server_impl.BeatMeasure)
|
||||
|
||||
beat = self.pool.create(server_impl.Beat, time=T0, velocity=100)
|
||||
measure.beats.append(beat)
|
||||
self.assertIs(measure.beats[0], beat)
|
||||
|
||||
|
||||
class BeatTest(pmodel_test.ModelTest):
|
||||
def test_time(self):
|
||||
beat = self.pool.create(server_impl.Beat, time=T0, velocity=100)
|
||||
|
||||
beat.time = audioproc.MusicalDuration(1, 4)
|
||||
self.assertEqual(beat.time, audioproc.MusicalDuration(1, 4))
|
||||
|
||||
def test_velocity(self):
|
||||
beat = self.pool.create(server_impl.Beat, time=T0, velocity=100)
|
||||
|
||||
beat.velocity = 120
|
||||
self.assertEqual(beat.velocity, 120)
|
@ -1,54 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# @begin:license
|
||||
#
|
||||
# Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# @end:license
|
||||
|
||||
from noisicaa import model
|
||||
from .score_track.client_impl import Note, ScoreMeasure, ScoreTrack
|
||||
from .beat_track.client_impl import Beat, BeatMeasure, BeatTrack
|
||||
from .control_track.client_impl import ControlPoint, ControlTrack
|
||||
from .sample_track.client_impl import SampleRef, SampleTrack
|
||||
from .instrument.client_impl import Instrument
|
||||
from .custom_csound.client_impl import CustomCSound, CustomCSoundPort
|
||||
from .midi_source.client_impl import MidiSource
|
||||
from .step_sequencer.client_impl import StepSequencer, StepSequencerChannel, StepSequencerStep
|
||||
from .midi_cc_to_cv.client_impl import MidiCCtoCV, MidiCCtoCVChannel
|
||||
|
||||
|
||||
def register_classes(pool: model.AbstractPool) -> None:
|
||||
pool.register_class(Note)
|
||||
pool.register_class(ScoreMeasure)
|
||||
pool.register_class(ScoreTrack)
|
||||
pool.register_class(Beat)
|
||||
pool.register_class(BeatMeasure)
|
||||
pool.register_class(BeatTrack)
|
||||
pool.register_class(ControlPoint)
|
||||
pool.register_class(ControlTrack)
|
||||
pool.register_class(SampleRef)
|
||||
pool.register_class(SampleTrack)
|
||||
pool.register_class(Instrument)
|
||||
pool.register_class(CustomCSoundPort)
|
||||
pool.register_class(CustomCSound)
|
||||
pool.register_class(MidiSource)
|
||||
pool.register_class(StepSequencer)
|
||||
pool.register_class(StepSequencerChannel)
|
||||
pool.register_class(StepSequencerStep)
|
||||
pool.register_class(MidiCCtoCV)
|
||||
pool.register_class(MidiCCtoCVChannel)
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* @begin:license
|
||||
*
|
||||
* Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* @end:license
|
||||
*/
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
import "noisicaa/music/commands.proto";
|
||||
import "noisicaa/builtin_nodes/score_track/commands.proto";
|
||||
import "noisicaa/builtin_nodes/beat_track/commands.proto";
|
||||
import "noisicaa/builtin_nodes/control_track/commands.proto";
|
||||
import "noisicaa/builtin_nodes/sample_track/commands.proto";
|
||||
import "noisicaa/builtin_nodes/instrument/commands.proto";
|
||||
import "noisicaa/builtin_nodes/custom_csound/commands.proto";
|
||||
import "noisicaa/builtin_nodes/midi_source/commands.proto";
|
||||
import "noisicaa/builtin_nodes/step_sequencer/commands.proto";
|
||||
import "noisicaa/builtin_nodes/midi_cc_to_cv/commands.proto";
|
||||
|
||||
package noisicaa.pb;
|
||||
|
||||
extend Command {
|
||||
// Score track (401xxx)
|
||||
optional UpdateScoreTrack update_score_track = 401000;
|
||||
optional UpdateScoreMeasure update_score_measure = 401001;
|
||||
optional CreateNote create_note = 401002;
|
||||
optional UpdateNote update_note = 401003;
|
||||
optional DeleteNote delete_note = 401004;
|
||||
|
||||
// Beat track (402xxx)
|
||||
optional UpdateBeatTrack update_beat_track = 402000;
|
||||
optional CreateBeat create_beat = 402001;
|
||||
optional UpdateBeat update_beat = 402002;
|
||||
optional DeleteBea |