Skip to content

Commit 8b04590

Browse files
committed
libxwax: Exchange the static delayline with a generic ringbuffer
This ringbuffer is more versatile and can also be used for later filter implementations.
1 parent aecc34e commit 8b04590

8 files changed

Lines changed: 174 additions & 153 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5157,7 +5157,7 @@ if(VINYLCONTROL)
51575157
lib/xwax/lut.c
51585158
lib/xwax/lut_mk2.c
51595159
lib/xwax/filters.c
5160-
lib/xwax/delayline.c
5160+
lib/xwax/ringbuffer.c
51615161
lib/xwax/pitch_kalman.c
51625162
)
51635163
target_include_directories(mixxx-xwax SYSTEM PUBLIC lib/xwax)

lib/xwax/delayline.c

Lines changed: 0 additions & 115 deletions
This file was deleted.

lib/xwax/delayline.h

Lines changed: 0 additions & 21 deletions
This file was deleted.

lib/xwax/ringbuffer.c

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#include <errno.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <string.h>
5+
6+
#include "ringbuffer.h"
7+
8+
/*
9+
* Allocates the ringbuffer
10+
*/
11+
12+
struct ringbuffer *rb_alloc(size_t size, size_t elem_size)
13+
{
14+
if (!size || !elem_size) {
15+
errno = EINVAL;
16+
perror(__func__);
17+
return NULL;
18+
}
19+
20+
struct ringbuffer *rb = malloc(sizeof(struct ringbuffer));
21+
if (!rb)
22+
goto error;
23+
24+
rb->size = size;
25+
rb->elem_size = elem_size;
26+
rb->current = size - 1;
27+
28+
rb->data = calloc(size, elem_size);
29+
if (!rb->data)
30+
goto error_data;
31+
32+
return rb;
33+
34+
error_data:
35+
free(rb);
36+
error:
37+
perror(__func__);
38+
39+
return NULL;
40+
}
41+
42+
/*
43+
* Initializes the ringbuffer
44+
*/
45+
46+
void rb_destroy(struct ringbuffer *rb)
47+
{
48+
if (!rb)
49+
return;
50+
51+
if (rb->data) {
52+
rb_reset(rb);
53+
free(rb->data);
54+
rb->data = NULL;
55+
}
56+
57+
free(rb);
58+
rb = NULL;
59+
}
60+
61+
/*
62+
* Gets the sample at index i in the ringbuffer
63+
*/
64+
65+
void *rb_at(const struct ringbuffer *rb, ptrdiff_t i)
66+
{
67+
if (!rb || !rb->data || rb->size == 0) {
68+
errno = EINVAL;
69+
perror(__func__);
70+
return NULL;
71+
}
72+
73+
ptrdiff_t index = (rb->current + i) % rb->size;
74+
if (index < 0)
75+
index += rb->size;
76+
77+
/* Offset from the start in bytes: index * sizeof(element) */
78+
79+
return (char *)rb->data + index * rb->elem_size;
80+
}
81+
82+
/*
83+
* Decrements the ringbuffer pointer
84+
*/
85+
86+
static inline void rb_dec(struct ringbuffer *rb)
87+
{
88+
if (!rb || rb->size == 0) {
89+
errno = EINVAL;
90+
perror(__func__);
91+
return;
92+
}
93+
94+
rb->current--;
95+
if (rb->current < 0)
96+
rb->current += rb->size;
97+
}
98+
99+
/*
100+
* Pushes a new sample to the ringbuffer
101+
*/
102+
103+
void rb_push(struct ringbuffer *rb, const void *elem)
104+
{
105+
if (!rb || !rb->data) {
106+
errno = EINVAL;
107+
perror(__func__);
108+
return;
109+
}
110+
111+
rb_dec(rb);
112+
113+
/* Compute the destination pointer as an offset in bytes from the start of the buffer */
114+
115+
memcpy((char *)rb->data + rb->current * rb->elem_size, elem, rb->elem_size);
116+
}
117+
118+
/*
119+
* Fills the ringbuffer data with zeros and resets the pointer
120+
*/
121+
122+
void rb_reset(struct ringbuffer *rb)
123+
{
124+
if (!rb || !rb->data) {
125+
errno = EINVAL;
126+
perror(__func__);
127+
return;
128+
}
129+
130+
rb->current = rb->size - 1;
131+
memset(rb->data, 0, rb->size * rb->elem_size);
132+
}

