Blame gdither.c

Packit c948fe
/*
Packit c948fe
 *  Copyright (C) 2002 Steve Harris <steve@plugin.org.uk>
Packit c948fe
 *
Packit c948fe
 *  This program is free software; you can redistribute it and/or modify
Packit c948fe
 *  it under the terms of the GNU General Public License as published by
Packit c948fe
 *  the Free Software Foundation; either version 2 of the License, or
Packit c948fe
 *  (at your option) any later version.
Packit c948fe
 *
Packit c948fe
 *  This program is distributed in the hope that it will be useful,
Packit c948fe
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit c948fe
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit c948fe
 *  GNU General Public License for more details.
Packit c948fe
 *
Packit c948fe
 *  You should have received a copy of the GNU General Public License
Packit c948fe
 *  along with this program; if not, write to the Free Software
Packit c948fe
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Packit c948fe
 *
Packit c948fe
 *  $Id: dither.cc,v 1.3 2004/02/22 23:04:00 taybin Exp $
Packit c948fe
 */
Packit c948fe
Packit c948fe
#include "gdither_types_internal.h"
Packit c948fe
#include "gdither.h"
Packit c948fe
#include "noise.h"
Packit c948fe
Packit c948fe
/* this monstrosity is necessary to get access to lrintf() and random().
Packit c948fe
   whoever is writing the glibc headers <cmath> and <cstdlib> should be
Packit c948fe
   hauled off to a programmer re-education camp. for the rest of
Packit c948fe
   their natural lives. or longer. <paul@linuxaudiosystems.com>
Packit c948fe
*/
Packit c948fe
Packit c948fe
#define	_ISOC9X_SOURCE	1
Packit c948fe
#define _ISOC99_SOURCE	1
Packit c948fe
#ifdef __cplusplus
Packit c948fe
#include <cmath>
Packit c948fe
#else
Packit c948fe
#include <math.h>
Packit c948fe
#endif
Packit c948fe
Packit c948fe
#undef  __USE_SVID 
Packit c948fe
#define __USE_SVID 1
Packit c948fe
#ifdef __cplusplus
Packit c948fe
#include <cstdlib>
Packit c948fe
#else
Packit c948fe
#include <stdlib.h>
Packit c948fe
#endif
Packit c948fe
Packit c948fe
/* and even then sometimes it doesn't work... */
Packit c948fe
long lrintf(float);
Packit c948fe
Packit c948fe
#include <sys/types.h>
Packit c948fe
Packit c948fe
/* Lipshitz's minimally audible FIR, only really works for 46kHz-ish signals */
Packit c948fe
static const float shaped_bs[] = { 2.033f, -2.165f, 1.959f, -1.590f, 0.6149f };
Packit c948fe
// 2nd order: static const float shaped_bs[] = { 1.652f, -1.049, 0.1382 };
Packit c948fe
Packit c948fe
/* Some useful constants */
Packit c948fe
#define MAX_U8        255
Packit c948fe
#define MIN_U8          0
Packit c948fe
#define SCALE_U8      128.0f
Packit c948fe
Packit c948fe
#define MAX_S16     32767
Packit c948fe
#define MIN_S16    -32768
Packit c948fe
#define SCALE_S16   32768.0f
Packit c948fe
Packit c948fe
#define MAX_S24   8388607
Packit c948fe
#define MIN_S24  -8388608
Packit c948fe
#define SCALE_S24 8388608.0f
Packit c948fe
Packit c948fe
GDither gdither_new(GDitherType type, unsigned int channels,
Packit c948fe
		    GDitherSize bit_depth, int dither_depth)
