mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
x64 build for wavpack, library updated to 4.5.0
This commit is contained in:
271
wavpack-4.5.0/src/bits.c
Normal file
271
wavpack-4.5.0/src/bits.c
Normal file
@@ -0,0 +1,271 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// **** WAVPACK **** //
|
||||
// Hybrid Lossless Wavefile Compressor //
|
||||
// Copyright (c) 1998 - 2006 Conifer Software. //
|
||||
// All Rights Reserved. //
|
||||
// Distributed under the BSD Software License (see license.txt) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// bits.c
|
||||
|
||||
// This module provides utilities to support the BitStream structure which is
|
||||
// used to read and write all WavPack audio data streams. It also contains a
|
||||
// wrapper for the stream I/O functions and a set of functions dealing with
|
||||
// endian-ness, both for enhancing portability. Finally, a debug wrapper for
|
||||
// the malloc() system is provided.
|
||||
|
||||
#include "wavpack_local.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
////////////////////////// Bitstream functions ////////////////////////////////
|
||||
|
||||
#if !defined(NO_UNPACK) || defined(INFO_ONLY)
|
||||
|
||||
// Open the specified BitStream and associate with the specified buffer.
|
||||
|
||||
static void bs_read (Bitstream *bs);
|
||||
|
||||
void bs_open_read (Bitstream *bs, void *buffer_start, void *buffer_end)
|
||||
{
|
||||
bs->error = bs->sr = bs->bc = 0;
|
||||
bs->ptr = (bs->buf = buffer_start) - 1;
|
||||
bs->end = buffer_end;
|
||||
bs->wrap = bs_read;
|
||||
}
|
||||
|
||||
// This function is only called from the getbit() and getbits() macros when
|
||||
// the BitStream has been exhausted and more data is required. Sinve these
|
||||
// bistreams no longer access files, this function simple sets an error and
|
||||
// resets the buffer.
|
||||
|
||||
static void bs_read (Bitstream *bs)
|
||||
{
|
||||
bs->ptr = bs->buf - 1;
|
||||
bs->error = 1;
|
||||
}
|
||||
|
||||
// This function is called to close the bitstream. It returns the number of
|
||||
// full bytes actually read as bits.
|
||||
|
||||
uint32_t bs_close_read (Bitstream *bs)
|
||||
{
|
||||
uint32_t bytes_read;
|
||||
|
||||
if (bs->bc < sizeof (*(bs->ptr)) * 8)
|
||||
bs->ptr++;
|
||||
|
||||
bytes_read = (uint32_t)(bs->ptr - bs->buf) * sizeof (*(bs->ptr));
|
||||
|
||||
if (!(bytes_read & 1))
|
||||
++bytes_read;
|
||||
|
||||
CLEAR (*bs);
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef NO_PACK
|
||||
|
||||
// Open the specified BitStream using the specified buffer pointers. It is
|
||||
// assumed that enough buffer space has been allocated for all data that will
|
||||
// be written, otherwise an error will be generated.
|
||||
|
||||
static void bs_write (Bitstream *bs);
|
||||
|
||||
void bs_open_write (Bitstream *bs, void *buffer_start, void *buffer_end)
|
||||
{
|
||||
bs->error = bs->sr = bs->bc = 0;
|
||||
bs->ptr = bs->buf = buffer_start;
|
||||
bs->end = buffer_end;
|
||||
bs->wrap = bs_write;
|
||||
}
|
||||
|
||||
// This function is only called from the putbit() and putbits() macros when
|
||||
// the buffer is full, which is now flagged as an error.
|
||||
|
||||
static void bs_write (Bitstream *bs)
|
||||
{
|
||||
bs->ptr = bs->buf;
|
||||
bs->error = 1;
|
||||
}
|
||||
|
||||
// This function forces a flushing write of the specified BitStream, and
|
||||
// returns the total number of bytes written into the buffer.
|
||||
|
||||
uint32_t bs_close_write (Bitstream *bs)
|
||||
{
|
||||
uint32_t bytes_written;
|
||||
|
||||
if (bs->error)
|
||||
return (uint32_t) -1;
|
||||
|
||||
while (1) {
|
||||
while (bs->bc)
|
||||
putbit_1 (bs);
|
||||
|
||||
bytes_written = (uint32_t)(bs->ptr - bs->buf) * sizeof (*(bs->ptr));
|
||||
|
||||
if (bytes_written & 1) {
|
||||
putbit_1 (bs);
|
||||
}
|
||||
else
|
||||
break;
|
||||
};
|
||||
|
||||
CLEAR (*bs);
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/////////////////////// Endian Correction Routines ////////////////////////////
|
||||
|
||||
void little_endian_to_native (void *data, char *format)
|
||||
{
|
||||
uchar *cp = (uchar *) data;
|
||||
int32_t temp;
|
||||
|
||||
while (*format) {
|
||||
switch (*format) {
|
||||
case 'L':
|
||||
temp = cp [0] + ((int32_t) cp [1] << 8) + ((int32_t) cp [2] << 16) + ((int32_t) cp [3] << 24);
|
||||
* (int32_t *) cp = temp;
|
||||
cp += 4;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
temp = cp [0] + (cp [1] << 8);
|
||||
* (short *) cp = (short) temp;
|
||||
cp += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isdigit (*format))
|
||||
cp += *format - '0';
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
format++;
|
||||
}
|
||||
}
|
||||
|
||||
void native_to_little_endian (void *data, char *format)
|
||||
{
|
||||
uchar *cp = (uchar *) data;
|
||||
int32_t temp;
|
||||
|
||||
while (*format) {
|
||||
switch (*format) {
|
||||
case 'L':
|
||||
temp = * (int32_t *) cp;
|
||||
*cp++ = (uchar) temp;
|
||||
*cp++ = (uchar) (temp >> 8);
|
||||
*cp++ = (uchar) (temp >> 16);
|
||||
*cp++ = (uchar) (temp >> 24);
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
temp = * (short *) cp;
|
||||
*cp++ = (uchar) temp;
|
||||
*cp++ = (uchar) (temp >> 8);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isdigit (*format))
|
||||
cp += *format - '0';
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
format++;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////// Debug Wrapper for Malloc ///////////////////////////
|
||||
|
||||
#ifdef DEBUG_ALLOC
|
||||
|
||||
void *vptrs [512];
|
||||
|
||||
static void *add_ptr (void *ptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 512; ++i)
|
||||
if (!vptrs [i]) {
|
||||
vptrs [i] = ptr;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == 512)
|
||||
error_line ("too many mallocs!");
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void *del_ptr (void *ptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 512; ++i)
|
||||
if (vptrs [i] == ptr) {
|
||||
vptrs [i] = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == 512)
|
||||
error_line ("free invalid ptr!");
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *malloc_db (uint32_t size)
|
||||
{
|
||||
if (size)
|
||||
return add_ptr (malloc (size));
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_db (void *ptr)
|
||||
{
|
||||
if (ptr)
|
||||
free (del_ptr (ptr));
|
||||
}
|
||||
|
||||
void *realloc_db (void *ptr, uint32_t size)
|
||||
{
|
||||
if (ptr && size)
|
||||
return add_ptr (realloc (del_ptr (ptr), size));
|
||||
else if (size)
|
||||
return malloc_db (size);
|
||||
else
|
||||
free_db (ptr);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t dump_alloc (void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (j = i = 0; i < 512; ++i)
|
||||
if (vptrs [i])
|
||||
j++;
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
#endif
|
||||
671
wavpack-4.5.0/src/extra1.c
Normal file
671
wavpack-4.5.0/src/extra1.c
Normal file
@@ -0,0 +1,671 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// **** WAVPACK **** //
|
||||
// Hybrid Lossless Wavefile Compressor //
|
||||
// Copyright (c) 1998 - 2006 Conifer Software. //
|
||||
// All Rights Reserved. //
|
||||
// Distributed under the BSD Software License (see license.txt) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// extra1.c
|
||||
|
||||
// This module handles the "extra" mode for mono files.
|
||||
|
||||
#include "wavpack_local.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
//#define USE_OVERHEAD
|
||||
#define LOG_LIMIT 6912
|
||||
//#define EXTRA_DUMP
|
||||
|
||||
#ifdef DEBUG_ALLOC
|
||||
#define malloc malloc_db
|
||||
#define realloc realloc_db
|
||||
#define free free_db
|
||||
void *malloc_db (uint32_t size);
|
||||
void *realloc_db (void *ptr, uint32_t size);
|
||||
void free_db (void *ptr);
|
||||
int32_t dump_alloc (void);
|
||||
#endif
|
||||
|
||||
//////////////////////////////// local tables ///////////////////////////////
|
||||
|
||||
typedef struct {
|
||||
int32_t *sampleptrs [MAX_NTERMS+2];
|
||||
struct decorr_pass dps [MAX_NTERMS];
|
||||
int nterms, log_limit;
|
||||
uint32_t best_bits;
|
||||
} WavpackExtraInfo;
|
||||
|
||||
static void decorr_mono_pass (int32_t *in_samples, int32_t *out_samples, uint32_t num_samples, struct decorr_pass *dpp, int dir)
|
||||
{
|
||||
int m = 0, i;
|
||||
|
||||
dpp->sum_A = 0;
|
||||
|
||||
if (dir < 0) {
|
||||
out_samples += (num_samples - 1);
|
||||
in_samples += (num_samples - 1);
|
||||
dir = -1;
|
||||
}
|
||||
else
|
||||
dir = 1;
|
||||
|
||||
dpp->weight_A = restore_weight (store_weight (dpp->weight_A));
|
||||
|
||||
for (i = 0; i < 8; ++i)
|
||||
dpp->samples_A [i] = exp2s (log2s (dpp->samples_A [i]));
|
||||
|
||||
if (dpp->term > MAX_TERM) {
|
||||
while (num_samples--) {
|
||||
int32_t left, sam_A;
|
||||
|
||||
if (dpp->term & 1)
|
||||
sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
|
||||
else
|
||||
sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
|
||||
|
||||
dpp->samples_A [1] = dpp->samples_A [0];
|
||||
dpp->samples_A [0] = left = in_samples [0];
|
||||
|
||||
left -= apply_weight (dpp->weight_A, sam_A);
|
||||
update_weight (dpp->weight_A, dpp->delta, sam_A, left);
|
||||
dpp->sum_A += dpp->weight_A;
|
||||
out_samples [0] = left;
|
||||
in_samples += dir;
|
||||
out_samples += dir;
|
||||
}
|
||||
}
|
||||
else if (dpp->term > 0) {
|
||||
while (num_samples--) {
|
||||
int k = (m + dpp->term) & (MAX_TERM - 1);
|
||||
int32_t left, sam_A;
|
||||
|
||||
sam_A = dpp->samples_A [m];
|
||||
dpp->samples_A [k] = left = in_samples [0];
|
||||
m = (m + 1) & (MAX_TERM - 1);
|
||||
|
||||
left -= apply_weight (dpp->weight_A, sam_A);
|
||||
update_weight (dpp->weight_A, dpp->delta, sam_A, left);
|
||||
dpp->sum_A += dpp->weight_A;
|
||||
out_samples [0] = left;
|
||||
in_samples += dir;
|
||||
out_samples += dir;
|
||||
}
|
||||
}
|
||||
|
||||
if (m && dpp->term > 0 && dpp->term <= MAX_TERM) {
|
||||
int32_t temp_A [MAX_TERM];
|
||||
int k;
|
||||
|
||||
memcpy (temp_A, dpp->samples_A, sizeof (dpp->samples_A));
|
||||
|
||||
for (k = 0; k < MAX_TERM; k++) {
|
||||
dpp->samples_A [k] = temp_A [m];
|
||||
m = (m + 1) & (MAX_TERM - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void reverse_mono_decorr (struct decorr_pass *dpp)
|
||||
{
|
||||
if (dpp->term > MAX_TERM) {
|
||||
int32_t sam_A;
|
||||
|
||||
if (dpp->term & 1)
|
||||
sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
|
||||
else
|
||||
sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
|
||||
|
||||
dpp->samples_A [1] = dpp->samples_A [0];
|
||||
dpp->samples_A [0] = sam_A;
|
||||
|
||||
if (dpp->term & 1)
|
||||
sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
|
||||
else
|
||||
sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
|
||||
|
||||
dpp->samples_A [1] = sam_A;
|
||||
}
|
||||
else if (dpp->term > 1) {
|
||||
int i = 0, j = dpp->term - 1, cnt = dpp->term / 2;
|
||||
|
||||
while (cnt--) {
|
||||
i &= (MAX_TERM - 1);
|
||||
j &= (MAX_TERM - 1);
|
||||
dpp->samples_A [i] ^= dpp->samples_A [j];
|
||||
dpp->samples_A [j] ^= dpp->samples_A [i];
|
||||
dpp->samples_A [i++] ^= dpp->samples_A [j--];
|
||||
}
|
||||
|
||||
// CLEAR (dpp->samples_A);
|
||||
}
|
||||
}
|
||||
|
||||
static void decorr_mono_buffer (int32_t *samples, int32_t *outsamples, uint32_t num_samples, struct decorr_pass *dpp, int tindex)
|
||||
{
|
||||
struct decorr_pass dp, *dppi = dpp + tindex;
|
||||
int delta = dppi->delta, pre_delta, term = dppi->term;
|
||||
|
||||
if (delta == 7)
|
||||
pre_delta = 7;
|
||||
else if (delta < 2)
|
||||
pre_delta = 3;
|
||||
else
|
||||
pre_delta = delta + 1;
|
||||
|
||||
CLEAR (dp);
|
||||
dp.term = term;
|
||||
dp.delta = pre_delta;
|
||||
decorr_mono_pass (samples, outsamples, num_samples > 2048 ? 2048 : num_samples, &dp, -1);
|
||||
dp.delta = delta;
|
||||
|
||||
if (tindex == 0)
|
||||
reverse_mono_decorr (&dp);
|
||||
else
|
||||
CLEAR (dp.samples_A);
|
||||
|
||||
memcpy (dppi->samples_A, dp.samples_A, sizeof (dp.samples_A));
|
||||
dppi->weight_A = dp.weight_A;
|
||||
|
||||
if (delta == 0) {
|
||||
dp.delta = 1;
|
||||
decorr_mono_pass (samples, outsamples, num_samples, &dp, 1);
|
||||
dp.delta = 0;
|
||||
memcpy (dp.samples_A, dppi->samples_A, sizeof (dp.samples_A));
|
||||
dppi->weight_A = dp.weight_A = dp.sum_A / num_samples;
|
||||
}
|
||||
|
||||
// if (memcmp (dppi, &dp, sizeof (dp)))
|
||||
// error_line ("decorr_passes don't match, delta = %d", delta);
|
||||
|
||||
decorr_mono_pass (samples, outsamples, num_samples, &dp, 1);
|
||||
}
|
||||
|
||||
static int log2overhead (int first_term, int num_terms)
|
||||
{
|
||||
#ifdef USE_OVERHEAD
|
||||
if (first_term > MAX_TERM)
|
||||
return (4 + num_terms * 2) << 11;
|
||||
else
|
||||
return (2 + num_terms * 2) << 11;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void recurse_mono (WavpackContext *wpc, WavpackExtraInfo *info, int depth, int delta, uint32_t input_bits)
|
||||
{
|
||||
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||
int term, branches = ((wpc->config.extra_flags & EXTRA_BRANCHES) >> 6) - depth;
|
||||
int32_t *samples, *outsamples;
|
||||
uint32_t term_bits [22], bits;
|
||||
|
||||
if (branches < 1 || depth + 1 == info->nterms)
|
||||
branches = 1;
|
||||
|
||||
CLEAR (term_bits);
|
||||
samples = info->sampleptrs [depth];
|
||||
outsamples = info->sampleptrs [depth + 1];
|
||||
|
||||
for (term = 1; term <= 18; ++term) {
|
||||
if (term == 17 && branches == 1 && depth + 1 < info->nterms)
|
||||
continue;
|
||||
|
||||
if (term > 8 && term < 17)
|
||||
continue;
|
||||
|
||||
if ((wpc->config.flags & CONFIG_FAST_FLAG) && (term > 4 && term < 17))
|
||||
continue;
|
||||
|
||||
info->dps [depth].term = term;
|
||||
info->dps [depth].delta = delta;
|
||||
decorr_mono_buffer (samples, outsamples, wps->wphdr.block_samples, info->dps, depth);
|
||||
bits = log2buffer (outsamples, wps->wphdr.block_samples, info->log_limit);
|
||||
|
||||
if (bits != (uint32_t) -1)
|
||||
bits += log2overhead (info->dps [0].term, depth + 1);
|
||||
|
||||
if (bits < info->best_bits) {
|
||||
info->best_bits = bits;
|
||||
CLEAR (wps->decorr_passes);
|
||||
memcpy (wps->decorr_passes, info->dps, sizeof (info->dps [0]) * (depth + 1));
|
||||
memcpy (info->sampleptrs [info->nterms + 1], info->sampleptrs [depth + 1], wps->wphdr.block_samples * 4);
|
||||
}
|
||||
|
||||
term_bits [term + 3] = bits;
|
||||
}
|
||||
|
||||
while (depth + 1 < info->nterms && branches--) {
|
||||
uint32_t local_best_bits = input_bits;
|
||||
int best_term = 0, i;
|
||||
|
||||
for (i = 0; i < 22; ++i)
|
||||
if (term_bits [i] && term_bits [i] < local_best_bits) {
|
||||
local_best_bits = term_bits [i];
|
||||
// term_bits [i] = 0;
|
||||
best_term = i - 3;
|
||||
}
|
||||
|
||||
if (!best_term)
|
||||
break;
|
||||
|
||||
term_bits [best_term + 3] = 0;
|
||||
|
||||
info->dps [depth].term = best_term;
|
||||
info->dps [depth].delta = delta;
|
||||
decorr_mono_buffer (samples, outsamples, wps->wphdr.block_samples, info->dps, depth);
|
||||
|
||||
// if (log2buffer (outsamples, wps->wphdr.block_samples * 2, 0) != local_best_bits)
|
||||
// error_line ("data doesn't match!");
|
||||
|
||||
recurse_mono (wpc, info, depth + 1, delta, local_best_bits);
|
||||
}
|
||||
}
|
||||
|
||||
static void delta_mono (WavpackContext *wpc, WavpackExtraInfo *info)
|
||||
{
|
||||
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||
int lower = FALSE, delta, d;
|
||||
uint32_t bits;
|
||||
|
||||
if (wps->decorr_passes [0].term)
|
||||
delta = wps->decorr_passes [0].delta;
|
||||
else
|
||||
return;
|
||||
|
||||
for (d = delta - 1; d >= 0; --d) {
|
||||
int i;
|
||||
|
||||
if (!d && (wps->wphdr.flags & HYBRID_FLAG))
|
||||
break;
|
||||
|
||||
for (i = 0; i < info->nterms && wps->decorr_passes [i].term; ++i) {
|
||||
info->dps [i].term = wps->decorr_passes [i].term;
|
||||
info->dps [i].delta = d;
|
||||
decorr_mono_buffer (info->sampleptrs [i], info->sampleptrs [i+1], wps->wphdr.block_samples, info->dps, i);
|
||||
}
|
||||
|
||||
bits = log2buffer (info->sampleptrs [i], wps->wphdr.block_samples, info->log_limit);
|
||||
|
||||
if (bits != (uint32_t) -1)
|
||||
bits += log2overhead (wps->decorr_passes [0].term, i);
|
||||
|
||||
if (bits < info->best_bits) {
|
||||
lower = TRUE;
|
||||
info->best_bits = bits;
|
||||
CLEAR (wps->decorr_passes);
|
||||
memcpy (wps->decorr_passes, info->dps, sizeof (info->dps [0]) * i);
|
||||
memcpy (info->sampleptrs [info->nterms + 1], info->sampleptrs [i], wps->wphdr.block_samples * 4);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
for (d = delta + 1; !lower && d <= 7; ++d) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < info->nterms && wps->decorr_passes [i].term; ++i) {
|
||||
info->dps [i].term = wps->decorr_passes [i].term;
|
||||
info->dps [i].delta = d;
|
||||
decorr_mono_buffer (info->sampleptrs [i], info->sampleptrs [i+1], wps->wphdr.block_samples, info->dps, i);
|
||||
}
|
||||
|
||||
bits = log2buffer (info->sampleptrs [i], wps->wphdr.block_samples, info->log_limit);
|
||||
|
||||
if (bits != (uint32_t) -1)
|
||||
bits += log2overhead (wps->decorr_passes [0].term, i);
|
||||
|
||||
if (bits < info->best_bits) {
|
||||
info->best_bits = bits;
|
||||
CLEAR (wps->decorr_passes);
|
||||
memcpy (wps->decorr_passes, info->dps, sizeof (info->dps [0]) * i);
|
||||
memcpy (info->sampleptrs [info->nterms + 1], info->sampleptrs [i], wps->wphdr.block_samples * 4);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sort_mono (WavpackContext *wpc, WavpackExtraInfo *info)
|
||||
{
|
||||
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||
int reversed = TRUE;
|
||||
uint32_t bits;
|
||||
|
||||
while (reversed) {
|
||||
int ri, i;
|
||||
|
||||
memcpy (info->dps, wps->decorr_passes, sizeof (wps->decorr_passes));
|
||||
reversed = FALSE;
|
||||
|
||||
for (ri = 0; ri < info->nterms && wps->decorr_passes [ri].term; ++ri) {
|
||||
|
||||
if (ri + 1 >= info->nterms || !wps->decorr_passes [ri+1].term)
|
||||
break;
|
||||
|
||||
if (wps->decorr_passes [ri].term == wps->decorr_passes [ri+1].term) {
|
||||
decorr_mono_buffer (info->sampleptrs [ri], info->sampleptrs [ri+1], wps->wphdr.block_samples, info->dps, ri);
|
||||
continue;
|
||||
}
|
||||
|
||||
info->dps [ri] = wps->decorr_passes [ri+1];
|
||||
info->dps [ri+1] = wps->decorr_passes [ri];
|
||||
|
||||
for (i = ri; i < info->nterms && wps->decorr_passes [i].term; ++i)
|
||||
decorr_mono_buffer (info->sampleptrs [i], info->sampleptrs [i+1], wps->wphdr.block_samples, info->dps, i);
|
||||
|
||||
bits = log2buffer (info->sampleptrs [i], wps->wphdr.block_samples, info->log_limit);
|
||||
|
||||
if (bits != (uint32_t) -1)
|
||||
bits += log2overhead (wps->decorr_passes [0].term, i);
|
||||
|
||||
if (bits < info->best_bits) {
|
||||
reversed = TRUE;
|
||||
info->best_bits = bits;
|
||||
CLEAR (wps->decorr_passes);
|
||||
memcpy (wps->decorr_passes, info->dps, sizeof (info->dps [0]) * i);
|
||||
memcpy (info->sampleptrs [info->nterms + 1], info->sampleptrs [i], wps->wphdr.block_samples * 4);
|
||||
}
|
||||
else {
|
||||
info->dps [ri] = wps->decorr_passes [ri];
|
||||
info->dps [ri+1] = wps->decorr_passes [ri+1];
|
||||
decorr_mono_buffer (info->sampleptrs [ri], info->sampleptrs [ri+1], wps->wphdr.block_samples, info->dps, ri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const uint32_t xtable [] = { 91, 123, 187, 251 };
|
||||
|
||||
static void analyze_mono (WavpackContext *wpc, int32_t *samples, int do_samples)
|
||||
{
|
||||
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||
WavpackExtraInfo info;
|
||||
int i;
|
||||
|
||||
#ifdef LOG_LIMIT
|
||||
info.log_limit = (((wps->wphdr.flags & MAG_MASK) >> MAG_LSB) + 4) * 256;
|
||||
|
||||
if (info.log_limit > LOG_LIMIT)
|
||||
info.log_limit = LOG_LIMIT;
|
||||
#else
|
||||
info.log_limit = 0;
|
||||
#endif
|
||||
|
||||
if (wpc->config.flags & (CONFIG_HIGH_FLAG | CONFIG_VERY_HIGH_FLAG))
|
||||
wpc->config.extra_flags = xtable [wpc->config.xmode - 4];
|
||||
else
|
||||
wpc->config.extra_flags = xtable [wpc->config.xmode - 3];
|
||||
|
||||
info.nterms = wps->num_terms;
|
||||
|
||||
for (i = 0; i < info.nterms + 2; ++i)
|
||||
info.sampleptrs [i] = malloc (wps->wphdr.block_samples * 4);
|
||||
|
||||
memcpy (info.dps, wps->decorr_passes, sizeof (info.dps));
|
||||
memcpy (info.sampleptrs [0], samples, wps->wphdr.block_samples * 4);
|
||||
|
||||
for (i = 0; i < info.nterms && info.dps [i].term; ++i)
|
||||
decorr_mono_pass (info.sampleptrs [i], info.sampleptrs [i + 1], wps->wphdr.block_samples, info.dps + i, 1);
|
||||
|
||||
info.best_bits = log2buffer (info.sampleptrs [info.nterms], wps->wphdr.block_samples, 0) * 1;
|
||||
info.best_bits += log2overhead (info.dps [0].term, i);
|
||||
memcpy (info.sampleptrs [info.nterms + 1], info.sampleptrs [i], wps->wphdr.block_samples * 4);
|
||||
|
||||
if (wpc->config.extra_flags & EXTRA_BRANCHES)
|
||||
recurse_mono (wpc, &info, 0, (int) floor (wps->delta_decay + 0.5),
|
||||
log2buffer (info.sampleptrs [0], wps->wphdr.block_samples, 0));
|
||||
|
||||
if (wpc->config.extra_flags & EXTRA_SORT_FIRST)
|
||||
sort_mono (wpc, &info);
|
||||
|
||||
if (wpc->config.extra_flags & EXTRA_TRY_DELTAS) {
|
||||
delta_mono (wpc, &info);
|
||||
|
||||
if ((wpc->config.extra_flags & EXTRA_ADJUST_DELTAS) && wps->decorr_passes [0].term)
|
||||
wps->delta_decay = (float)((wps->delta_decay * 2.0 + wps->decorr_passes [0].delta) / 3.0);
|
||||
else
|
||||
wps->delta_decay = 2.0;
|
||||
}
|
||||
|
||||
if (wpc->config.extra_flags & EXTRA_SORT_LAST)
|
||||
sort_mono (wpc, &info);
|
||||
|
||||
if (do_samples)
|
||||
memcpy (samples, info.sampleptrs [info.nterms + 1], wps->wphdr.block_samples * 4);
|
||||
|
||||
for (i = 0; i < info.nterms; ++i)
|
||||
if (!wps->decorr_passes [i].term)
|
||||
break;
|
||||
|
||||
wps->num_terms = i;
|
||||
|
||||
for (i = 0; i < info.nterms + 2; ++i)
|
||||
free (info.sampleptrs [i]);
|
||||
}
|
||||
|
||||
static void mono_add_noise (WavpackStream *wps, int32_t *lptr, int32_t *rptr)
|
||||
{
|
||||
int shaping_weight, new = wps->wphdr.flags & NEW_SHAPING;
|
||||
short *shaping_array = wps->dc.shaping_array;
|
||||
int32_t error = 0, temp, cnt;
|
||||
|
||||
scan_word (wps, rptr, wps->wphdr.block_samples, -1);
|
||||
cnt = wps->wphdr.block_samples;
|
||||
|
||||
if (wps->wphdr.flags & HYBRID_SHAPE) {
|
||||
while (cnt--) {
|
||||
if (shaping_array)
|
||||
shaping_weight = *shaping_array++;
|
||||
else
|
||||
shaping_weight = (wps->dc.shaping_acc [0] += wps->dc.shaping_delta [0]) >> 16;
|
||||
|
||||
temp = -apply_weight (shaping_weight, error);
|
||||
|
||||
if (new && shaping_weight < 0 && temp) {
|
||||
if (temp == error)
|
||||
temp = (temp < 0) ? temp + 1 : temp - 1;
|
||||
|
||||
lptr [0] += (error = nosend_word (wps, rptr [0], 0) - rptr [0] + temp);
|
||||
}
|
||||
else
|
||||
lptr [0] += (error = nosend_word (wps, rptr [0], 0) - rptr [0]) + temp;
|
||||
|
||||
lptr++;
|
||||
rptr++;
|
||||
}
|
||||
|
||||
if (!shaping_array)
|
||||
wps->dc.shaping_acc [0] -= wps->dc.shaping_delta [0] * wps->wphdr.block_samples;
|
||||
}
|
||||
else
|
||||
while (cnt--) {
|
||||
lptr [0] += nosend_word (wps, rptr [0], 0) - rptr [0];
|
||||
lptr++;
|
||||
rptr++;
|
||||
}
|
||||
}
|
||||
|
||||
void execute_mono (WavpackContext *wpc, int32_t *samples, int no_history, int do_samples)
|
||||
{
|
||||
int32_t *temp_buffer [2], *best_buffer, *noisy_buffer = NULL;
|
||||
struct decorr_pass temp_decorr_pass, save_decorr_passes [MAX_NTERMS];
|
||||
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||
int32_t num_samples = wps->wphdr.block_samples;
|
||||
int32_t buf_size = sizeof (int32_t) * num_samples;
|
||||
uint32_t best_size = (uint32_t) -1, size;
|
||||
int log_limit, pi, i;
|
||||
|
||||
for (i = 0; i < num_samples; ++i)
|
||||
if (samples [i])
|
||||
break;
|
||||
|
||||
if (i == num_samples) {
|
||||
CLEAR (wps->decorr_passes);
|
||||
wps->num_terms = 0;
|
||||
init_words (wps);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef LOG_LIMIT
|
||||
log_limit = (((wps->wphdr.flags & MAG_MASK) >> MAG_LSB) + 4) * 256;
|
||||
|
||||
if (log_limit > LOG_LIMIT)
|
||||
log_limit = LOG_LIMIT;
|
||||
#else
|
||||
log_limit = 0;
|
||||
#endif
|
||||
|
||||
CLEAR (save_decorr_passes);
|
||||
temp_buffer [0] = malloc (buf_size);
|
||||
temp_buffer [1] = malloc (buf_size);
|
||||
best_buffer = malloc (buf_size);
|
||||
|
||||
if (wps->num_passes > 1 && (wps->wphdr.flags & HYBRID_FLAG)) {
|
||||
CLEAR (temp_decorr_pass);
|
||||
temp_decorr_pass.delta = 2;
|
||||
temp_decorr_pass.term = 18;
|
||||
|
||||
decorr_mono_pass (samples, temp_buffer [0],
|
||||
num_samples > 2048 ? 2048 : num_samples, &temp_decorr_pass, -1);
|
||||
|
||||
reverse_mono_decorr (&temp_decorr_pass);
|
||||
decorr_mono_pass (samples, temp_buffer [0], num_samples, &temp_decorr_pass, 1);
|
||||
CLEAR (temp_decorr_pass);
|
||||
temp_decorr_pass.delta = 2;
|
||||
temp_decorr_pass.term = 17;
|
||||
|
||||
decorr_mono_pass (temp_buffer [0], temp_buffer [1],
|
||||
num_samples > 2048 ? 2048 : num_samples, &temp_decorr_pass, -1);
|
||||
|
||||
decorr_mono_pass (temp_buffer [0], temp_buffer [1], num_samples, &temp_decorr_pass, 1);
|
||||
noisy_buffer = malloc (buf_size);
|
||||
memcpy (noisy_buffer, samples, buf_size);
|
||||
mono_add_noise (wps, noisy_buffer, temp_buffer [1]);
|
||||
no_history = 1;
|
||||
}
|
||||
|
||||
if (no_history || wps->num_passes >= 7)
|
||||
wps->best_decorr = wps->mask_decorr = 0;
|
||||
|
||||
for (pi = 0; pi < wps->num_passes;) {
|
||||
const WavpackDecorrSpec *wpds;
|
||||
int nterms, c, j;
|
||||
|
||||
if (!pi)
|
||||
c = wps->best_decorr;
|
||||
else {
|
||||
if (wps->mask_decorr == 0)
|
||||
c = 0;
|
||||
else
|
||||
c = (wps->best_decorr & (wps->mask_decorr - 1)) | wps->mask_decorr;
|
||||
|
||||
if (c == wps->best_decorr) {
|
||||
wps->mask_decorr = wps->mask_decorr ? ((wps->mask_decorr << 1) & (wps->num_decorrs - 1)) : 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
wpds = &wps->decorr_specs [c];
|
||||
nterms = (int) strlen (wpds->terms);
|
||||
|
||||
while (1) {
|
||||
memcpy (temp_buffer [0], noisy_buffer ? noisy_buffer : samples, buf_size);
|
||||
CLEAR (save_decorr_passes);
|
||||
|
||||
for (j = 0; j < nterms; ++j) {
|
||||
CLEAR (temp_decorr_pass);
|
||||
temp_decorr_pass.delta = wpds->delta;
|
||||
temp_decorr_pass.term = wpds->terms [j];
|
||||
|
||||
if (temp_decorr_pass.term < 0)
|
||||
temp_decorr_pass.term = 1;
|
||||
|
||||
decorr_mono_pass (temp_buffer [j&1], temp_buffer [~j&1],
|
||||
num_samples > 2048 ? 2048 : num_samples, &temp_decorr_pass, -1);
|
||||
|
||||
if (j) {
|
||||
CLEAR (temp_decorr_pass.samples_A);
|
||||
}
|
||||
else
|
||||
reverse_mono_decorr (&temp_decorr_pass);
|
||||
|
||||
memcpy (save_decorr_passes + j, &temp_decorr_pass, sizeof (struct decorr_pass));
|
||||
decorr_mono_pass (temp_buffer [j&1], temp_buffer [~j&1], num_samples, &temp_decorr_pass, 1);
|
||||
}
|
||||
|
||||
size = log2buffer (temp_buffer [j&1], num_samples, log_limit);
|
||||
|
||||
if (size == (uint32_t) -1 && nterms)
|
||||
nterms >>= 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
size += log2overhead (wpds->terms [0], nterms);
|
||||
|
||||
if (size < best_size) {
|
||||
memcpy (best_buffer, temp_buffer [j&1], buf_size);
|
||||
memcpy (wps->decorr_passes, save_decorr_passes, sizeof (struct decorr_pass) * MAX_NTERMS);
|
||||
wps->num_terms = nterms;
|
||||
wps->best_decorr = c;
|
||||
best_size = size;
|
||||
}
|
||||
|
||||
if (pi++)
|
||||
wps->mask_decorr = wps->mask_decorr ? ((wps->mask_decorr << 1) & (wps->num_decorrs - 1)) : 1;
|
||||
}
|
||||
|
||||
if (wpc->config.xmode > 3) {
|
||||
if (noisy_buffer) {
|
||||
analyze_mono (wpc, noisy_buffer, do_samples);
|
||||
|
||||
if (do_samples)
|
||||
memcpy (samples, noisy_buffer, buf_size);
|
||||
}
|
||||
else
|
||||
analyze_mono (wpc, samples, do_samples);
|
||||
}
|
||||
else if (do_samples)
|
||||
memcpy (samples, best_buffer, buf_size);
|
||||
|
||||
if (no_history || wpc->config.xmode > 3)
|
||||
scan_word (wps, best_buffer, num_samples, -1);
|
||||
|
||||
if (noisy_buffer)
|
||||
free (noisy_buffer);
|
||||
|
||||
free (temp_buffer [1]);
|
||||
free (temp_buffer [0]);
|
||||
free (best_buffer);
|
||||
|
||||
#ifdef EXTRA_DUMP
|
||||
if (1) {
|
||||
char string [256], substring [20];
|
||||
int i;
|
||||
|
||||
sprintf (string, "M: terms =");
|
||||
|
||||
for (i = 0; i < wps->num_terms; ++i) {
|
||||
if (wps->decorr_passes [i].term) {
|
||||
if (i && wps->decorr_passes [i-1].delta == wps->decorr_passes [i].delta)
|
||||
sprintf (substring, " %d", wps->decorr_passes [i].term);
|
||||
else
|
||||
sprintf (substring, " %d->%d", wps->decorr_passes [i].term,
|
||||
wps->decorr_passes [i].delta);
|
||||
}
|
||||
else
|
||||
sprintf (substring, " *");
|
||||
|
||||
strcat (string, substring);
|
||||
}
|
||||
|
||||
error_line (string);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
1355
wavpack-4.5.0/src/extra2.c
Normal file
1355
wavpack-4.5.0/src/extra2.c
Normal file
File diff suppressed because it is too large
Load Diff
371
wavpack-4.5.0/src/float.c
Normal file
371
wavpack-4.5.0/src/float.c
Normal file
@@ -0,0 +1,371 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// **** WAVPACK **** //
|
||||
// Hybrid Lossless Wavefile Compressor //
|
||||
// Copyright (c) 1998 - 2006 Conifer Software. //
|
||||
// All Rights Reserved. //
|
||||
// Distributed under the BSD Software License (see license.txt) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// float.c
|
||||
|
||||
#include "wavpack_local.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef DEBUG_ALLOC
|
||||
#define malloc malloc_db
|
||||
#define realloc realloc_db
|
||||
#define free free_db
|
||||
void *malloc_db (uint32_t size);
|
||||
void *realloc_db (void *ptr, uint32_t size);
|
||||
void free_db (void *ptr);
|
||||
int32_t dump_alloc (void);
|
||||
#endif
|
||||
|
||||
#ifndef NO_PACK
|
||||
|
||||
void write_float_info (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||
{
|
||||
char *byteptr;
|
||||
|
||||
byteptr = wpmd->data = malloc (4);
|
||||
wpmd->id = ID_FLOAT_INFO;
|
||||
*byteptr++ = wps->float_flags;
|
||||
*byteptr++ = wps->float_shift;
|
||||
*byteptr++ = wps->float_max_exp;
|
||||
*byteptr++ = wps->float_norm_exp;
|
||||
wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data);
|
||||
}
|
||||
|
||||
int scan_float_data (WavpackStream *wps, f32 *values, int32_t num_values)
|
||||
{
|
||||
int32_t shifted_ones = 0, shifted_zeros = 0, shifted_both = 0;
|
||||
int32_t false_zeros = 0, neg_zeros = 0;
|
||||
uint32_t ordata = 0, crc = 0xffffffff;
|
||||
int32_t count, value, shift_count;
|
||||
int max_exp = 0;
|
||||
f32 *dp;
|
||||
|
||||
wps->float_shift = wps->float_flags = 0;
|
||||
|
||||
for (dp = values, count = num_values; count--; dp++) {
|
||||
crc = crc * 27 + get_mantissa (*dp) * 9 + get_exponent (*dp) * 3 + get_sign (*dp);
|
||||
|
||||
if (get_exponent (*dp) > max_exp && get_exponent (*dp) < 255)
|
||||
max_exp = get_exponent (*dp);
|
||||
}
|
||||
|
||||
wps->crc_x = crc;
|
||||
|
||||
for (dp = values, count = num_values; count--; dp++) {
|
||||
if (get_exponent (*dp) == 255) {
|
||||
wps->float_flags |= FLOAT_EXCEPTIONS;
|
||||
value = 0x1000000;
|
||||
shift_count = 0;
|
||||
}
|
||||
else if (get_exponent (*dp)) {
|
||||
shift_count = max_exp - get_exponent (*dp);
|
||||
value = 0x800000 + get_mantissa (*dp);
|
||||
}
|
||||
else {
|
||||
shift_count = max_exp ? max_exp - 1 : 0;
|
||||
value = get_mantissa (*dp);
|
||||
|
||||
// if (get_mantissa (*dp))
|
||||
// denormals++;
|
||||
}
|
||||
|
||||
if (shift_count < 25)
|
||||
value >>= shift_count;
|
||||
else
|
||||
value = 0;
|
||||
|
||||
if (!value) {
|
||||
if (get_exponent (*dp) || get_mantissa (*dp))
|
||||
++false_zeros;
|
||||
else if (get_sign (*dp))
|
||||
++neg_zeros;
|
||||
}
|
||||
else if (shift_count) {
|
||||
int32_t mask = (1 << shift_count) - 1;
|
||||
|
||||
if (!(get_mantissa (*dp) & mask))
|
||||
shifted_zeros++;
|
||||
else if ((get_mantissa (*dp) & mask) == mask)
|
||||
shifted_ones++;
|
||||
else
|
||||
shifted_both++;
|
||||
}
|
||||
|
||||
ordata |= value;
|
||||
* (int32_t *) dp = (get_sign (*dp)) ? -value : value;
|
||||
}
|
||||
|
||||
wps->float_max_exp = max_exp;
|
||||
|
||||
if (shifted_both)
|
||||
wps->float_flags |= FLOAT_SHIFT_SENT;
|
||||
else if (shifted_ones && !shifted_zeros)
|
||||
wps->float_flags |= FLOAT_SHIFT_ONES;
|
||||
else if (shifted_ones && shifted_zeros)
|
||||
wps->float_flags |= FLOAT_SHIFT_SAME;
|
||||
else if (ordata && !(ordata & 1)) {
|
||||
while (!(ordata & 1)) {
|
||||
wps->float_shift++;
|
||||
ordata >>= 1;
|
||||
}
|
||||
|
||||
for (dp = values, count = num_values; count--; dp++)
|
||||
* (int32_t *) dp >>= wps->float_shift;
|
||||
}
|
||||
|
||||
wps->wphdr.flags &= ~MAG_MASK;
|
||||
|
||||
while (ordata) {
|
||||
wps->wphdr.flags += 1 << MAG_LSB;
|
||||
ordata >>= 1;
|
||||
}
|
||||
|
||||
if (false_zeros || neg_zeros)
|
||||
wps->float_flags |= FLOAT_ZEROS_SENT;
|
||||
|
||||
if (neg_zeros)
|
||||
wps->float_flags |= FLOAT_NEG_ZEROS;
|
||||
|
||||
// error_line ("samples = %d, max exp = %d, pre-shift = %d, denormals = %d",
|
||||
// num_values, max_exp, wps->float_shift, denormals);
|
||||
// if (wps->float_flags & FLOAT_EXCEPTIONS)
|
||||
// error_line ("exceptions!");
|
||||
// error_line ("shifted ones/zeros/both = %d/%d/%d, true/neg/false zeros = %d/%d/%d",
|
||||
// shifted_ones, shifted_zeros, shifted_both, true_zeros, neg_zeros, false_zeros);
|
||||
|
||||
return wps->float_flags & (FLOAT_EXCEPTIONS | FLOAT_ZEROS_SENT | FLOAT_SHIFT_SENT | FLOAT_SHIFT_SAME);
|
||||
}
|
||||
|
||||
void send_float_data (WavpackStream *wps, f32 *values, int32_t num_values)
|
||||
{
|
||||
int max_exp = wps->float_max_exp;
|
||||
int32_t count, value, shift_count;
|
||||
f32 *dp;
|
||||
|
||||
for (dp = values, count = num_values; count--; dp++) {
|
||||
if (get_exponent (*dp) == 255) {
|
||||
if (get_mantissa (*dp)) {
|
||||
putbit_1 (&wps->wvxbits);
|
||||
putbits (get_mantissa (*dp), 23, &wps->wvxbits);
|
||||
}
|
||||
else {
|
||||
putbit_0 (&wps->wvxbits);
|
||||
}
|
||||
|
||||
value = 0x1000000;
|
||||
shift_count = 0;
|
||||
}
|
||||
else if (get_exponent (*dp)) {
|
||||
shift_count = max_exp - get_exponent (*dp);
|
||||
value = 0x800000 + get_mantissa (*dp);
|
||||
}
|
||||
else {
|
||||
shift_count = max_exp ? max_exp - 1 : 0;
|
||||
value = get_mantissa (*dp);
|
||||
}
|
||||
|
||||
if (shift_count < 25)
|
||||
value >>= shift_count;
|
||||
else
|
||||
value = 0;
|
||||
|
||||
if (!value) {
|
||||
if (wps->float_flags & FLOAT_ZEROS_SENT) {
|
||||
if (get_exponent (*dp) || get_mantissa (*dp)) {
|
||||
putbit_1 (&wps->wvxbits);
|
||||
putbits (get_mantissa (*dp), 23, &wps->wvxbits);
|
||||
|
||||
if (max_exp >= 25) {
|
||||
putbits (get_exponent (*dp), 8, &wps->wvxbits);
|
||||
}
|
||||
|
||||
putbit (get_sign (*dp), &wps->wvxbits);
|
||||
}
|
||||
else {
|
||||
putbit_0 (&wps->wvxbits);
|
||||
|
||||
if (wps->float_flags & FLOAT_NEG_ZEROS)
|
||||
putbit (get_sign (*dp), &wps->wvxbits);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (shift_count) {
|
||||
if (wps->float_flags & FLOAT_SHIFT_SENT) {
|
||||
int32_t data = get_mantissa (*dp) & ((1 << shift_count) - 1);
|
||||
putbits (data, shift_count, &wps->wvxbits);
|
||||
}
|
||||
else if (wps->float_flags & FLOAT_SHIFT_SAME) {
|
||||
putbit (get_mantissa (*dp) & 1, &wps->wvxbits);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(NO_UNPACK) || defined(INFO_ONLY)
|
||||
|
||||
int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||
{
|
||||
int bytecnt = wpmd->byte_length;
|
||||
char *byteptr = wpmd->data;
|
||||
|
||||
if (bytecnt != 4)
|
||||
return FALSE;
|
||||
|
||||
wps->float_flags = *byteptr++;
|
||||
wps->float_shift = *byteptr++;
|
||||
wps->float_max_exp = *byteptr++;
|
||||
wps->float_norm_exp = *byteptr;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef NO_UNPACK
|
||||
|
||||
static void float_values_nowvx (WavpackStream *wps, int32_t *values, int32_t num_values);
|
||||
|
||||
void float_values (WavpackStream *wps, int32_t *values, int32_t num_values)
|
||||
{
|
||||
uint32_t crc = wps->crc_x;
|
||||
|
||||
if (!bs_is_open (&wps->wvxbits)) {
|
||||
float_values_nowvx (wps, values, num_values);
|
||||
return;
|
||||
}
|
||||
|
||||
while (num_values--) {
|
||||
int shift_count = 0, exp = wps->float_max_exp;
|
||||
f32 outval = 0;
|
||||
uint32_t temp;
|
||||
|
||||
if (*values == 0) {
|
||||
if (wps->float_flags & FLOAT_ZEROS_SENT) {
|
||||
if (getbit (&wps->wvxbits)) {
|
||||
getbits (&temp, 23, &wps->wvxbits);
|
||||
set_mantissa (outval, temp);
|
||||
|
||||
if (exp >= 25) {
|
||||
getbits (&temp, 8, &wps->wvxbits);
|
||||
set_exponent (outval, temp);
|
||||
}
|
||||
|
||||
set_sign (outval, getbit (&wps->wvxbits));
|
||||
}
|
||||
else if (wps->float_flags & FLOAT_NEG_ZEROS)
|
||||
set_sign (outval, getbit (&wps->wvxbits));
|
||||
}
|
||||
}
|
||||
else {
|
||||
*values <<= wps->float_shift;
|
||||
|
||||
if (*values < 0) {
|
||||
*values = -*values;
|
||||
set_sign (outval, 1);
|
||||
}
|
||||
|
||||
if (*values == 0x1000000) {
|
||||
if (getbit (&wps->wvxbits)) {
|
||||
getbits (&temp, 23, &wps->wvxbits);
|
||||
set_mantissa (outval, temp);
|
||||
}
|
||||
|
||||
set_exponent (outval, 255);
|
||||
}
|
||||
else {
|
||||
if (exp)
|
||||
while (!(*values & 0x800000) && --exp) {
|
||||
shift_count++;
|
||||
*values <<= 1;
|
||||
}
|
||||
|
||||
if (shift_count) {
|
||||
if ((wps->float_flags & FLOAT_SHIFT_ONES) ||
|
||||
((wps->float_flags & FLOAT_SHIFT_SAME) && getbit (&wps->wvxbits)))
|
||||
*values |= ((1 << shift_count) - 1);
|
||||
else if (wps->float_flags & FLOAT_SHIFT_SENT) {
|
||||
getbits (&temp, shift_count, &wps->wvxbits);
|
||||
*values |= temp & ((1 << shift_count) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
set_mantissa (outval, *values);
|
||||
set_exponent (outval, exp);
|
||||
}
|
||||
}
|
||||
|
||||
crc = crc * 27 + get_mantissa (outval) * 9 + get_exponent (outval) * 3 + get_sign (outval);
|
||||
* (f32 *) values++ = outval;
|
||||
}
|
||||
|
||||
wps->crc_x = crc;
|
||||
}
|
||||
|
||||
static void float_values_nowvx (WavpackStream *wps, int32_t *values, int32_t num_values)
|
||||
{
|
||||
while (num_values--) {
|
||||
int shift_count = 0, exp = wps->float_max_exp;
|
||||
f32 outval = 0;
|
||||
|
||||
if (*values) {
|
||||
*values <<= wps->float_shift;
|
||||
|
||||
if (*values < 0) {
|
||||
*values = -*values;
|
||||
set_sign (outval, 1);
|
||||
}
|
||||
|
||||
if (*values >= 0x1000000) {
|
||||
while (*values & 0xf000000) {
|
||||
*values >>= 1;
|
||||
++exp;
|
||||
}
|
||||
}
|
||||
else if (exp) {
|
||||
while (!(*values & 0x800000) && --exp) {
|
||||
shift_count++;
|
||||
*values <<= 1;
|
||||
}
|
||||
|
||||
if (shift_count && (wps->float_flags & FLOAT_SHIFT_ONES))
|
||||
*values |= ((1 << shift_count) - 1);
|
||||
}
|
||||
|
||||
set_mantissa (outval, *values);
|
||||
set_exponent (outval, exp);
|
||||
}
|
||||
|
||||
* (f32 *) values++ = outval;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void WavpackFloatNormalize (int32_t *values, int32_t num_values, int delta_exp)
|
||||
{
|
||||
f32 *fvalues = (f32 *) values;
|
||||
int exp;
|
||||
|
||||
if (!delta_exp)
|
||||
return;
|
||||
|
||||
while (num_values--) {
|
||||
if ((exp = get_exponent (*fvalues)) == 0 || exp + delta_exp <= 0)
|
||||
*fvalues = 0;
|
||||
else if (exp == 255 || (exp += delta_exp) >= 255) {
|
||||
set_exponent (*fvalues, 255);
|
||||
set_mantissa (*fvalues, 0);
|
||||
}
|
||||
else
|
||||
set_exponent (*fvalues, exp);
|
||||
|
||||
fvalues++;
|
||||
}
|
||||
}
|
||||
26
wavpack-4.5.0/src/libwavpack.sln
Normal file
26
wavpack-4.5.0/src/libwavpack.sln
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libwavpack", "libwavpack.vcproj", "{5CCCB9CF-0384-458F-BA08-72B73866840F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{5CCCB9CF-0384-458F-BA08-72B73866840F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{5CCCB9CF-0384-458F-BA08-72B73866840F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{5CCCB9CF-0384-458F-BA08-72B73866840F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5CCCB9CF-0384-458F-BA08-72B73866840F}.Debug|x64.Build.0 = Debug|x64
|
||||
{5CCCB9CF-0384-458F-BA08-72B73866840F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{5CCCB9CF-0384-458F-BA08-72B73866840F}.Release|Win32.Build.0 = Release|Win32
|
||||
{5CCCB9CF-0384-458F-BA08-72B73866840F}.Release|x64.ActiveCfg = Release|x64
|
||||
{5CCCB9CF-0384-458F-BA08-72B73866840F}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
359
wavpack-4.5.0/src/libwavpack.vcproj
Normal file
359
wavpack-4.5.0/src/libwavpack.vcproj
Normal file
@@ -0,0 +1,359 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8,00"
|
||||
Name="libwavpack"
|
||||
ProjectGUID="{5CCCB9CF-0384-458F-BA08-72B73866840F}"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)..\bin\$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(SolutionDir)..\obj\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;OPT_MMX"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)..\bin\$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(SolutionDir)..\obj\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;OPT_SSE2"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)..\bin\$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(SolutionDir)..\obj\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;OPT_MMX"
|
||||
StringPooling="true"
|
||||
ExceptionHandling="0"
|
||||
RuntimeLibrary="2"
|
||||
BufferSecurityCheck="false"
|
||||
EnableFunctionLevelLinking="true"
|
||||
DisableLanguageExtensions="false"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="0"
|
||||
CompileAs="0"
|
||||
OmitDefaultLibName="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
IgnoreAllDefaultLibraries="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)..\bin\$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(SolutionDir)..\obj\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;OPT_SSE2"
|
||||
StringPooling="true"
|
||||
ExceptionHandling="0"
|
||||
RuntimeLibrary="2"
|
||||
BufferSecurityCheck="false"
|
||||
EnableFunctionLevelLinking="true"
|
||||
DisableLanguageExtensions="false"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="0"
|
||||
CompileAs="0"
|
||||
OmitDefaultLibName="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
IgnoreAllDefaultLibraries="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\unpack3.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wavpack_local.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\bits.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\extra1.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\extra2.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\float.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\metadata.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pack.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\unpack.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\unpack3.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\words.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wputils.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
313
wavpack-4.5.0/src/metadata.c
Normal file
313
wavpack-4.5.0/src/metadata.c
Normal file
@@ -0,0 +1,313 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// **** WAVPACK **** //
|
||||
// Hybrid Lossless Wavefile Compressor //
|
||||
// Copyright (c) 1998 - 2006 Conifer Software. //
|
||||
// All Rights Reserved. //
|
||||
// Distributed under the BSD Software License (see license.txt) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// metadata.c
|
||||
|
||||
// This module handles the metadata structure introduced in WavPack 4.0
|
||||
|
||||
#include "wavpack_local.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef DEBUG_ALLOC
|
||||
#define malloc malloc_db
|
||||
#define realloc realloc_db
|
||||
#define free free_db
|
||||
void *malloc_db (uint32_t size);
|
||||
void *realloc_db (void *ptr, uint32_t size);
|
||||
void free_db (void *ptr);
|
||||
int32_t dump_alloc (void);
|
||||
#endif
|
||||
|
||||
#if !defined(NO_UNPACK) || defined(INFO_ONLY)
|
||||
|
||||
int read_metadata_buff (WavpackMetadata *wpmd, uchar *blockbuff, uchar **buffptr)
|
||||
{
|
||||
WavpackHeader *wphdr = (WavpackHeader *) blockbuff;
|
||||
uchar *buffend = blockbuff + wphdr->ckSize + 8;
|
||||
|
||||
if (buffend - *buffptr < 2)
|
||||
return FALSE;
|
||||
|
||||
wpmd->id = *(*buffptr)++;
|
||||
wpmd->byte_length = *(*buffptr)++ << 1;
|
||||
|
||||
if (wpmd->id & ID_LARGE) {
|
||||
wpmd->id &= ~ID_LARGE;
|
||||
|
||||
if (buffend - *buffptr < 2)
|
||||
return FALSE;
|
||||
|
||||
wpmd->byte_length += *(*buffptr)++ << 9;
|
||||
wpmd->byte_length += *(*buffptr)++ << 17;
|
||||
}
|
||||
|
||||
if (wpmd->id & ID_ODD_SIZE) {
|
||||
wpmd->id &= ~ID_ODD_SIZE;
|
||||
wpmd->byte_length--;
|
||||
}
|
||||
|
||||
if (wpmd->byte_length) {
|
||||
if (buffend - *buffptr < wpmd->byte_length + (wpmd->byte_length & 1)) {
|
||||
wpmd->data = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wpmd->data = *buffptr;
|
||||
(*buffptr) += wpmd->byte_length + (wpmd->byte_length & 1);
|
||||
}
|
||||
else
|
||||
wpmd->data = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd)
|
||||
{
|
||||
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||
|
||||
switch (wpmd->id) {
|
||||
case ID_DUMMY:
|
||||
return TRUE;
|
||||
|
||||
case ID_DECORR_TERMS:
|
||||
return read_decorr_terms (wps, wpmd);
|
||||
|
||||
case ID_DECORR_WEIGHTS:
|
||||
return read_decorr_weights (wps, wpmd);
|
||||
|
||||
case ID_DECORR_SAMPLES:
|
||||
return read_decorr_samples (wps, wpmd);
|
||||
|
||||
case ID_ENTROPY_VARS:
|
||||
return read_entropy_vars (wps, wpmd);
|
||||
|
||||
case ID_HYBRID_PROFILE:
|
||||
return read_hybrid_profile (wps, wpmd);
|
||||
|
||||
case ID_SHAPING_WEIGHTS:
|
||||
return read_shaping_info (wps, wpmd);
|
||||
|
||||
case ID_FLOAT_INFO:
|
||||
return read_float_info (wps, wpmd);
|
||||
|
||||
case ID_INT32_INFO:
|
||||
return read_int32_info (wps, wpmd);
|
||||
|
||||
case ID_CHANNEL_INFO:
|
||||
return read_channel_info (wpc, wpmd);
|
||||
|
||||
case ID_CONFIG_BLOCK:
|
||||
return read_config_info (wpc, wpmd);
|
||||
|
||||
case ID_SAMPLE_RATE:
|
||||
return read_sample_rate (wpc, wpmd);
|
||||
|
||||
case ID_WV_BITSTREAM:
|
||||
return init_wv_bitstream (wps, wpmd);
|
||||
|
||||
case ID_WVC_BITSTREAM:
|
||||
return init_wvc_bitstream (wps, wpmd);
|
||||
|
||||
case ID_WVX_BITSTREAM:
|
||||
return init_wvx_bitstream (wps, wpmd);
|
||||
|
||||
case ID_RIFF_HEADER: case ID_RIFF_TRAILER:
|
||||
return read_wrapper_data (wpc, wpmd);
|
||||
|
||||
case ID_MD5_CHECKSUM:
|
||||
if (wpmd->byte_length == 16) {
|
||||
memcpy (wpc->config.md5_checksum, wpmd->data, 16);
|
||||
wpc->config.flags |= CONFIG_MD5_CHECKSUM;
|
||||
wpc->config.md5_read = 1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return (wpmd->id & ID_OPTIONAL_DATA) ? TRUE : FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef NO_PACK
|
||||
|
||||
int copy_metadata (WavpackMetadata *wpmd, uchar *buffer_start, uchar *buffer_end)
|
||||
{
|
||||
uint32_t mdsize = wpmd->byte_length + (wpmd->byte_length & 1);
|
||||
WavpackHeader *wphdr = (WavpackHeader *) buffer_start;
|
||||
|
||||
if (wpmd->byte_length & 1)
|
||||
((char *) wpmd->data) [wpmd->byte_length] = 0;
|
||||
|
||||
mdsize += (wpmd->byte_length > 510) ? 4 : 2;
|
||||
buffer_start += wphdr->ckSize + 8;
|
||||
|
||||
if (buffer_start + mdsize >= buffer_end)
|
||||
return FALSE;
|
||||
|
||||
buffer_start [0] = wpmd->id | (wpmd->byte_length & 1 ? ID_ODD_SIZE : 0);
|
||||
buffer_start [1] = (wpmd->byte_length + 1) >> 1;
|
||||
|
||||
if (wpmd->byte_length > 510) {
|
||||
buffer_start [0] |= ID_LARGE;
|
||||
buffer_start [2] = (wpmd->byte_length + 1) >> 9;
|
||||
buffer_start [3] = (wpmd->byte_length + 1) >> 17;
|
||||
}
|
||||
|
||||
if (wpmd->data && wpmd->byte_length) {
|
||||
if (wpmd->byte_length > 510) {
|
||||
buffer_start [0] |= ID_LARGE;
|
||||
buffer_start [2] = (wpmd->byte_length + 1) >> 9;
|
||||
buffer_start [3] = (wpmd->byte_length + 1) >> 17;
|
||||
memcpy (buffer_start + 4, wpmd->data, mdsize - 4);
|
||||
}
|
||||
else
|
||||
memcpy (buffer_start + 2, wpmd->data, mdsize - 2);
|
||||
}
|
||||
|
||||
wphdr->ckSize += mdsize;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int add_to_metadata (WavpackContext *wpc, void *data, uint32_t bcount, uchar id)
|
||||
{
|
||||
WavpackMetadata *mdp;
|
||||
uchar *src = data;
|
||||
|
||||
while (bcount) {
|
||||
if (wpc->metacount) {
|
||||
uint32_t bc = bcount;
|
||||
|
||||
mdp = wpc->metadata + wpc->metacount - 1;
|
||||
|
||||
if (mdp->id == id) {
|
||||
if (wpc->metabytes + bcount > 1000000)
|
||||
bc = 1000000 - wpc->metabytes;
|
||||
|
||||
mdp->data = realloc (mdp->data, mdp->byte_length + bc);
|
||||
memcpy ((char *) mdp->data + mdp->byte_length, src, bc);
|
||||
mdp->byte_length += bc;
|
||||
wpc->metabytes += bc;
|
||||
bcount -= bc;
|
||||
src += bc;
|
||||
|
||||
if (wpc->metabytes >= 1000000 && !write_metadata_block (wpc))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcount) {
|
||||
wpc->metadata = realloc (wpc->metadata, (wpc->metacount + 1) * sizeof (WavpackMetadata));
|
||||
mdp = wpc->metadata + wpc->metacount++;
|
||||
mdp->byte_length = 0;
|
||||
mdp->data = NULL;
|
||||
mdp->id = id;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static char *write_metadata (WavpackMetadata *wpmd, char *outdata)
|
||||
{
|
||||
uchar id = wpmd->id, wordlen [3];
|
||||
|
||||
wordlen [0] = (wpmd->byte_length + 1) >> 1;
|
||||
wordlen [1] = (wpmd->byte_length + 1) >> 9;
|
||||
wordlen [2] = (wpmd->byte_length + 1) >> 17;
|
||||
|
||||
if (wpmd->byte_length & 1) {
|
||||
// ((char *) wpmd->data) [wpmd->byte_length] = 0;
|
||||
id |= ID_ODD_SIZE;
|
||||
}
|
||||
|
||||
if (wordlen [1] || wordlen [2])
|
||||
id |= ID_LARGE;
|
||||
|
||||
*outdata++ = id;
|
||||
*outdata++ = wordlen [0];
|
||||
|
||||
if (id & ID_LARGE) {
|
||||
*outdata++ = wordlen [1];
|
||||
*outdata++ = wordlen [2];
|
||||
}
|
||||
|
||||
if (wpmd->data && wpmd->byte_length) {
|
||||
memcpy (outdata, wpmd->data, wpmd->byte_length);
|
||||
outdata += wpmd->byte_length;
|
||||
|
||||
if (wpmd->byte_length & 1)
|
||||
*outdata++ = 0;
|
||||
}
|
||||
|
||||
return outdata;
|
||||
}
|
||||
|
||||
int write_metadata_block (WavpackContext *wpc)
|
||||
{
|
||||
char *block_buff, *block_ptr;
|
||||
WavpackHeader *wphdr;
|
||||
|
||||
if (wpc->metacount) {
|
||||
int metacount = wpc->metacount, block_size = sizeof (WavpackHeader);
|
||||
WavpackMetadata *wpmdp = wpc->metadata;
|
||||
|
||||
while (metacount--) {
|
||||
block_size += wpmdp->byte_length + (wpmdp->byte_length & 1);
|
||||
block_size += (wpmdp->byte_length > 510) ? 4 : 2;
|
||||
wpmdp++;
|
||||
}
|
||||
|
||||
wphdr = (WavpackHeader *) (block_buff = malloc (block_size));
|
||||
|
||||
CLEAR (*wphdr);
|
||||
memcpy (wphdr->ckID, "wvpk", 4);
|
||||
wphdr->total_samples = wpc->total_samples;
|
||||
wphdr->version = wpc->stream_version;
|
||||
wphdr->ckSize = block_size - 8;
|
||||
wphdr->block_samples = 0;
|
||||
|
||||
block_ptr = (char *)(wphdr + 1);
|
||||
|
||||
wpmdp = wpc->metadata;
|
||||
|
||||
while (wpc->metacount) {
|
||||
block_ptr = write_metadata (wpmdp, block_ptr);
|
||||
wpc->metabytes -= wpmdp->byte_length;
|
||||
free_metadata (wpmdp++);
|
||||
wpc->metacount--;
|
||||
}
|
||||
|
||||
free (wpc->metadata);
|
||||
wpc->metadata = NULL;
|
||||
native_to_little_endian ((WavpackHeader *) block_buff, WavpackHeaderFormat);
|
||||
|
||||
if (!wpc->blockout (wpc->wv_out, block_buff, block_size)) {
|
||||
free (block_buff);
|
||||
strcpy (wpc->error_message, "can't write WavPack data, disk probably full!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
free (block_buff);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void free_metadata (WavpackMetadata *wpmd)
|
||||
{
|
||||
if (wpmd->data) {
|
||||
free (wpmd->data);
|
||||
wpmd->data = NULL;
|
||||
}
|
||||
}
|
||||
2992
wavpack-4.5.0/src/pack.c
Normal file
2992
wavpack-4.5.0/src/pack.c
Normal file
File diff suppressed because it is too large
Load Diff
1399
wavpack-4.5.0/src/unpack.c
Normal file
1399
wavpack-4.5.0/src/unpack.c
Normal file
File diff suppressed because it is too large
Load Diff
2195
wavpack-4.5.0/src/unpack3.c
Normal file
2195
wavpack-4.5.0/src/unpack3.c
Normal file
File diff suppressed because it is too large
Load Diff
113
wavpack-4.5.0/src/unpack3.h
Normal file
113
wavpack-4.5.0/src/unpack3.h
Normal file
@@ -0,0 +1,113 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// **** WAVPACK **** //
|
||||
// Hybrid Lossless Wavefile Compressor //
|
||||
// Copyright (c) 1998 - 2006 Conifer Software. //
|
||||
// All Rights Reserved. //
|
||||
// Distributed under the BSD Software License (see license.txt) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// wavpack3.h
|
||||
|
||||
// This header file contains all the additional definitions required for
|
||||
// decoding old (versions 1, 2 & 3) WavPack files.
|
||||
|
||||
typedef struct {
|
||||
ushort FormatTag, NumChannels;
|
||||
uint32_t SampleRate, BytesPerSecond;
|
||||
ushort BlockAlign, BitsPerSample;
|
||||
} WaveHeader3;
|
||||
|
||||
#define WaveHeader3Format "SSLLSS"
|
||||
|
||||
typedef struct {
|
||||
char ckID [4];
|
||||
int32_t ckSize;
|
||||
short version;
|
||||
short bits; // added for version 2.00
|
||||
short flags, shift; // added for version 3.00
|
||||
int32_t total_samples, crc, crc2;
|
||||
char extension [4], extra_bc, extras [3];
|
||||
} WavpackHeader3;
|
||||
|
||||
#define WavpackHeader3Format "4LSSSSLLL4L"
|
||||
|
||||
// these flags added for version 3
|
||||
|
||||
#undef MONO_FLAG // these definitions changed for WavPack 4.0
|
||||
#undef CROSS_DECORR
|
||||
#undef JOINT_STEREO
|
||||
|
||||
#define MONO_FLAG 1 // not stereo
|
||||
#define FAST_FLAG 2 // non-adaptive predictor and stereo mode
|
||||
#define RAW_FLAG 4 // raw mode (no .wav header)
|
||||
#define CALC_NOISE 8 // calc noise in lossy mode (no longer stored)
|
||||
#define HIGH_FLAG 0x10 // high quality mode (all modes)
|
||||
#define BYTES_3 0x20 // files have 3-byte samples
|
||||
#define OVER_20 0x40 // samples are over 20 bits
|
||||
#define WVC_FLAG 0x80 // create/use .wvc (no longer stored)
|
||||
#define LOSSY_SHAPE 0x100 // noise shape (lossy mode only)
|
||||
#define VERY_FAST_FLAG 0x200 // double fast (no longer stored)
|
||||
#define NEW_HIGH_FLAG 0x400 // new high quality mode (lossless only)
|
||||
#define CANCEL_EXTREME 0x800 // cancel EXTREME_DECORR
|
||||
#define CROSS_DECORR 0x1000 // decorrelate chans (with EXTREME_DECORR flag)
|
||||
#define NEW_DECORR_FLAG 0x2000 // new high-mode decorrelator
|
||||
#define JOINT_STEREO 0x4000 // joint stereo (lossy and high lossless)
|
||||
#define EXTREME_DECORR 0x8000 // extra decorrelation (+ enables other flags)
|
||||
|
||||
#define STORED_FLAGS 0xfd77 // these are only flags that affect unpacking
|
||||
#define NOT_STORED_FLAGS (~STORED_FLAGS & 0xffff)
|
||||
|
||||
// BitStream stuff (bits.c)
|
||||
|
||||
typedef struct bs3 {
|
||||
void (*wrap)(struct bs3 *bs);
|
||||
uchar *buf, *end, *ptr;
|
||||
uint32_t bufsiz, fpos, sr;
|
||||
WavpackStreamReader *reader;
|
||||
int error, bc;
|
||||
void *id;
|
||||
} Bitstream3;
|
||||
|
||||
#define K_DEPTH 3
|
||||
#define MAX_NTERMS3 18
|
||||
|
||||
typedef struct {
|
||||
WavpackHeader3 wphdr;
|
||||
Bitstream3 wvbits, wvcbits;
|
||||
uint32_t sample_index;
|
||||
int num_terms;
|
||||
|
||||
#ifndef NO_SEEKING
|
||||
struct index_point {
|
||||
char saved;
|
||||
uint32_t sample_index;
|
||||
} index_points [256];
|
||||
|
||||
uchar *unpack_data;
|
||||
uint32_t unpack_size;
|
||||
#endif
|
||||
|
||||
struct {
|
||||
int32_t sum_level, left_level, right_level, diff_level;
|
||||
int last_extra_bits, extra_bits_count, m;
|
||||
int32_t error [2], crc;
|
||||
int32_t sample [2] [2];
|
||||
int weight [2] [1];
|
||||
} dc;
|
||||
|
||||
struct decorr_pass decorr_passes [MAX_NTERMS3];
|
||||
|
||||
struct {
|
||||
uint index [2], k_value [2], ave_k [2];
|
||||
uint32_t zeros_acc, ave_level [K_DEPTH] [2];
|
||||
} w1;
|
||||
|
||||
struct { int last_dbits [2], last_delta_sign [2], bit_limit; } w2;
|
||||
|
||||
struct { int ave_dbits [2], bit_limit; } w3;
|
||||
|
||||
struct {
|
||||
uint32_t fast_level [2], slow_level [2];
|
||||
int bits_acc [2], bitrate;
|
||||
} w4;
|
||||
} WavpackStream3;
|
||||
764
wavpack-4.5.0/src/wavpack_local.h
Normal file
764
wavpack-4.5.0/src/wavpack_local.h
Normal file
@@ -0,0 +1,764 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// **** WAVPACK **** //
|
||||
// Hybrid Lossless Wavefile Compressor //
|
||||
// Copyright (c) 1998 - 2006 Conifer Software. //
|
||||
// All Rights Reserved. //
|
||||
// Distributed under the BSD Software License (see license.txt) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// wavpack_local.h
|
||||
|
||||
#ifndef WAVPACK_LOCAL_H
|
||||
#define WAVPACK_LOCAL_H
|
||||
|
||||
#if defined(WIN32)
|
||||
#define FASTCALL __fastcall
|
||||
#else
|
||||
#define FASTCALL
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || \
|
||||
(defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && (BYTE_ORDER == LITTLE_ENDIAN))
|
||||
#define BITSTREAM_SHORTS // use "shorts" for reading/writing bitstreams
|
||||
// (only works on little-endian machines)
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
// This header file contains all the definitions required by WavPack.
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
#include <stdlib.h>
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int8 int8_t;
|
||||
typedef float float32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
typedef unsigned char uchar;
|
||||
|
||||
#if !defined(__GNUC__) || defined(WIN32)
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
#endif
|
||||
|
||||
// Because the C99 specification states that "The order of allocation of
|
||||
// bit-fields within a unit (high-order to low-order or low-order to
|
||||
// high-order) is implementation-defined" (6.7.2.1), I decided to change
|
||||
// the representation of floating-point values from a structure of
|
||||
// bit-fields to a 32-bit integer with access macros. Note that the WavPack
|
||||
// library doesn't use any floating-point math to implement compression of
|
||||
// floating-point data (although a little floating-point math is used in
|
||||
// high-level functions unrelated to the codec).
|
||||
|
||||
typedef int32_t f32;
|
||||
|
||||
#define get_mantissa(f) ((f) & 0x7fffff)
|
||||
#define get_exponent(f) (((f) >> 23) & 0xff)
|
||||
#define get_sign(f) (((f) >> 31) & 0x1)
|
||||
|
||||
#define set_mantissa(f,v) (f) ^= (((f) ^ (v)) & 0x7fffff)
|
||||
#define set_exponent(f,v) (f) ^= (((f) ^ ((v) << 23)) & 0x7f800000)
|
||||
#define set_sign(f,v) (f) ^= (((f) ^ ((v) << 31)) & 0x80000000)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
// ID3v1 and APEv2 TAG formats (may occur at the end of WavPack files)
|
||||
|
||||
typedef struct {
|
||||
char tag_id [3], title [30], artist [30], album [30];
|
||||
char year [4], comment [30], genre;
|
||||
} ID3_Tag;
|
||||
|
||||
typedef struct {
|
||||
char ID [8];
|
||||
int32_t version, length, item_count, flags;
|
||||
char res [8];
|
||||
} APE_Tag_Hdr;
|
||||
|
||||
#define APE_Tag_Hdr_Format "8LLLL"
|
||||
|
||||
typedef struct {
|
||||
int32_t tag_file_pos;
|
||||
ID3_Tag id3_tag;
|
||||
APE_Tag_Hdr ape_tag_hdr;
|
||||
char *ape_tag_data;
|
||||
} M_Tag;
|
||||
|
||||
// RIFF / wav header formats (these occur at the beginning of both wav files
|
||||
// and pre-4.0 WavPack files that are not in the "raw" mode)
|
||||
|
||||
typedef struct {
|
||||
char ckID [4];
|
||||
uint32_t ckSize;
|
||||
char formType [4];
|
||||
} RiffChunkHeader;
|
||||
|
||||
typedef struct {
|
||||
char ckID [4];
|
||||
uint32_t ckSize;
|
||||
} ChunkHeader;
|
||||
|
||||
#define ChunkHeaderFormat "4L"
|
||||
|
||||
typedef struct {
|
||||
ushort FormatTag, NumChannels;
|
||||
uint32_t SampleRate, BytesPerSecond;
|
||||
ushort BlockAlign, BitsPerSample;
|
||||
ushort cbSize, ValidBitsPerSample;
|
||||
int32_t ChannelMask;
|
||||
ushort SubFormat;
|
||||
char GUID [14];
|
||||
} WaveHeader;
|
||||
|
||||
#define WaveHeaderFormat "SSLLSSSSLS"
|
||||
|
||||
////////////////////////////// WavPack Header /////////////////////////////////
|
||||
|
||||
// Note that this is the ONLY structure that is written to (or read from)
|
||||
// WavPack 4.0 files, and is the preamble to every block in both the .wv
|
||||
// and .wvc files.
|
||||
|
||||
typedef struct {
|
||||
char ckID [4];
|
||||
uint32_t ckSize;
|
||||
short version;
|
||||
uchar track_no, index_no;
|
||||
uint32_t total_samples, block_index, block_samples, flags, crc;
|
||||
} WavpackHeader;
|
||||
|
||||
#define WavpackHeaderFormat "4LS2LLLLL"
|
||||
|
||||
// or-values for "flags"
|
||||
|
||||
#define BYTES_STORED 3 // 1-4 bytes/sample
|
||||
#define MONO_FLAG 4 // not stereo
|
||||
#define HYBRID_FLAG 8 // hybrid mode
|
||||
#define JOINT_STEREO 0x10 // joint stereo
|
||||
#define CROSS_DECORR 0x20 // no-delay cross decorrelation
|
||||
#define HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
|
||||
#define FLOAT_DATA 0x80 // ieee 32-bit floating point data
|
||||
|
||||
#define INT32_DATA 0x100 // special extended int handling
|
||||
#define HYBRID_BITRATE 0x200 // bitrate noise (hybrid mode only)
|
||||
#define HYBRID_BALANCE 0x400 // balance noise (hybrid stereo mode only)
|
||||
|
||||
#define INITIAL_BLOCK 0x800 // initial block of multichannel segment
|
||||
#define FINAL_BLOCK 0x1000 // final block of multichannel segment
|
||||
|
||||
#define SHIFT_LSB 13
|
||||
#define SHIFT_MASK (0x1fL << SHIFT_LSB)
|
||||
|
||||
#define MAG_LSB 18
|
||||
#define MAG_MASK (0x1fL << MAG_LSB)
|
||||
|
||||
#define SRATE_LSB 23
|
||||
#define SRATE_MASK (0xfL << SRATE_LSB)
|
||||
|
||||
#define FALSE_STEREO 0x40000000 // block is stereo, but data is mono
|
||||
|
||||
#define IGNORED_FLAGS 0x18000000 // reserved, but ignore if encountered
|
||||
#define NEW_SHAPING 0x20000000 // use IIR filter for negative shaping
|
||||
#define UNKNOWN_FLAGS 0x80000000 // also reserved, but refuse decode if
|
||||
// encountered
|
||||
|
||||
#define MONO_DATA (MONO_FLAG | FALSE_STEREO)
|
||||
|
||||
#define MIN_STREAM_VERS 0x402 // lowest stream version we'll decode
|
||||
#define MAX_STREAM_VERS 0x410 // highest stream version we'll decode or encode
|
||||
#define CUR_STREAM_VERS 0x407 // stream version we are [normally] writing now
|
||||
|
||||
|
||||
//////////////////////////// WavPack Metadata /////////////////////////////////
|
||||
|
||||
// This is an internal representation of metadata.
|
||||
|
||||
typedef struct {
|
||||
int32_t byte_length;
|
||||
void *data;
|
||||
uchar id;
|
||||
} WavpackMetadata;
|
||||
|
||||
#define ID_UNIQUE 0x3f
|
||||
#define ID_OPTIONAL_DATA 0x20
|
||||
#define ID_ODD_SIZE 0x40
|
||||
#define ID_LARGE 0x80
|
||||
|
||||
#define ID_DUMMY 0x0
|
||||
#define ID_ENCODER_INFO 0x1
|
||||
#define ID_DECORR_TERMS 0x2
|
||||
#define ID_DECORR_WEIGHTS 0x3
|
||||
#define ID_DECORR_SAMPLES 0x4
|
||||
#define ID_ENTROPY_VARS 0x5
|
||||
#define ID_HYBRID_PROFILE 0x6
|
||||
#define ID_SHAPING_WEIGHTS 0x7
|
||||
#define ID_FLOAT_INFO 0x8
|
||||
#define ID_INT32_INFO 0x9
|
||||
#define ID_WV_BITSTREAM 0xa
|
||||
#define ID_WVC_BITSTREAM 0xb
|
||||
#define ID_WVX_BITSTREAM 0xc
|
||||
#define ID_CHANNEL_INFO 0xd
|
||||
|
||||
#define ID_RIFF_HEADER (ID_OPTIONAL_DATA | 0x1)
|
||||
#define ID_RIFF_TRAILER (ID_OPTIONAL_DATA | 0x2)
|
||||
#define ID_REPLAY_GAIN (ID_OPTIONAL_DATA | 0x3)
|
||||
#define ID_CUESHEET (ID_OPTIONAL_DATA | 0x4)
|
||||
#define ID_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0x5)
|
||||
#define ID_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x6)
|
||||
#define ID_SAMPLE_RATE (ID_OPTIONAL_DATA | 0x7)
|
||||
|
||||
///////////////////////// WavPack Configuration ///////////////////////////////
|
||||
|
||||
// This internal structure is used during encode to provide configuration to
|
||||
// the encoding engine and during decoding to provide fle information back to
|
||||
// the higher level functions. Not all fields are used in both modes.
|
||||
|
||||
typedef struct {
|
||||
float bitrate, shaping_weight;
|
||||
int bits_per_sample, bytes_per_sample;
|
||||
int qmode, flags, xmode, num_channels, float_norm_exp;
|
||||
int32_t block_samples, extra_flags, sample_rate, channel_mask;
|
||||
uchar md5_checksum [16], md5_read;
|
||||
int num_tag_strings;
|
||||
char **tag_strings;
|
||||
} WavpackConfig;
|
||||
|
||||
#define CONFIG_BYTES_STORED 3 // 1-4 bytes/sample
|
||||
#define CONFIG_MONO_FLAG 4 // not stereo
|
||||
#define CONFIG_HYBRID_FLAG 8 // hybrid mode
|
||||
#define CONFIG_JOINT_STEREO 0x10 // joint stereo
|
||||
#define CONFIG_CROSS_DECORR 0x20 // no-delay cross decorrelation
|
||||
#define CONFIG_HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
|
||||
#define CONFIG_FLOAT_DATA 0x80 // ieee 32-bit floating point data
|
||||
|
||||
#define CONFIG_FAST_FLAG 0x200 // fast mode
|
||||
#define CONFIG_HIGH_FLAG 0x800 // high quality mode
|
||||
#define CONFIG_VERY_HIGH_FLAG 0x1000 // very high
|
||||
#define CONFIG_BITRATE_KBPS 0x2000 // bitrate is kbps, not bits / sample
|
||||
#define CONFIG_AUTO_SHAPING 0x4000 // automatic noise shaping
|
||||
#define CONFIG_SHAPE_OVERRIDE 0x8000 // shaping mode specified
|
||||
#define CONFIG_JOINT_OVERRIDE 0x10000 // joint-stereo mode specified
|
||||
#define CONFIG_DYNAMIC_SHAPING 0x20000 // dynamic noise shaping
|
||||
#define CONFIG_CREATE_EXE 0x40000 // create executable
|
||||
#define CONFIG_CREATE_WVC 0x80000 // create correction file
|
||||
#define CONFIG_OPTIMIZE_WVC 0x100000 // maximize bybrid compression
|
||||
#define CONFIG_CALC_NOISE 0x800000 // calc noise in hybrid mode
|
||||
#define CONFIG_LOSSY_MODE 0x1000000 // obsolete (for information)
|
||||
#define CONFIG_EXTRA_MODE 0x2000000 // extra processing mode
|
||||
#define CONFIG_SKIP_WVX 0x4000000 // no wvx stream w/ floats & big ints
|
||||
#define CONFIG_MD5_CHECKSUM 0x8000000 // compute & store MD5 signature
|
||||
#define CONFIG_MERGE_BLOCKS 0x10000000 // merge blocks of equal redundancy (for lossyWAV)
|
||||
#define CONFIG_OPTIMIZE_MONO 0x80000000 // optimize for mono streams posing as stereo
|
||||
|
||||
/*
|
||||
* These config flags were never actually used, or are no longer used, or are
|
||||
* used for something else now. They may be used in the future for what they
|
||||
* say, or for something else. WavPack files in the wild *may* have some of
|
||||
* these bit set in their config flags (with these older meanings), but only
|
||||
* if the stream version is 0x410 or less than 0x407. Of course, this is not
|
||||
* very important because once the file has been encoded, the config bits are
|
||||
* just for information purposes (i.e., they do not affect decoding),
|
||||
*
|
||||
#define CONFIG_ADOBE_MODE 0x100 // "adobe" mode for 32-bit floats
|
||||
#define CONFIG_VERY_FAST_FLAG 0x400 // double fast
|
||||
#define CONFIG_COPY_TIME 0x20000 // copy file-time from source
|
||||
#define CONFIG_QUALITY_MODE 0x200000 // psychoacoustic quality mode
|
||||
#define CONFIG_RAW_FLAG 0x400000 // raw mode (not implemented yet)
|
||||
#define CONFIG_QUIET_MODE 0x10000000 // don't report progress %
|
||||
#define CONFIG_IGNORE_LENGTH 0x20000000 // ignore length in wav header
|
||||
#define CONFIG_NEW_RIFF_HEADER 0x40000000 // generate new RIFF wav header
|
||||
*
|
||||
*/
|
||||
|
||||
#define EXTRA_SCAN_ONLY 1
|
||||
#define EXTRA_STEREO_MODES 2
|
||||
#define EXTRA_TRY_DELTAS 8
|
||||
#define EXTRA_ADJUST_DELTAS 16
|
||||
#define EXTRA_SORT_FIRST 32
|
||||
#define EXTRA_BRANCHES 0x1c0
|
||||
#define EXTRA_SKIP_8TO16 512
|
||||
#define EXTRA_TERMS 0x3c00
|
||||
#define EXTRA_DUMP_TERMS 16384
|
||||
#define EXTRA_SORT_LAST 32768
|
||||
|
||||
//////////////////////////////// WavPack Stream ///////////////////////////////
|
||||
|
||||
// This internal structure contains everything required to handle a WavPack
|
||||
// "stream", which is defined as a stereo or mono stream of audio samples. For
|
||||
// multichannel audio several of these would be required. Each stream contains
|
||||
// pointers to hold a complete allocated block of WavPack data, although it's
|
||||
// possible to decode WavPack blocks without buffering an entire block.
|
||||
|
||||
typedef struct bs {
|
||||
#ifdef BITSTREAM_SHORTS
|
||||
unsigned short *buf, *end, *ptr;
|
||||
#else
|
||||
unsigned char *buf, *end, *ptr;
|
||||
#endif
|
||||
void (*wrap)(struct bs *bs);
|
||||
int error, bc;
|
||||
uint32_t sr;
|
||||
} Bitstream;
|
||||
|
||||
#define MAX_WRAPPER_BYTES 16777216
|
||||
#define MAX_STREAMS 8
|
||||
#define MAX_NTERMS 16
|
||||
#define MAX_TERM 8
|
||||
|
||||
struct decorr_pass {
|
||||
int term, delta, weight_A, weight_B;
|
||||
int32_t samples_A [MAX_TERM], samples_B [MAX_TERM];
|
||||
int32_t aweight_A, aweight_B;
|
||||
int32_t sum_A, sum_B;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char joint_stereo, delta, terms [MAX_NTERMS+1];
|
||||
} WavpackDecorrSpec;
|
||||
|
||||
struct entropy_data {
|
||||
uint32_t median [3], slow_level, error_limit;
|
||||
};
|
||||
|
||||
struct words_data {
|
||||
uint32_t bitrate_delta [2], bitrate_acc [2];
|
||||
uint32_t pend_data, holding_one, zeros_acc;
|
||||
int holding_zero, pend_count;
|
||||
struct entropy_data c [2];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
WavpackHeader wphdr;
|
||||
struct words_data w;
|
||||
|
||||
uchar *blockbuff, *blockend;
|
||||
uchar *block2buff, *block2end;
|
||||
int32_t *sample_buffer;
|
||||
|
||||
int bits, num_terms, mute_error, joint_stereo, false_stereo, shift;
|
||||
int num_decorrs, num_passes, best_decorr, mask_decorr;
|
||||
uint32_t sample_index, crc, crc_x, crc_wvx;
|
||||
Bitstream wvbits, wvcbits, wvxbits;
|
||||
int init_done, wvc_skip;
|
||||
float delta_decay;
|
||||
|
||||
uchar int32_sent_bits, int32_zeros, int32_ones, int32_dups;
|
||||
uchar float_flags, float_shift, float_max_exp, float_norm_exp;
|
||||
|
||||
struct {
|
||||
int32_t shaping_acc [2], shaping_delta [2], error [2];
|
||||
double noise_sum, noise_ave, noise_max;
|
||||
short *shaping_data, *shaping_array;
|
||||
int32_t shaping_samples;
|
||||
} dc;
|
||||
|
||||
struct decorr_pass decorr_passes [MAX_NTERMS], analysis_pass;
|
||||
const WavpackDecorrSpec *decorr_specs;
|
||||
} WavpackStream;
|
||||
|
||||
// flags for float_flags:
|
||||
|
||||
#define FLOAT_SHIFT_ONES 1 // bits left-shifted into float = '1'
|
||||
#define FLOAT_SHIFT_SAME 2 // bits left-shifted into float are the same
|
||||
#define FLOAT_SHIFT_SENT 4 // bits shifted into float are sent literally
|
||||
#define FLOAT_ZEROS_SENT 8 // "zeros" are not all real zeros
|
||||
#define FLOAT_NEG_ZEROS 0x10 // contains negative zeros
|
||||
#define FLOAT_EXCEPTIONS 0x20 // contains exceptions (inf, nan, etc.)
|
||||
|
||||
/////////////////////////////// WavPack Context ///////////////////////////////
|
||||
|
||||
// This internal structure holds everything required to encode or decode WavPack
|
||||
// files. It is recommended that direct access to this structure be minimized
|
||||
// and the provided utilities used instead.
|
||||
|
||||
typedef struct {
|
||||
int32_t (*read_bytes)(void *id, void *data, int32_t bcount);
|
||||
uint32_t (*get_pos)(void *id);
|
||||
int (*set_pos_abs)(void *id, uint32_t pos);
|
||||
int (*set_pos_rel)(void *id, int32_t delta, int mode);
|
||||
int (*push_back_byte)(void *id, int c);
|
||||
uint32_t (*get_length)(void *id);
|
||||
int (*can_seek)(void *id);
|
||||
|
||||
// this callback is for writing edited tags only
|
||||
int32_t (*write_bytes)(void *id, void *data, int32_t bcount);
|
||||
} WavpackStreamReader;
|
||||
|
||||
typedef int (*WavpackBlockOutput)(void *id, void *data, int32_t bcount);
|
||||
|
||||
typedef struct {
|
||||
WavpackConfig config;
|
||||
|
||||
WavpackMetadata *metadata;
|
||||
uint32_t metabytes;
|
||||
int metacount;
|
||||
|
||||
uchar *wrapper_data;
|
||||
uint32_t wrapper_bytes;
|
||||
|
||||
WavpackBlockOutput blockout;
|
||||
void *wv_out, *wvc_out;
|
||||
|
||||
WavpackStreamReader *reader;
|
||||
void *wv_in, *wvc_in;
|
||||
|
||||
uint32_t filelen, file2len, filepos, file2pos, total_samples, crc_errors, first_flags;
|
||||
int wvc_flag, open_flags, norm_offset, reduced_channels, lossy_blocks, close_files;
|
||||
uint32_t block_samples, ave_block_samples, block_boundary, max_samples, acc_samples, initial_index;
|
||||
int riff_header_added, riff_header_created;
|
||||
M_Tag m_tag;
|
||||
|
||||
int current_stream, num_streams, stream_version;
|
||||
WavpackStream *streams [MAX_STREAMS];
|
||||
void *stream3;
|
||||
|
||||
char error_message [80];
|
||||
} WavpackContext;
|
||||
|
||||
//////////////////////// function prototypes and macros //////////////////////
|
||||
|
||||
#define CLEAR(destin) memset (&destin, 0, sizeof (destin));
|
||||
|
||||
// these macros implement the weight application and update operations
|
||||
// that are at the heart of the decorrelation loops
|
||||
|
||||
#define apply_weight_i(weight, sample) ((weight * sample + 512) >> 10)
|
||||
|
||||
#define apply_weight_f(weight, sample) (((((sample & 0xffff) * weight) >> 9) + \
|
||||
(((sample & ~0xffff) >> 9) * weight) + 1) >> 1)
|
||||
|
||||
#if 1 // PERFCOND
|
||||
#define apply_weight(weight, sample) (sample != (short) sample ? \
|
||||
apply_weight_f (weight, sample) : apply_weight_i (weight, sample))
|
||||
#else
|
||||
#define apply_weight(weight, sample) ((int32_t)((weight * (int64_t) sample + 512) >> 10))
|
||||
#endif
|
||||
|
||||
#if 1 // PERFCOND
|
||||
#define update_weight(weight, delta, source, result) \
|
||||
if (source && result) { int32_t s = (int32_t) (source ^ result) >> 31; weight = (delta ^ s) + (weight - s); }
|
||||
#elif 1
|
||||
#define update_weight(weight, delta, source, result) \
|
||||
if (source && result) weight += (((source ^ result) >> 30) | 1) * delta;
|
||||
#else
|
||||
#define update_weight(weight, delta, source, result) \
|
||||
if (source && result) (source ^ result) < 0 ? (weight -= delta) : (weight += delta);
|
||||
#endif
|
||||
|
||||
#define update_weight_d2(weight, delta, source, result) \
|
||||
if (source && result) weight -= (((source ^ result) >> 29) & 4) - 2;
|
||||
|
||||
#define update_weight_clip(weight, delta, source, result) \
|
||||
if (source && result) { \
|
||||
const int32_t s = (source ^ result) >> 31; \
|
||||
if ((weight = (weight ^ s) + (delta - s)) > 1024) weight = 1024; \
|
||||
weight = (weight ^ s) - s; \
|
||||
}
|
||||
|
||||
#define update_weight_clip_d2(weight, delta, source, result) \
|
||||
if (source && result) { \
|
||||
const int32_t s = (source ^ result) >> 31; \
|
||||
if ((weight = (weight ^ s) + (2 - s)) > 1024) weight = 1024; \
|
||||
weight = (weight ^ s) - s; \
|
||||
}
|
||||
|
||||
// bits.c
|
||||
|
||||
void bs_open_read (Bitstream *bs, void *buffer_start, void *buffer_end);
|
||||
void bs_open_write (Bitstream *bs, void *buffer_start, void *buffer_end);
|
||||
uint32_t bs_close_read (Bitstream *bs);
|
||||
uint32_t bs_close_write (Bitstream *bs);
|
||||
|
||||
int DoReadFile (FILE *hFile, void *lpBuffer, uint32_t nNumberOfBytesToRead, uint32_t *lpNumberOfBytesRead);
|
||||
int DoWriteFile (FILE *hFile, void *lpBuffer, uint32_t nNumberOfBytesToWrite, uint32_t *lpNumberOfBytesWritten);
|
||||
uint32_t DoGetFileSize (FILE *hFile), DoGetFilePosition (FILE *hFile);
|
||||
int DoSetFilePositionRelative (FILE *hFile, int32_t pos, int mode);
|
||||
int DoSetFilePositionAbsolute (FILE *hFile, uint32_t pos);
|
||||
int DoUngetc (int c, FILE *hFile), DoDeleteFile (char *filename);
|
||||
int DoCloseHandle (FILE *hFile), DoTruncateFile (FILE *hFile);
|
||||
|
||||
#define bs_is_open(bs) ((bs)->ptr != NULL)
|
||||
|
||||
#define getbit(bs) ( \
|
||||
(((bs)->bc) ? \
|
||||
((bs)->bc--, (bs)->sr & 1) : \
|
||||
(((++((bs)->ptr) != (bs)->end) ? (void) 0 : (bs)->wrap (bs)), (bs)->bc = sizeof (*((bs)->ptr)) * 8 - 1, ((bs)->sr = *((bs)->ptr)) & 1) \
|
||||
) ? \
|
||||
((bs)->sr >>= 1, 1) : \
|
||||
((bs)->sr >>= 1, 0) \
|
||||
)
|
||||
|
||||
#define getbits(value, nbits, bs) { \
|
||||
while ((nbits) > (bs)->bc) { \
|
||||
if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
|
||||
(bs)->sr |= (int32_t)*((bs)->ptr) << (bs)->bc; \
|
||||
(bs)->bc += sizeof (*((bs)->ptr)) * 8; \
|
||||
} \
|
||||
*(value) = (bs)->sr; \
|
||||
if ((bs)->bc > 32) { \
|
||||
(bs)->bc -= (nbits); \
|
||||
(bs)->sr = *((bs)->ptr) >> (sizeof (*((bs)->ptr)) * 8 - (bs)->bc); \
|
||||
} \
|
||||
else { \
|
||||
(bs)->bc -= (nbits); \
|
||||
(bs)->sr >>= (nbits); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define putbit(bit, bs) { if (bit) (bs)->sr |= (1 << (bs)->bc); \
|
||||
if (++((bs)->bc) == sizeof (*((bs)->ptr)) * 8) { \
|
||||
*((bs)->ptr) = (bs)->sr; \
|
||||
(bs)->sr = (bs)->bc = 0; \
|
||||
if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
|
||||
}}
|
||||
|
||||
#define putbit_0(bs) { \
|
||||
if (++((bs)->bc) == sizeof (*((bs)->ptr)) * 8) { \
|
||||
*((bs)->ptr) = (bs)->sr; \
|
||||
(bs)->sr = (bs)->bc = 0; \
|
||||
if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
|
||||
}}
|
||||
|
||||
#define putbit_1(bs) { (bs)->sr |= (1 << (bs)->bc); \
|
||||
if (++((bs)->bc) == sizeof (*((bs)->ptr)) * 8) { \
|
||||
*((bs)->ptr) = (bs)->sr; \
|
||||
(bs)->sr = (bs)->bc = 0; \
|
||||
if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
|
||||
}}
|
||||
|
||||
#define putbits(value, nbits, bs) { \
|
||||
(bs)->sr |= (int32_t)(value) << (bs)->bc; \
|
||||
if (((bs)->bc += (nbits)) >= sizeof (*((bs)->ptr)) * 8) \
|
||||
do { \
|
||||
*((bs)->ptr) = (bs)->sr; \
|
||||
(bs)->sr >>= sizeof (*((bs)->ptr)) * 8; \
|
||||
if (((bs)->bc -= sizeof (*((bs)->ptr)) * 8) > 32 - sizeof (*((bs)->ptr)) * 8) \
|
||||
(bs)->sr |= ((value) >> ((nbits) - (bs)->bc)); \
|
||||
if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
|
||||
} while ((bs)->bc >= sizeof (*((bs)->ptr)) * 8); \
|
||||
}
|
||||
|
||||
void little_endian_to_native (void *data, char *format);
|
||||
void native_to_little_endian (void *data, char *format);
|
||||
|
||||
// pack.c
|
||||
|
||||
void pack_init (WavpackContext *wpc);
|
||||
int pack_block (WavpackContext *wpc, int32_t *buffer);
|
||||
double WavpackGetEncodedNoise (WavpackContext *wpc, double *peak);
|
||||
|
||||
// unpack.c
|
||||
|
||||
int unpack_init (WavpackContext *wpc);
|
||||
int init_wv_bitstream (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
int init_wvc_bitstream (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
int init_wvx_bitstream (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
int read_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
int read_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
int read_shaping_info (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
int read_int32_info (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
int read_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd);
|
||||
int read_config_info (WavpackContext *wpc, WavpackMetadata *wpmd);
|
||||
int read_sample_rate (WavpackContext *wpc, WavpackMetadata *wpmd);
|
||||
int read_wrapper_data (WavpackContext *wpc, WavpackMetadata *wpmd);
|
||||
int32_t unpack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count);
|
||||
int check_crc_error (WavpackContext *wpc);
|
||||
|
||||
// unpack3.c
|
||||
|
||||
WavpackContext *open_file3 (WavpackContext *wpc, char *error);
|
||||
int32_t unpack_samples3 (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count);
|
||||
int seek_sample3 (WavpackContext *wpc, uint32_t desired_index);
|
||||
uint32_t get_sample_index3 (WavpackContext *wpc);
|
||||
void free_stream3 (WavpackContext *wpc);
|
||||
int get_version3 (WavpackContext *wpc);
|
||||
|
||||
// metadata.c stuff
|
||||
|
||||
int read_metadata_buff (WavpackMetadata *wpmd, uchar *blockbuff, uchar **buffptr);
|
||||
int write_metadata_block (WavpackContext *wpc);
|
||||
int copy_metadata (WavpackMetadata *wpmd, uchar *buffer_start, uchar *buffer_end);
|
||||
int add_to_metadata (WavpackContext *wpc, void *data, uint32_t bcount, uchar id);
|
||||
int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd);
|
||||
void free_metadata (WavpackMetadata *wpmd);
|
||||
|
||||
// words.c stuff
|
||||
|
||||
void init_words (WavpackStream *wps);
|
||||
void word_set_bitrate (WavpackStream *wps);
|
||||
void write_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
void write_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
int32_t FASTCALL send_word (WavpackStream *wps, int32_t value, int chan);
|
||||
void send_words_lossless (WavpackStream *wps, int32_t *buffer, int32_t nsamples);
|
||||
int32_t FASTCALL get_word (WavpackStream *wps, int chan, int32_t *correction);
|
||||
int32_t get_words_lossless (WavpackStream *wps, int32_t *buffer, int32_t nsamples);
|
||||
void flush_word (WavpackStream *wps);
|
||||
int32_t nosend_word (WavpackStream *wps, int32_t value, int chan);
|
||||
void scan_word (WavpackStream *wps, int32_t *samples, uint32_t num_samples, int dir);
|
||||
|
||||
int log2s (int32_t value);
|
||||
int32_t exp2s (int log);
|
||||
uint32_t log2buffer (int32_t *samples, uint32_t num_samples, int limit);
|
||||
|
||||
signed char store_weight (int weight);
|
||||
int restore_weight (signed char weight);
|
||||
|
||||
#define WORD_EOF ((int32_t)(1L << 31))
|
||||
|
||||
// float.c
|
||||
|
||||
void write_float_info (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
int scan_float_data (WavpackStream *wps, f32 *values, int32_t num_values);
|
||||
void send_float_data (WavpackStream *wps, f32 *values, int32_t num_values);
|
||||
int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||
void float_values (WavpackStream *wps, int32_t *values, int32_t num_values);
|
||||
void WavpackFloatNormalize (int32_t *values, int32_t num_values, int delta_exp);
|
||||
|
||||
// extra?.c
|
||||
|
||||
// void analyze_stereo (WavpackContext *wpc, int32_t *samples);
|
||||
// void analyze_mono (WavpackContext *wpc, int32_t *samples);
|
||||
void execute_stereo (WavpackContext *wpc, int32_t *samples, int no_history, int do_samples);
|
||||
void execute_mono (WavpackContext *wpc, int32_t *samples, int no_history, int do_samples);
|
||||
|
||||
// wputils.c
|
||||
|
||||
WavpackContext *WavpackOpenFileInputEx (WavpackStreamReader *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset);
|
||||
WavpackContext *WavpackOpenFileInput (const wchar_t *infilename, char *error, int flags, int norm_offset);
|
||||
|
||||
#define OPEN_WVC 0x1 // open/read "correction" file
|
||||
#define OPEN_TAGS 0x2 // read ID3v1 / APEv2 tags (seekable file)
|
||||
#define OPEN_WRAPPER 0x4 // make audio wrapper available (i.e. RIFF)
|
||||
#define OPEN_2CH_MAX 0x8 // open multichannel as stereo (no downmix)
|
||||
#define OPEN_NORMALIZE 0x10 // normalize floating point data to +/- 1.0
|
||||
#define OPEN_STREAMING 0x20 // "streaming" mode blindly unpacks blocks
|
||||
// w/o regard to header file position info
|
||||
#define OPEN_EDIT_TAGS 0x40 // allow editing of tags
|
||||
|
||||
int WavpackGetMode (WavpackContext *wpc);
|
||||
|
||||
#define MODE_WVC 0x1
|
||||
#define MODE_LOSSLESS 0x2
|
||||
#define MODE_HYBRID 0x4
|
||||
#define MODE_FLOAT 0x8
|
||||
#define MODE_VALID_TAG 0x10
|
||||
#define MODE_HIGH 0x20
|
||||
#define MODE_FAST 0x40
|
||||
#define MODE_EXTRA 0x80 // extra mode used, see MODE_XMODE for possible level
|
||||
#define MODE_APETAG 0x100
|
||||
#define MODE_SFX 0x200
|
||||
#define MODE_VERY_HIGH 0x400
|
||||
#define MODE_MD5 0x800
|
||||
#define MODE_XMODE 0x7000 // mask for extra level (1-6, 0=unknown)
|
||||
#define MODE_DNS 0x8000
|
||||
|
||||
char *WavpackGetErrorMessage (WavpackContext *wpc);
|
||||
int WavpackGetVersion (WavpackContext *wpc);
|
||||
uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t samples);
|
||||
uint32_t WavpackGetNumSamples (WavpackContext *wpc);
|
||||
uint32_t WavpackGetSampleIndex (WavpackContext *wpc);
|
||||
int WavpackGetNumErrors (WavpackContext *wpc);
|
||||
int WavpackLossyBlocks (WavpackContext *wpc);
|
||||
int WavpackSeekSample (WavpackContext *wpc, uint32_t sample);
|
||||
WavpackContext *WavpackCloseFile (WavpackContext *wpc);
|
||||
uint32_t WavpackGetSampleRate (WavpackContext *wpc);
|
||||
int WavpackGetBitsPerSample (WavpackContext *wpc);
|
||||
int WavpackGetBytesPerSample (WavpackContext *wpc);
|
||||
int WavpackGetNumChannels (WavpackContext *wpc);
|
||||
int WavpackGetChannelMask (WavpackContext *wpc);
|
||||
int WavpackGetReducedChannels (WavpackContext *wpc);
|
||||
int WavpackGetFloatNormExp (WavpackContext *wpc);
|
||||
int WavpackGetMD5Sum (WavpackContext *wpc, uchar data [16]);
|
||||
uint32_t WavpackGetWrapperBytes (WavpackContext *wpc);
|
||||
uchar *WavpackGetWrapperData (WavpackContext *wpc);
|
||||
void WavpackFreeWrapper (WavpackContext *wpc);
|
||||
void WavpackSeekTrailingWrapper (WavpackContext *wpc);
|
||||
double WavpackGetProgress (WavpackContext *wpc);
|
||||
uint32_t WavpackGetFileSize (WavpackContext *wpc);
|
||||
double WavpackGetRatio (WavpackContext *wpc);
|
||||
double WavpackGetAverageBitrate (WavpackContext *wpc, int count_wvc);
|
||||
double WavpackGetInstantBitrate (WavpackContext *wpc);
|
||||
int WavpackGetNumTagItems (WavpackContext *wpc);
|
||||
int WavpackGetTagItem (WavpackContext *wpc, const char *item, char *value, int size);
|
||||
int WavpackGetTagItemIndexed (WavpackContext *wpc, int index, char *item, int size);
|
||||
int WavpackAppendTagItem (WavpackContext *wpc, const char *item, const char *value, int vsize);
|
||||
int WavpackDeleteTagItem (WavpackContext *wpc, const char *item);
|
||||
int WavpackWriteTag (WavpackContext *wpc);
|
||||
|
||||
WavpackContext *WavpackOpenFileOutput (WavpackBlockOutput blockout, void *wv_id, void *wvc_id);
|
||||
int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_t total_samples);
|
||||
int WavpackAddWrapper (WavpackContext *wpc, void *data, uint32_t bcount);
|
||||
int WavpackStoreMD5Sum (WavpackContext *wpc, uchar data [16]);
|
||||
int WavpackPackInit (WavpackContext *wpc);
|
||||
int WavpackPackSamples (WavpackContext *wpc, int32_t *sample_buffer, uint32_t sample_count);
|
||||
int WavpackFlushSamples (WavpackContext *wpc);
|
||||
void WavpackUpdateNumSamples (WavpackContext *wpc, void *first_block);
|
||||
void *WavpackGetWrapperLocation (void *first_block, uint32_t *size);
|
||||
|
||||
void WavpackLittleEndianToNative (void *data, char *format);
|
||||
void WavpackNativeToLittleEndian (void *data, char *format);
|
||||
|
||||
uint32_t WavpackGetLibraryVersion (void);
|
||||
const char *WavpackGetLibraryVersionString (void);
|
||||
|
||||
///////////////////////////// SIMD helper macros /////////////////////////////
|
||||
|
||||
#ifdef OPT_MMX
|
||||
|
||||
#if defined (__GNUC__) && !defined (__INTEL_COMPILER)
|
||||
//directly map to gcc's native builtins for faster code
|
||||
|
||||
#if __GNUC__ < 4
|
||||
typedef int __di __attribute__ ((__mode__ (__DI__)));
|
||||
typedef int __m64 __attribute__ ((__mode__ (__V2SI__)));
|
||||
typedef int __v4hi __attribute__ ((__mode__ (__V4HI__)));
|
||||
#define _m_paddsw(m1, m2) (__m64) __builtin_ia32_paddsw ((__v4hi) m1, (__v4hi) m2)
|
||||
#define _m_pand(m1, m2) (__m64) __builtin_ia32_pand ((__di) m1, (__di) m2)
|
||||
#define _m_pandn(m1, m2) (__m64) __builtin_ia32_pandn ((__di) m1, (__di) m2)
|
||||
#define _m_pmaddwd(m1, m2) __builtin_ia32_pmaddwd ((__v4hi) m1, (__v4hi) m2)
|
||||
#define _m_por(m1, m2) (__m64) __builtin_ia32_por ((__di) m1, (__di) m2)
|
||||
#define _m_pxor(m1, m2) (__m64) __builtin_ia32_pxor ((__di) m1, (__di) m2)
|
||||
#else
|
||||
typedef int __m64 __attribute__ ((__vector_size__ (8)));
|
||||
typedef short __m64_16 __attribute__ ((__vector_size__ (8)));
|
||||
#define _m_paddsw(m1, m2) (__m64) __builtin_ia32_paddsw ((__m64_16) m1, (__m64_16) m2)
|
||||
#define _m_pand(m1, m2) __builtin_ia32_pand (m1, m2)
|
||||
#define _m_pandn(m1, m2) __builtin_ia32_pandn (m1, m2)
|
||||
#define _m_pmaddwd(m1, m2) __builtin_ia32_pmaddwd ((__m64_16) m1, (__m64_16) m2)
|
||||
#define _m_por(m1, m2) __builtin_ia32_por (m1, m2)
|
||||
#define _m_pxor(m1, m2) __builtin_ia32_pxor (m1, m2)
|
||||
#endif
|
||||
|
||||
#define _m_paddd(m1, m2) __builtin_ia32_paddd (m1, m2)
|
||||
#define _m_pcmpeqd(m1, m2) __builtin_ia32_pcmpeqd (m1, m2)
|
||||
#define _m_pslldi(m1, m2) __builtin_ia32_pslld (m1, m2)
|
||||
#define _m_psradi(m1, m2) __builtin_ia32_psrad (m1, m2)
|
||||
#define _m_psrldi(m1, m2) __builtin_ia32_psrld (m1, m2)
|
||||
#define _m_psubd(m1, m2) __builtin_ia32_psubd (m1, m2)
|
||||
#define _m_punpckhdq(m1, m2) __builtin_ia32_punpckhdq (m1, m2)
|
||||
#define _m_punpckldq(m1, m2) __builtin_ia32_punpckldq (m1, m2)
|
||||
#define _mm_empty() __builtin_ia32_emms ()
|
||||
#define _mm_set_pi32(m1, m2) { m2, m1 }
|
||||
#define _mm_set1_pi32(m) { m, m }
|
||||
|
||||
#else
|
||||
#include <mmintrin.h>
|
||||
#endif
|
||||
|
||||
#endif //OPT_MMX
|
||||
|
||||
#endif
|
||||
19
wavpack-4.5.0/src/wavpack_version.h
Normal file
19
wavpack-4.5.0/src/wavpack_version.h
Normal file
@@ -0,0 +1,19 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// **** WAVPACK **** //
|
||||
// Hybrid Lossless Wavefile Compressor //
|
||||
// Copyright (c) 1998 - 2006 Conifer Software. //
|
||||
// All Rights Reserved. //
|
||||
// Distributed under the BSD Software License (see license.txt) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// wavpack_version.h
|
||||
|
||||
#ifndef WAVPACK_VERSION_H
|
||||
#define WAVPACK_VERSION_H
|
||||
|
||||
#define LIBWAVPACK_MAJOR 4
|
||||
#define LIBWAVPACK_MINOR 50
|
||||
#define LIBWAVPACK_MICRO 0
|
||||
#define LIBWAVPACK_VERSION_STRING "4.50.0"
|
||||
|
||||
#endif
|
||||
1468
wavpack-4.5.0/src/words.c
Normal file
1468
wavpack-4.5.0/src/words.c
Normal file
File diff suppressed because it is too large
Load Diff
2928
wavpack-4.5.0/src/wputils.c
Normal file
2928
wavpack-4.5.0/src/wputils.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user