History

jack: adjust ringbuffer size to target latency

koukuno committed 5 years ago

Commit 91d9a0a1 parent 34aa1a53 files · +42 −26Browse files

Unified · Split

3 files
  1. Receivers/unix/jack.c +40 −24
  2. Receivers/unix/jack.h +1 −1
  3. Receivers/unix/scream.c +1 −1
Receivers/unix/jack.c+40−24
@@ -12,25 +12,45 @@ · 11 unmodified lines
1212
1313 #include "jack.h"
1414
15+// from the Bit Twiddling hacks
16+static inline jack_nframes_t round_nframes_to_power_of_two(jack_nframes_t x)
17+{
18+ x--;
19+ x |= x >> 1;
20+ x |= x >> 2;
21+ x |= x >> 4;
22+ x |= x >> 8;
23+ x |= x >> 16;
24+ x++;
25+ return x;
26+}
1527
28+static jack_nframes_t usec_to_nframes(int rate, int sample_size, int channels, int time_usec)
29+{
30+ // this number can be larger than UINT32_MAX
31+ uint64_t x = time_usec*(uint64_t)rate;
32+ return round_nframes_to_power_of_two((jack_nframes_t)(x/1000000)*((sample_size/8)*channels));
33+}
1634
1735 typedef jack_default_audio_sample_t ringbuffer_element_t;
18−#define RINGBUFFER_SIZE 8192
1936 struct ringbuffer_t
2037 {
21− ringbuffer_element_t elements[RINGBUFFER_SIZE];
38+ ringbuffer_element_t *elements;
39+ uint32_t total_size;
2240 uint32_t read_pos;
2341 uint32_t write_pos;
2442 };
2543
2644
27−uint32_t ringbuffer_mask(uint32_t val)
45+uint32_t ringbuffer_mask(uint32_t size, uint32_t val)
2846 {
29− return val & (RINGBUFFER_SIZE - 1u);
47+ return val & (size - 1u);
3048 }
3149
32−void ringbuffer_init(struct ringbuffer_t *rb)
50+void ringbuffer_init(struct ringbuffer_t *rb, uint32_t size)
3351 {
52+ rb->elements = calloc(sizeof(ringbuffer_element_t), size);
53+ rb->total_size = size;
3454 rb->read_pos = 0u;
3555 rb->write_pos = 0u;
3656 }
@@ -47,34 +67,23 @@ int ringbuffer_empty(struct ringbuffer_t *rb) · 10 unmodified lines
4767
4868 int ringbuffer_full(struct ringbuffer_t *rb)
4969 {
50− return ringbuffer_size(rb) == RINGBUFFER_SIZE;
70+ return ringbuffer_size(rb) == rb->total_size;
5171 }
5272
5373 void ringbuffer_push(struct ringbuffer_t *rb, ringbuffer_element_t val)
5474 {
5575 if (!ringbuffer_full(rb))
5676 {
57− rb->elements[ringbuffer_mask(rb->write_pos++)] = val;
77+ rb->elements[ringbuffer_mask(rb->total_size, rb->write_pos++)] = val;
5878 }
59− else
60− {
61− fprintf(stderr, "ringbuffer overflow\n");
62− }
63−
6479 }
6580
6681 ringbuffer_element_t ringbuffer_pop(struct ringbuffer_t *rb)
6782 {
6883 if (!ringbuffer_empty(rb))
6984 {
70− return rb->elements[ringbuffer_mask(rb->read_pos++)];
71− }
72− else
73− {
74− fprintf(stderr, "ringbuffer underflow\n");
75− return (ringbuffer_element_t)0;
85+ return rb->elements[ringbuffer_mask(rb->total_size, rb->read_pos++)];
7686 }
77−
7887 }
7988
8089
@@ -89,6 +98,7 @@ static struct jack_output_data · 8 unmodified lines
8998 jack_default_audio_sample_t *resample_buffer;
9099 size_t resample_buffer_size;
91100 struct ringbuffer_t rb;
101+ int latency;
92102 }
93103 jo_data;
94104
@@ -104,7 +114,7 @@ int jack_process(jack_nframes_t nframes, void *arg); · 9 unmodified lines
104114
105115
106116
107−int jack_output_init(char *stream_name)
117+int jack_output_init(int latency, char *stream_name)
108118 {
109119 jack_status_t status;
110120
@@ -117,9 +127,8 @@ int jack_output_init(char *stream_name) · 6 unmodified lines
117127 jo_data.soxr = NULL;
118128 jo_data.resample_buffer = NULL;
119129 jo_data.resample_buffer_size = 0;
120−
121− ringbuffer_init(&jo_data.rb);
122−
130+ jo_data.latency = latency;
131+ jo_data.rb.elements = NULL;
123132
124133 jo_data.client = jack_client_open(stream_name, JackNullOption, &status, NULL);
125134 if (jo_data.client == NULL)
@@ -177,7 +186,6 @@ int jack_output_send(receiver_data_t *data) · 51 unmodified lines
177186 }
178187
179188
180−
181189 if (jack_deactivate(jo_data.client))
182190 {
183191 fprintf(stderr, "cannot deactivate client");
@@ -200,6 +208,14 @@ int jack_output_send(receiver_data_t *data) · 16 unmodified lines
200208 {
201209 return 1;
202210 }
211+
212+ if (jo_data.rb.elements != NULL)
213+ free(jo_data.rb.elements);
214+
215+ jack_nframes_t nframes = usec_to_nframes(jo_data.sample_rate, jo_data.receiver_format.sample_size, jo_data.receiver_format.channels, jo_data.latency*1000);
216+
217+ printf("initializing ringbuffer with size: %u\n", nframes);
218+ ringbuffer_init(&jo_data.rb, nframes);
203219 }
204220
205221
Receivers/unix/jack.h+1−1
@@ -3,7 +3,7 @@ · 2 unmodified lines
33
44 #include "scream.h"
55
6−int jack_output_init(char *stream_name);
6+int jack_output_init(int latency, char *stream_name);
77 int jack_output_send(receiver_data_t *data);
88
99 #endif
Receivers/unix/scream.c+1−1
@@ -237,7 +237,7 @@ int main(int argc, char*argv[]) { · 236 unmodified lines
237237 case Jack:
238238 #if JACK_ENABLE
239239 if (verbosity) fprintf(stderr, "Using JACK output\n");
240− if (jack_output_init(jack_client_name) != 0) {
240+ if (jack_output_init(target_latency_ms, jack_client_name) != 0) {
241241 return 1;
242242 }
243243 output_send_fn = jack_output_send;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t