Packit c948fe
{
Packit c948fe
    GDither s;
Packit c948fe
Packit c948fe
    s = (GDither)calloc(1, sizeof(struct GDither_s));
Packit c948fe
    s->type = type;
Packit c948fe
    s->channels = channels;
Packit c948fe
    s->bit_depth = (int)bit_depth;
Packit c948fe
Packit c948fe
    if (dither_depth <= 0 || dither_depth > (int)bit_depth) {
Packit c948fe
	dither_depth = (int)bit_depth;
Packit c948fe
    }
Packit c948fe
    s->dither_depth = dither_depth;
Packit c948fe
Packit c948fe
    s->scale = (float)(1LL << (dither_depth - 1));
Packit c948fe
    if (bit_depth == GDitherFloat || bit_depth == GDitherDouble) {
Packit c948fe
	s->post_scale_fp = 1.0f / s->scale;
Packit c948fe
	s->post_scale = 0;
Packit c948fe
    } else {
Packit c948fe
	s->post_scale_fp = 0.0f;
Packit c948fe
	s->post_scale = 1 << ((int)bit_depth - dither_depth);
Packit c948fe
    }
Packit c948fe
Packit c948fe
    switch (bit_depth) {
Packit c948fe
    case GDither8bit:
Packit c948fe
	/* Unsigned 8 bit */
Packit c948fe
	s->bias = 1.0f;
Packit c948fe
	s->clamp_u = 255;
Packit c948fe
	s->clamp_l = 0;
Packit c948fe
	break;
Packit c948fe
    case GDither16bit:
Packit c948fe
	/* Signed 16 bit */
Packit c948fe
	s->bias = 0.0f;
Packit c948fe
	s->clamp_u = 32767;
Packit c948fe
	s->clamp_l = -32768;
Packit c948fe
	break;
Packit c948fe
    case GDither32bit:
Packit c948fe
	/* Signed 24 bit, in upper 24 bits of 32 bit word */
Packit c948fe
	s->bias = 0.0f;
Packit c948fe
	s->clamp_u = 8388607;
Packit c948fe
	s->clamp_l = -8388608;
Packit c948fe
	break;
Packit c948fe
    case GDitherFloat:
Packit c948fe
	/* normalised float */
Packit c948fe
	s->bias = 0.0f;
Packit c948fe
	s->clamp_u = lrintf(s->scale);
Packit c948fe
	s->clamp_l = lrintf(-s->scale);
Packit c948fe
	break;
Packit c948fe
    case GDitherDouble:
Packit c948fe
	/* normalised float */
Packit c948fe
	s->bias = 0.0f;
Packit c948fe
	s->clamp_u = lrintf(s->scale);
Packit c948fe
	s->clamp_l = lrintf(-s->scale);
Packit c948fe
	break;
Packit c948fe
    case 23:
Packit c948fe
	/* special performance test case */
Packit c948fe
	s->scale = SCALE_S24;
Packit c948fe
	s->post_scale = 256;
Packit c948fe
	s->bias = 0.0f;
Packit c948fe
	s->clamp_u = 8388607;
Packit c948fe
	s->clamp_l = -8388608;
Packit c948fe
	break;
Packit c948fe
    default:
Packit c948fe
	/* Not a bit depth we can handle */
Packit c948fe
	free(s);
Packit c948fe
Packit c948fe
	return NULL;
Packit c948fe
	break;
Packit c948fe
    }
Packit c948fe
Packit c948fe
    switch (type) {
Packit c948fe
    case GDitherNone:
Packit c948fe
    case GDitherRect:
Packit c948fe
	/* No state */
Packit c948fe
	break;
Packit c948fe
Packit c948fe
    case GDitherTri:
Packit c948fe
	/* The last whitenoise sample */
Packit c948fe
	s->tri_state = (float *) calloc(channels, sizeof(float));
Packit c948fe
	break;
Packit c948fe
Packit c948fe
    case GDitherShaped:
Packit c948fe
	/* The error from the last few samples encoded */
Packit c948fe
	s->shaped_state = (GDitherShapedState*)
Packit c948fe
			   calloc(channels, sizeof(GDitherShapedState));
Packit c948fe
	break;
Packit c948fe
    }
Packit c948fe
Packit c948fe
    return s;
Packit c948fe
}
Packit c948fe
Packit c948fe
void gdither_free(GDither s)
Packit c948fe
{
Packit c948fe
    if (s) {
Packit c948fe
	free(s->tri_state);
Packit c948fe
	free(s->shaped_state);
Packit c948fe
	free(s);
Packit c948fe
    }
Packit c948fe
}
Packit c948fe
Packit c948fe
inline static void gdither_innner_loop(const GDitherType dt, 
Packit c948fe
    const unsigned int stride, const float bias, const float scale, 
Packit c948fe
    const unsigned int post_scale, const int bit_depth, 
Packit c948fe
    const unsigned int channel, const unsigned int length, float *ts, 
Packit c948fe
    GDitherShapedState *ss, float *x, void *y, const int clamp_u, 
Packit c948fe
    const int clamp_l)
