Beatmup
sequence.h
Go to the documentation of this file.
1 /*
2  Beatmup image and signal processing library
3  Copyright (C) 2019, lnstadrum
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 #include "../basic_types.h"
21 #include "fragment.h"
22 #include "../exception.h"
23 #include <vector>
24 
25 namespace Beatmup {
26  namespace Fragments {
27 
28  /**
29  Fragmented signal in time domain.
30  Implements basic editing operations (copy, paste, cut in two, shrink, etc.).
31  Operations are performed on the set of fragments, but not directly to the signal content in memory.
32  */
33  class Sequence : public Object {
34  protected:
35  /**
36  Points to a position within a sequence
37  */
38  class Pointer {
39  private:
40  bool writing; //!< if `true`, the pointer is used to modify the data
41  bool watching; //!< if `true`, the pointer will remain valid even if the sequence is being modified
44 
45  protected:
47  FragmentPtr pointer; //!< pointed fragment
49  ~Pointer();
50 
51  public:
52  /**
53  Sets pointer to a specific time
54  \param time The time (in samples) to set the pointer to
55  */
56  void moveTo(dtime time);
57 
58  /**
59  Moves the pointer forward an arbitrary number of samples
60  */
61  void step();
62 
63  /**
64  Enables "watching mode", i.e., if the sequence is modified, the pointer will follow the modifications and remain valid
65  */
66  void watch();
67 
68  /**
69  Moves the pointer by a given number of samples relatively to the current position
70  */
71  inline void jump(dtime by) { moveTo(currentTime + by); }
72 
73  inline dtime getTime() const { return currentTime; }
74  inline bool hasData() const { return !pointer.isNull(); }
75  inline int samplesAvailable() const { return pointer.length; }
76  };
77 
78  private:
79  std::vector<FragmentPtr> fragments; //!< the content
80  std::vector<dtime> cumTimes; //!< cumulative sum of fragment lengths, starts from 0, of N+1 entries (N = num. of fragments)
81  std::vector<Pointer*> pointers; //!< pointers currently accessing the sequence
82 
83  /**
84  Log search for a fragment containing given time moment
85  \return a valid fragment index if available, VOID_LEFT or VOID_RIGHT otherwise
86  */
87  int findFragment(dtime time) const;
88 
89  /**
90  Splits a given fragment in two. Does not recompute the cumulative time index.
91  \param index the fragment index
92  \param delta additional offset w.r.t. fragment internal offset specifying where to split
93  */
94  void splitFragment(int index, dtime delta);
95 
96  static const int
97  VOID_LEFT = -123, //!< returned by getFragment() when the entire sequence is on the right of the given time moment
98  VOID_RIGHT = -456; //!< returned by getFragment() when the entire sequence is on the left of the given time moment
99 
100  protected:
102  virtual ~Sequence();
103 
104  /**
105  Initializes an empty sequence, used to bootstrap copying operations.
106  */
107  virtual Sequence* createEmpty() const = 0;
108 
109  /**
110  Adds a new fragment at the end of the sequence
111  */
112  void concatenate(Fragment& fragment, dtime offset, dtime length);
113 
114  /**
115  Resets pointers once the sequence changes to keep them consistent
116  */
117  void syncPointers();
118 
119  public:
120  /**
121  Returns sequence duration in number of samples
122  */
123  inline const dtime getDuration() const { return cumTimes.back(); }
124 
125  /**
126  Returns `true` if sequence contains no samples
127  */
128  inline bool isEmpty() const { return getDuration() == 0; }
129 
130  /**
131  Removes the content of the sequence making it empty (of zero duration).
132  */
133  void clear();
134 
135  /**
136  Shrinks the sequence to given time bounds
137  \param timeLeft Left limit to shrink to (included), i.e., the earliest time moment from which the new (shrinked) sequence will begin
138  \param timeRight Right limit to shrink to (excluded)
139  */
140  void shrink(dtime timeLeft, dtime timeRight);
141 
142  /**
143  Copies a given piece of the current sequence into new Sequence
144  \param fromTime The beginning of the piece to copy (included in the resulting sequence)
145  \param toTime The end of the piece (excluded from the resulting sequence)
146  */
147  Sequence* copy(dtime fromTime, dtime toTime) const;
148 
149  /**
150  Inserts a Sequence at a given position in time
151  \param sequence The sequence to insert
152  \param time The time to insert from
153  */
154  void insert(const Sequence& sequence, dtime time);
155 
156  /**
157  Erases a part of the sequence between two given time moments
158  \param fromTime The beginning of the part to remove
159  \param toTime The end of the part to remove
160  */
161  void remove(dtime fromTime, dtime toTime);
162 
163  /**
164  Splits the sequence in two at a specific time.
165  Creates two new Sequence instances. The content of the current sequence remains unchanged.
166  \param time The time moment to cut at
167  \param left The left part of the split
168  \param right The right part of the split
169  */
170  void split(dtime time, Sequence* left, Sequence* right) const;
171 
172  class AccessException : public Exception {
173  public:
174  AccessException(const char* message, const Sequence& sequence) : Exception(message) {}
175  };
176  };
177 
178 
179  template<class T> class SequenceToolkit : public Sequence {
180  public:
181  T* copy(dtime fromTime, dtime toTime) const { return static_cast<T*>(Sequence::copy(fromTime, toTime)); }
182  };
183  }
184 }
Base class for all exceptions.
Definition: exception.h:37
std::string message
Definition: exception.h:39
Represents a continuous set of data samples.
Definition: fragment.h:31
T * copy(dtime fromTime, dtime toTime) const
Definition: sequence.h:181
AccessException(const char *message, const Sequence &sequence)
Definition: sequence.h:174
Points to a position within a sequence.
Definition: sequence.h:38
void moveTo(dtime time)
Sets pointer to a specific time.
Definition: sequence.cpp:361
FragmentPtr pointer
pointed fragment
Definition: sequence.h:47
void jump(dtime by)
Moves the pointer by a given number of samples relatively to the current position.
Definition: sequence.h:71
void watch()
Enables "watching mode", i.e., if the sequence is modified, the pointer will follow the modifications...
Definition: sequence.cpp:391
Pointer(Sequence &sequence, dtime time, bool writing)
Definition: sequence.cpp:339
void step()
Moves the pointer forward an arbitrary number of samples.
Definition: sequence.cpp:377
bool writing
if true, the pointer is used to modify the data
Definition: sequence.h:40
bool watching
if true, the pointer will remain valid even if the sequence is being modified
Definition: sequence.h:41
Fragmented signal in time domain.
Definition: sequence.h:33
std::vector< Pointer * > pointers
pointers currently accessing the sequence
Definition: sequence.h:81
int findFragment(dtime time) const
Log search for a fragment containing given time moment.
void remove(dtime fromTime, dtime toTime)
Erases a part of the sequence between two given time moments.
void shrink(dtime timeLeft, dtime timeRight)
Shrinks the sequence to given time bounds.
const dtime getDuration() const
Returns sequence duration in number of samples.
Definition: sequence.h:123
static const int VOID_RIGHT
returned by getFragment() when the entire sequence is on the left of the given time moment
Definition: sequence.h:98
void splitFragment(int index, dtime delta)
Splits a given fragment in two.
void split(dtime time, Sequence *left, Sequence *right) const
Splits the sequence in two at a specific time.
std::vector< dtime > cumTimes
cumulative sum of fragment lengths, starts from 0, of N+1 entries (N = num. of fragments)
Definition: sequence.h:80
virtual Sequence * createEmpty() const =0
Initializes an empty sequence, used to bootstrap copying operations.
void syncPointers()
Resets pointers once the sequence changes to keep them consistent.
void concatenate(Fragment &fragment, dtime offset, dtime length)
Adds a new fragment at the end of the sequence.
void clear()
Removes the content of the sequence making it empty (of zero duration).
bool isEmpty() const
Returns true if sequence contains no samples.
Definition: sequence.h:128
std::vector< FragmentPtr > fragments
the content
Definition: sequence.h:79
static const int VOID_LEFT
returned by getFragment() when the entire sequence is on the right of the given time moment
Definition: sequence.h:97
void insert(const Sequence &sequence, dtime time)
Inserts a Sequence at a given position in time.
Sequence * copy(dtime fromTime, dtime toTime) const
Copies a given piece of the current sequence into new Sequence.
Beatmup object base class
Definition: basic_types.h:67
int dtime
discrete time
Definition: basic_types.h:37
Pointer to a Fragment.
Definition: fragment.h:67
int length
number of samples to use from the fragment
Definition: fragment.h:71
JNIEnv jobject jint jint jint jfloat fragment
jlong jint index
jlong jlong jint time
jlong jlong jint jint jint jint jint left