mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
TAD: working kotlin decoder
This commit is contained in:
@@ -312,7 +312,7 @@ static void dwt_dd4_inverse_1d(float *data, int length) {
|
||||
free(temp);
|
||||
}
|
||||
|
||||
static void dwt_haar_inverse_multilevel(float *data, int length, int levels) {
|
||||
static void dwt_inverse_multilevel(float *data, int length, int levels) {
|
||||
// Calculate the length at the deepest level (size of low-pass after all forward DWTs)
|
||||
int current_length = length;
|
||||
for (int level = 0; level < levels; level++) {
|
||||
@@ -588,8 +588,8 @@ static int decode_chunk(const uint8_t *input, size_t input_size, uint8_t *pcmu8_
|
||||
dequantize_dwt_coefficients(quant_side, dwt_side, sample_count, sample_count, dwt_levels, max_index, quantiser_scale);
|
||||
|
||||
// Inverse DWT
|
||||
dwt_haar_inverse_multilevel(dwt_mid, sample_count, dwt_levels);
|
||||
dwt_haar_inverse_multilevel(dwt_side, sample_count, dwt_levels);
|
||||
dwt_inverse_multilevel(dwt_mid, sample_count, dwt_levels);
|
||||
dwt_inverse_multilevel(dwt_side, sample_count, dwt_levels);
|
||||
|
||||
float err[2][2] = {{0,0},{0,0}};
|
||||
|
||||
|
||||
@@ -36,9 +36,8 @@ static const float BASE_QUANTISER_WEIGHTS[] = {
|
||||
|
||||
// Forward declarations for internal functions
|
||||
static void dwt_dd4_forward_1d(float *data, int length);
|
||||
static void dwt_dd4_forward_multilevel(float *data, int length, int levels);
|
||||
static void dwt_forward_multilevel(float *data, int length, int levels);
|
||||
static void quantize_dwt_coefficients(const float *coeffs, int8_t *quantized, size_t count, int apply_deadzone, int chunk_size, int dwt_levels, int quant_bits, int *current_subband_index, float quantiser_scale);
|
||||
static size_t encode_twobitmap(const int8_t *values, size_t count, uint8_t *output);
|
||||
|
||||
static inline float FCLAMP(float x, float min, float max) {
|
||||
return x < min ? min : (x > max ? max : x);
|
||||
@@ -190,7 +189,7 @@ static void dwt_97_forward_1d(float *data, int length) {
|
||||
}
|
||||
|
||||
// Apply multi-level DWT (using DD-4 wavelet)
|
||||
static void dwt_dd4_forward_multilevel(float *data, int length, int levels) {
|
||||
static void dwt_forward_multilevel(float *data, int length, int levels) {
|
||||
int current_length = length;
|
||||
for (int level = 0; level < levels; level++) {
|
||||
// dwt_dd4_forward_1d(data, current_length);
|
||||
@@ -315,61 +314,6 @@ static void quantize_dwt_coefficients(const float *coeffs, int8_t *quantized, si
|
||||
free(sideband_starts);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Twobit-map Significance Map Encoding
|
||||
//=============================================================================
|
||||
|
||||
// Twobit-map encoding: 2 bits per coefficient for common values
|
||||
// 00 = 0
|
||||
// 01 = +1
|
||||
// 10 = -1
|
||||
// 11 = other value (followed by int8_t in separate array)
|
||||
static size_t encode_twobitmap(const int8_t *values, size_t count, uint8_t *output) {
|
||||
// Calculate size needed for twobit map
|
||||
size_t map_bytes = (count * 2 + 7) / 8; // 2 bits per coefficient
|
||||
|
||||
// First pass: create significance map and count "other" values
|
||||
uint8_t *map = output;
|
||||
memset(map, 0, map_bytes);
|
||||
|
||||
size_t other_count = 0;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
int8_t val = values[i];
|
||||
uint8_t code;
|
||||
|
||||
if (val == 0) {
|
||||
code = 0; // 00
|
||||
} else if (val == 1) {
|
||||
code = 1; // 01
|
||||
} else if (val == -1) {
|
||||
code = 2; // 10
|
||||
} else {
|
||||
code = 3; // 11
|
||||
other_count++;
|
||||
}
|
||||
|
||||
// Write 2-bit code into map
|
||||
size_t bit_offset = i * 2;
|
||||
size_t byte_idx = bit_offset / 8;
|
||||
size_t bit_in_byte = bit_offset % 8;
|
||||
|
||||
map[byte_idx] |= (code << bit_in_byte);
|
||||
}
|
||||
|
||||
// Second pass: write "other" values
|
||||
int8_t *other_values = (int8_t*)(output + map_bytes);
|
||||
size_t other_idx = 0;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
int8_t val = values[i];
|
||||
if (val != 0 && val != 1 && val != -1) {
|
||||
other_values[other_idx++] = val;
|
||||
}
|
||||
}
|
||||
|
||||
return map_bytes + other_count;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Coefficient Statistics
|
||||
//=============================================================================
|
||||
@@ -818,8 +762,8 @@ size_t tad32_encode_chunk(const float *pcm32_stereo, size_t num_samples,
|
||||
dwt_side[i] = pcm32_side[i];
|
||||
}
|
||||
|
||||
dwt_dd4_forward_multilevel(dwt_mid, num_samples, dwt_levels);
|
||||
dwt_dd4_forward_multilevel(dwt_side, num_samples, dwt_levels);
|
||||
dwt_forward_multilevel(dwt_mid, num_samples, dwt_levels);
|
||||
dwt_forward_multilevel(dwt_side, num_samples, dwt_levels);
|
||||
|
||||
// Step 3.5: Accumulate coefficient statistics if enabled
|
||||
static int stats_enabled = -1;
|
||||
|
||||
@@ -48,8 +48,13 @@ static void print_usage(const char *prog_name) {
|
||||
printf("Options:\n");
|
||||
printf(" -i <file> Input audio file (any format supported by FFmpeg)\n");
|
||||
printf(" -o <file> Output TAD32 file (optional, auto-generated as input.qN.tad)\n");
|
||||
printf(" -q <bits> Positive side quantization steps (default: 47, range: up to 127)\n");
|
||||
printf(" Higher = more precision, larger files\n");
|
||||
printf(" -q <level> Quality level (0-5, default: %d)\n", TAD32_QUALITY_DEFAULT);
|
||||
printf(" 0 = lowest quality/smallest (max_index=31)\n");
|
||||
printf(" 1 = low quality (max_index=35)\n");
|
||||
printf(" 2 = medium quality (max_index=39)\n");
|
||||
printf(" 3 = good quality (max_index=47) [DEFAULT]\n");
|
||||
printf(" 4 = high quality (max_index=56)\n");
|
||||
printf(" 5 = very high quality/largest (max_index=89)\n");
|
||||
printf(" -s <scale> Quantiser scaling factor (default: 1.0, range: 0.5-4.0)\n");
|
||||
printf(" Higher = more aggressive quantization, smaller files\n");
|
||||
printf(" 2.0 = quantize 2x coarser than baseline\n");
|
||||
@@ -65,7 +70,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
char *input_file = NULL;
|
||||
char *output_file = NULL;
|
||||
int max_index = 47; // Default QUANT_BITS
|
||||
int quality = TAD32_QUALITY_DEFAULT; // Default quality level (0-5)
|
||||
float quantiser_scale = 1.0f; // Default quantiser scaling
|
||||
int verbose = 0;
|
||||
|
||||
@@ -86,7 +91,11 @@ int main(int argc, char *argv[]) {
|
||||
output_file = optarg;
|
||||
break;
|
||||
case 'q':
|
||||
max_index = atoi(optarg);
|
||||
quality = atoi(optarg);
|
||||
if (quality < TAD32_QUALITY_MIN || quality > TAD32_QUALITY_MAX) {
|
||||
fprintf(stderr, "Error: Quality must be in range %d-%d\n", TAD32_QUALITY_MIN, TAD32_QUALITY_MAX);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
quantiser_scale = atof(optarg);
|
||||
@@ -113,6 +122,9 @@ int main(int argc, char *argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Convert quality (0-5) to max_index for quantization
|
||||
int max_index = tad32_quality_to_max_index(quality);
|
||||
|
||||
// Generate output filename if not provided
|
||||
if (!output_file) {
|
||||
// Allocate space for output filename
|
||||
@@ -140,8 +152,8 @@ int main(int argc, char *argv[]) {
|
||||
strcpy(output_file + dir_len, basename_start);
|
||||
}
|
||||
|
||||
// Append .qNN.tad
|
||||
sprintf(output_file + strlen(output_file), ".q%d.tad", max_index);
|
||||
// Append .qNN.tad (use quality level for filename)
|
||||
sprintf(output_file + strlen(output_file), ".q%d.tad", quality);
|
||||
|
||||
if (verbose) {
|
||||
printf("Auto-generated output path: %s\n", output_file);
|
||||
@@ -152,7 +164,7 @@ int main(int argc, char *argv[]) {
|
||||
printf("%s\n", ENCODER_VENDOR_STRING);
|
||||
printf("Input: %s\n", input_file);
|
||||
printf("Output: %s\n", output_file);
|
||||
printf("Quant bits: %d\n", max_index);
|
||||
printf("Quality level: %d (max_index=%d)\n", quality, max_index);
|
||||
printf("Quantiser scale: %.2f\n", quantiser_scale);
|
||||
}
|
||||
|
||||
|
||||
@@ -9041,7 +9041,7 @@ static int write_tad_packet_samples(tav_encoder_t *enc, FILE *output, int sample
|
||||
|
||||
if (enc->verbose) {
|
||||
printf("TAD32 packet: %d samples, %u bytes compressed (Q%d)\n",
|
||||
sample_count, tad_payload_size, tad_quality);
|
||||
sample_count, tad_payload_size, quant_size);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
|
||||
Reference in New Issue
Block a user