Packit c948fe
{
Packit c948fe
    unsigned int pos, i;
Packit c948fe
    u_int8_t *o8 = (u_int8_t*) y;
Packit c948fe
    int16_t *o16 = (int16_t*) y;
Packit c948fe
    int32_t *o32 = (int32_t*) y;
Packit c948fe
    float tmp, r, ideal;
Packit c948fe
    int64_t clamped;
Packit c948fe
Packit c948fe
    i = channel;
Packit c948fe
    for (pos = 0; pos < length; pos++, i += stride) {
Packit c948fe
	tmp = x[pos] * scale + bias;
Packit c948fe
Packit c948fe
	switch (dt) {
Packit c948fe
	case GDitherNone:
Packit c948fe
	    break;
Packit c948fe
	case GDitherRect:
Packit c948fe
	    tmp -= GDITHER_NOISE;
Packit c948fe
	    break;
Packit c948fe
	case GDitherTri:
Packit c948fe
	    r = GDITHER_NOISE - 0.5f;
Packit c948fe
	    tmp -= r - ts[channel];
Packit c948fe
	    ts[channel] = r;
Packit c948fe
	    break;
Packit c948fe
	case GDitherShaped:
Packit c948fe
	    /* Save raw value for error calculations */
Packit c948fe
	    ideal = tmp;
Packit c948fe
Packit c948fe
	    /* Run FIR and add white noise */
Packit c948fe
	    ss->buffer[ss->phase] = GDITHER_NOISE * 0.5f;
Packit c948fe
	    tmp += ss->buffer[ss->phase] * shaped_bs[0]
Packit c948fe
		   + ss->buffer[(ss->phase - 1) & GDITHER_SH_BUF_MASK]
Packit c948fe
		     * shaped_bs[1]
Packit c948fe
		   + ss->buffer[(ss->phase - 2) & GDITHER_SH_BUF_MASK]
Packit c948fe
		     * shaped_bs[2]
Packit c948fe
		   + ss->buffer[(ss->phase - 3) & GDITHER_SH_BUF_MASK]
Packit c948fe
		     * shaped_bs[3]
Packit c948fe
		   + ss->buffer[(ss->phase - 4) & GDITHER_SH_BUF_MASK]
Packit c948fe
		     * shaped_bs[4];
Packit c948fe
Packit c948fe
	    /* Roll buffer and store last error */
Packit c948fe
	    ss->phase = (ss->phase + 1) & GDITHER_SH_BUF_MASK;
Packit c948fe
	    ss->buffer[ss->phase] = (float)lrintf(tmp) - ideal;
Packit c948fe
	    break;
Packit c948fe
	}
Packit c948fe
	
Packit c948fe
	clamped = lrintf(tmp);
Packit c948fe
	if (clamped > clamp_u) {
Packit c948fe
		clamped = clamp_u;
Packit c948fe
	} else if (clamped < clamp_l) {
Packit c948fe
		clamped = clamp_l;
Packit c948fe
	}
Packit c948fe
Packit c948fe
	switch (bit_depth) {
Packit c948fe
	case GDither8bit:
Packit c948fe
	    o8[i] = (u_int8_t) (clamped * post_scale);
Packit c948fe
	    break;
Packit c948fe
	case GDither16bit:
Packit c948fe
	    o16[i] = (int16_t) (clamped * post_scale);
Packit c948fe
	    break;
Packit c948fe
	case GDither32bit:
Packit c948fe
	    o32[i] = (int32_t) (clamped * post_scale);
Packit c948fe
	    break;
Packit c948fe
	}
Packit c948fe
    }
Packit c948fe
}
Packit c948fe
Packit c948fe
/* floating pint version of the inner loop function */
Packit c948fe
inline static void gdither_innner_loop_fp(const GDitherType dt, 
Packit c948fe
    const unsigned int stride, const float bias, const float scale, 
Packit c948fe
    const float post_scale, const int bit_depth, 
Packit c948fe
    const unsigned int channel, const unsigned int length, float *ts, 
Packit c948fe
    GDitherShapedState *ss, float *x, void *y, const int clamp_u, 
Packit c948fe
    const int clamp_l)
