Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package liblc3 for openSUSE:Factory checked in at 2023-08-05 12:54:45 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/liblc3 (Old) and /work/SRC/openSUSE:Factory/.liblc3.new.22712 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "liblc3" Sat Aug 5 12:54:45 2023 rev:4 rq:1102326 version:1.0.4 Changes: -------- --- /work/SRC/openSUSE:Factory/liblc3/liblc3.changes 2023-05-09 13:08:26.969417969 +0200 +++ /work/SRC/openSUSE:Factory/.liblc3.new.22712/liblc3.changes 2023-08-05 12:54:54.300578339 +0200 @@ -1,0 +2,8 @@ +Fri Aug 4 09:24:21 UTC 2023 - Bjørn Lie <bjorn....@gmail.com> + +- Update to version 1.0.4: + + Enhancement: Add fuzzing test harness. + + Fixes: Gain adjustment during second quantization phase can + exceed minimum gain (introduce distortion at high bitrate). + +------------------------------------------------------------------- Old: ---- liblc3-1.0.3.obscpio New: ---- liblc3-1.0.4.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ liblc3.spec ++++++ --- /var/tmp/diff_new_pack.x0ei80/_old 2023-08-05 12:54:54.976582663 +0200 +++ /var/tmp/diff_new_pack.x0ei80/_new 2023-08-05 12:54:54.980582689 +0200 @@ -19,7 +19,7 @@ %define lc3soname liblc3-1 Name: liblc3 -Version: 1.0.3 +Version: 1.0.4 Release: 0 Summary: Low Complexity Communication Codec (LC3) License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.x0ei80/_old 2023-08-05 12:54:55.004582842 +0200 +++ /var/tmp/diff_new_pack.x0ei80/_new 2023-08-05 12:54:55.008582868 +0200 @@ -5,7 +5,7 @@ <param name="scm">git</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v([0-9\.]*)</param> - <param name="revision">v1.0.3</param> + <param name="revision">v1.0.4</param> </service> <service name="tar" mode="buildtime"/> <service name="recompress" mode="buildtime"> ++++++ liblc3-1.0.3.obscpio -> liblc3-1.0.4.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/liblc3-1.0.3/Makefile new/liblc3-1.0.4/Makefile --- old/liblc3-1.0.3/Makefile 2023-05-08 19:53:53.000000000 +0200 +++ new/liblc3-1.0.4/Makefile 2023-08-03 18:45:11.000000000 +0200 @@ -61,13 +61,15 @@ define set-target $(eval $(1)_obj ?= $(patsubst %.c,%.o,$(filter %.c,$($(1)_src))) \ - $(patsubst %.s,%.o,$(filter %.s,$($(1)_src)))) + $(patsubst %.s,%.o,$(filter %.s,$($(1)_src))) \ + $(patsubst %.cc,%.o,$(filter %.cc,$($(1)_src)))) $(eval $(1)_obj := $(addprefix $(BUILD_DIR)/,$($(1)_obj))) $(eval $(1)_lib := $(foreach lib, $($(1)_lib), $($(lib)_bin))) - $($(1)_obj): INCLUDE += $($(1)_include) - $($(1)_obj): DEFINE += $($(1)_define) - $($(1)_obj): CFLAGS += $($(1)_cflags) + $($(1)_obj): INCLUDE += $($(1)_include) + $($(1)_obj): DEFINE += $($(1)_define) + $($(1)_obj): CFLAGS += $($(1)_cflags) + $($(1)_obj): CXXFLAGS += $($(1)_cxxflags) -include $($(1)_obj:.o=.d) @@ -94,6 +96,9 @@ TEST_DIR := test -include $(TEST_DIR)/makefile.mk +FUZZ_DIR := fuzz +-include $(FUZZ_DIR)/makefile.mk + # # Rules @@ -118,6 +123,13 @@ $(addprefix -I,$(INCLUDE)) \ $(addprefix -D,$(DEFINE)) -MMD -MF $(@:.o=.d) -o $@ +$(BUILD_DIR)/%.o: %.cc $(MAKEFILE_DEPS) + @echo " CXX $(notdir $<)" + $(V)mkdir -p $(dir $@) + $(V)$(CXX) $< -c $(CXXFLAGS) \ + $(addprefix -I,$(INCLUDE)) \ + $(addprefix -D,$(DEFINE)) -MMD -MF $(@:.o=.d) -o $@ + $(LIB): $(MAKEFILE_DEPS) @echo " AR $(notdir $@)" $(V)mkdir -p $(dir $@) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/liblc3-1.0.3/README.md new/liblc3-1.0.4/README.md --- old/liblc3-1.0.3/README.md 2023-05-08 19:53:53.000000000 +0200 +++ new/liblc3-1.0.4/README.md 2023-08-03 18:45:11.000000000 +0200 @@ -11,6 +11,7 @@ - src: Source files - tools: Standalone encoder/decoder tools - test: Python implentation, used as reference for unit testing +- fuzz: Roundtrip fuzz testing harness - build: Building outputs - bin: Compilation output @@ -91,10 +92,23 @@ $ make test ``` -## Conformance +## Fuzzing -The proposed encoder and decoder implementation have been fully tested and -validated. +Roundtrip fuzz testing harness is available in `fuzz` directory. +LLVM `clang` and `clang++` compilers are needed to run fuzzing. + +The encoder and decoder fuzzers can be run, for 1 million iterations, using +target respectively `dfuzz` and `efuzz`. The `fuzz` target runs both. + +```sh +$ make efuzz # Run encoder fuzzer for 1M iteration +$ make dfuzz # Run decoder fuzzer for 1M iteration +$ make fuzz -j # Run encoder and decoder fuzzers in parallel +``` + +## Qualification / Conformance + +The implementation is qualified under the [_QDID 194161_](https://launchstudio.bluetooth.com/ListingDetails/160904) as part of Google Fluoride 1.5. For more detail on conformance, refer to [_Bluetooth Conformance Documents and scripts_](https://www.bluetooth.com/specifications/specs/low-complexity-communication-codec-1-0/) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/liblc3-1.0.3/fuzz/dfuzz.cc new/liblc3-1.0.4/fuzz/dfuzz.cc --- old/liblc3-1.0.3/fuzz/dfuzz.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/liblc3-1.0.4/fuzz/dfuzz.cc 2023-08-03 18:45:11.000000000 +0200 @@ -0,0 +1,64 @@ +/****************************************************************************** + * + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include <lc3_cpp.h> +#include <fuzzer/FuzzedDataProvider.h> + +using namespace lc3; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const int dt_list[] = { 7500, 10000 }; + const int sr_list[] = { 8000, 16000, 24000, 32000, 48000 }; + + FuzzedDataProvider fdp(data, size); + + int dt_us = fdp.PickValueInArray(dt_list); + int sr_hz = fdp.PickValueInArray(sr_list); + int nchannels =fdp.PickValueInArray({1, 2}); + + int sr_pcm_hz = fdp.PickValueInArray(sr_list); + if (sr_pcm_hz < sr_hz) + sr_pcm_hz = 0; + + Decoder dec(dt_us, sr_hz, sr_pcm_hz, nchannels); + + int frame_size = fdp.ConsumeIntegralInRange( + LC3_MIN_FRAME_BYTES, LC3_MAX_FRAME_BYTES); + + PcmFormat fmt = fdp.PickValueInArray( + { PcmFormat::kS16, PcmFormat::kS24, + PcmFormat::kS24In3Le, PcmFormat::kF32 }); + + int frame_samples = dec.GetFrameSamples(); + + int sample_bytes = + fmt == PcmFormat::kS16 ? sizeof(int16_t) : + fmt == PcmFormat::kS24 ? sizeof(int32_t) : + fmt == PcmFormat::kS24In3Le ? sizeof(uint8_t) * 3 : + fmt == PcmFormat::kF32 ? sizeof(float) : 0; + + if (fdp.remaining_bytes() < frame_size * nchannels) + return -1; + + dec.Decode( + fdp.ConsumeBytes<uint8_t>(nchannels * frame_size).data(), frame_size, + fmt, std::vector<uint8_t>(nchannels * frame_samples * sample_bytes).data()); + + return 0; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/liblc3-1.0.3/fuzz/efuzz.cc new/liblc3-1.0.4/fuzz/efuzz.cc --- old/liblc3-1.0.3/fuzz/efuzz.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/liblc3-1.0.4/fuzz/efuzz.cc 2023-08-03 18:45:11.000000000 +0200 @@ -0,0 +1,117 @@ +/****************************************************************************** + * + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include <lc3_cpp.h> +#include <fuzzer/FuzzedDataProvider.h> + +using namespace lc3; + +template <typename T> +T ConsumeInRange(FuzzedDataProvider &fdp, T min, T max) { + return fdp.ConsumeIntegralInRange<T>(min, max); +} + +template <> +float ConsumeInRange(FuzzedDataProvider &fdp, float min, float max) { + return fdp.ConsumeFloatingPointInRange<float>(min, max); +} + +template <typename T> +int encode(Encoder &e, int nchannels, int frame_size, FuzzedDataProvider &fdp, + T min = std::numeric_limits<T>::min(), T max = std::numeric_limits<T>::max()) +{ + int pcm_samples = nchannels * e.GetFrameSamples(); + if (fdp.remaining_bytes() < pcm_samples * sizeof(T)) + return -1; + + std::vector<T> pcm(pcm_samples); + for (auto &s: pcm) + s = ConsumeInRange<T>(fdp, min, max); + + e.Encode(pcm.data(), + frame_size, std::vector<uint8_t>(nchannels * frame_size).data()); + + return 0; +} + +int encode(Encoder &e, int frame_size, int nchannels, + PcmFormat fmt, FuzzedDataProvider &fdp) +{ + int sample_bytes = + fmt == PcmFormat::kS16 ? sizeof(int16_t) : + fmt == PcmFormat::kS24 ? sizeof(int32_t) : + fmt == PcmFormat::kS24In3Le ? sizeof(uint8_t) * 3 : + fmt == PcmFormat::kF32 ? sizeof(float) : 0; + + int pcm_bytes = nchannels * e.GetFrameSamples() * sample_bytes; + if (fdp.remaining_bytes() < pcm_bytes) + return -1; + + e.Encode(fmt, fdp.ConsumeBytes<uint8_t>(pcm_bytes).data(), + frame_size, std::vector<uint8_t>(nchannels * frame_size).data()); + + return 0; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const int dt_list[] = { 7500, 10000 }; + const int sr_list[] = { 8000, 16000, 24000, 32000, 48000 }; + + FuzzedDataProvider fdp(data, size); + + int dt_us = fdp.PickValueInArray(dt_list); + int sr_hz = fdp.PickValueInArray(sr_list); + int nchannels = fdp.PickValueInArray({1, 2}); + + int sr_pcm_hz = fdp.PickValueInArray(sr_list); + if (sr_pcm_hz < sr_hz) + sr_pcm_hz = 0; + + Encoder enc(dt_us, sr_hz, sr_pcm_hz, nchannels); + + PcmFormat fmt = fdp.PickValueInArray( + { PcmFormat::kS16, PcmFormat::kS24, + PcmFormat::kS24In3Le, PcmFormat::kF32 }); + + int frame_size = fdp.ConsumeIntegralInRange( + LC3_MIN_FRAME_BYTES, LC3_MAX_FRAME_BYTES); + + switch (fmt) { + + case PcmFormat::kS16: + return encode<int16_t>(enc, nchannels, frame_size, fdp); + + case PcmFormat::kS24: { + const int32_t s24_min = -(1 << 23); + const int32_t s24_max = (1 << 23) - 1; + return encode<int32_t>(enc, nchannels, frame_size, fdp, s24_min, s24_max); + } + + case PcmFormat::kF32: { + const float f32_min = -1.0; + const float f32_max = 1.0; + return encode<float>(enc, nchannels, frame_size, fdp, f32_min, f32_max); + } + + case PcmFormat::kS24In3Le: + return encode(enc, nchannels, frame_size, fmt, fdp); + } + + return 0; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/liblc3-1.0.3/fuzz/makefile.mk new/liblc3-1.0.4/fuzz/makefile.mk --- old/liblc3-1.0.3/fuzz/makefile.mk 1970-01-01 01:00:00.000000000 +0100 +++ new/liblc3-1.0.4/fuzz/makefile.mk 2023-08-03 18:45:11.000000000 +0200 @@ -0,0 +1,52 @@ +# +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +efuzz_src += \ + $(FUZZ_DIR)/efuzz.cc + +efuzz_lib += liblc3 +efuzz_ldlibs += m + +$(eval $(call add-bin,efuzz)) + + +dfuzz_src += \ + $(FUZZ_DIR)/dfuzz.cc + +dfuzz_lib += liblc3 +dfuzz_ldlibs += m + +$(eval $(call add-bin,dfuzz)) + + +.PHONY: fuzz dfuzz efuzz + +efuzz dfuzz: CC = clang +efuzz dfuzz: CXX = clang++ +efuzz dfuzz: LD = clang + +FUZZER_SANITIZE := -fsanitize=fuzzer,address +efuzz dfuzz: CFLAGS += $(FUZZER_SANITIZE) +efuzz dfuzz: CXXFLAGS += $(FUZZER_SANITIZE) +efuzz dfuzz: LDFLAGS += $(FUZZER_SANITIZE) + +dfuzz: + $(V)$(dfuzz_bin) -runs=1000000 + +efuzz: + $(V)$(efuzz_bin) -runs=1000000 + +fuzz: efuzz dfuzz diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/liblc3-1.0.3/include/lc3_cpp.h new/liblc3-1.0.4/include/lc3_cpp.h --- old/liblc3-1.0.3/include/lc3_cpp.h 2023-05-08 19:53:53.000000000 +0200 +++ new/liblc3-1.0.4/include/lc3_cpp.h 2023-08-03 18:45:11.000000000 +0200 @@ -26,6 +26,7 @@ #include <cassert> #include <memory> #include <vector> +#include <stdlib.h> #include "lc3.h" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/liblc3-1.0.3/meson.build new/liblc3-1.0.4/meson.build --- old/liblc3-1.0.3/meson.build 2023-05-08 19:53:53.000000000 +0200 +++ new/liblc3-1.0.4/meson.build 2023-08-03 18:45:11.000000000 +0200 @@ -13,7 +13,7 @@ # limitations under the License. project('lc3', 'c', - version: '1.0.3', + version: '1.0.4', license: 'Apache-2.0', meson_version: '>= 0.47.0', default_options: ['b_lto=true']) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/liblc3-1.0.3/src/spec.c new/liblc3-1.0.4/src/spec.c --- old/liblc3-1.0.3/src/spec.c 2023-05-08 19:53:53.000000000 +0200 +++ new/liblc3-1.0.4/src/spec.c 2023-08-03 18:45:11.000000000 +0200 @@ -44,11 +44,12 @@ * nbits_off Offset on the available bits, temporarily smoothed * g_off Gain index offset * reset_off Return True when the nbits_off must be reset + * g_min Return lower bound of quantized gain value * return The quantized gain value */ LC3_HOT static int estimate_gain( enum lc3_dt dt, enum lc3_srate sr, const float *x, - int nbits_budget, float nbits_off, int g_off, bool *reset_off) + int nbits_budget, float nbits_off, int g_off, bool *reset_off, int *g_min) { int ne = LC3_NE(dt, sr) >> 2; int e[LC3_MAX_NE]; @@ -102,12 +103,12 @@ /* --- Limit gain index --- */ - int g_min = x2_max == 0 ? -g_off : + *g_min = x2_max == 0 ? -g_off : ceilf(28 * log10f(sqrtf(x2_max) / (32768 - 0.375f))); - *reset_off = g_int < g_min || x2_max == 0; + *reset_off = g_int < *g_min || x2_max == 0; if (*reset_off) - g_int = g_min; + g_int = *g_min; return g_int; } @@ -118,10 +119,11 @@ * g_idx The estimated quantized gain index * nbits Computed number of bits coding the spectrum * nbits_budget Number of bits available for coding the spectrum + * g_idx_min Minimum gain index value * return Gain adjust value (-1 to 2) */ -LC3_HOT static int adjust_gain( - enum lc3_srate sr, int g_idx, int nbits, int nbits_budget) +LC3_HOT static int adjust_gain(enum lc3_srate sr, int g_idx, + int nbits, int nbits_budget, int g_idx_min) { /* --- Compute delta threshold --- */ @@ -149,7 +151,7 @@ /* --- Adjust gain --- */ if (nbits < nbits_budget - (delta + 2)) - return -(g_idx > 0); + return -(g_idx > g_idx_min); if (nbits > nbits_budget) return (g_idx < 255) + (g_idx < 254 && nbits >= nbits_budget + delta); @@ -789,8 +791,8 @@ int g_off = resolve_gain_offset(sr, nbytes); - int g_int = estimate_gain(dt, sr, - x, nbits_budget, nbits_off, g_off, &reset_off); + int g_min, g_int = estimate_gain(dt, sr, + x, nbits_budget, nbits_off, g_off, &reset_off, &g_min); /* --- Quantization --- */ @@ -803,7 +805,8 @@ /* --- Adjust gain and requantize --- */ - int g_adj = adjust_gain(sr, g_int + g_off, nbits, nbits_budget); + int g_adj = adjust_gain(sr, g_off + g_int, + nbits, nbits_budget, g_off + g_min); if (g_adj) quantize(dt, sr, g_adj, x, xq, &side->nq); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/liblc3-1.0.3/test/spec.py new/liblc3-1.0.4/test/spec.py --- old/liblc3-1.0.3/test/spec.py 2023-05-08 19:53:53.000000000 +0200 +++ new/liblc3-1.0.4/test/spec.py 2023-08-03 18:45:11.000000000 +0200 @@ -589,7 +589,7 @@ (g_int, reset_off) = \ analysis.estimate_gain(x, nbits_budget, nbits_off, g_off) - (g_int_c, reset_off_c) = lc3.spec_estimate_gain( + (g_int_c, reset_off_c, _) = lc3.spec_estimate_gain( dt, sr, x, nbits_budget, nbits_off, -g_off) ok = ok and g_int_c == g_int @@ -664,7 +664,7 @@ g_adj = analysis.adjust_gain(g_idx, nbits, nbits_budget) - g_adj_c = lc3.spec_adjust_gain(sr, g_idx, nbits, nbits_budget) + g_adj_c = lc3.spec_adjust_gain(sr, g_idx, nbits, nbits_budget, 0) ok = ok and g_adj_c == g_adj @@ -752,7 +752,7 @@ ok = ok and nbits == C.NBITS_EST[dt][i] g_adj = lc3.spec_adjust_gain(sr, - C.GG_IND[dt][i], C.NBITS_EST[dt][i], C.NBITS_SPEC[dt][i]) + C.GG_IND[dt][i], C.NBITS_EST[dt][i], C.NBITS_SPEC[dt][i], 0) ok = ok and g_adj == C.GG_IND_ADJ[dt][i] - C.GG_IND[dt][i] if C.GG_IND_ADJ[dt][i] != C.GG_IND[dt][i]: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/liblc3-1.0.3/test/spec_py.c new/liblc3-1.0.4/test/spec_py.c --- old/liblc3-1.0.3/test/spec_py.c 2023-05-08 19:53:53.000000000 +0200 +++ new/liblc3-1.0.4/test/spec_py.c 2023-08-03 18:45:11.000000000 +0200 @@ -30,7 +30,7 @@ float *x; int nbits_budget; float nbits_off; - int g_off; + int g_off, g_min; bool reset_off; if (!PyArg_ParseTuple(args, "IIOifi", &dt, &sr, @@ -45,23 +45,24 @@ CTYPES_CHECK("x", x_obj = to_1d_ptr(x_obj, NPY_FLOAT, ne, &x)); int g_int = estimate_gain(dt, sr, - x, nbits_budget, nbits_off, g_off, &reset_off); + x, nbits_budget, nbits_off, g_off, &reset_off, &g_min); - return Py_BuildValue("ii", g_int, reset_off); + return Py_BuildValue("iii", g_int, reset_off, g_min); } static PyObject *adjust_gain_py(PyObject *m, PyObject *args) { unsigned sr; - int g_idx, nbits, nbits_budget; + int g_idx, nbits, nbits_budget, g_idx_min; - if (!PyArg_ParseTuple(args, "Iiii", &sr, &g_idx, &nbits, &nbits_budget)) + if (!PyArg_ParseTuple(args, "Iiiii", &sr, &g_idx, + &nbits, &nbits_budget, &g_idx_min)) return NULL; CTYPES_CHECK("sr", (unsigned)sr < LC3_NUM_SRATE); CTYPES_CHECK("g_idx", g_idx >= 0 && g_idx <= 255); - g_idx = adjust_gain(sr, g_idx, nbits, nbits_budget); + g_idx = adjust_gain(sr, g_idx, nbits, nbits_budget, g_idx_min); return Py_BuildValue("i", g_idx); } ++++++ liblc3.obsinfo ++++++ --- /var/tmp/diff_new_pack.x0ei80/_old 2023-08-05 12:54:55.180583968 +0200 +++ /var/tmp/diff_new_pack.x0ei80/_new 2023-08-05 12:54:55.184583994 +0200 @@ -1,5 +1,5 @@ name: liblc3 -version: 1.0.3 -mtime: 1683568433 -commit: 3d769309ffacb3c18b4a0bdd6b46544eb26bbfb2 +version: 1.0.4 +mtime: 1691081111 +commit: 1a5938ebaca4f13fe79ce074f5dee079783aa29f