Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ LAC_THREADS=4 ctest --test-dir build-tests --output-on-failure

The default CTest configuration uses lightweight generated WAV fixtures and exercises both internal codec paths and `lac_cli` subprocess roundtrips. To opt into larger local E2E fixtures, configure with `-DLAC_TEST_ASSETS_DIR="$PWD/assets"`. The generated fixtures keep clean checkouts and routine development self-contained.

Set `LAC_THREADS=N` to cap encode and decode worker threads during tests. The heavier `test_all.sh` asset roundtrip script defaults to `LAC_THREADS=12` unless the environment already sets a different value.
Set `LAC_THREADS=N` to cap encode and decode worker threads in the `lac_cli` binary; `--threads=N` takes precedence over it. This is resolved by the CLI, so it applies to `lac_cli` usage and the CLI subprocess tests (the internal codec unit tests set their own thread counts). The heavier `test_all.sh` asset roundtrip script defaults to `LAC_THREADS=12` unless the environment already sets a different value.

## Contributing

Expand Down
3 changes: 1 addition & 2 deletions src/codec/lac/decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include <thread>
#include "codec/block/decoder.hpp"
#include "codec/bitstream/bit_reader.hpp"
#include "codec/lac/thread_limit.hpp"
#include "codec/simd/neon.hpp"

namespace LAC {
Expand Down Expand Up @@ -236,7 +235,7 @@ void Decoder::decode(const uint8_t* data,

size_t hardware_threads =
std::max<size_t>(1, static_cast<size_t>(std::thread::hardware_concurrency()));
const size_t thread_limit = LAC::resolve_thread_limit(this->thread_count);
const size_t thread_limit = this->thread_count; // 0 = auto; env is resolved by the CLI
if (thread_limit > 0) {
hardware_threads = std::min(hardware_threads, thread_limit);
}
Expand Down
3 changes: 1 addition & 2 deletions src/codec/lac/encoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <utility>
#include <iostream>
#include "codec/simd/neon.hpp"
#include "codec/lac/thread_limit.hpp"
#include "utils/logger.hpp"

namespace {
Expand Down Expand Up @@ -384,7 +383,7 @@ namespace LAC {
};

size_t hardware_threads = std::max<size_t>(1, static_cast<size_t>(std::thread::hardware_concurrency()));
const size_t thread_limit = LAC::resolve_thread_limit(this->thread_count);
const size_t thread_limit = this->thread_count; // 0 = auto; env is resolved by the CLI
if (thread_limit > 0) {
hardware_threads = std::min(hardware_threads, thread_limit);
}
Expand Down
7 changes: 3 additions & 4 deletions src/codec/lac/thread_limit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ inline size_t parse_thread_limit(const char* value) {
return static_cast<size_t>(parsed);
}

inline size_t resolve_thread_limit(size_t explicit_limit) {
if (explicit_limit > 0) return explicit_limit;
return parse_thread_limit(std::getenv("LAC_THREADS"));
}
// Note: this header intentionally no longer resolves LAC_THREADS. Reading the
// environment is the CLI's job; the library uses the explicit thread count it
// is given (0 = auto). See main.cpp resolve_cli_thread_count.

} // namespace LAC
15 changes: 12 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <atomic>
#include <cerrno>
#include <cstdint>
#include <cstdlib>
#include <vector>
#include <string>
#include <cmath>
Expand Down Expand Up @@ -315,9 +316,8 @@ static FastDecodeStatus decode_lac_v3_to_mapped_wav(const uint8_t* data,

size_t hardware_threads =
std::max<size_t>(1, static_cast<size_t>(std::thread::hardware_concurrency()));
const size_t resolved_limit = LAC::resolve_thread_limit(thread_count);
if (resolved_limit > 0) {
hardware_threads = std::min(hardware_threads, resolved_limit);
if (thread_count > 0) {
hardware_threads = std::min(hardware_threads, thread_count);
}
const size_t worker_count = std::min<size_t>(hardware_threads, block_count);

Expand Down Expand Up @@ -583,6 +583,13 @@ static bool parse_threads_flag(const std::string& flag, size_t& out_threads) {
return true;
}

static size_t resolve_cli_thread_count(size_t explicit_count) {
// CLI owns environment resolution: --threads (explicit_count) wins, else
// LAC_THREADS. The library never reads the environment itself.
if (explicit_count > 0) return explicit_count;
return LAC::parse_thread_limit(std::getenv("LAC_THREADS"));
}

static void usage() {
std::cerr << "Usage:\n";
std::cerr << " lac_cli encode input.wav output.lac [--stereo-mode=lr|ms] [--threads=N] [--debug-threads] [--debug-lpc] [--debug-stereo-est] [--debug-zr] [--debug-partitions] [--no-partitioning]\n";
Expand Down Expand Up @@ -643,6 +650,7 @@ int main(int argc, char** argv) {
return 1;
}
}
thread_count = resolve_cli_thread_count(thread_count);
std::vector<int32_t> left, right;
uint16_t channels = 0;
uint32_t sample_rate = 0;
Expand Down Expand Up @@ -725,6 +733,7 @@ int main(int argc, char** argv) {
return 1;
}
}
thread_count = resolve_cli_thread_count(thread_count);
std::vector<uint8_t> bitstream;
if (!load_file(in_path, bitstream)) {
std::cerr << "Failed to read LAC file: " << in_path << "\n";
Expand Down
Loading