| 114 | } |
| 115 | |
| 116 | bool AudioNodeScheduler::update(ContextRenderLock & r, int epoch_length) |
| 117 | { |
| 118 | uint64_t proposed_epoch = r.context()->currentSampleFrame(); |
| 119 | if (_epoch >= proposed_epoch) |
| 120 | return false; |
| 121 | |
| 122 | _epoch = proposed_epoch; |
| 123 | _renderOffset = 0; |
| 124 | _renderLength = epoch_length; |
| 125 | |
| 126 | switch (_playbackState) |
| 127 | { |
| 128 | case SchedulingState::UNSCHEDULED: |
| 129 | break; |
| 130 | |
| 131 | case SchedulingState::SCHEDULED: |
| 132 | // start has been called, start looking for the start time |
| 133 | if (_startWhen <= _epoch) |
| 134 | { |
| 135 | // exactly on start, or late, get going straight away |
| 136 | _renderOffset = 0; |
| 137 | _renderLength = epoch_length; |
| 138 | _playbackState = SchedulingState::FADE_IN; |
| 139 | ASN_PRINT("fade in\n"); |
| 140 | } |
| 141 | else if (_startWhen < _epoch + epoch_length) |
| 142 | { |
| 143 | // start falls within the frame |
| 144 | _renderOffset = static_cast<int>(_startWhen - _epoch); |
| 145 | _renderLength = epoch_length - _renderOffset; |
| 146 | _playbackState = SchedulingState::FADE_IN; |
| 147 | ASN_PRINT("fade in\n"); |
| 148 | } |
| 149 | |
| 150 | /// @TODO the case of a start and stop within one epoch needs to be special |
| 151 | /// cased, to fit this current architecture, there'd be a FADE_IN_OUT scheduling |
| 152 | /// state so that the envelope can be correctly applied. |
| 153 | // FADE_IN_OUT would transition to UNSCHEDULED. |
| 154 | break; |
| 155 | |
| 156 | case SchedulingState::FADE_IN: |
| 157 | // start time has been achieved, there'll be one quantum with fade in applied. |
| 158 | _renderOffset = 0; |
| 159 | _playbackState = SchedulingState::PLAYING; |
| 160 | ASN_PRINT("playing\n"); |
| 161 | // fall through to PLAYING to allow render length to be adjusted if stop-start is less than one quantum length |
| 162 | |
| 163 | case SchedulingState::PLAYING: |
| 164 | /// @TODO include the end envelope in the stop check so that a scheduled stop that |
| 165 | /// spans this quantum and the next ends in the current quantum |
| 166 | |
| 167 | if (_stopWhen <= _epoch) |
| 168 | { |
| 169 | // exactly on start, or late, stop straight away, render a whole frame of fade out |
| 170 | _renderLength = epoch_length - _renderOffset; |
| 171 | _playbackState = SchedulingState::STOPPING; |
| 172 | ASN_PRINT("stopping\n"); |
| 173 | } |
no test coverage detected