Skip to content

Commit 1dc05a9

Browse files
author
Hannes Barfuss
committedJan 19, 2022
first draft of compressed delay buffer - working, but at the moment even more inefficient than original ;)
1 parent 3b59e26 commit 1dc05a9

File tree

2 files changed

+94
-14
lines changed

2 files changed

+94
-14
lines changed
 

‎SoundStageNative/CompressedRingBuffer.cpp

+94-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,97 @@
55
// Created by hb on 19.01.22.
66
//
77

8-
#include "CompressedRingBuffer.hpp"
8+
#include "CompressedRingBuffer.h"
9+
#include "util.h"
10+
#include <string.h>
11+
#include <assert.h>
12+
#include <math.h>
13+
14+
/* bc this needs oversampling factor x backtracking, it is just as inefficient as the original Ringbuffer_WritePadded function :( */
15+
void CompressedRingBuffer_Read(float *dest, int n, int offset, float stride, CompressedRingBuffer *x)
16+
{
17+
/* Find starting point */
18+
assert(offset <= 0);
19+
assert(stride > 0);
20+
21+
int ptr = x->ptr;
22+
float o = 0;
23+
float vStride;
24+
while(o > offset)
25+
{
26+
ptr -= 1;
27+
if(ptr < 0)
28+
ptr = x->n - 1;
29+
vStride = x->weights[ptr] / stride; //example: a sample that has been written with a stride of 4 (x->weights) but is now read with a stride of 1, needs to be copied 4 times, therefore it advances the offset by 4 samples. In a delay, this results in audio stretching / lower pitch.
30+
o -= vStride;
31+
}
32+
//Take into account that we may have to start in the middle of x->data[ptr]; or in other words, for the first physical sample, we do not necessarily have to read weights[ptr] virtual samples:
33+
vStride = stride / x->weights[ptr]; //Note that this time it is the other way round.
34+
float fPtr = ptr + fabs(o - offset) * vStride; //abs(o-offset) is the number of samples we do not want to copy. vStride is the advancement of the fPtr when copying 1 sample.
35+
ptr = (int)(fPtr + 0.5f) % x->n;
36+
37+
for(int i = 0; i < n; i++)
38+
{
39+
dest[i] = x->data[ptr];
40+
vStride = stride / x->weights[ptr]; //Note that this time it is the other way round.
41+
fPtr += vStride;
42+
ptr = (int)(fPtr + 0.5f) % x->n;
43+
}
44+
}
45+
46+
void CompressedRingBuffer_Write(float *src, int n, float stride, CompressedRingBuffer *x)
47+
{
48+
assert(stride > 0);
49+
50+
if(n > x->n)
51+
{
52+
src = src + (n - x->n);
53+
n = x->n;
54+
}
55+
int n1 = _min( x->n - x->ptr, n);
56+
memcpy(x->data + x->ptr, src, n1*sizeof(float));
57+
for(int i = 0; i < n1; i++)
58+
x->weights[x->ptr + i] = stride;
59+
x->ptr = (x->ptr + n1) % x->n;
60+
if(n1 < n)
61+
{
62+
int n2 = n - n1;
63+
memcpy(x->data, src + n1, n2*sizeof(float));
64+
for(int i = 0; i < n2; i++)
65+
x->weights[i] = stride;
66+
x->ptr = (x->ptr + n2) % x->n;
67+
}
68+
}
69+
70+
void CompressedRingBuffer_Print(CompressedRingBuffer *x)
71+
{
72+
printv("================= \n");
73+
printv("CompressedRingBuffer: \n");
74+
for(int i = 0; i < x->n; i++)
75+
{
76+
printv("%d: %f (weight: %f)\n", i, x->data[i], x->weights[i]);
77+
}
78+
printv("================= \n");
79+
}
80+
81+
CompressedRingBuffer *CompressedRingBuffer_New(int n)
82+
{
83+
CompressedRingBuffer *x = (CompressedRingBuffer*)_malloc(sizeof(CompressedRingBuffer));
84+
85+
x->data = (float*)_malloc(n * sizeof(float));
86+
x->weights = (float*)_malloc(n * sizeof(float));
87+
_fZero(x->data, n);
88+
for(int i = 0; i < n; i++)
89+
x->weights[i] = 1;
90+
x->ptr = 0;
91+
x->n = n;
92+
93+
return x;
94+
}
95+
96+
void CompressedRingBuffer_Free(CompressedRingBuffer *x)
97+
{
98+
_free(x->data);
99+
_free(x->weights);
100+
_free(x);
101+
}

‎SoundStageNative/CompressedRingBuffer.hpp

-13
This file was deleted.

0 commit comments

Comments
 (0)