ProcessOne() takes a track, transforms it to bunch of buffer-blocks, and executes ProcessSoundTouch on these blocks
| 170 | //ProcessOne() takes a track, transforms it to bunch of buffer-blocks, |
| 171 | //and executes ProcessSoundTouch on these blocks |
| 172 | bool SoundTouchBase::ProcessOne(soundtouch::SoundTouch *pSoundTouch, |
| 173 | WaveChannel &orig, WaveTrack &out, |
| 174 | sampleCount start, sampleCount end, |
| 175 | const TimeWarper &warper) |
| 176 | { |
| 177 | // ProcessStereo handles the stereo case instead. This is a precondition |
| 178 | // for Append: |
| 179 | assert(out.NChannels() == 1); |
| 180 | |
| 181 | pSoundTouch->setSampleRate( |
| 182 | static_cast<unsigned int>((orig.GetRate() + 0.5))); |
| 183 | |
| 184 | //Get the length of the buffer (as double). len is |
| 185 | //used simple to calculate a progress meter, so it is easier |
| 186 | //to make it a double now than it is to do it later |
| 187 | auto len = (end - start).as_double(); |
| 188 | |
| 189 | { |
| 190 | //Initiate a processing buffer. This buffer will (most likely) |
| 191 | //be shorter than the length of the track being processed. |
| 192 | Floats buffer{ orig.GetMaxBlockSize() }; |
| 193 | |
| 194 | //Go through the track one buffer at a time. s counts which |
| 195 | //sample the current buffer starts at. |
| 196 | auto s = start; |
| 197 | while (s < end) { |
| 198 | //Get a block of samples (smaller than the size of the buffer) |
| 199 | const auto block = std::min<size_t>(8192, |
| 200 | limitSampleBufferSize(orig.GetBestBlockSize(s), end - s)); |
| 201 | |
| 202 | //Get the samples from the track and put them in the buffer |
| 203 | orig.GetFloats(buffer.get(), s, block); |
| 204 | |
| 205 | //Add samples to SoundTouch |
| 206 | pSoundTouch->putSamples(buffer.get(), block); |
| 207 | |
| 208 | //Get back samples from SoundTouch |
| 209 | unsigned int outputCount = pSoundTouch->numSamples(); |
| 210 | if (outputCount > 0) { |
| 211 | Floats buffer2{ outputCount }; |
| 212 | pSoundTouch->receiveSamples(buffer2.get(), outputCount); |
| 213 | out.Append(0, (samplePtr)buffer2.get(), floatSample, outputCount); |
| 214 | } |
| 215 | |
| 216 | //Increment s one blockfull of samples |
| 217 | s += block; |
| 218 | |
| 219 | //Update the Progress meter |
| 220 | if (TrackProgress(mCurTrackNum, (s - start).as_double() / len)) |
| 221 | return false; |
| 222 | } |
| 223 | |
| 224 | // Tell SoundTouch to finish processing any remaining samples |
| 225 | pSoundTouch->flush(); // this should only be used for changeTempo - it dumps data otherwise with pRateTransposer->clear(); |
| 226 | |
| 227 | unsigned int outputCount = pSoundTouch->numSamples(); |
| 228 | if (outputCount > 0) { |
| 229 | Floats buffer2{ outputCount }; |
nothing calls this directly
no test coverage detected