Beatmup
Beatmup::Audio::SignalFragment::DynamicsLookup Class Reference

Data structure allowing to plot efficiently audio signal graphs. More...

Public Member Functions

 DynamicsLookup ()
 
 ~DynamicsLookup ()
 
void disposeTree ()
 Frees the current level and all previous. More...
 
void configureTree (unsigned char channelCount, int levelCount, int fineStepSize, int coarserStepSize)
 Sets up the tree structure. More...
 
template<typename sample >
void updateTree (const sample *data, int sampleCount)
 Updates tree from raw sample data. More...
 
template<typename sample >
void measure (dtime time0, dtime time1, sample *min, sample *max, const void *data) const
 Measures dynamics from time0 to time1 in each channels separately. More...
 
bool isReady () const
 

Private Member Functions

 DynamicsLookup (const DynamicsLookup &)=delete
 disabling copying constructor More...
 

Private Attributes

DynamicsLookupprev
 previous (finer scale) level More...
 
void * minmax
 (2*size) points per channel, channel-wise multiplexed, interleaved minima and maxima More...
 
unsigned char channelCount
 
int size
 buffer size in points in one channel, i.e., size in bytes is 2*channelCount*sizeof(magnitude)*size More...
 
int step
 step (block) size in points w.r.t. previous layer (points = samples if there's no previous layer) More...
 
int stepTime
 step (block) size in absolute time units More...
 

Detailed Description

Data structure allowing to plot efficiently audio signal graphs.

Definition at line 44 of file signal_fragment.h.

Constructor & Destructor Documentation

◆ DynamicsLookup() [1/2]

Beatmup::Audio::SignalFragment::DynamicsLookup::DynamicsLookup ( const DynamicsLookup )
privatedelete

disabling copying constructor

◆ DynamicsLookup() [2/2]

Beatmup::Audio::SignalFragment::DynamicsLookup::DynamicsLookup ( )
inline

Definition at line 56 of file signal_fragment.h.

56 : prev(nullptr), minmax(nullptr), channelCount(0), size(0), step(0), stepTime(0) {}
int stepTime
step (block) size in absolute time units
DynamicsLookup * prev
previous (finer scale) level
int step
step (block) size in points w.r.t. previous layer (points = samples if there's no previous layer)
int size
buffer size in points in one channel, i.e., size in bytes is 2*channelCount*sizeof(magnitude)*size
void * minmax
(2*size) points per channel, channel-wise multiplexed, interleaved minima and maxima

◆ ~DynamicsLookup()

SignalFragment::DynamicsLookup::~DynamicsLookup ( )

Definition at line 235 of file signal_fragment.cpp.

235  {
236  disposeTree();
237 }
void disposeTree()
Frees the current level and all previous.

Member Function Documentation

◆ disposeTree()

void SignalFragment::DynamicsLookup::disposeTree ( )

Frees the current level and all previous.

Definition at line 53 of file signal_fragment.cpp.

53  {
54  if (prev) {
55  delete prev;
56  prev = nullptr;
57  }
58  if (minmax)
59  free(minmax);
60  size = 0;
61 }

◆ configureTree()

void SignalFragment::DynamicsLookup::configureTree ( unsigned char  channelCount,
int  levelCount,
int  fineStepSize,
int  coarserStepSize 
)

Sets up the tree structure.

Parameters
channelCountNumber of channels
levelCountNumber of detail levels
fineStepSizeThe most detailed level step size in samples
coarserStepSizeSize of step in points for every upper (less detailed) level

Definition at line 64 of file signal_fragment.cpp.

64  {
65  this->channelCount = channelCount;
66  if (levelCount == 1) {
67  // fine level
68  if (prev)
69  delete prev;
70  stepTime = step = fineStepSize;
71  prev = nullptr;
72  }
73  else if (levelCount > 0) {
74  if (!prev)
75  prev = new DynamicsLookup();
76  step = coarserStepSize;
77  prev->configureTree(channelCount, levelCount - 1, fineStepSize, coarserStepSize);
79  }
80 }
void configureTree(unsigned char channelCount, int levelCount, int fineStepSize, int coarserStepSize)
Sets up the tree structure.

◆ updateTree()

template<typename sample >
template void SignalFragment::DynamicsLookup::updateTree ( const sample *  data,
int  sampleCount 
)
inline

Updates tree from raw sample data.

Parameters
dataPointer to the input data
sampleCountNumber of samples pointed by the data in each channel

Definition at line 83 of file signal_fragment.cpp.

83  {
84  // if there is a finer scale ...
85  if (prev) {
86  // ... send sample data to it recursively
88  // update the current level: reallocate table first
89  int newSize = ceili(prev->size, step);
90  if (newSize != size) {
91  minmax = realloc(minmax, newSize * 2 * channelCount * sizeof(sample));
92  size = newSize;
93  }
94  // fill it then
95  sample *out = (sample*)minmax;
96  const int skip = 2 * channelCount;
97  for (int block = 0; block < prev->size; block += step) {
98  const int blockSize = std::min(step, prev->size - block);
99  // channel multiplexing
100  for (int ch = 0; ch < channelCount; ch++) {
101  sample *in = (sample*)prev->minmax + block * skip + 2 * ch, *stop = in + blockSize * skip;
102  sample vMin = in[0], vMax = in[1];
103  in += skip;
104  while (in < stop) {
105  vMin = std::min(vMin, in[0]);
106  vMax = std::max(vMax, in[1]);
107  in += skip;
108  }
109  *(out++) = vMin;
110  *(out++) = vMax;
111  }
112  }
113  }
114  // update finest scale level: reallocate table first
115  else {
116  int newSize = ceili(sampleCount, step);
117  if (newSize != size) {
118  minmax = realloc(minmax, newSize * 2 * channelCount * sizeof(sample));
119  size = newSize;
120  }
121  // fill it then
122  sample *out = (sample*)minmax;
123  for (int time = 0; time < sampleCount; time += step) {
124  const int blockSize = std::min(step, sampleCount - time);
125  const sample *start = data + time * channelCount, *stop = start + blockSize * channelCount;
126  // channel demultiplexing
127  for (int ch = 0; ch < channelCount; ch++) {
128  sample min{ sample::MAX_VALUE }, max{ sample::MIN_VALUE };
130  out[0] = min;
131  out[1] = max;
132  out += 2;
133  }
134  }
135  }
136 }
void updateTree(const sample *data, int sampleCount)
Updates tree from raw sample data.
unsigned char blockSize
size in bytes of a channelwise-multiplexed sample (block containing 1 sample per channel)
int sampleCount
number of samples within this frame
Definition: fragment.h:39
CustomPoint< numeric > min(const CustomPoint< numeric > &a, const CustomPoint< numeric > &b)
Definition: geometry.h:724
CustomPoint< numeric > max(const CustomPoint< numeric > &a, const CustomPoint< numeric > &b)
Definition: geometry.h:728
void measureMultiplexedChannelDynamics(const sample *startSample, const sample *stopSample, const unsigned char stride, sample &min, sample &max)
Measures dynamics from samples for a single channel in a multiplexed stream.
#define ceili(x, y)
integer division x/y with ceiling
Definition: utils.hpp:21
jlong jint start
jlong jlong jint time
JNIEnv jlong jint out

◆ measure()

template<typename sample >
template void SignalFragment::DynamicsLookup::measure ( dtime  time0,
dtime  time1,
sample *  min,
sample *  max,
const void *  data 
) const

Measures dynamics from time0 to time1 in each channels separately.

Parameters
time0Start time
time1Stop time
minChannelwise multiplexed minima
maxChannelwise multiplexed maxima
dataChannelwise multiplexed sample data for a more precise measurement; may be null

Definition at line 144 of file signal_fragment.cpp.

144  {
145  int b0, b1; // bounding block indices
146  // if there is a finer level, take the inset and ask for the remaining parts this finer level
147  if (prev) {
148  b0 = ceili(time0, stepTime);
149  b1 = time1 / stepTime;
150  dtime
151  t0 = b0 * stepTime,
152  t1 = b1 * stepTime;
153  if (t0 >= t1) {
154  // this level is too coarse
155  prev->measure<sample>(time0, time1, min, max, data);
156  return;
157  }
158 
159  if (time0 < t0)
160  prev->measure<sample>(time0, t0, min, max, data);
161  if (t1 < time1)
162  prev->measure<sample>(t1, time1, min, max, data);
163  }
164 
165  // if not, but if there is some sample data, take an inset and measure leftovers using the sample data
166  else if (data) {
167  b0 = ceili(time0, stepTime);
168  b1 = time1 / stepTime;
169  // if there are some blocks (more than one)
170  if (b0 < b1) {
171  dtime
172  t0 = b0 * stepTime,
173  t1 = b1 * stepTime;
174  if (time0 < t0 || t1 < time1) {
175  sample *pMin = min, *pMax = max;
176  for (int ch = 0; ch < channelCount; ch++, pMin++, pMax++) {
177  if (time0 < t0)
179  (sample*)data + time0 * channelCount + ch,
180  (sample*)data + t0 * channelCount + ch,
181  channelCount,
182  *pMin, *pMax
183  );
184  if (t1 < time1)
186  (sample*)data + t1 * channelCount + ch,
187  (sample*)data + time1 * channelCount + ch,
188  channelCount,
189  *pMin, *pMax
190  );
191  }
192  }
193  }
194  // the time borders are both within the same block
195  else {
196  for (int ch = 0; ch < channelCount; ch++, min++, max++)
198  (sample*)data + time0 * channelCount + ch,
199  (sample*)data + time1 * channelCount + ch,
200  channelCount,
201  *min, *max
202  );
203  return;
204  }
205  }
206 
207  // otherwise take the outset
208  else {
209  b0 = time0 / stepTime;
210  b1 = std::max(b0+1, ceili(time1, stepTime));
211  }
212 
213  BEATMUP_ASSERT_DEBUG(b1 <= size);
214 
215  // scan selected block set
216  const int skip = 2 * channelCount;
217  for (int chSkip = 0; chSkip < skip; chSkip += 2) {
218  sample *ptr = (sample*)minmax + skip*b0 + chSkip, *stop = (sample*)minmax + skip*b1 + chSkip;
219  while (ptr < stop) {
220  min->x = std::min(ptr[0].x, min->x);
221  max->x = std::max(ptr[1].x, max->x);
222  ptr += skip;
223  }
224  min++;
225  max++;
226  }
227 }
void measure(dtime time0, dtime time1, sample *min, sample *max, const void *data) const
Measures dynamics from time0 to time1 in each channels separately.
#define BEATMUP_ASSERT_DEBUG(C)
Definition: exception.h:163
int dtime
discrete time
Definition: basic_types.h:37
JNIEnv jlong jint t1
jobject jlong jint x

