class_docstr: Transition model for note transcription with a HMM.
  
  Parameters
  ----------
  state_space : :class:`ADSRStateSpace` instance
      ADSRStateSpace which maps state numbers to states.
  onset_prob : float, optional
      Probability to enter/stay in the attack and decay phase. When entering
      this phase from a previously sounding note, this probability will be
      divided by the sum of `onset_prob`, `note_prob`, and `offset_prob`.
  note_prob : float, optional
      Probability to enter the sustain phase. Notes can stay in the sustain
      phase given by this probability divided by the sum of `onset_prob`,
      `note_prob`, and `offset_prob`.
  offset_prob : float, optional
      Probability to enter/stay in the release phase.
  end_prob : float, optional
      Probability to go back from release to silence.
code: def __init__(
      self,
      state_space,
      onset_prob=0.8,
      note_prob=0.8,
      offset_prob=0.2,
      end_prob=1.0,
  ):
      # save attributes
      self.state_space = state_space
      # states
      silence = state_space.silence
      attack = state_space.attack
      decay = state_space.decay
      sustain = state_space.sustain
      release = state_space.release
      # transitions = [(from_state, to_state, prob), ...]
      # onset phase & min_onset_length
      t = [
          (silence, silence, 1.0 - onset_prob),
          (silence, attack, onset_prob),
      ]
      for s in range(attack, decay):
          t.append((s, silence, 1.0 - onset_prob))
          t.append((s, s + 1, onset_prob))
      # transition to note & min_note_duration
      for s in range(decay, sustain):
          t.append((s, silence, 1.0 - note_prob))
          t.append((s, s + 1, note_prob))
      # 3 possibilities to continue note
      prob_sum = onset_prob + note_prob + offset_prob
      # 1) sustain note (keep sounding)
      t.append((sustain, sustain, note_prob / prob_sum))
      # 2) new note
      t.append((sustain, attack, onset_prob / prob_sum))
      # 3) release note (end note)
      t.append((sustain, sustain + 1, offset_prob / prob_sum))
      # release phase
      for s in range(sustain + 1, release):
          t.append((s, sustain, offset_prob))
          t.append((s, s + 1, 1.0 - offset_prob))
      # after releasing a note, go back to silence or start new note
      t.append((release, silence, end_prob))
      t.append((release, release, 1.0 - end_prob))
      t = np.array(t)
      # make the transitions sparse
      t = self.make_sparse(
          t[:, 1].astype(int), t[:, 0].astype(int), t[:, 2]
      )
      # instantiate a TransitionModel
      super(ADSRTransitionModel, self).__init__(*t)
  
file_path: madmom/madmom/features/notes_hmm.py
imports: from __future__ import absolute_import, division, print_function
  import numpy
  from madmom.ml.hmm import TransitionModel, ObservationModel
label_desc: Use image node_id 1 to create a new ADSRTransitionModel object from inherited base classes: TransitionModel with example: obj = ADSRTransitionModel(state_space, onset_prob, note_prob, offset_prob, end_prob)