Packit c948fe
{
Packit c948fe
    unsigned int pos, i;
Packit c948fe
    float *oflt = (float*) y;
Packit c948fe
    double *odbl = (double*) y;
Packit c948fe
    float tmp, r, ideal;
Packit c948fe
    double clamped;
Packit c948fe
Packit c948fe
    i = channel;
Packit c948fe
    for (pos = 0; pos < length; pos++, i += stride) {
Packit c948fe
	tmp = x[i] * scale + bias;
Packit c948fe
Packit c948fe
	switch (dt) {
Packit c948fe
	case GDitherNone:
Packit c948fe
	    break;
Packit c948fe
	case GDitherRect:
Packit c948fe
	    tmp -= GDITHER_NOISE;
Packit c948fe
	    break;
Packit c948fe
	case GDitherTri:
Packit c948fe
	    r = GDITHER_NOISE - 0.5f;
Packit c948fe
	    tmp -= r - ts[channel];
Packit c948fe
	    ts[channel] = r;
Packit c948fe
	    break;
Packit c948fe
	case GDitherShaped:
Packit c948fe
	    /* Save raw value for error calculations */
Packit c948fe
	    ideal = tmp;
Packit c948fe
Packit c948fe
	    /* Run FIR and add white noise */
Packit c948fe
	    ss->buffer[ss->phase] = GDITHER_NOISE * 0.5f;
Packit c948fe
	    tmp += ss->buffer[ss->phase] * shaped_bs[0]
Packit c948fe
		   + ss->buffer[(ss->phase - 1) & GDITHER_SH_BUF_MASK]
Packit c948fe
		     * shaped_bs[1]
Packit c948fe
		   + ss->buffer[(ss->phase - 2) & GDITHER_SH_BUF_MASK]
Packit c948fe
		     * shaped_bs[2]
Packit c948fe
		   + ss->buffer[(ss->phase - 3) & GDITHER_SH_BUF_MASK]
Packit c948fe
		     * shaped_bs[3]
Packit c948fe
		   + ss->buffer[(ss->phase - 4) & GDITHER_SH_BUF_MASK]
Packit c948fe
		     * shaped_bs[4];
Packit c948fe
Packit c948fe
	    /* Roll buffer and store last error */
Packit c948fe
	    ss->phase = (ss->phase + 1) & GDITHER_SH_BUF_MASK;
Packit c948fe
	    ss->buffer[ss->phase] = (float)lrintf(tmp) - ideal;
Packit c948fe
	    break;
Packit c948fe
	}
Packit c948fe
	
Packit c948fe
	clamped = rintf(tmp);
Packit c948fe
	if (clamped > clamp_u) {
Packit c948fe
		clamped = clamp_u;
Packit c948fe
	} else if (clamped < clamp_l) {
Packit c948fe
		clamped = clamp_l;
Packit c948fe
	}
Packit c948fe
Packit c948fe
	switch (bit_depth) {
Packit c948fe
	case GDitherFloat:
Packit c948fe
	    oflt[i] = (float) (clamped * post_scale);
Packit c948fe
	    break;
Packit c948fe
	case GDitherDouble:
Packit c948fe
	    odbl[i] = (double) (clamped * post_scale);
Packit c948fe
	    break;
Packit c948fe
	}
Packit c948fe
    }
Packit c948fe
}
Packit c948fe
Packit c948fe
#define GDITHER_CONV_BLOCK 512
Packit c948fe
Packit c948fe
void gdither_run(GDither s, unsigned int channel, unsigned int length,
Packit c948fe
                 double *x, void *y)
