Audio/extrapolator: Fix short prime length
When the input buffer has less samples in it than the LPC order, it would crash reaching past the ends of the buffer. Now, it will pad past the correct end of the audio with silence, while still extrapolating a prime input minimum of the LPC order. Should fix the last of the outstanding crashes. Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
91b31255e6
commit
cc79342c5b
1 changed files with 37 additions and 12 deletions
49
Audio/ThirdParty/lvqcl/lpc.c
vendored
49
Audio/ThirdParty/lvqcl/lpc.c
vendored
|
@ -139,7 +139,10 @@ static void vorbis_lpc_predict(float *coeff, float *prime, int m, float *data, l
|
||||||
}
|
}
|
||||||
|
|
||||||
void lpc_extrapolate2(float *const data, const size_t data_len, const int nch, const int lpc_order, const size_t extra_bkwd, const size_t extra_fwd, void **extrapolate_buffer, size_t *extrapolate_buffer_size) {
|
void lpc_extrapolate2(float *const data, const size_t data_len, const int nch, const int lpc_order, const size_t extra_bkwd, const size_t extra_fwd, void **extrapolate_buffer, size_t *extrapolate_buffer_size) {
|
||||||
const size_t tdata_size = sizeof(float) * (extra_bkwd + data_len + extra_fwd);
|
const size_t max_to_prime = (data_len < lpc_order) ? data_len : lpc_order;
|
||||||
|
const size_t min_data_len = (data_len < lpc_order) ? lpc_order : data_len;
|
||||||
|
|
||||||
|
const size_t tdata_size = sizeof(float) * (extra_bkwd + min_data_len + extra_fwd);
|
||||||
const size_t aut_size = sizeof(double) * (lpc_order + 1);
|
const size_t aut_size = sizeof(double) * (lpc_order + 1);
|
||||||
const size_t lpc_size = sizeof(double) * lpc_order;
|
const size_t lpc_size = sizeof(double) * lpc_order;
|
||||||
const size_t lpci_size = sizeof(float) * lpc_order;
|
const size_t lpci_size = sizeof(float) * lpc_order;
|
||||||
|
@ -162,32 +165,54 @@ void lpc_extrapolate2(float *const data, const size_t data_len, const int nch, c
|
||||||
for(int c = 0; c < nch; c++) {
|
for(int c = 0; c < nch; c++) {
|
||||||
if(extra_bkwd) {
|
if(extra_bkwd) {
|
||||||
for(int i = 0; i < (int)data_len; i++)
|
for(int i = 0; i < (int)data_len; i++)
|
||||||
tdata[data_len - 1 - i] = data[i * nch + c];
|
tdata[min_data_len - 1 - i] = data[i * nch + c];
|
||||||
|
if(data_len < min_data_len)
|
||||||
|
for(int i = (int)data_len; i < (int)min_data_len; i++)
|
||||||
|
tdata[min_data_len - 1 - i] = 0.0f;
|
||||||
} else {
|
} else {
|
||||||
for(int i = 0; i < (int)data_len; i++)
|
const ssize_t len_diff = min_data_len - data_len;
|
||||||
tdata[i] = data[i * nch + c];
|
if(len_diff <= 0) {
|
||||||
|
for(int i = 0; i < (int)data_len; i++)
|
||||||
|
tdata[i] = data[i * nch + c];
|
||||||
|
} else {
|
||||||
|
for(int i = 0; i < (int)len_diff; i++)
|
||||||
|
tdata[i] = 0.0f;
|
||||||
|
for(int i = 0; i < (int)data_len; i++)
|
||||||
|
tdata[len_diff + i] = data[i * nch + c];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply_window(tdata, data_len);
|
apply_window(tdata, min_data_len);
|
||||||
vorbis_lpc_from_data(tdata, lpci, (int)data_len, lpc_order, aut, lpc);
|
vorbis_lpc_from_data(tdata, lpci, (int)min_data_len, lpc_order, aut, lpc);
|
||||||
|
|
||||||
// restore after apply_window
|
// restore after apply_window
|
||||||
if(extra_bkwd) {
|
if(extra_bkwd) {
|
||||||
for(int i = 0; i < (int)data_len; i++)
|
for(int i = 0; i < (int)data_len; i++)
|
||||||
tdata[data_len - 1 - i] = data[i * nch + c];
|
tdata[min_data_len - 1 - i] = data[i * nch + c];
|
||||||
|
if(data_len < min_data_len)
|
||||||
|
for(int i = (int)data_len; i < (int)min_data_len; i++)
|
||||||
|
tdata[min_data_len - 1 - i] = 0.0f;
|
||||||
} else {
|
} else {
|
||||||
for(int i = 0; i < (int)data_len; i++)
|
const ssize_t len_diff = min_data_len - data_len;
|
||||||
tdata[i] = data[i * nch + c];
|
if(len_diff <= 0) {
|
||||||
|
for(int i = 0; i < (int)data_len; i++)
|
||||||
|
tdata[i] = data[i * nch + c];
|
||||||
|
} else {
|
||||||
|
for(int i = 0; i < (int)len_diff; i++)
|
||||||
|
tdata[i] = 0.0f;
|
||||||
|
for(int i = 0; i < (int)data_len; i++)
|
||||||
|
tdata[len_diff + i] = data[i * nch + c];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vorbis_lpc_predict(lpci, tdata + data_len - lpc_order, lpc_order, tdata + data_len, extra_fwd + extra_bkwd, work);
|
vorbis_lpc_predict(lpci, tdata + min_data_len - lpc_order, lpc_order, tdata + min_data_len, extra_fwd + extra_bkwd, work);
|
||||||
|
|
||||||
if(extra_bkwd) {
|
if(extra_bkwd) {
|
||||||
for(int i = 0; i < extra_bkwd; i++)
|
for(int i = 0; i < extra_bkwd; i++)
|
||||||
data[(-i - 1) * nch + c] = tdata[data_len + i];
|
data[(-i - 1) * nch + c] = tdata[min_data_len + i];
|
||||||
} else {
|
} else {
|
||||||
for(int i = 0; i < extra_fwd; i++)
|
for(int i = 0; i < extra_fwd; i++)
|
||||||
data[(i + data_len) * nch + c] = tdata[data_len + i];
|
data[(i + data_len) * nch + c] = tdata[min_data_len + i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue