Audacity 3.2.0
ClipTimeAndPitchSource.cpp
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*!********************************************************************
3
4 Audacity: A Digital Audio Editor
5
6 ClipTimeAndPitchSource.cpp
7
8 Matthieu Hodgkinson
9
10**********************************************************************/
11
13#include "ClipInterface.h"
14
15
16#include <cassert>
17
18namespace
19{
21 const ClipInterface& clip, double durationToDiscard,
22 PlaybackDirection direction)
23{
24 if (direction == PlaybackDirection::forward)
25 return sampleCount {
26 clip.GetRate() * durationToDiscard / clip.GetStretchRatio() + .5
27 };
28 else
29 return clip.GetVisibleSampleCount() - sampleCount {
30 clip.GetRate() * durationToDiscard / clip.GetStretchRatio() + .5
31 };
32}
33} // namespace
34
36 const ClipInterface& clip, double durationToDiscard,
37 PlaybackDirection direction)
38 : mClip { clip }
39 , mLastReadSample { GetLastReadSample(clip, durationToDiscard, direction) }
40 , mPlaybackDirection { direction }
41{
42}
43
45 float* const* buffers, size_t samplesPerChannel)
46{
48 const auto remainingSamplesInClip =
51 const auto numSamplesToRead =
52 limitSampleBufferSize(samplesPerChannel, remainingSamplesInClip);
53 if (numSamplesToRead > 0u)
54 {
55 constexpr auto mayThrow = false;
56 const auto start =
57 forward ? mLastReadSample : mLastReadSample - numSamplesToRead;
58 const auto nChannels = mClip.NChannels();
59 ChannelSampleViews newViews;
60 for (auto i = 0u; i < nChannels; ++i)
61 {
62 auto channelView = mClip.GetSampleView(i, start, numSamplesToRead);
63 // Query `samplesPerChannel` samples ; `AudioSegmentSampleView::Copy`
64 // will zero from `numSamplesToRead` to `samplesPerChannel` if needed.
65 channelView.Copy(buffers[i], samplesPerChannel);
66 newViews.push_back(std::move(channelView));
67 if (!forward)
69 reinterpret_cast<samplePtr>(buffers[i]), floatSample, 0,
70 numSamplesToRead);
71 }
72 mChannelSampleViews = std::move(newViews);
74 forward ?
75 sampleCount { numSamplesToRead } :
76 // Cast to `sampleCount` before negating ;
77 // on x86, size_t is 32 bits, but sampleCount will store it as 64
78 // bits. Result : -1 becomes 2^32-1 and adding it to mLastReadSample
79 // will not overflow, which is actually wanted in that case to
80 // become a reasonably small value again :)
81 -sampleCount { numSamplesToRead };
82 }
83 else
84 {
85 for (auto i = 0u; i < mClip.NChannels(); ++i)
86 std::fill(buffers[i], buffers[i] + samplesPerChannel, 0.f);
87 }
88}
89
91{
92 return mClip.NChannels();
93}
std::vector< AudioSegmentSampleView > ChannelSampleViews
PlaybackDirection
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:22
void ReverseSamples(samplePtr dst, sampleFormat format, int start, int len)
char * samplePtr
Definition: SampleFormat.h:57
void Copy(float *buffer, size_t bufferSize) const
Copies up to GetSampleCount() or bufferSize samples, whichever is less, into buffer....
virtual size_t NChannels() const =0
virtual AudioSegmentSampleView GetSampleView(size_t iChannel, sampleCount start, size_t length, bool mayThrow=true) const =0
ChannelSampleViews mChannelSampleViews
const PlaybackDirection mPlaybackDirection
ClipTimeAndPitchSource(const ClipInterface &, double durationToDiscard, PlaybackDirection)
const ClipInterface & mClip
void Pull(float *const *, size_t samplesPerChannel) override
virtual int GetRate() const =0
virtual double GetStretchRatio() const =0
virtual sampleCount GetVisibleSampleCount() const =0
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
sampleCount GetLastReadSample(const ClipInterface &clip, double durationToDiscard, PlaybackDirection direction)