Packit c948fe
{
Packit c948fe
    float conv[GDITHER_CONV_BLOCK];
Packit c948fe
    unsigned int i, pos;
Packit c948fe
    char *ycast = (char *)y;
Packit c948fe
    int step;
Packit c948fe
Packit c948fe
    switch (s->bit_depth) {
Packit c948fe
    case GDither8bit:
Packit c948fe
	step = 1;
Packit c948fe
	break;
Packit c948fe
    case GDither16bit:
Packit c948fe
	step = 2;
Packit c948fe
	break;
Packit c948fe
    case GDither32bit:
Packit c948fe
    case GDitherFloat:
Packit c948fe
	step = 4;
Packit c948fe
	break;
Packit c948fe
    case GDitherDouble:
Packit c948fe
	step = 8;
Packit c948fe
	break;
Packit c948fe
    default:
Packit c948fe
	step = 0;
Packit c948fe
	break;
Packit c948fe
    }
Packit c948fe
Packit c948fe
    pos = 0;
Packit c948fe
    while (pos < length) {
Packit c948fe
	for (i=0; (i + pos) < length && i < GDITHER_CONV_BLOCK; i++) {
Packit c948fe
	    conv[i] = x[pos + i];
Packit c948fe
	}
Packit 63997b
	gdither_runf(s, channel, i, conv, ycast + pos * step);
Packit c948fe
	pos += i;
Packit c948fe
    }
Packit c948fe
}
Packit c948fe
Packit c948fe
void gdither_runf(GDither s, unsigned int channel, unsigned int length,
Packit c948fe
                 float *x, void *y)
