1 /* 2 * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/> 3 * (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com> 4 * 5 * This file is part of lsp-plugins 6 * Created on: 27 авг. 2018 г. 7 * 8 * lsp-plugins is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU Lesser General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * any later version. 12 * 13 * lsp-plugins is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public License 19 * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>. 20 */ 21 22 #include <test/mtest.h> 23 #include <test/helpers.h> 24 25 #include <core/types.h> 26 #include <core/alloc.h> 27 #include <data/cvector.h> 28 29 #include <core/envelope.h> 30 #include <math.h> 31 #include <core/util/LatencyDetector.h> 32 #include <stdlib.h> 33 #include <time.h> 34 35 #include <dsp/dsp.h> 36 37 #define LATENCYDETECTOR_BUFFER_SIZE 1024 38 #define LATENCYDETECTOR_SAMPLE_RATE 96000 39 #define LATENCYDETECTOR_MAX_DELAY LATENCYDETECTOR_BUFFER_SIZE - 1 40 #define LATENCYDETECTOR_DELAY_STEP 1 41 42 using namespace lsp; 43 44 MTEST_BEGIN("core.util", latency_detector) 45 test_latencydetector(float * out,float * bak,float * in,size_t * delay_exact,size_t * delay_detected,size_t buf_count,size_t bak_count)46 void test_latencydetector(float *out, float *bak, float *in, size_t *delay_exact, size_t *delay_detected, size_t buf_count, size_t bak_count) 47 { 48 printf("Testing LatencyDetector... "); 49 50 // Initialise the LatencyDetector object: 51 LatencyDetector ld; 52 ld.init(); 53 ld.set_sample_rate(LATENCYDETECTOR_SAMPLE_RATE); 54 ld.set_delay_ratio(0.5f); 55 ld.set_peak_threshold(0.5f); 56 ld.set_abs_threshold(0.01f); 57 58 // Test Parameters 59 // ld.set_duration(0.015f); 60 // ld.set_fading(0.030f); 61 // ld.set_pause(0.025f); 62 63 // Random Parameters: 64 ld.set_duration((float(rand()) * 0.040f / RAND_MAX) + 0.010f); 65 ld.set_op_fading((float(rand()) * 0.045f / RAND_MAX) + 0.005f); 66 ld.set_op_pause((float(rand()) * 0.045f / RAND_MAX) + 0.005f); 67 68 ld.set_ip_detection((3 * 0.050f) + (float(LATENCYDETECTOR_MAX_DELAY) / LATENCYDETECTOR_SAMPLE_RATE) + 0.005f); 69 70 if (ld.needs_update()) 71 ld.update_settings(); 72 73 ld.start_capture(); 74 75 // size_t bak_head = 0; 76 77 while (true) 78 { 79 // dump_buffer("in", in, buf_count); 80 // dump_buffer("out", out, buf_count); 81 ld.process(out, in, buf_count); 82 83 if (ld.cycle_complete()) 84 break; 85 86 // This will work only for delays shorter than the buffer length 87 88 // When in CS_DETECT, in out there will be the chirp. Let's put a 89 // delayed copy into in. 90 91 // Old tail of out is in the beginning: 92 dsp::copy(in, bak, *delay_exact); 93 94 // Body of the delayed signal after: 95 dsp::copy(&in[*delay_exact], out, buf_count - *delay_exact); 96 97 // Save out tail: 98 dsp::copy(bak, &out[buf_count - *delay_exact], *delay_exact); 99 100 // Do Scaling (opposite phase with negative sign). 101 dsp::mul_k2(in, -1.0f, buf_count); 102 } 103 104 // Now latency is detected: 105 *delay_detected = ld.get_latency_samples() - buf_count; 106 107 if (*delay_exact == *delay_detected) 108 { 109 printf("Success\n"); 110 } 111 else 112 { 113 printf("FAIL: %lu", (long unsigned)(*delay_exact)); 114 printf(" VS %lu\n", (long unsigned)(*delay_detected)); 115 } 116 } 117 118 MTEST_MAIN 119 { 120 size_t buf_size = LATENCYDETECTOR_BUFFER_SIZE; 121 size_t bak_size = LATENCYDETECTOR_BUFFER_SIZE * ceil(float(LATENCYDETECTOR_MAX_DELAY) / LATENCYDETECTOR_BUFFER_SIZE); 122 123 float *out = new float[buf_size]; 124 float *in = new float[buf_size]; 125 float *bak = new float[bak_size]; 126 127 size_t delay_array_size = ceil(float(LATENCYDETECTOR_MAX_DELAY) / LATENCYDETECTOR_DELAY_STEP); 128 size_t *delays_exact = new size_t[delay_array_size]; 129 size_t *delays_detected = new size_t[delay_array_size]; 130 ssize_t *delays_error = new ssize_t[delay_array_size]; 131 132 size_t delay_idx = 0; 133 134 size_t count_success = 0; 135 size_t count_fail = 0; 136 size_t count_total = 0; 137 138 for (size_t delay = 0; delay < LATENCYDETECTOR_MAX_DELAY; delay += LATENCYDETECTOR_DELAY_STEP) 139 { 140 printf("%.1f Percent:\t", 100.0f * float(delay) / (LATENCYDETECTOR_MAX_DELAY - 1)); 141 142 delays_exact[delay_idx] = delay; 143 dsp::fill_zero(out, buf_size); 144 dsp::fill_zero(in, buf_size); 145 dsp::fill_zero(bak, bak_size); 146 147 test_latencydetector(out, bak, in, &delays_exact[delay_idx], &delays_detected[delay_idx], buf_size, bak_size); 148 149 count_total += 1; 150 if (delays_exact[delay_idx] == delays_detected[delay_idx]) 151 count_success ++; 152 else 153 count_fail ++; 154 155 delays_error[delay_idx] = delays_exact[delay_idx] - delays_detected[delay_idx]; 156 157 delay_idx += 1; 158 } 159 160 // dump_buffer("exact_latency", delays_exact, delay_array_size); 161 // dump_buffer("detected_latency", delays_detected, delay_array_size); 162 dump_buffer("delays_error", delays_error, delay_array_size); 163 printf("Success Rate:\t%.1f percent\n", 100 * float(count_success) / count_total); 164 printf("Fail Rate:\t%.1f percent\n", 100 * float(count_fail) / count_total); 165 166 delete [] out; 167 delete [] in; 168 delete [] bak; 169 delete [] delays_exact; 170 delete [] delays_detected; 171 } 172 173 MTEST_END 174 175 176 177 178 179