◆ isReady()

bool Beatmup::Audio::SignalFragment::DynamicsLookup::isReady ( ) const
inline

Definition at line 93 of file signal_fragment.h.

93 { return minmax != NULL; }

Member Data Documentation

◆ prev

DynamicsLookup* Beatmup::Audio::SignalFragment::DynamicsLookup::prev
private

previous (finer scale) level

Definition at line 46 of file signal_fragment.h.

◆ minmax

void* Beatmup::Audio::SignalFragment::DynamicsLookup::minmax
private

(2*size) points per channel, channel-wise multiplexed, interleaved minima and maxima

Definition at line 47 of file signal_fragment.h.

◆ channelCount

unsigned char Beatmup::Audio::SignalFragment::DynamicsLookup::channelCount
private

Definition at line 48 of file signal_fragment.h.

◆ size

int Beatmup::Audio::SignalFragment::DynamicsLookup::size
private

buffer size in points in one channel, i.e., size in bytes is 2*channelCount*sizeof(magnitude)*size

Definition at line 49 of file signal_fragment.h.

◆ step

int Beatmup::Audio::SignalFragment::DynamicsLookup::step
private

step (block) size in points w.r.t. previous layer (points = samples if there's no previous layer)

Definition at line 50 of file signal_fragment.h.

◆ stepTime

int Beatmup::Audio::SignalFragment::DynamicsLookup::stepTime
private

step (block) size in absolute time units

Definition at line 51 of file signal_fragment.h.


The documentation for this class was generated from the following files: