| 173 | } |
| 174 | |
| 175 | float AudioParamTimeline::valuesForTimeRangeImpl( |
| 176 | double startTime, |
| 177 | double endTime, |
| 178 | float defaultValue, |
| 179 | float * values, |
| 180 | size_t numberOfValues, |
| 181 | double sampleRate, |
| 182 | double controlRate) |
| 183 | { |
| 184 | if (!values) |
| 185 | return defaultValue; |
| 186 | |
| 187 | // Return default value if there are no events matching the desired time range. |
| 188 | std::unique_lock<std::mutex> lock(m_eventsMutex, std::try_to_lock); |
| 189 | if (!lock.owns_lock() || !m_events.size() || endTime <= m_events[0].time()) |
| 190 | { |
| 191 | for (unsigned i = 0; i < numberOfValues; ++i) |
| 192 | values[i] = defaultValue; |
| 193 | return defaultValue; |
| 194 | } |
| 195 | |
| 196 | // Maintain a running time and index for writing the values buffer. |
| 197 | double currentTime = startTime; |
| 198 | unsigned writeIndex = 0; |
| 199 | |
| 200 | // If first event is after startTime then fill initial part of values buffer with defaultValue |
| 201 | // until we reach the first event time. |
| 202 | double firstEventTime = m_events[0].time(); |
| 203 | if (firstEventTime > startTime) |
| 204 | { |
| 205 | double fillToTime = std::min(endTime, firstEventTime); |
| 206 | size_t fillToFrame = AudioUtilities::timeToSampleFrame(fillToTime - startTime, sampleRate); |
| 207 | fillToFrame = std::min(fillToFrame, numberOfValues); |
| 208 | for (; writeIndex < fillToFrame; ++writeIndex) |
| 209 | values[writeIndex] = defaultValue; |
| 210 | |
| 211 | currentTime = fillToTime; |
| 212 | } |
| 213 | |
| 214 | float value = defaultValue; |
| 215 | |
| 216 | // Go through each event and render the value buffer where the times overlap, |
| 217 | // stopping when we've rendered all the requested values. |
| 218 | // FIXME: could try to optimize by avoiding having to iterate starting from the very first event |
| 219 | // and keeping track of a "current" event index. |
| 220 | int n = static_cast<int>(m_events.size()); |
| 221 | for (int i = 0; i < n && writeIndex < numberOfValues; ++i) |
| 222 | { |
| 223 | ParamEvent & event = m_events[i]; |
| 224 | ParamEvent * nextEvent = i < n - 1 ? &(m_events[i + 1]) : 0; |
| 225 | |
| 226 | // Wait until we get a more recent event. |
| 227 | if (nextEvent && nextEvent->time() < currentTime) |
| 228 | continue; |
| 229 | |
| 230 | float value1 = event.value(); |
| 231 | double time1 = event.time(); |
| 232 | float value2 = nextEvent ? nextEvent->value() : value1; |
nothing calls this directly
no test coverage detected