Skip to content

Commit 7ae1528

Browse files
committed
make slicing more robust
1 parent 50c329d commit 7ae1528

File tree

2 files changed

+42
-13
lines changed

2 files changed

+42
-13
lines changed

ReacomaExtension/Algorithms/FlucomaAlgorithmBase.h

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,23 @@ template <typename ClientType> class FlucomaAlgorithm : public IAlgorithm {
3636
bool StartProcessItemAsync(MediaItem *item) override final {
3737

3838
SetMediaItemInfo_Value(item, "C_LOCK", true);
39-
UpdateTimeline();
4039

4140
if (!item || !mApiProvider)
4241
return false;
4342
mIsFinishedFlag = false;
4443
mProgress = 0.0;
4544

4645
MediaItem_Take *take = GetActiveTake(item);
47-
if (!take)
46+
if (!take) {
47+
SetMediaItemInfo_Value(item, "C_LOCK", false);
4848
return false;
49+
}
4950

5051
PCM_source *source = GetMediaItemTake_Source(take);
51-
if (!source)
52+
if (!source) {
53+
SetMediaItemInfo_Value(item, "C_LOCK", false);
5254
return false;
55+
}
5356

5457
const int sampleRate = GetMediaSourceSampleRate(source);
5558
const int numChannels = GetMediaSourceNumChannels(source);
@@ -113,6 +116,8 @@ template <typename ClientType> class FlucomaAlgorithm : public IAlgorithm {
113116
if (!mItemForAsync || item != mItemForAsync)
114117
return false;
115118

119+
SetMediaItemInfo_Value(item, "C_LOCK", false);
120+
116121
bool success = HandleResults(mItemForAsync, mTakeForAsync,
117122
mNumChannelsForAsync, mSampleRateForAsync);
118123

@@ -123,8 +128,6 @@ template <typename ClientType> class FlucomaAlgorithm : public IAlgorithm {
123128
mItemForAsync = nullptr;
124129
mTakeForAsync = nullptr;
125130

126-
SetMediaItemInfo_Value(item, "C_LOCK", false);
127-
128131
if (success) {
129132
UpdateTimeline();
130133
}
@@ -159,8 +162,10 @@ template <typename ClientType> class FlucomaAlgorithm : public IAlgorithm {
159162
return;
160163

161164
double itemPos = GetMediaItemInfo_Value(item, "D_POSITION");
165+
double itemLen = GetMediaItemInfo_Value(item, "D_LENGTH");
162166
double startOffs = GetMediaItemTakeInfo_Value(take, "D_STARTOFFS");
163167
double playrate = GetMediaItemTakeInfo_Value(take, "D_PLAYRATE");
168+
double epsilon = 0.0001; // Avoid splitting at the very start or end
164169

165170
// Collect marker positions (in source time) and convert to project time
166171
std::vector<double> splitPositions;
@@ -171,11 +176,19 @@ template <typename ClientType> class FlucomaAlgorithm : public IAlgorithm {
171176
// project_time = item_position + (marker_source_time -
172177
// take_offset) / playrate
173178
double projectTime = itemPos + (srcPos - startOffs) / playrate;
174-
splitPositions.push_back(projectTime);
179+
180+
// Only split if within item bounds (with small epsilon)
181+
if (projectTime > itemPos + epsilon &&
182+
projectTime < itemPos + itemLen - epsilon) {
183+
splitPositions.push_back(projectTime);
184+
}
175185
}
176186
}
177187

178188
std::sort(splitPositions.begin(), splitPositions.end());
189+
splitPositions.erase(
190+
std::unique(splitPositions.begin(), splitPositions.end()),
191+
splitPositions.end());
179192

180193
// Split from right to left so earlier positions remain valid
181194
for (int i = static_cast<int>(splitPositions.size()) - 1; i >= 0; i--) {
@@ -282,6 +295,8 @@ class AudioOutputAlgorithm : public FlucomaAlgorithm<ClientType> {
282295
GetSetMediaItemTakeInfo(newTake, "P_SOURCE", newSource);
283296
GetSetMediaItemTakeInfo(newTake, "P_NAME",
284297
(char *)takeName.c_str());
298+
double zero = 0.0;
299+
GetSetMediaItemTakeInfo(newTake, "D_STARTOFFS", &zero);
285300
}
286301
}
287302
}

ReacomaExtension/Algorithms/SlicingAlgorithm.h

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,19 @@ class SlicingAlgorithm : public FlucomaAlgorithm<ClientType> {
4141
DeleteTakeMarker(take, i);
4242

4343
double itemLength = GetMediaItemInfo_Value(item, "D_LENGTH");
44+
double takeOffset = GetMediaItemTakeInfo_Value(take, "D_STARTOFFS");
45+
double playrate = GetMediaItemTakeInfo_Value(take, "D_PLAYRATE");
46+
double maxSourceTime = itemLength * playrate;
47+
4448
auto view = reader.samps(0);
4549
for (fluid::index i = 0; i < view.size(); i++) {
46-
if (view(i) > 0) {
47-
double markerTimeInSeconds =
50+
if (view(i) >= 0) {
51+
double timeInSeconds =
4852
static_cast<double>(view(i)) / sampleRate;
49-
if (markerTimeInSeconds < itemLength)
50-
SetTakeMarker(take, -1, "", &markerTimeInSeconds, nullptr);
53+
if (timeInSeconds < maxSourceTime) {
54+
double srcPos = takeOffset + timeInSeconds;
55+
SetTakeMarker(take, -1, "", &srcPos, nullptr);
56+
}
5157
}
5258
}
5359
}
@@ -64,6 +70,10 @@ class SlicingAlgorithm : public FlucomaAlgorithm<ClientType> {
6470

6571
double itemPos = GetMediaItemInfo_Value(item, "D_POSITION");
6672
double itemLen = GetMediaItemInfo_Value(item, "D_LENGTH");
73+
MediaItem_Take *take = GetActiveTake(item);
74+
double playrate =
75+
take ? GetMediaItemTakeInfo_Value(take, "D_PLAYRATE") : 1.0;
76+
double maxSourceTime = itemLen * playrate;
6777

6878
auto view = reader.samps(0);
6979
std::vector<double> sliceTimes;
@@ -74,11 +84,15 @@ class SlicingAlgorithm : public FlucomaAlgorithm<ClientType> {
7484

7585
// Collect all slice points and convert from samples to seconds
7686
for (fluid::index i = 0; i < view.size(); i++) {
77-
if (view(i) > 0) {
87+
if (view(i) >= 0) {
7888
double timeInSeconds =
7989
static_cast<double>(view(i)) / sampleRate;
80-
if (timeInSeconds < itemLen)
81-
sliceTimes.push_back(timeInSeconds);
90+
if (timeInSeconds < maxSourceTime) {
91+
// Convert source time relative to start of buffer to
92+
// project time relative to item start
93+
double projectTimeRelative = timeInSeconds / playrate;
94+
sliceTimes.push_back(projectTimeRelative);
95+
}
8296
}
8397
}
8498

0 commit comments

Comments
 (0)