lib/xwax/ringbuffer.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef RINGBUFFER_H
2+
3+
#define RINGBUFFER_H
4+
5+
#include <stddef.h>
6+
7+
struct ringbuffer {
8+
size_t size;
9+
size_t elem_size;
10+
void *data;
11+
ptrdiff_t current;
12+
};
13+
14+
struct ringbuffer *rb_alloc(size_t size, size_t elem_size);
15+
void rb_destroy(struct ringbuffer *rb);
16+
void rb_reset(struct ringbuffer *rb);
17+
18+
void *rb_at(const struct ringbuffer *rb, ptrdiff_t i);
19+
void rb_push(struct ringbuffer *rb, const void *elem);
20+
21+
#endif /* end of include guard RINGBUFFER_H */

lib/xwax/timecoder.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,9 @@ void mk2_subcode_init(struct mk2_subcode *sc)
380380
sc->avg_slope = INT_MAX/2;
381381
sc->bit = U128_ZERO;
382382

383-
delayline_init(&sc->readings);
383+
sc->readings = rb_alloc(5, sizeof(int));
384+
assert(sc->readings);
385+
384386

385387
/* Initialise smoothing filters */
386388
ema_init(&sc->ema_reading, 0.01);
@@ -397,7 +399,8 @@ static void init_mk2_channel(struct timecoder_channel *ch)
397399
ch->mk2.rms = INT_MAX/2;
398400
ch->mk2.rms_deriv = 0;
399401

400-
delayline_init(&ch->mk2.delayline);
402+
ch->mk2.delayline = rb_alloc(5, sizeof(int));
403+
assert(ch->mk2.delayline );
401404

402405
ema_init(&ch->mk2.ema_filter, 3e-1);
403406
derivative_init(&ch->mk2.differentiator);
@@ -495,10 +498,10 @@ void timecoder_clear(struct timecoder *tc)
495498
assert(tc->mon == NULL);
496499

497500
if (tc->def->flags & TRAKTOR_MK2) {
498-
delayline_init(&tc->primary.mk2.delayline);
499-
delayline_init(&tc->secondary.mk2.delayline);
500-
delayline_init(&tc->upper_bitstream.readings);
501-
delayline_init(&tc->lower_bitstream.readings);
501+
rb_destroy(tc->primary.mk2.delayline);
502+
rb_destroy(tc->secondary.mk2.delayline);
503+
rb_destroy(tc->upper_bitstream.readings);
504+
rb_destroy(tc->lower_bitstream.readings);
502505
}
503506
}
504507

@@ -783,7 +786,7 @@ static void process_sample(struct timecoder *tc,
783786
if (tc->def->flags & TRAKTOR_MK2) {
784787
if (tc->secondary.swapped)
785788
{
786-
int reading = *delayline_at(&tc->secondary.mk2.delayline, 3);
789+
int reading = *(int*)rb_at(tc->secondary.mk2.delayline, 3);
787790
mk2_process_timecode(tc, reading);
788791
}
789792
} else {

lib/xwax/timecoder.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include "lut_mk2.h"
2828
#include "pitch.h"
2929
#include "pitch_kalman.h"
30-
#include "delayline.h"
30+
#include "ringbuffer.h"
3131

3232
#define TIMECODER_CHANNELS 2
3333

@@ -58,7 +58,7 @@ struct timecoder_channel_mk2 {
5858
int rms, rms_deriv; /* RMS values for the signal and its derivative */
5959
signed int deriv, deriv_scaled; /* Derivative and its scaled version */
6060

61-
struct delayline delayline; /* needed for the Traktor MK2 demodulation */
61+
struct ringbuffer *delayline; /* needed for the Traktor MK2 demodulation */
6262
struct ema_filter ema_filter;
6363
struct differentiator differentiator;
6464
struct root_mean_square rms_filter, rms_deriv_filter;
@@ -83,7 +83,7 @@ struct mk2_subcode {
8383
signed int avg_slope;
8484
bool recent_bit_flip;
8585

86-
struct delayline readings;
86+
struct ringbuffer *readings;
8787
struct ema_filter ema_reading;
8888
struct ema_filter ema_slope;
8989
};

0 commit comments

Comments
 (0)