Skip to content

Commit fd850e6

Browse files
committed
Rewrite latency calculations
1 parent 98fed99 commit fd850e6

File tree

9 files changed

+149
-130
lines changed

9 files changed

+149
-130
lines changed

src/engine.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,12 @@ set_usb_input_data_blks (struct ow_engine *engine)
155155
}
156156

157157
pthread_spin_lock (&engine->lock);
158-
engine->o2h_latency =
159-
engine->context->read_space (engine->context->o2h_audio);
160-
if (engine->o2h_latency > engine->o2h_max_latency)
158+
engine->latency_o2h =
159+
engine->context->read_space (engine->context->o2h_audio) /
160+
engine->o2h_frame_size;
161+
if (engine->latency_o2h > engine->latency_o2h_max)
161162
{
162-
engine->o2h_max_latency = engine->o2h_latency;
163+
engine->latency_o2h_max = engine->latency_o2h;
163164
}
164165
pthread_spin_unlock (&engine->lock);
165166
}
@@ -234,17 +235,17 @@ set_usb_output_data_blks (struct ow_engine *engine)
234235
debug_print (2, "h2o: Clearing buffer and stopping...");
235236
memset (engine->h2o_transfer_buf, 0, engine->h2o_transfer_size);
236237
engine->reading_at_h2o_end = 0;
237-
engine->h2o_max_latency = 0;
238+
engine->latency_h2o_max = engine->latency_h2o_min;
238239
goto set_blocks;
239240
}
240241
return;
241242
}
242243

243244
pthread_spin_lock (&engine->lock);
244-
engine->h2o_latency = rsh2o;
245-
if (engine->h2o_latency > engine->h2o_max_latency)
245+
engine->latency_h2o = rsh2o / engine->h2o_frame_size;
246+
if (engine->latency_h2o > engine->latency_h2o_max)
246247
{
247-
engine->h2o_max_latency = engine->h2o_latency;
248+
engine->latency_h2o_max = engine->latency_h2o;
248249
}
249250
pthread_spin_unlock (&engine->lock);
250251

