| 40 | } |
| 41 | |
| 42 | void Get(sampleCount &startSample, sampleCount &endSample, |
| 43 | sampleCount inDuration, sampleCount &duration) |
| 44 | { |
| 45 | // Called by the thread that calls AudioIO::SequenceBufferExchange |
| 46 | startSample = endSample = duration = -1LL; |
| 47 | sampleCount s0Init; |
| 48 | |
| 49 | Message message( mMessage.Read() ); |
| 50 | if ( !mStarted ) { |
| 51 | s0Init = llrint( mRate * |
| 52 | std::max( message.options.minTime, |
| 53 | std::min( message.options.maxTime, mStartTime ) ) ); |
| 54 | |
| 55 | // Make some initial silence. This is not needed in the case of |
| 56 | // keyboard scrubbing or play-at-speed, because the initial speed |
| 57 | // is known when this function is called the first time. |
| 58 | if ( !(message.options.isKeyboardScrubbing) ) { |
| 59 | mData.mS0 = mData.mS1 = s0Init; |
| 60 | mData.mGoal = -1; |
| 61 | mData.mDuration = duration = inDuration; |
| 62 | mData.mSilence = 0; |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | if (mStarted || message.options.isKeyboardScrubbing) { |
| 67 | Data newData; |
| 68 | inDuration += mAccumulatedSeekDuration; |
| 69 | |
| 70 | // If already started, use the previous end as NEW start. |
| 71 | const auto s0 = mStarted ? mData.mS1 : s0Init; |
| 72 | const sampleCount s1 ( message.options.bySpeed |
| 73 | ? s0.as_double() + |
| 74 | lrint(inDuration.as_double() * message.end) // end is a speed |
| 75 | : lrint(message.end * mRate) // end is a time |
| 76 | ); |
| 77 | auto success = |
| 78 | newData.Init(mData, s0, s1, inDuration, message.options, mRate); |
| 79 | if (success) |
| 80 | mAccumulatedSeekDuration = 0; |
| 81 | else { |
| 82 | mAccumulatedSeekDuration += inDuration; |
| 83 | return; |
| 84 | } |
| 85 | mData = newData; |
| 86 | }; |
| 87 | |
| 88 | mStarted = true; |
| 89 | |
| 90 | Data &entry = mData; |
| 91 | if ( mStopped.load( std::memory_order_relaxed ) ) { |
| 92 | // We got the shut-down signal, or we discarded all the work. |
| 93 | // Output the -1 values. |
| 94 | } |
| 95 | else if (entry.mDuration > 0) { |
| 96 | // First use of the entry |
| 97 | startSample = entry.mS0; |
| 98 | endSample = entry.mS1; |
| 99 | duration = entry.mDuration; |