Packit c948fe
{
Packit c948fe
    unsigned int pos, i;
Packit c948fe
    float tmp;
Packit c948fe
    int64_t clamped;
Packit c948fe
    GDitherShapedState *ss = NULL;
Packit c948fe
Packit c948fe
    if (!s || channel >= s->channels) {
Packit c948fe
	return;
Packit c948fe
    }
Packit c948fe
Packit c948fe
    if (s->shaped_state) {
Packit c948fe
	ss = s->shaped_state + channel;
Packit c948fe
    }
Packit c948fe
Packit c948fe
    if (s->type == GDitherNone && s->bit_depth == 23) {
Packit c948fe
	int32_t *o32 = (int32_t*) y;
Packit c948fe
Packit c948fe
        for (pos = 0; pos < length; pos++) {
Packit c948fe
            i = channel + (pos * s->channels);
Packit c948fe
            tmp = x[i] * 8388608.0f;
Packit c948fe
Packit c948fe
            clamped = lrintf(tmp);
Packit c948fe
            if (clamped > 8388607) {
Packit c948fe
                    clamped = 8388607;
Packit c948fe
            } else if (clamped < -8388608) {
Packit c948fe
                    clamped = -8388608;
Packit c948fe
            }
Packit c948fe
Packit c948fe
            o32[i] = (int32_t) (clamped * 256);
Packit c948fe
        }
Packit c948fe
Packit c948fe
        return;
Packit c948fe
    }
Packit c948fe
Packit c948fe
    /* some common case handling code - looks a bit wierd, but it allows
Packit c948fe
     * the compiler to optiomise out the branches in the inner loop */
Packit c948fe
    if (s->bit_depth == 8 && s->dither_depth == 8) {
Packit c948fe
	switch (s->type) {
Packit c948fe
	case GDitherNone:
Packit c948fe
	    gdither_innner_loop(GDitherNone, s->channels, 128.0f, SCALE_U8,
Packit c948fe
				1, 8, channel, length, NULL, NULL, x, y,
Packit c948fe
				MAX_U8, MIN_U8);
Packit c948fe
	    break;
Packit c948fe
	case GDitherRect:
Packit c948fe
	    gdither_innner_loop(GDitherRect, s->channels, 128.0f, SCALE_U8,
Packit c948fe
				1, 8, channel, length, NULL, NULL, x, y,
Packit c948fe
				MAX_U8, MIN_U8);
Packit c948fe
	    break;
Packit c948fe
	case GDitherTri:
Packit c948fe
	    gdither_innner_loop(GDitherTri, s->channels, 128.0f, SCALE_U8,
Packit c948fe
				1, 8, channel, length, s->tri_state,
Packit c948fe
				NULL, x, y, MAX_U8, MIN_U8);
Packit c948fe
	    break;
Packit c948fe
	case GDitherShaped:
Packit c948fe
	    gdither_innner_loop(GDitherShaped, s->channels, 128.0f, SCALE_U8,
Packit c948fe
			        1, 8, channel, length, NULL,
Packit c948fe
				ss, x, y, MAX_U8, MIN_U8);
Packit c948fe
	    break;
Packit c948fe
	}
Packit c948fe
    } else if (s->bit_depth == 16 && s->dither_depth == 16) {
Packit c948fe
	switch (s->type) {
Packit c948fe
	case GDitherNone:
Packit c948fe
	    gdither_innner_loop(GDitherNone, s->channels, 0.0f, SCALE_S16,
Packit c948fe
				1, 16, channel, length, NULL, NULL, x, y,
Packit c948fe
				MAX_S16, MIN_S16);
Packit c948fe
	    break;
Packit c948fe
	case GDitherRect:
Packit c948fe
	    gdither_innner_loop(GDitherRect, s->channels, 0.0f, SCALE_S16,
Packit c948fe
				1, 16, channel, length, NULL, NULL, x, y,
Packit c948fe
				MAX_S16, MIN_S16);
Packit c948fe
	    break;
Packit c948fe
	case GDitherTri:
Packit c948fe
	    gdither_innner_loop(GDitherTri, s->channels, 0.0f, SCALE_S16,
Packit c948fe
				1, 16, channel, length, s->tri_state,
Packit c948fe
				NULL, x, y, MAX_S16, MIN_S16);
Packit c948fe
	    break;
Packit c948fe
	case GDitherShaped:
Packit c948fe
	    gdither_innner_loop(GDitherShaped, s->channels, 0.0f,
Packit c948fe
				SCALE_S16, 1, 16, channel, length, NULL,
Packit c948fe
				ss, x, y, MAX_S16, MIN_S16);
Packit c948fe
	    break;
Packit c948fe
	}
Packit c948fe
    } else if (s->bit_depth == 32 && s->dither_depth == 24) {
Packit c948fe
	switch (s->type) {
Packit c948fe
	case GDitherNone:
Packit c948fe
	    gdither_innner_loop(GDitherNone, s->channels, 0.0f, SCALE_S24,
Packit c948fe
				256, 32, channel, length, NULL, NULL, x,
Packit c948fe
				y, MAX_S24, MIN_S24);
Packit c948fe
	    break;
Packit c948fe
	case GDitherRect:
Packit c948fe
	    gdither_innner_loop(GDitherRect, s->channels, 0.0f, SCALE_S24,
Packit c948fe
				256, 32, channel, length, NULL, NULL, x,
Packit c948fe
				y, MAX_S24, MIN_S24);
Packit c948fe
	    break;
Packit c948fe
	case GDitherTri:
Packit c948fe
	    gdither_innner_loop(GDitherTri, s->channels, 0.0f, SCALE_S24,
Packit c948fe
				256, 32, channel, length, s->tri_state,
Packit c948fe
				NULL, x, y, MAX_S24, MIN_S24);
Packit c948fe
	    break;
Packit c948fe
	case GDitherShaped:
Packit c948fe
	    gdither_innner_loop(GDitherShaped, s->channels, 0.0f, SCALE_S24,
Packit c948fe
				256, 32, channel, length,
Packit c948fe
				NULL, ss, x, y, MAX_S24, MIN_S24);
Packit c948fe
	    break;
Packit c948fe
	}
Packit c948fe
    } else if (s->bit_depth == GDitherFloat || s->bit_depth == GDitherDouble) {
Packit c948fe
	gdither_innner_loop_fp(s->type, s->channels, s->bias, s->scale,
Packit c948fe
			    s->post_scale_fp, s->bit_depth, channel, length,
Packit c948fe
			    s->tri_state, ss, x, y, s->clamp_u, s->clamp_l);
Packit c948fe
    } else {
Packit c948fe
	/* no special case handling, just process it from the struct */
Packit c948fe
Packit c948fe
	gdither_innner_loop(s->type, s->channels, s->bias, s->scale,
Packit c948fe
			    s->post_scale, s->bit_depth, channel,
Packit c948fe
			    length, s->tri_state, ss, x, y, s->clamp_u,
Packit c948fe
			    s->clamp_l);
Packit c948fe
    }
Packit c948fe
}
Packit c948fe
Packit c948fe
/* vi:set ts=8 sts=4 sw=4: */