@@ -282,6 +283,11 @@ set_usb_output_data_blks (struct ow_engine *engine)
282283
engine->h2o_data.src_ratio, engine->h2o_data.output_frames_gen,
283284
engine->frames_per_transfer);
284285
}
286+
287+
// Any maximum value is invalid at this point
288+
pthread_spin_lock (&engine->lock);
289+
engine->latency_o2h_max = engine->latency_o2h_min;
290+
pthread_spin_unlock (&engine->lock);
285291
}
286292
else
287293
{
@@ -478,8 +484,8 @@ ow_engine_init_mem (struct ow_engine *engine,
478484
debug_print (2, "h2o: audio transfer size: %zu B",
479485
engine->h2o_transfer_size);
480486

481-
engine->o2h_min_latency = engine->frames_per_transfer;
482-
engine->h2o_min_latency = engine->frames_per_transfer;
487+
engine->latency_o2h_min = engine->frames_per_transfer;
488+
engine->latency_h2o_min = engine->frames_per_transfer;
483489

484490
engine->usb.audio_frames_counter = 0;
485491
engine->usb.xfr_audio_in_data_len =
@@ -787,11 +793,12 @@ run_audio (void *data)
787793

788794
debug_print (1, "Booting or clearing engine...");
789795

790-
engine->h2o_latency = 0;
791-
engine->h2o_max_latency = 0;
796+
engine->latency_h2o = engine->latency_h2o_min;
797+
engine->latency_h2o_max = engine->latency_h2o_min;
798+
engine->latency_o2h = engine->latency_o2h_min;
799+
engine->latency_o2h_max = engine->latency_o2h_min;
800+
792801
engine->reading_at_h2o_end = engine->context->dll ? 0 : 1;
793-
engine->o2h_latency = 0;
794-
engine->o2h_max_latency = 0;
795802

796803
pthread_spin_lock (&engine->lock);
797804
if (engine->status <= OW_ENGINE_STATUS_STOP)

src/engine.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,13 @@ struct ow_engine
171171
unsigned int blocks_per_transfer;
172172
unsigned int frames_per_transfer;
173173
pthread_spinlock_t lock;
174-
//Latencies are measured in bytes
175-
size_t o2h_latency;
176-
size_t o2h_min_latency;
177-
size_t o2h_max_latency;
178-
size_t h2o_latency;
179-
size_t h2o_min_latency;
180-
size_t h2o_max_latency;
174+
//Latencies are measured in frames
175+
size_t latency_o2h;
176+
size_t latency_o2h_min;
177+
size_t latency_o2h_max;
178+
size_t latency_h2o;
179+
size_t latency_h2o_min;
180+
size_t latency_h2o_max;
181181
pthread_t thread;
182182
size_t h2o_transfer_size;
183183
size_t o2h_transfer_size;

src/jclient.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,39 +66,38 @@ jclient_set_latency_cb (jack_latency_callback_mode_t mode, void *cb_data)
6666
{
6767
jack_latency_range_t range;
6868
struct jclient *jclient = cb_data;
69-
uint32_t latency, min_latency, max_latency;
7069
struct ow_engine *engine = ow_resampler_get_engine (jclient->resampler);
7170
const struct ow_device_desc *desc = &ow_engine_get_device (engine)->desc;
71+
struct ow_resampler_state *state =
72+
ow_resampler_get_state (jclient->resampler);
7273

7374
debug_print (2, "JACK latency request");
7475

7576
if (mode == JackPlaybackLatency)
7677
{
77-
ow_resampler_get_o2h_latency (jclient->resampler, &latency,
78-
&min_latency, &max_latency);
79-
debug_print (2, "o2h latency: [ %d, %d ]", min_latency, max_latency);
78+
debug_print (2, "o2h latency: [ %d, %d ]", state->f_latency_o2h_min,
79+
state->f_latency_o2h_max);
8080

8181
for (int i = 0; i < desc->outputs; i++)
8282
{
8383
jack_port_get_latency_range (jclient->input_ports[0], mode, &range);
84-
range.min += min_latency;
85-
range.max += max_latency;
84+
range.min += state->f_latency_o2h_min;
85+
range.max += state->f_latency_o2h_max;
8686
jack_port_set_latency_range (jclient->output_ports[i], mode,
8787
&range);
8888
}
8989
}
9090
else if (mode == JackCaptureLatency)
9191
{
92-
ow_resampler_get_h2o_latency (jclient->resampler, &latency,
93-
&min_latency, &max_latency);
94-
debug_print (2, "h2o latency: [ %d, %d ]", min_latency, max_latency);
92+
debug_print (2, "h2o latency: [ %d, %d ]", state->f_latency_h2o_min,
93+
state->f_latency_h2o_max);
9594

9695
for (int i = 0; i < desc->inputs; i++)
9796
{
9897
jack_port_get_latency_range (jclient->output_ports[0], mode,
9998
&range);
100-
range.min += min_latency;
101-
range.max += max_latency;
99+
range.min += state->f_latency_h2o_min;
100+
range.max += state->f_latency_h2o_max;
102101
jack_port_set_latency_range (jclient->input_ports[i], mode, &range);
103102
}
104103
}

src/main-service.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ handle_get_state ()
370370
struct ow_engine *engine = ow_resampler_get_engine (resampler);
371371
const struct ow_device *device = ow_engine_get_device (engine);
372372
const gchar *name = ow_engine_get_overbridge_name (engine);
373-
ow_resampler_get_state (resampler, &state);
373+
ow_resampler_get_state_copy (resampler, &state);
374374
message_state_builder_add_device (builder, i, name, device, &state);
375375
}
376376

src/message.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,17 @@ message_state_builder_add_device (JsonBuilder *builder, guint32 id,
7474
json_builder_set_member_name (builder, STATE_DEVICE_STATUS);
7575
json_builder_add_int_value (builder, state->status);
7676
json_builder_set_member_name (builder, STATE_DEVICE_LATENCY_O2H);
77-
json_builder_add_double_value (builder, state->latency_o2h);
77+
json_builder_add_double_value (builder, state->t_latency_o2h);
7878
json_builder_set_member_name (builder, STATE_DEVICE_LATENCY_O2H_MAX);
79-
json_builder_add_double_value (builder, state->latency_o2h_max);
79+
json_builder_add_double_value (builder, state->t_latency_o2h_max);
8080
json_builder_set_member_name (builder, STATE_DEVICE_LATENCY_O2H_MIN);
81-
json_builder_add_double_value (builder, state->latency_o2h_min);
81+
json_builder_add_double_value (builder, state->t_latency_o2h_min);
8282
json_builder_set_member_name (builder, STATE_DEVICE_LATENCY_H2O);
83-
json_builder_add_double_value (builder, state->latency_h2o);
83+
json_builder_add_double_value (builder, state->t_latency_h2o);
8484
json_builder_set_member_name (builder, STATE_DEVICE_LATENCY_H2O_MAX);
85-
json_builder_add_double_value (builder, state->latency_h2o_max);
85+
json_builder_add_double_value (builder, state->t_latency_h2o_max);
8686
json_builder_set_member_name (builder, STATE_DEVICE_LATENCY_H2O_MIN);
87-
json_builder_add_double_value (builder, state->latency_h2o_min);
87+
json_builder_add_double_value (builder, state->t_latency_h2o_min);
8888
json_builder_set_member_name (builder, STATE_DEVICE_RATIO_O2H);
8989
json_builder_add_double_value (builder, state->ratio_o2h);
9090
json_builder_set_member_name (builder, STATE_DEVICE_RATIO_H2O);
@@ -184,8 +184,8 @@ message_state_reader_get_device (JsonReader *reader, guint index)
184184
static gchar h2o_latency[OW_LABEL_MAX_LEN];
185185
const gchar *name, *device_name;
186186

187-
state.latency_o2h = 0;
188-
state.latency_h2o = 0;
187+
state.t_latency_o2h = 0;
188+
state.t_latency_h2o = 0;
189189
state.ratio_o2h = 0;
190190
state.ratio_o2h = 0;
191191

@@ -256,7 +256,7 @@ message_state_reader_get_device (JsonReader *reader, guint index)
256256

257257
if (json_reader_read_member (reader, STATE_DEVICE_LATENCY_O2H))
258258
{
259-
state.latency_o2h = json_reader_get_double_value (reader);
259+
state.t_latency_o2h = json_reader_get_double_value (reader);
260260
json_reader_end_member (reader);
261261
}
262262
else
@@ -266,7 +266,7 @@ message_state_reader_get_device (JsonReader *reader, guint index)
266266

267267
if (json_reader_read_member (reader, STATE_DEVICE_LATENCY_O2H_MAX))
268268
{
269-
state.latency_o2h_max = json_reader_get_double_value (reader);
269+
state.t_latency_o2h_max = json_reader_get_double_value (reader);
270270
json_reader_end_member (reader);
271271
}
272272
else
@@ -276,7 +276,7 @@ message_state_reader_get_device (JsonReader *reader, guint index)
276276

277277
if (json_reader_read_member (reader, STATE_DEVICE_LATENCY_O2H_MIN))
278278
{
279-
state.latency_o2h_min = json_reader_get_double_value (reader);
279+
state.t_latency_o2h_min = json_reader_get_double_value (reader);
280280
json_reader_end_member (reader);
281281
}
282282
else
@@ -296,7 +296,7 @@ message_state_reader_get_device (JsonReader *reader, guint index)
296296

297297
if (json_reader_read_member (reader, STATE_DEVICE_LATENCY_H2O))
298298
{
299-
state.latency_h2o = json_reader_get_double_value (reader);
299+
state.t_latency_h2o = json_reader_get_double_value (reader);
300300
json_reader_end_member (reader);
301301
}
302302
else
@@ -306,7 +306,7 @@ message_state_reader_get_device (JsonReader *reader, guint index)
306306

307307
if (json_reader_read_member (reader, STATE_DEVICE_LATENCY_H2O_MAX))
308308
{
309-
state.latency_h2o_max = json_reader_get_double_value (reader);
309+
state.t_latency_h2o_max = json_reader_get_double_value (reader);
310310
json_reader_end_member (reader);
311311
}
312312
else
@@ -316,7 +316,7 @@ message_state_reader_get_device (JsonReader *reader, guint index)
316316

317317
if (json_reader_read_member (reader, STATE_DEVICE_LATENCY_H2O_MIN))
318318
{
319-
state.latency_h2o_min = json_reader_get_double_value (reader);
319+
state.t_latency_h2o_min = json_reader_get_double_value (reader);
320320
json_reader_end_member (reader);
321321
}
322322
else
@@ -334,22 +334,22 @@ message_state_reader_get_device (JsonReader *reader, guint index)
334334
goto end;
335335
}
336336

337-
if (state.latency_o2h >= 0)
337+
if (state.t_latency_o2h >= 0)
338338
{
339339
g_snprintf (o2h_latency, OW_LABEL_MAX_LEN,
340-
"%.1f [%.1f, %.1f] ms", state.latency_o2h,
341-
state.latency_o2h_min, state.latency_o2h_max);
340+
"%.1f [%.1f, %.1f] ms", state.t_latency_o2h,
341+
state.t_latency_o2h_min, state.t_latency_o2h_max);
342342
}
343343
else
344344
{
345345
o2h_latency[0] = '\0';
346346
}
347347

348-
if (state.latency_h2o >= 0)
348+
if (state.t_latency_h2o >= 0)
349349
{
350350
g_snprintf (h2o_latency, OW_LABEL_MAX_LEN,
351-
"%.1f [%.1f, %.1f] ms", state.latency_h2o,
352-
state.latency_h2o_min, state.latency_h2o_max);
351+
"%.1f [%.1f, %.1f] ms", state.t_latency_h2o,
352+
state.t_latency_h2o_min, state.t_latency_h2o_max);
353353
}
354354
else
355355
{

src/overwitch.h

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,22 @@ struct ow_device
170170
struct ow_resampler_state
171171
{
172172
ow_resampler_status_t status;
173-
double latency_o2h;
174-
double latency_o2h_min;
175-
double latency_o2h_max;
176-
double latency_h2o;
177-
double latency_h2o_min;
178-
double latency_h2o_max;
179173
double ratio_o2h;
180174
double ratio_h2o;
175+
//Time latency members
176+
double t_latency_o2h;
177+
double t_latency_o2h_min;
178+
double t_latency_o2h_max;
179+
double t_latency_h2o;
180+
double t_latency_h2o_min;
181+
double t_latency_h2o_max;
182+
//Frame latency members
183+
uint32_t f_latency_o2h;
184+
uint32_t f_latency_o2h_min;
185+
uint32_t f_latency_o2h_max;
186+
uint32_t f_latency_h2o;
187+
uint32_t f_latency_h2o_min;
188+
uint32_t f_latency_h2o_max;
181189
};
182190

183191
typedef void (*ow_hotplug_callback_t) (struct ow_device * device);
@@ -256,9 +264,6 @@ void ow_resampler_wait (struct ow_resampler *resampler);
256264

257265
void ow_resampler_destroy (struct ow_resampler *resampler);
258266

259-
void ow_resampler_get_state (struct ow_resampler *resampler,
260-
struct ow_resampler_state *state);
261-
262267
void ow_resampler_clear_buffers (struct ow_resampler *resampler);
263268

264269
void ow_resampler_reset (struct ow_resampler *resampler);
@@ -300,10 +305,10 @@ float *ow_resampler_get_h2o_audio_buffer (struct ow_resampler *resampler);
300305
struct ow_resampler_reporter *ow_resampler_get_reporter (struct ow_resampler
301306
*);
302307

303-
void ow_resampler_get_h2o_latency (struct ow_resampler *resampler, uint32_t *,
304-
uint32_t *, uint32_t *);
308+
double ow_resampler_get_target_delay_ms (struct ow_resampler *resampler);
305309

306-
void ow_resampler_get_o2h_latency (struct ow_resampler *resampler, uint32_t *,
307-
uint32_t *, uint32_t *);
310+
struct ow_resampler_state *ow_resampler_get_state (struct ow_resampler
311+
*resampler);
308312

309-
double ow_resampler_get_target_delay_ms (struct ow_resampler *resampler);
313+
void ow_resampler_get_state_copy (struct ow_resampler *resampler,
314+
struct ow_resampler_state *state);

0 commit comments

Comments
 (0)