Skip to content

Commit bf1c305

Browse files
committed
refactor(memory): unify track analysis architecture, fix SIGSEGV, and optimize for low-end devices
1 parent c1902d9 commit bf1c305

13 files changed

Lines changed: 330 additions & 248 deletions

File tree

src/core/logger.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -419,12 +419,13 @@ void Log_LogDeviceInfo(const char* gpuModel) {
419419
#elif defined(__ANDROID__) || defined(__linux__)
420420
struct sysinfo si;
421421
if (sysinfo(&si) == 0) {
422-
totalRAM = (float)(si.totalram * si.mem_unit) / (1024.0f * 1024.0f);
423-
freeRAM = (float)(si.freeram * si.mem_unit) / (1024.0f * 1024.0f);
422+
totalRAM = (float)((uint64_t)si.totalram * si.mem_unit) / (1024.0f * 1024.0f);
423+
freeRAM = (float)((uint64_t)si.freeram * si.mem_unit) / (1024.0f * 1024.0f);
424424
}
425425
#endif
426-
UNX_LOG_INFO("Total RAM : %.0f MB", totalRAM);
427-
UNX_LOG_INFO("Free RAM : %.0f MB %s", freeRAM, (freeRAM < 256.0f) ? "(CRITICAL: Low Memory)" : "");
426+
UNX_LOG_INFO("Total RAM : %.0f MB (%.2f GB)", totalRAM, totalRAM / 1024.0f);
427+
float freePercent = (totalRAM > 0) ? (freeRAM / totalRAM) * 100.0f : 0;
428+
UNX_LOG_INFO("Free RAM : %.0f MB (%.1f%%) %s", freeRAM, freePercent, (freeRAM < 256.0f) ? "!!! LOW MEMORY !!!" : "");
428429

429430
// Display
430431
UNX_LOG_INFO("Display : %dx%d @ %dHz", GetScreenWidth(), GetScreenHeight(), GetMonitorRefreshRate(GetCurrentMonitor()));
@@ -483,10 +484,10 @@ float Log_GetRAMUsage(void) {
483484
// Linux fallback via /proc/self/statm
484485
FILE* f = fopen("/proc/self/statm", "r");
485486
if (f) {
486-
long pages;
487-
if (fscanf(f, "%ld", &pages) == 1) {
487+
long total_pages, rss_pages;
488+
if (fscanf(f, "%ld %ld", &total_pages, &rss_pages) == 2) {
488489
fclose(f);
489-
return (float)(pages * sysconf(_SC_PAGESIZE)) / (1024.0f * 1024.0f);
490+
return (float)((uint64_t)rss_pages * sysconf(_SC_PAGESIZE)) / (1024.0f * 1024.0f);
490491
}
491492
fclose(f);
492493
}

src/core/logic/quantize.c

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
#include <math.h>
44

55
int64_t Quantize_GetNearestBeatMs(TrackState *track, int64_t currentMs) {
6-
if (!track || track->BeatGridCount == 0 || !track->BeatGrid) return currentMs;
6+
if (!track || track->Analysis.BeatGridCount == 0 || !track->Analysis.BeatGrid) return currentMs;
77

88
// Find closest beat in BeatGrid array
9-
int64_t closestBeatMs = (int64_t)track->BeatGrid[0].Time;
9+
int64_t closestBeatMs = (int64_t)track->Analysis.BeatGrid[0].Time;
1010
int64_t minDiff = llabs(currentMs - closestBeatMs);
1111

12-
for (int i = 1; i < track->BeatGridCount; i++) {
13-
int64_t diff = llabs(currentMs - (int64_t)track->BeatGrid[i].Time);
12+
for (int i = 1; i < track->Analysis.BeatGridCount; i++) {
13+
int64_t diff = llabs(currentMs - (int64_t)track->Analysis.BeatGrid[i].Time);
1414
if (diff < minDiff) {
1515
minDiff = diff;
16-
closestBeatMs = (int64_t)track->BeatGrid[i].Time;
16+
closestBeatMs = (int64_t)track->Analysis.BeatGrid[i].Time;
1717
} else if (diff > minDiff) {
1818
// Since BeatGrid is sorted, distance starts increasing after we pass the minimum
1919
break;
@@ -24,30 +24,30 @@ int64_t Quantize_GetNearestBeatMs(TrackState *track, int64_t currentMs) {
2424
}
2525

2626
int32_t Quantize_GetPhaseErrorMs(TrackState *track, int64_t currentMs) {
27-
if (!track || track->BeatGridCount == 0 || !track->BeatGrid) return 0;
27+
if (!track || track->Analysis.BeatGridCount == 0 || !track->Analysis.BeatGrid) return 0;
2828
int64_t nearest = Quantize_GetNearestBeatMs(track, currentMs);
2929
return (int32_t)(currentMs - nearest);
3030
}
3131

3232
int32_t Quantize_GetWaitMs(TrackState *track, int64_t currentMs) {
33-
if (!track || track->BeatGridCount == 0 || !track->BeatGrid) return 0;
33+
if (!track || track->Analysis.BeatGridCount == 0 || !track->Analysis.BeatGrid) return 0;
3434

3535
// Look forward for the *next* or *current* beat grid marker
36-
for (int i = 0; i < track->BeatGridCount; i++) {
37-
if ((int64_t)track->BeatGrid[i].Time >= currentMs) {
38-
return (int32_t)((int64_t)track->BeatGrid[i].Time - currentMs);
36+
for (int i = 0; i < track->Analysis.BeatGridCount; i++) {
37+
if ((int64_t)track->Analysis.BeatGrid[i].Time >= currentMs) {
38+
return (int32_t)((int64_t)track->Analysis.BeatGrid[i].Time - currentMs);
3939
}
4040
}
4141
return 0; // If past end of grids, don't wait
4242
}
4343

4444
double Quantize_GetBeatDistance(TrackState *track, int64_t currentMs) {
45-
if (!track || track->BeatGridCount < 2 || !track->BeatGrid) return 0.0;
45+
if (!track || track->Analysis.BeatGridCount < 2 || !track->Analysis.BeatGrid) return 0.0;
4646

47-
for (int i = 0; i < track->BeatGridCount - 1; i++) {
48-
if (currentMs >= (int64_t)track->BeatGrid[i].Time && currentMs < (int64_t)track->BeatGrid[i+1].Time) {
49-
int64_t beatStart = (int64_t)track->BeatGrid[i].Time;
50-
int64_t beatEnd = (int64_t)track->BeatGrid[i+1].Time;
47+
for (int i = 0; i < track->Analysis.BeatGridCount - 1; i++) {
48+
if (currentMs >= (int64_t)track->Analysis.BeatGrid[i].Time && currentMs < (int64_t)track->Analysis.BeatGrid[i+1].Time) {
49+
int64_t beatStart = (int64_t)track->Analysis.BeatGrid[i].Time;
50+
int64_t beatEnd = (int64_t)track->Analysis.BeatGrid[i+1].Time;
5151
int64_t beatLen = beatEnd - beatStart;
5252
if (beatLen == 0) return 0.0;
5353
return (double)(currentMs - beatStart) / (double)beatLen;
@@ -57,22 +57,23 @@ double Quantize_GetBeatDistance(TrackState *track, int64_t currentMs) {
5757
}
5858

5959
int Quantize_GetCurrentBeat(TrackState *track, int64_t currentMs) {
60-
if (!track || track->BeatGridCount == 0 || !track->BeatGrid) return 1;
61-
for (int i = 0; i < track->BeatGridCount; i++) {
62-
if ((int64_t)track->BeatGrid[i].Time > currentMs) {
63-
if (i == 0) return track->BeatGrid[0].BeatNumber;
64-
return track->BeatGrid[i - 1].BeatNumber;
60+
if (!track || track->Analysis.BeatGridCount == 0 || !track->Analysis.BeatGrid) return 1;
61+
for (int i = 0; i < track->Analysis.BeatGridCount; i++) {
62+
if ((int64_t)track->Analysis.BeatGrid[i].Time > currentMs) {
63+
if (i == 0) return track->Analysis.BeatGrid[0].BeatNumber;
64+
return track->Analysis.BeatGrid[i - 1].BeatNumber;
6565
}
6666
}
67-
return track->BeatGrid[track->BeatGridCount - 1].BeatNumber;
67+
return track->Analysis.BeatGrid[track->Analysis.BeatGridCount - 1].BeatNumber;
6868
}
6969

7070
float Quantize_GetBeatFXLengthMs(TrackState *track, float targetRatio) {
71-
if (!track || track->BeatGridCount < 2 || !track->BeatGrid) return 0.0f;
71+
if (!track || track->Analysis.BeatGridCount < 2 || !track->Analysis.BeatGrid) return 0.0f;
7272

7373
// Calculate average ms per beat from the grid
74-
int count = track->BeatGridCount;
75-
float avgBeatLength = (float)(track->BeatGrid[count - 1].Time - track->BeatGrid[0].Time) / (float)(count - 1);
74+
int count = track->Analysis.BeatGridCount;
75+
if (count < 2) return 0.0f;
76+
float avgBeatLength = (float)(track->Analysis.BeatGrid[count - 1].Time - track->Analysis.BeatGrid[0].Time) / (float)(count - 1);
7677

7778
// Fallback if there is an error
7879
if (avgBeatLength <= 0.0f) return 0.0f;

src/core/logic/sync.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ void Sync_Update(DeckState *deckA, DeckState *deckB, AudioEngine *audioEngine) {
7878
// We need the current beat length to convert fraction to ms
7979
uint32_t fCurrentMs = follower->PositionMs;
8080
uint32_t fBeatLen = 500; // Default fallback (120 BPM)
81-
for (int i = 0; i < follower->LoadedTrack->BeatGridCount - 1; i++) {
82-
if (fCurrentMs >= follower->LoadedTrack->BeatGrid[i].Time &&
83-
fCurrentMs < follower->LoadedTrack->BeatGrid[i+1].Time) {
84-
fBeatLen = follower->LoadedTrack->BeatGrid[i+1].Time - follower->LoadedTrack->BeatGrid[i].Time;
81+
for (int i = 0; i < follower->LoadedTrack->Analysis.BeatGridCount - 1; i++) {
82+
if (fCurrentMs >= follower->LoadedTrack->Analysis.BeatGrid[i].Time &&
83+
fCurrentMs < follower->LoadedTrack->Analysis.BeatGrid[i+1].Time) {
84+
fBeatLen = follower->LoadedTrack->Analysis.BeatGrid[i+1].Time - follower->LoadedTrack->Analysis.BeatGrid[i].Time;
8585
break;
8686
}
8787
}
@@ -151,18 +151,18 @@ void Sync_RequestPhaseSnap(DeckState *follower, DeckState *master, AudioEngine *
151151
uint32_t beatEnd = 0;
152152

153153
// Find the beat segment the follower is currently in
154-
for (int i = 0; i < fTrack->BeatGridCount - 1; i++) {
155-
if (currentMs >= fTrack->BeatGrid[i].Time && currentMs < fTrack->BeatGrid[i+1].Time) {
156-
beatStart = fTrack->BeatGrid[i].Time;
157-
beatEnd = fTrack->BeatGrid[i+1].Time;
154+
for (int i = 0; i < fTrack->Analysis.BeatGridCount - 1; i++) {
155+
if (currentMs >= fTrack->Analysis.BeatGrid[i].Time && currentMs < fTrack->Analysis.BeatGrid[i+1].Time) {
156+
beatStart = fTrack->Analysis.BeatGrid[i].Time;
157+
beatEnd = fTrack->Analysis.BeatGrid[i+1].Time;
158158
break;
159159
}
160160
}
161161

162162
// Fallback if not found (e.g. at the very start or end)
163-
if (beatEnd == 0 && fTrack->BeatGridCount >= 2) {
164-
beatStart = fTrack->BeatGrid[0].Time;
165-
beatEnd = fTrack->BeatGrid[1].Time;
163+
if (beatEnd == 0 && fTrack->Analysis.BeatGridCount >= 2) {
164+
beatStart = fTrack->Analysis.BeatGrid[0].Time;
165+
beatEnd = fTrack->Analysis.BeatGrid[1].Time;
166166
}
167167

168168
if (beatEnd > beatStart) {

0 commit comments

Comments
 (0)