File: SampleTrackSource.cpp

package info (click to toggle)
audacity 3.2.4%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 106,704 kB
  • sloc: cpp: 277,038; ansic: 73,623; lisp: 7,761; python: 3,305; sh: 2,715; perl: 821; xml: 275; makefile: 119
file content (93 lines) | stat: -rw-r--r-- 2,700 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**********************************************************************

  Audacity: A Digital Audio Editor

  @file SampleTrackSource.cpp

  Dominic Mazzoni
  Vaughan Johnson
  Martyn Shaw

  Paul Licameli split from PerTrackEffect.cpp

*******************************************************************//**

\class PerTrackEffect
\brief Base class for many of the effects in Audacity.

*//*******************************************************************/


#include "SampleTrackSource.h"

#include "AudioGraphBuffers.h"
#include "SampleTrack.h"
#include <cassert>

SampleTrackSource::SampleTrackSource(
   const SampleTrack &left, const SampleTrack *pRight,
   sampleCount start, sampleCount len, Poller pollUser
)  : mLeft{ left }, mpRight{ pRight }, mPollUser{ move(pollUser) }
   , mPos{ start }, mOutputRemaining{ len  }
{
}

SampleTrackSource::~SampleTrackSource() = default;

bool SampleTrackSource::AcceptsBuffers(const Buffers &buffers) const
{
   return mOutputRemaining == 0 || buffers.Channels() > 0;
}

bool SampleTrackSource::AcceptsBlockSize(size_t) const
{
   return true;
}

sampleCount SampleTrackSource::Remaining() const
{
   return std::max<sampleCount>(0, mOutputRemaining);
}

std::optional<size_t> SampleTrackSource::Acquire(Buffers &data, size_t bound)
{
   assert(bound <= data.BlockSize());
   assert(data.BlockSize() <= data.Remaining());
   assert(AcceptsBuffers(data));
   assert(AcceptsBlockSize(data.BlockSize()));

   if (!mInitialized || mFetched < bound) {
      // Need to fill sufficent data in the buffers
      // Calculate the number of samples to get
      const auto fetch =
         limitSampleBufferSize(data.Remaining() - mFetched, Remaining());
      // guarantees write won't overflow
      assert(mFetched + fetch <= data.Remaining());
      // Fill the buffers
      mLeft.GetFloats(&data.GetWritePosition(0) + mFetched, mPos, fetch);
      if (mpRight && data.Channels() > 1)
         mpRight->GetFloats(&data.GetWritePosition(1) + mFetched, mPos, fetch);
      mPos += fetch;
      mFetched += fetch;
      mInitialized = true;
   }
   assert(data.Remaining() > 0);
   auto result = mLastProduced = std::min(bound,
      limitSampleBufferSize(data.Remaining(), Remaining()));
   // assert post
   assert(result <= bound);
   assert(result <= data.Remaining());
   assert(result <= Remaining());
   // true because the three terms of the min would be positive
   assert(bound == 0 || Remaining() == 0 || result > 0);
   return { result };
}

bool SampleTrackSource::Release()
{
   mOutputRemaining -= mLastProduced;
   mFetched -= mLastProduced;
   mLastProduced = 0;
   assert(mOutputRemaining >= 0);
   return !mPollUser || mPollUser(mPos);
}