You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

song.py 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. # Copyright (c) 2018 Anki, Inc.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License in the file LICENSE.txt or at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. '''
  15. Song related classes, functions, events and values.
  16. '''
  17. # __all__ should order by constants, event classes, other classes, functions.
  18. __all__ = ['NoteTypes', 'NoteDurations', 'SongNote']
  19. import collections
  20. from . import logger
  21. from . import action
  22. from . import exceptions
  23. from . import event
  24. from ._clad import _clad_to_engine_iface, _clad_to_engine_cozmo, _clad_to_engine_anki, CladEnumWrapper
  25. # generate names for each CLAD defined Note Type
  26. class _NoteType(collections.namedtuple('_NoteType', 'name id')):
  27. # Tuple mapping between CLAD SongNoteType. name and ID
  28. # All instances will be members of NoteTypes
  29. # Keep _NoteType as lightweight as a normal namedtuple
  30. __slots__ = ()
  31. def __str__(self):
  32. return 'NoteTypes.%s' % self.name
  33. class NoteTypes(CladEnumWrapper):
  34. """The possible values for an NoteType.
  35. A pitch between C2 and C3_Sharp can be specified,
  36. as well as a rest (for timed silence), giving
  37. cozmo a vocal range of slightly more than one
  38. octave.
  39. B_Flat and E_Flat are represented as their corresponding
  40. sharps.
  41. """
  42. _clad_enum = _clad_to_engine_iface.SongNoteType
  43. _entry_type = _NoteType
  44. #:
  45. C2 = _entry_type("C2", _clad_enum.C2)
  46. #:
  47. C2_Sharp = _entry_type("C2_Sharp", _clad_enum.C2_Sharp)
  48. #:
  49. D2 = _entry_type("D2", _clad_enum.D2)
  50. #:
  51. D2_Sharp = _entry_type("D2_Sharp", _clad_enum.D2_Sharp)
  52. #:
  53. E2 = _entry_type("E2", _clad_enum.E2)
  54. #:
  55. F2 = _entry_type("F2", _clad_enum.F2)
  56. #:
  57. F2_Sharp = _entry_type("F2_Sharp", _clad_enum.F2_Sharp)
  58. #:
  59. G2 = _entry_type("G2", _clad_enum.G2)
  60. #:
  61. G2_Sharp = _entry_type("G2_Sharp", _clad_enum.G2_Sharp)
  62. #:
  63. A2 = _entry_type("A2", _clad_enum.A2)
  64. #:
  65. A2_Sharp = _entry_type("A2_Sharp", _clad_enum.A2_Sharp)
  66. #:
  67. B2 = _entry_type("B2", _clad_enum.B2)
  68. #:
  69. C3 = _entry_type("C3", _clad_enum.C3)
  70. #:
  71. C3_Sharp = _entry_type("C3_Sharp", _clad_enum.C3_Sharp)
  72. #:
  73. Rest = _entry_type("Rest", _clad_enum.Rest)
  74. NoteTypes._init_class(warn_on_missing_definitions=True)
  75. # generate names for each CLAD defined Note Duration
  76. class _NoteDuration(collections.namedtuple('_NoteDuration', 'name id')):
  77. # Tuple mapping between CLAD SongNoteDuration. name and ID
  78. # All instances will be members of NoteTypes
  79. # Keep _NoteDuration as lightweight as a normal namedtuple
  80. __slots__ = ()
  81. def __str__(self):
  82. return 'NoteDurations.%s' % self.name
  83. class NoteDurations(CladEnumWrapper):
  84. """The possible values for a NoteDuration.
  85. """
  86. _clad_enum = _clad_to_engine_iface.SongNoteDuration
  87. _entry_type = _NoteDuration
  88. #:
  89. Whole = _entry_type("Whole", _clad_enum.Whole)
  90. #:
  91. ThreeQuarter = _entry_type("ThreeQuarter", _clad_enum.ThreeQuarter)
  92. #:
  93. Half = _entry_type("Half", _clad_enum.Half)
  94. #:
  95. Quarter = _entry_type("Quarter", _clad_enum.Quarter)
  96. NoteDurations._init_class(warn_on_missing_definitions=True)
  97. class SongNote(_clad_to_engine_iface.SongNote):
  98. """Represents on element in a song. Consists of a :class:`cozmo.song.NoteTypes` which specifies
  99. either a pitch or rest, and a :class:`cozmo.song.NoteDurations` specifying the length of the
  100. note.
  101. """
  102. def __init__(self, noteType=NoteTypes.C2, noteDuration=NoteDurations.Whole):
  103. super(SongNote, self).__init__(noteType.id, noteDuration.id)