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
12 12
13#include "jack.h"13#include "jack.h"
14 14
15// from the Bit Twiddling hacks
16static 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}
15 27
28static 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}
16 34
17typedef jack_default_audio_sample_t ringbuffer_element_t;35typedef jack_default_audio_sample_t ringbuffer_element_t;
18#define RINGBUFFER_SIZE 8192
19struct ringbuffer_t36struct ringbuffer_t
20{37{
21 ringbuffer_element_t elements[RINGBUFFER_SIZE];38 ringbuffer_element_t *elements;
39 uint32_t total_size;
22 uint32_t read_pos;40 uint32_t read_pos;
23 uint32_t write_pos;41 uint32_t write_pos;
24};42};
25 43
26 44
27uint32_t ringbuffer_mask(uint32_t val)45uint32_t ringbuffer_mask(uint32_t size, uint32_t val)
28{46{
29 return val & (RINGBUFFER_SIZE - 1u);47 return val & (size - 1u);
30}48}
31 49
32void ringbuffer_init(struct ringbuffer_t *rb)50void ringbuffer_init(struct ringbuffer_t *rb, uint32_t size)
33{51{
52 rb->elements = calloc(sizeof(ringbuffer_element_t), size);
53 rb->total_size = size;
34 rb->read_pos = 0u;54 rb->read_pos = 0u;
35 rb->write_pos = 0u;55 rb->write_pos = 0u;
36}56}
@@ -47,34 +67,23 @@ int ringbuffer_empty(struct ringbuffer_t *rb) · 10 unmodified lines
47 67
48int ringbuffer_full(struct ringbuffer_t *rb)68int ringbuffer_full(struct ringbuffer_t *rb)
49{69{
50 return ringbuffer_size(rb) == RINGBUFFER_SIZE;70 return ringbuffer_size(rb) == rb->total_size;
51}71}
52 72
53void ringbuffer_push(struct ringbuffer_t *rb, ringbuffer_element_t val)73void ringbuffer_push(struct ringbuffer_t *rb, ringbuffer_element_t val)
54{74{
55 if (!ringbuffer_full(rb))75 if (!ringbuffer_full(rb))
56 {76 {
57 rb->elements[ringbuffer_mask(rb->write_pos++)] = val;77 rb->elements[ringbuffer_mask(rb->total_size, rb->write_pos++)] = val;
58 }78 }
59 else
60 {
61 fprintf(stderr, "ringbuffer overflow\n");
62 }
63
64}79}
65 80
66ringbuffer_element_t ringbuffer_pop(struct ringbuffer_t *rb)81ringbuffer_element_t ringbuffer_pop(struct ringbuffer_t *rb)
67{82{
68 if (!ringbuffer_empty(rb))83 if (!ringbuffer_empty(rb))
69 {84 {
70 return rb->elements[ringbuffer_mask(rb->read_pos++)];85 return rb->elements[ringbuffer_mask(rb->total_size, rb->read_pos++)];
71 }
72 else
73 {
74 fprintf(stderr, "ringbuffer underflow\n");
75 return (ringbuffer_element_t)0;
76 }86 }
77
78}87}
79 88
80 89
@@ -89,6 +98,7 @@ static struct jack_output_data · 8 unmodified lines
89 jack_default_audio_sample_t *resample_buffer;98 jack_default_audio_sample_t *resample_buffer;
90 size_t resample_buffer_size;99 size_t resample_buffer_size;
91 struct ringbuffer_t rb;100 struct ringbuffer_t rb;
101 int latency;
92}102}
93jo_data;103jo_data;
94 104
@@ -104,7 +114,7 @@ int jack_process(jack_nframes_t nframes, void *arg); · 9 unmodified lines
104 114
105 115
106 116
107int jack_output_init(char *stream_name)117int jack_output_init(int latency, char *stream_name)
108{118{
109 jack_status_t status;119 jack_status_t status;
110 120
@@ -117,9 +127,8 @@ int jack_output_init(char *stream_name) · 6 unmodified lines
117 jo_data.soxr = NULL;127 jo_data.soxr = NULL;
118 jo_data.resample_buffer = NULL;128 jo_data.resample_buffer = NULL;
119 jo_data.resample_buffer_size = 0;129 jo_data.resample_buffer_size = 0;
120 130 jo_data.latency = latency;
121 ringbuffer_init(&jo_data.rb);131 jo_data.rb.elements = NULL;
122
123 132
124 jo_data.client = jack_client_open(stream_name, JackNullOption, &status, NULL);133 jo_data.client = jack_client_open(stream_name, JackNullOption, &status, NULL);
125 if (jo_data.client == NULL)134 if (jo_data.client == NULL)
@@ -177,7 +186,6 @@ int jack_output_send(receiver_data_t *data) · 51 unmodified lines
177 }186 }
178 187
179 188
180
181 if (jack_deactivate(jo_data.client))189 if (jack_deactivate(jo_data.client))
182 {190 {
183 fprintf(stderr, "cannot deactivate client");191 fprintf(stderr, "cannot deactivate client");
@@ -200,6 +208,14 @@ int jack_output_send(receiver_data_t *data) · 16 unmodified lines
200 {208 {
201 return 1;209 return 1;
202 }210 }
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);
203 }219 }
204 220
205 221
Receivers/unix/jack.h+1−1
@@ -3,7 +3,7 @@ · 2 unmodified lines
3 3
4#include "scream.h"4#include "scream.h"
5 5
6int jack_output_init(char *stream_name);6int jack_output_init(int latency, char *stream_name);
7int jack_output_send(receiver_data_t *data);7int jack_output_send(receiver_data_t *data);
8 8
9#endif9#endif
Receivers/unix/scream.c+1−1
@@ -237,7 +237,7 @@ int main(int argc, char*argv[]) { · 236 unmodified lines
237 case Jack:237 case Jack:
238#if JACK_ENABLE238#if JACK_ENABLE
239 if (verbosity) fprintf(stderr, "Using JACK output\n");239 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) {
241 return 1;241 return 1;
242 }242 }
243 output_send_fn = jack_output_send;243 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