vdr/xine-lib-vdr/src/post/audio Makefile.am Makefile.in audio_filters.c audio_filters.h dsp.h filter.c filter.h stretch.c upmix.c window.c window.h

Darren Salt pkg-vdr-dvb-changes@lists.alioth.debian.org
Mon, 04 Apr 2005 22:38:20 +0000


Update of /cvsroot/pkg-vdr-dvb/vdr/xine-lib-vdr/src/post/audio
In directory haydn:/tmp/cvs-serv13100/src/post/audio

Added Files:
	Makefile.am Makefile.in audio_filters.c audio_filters.h dsp.h 
	filter.c filter.h stretch.c upmix.c window.c window.h 
Log Message:
Import of VDR-patched xine-lib.

--- NEW FILE: window.c ---
/*=============================================================================
 *	
 *  This software has been released under the terms of the GNU Public
 *  license. See http://www.gnu.org/copyleft/gpl.html for details.
 *
 *  Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au
 *
 *=============================================================================
 */

/* Calculates a number of window functions. The following window
 * functions are currently implemented: Boxcar, Triang, Hanning,
 * Hamming, Blackman, Flattop and Kaiser. In the function call n is
 * the number of filter taps and w the buffer in which the filter
 * coefficients will be stored.
 */

#include <math.h>
#include "dsp.h"

/*
 * Boxcar
 *
 * n window length
 * w buffer for the window parameters
 */
void boxcar(int n, _ftype_t* w)
{
  int i;
  /* Calculate window coefficients */
  for (i=0 ; i<n ; i++)
    w[i] = 1.0;
}


/*
 * Triang a.k.a Bartlett
 *
 *               |    (N-1)| 
 *           2 * |k - -----|
 *               |      2  |
 * w = 1.0 - ---------------
 *                    N+1
 * n window length
 * w buffer for the window parameters
 */
void triang(int n, _ftype_t* w)
{
  _ftype_t k1  = (_ftype_t)(n & 1);
  _ftype_t k2  = 1/((_ftype_t)n + k1);
  int      end = (n + 1) >> 1;
  int	   i;
  
  /* Calculate window coefficients */
  for (i=0 ; i<end ; i++)
    w[i] = w[n-i-1] = (2.0*((_ftype_t)(i+1))-(1.0-k1))*k2;
}


/*
 * Hanning
 *                   2*pi*k
 * w = 0.5 - 0.5*cos(------), where 0 < k <= N
 *                    N+1
 * n window length
 * w buffer for the window parameters
 */
void hanning(int n, _ftype_t* w)
{
  int	   i;
  _ftype_t k = 2*M_PI/((_ftype_t)(n+1)); /* 2*pi/(N+1) */
  
  /* Calculate window coefficients */
  for (i=0; i<n; i++)
    *w++ = 0.5*(1.0 - cos(k*(_ftype_t)(i+1)));
}

/*
 * Hamming
 *                        2*pi*k
 * w(k) = 0.54 - 0.46*cos(------), where 0 <= k < N
 *                         N-1
 *
 * n window length
 * w buffer for the window parameters
 */
void hamming(int n,_ftype_t* w)
{
  int      i;
  _ftype_t k = 2*M_PI/((_ftype_t)(n-1)); /* 2*pi/(N-1) */

  /* Calculate window coefficients */
  for (i=0; i<n; i++)
    *w++ = 0.54 - 0.46*cos(k*(_ftype_t)i);
}

/*
 * Blackman
 *                       2*pi*k             4*pi*k
 * w(k) = 0.42 - 0.5*cos(------) + 0.08*cos(------), where 0 <= k < N
 *                        N-1                 N-1
 *
 * n window length
 * w buffer for the window parameters
 */
void blackman(int n,_ftype_t* w)
{
  int      i;
  _ftype_t k1 = 2*M_PI/((_ftype_t)(n-1)); /* 2*pi/(N-1) */
  _ftype_t k2 = 2*k1; /* 4*pi/(N-1) */

  /* Calculate window coefficients */
  for (i=0; i<n; i++)
    *w++ = 0.42 - 0.50*cos(k1*(_ftype_t)i) + 0.08*cos(k2*(_ftype_t)i);
}

/*
 * Flattop
 *                                        2*pi*k                     4*pi*k
 * w(k) = 0.2810638602 - 0.5208971735*cos(------) + 0.1980389663*cos(------), where 0 <= k < N
 *                                          N-1                        N-1
 *
 * n window length
 * w buffer for the window parameters
 */
void flattop(int n,_ftype_t* w)
{
  int      i;
  _ftype_t k1 = 2*M_PI/((_ftype_t)(n-1)); /* 2*pi/(N-1) */
  _ftype_t k2 = 2*k1;                   /* 4*pi/(N-1) */
  
  /* Calculate window coefficients */
  for (i=0; i<n; i++)
    *w++ = 0.2810638602 - 0.5208971735*cos(k1*(_ftype_t)i) + 0.1980389663*cos(k2*(_ftype_t)i);
}

/* Computes the 0th order modified Bessel function of the first kind.  
 * (Needed to compute Kaiser window) 
 *   
 * y = sum( (x/(2*n))^2 )
 *      n
 */
#define BIZ_EPSILON 1E-21 /* Max error acceptable */

static _ftype_t besselizero(_ftype_t x)
{ 
  _ftype_t temp;
  _ftype_t sum   = 1.0;
  _ftype_t u     = 1.0;
  _ftype_t halfx = x/2.0;
  int      n     = 1;

  do {
    temp = halfx/(_ftype_t)n;
    u *=temp * temp;
    sum += u;
    n++;
  } while (u >= BIZ_EPSILON * sum);
  return(sum);
}

/*
 * Kaiser
 *
 * n window length
 * w buffer for the window parameters
 * b beta parameter of Kaiser window, Beta >= 1
 *
 * Beta trades the rejection of the low pass filter against the
 * transition width from passband to stop band.  Larger Beta means a
 * slower transition and greater stop band rejection.  See Rabiner and
 * Gold (Theory and Application of DSP) under Kaiser windows for more
 * about Beta.  The following table from Rabiner and Gold gives some
 * feel for the effect of Beta:
 * 
 * All ripples in dB, width of transition band = D*N where N = window
 * length
 * 
 * BETA    D       PB RIP   SB RIP
 * 2.120   1.50  +-0.27      -30
 * 3.384   2.23    0.0864    -40
 * 4.538   2.93    0.0274    -50
 * 5.658   3.62    0.00868   -60
 * 6.764   4.32    0.00275   -70
 * 7.865   5.0     0.000868  -80
 * 8.960   5.7     0.000275  -90
 * 10.056  6.4     0.000087  -100
 */
void kaiser(int n, _ftype_t* w, _ftype_t b)
{
  _ftype_t tmp;
  _ftype_t k1  = 1.0/besselizero(b);
  int	   k2  = 1 - (n & 1);
  int      end = (n + 1) >> 1;
  int      i; 
  
  /* Calculate window coefficients */
  for (i=0 ; i<end ; i++){
    tmp = (_ftype_t)(2*i + k2) / ((_ftype_t)n - 1.0);
    w[end-(1&(!k2))+i] = w[end-1-i] = k1 * besselizero(b*sqrt(1.0 - tmp*tmp));
  }
}


--- NEW FILE: audio_filters.c ---
/*
 * Copyright (C) 2000-2004 the xine project
 * 
 * This file is part of xine, a free video player.
 * 
 * xine is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * xine is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
 *
 * $Id: audio_filters.c,v 1.1 2005/04/04 22:38:17 dsalt-guest Exp $
 *
 * catalog for audio filter plugins
 */


#include "xine_internal.h"
#include "xineutils.h"
#include "post.h"

#include "audio_filters.h"


post_info_t upmix_special_info   = { XINE_POST_TYPE_AUDIO_FILTER };
post_info_t stretch_special_info = { XINE_POST_TYPE_AUDIO_FILTER };


plugin_info_t xine_plugin_info[] = {
  /* type, API, "name", version, special_info, init_function */  
  { PLUGIN_POST, 9, "upmix", XINE_VERSION_CODE, &upmix_special_info, &upmix_init_plugin },
  { PLUGIN_POST, 9, "stretch", XINE_VERSION_CODE, &stretch_special_info, &stretch_init_plugin },
  { PLUGIN_NONE, 0, "", 0, NULL, NULL }
};

--- NEW FILE: audio_filters.h ---
/*
 * Copyright (C) 2000-2004 the xine project
 * 
 * This file is part of xine, a free video player.
 * 
 * xine is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * xine is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
 *
 * $Id: audio_filters.h,v 1.1 2005/04/04 22:38:18 dsalt-guest Exp $
 *
 * catalog for audio filter plugins
 */

#include "xine_internal.h"


void *upmix_init_plugin(xine_t *xine, void *data);
void *stretch_init_plugin(xine_t *xine, void *data);

--- NEW FILE: window.h ---
/*=============================================================================
 *	
 *  This software has been released under the terms of the GNU Public
 *  license. See http://www.gnu.org/copyleft/gpl.html for details.
 *
 *  Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au
 *
 *=============================================================================
 */

/* Calculates a number of window functions. The following window
 * functions are currently implemented: Boxcar, Triang, Hanning,
 * Hamming, Blackman, Flattop and Kaiser. In the function call n is
 * the number of filter taps and w the buffer in which the filter
 * coefficients will be stored.
 */

#if !defined _DSP_H
# error "Never use <window.h> directly; include <dsp.h> instead"
#endif

#ifndef _WINDOW_H
#define _WINDOW_H	1

extern void boxcar(int n, _ftype_t* w);
extern void triang(int n, _ftype_t* w);
extern void hanning(int n, _ftype_t* w);
extern void hamming(int n,_ftype_t* w);
extern void blackman(int n,_ftype_t* w);
extern void flattop(int n,_ftype_t* w);
extern void kaiser(int n, _ftype_t* w,_ftype_t b);

#endif

--- NEW FILE: Makefile.am ---
include $(top_srcdir)/misc/Makefile.common

noinst_HEADERS = dsp.h filter.h window.h audio_filters.h

libdir = $(XINE_PLUGINDIR)/post

lib_LTLIBRARIES = xineplug_post_audio_filters.la

xineplug_post_audio_filters_la_SOURCES = \
        upmix.c filter.c window.c stretch.c audio_filters.c
xineplug_post_audio_filters_la_LIBADD = $(XINE_LIB)
xineplug_post_audio_filters_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ -lm


--- NEW FILE: upmix.c ---
/*
 * Copyright (C) 2000-2004 the xine project
 * 
 * This file is part of xine, a free video player.
 * 
 * xine is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * xine is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
 *
 * Upmix audio filter for xine.
 *   (c) 2004 James Courtier-Dutton (James@superbug.demon.co.uk)
 * This is an up-mix audio filter post plugin.
 * It simply creates output channels to match the speaker arrangement.
 * E.g. Converts Stereo into Surround 5.1
 *
 * $Id: upmix.c,v 1.1 2005/04/04 22:38:18 dsalt-guest Exp $
 *
 */

#include <stdio.h>

#include "xine_internal.h"
#include "xineutils.h"
#include "post.h"
#include "dsp.h"

#include "audio_filters.h"


typedef struct post_plugin_upmix_s post_plugin_upmix_t;

typedef struct post_class_upmix_s post_class_upmix_t;

struct post_class_upmix_s {
  post_class_t        post_class;

  xine_t             *xine;
};

/* Q value for low-pass filter */
#define Q 1.0

/* Analog domain biquad section */
typedef struct{
  float a[3];           /* Numerator coefficients */
  float b[3];           /* Denominator coefficients */
} biquad_t;

/* S-parameters for designing 4th order Butterworth filter */
static biquad_t s_param[2] = {{{1.0,0.0,0.0},{1.0,0.765367,1.0}},
                         {{1.0,0.0,0.0},{1.0,1.847759,1.0}}};

/* Data for specific instances of this filter */
typedef struct af_sub_s
{
  float w[2][4];        /* Filter taps for low-pass filter */
  float q[2][2];        /* Circular queues */
  float fc;             /* Cutoff frequency [Hz] for low-pass filter */
  float k;              /* Filter gain */
}af_sub_t;

#ifndef IIR
#define IIR(in,w,q,out) { \
  float h0 = (q)[0]; \
  float h1 = (q)[1]; \
  float hn = (in) - h0 * (w)[0] - h1 * (w)[1];  \
  out = hn + h0 * (w)[2] + h1 * (w)[3];  \
  (q)[1] = h0; \
  (q)[0] = hn; \
}
#endif

typedef struct upmix_parameters_s {
  int cut_off_freq;
} upmix_parameters_t;

/*
 * description of params struct
 */
START_PARAM_DESCR( upmix_parameters_t )
PARAM_ITEM( POST_PARAM_TYPE_INT, cut_off_freq, NULL, 0, 500, 0,
            "cut_off_freq" )
END_PARAM_DESCR( param_descr )

struct post_plugin_upmix_s {
  post_plugin_t  post;

  /* private data */
  pthread_mutex_t    lock;
  xine_post_in_t params_input;
  upmix_parameters_t params;
  audio_buffer_t *buf;   /* dummy buffer just to hold a copy of audio data */
  af_sub_t       *sub;
  int            channels;
  int            channels_out;
};

/**************************************************************************
 * upmix parameters functions
 *************************************************************************/
static int set_parameters (xine_post_t *this_gen, void *param_gen) {
  post_plugin_upmix_t *this = (post_plugin_upmix_t *)this_gen;
  upmix_parameters_t *param = (upmix_parameters_t *)param_gen;

  pthread_mutex_lock (&this->lock);
  memcpy( &this->params, param, sizeof(upmix_parameters_t) );
  pthread_mutex_unlock (&this->lock);

  return 1;
}
static int get_parameters (xine_post_t *this_gen, void *param_gen) {
  post_plugin_upmix_t *this = (post_plugin_upmix_t *)this_gen;
  upmix_parameters_t *param = (upmix_parameters_t *)param_gen;

  pthread_mutex_lock (&this->lock);
  memcpy( param, &this->params, sizeof(upmix_parameters_t) );
  pthread_mutex_unlock (&this->lock);

  return 1;
}

static xine_post_api_descr_t * get_param_descr (void) {
  return &param_descr;
}

static char * get_help (void) {
  return _("Upmix functions. e.g. Take stereo input and produce Surround 5.1 output."
           "\n"
           "Parameters\n"
           "  cut_off_freq\n"
           "\n"
           "Note: It is possible to use frontend's control window to set "
           "these parameters.\n"
           "\n"
           );
}

static xine_post_api_t post_api = {
  set_parameters,
  get_parameters,
  get_param_descr,
  get_help,
};


/**************************************************************************
 * xine audio post plugin functions
 *************************************************************************/

static int upmix_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream,
		   uint32_t bits, uint32_t rate, int mode) {

  post_audio_port_t  *port = (post_audio_port_t *)port_gen;
  post_plugin_upmix_t *this = (post_plugin_upmix_t *)port->post;
  uint32_t capabilities;

  _x_post_rewire(&this->post);
  _x_post_inc_usage(port);
  
  port->stream = stream;
  port->bits = bits;
  port->rate = rate;
  port->mode = mode;
  capabilities = port->original_port->get_capabilities(port->original_port);
  
  this->channels = _x_ao_mode2channels(mode);
  /* FIXME: Handle all desired output formats */
  if ((capabilities & AO_CAP_MODE_5_1CHANNEL) && (capabilities & AO_CAP_FLOAT32)) {
    this->channels_out=6;
    mode = AO_CAP_MODE_5_1CHANNEL;
    bits = 32; /* Upmix to Floats */
  } else {
    this->channels_out=2;
  }

  pthread_mutex_lock (&this->lock);
  this->sub = xine_xmalloc(sizeof(af_sub_t));
  if (!this->sub) {
    pthread_mutex_unlock (&this->lock);
    return 0;
  }
  this->sub->fc = this->params.cut_off_freq;    /* LFE Cutoff frequency 100Hz */
  this->sub->k = 1.0;
    if((-1 == szxform(s_param[0].a, s_param[0].b, Q, this->sub->fc,
       (float)rate, &this->sub->k, this->sub->w[0])) ||
       (-1 == szxform(s_param[1].a, s_param[1].b, Q, this->sub->fc,
       (float)rate, &this->sub->k, this->sub->w[1]))) {
    free(this->sub);
    this->sub=NULL;
    pthread_mutex_unlock (&this->lock);
    return 0;
  }

  pthread_mutex_unlock (&this->lock);

  return port->original_port->open(port->original_port, stream, bits, rate, mode );
}

#if 0
static void upmix_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream ) {

  post_audio_port_t  *port = (post_audio_port_t *)port_gen;

  port->stream = NULL;
  port->original_port->close(port->original_port, stream );
  _x_post_dec_usage(port);
}
#endif

static int upmix_frames_2to51_any_to_float( uint8_t *dst8, uint8_t *src8, int num_frames, int step_channel_in, af_sub_t *sub) {
  float *dst=(float *)dst8;
  int16_t *src16=(int16_t *)src8;
  float *src_float=(float *)src8;
  int src_num_channels=2;
  int dst_num_channels=6;
  int src_frame;
  int dst_frame;
  int32_t sample24;
  float sample;
  float left;
  float right;
  float sum;
  int frame;
  int src_units_per_sample=1; 
  if (step_channel_in == 3) src_units_per_sample=step_channel_in; /* Special handling for 24 bit 3byte input */

  for (frame=0;frame < num_frames; frame++) {
    dst_frame=frame*dst_num_channels;
    src_frame=frame*src_num_channels*src_units_per_sample;
    switch (step_channel_in) {
    case 1:
      left = src8[src_frame];
      left = (left - 128 ) / 128; /* FIXME: Need to verify this is correct */
      right = src8[src_frame+1];
      right = (right - 128) / 128;
      break;
    case 2:
      left = (1.0/SHRT_MAX)*((float)src16[src_frame]);
      right = (1.0/SHRT_MAX)*((float)src16[src_frame+1]);
      break;
    case 3:
#ifdef WORDS_BIGENDIAN
      sample24 = (src8[src_frame] << 24) | (src8[src_frame+1] << 16) | ( src8[src_frame+2] << 8);
#else
      sample24 = (src8[src_frame] << 8) | (src8[src_frame+1] << 16) | ( src8[src_frame+2] << 24);
#endif
      left = (1.0/INT32_MAX)*((float)sample24);
#ifdef WORDS_BIGENDIAN
      sample24 = (src8[src_frame+3] << 24) | (src8[src_frame+4] << 16) | ( src8[src_frame+5] << 8);
#else
      sample24 = (src8[src_frame+3] << 8) | (src8[src_frame+4] << 16) | ( src8[src_frame+5] << 24);
#endif
      right = (1.0/INT32_MAX)*((float)sample24);
      break;
    case 4:
      left = src_float[src_frame];
      right = src_float[src_frame+1];
      break;
    default:
      left = right = 0.0;
    }
    /* Left channel */
    dst[dst_frame] = left;
    /* Right channel */
    dst[dst_frame+1] = right;
    /* try a bit of dolby */
    /* FIXME: Dobly surround is a bit more complicated than this, but this is a start. */
    /* Rear Left channel */
    dst[dst_frame+2] = (left - right) / 2;
    /* Rear Right channel */
    dst[dst_frame+3] = (left - right) / 2;
    sum = (left + right) / 2;
    /* Center channel */
    /* Mute this one because it just causes the Left/Right channel spacing to get moved to the center. */
    /* dst[dst_frame+4] = sum; */
    dst[dst_frame+4] = 0;
    /* Create the LFE channel using a low pass filter */
    /* filter feature ported from mplayer */
    sample = sum;
    IIR(sample * sub->k, sub->w[0], sub->q[0], sample);
    IIR(sample , sub->w[1], sub->q[1], sample);
    /* LFE or Sub woofer channel */
    dst[dst_frame+5] = sample;

  }
  return frame;
}

static void upmix_port_put_buffer (xine_audio_port_t *port_gen, 
                             audio_buffer_t *buf, xine_stream_t *stream) {
  
  post_audio_port_t  *port = (post_audio_port_t *)port_gen;
  post_plugin_upmix_t *this = (post_plugin_upmix_t *)port->post;
  int src_step_frame;
  int dst_step_frame;
  int step_channel_in;
  int step_channel_out;
  uint8_t *data8src;
  uint8_t *data8dst;
  int num_bytes;
  int num_frames;
  int num_frames_done;
  int num_frames_processed=0;

  if ((this->channels==2) && (this->channels_out==6)) {
    while (num_frames_processed < buf->num_frames) {
      this->buf = port->original_port->get_buffer(port->original_port); 
      /* this->buf->num_frames is handled after the upmix */
      this->buf->vpts = buf->vpts;
      if (num_frames_processed != 0) this->buf->vpts = 0;
      this->buf->frame_header_count = buf->frame_header_count;
      this->buf->first_access_unit = buf->first_access_unit;
      /* FIXME: The audio buffer should contain this info.
       *        We should not have to get it from the open call.
       */
      this->buf->format.bits = 32; /* Upmix to floats */
      this->buf->format.rate = port->rate;
      this->buf->format.mode = AO_CAP_MODE_5_1CHANNEL;
      _x_extra_info_merge( this->buf->extra_info, buf->extra_info); 
      step_channel_in = port->bits>>3;
      step_channel_out = this->buf->format.bits>>3;
      dst_step_frame = this->channels_out*step_channel_out;
      src_step_frame = this->channels*step_channel_in;
      num_bytes=(buf->num_frames-num_frames_processed)*dst_step_frame;
      if (num_bytes > this->buf->mem_size) {
        num_bytes = this->buf->mem_size;
      }
      num_frames = num_bytes/dst_step_frame;
      data8src=(int8_t*)buf->mem;
      data8src+=num_frames_processed*src_step_frame;
      data8dst=(int8_t*)this->buf->mem;
      pthread_mutex_lock (&this->lock);
      if ((this->sub) && (this->sub->fc != this->params.cut_off_freq)) {
        this->sub->fc = this->params.cut_off_freq;    /* LFE Cutoff frequency 100Hz */
        this->sub->k = 1.0;
        if((-1 == szxform(s_param[0].a, s_param[0].b, Q, this->sub->fc,
            (float)port->rate, &this->sub->k, this->sub->w[0])) ||
            (-1 == szxform(s_param[1].a, s_param[1].b, Q, this->sub->fc,
            (float)port->rate, &this->sub->k, this->sub->w[1]))) {
          /* Complain fairly loudly! */
          printf("Low pass filter init failed!\n");
        }
      }
      pthread_mutex_unlock (&this->lock);
  
      num_frames_done = upmix_frames_2to51_any_to_float(data8dst, data8src, num_frames, step_channel_in, this->sub);
      this->buf->num_frames = num_frames_done;
      num_frames_processed+= num_frames_done;
      /* pass data to original port */
      port->original_port->put_buffer(port->original_port, this->buf, stream );  
    }
    /* free data from origial buffer */
    buf->num_frames=0; /* UNDOCUMENTED, but hey, it works! Force old audio_out buffer free. */
  }
  port->original_port->put_buffer(port->original_port, buf, stream );  
  
  return;
}

static void upmix_dispose(post_plugin_t *this_gen)
{
  post_plugin_upmix_t *this = (post_plugin_upmix_t *)this_gen;

  if (_x_post_dispose(this_gen)) {
    if (this->sub) free(this->sub);
    free(this);
  }
}

/* plugin class functions */
static post_plugin_t *upmix_open_plugin(post_class_t *class_gen, int inputs,
					 xine_audio_port_t **audio_target,
					 xine_video_port_t **video_target)
{
  post_plugin_upmix_t *this  = (post_plugin_upmix_t *)xine_xmalloc(sizeof(post_plugin_upmix_t));
  post_in_t            *input;
  post_out_t           *output;
  xine_post_in_t       *input_api;
  post_audio_port_t    *port;
  
  if (!this || !audio_target || !audio_target[0] ) {
    free(this);
    return NULL;
  }
  
  _x_post_init(&this->post, 1, 0);

  this->params.cut_off_freq = 100;
  
  port = _x_post_intercept_audio_port(&this->post, audio_target[0], &input, &output);
  port->new_port.open       = upmix_port_open;
#if 0
  port->new_port.close      = upmix_port_close;
#endif
  port->new_port.put_buffer = upmix_port_put_buffer;

  input_api       = &this->params_input;
  input_api->name = "parameters";
  input_api->type = XINE_POST_DATA_PARAMETERS;
  input_api->data = &post_api;
  xine_list_append_content(this->post.input, input_api);

  this->post.xine_post.audio_input[0] = &port->new_port;

  this->post.dispose = upmix_dispose;

  return &this->post;
}

static char *upmix_get_identifier(post_class_t *class_gen)
{
  return "upmix";
}

static char *upmix_get_description(post_class_t *class_gen)
{
  return "upmix";
}

static void upmix_class_dispose(post_class_t *class_gen)
{
  free(class_gen);
}

/* plugin class initialization function */
void *upmix_init_plugin(xine_t *xine, void *data)
{
  post_class_upmix_t *class = (post_class_upmix_t *)malloc(sizeof(post_class_upmix_t));
  
  if (!class)
    return NULL;
  
  class->post_class.open_plugin     = upmix_open_plugin;
  class->post_class.get_identifier  = upmix_get_identifier;
  class->post_class.get_description = upmix_get_description;
  class->post_class.dispose         = upmix_class_dispose;
  
  class->xine                       = xine;
  
  return class;
}

--- NEW FILE: filter.c ---
/*=============================================================================
 *	
 *  This software has been released under the terms of the GNU Public
 *  license. See http://www.gnu.org/copyleft/gpl.html for details.
 *
 *  Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au
 *
 *=============================================================================
 */

/* Design and implementation of different types of digital filters */

#include <string.h>
#include <math.h>
#include "dsp.h"

/******************************************************************************
 *  FIR filter implementations
 ******************************************************************************/

/* C implementation of FIR filter y=w*x
 *
 * n number of filter taps, where mod(n,4)==0
 * w filter taps
 * x input signal must be a circular buffer which is indexed backwards 
 */
inline _ftype_t fir(register unsigned int n, _ftype_t* w, _ftype_t* x)
{
  register _ftype_t y; /* Output */
  y = 0.0; 
  do{
    n--;
    y+=w[n]*x[n];
  }while(n != 0);
  return y;
}

/* C implementation of parallel FIR filter y(k)=w(k) * x(k) (where * denotes convolution)
 *
 * n  number of filter taps, where mod(n,4)==0
 * d  number of filters
 * xi current index in xq
 * w  filter taps k by n big
 * x  input signal must be a circular buffers which are indexed backwards 
 * y  output buffer
 * s  output buffer stride
 */
inline _ftype_t* pfir(unsigned int n, unsigned int d, unsigned int xi, _ftype_t** w, _ftype_t** x, _ftype_t* y, unsigned int s)
{
  register _ftype_t* xt = *x + xi;
  register _ftype_t* wt = *w;
  register int    nt = 2*n;
  while(d-- > 0){
    *y = fir(n,wt,xt);
    wt+=n;
    xt+=nt;
    y+=s;
  }
  return y;
}

/* Add new data to circular queue designed to be used with a parallel
   FIR filter, with d filters. xq is the circular queue, in pointing
   at the new samples, xi current index in xq and n the length of the
   filter. xq must be n*2 by k big, s is the index for in.
*/
inline int updatepq(unsigned int n, unsigned int d, unsigned int xi, _ftype_t** xq, _ftype_t* in, unsigned int s)  
{
  register _ftype_t* txq = *xq + xi;
  register int nt = n*2;
  
  while(d-- >0){
    *txq= *(txq+n) = *in;
    txq+=nt;
    in+=s;
  }
  return (++xi)&(n-1);
}

/******************************************************************************
*  FIR filter design
******************************************************************************/

/* Design FIR filter using the Window method

   n     filter length must be odd for HP and BS filters
   w     buffer for the filter taps (must be n long)
   fc    cutoff frequencies (1 for LP and HP, 2 for BP and BS) 
         0 < fc < 1 where 1 <=> Fs/2
   flags window and filter type as defined in filter.h
         variables are ored together: i.e. LP|HAMMING will give a 
	 low pass filter designed using a hamming window  
   opt   beta constant used only when designing using kaiser windows
   
   returns 0 if OK, -1 if fail
*/
int design_fir(unsigned int n, _ftype_t* w, _ftype_t* fc, unsigned int flags, _ftype_t opt)
{
  unsigned int	o   = n & 1;          	/* Indicator for odd filter length */
  unsigned int	end = ((n + 1) >> 1) - o;  /* Loop end */
  unsigned int	i;			/* Loop index */

  _ftype_t k1 = 2 * M_PI;		/* 2*pi*fc1 */
  _ftype_t k2 = 0.5 * (_ftype_t)(1 - o);/* Constant used if the filter has even length */
  _ftype_t k3;				/* 2*pi*fc2 Constant used in BP and BS design */
  _ftype_t g  = 0.0;     		/* Gain */
  _ftype_t t1,t2,t3;     		/* Temporary variables */
  _ftype_t fc1,fc2;			/* Cutoff frequencies */

  /* Sanity check */
  if(!w || (n == 0)) return -1;

  /* Get window coefficients */
  switch(flags & WINDOW_MASK){
  case(BOXCAR):
    boxcar(n,w); break;
  case(TRIANG):
    triang(n,w); break;
  case(HAMMING):
    hamming(n,w); break;
  case(HANNING):
    hanning(n,w); break;
  case(BLACKMAN):
    blackman(n,w); break;
  case(FLATTOP):
    flattop(n,w); break;
  case(KAISER):
    kaiser(n,w,opt); break;
  default:
    return -1;	
  }

  if(flags & (LP | HP)){ 
    fc1=*fc;
    /* Cutoff frequency must be < 0.5 where 0.5 <=> Fs/2 */
    fc1 = ((fc1 <= 1.0) && (fc1 > 0.0)) ? fc1/2 : 0.25;
    k1 *= fc1;

    if(flags & LP){ /* Low pass filter */

      /*
       * If the filter length is odd, there is one point which is exactly
       * in the middle. The value at this point is 2*fCutoff*sin(x)/x, 
       * where x is zero. To make sure nothing strange happens, we set this
       * value separately.
       */
      if (o){
	w[end] = fc1 * w[end] * 2.0;
	g=w[end];
      }

      /* Create filter */
      for (i=0 ; i<end ; i++){
	t1 = (_ftype_t)(i+1) - k2;
	w[end-i-1] = w[n-end+i] = w[end-i-1] * sin(k1 * t1)/(M_PI * t1); /* Sinc */
	g += 2*w[end-i-1]; /* Total gain in filter */
      }
    }
    else{ /* High pass filter */
      if (!o) /* High pass filters must have odd length */
	return -1;
      w[end] = 1.0 - (fc1 * w[end] * 2.0);
      g= w[end];

      /* Create filter */
      for (i=0 ; i<end ; i++){
	t1 = (_ftype_t)(i+1);
	w[end-i-1] = w[n-end+i] = -1 * w[end-i-1] * sin(k1 * t1)/(M_PI * t1); /* Sinc */
	g += ((i&1) ? (2*w[end-i-1]) : (-2*w[end-i-1])); /* Total gain in filter */
      }
    }
  }

  if(flags & (BP | BS)){
    fc1=fc[0];
    fc2=fc[1];
    /* Cutoff frequencies must be < 1.0 where 1.0 <=> Fs/2 */
    fc1 = ((fc1 <= 1.0) && (fc1 > 0.0)) ? fc1/2 : 0.25;
    fc2 = ((fc2 <= 1.0) && (fc2 > 0.0)) ? fc2/2 : 0.25;
    k3  = k1 * fc2; /* 2*pi*fc2 */
    k1 *= fc1;      /* 2*pi*fc1 */

    if(flags & BP){ /* Band pass */
      /* Calculate center tap */
      if (o){
	g=w[end]*(fc1+fc2);
	w[end] = (fc2 - fc1) * w[end] * 2.0;
      }

      /* Create filter */
      for (i=0 ; i<end ; i++){
	t1 = (_ftype_t)(i+1) - k2;
	t2 = sin(k3 * t1)/(M_PI * t1); /* Sinc fc2 */
	t3 = sin(k1 * t1)/(M_PI * t1); /* Sinc fc1 */
	g += w[end-i-1] * (t3 + t2);   /* Total gain in filter */
	w[end-i-1] = w[n-end+i] = w[end-i-1] * (t2 - t3); 
      }
    }      
    else{ /* Band stop */
      if (!o) /* Band stop filters must have odd length */
	return -1;
      w[end] = 1.0 - (fc2 - fc1) * w[end] * 2.0;
      g= w[end];

      /* Create filter */
      for (i=0 ; i<end ; i++){
	t1 = (_ftype_t)(i+1);
	t2 = sin(k1 * t1)/(M_PI * t1); /* Sinc fc1 */
	t3 = sin(k3 * t1)/(M_PI * t1); /* Sinc fc2 */
	w[end-i-1] = w[n-end+i] = w[end-i-1] * (t2 - t3); 
	g += 2*w[end-i-1]; /* Total gain in filter */
      }
    }
  }

  /* Normalize gain */
  g=1/g;
  for (i=0; i<n; i++) 
    w[i] *= g;
  
  return 0;
}

/* Design polyphase FIR filter from prototype filter
 *
 * n     length of prototype filter
 * k     number of polyphase components
 * w     prototype filter taps
 * pw    Parallel FIR filter 
 * g     Filter gain
 * flags FWD forward indexing
 *       REW reverse indexing
 *       ODD multiply every 2nd filter tap by -1 => HP filter
 *
 * returns 0 if OK, -1 if fail
 */
int design_pfir(unsigned int n, unsigned int k, _ftype_t* w, _ftype_t** pw, _ftype_t g, unsigned int flags)
{
  int l = (int)n/k;	/* Length of individual FIR filters */
  int i;     	/* Counters */
  int j;
  _ftype_t t;	/* g * w[i] */
  
  /* Sanity check */
  if(l<1 || k<1 || !w || !pw)
    return -1;

  /* Do the stuff */
  if(flags&REW){
    for(j=l-1;j>-1;j--){ /* Columns */
      for(i=0;i<(int)k;i++){ /* Rows */
	t=g *  *w++;
	pw[i][j]=t * ((flags & ODD) ? ((j & 1) ? -1 : 1) : 1);
      }
    }
  }
  else{
    for(j=0;j<l;j++){ /* Columns */
      for(i=0;i<(int)k;i++){ /* Rows */
	t=g *  *w++;
	pw[i][j]=t * ((flags & ODD) ? ((j & 1) ? 1 : -1) : 1);
      }
    }
  }
  return -1;
}

/******************************************************************************
*  IIR filter design
******************************************************************************/

/* Helper functions for the bilinear transform */

/* Pre-warp the coefficients of a numerator or denominator.
 * Note that a0 is assumed to be 1, so there is no wrapping
 * of it.  
 */
void prewarp(_ftype_t* a, _ftype_t fc, _ftype_t fs)
{
  _ftype_t wp;
  wp = 2.0 * fs * tan(M_PI * fc / fs);
  a[2] = a[2]/(wp * wp);
  a[1] = a[1]/wp;
}

/* Transform the numerator and denominator coefficients of s-domain
 * biquad section into corresponding z-domain coefficients.
 *
 * The transfer function for z-domain is:
 *
 *        1 + alpha1 * z^(-1) + alpha2 * z^(-2)
 * H(z) = -------------------------------------
 *        1 + beta1 * z^(-1) + beta2 * z^(-2)
 *
 * Store the 4 IIR coefficients in array pointed by coef in following
 * order:
 * beta1, beta2    (denominator)
 * alpha1, alpha2  (numerator)
 *
 *  Arguments:
 * a       - s-domain numerator coefficients
 * b       - s-domain denominator coefficients
 * k 	   - filter gain factor. Initially set to 1 and modified by each
 *           biquad section in such a way, as to make it the
 *           coefficient by which to multiply the overall filter gain
 *           in order to achieve a desired overall filter gain,
 *           specified in initial value of k.  
 * fs 	   - sampling rate (Hz)
 * coef    - array of z-domain coefficients to be filled in.
 *
 * Return: On return, set coef z-domain coefficients and k to the gain
 * required to maintain overall gain = 1.0;
 */
void bilinear(_ftype_t* a, _ftype_t* b, _ftype_t* k, _ftype_t fs, _ftype_t *coef)
{
  _ftype_t ad, bd;

  /* alpha (Numerator in s-domain) */
  ad = 4. * a[2] * fs * fs + 2. * a[1] * fs + a[0];
  /* beta (Denominator in s-domain) */
  bd = 4. * b[2] * fs * fs + 2. * b[1] * fs + b[0];

  /* Update gain constant for this section */
  *k *= ad/bd;

  /* Denominator */
  *coef++ = (2. * b[0] - 8. * b[2] * fs * fs)/bd; /* beta1 */
  *coef++ = (4. * b[2] * fs * fs - 2. * b[1] * fs + b[0])/bd; /* beta2 */

  /* Numerator */
  *coef++ = (2. * a[0] - 8. * a[2] * fs * fs)/ad; /* alpha1 */
  *coef   = (4. * a[2] * fs * fs - 2. * a[1] * fs + a[0])/ad;   /* alpha2 */
}



/* IIR filter design using bilinear transform and prewarp. Transforms
 * 2nd order s domain analog filter into a digital IIR biquad link. To
 * create a filter fill in a, b, Q and fs and make space for coef and k.
 *
 *
 * Example Butterworth design: 
 *
 * Below are Butterworth polynomials, arranged as a series of 2nd
 * order sections:
 *
 * Note: n is filter order.
 *
 * n  Polynomials
 * -------------------------------------------------------------------
 * 2  s^2 + 1.4142s + 1
 * 4  (s^2 + 0.765367s + 1) * (s^2 + 1.847759s + 1)
 * 6  (s^2 + 0.5176387s + 1) * (s^2 + 1.414214 + 1) * (s^2 + 1.931852s + 1)
 *
 * For n=4 we have following equation for the filter transfer function:
 *                     1                              1
 * T(s) = --------------------------- * ----------------------------
 *        s^2 + (1/Q) * 0.765367s + 1   s^2 + (1/Q) * 1.847759s + 1
 *
 * The filter consists of two 2nd order sections since highest s power
 * is 2.  Now we can take the coefficients, or the numbers by which s
 * is multiplied and plug them into a standard formula to be used by
 * bilinear transform.
 *
 * Our standard form for each 2nd order section is:
 *
 *        a2 * s^2 + a1 * s + a0
 * H(s) = ----------------------
 *        b2 * s^2 + b1 * s + b0
 *
 * Note that Butterworth numerator is 1 for all filter sections, which
 * means s^2 = 0 and s^1 = 0
 *
 * Let's convert standard Butterworth polynomials into this form:
 *
 *           0 + 0 + 1                  0 + 0 + 1
 * --------------------------- * --------------------------
 * 1 + ((1/Q) * 0.765367) + 1   1 + ((1/Q) * 1.847759) + 1
 *
 * Section 1:
 * a2 = 0; a1 = 0; a0 = 1;
 * b2 = 1; b1 = 0.765367; b0 = 1;
 *
 * Section 2:
 * a2 = 0; a1 = 0; a0 = 1;
 * b2 = 1; b1 = 1.847759; b0 = 1;
 *
 * Q is filter quality factor or resonance, in the range of 1 to
 * 1000. The overall filter Q is a product of all 2nd order stages.
 * For example, the 6th order filter (3 stages, or biquads) with
 * individual Q of 2 will have filter Q = 2 * 2 * 2 = 8.
 *
 *
 * Arguments:
 * a       - s-domain numerator coefficients, a[1] is always assumed to be 1.0
 * b       - s-domain denominator coefficients
 * Q	   - Q value for the filter
 * k 	   - filter gain factor. Initially set to 1 and modified by each
 *           biquad section in such a way, as to make it the
 *           coefficient by which to multiply the overall filter gain
 *           in order to achieve a desired overall filter gain,
 *           specified in initial value of k.  
 * fs 	   - sampling rate (Hz)
 * coef    - array of z-domain coefficients to be filled in.
 *
 * Note: Upon return from each call, the k argument will be set to a
 * value, by which to multiply our actual signal in order for the gain
 * to be one. On second call to szxform() we provide k that was
 * changed by the previous section. During actual audio filtering
 * k can be used for gain compensation.
 *
 * return -1 if fail 0 if success.
 */
int szxform(_ftype_t* a, _ftype_t* b, _ftype_t Q, _ftype_t fc, _ftype_t fs, _ftype_t *k, _ftype_t *coef)
{
  _ftype_t at[3];
  _ftype_t bt[3];

  if(!a || !b || !k || !coef || (Q>1000.0 || Q< 1.0)) 
    return -1;

  memcpy(at,a,3*sizeof(_ftype_t));
  memcpy(bt,b,3*sizeof(_ftype_t));

  bt[1]/=Q;

  /* Calculate a and b and overwrite the original values */
  prewarp(at, fc, fs);
  prewarp(bt, fc, fs);
  /* Execute bilinear transform */
  bilinear(at, bt, k, fs, coef);

  return 0;
}


--- NEW FILE: Makefile.in ---
# Makefile.in generated by automake 1.9.3 from Makefile.am.
# @configure_input@

# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004  Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

@SET_MAKE@


SOURCES = $(xineplug_post_audio_filters_la_SOURCES)

srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
	$(srcdir)/Makefile.in $(top_srcdir)/misc/Makefile.common
subdir = src/post/audio
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/_xine.m4 $(top_srcdir)/m4/aa.m4 \
	$(top_srcdir)/m4/alsa.m4 $(top_srcdir)/m4/arts.m4 \
	$(top_srcdir)/m4/as.m4 $(top_srcdir)/m4/caca.m4 \
	$(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/directx.m4 \
	$(top_srcdir)/m4/dl.m4 $(top_srcdir)/m4/dvdnav.m4 \
	$(top_srcdir)/m4/esd.m4 $(top_srcdir)/m4/ffmpeg.m4 \
	$(top_srcdir)/m4/freetype2.m4 $(top_srcdir)/m4/gettext.m4 \
	$(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/iconv.m4 \
	$(top_srcdir)/m4/irixal.m4 $(top_srcdir)/m4/lcmessage.m4 \
	$(top_srcdir)/m4/libFLAC.m4 $(top_srcdir)/m4/libfame.m4 \
	$(top_srcdir)/m4/ogg.m4 $(top_srcdir)/m4/opengl.m4 \
	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/progtest.m4 \
	$(top_srcdir)/m4/sdl.m4 $(top_srcdir)/m4/speex.m4 \
	$(top_srcdir)/m4/theora.m4 $(top_srcdir)/m4/vorbis.m4 \
	$(top_srcdir)/m4/xv.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
    *) f=$$p;; \
  esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libdir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 = $(top_builddir)/src/xine-engine/libxine.la
xineplug_post_audio_filters_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_xineplug_post_audio_filters_la_OBJECTS = upmix.lo filter.lo \
	window.lo stretch.lo audio_filters.lo
xineplug_post_audio_filters_la_OBJECTS =  \
	$(am_xineplug_post_audio_filters_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
	$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
	$(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(xineplug_post_audio_filters_la_SOURCES)
DIST_SOURCES = $(xineplug_post_audio_filters_la_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
AAINFO = @AAINFO@
AALIB_CFLAGS = @AALIB_CFLAGS@
AALIB_CONFIG = @AALIB_CONFIG@
AALIB_LIBS = @AALIB_LIBS@
ACLOCAL = @ACLOCAL@
ACLOCAL_DIR = @ACLOCAL_DIR@
ALLOCA = @ALLOCA@
ALSA_CFLAGS = @ALSA_CFLAGS@
ALSA_LIBS = @ALSA_LIBS@
ALSA_STATIC_LIB = @ALSA_STATIC_LIB@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
ARTS_CFLAGS = @ARTS_CFLAGS@
ARTS_CONFIG = @ARTS_CONFIG@
ARTS_LIBS = @ARTS_LIBS@
AS = @AS@
ASFLAGS = @ASFLAGS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_ASF_FALSE = @BUILD_ASF_FALSE@
BUILD_ASF_TRUE = @BUILD_ASF_TRUE@
BUILD_DHA_KMOD_FALSE = @BUILD_DHA_KMOD_FALSE@
BUILD_DHA_KMOD_TRUE = @BUILD_DHA_KMOD_TRUE@
BUILD_FAAD_FALSE = @BUILD_FAAD_FALSE@
BUILD_FAAD_TRUE = @BUILD_FAAD_TRUE@
BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
CACA_CFLAGS = @CACA_CFLAGS@
CACA_CONFIG = @CACA_CONFIG@
CACA_LIBS = @CACA_LIBS@
CATALOGS = @CATALOGS@
CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCAS = @CCAS@
CCASCOMPILE = @CCASCOMPILE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DATADIRNAME = @DATADIRNAME@
DEBUG_CFLAGS = @DEBUG_CFLAGS@
DEFS = @DEFS@
DEPCOMP = @DEPCOMP@
DEPDIR = @DEPDIR@
DEPMOD = @DEPMOD@
DIRECTFB_CFLAGS = @DIRECTFB_CFLAGS@
DIRECTFB_LIBS = @DIRECTFB_LIBS@
DIRECTX_AUDIO_LIBS = @DIRECTX_AUDIO_LIBS@
DIRECTX_CPPFLAGS = @DIRECTX_CPPFLAGS@
DIRECTX_VIDEO_LIBS = @DIRECTX_VIDEO_LIBS@
DLLTOOL = @DLLTOOL@
DVDNAV_CFLAGS = @DVDNAV_CFLAGS@
DVDNAV_CONFIG = @DVDNAV_CONFIG@
DVDNAV_LIBS = @DVDNAV_LIBS@
DYNAMIC_LD_LIBS = @DYNAMIC_LD_LIBS@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_VCD_FALSE = @ENABLE_VCD_FALSE@
ENABLE_VCD_TRUE = @ENABLE_VCD_TRUE@
ESD_CFLAGS = @ESD_CFLAGS@
ESD_CONFIG = @ESD_CONFIG@
ESD_LIBS = @ESD_LIBS@
EXEEXT = @EXEEXT@
EXTRA_X_CFLAGS = @EXTRA_X_CFLAGS@
EXTRA_X_LIBS = @EXTRA_X_LIBS@
F77 = @F77@
FFLAGS = @FFLAGS@
FFMPEG_CPPFLAGS = @FFMPEG_CPPFLAGS@
FFMPEG_LIBS = @FFMPEG_LIBS@
FIG2DEV = @FIG2DEV@
FREETYPE_CONFIG = @FREETYPE_CONFIG@
FT2_CFLAGS = @FT2_CFLAGS@
FT2_LIBS = @FT2_LIBS@
GENCAT = @GENCAT@
GLIBC21 = @GLIBC21@
GLUT_LIBS = @GLUT_LIBS@
GLU_LIBS = @GLU_LIBS@
GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
GNOME_VFS_CFLAGS = @GNOME_VFS_CFLAGS@
GNOME_VFS_LIBS = @GNOME_VFS_LIBS@
GOOM_LIBS = @GOOM_LIBS@
HAVE_AA_FALSE = @HAVE_AA_FALSE@
HAVE_AA_TRUE = @HAVE_AA_TRUE@
HAVE_ALSA09_FALSE = @HAVE_ALSA09_FALSE@
HAVE_ALSA09_TRUE = @HAVE_ALSA09_TRUE@
HAVE_ALSA_FALSE = @HAVE_ALSA_FALSE@
HAVE_ALSA_TRUE = @HAVE_ALSA_TRUE@
HAVE_ARMV4L_FALSE = @HAVE_ARMV4L_FALSE@
HAVE_ARMV4L_TRUE = @HAVE_ARMV4L_TRUE@
HAVE_ARTS_FALSE = @HAVE_ARTS_FALSE@
HAVE_ARTS_TRUE = @HAVE_ARTS_TRUE@
HAVE_BSDI_CDROM = @HAVE_BSDI_CDROM@
HAVE_CACA_FALSE = @HAVE_CACA_FALSE@
HAVE_CACA_TRUE = @HAVE_CACA_TRUE@
HAVE_CDROM_IOCTLS_FALSE = @HAVE_CDROM_IOCTLS_FALSE@
HAVE_CDROM_IOCTLS_TRUE = @HAVE_CDROM_IOCTLS_TRUE@
HAVE_COREAUDIO_FALSE = @HAVE_COREAUDIO_FALSE@
HAVE_COREAUDIO_TRUE = @HAVE_COREAUDIO_TRUE@
HAVE_DARWIN_CDROM = @HAVE_DARWIN_CDROM@
HAVE_DIRECTFB_FALSE = @HAVE_DIRECTFB_FALSE@
HAVE_DIRECTFB_TRUE = @HAVE_DIRECTFB_TRUE@
HAVE_DIRECTX_FALSE = @HAVE_DIRECTX_FALSE@
HAVE_DIRECTX_TRUE = @HAVE_DIRECTX_TRUE@
HAVE_DVDNAV_FALSE = @HAVE_DVDNAV_FALSE@
HAVE_DVDNAV_TRUE = @HAVE_DVDNAV_TRUE@
HAVE_DXR3_FALSE = @HAVE_DXR3_FALSE@
HAVE_DXR3_TRUE = @HAVE_DXR3_TRUE@
HAVE_ESD_FALSE = @HAVE_ESD_FALSE@
HAVE_ESD_TRUE = @HAVE_ESD_TRUE@
HAVE_FB_FALSE = @HAVE_FB_FALSE@
HAVE_FB_TRUE = @HAVE_FB_TRUE@
HAVE_FFMMX_FALSE = @HAVE_FFMMX_FALSE@
HAVE_FFMMX_TRUE = @HAVE_FFMMX_TRUE@
HAVE_FFMPEG_FALSE = @HAVE_FFMPEG_FALSE@
HAVE_FFMPEG_TRUE = @HAVE_FFMPEG_TRUE@
HAVE_FIG2DEV_FALSE = @HAVE_FIG2DEV_FALSE@
HAVE_FIG2DEV_TRUE = @HAVE_FIG2DEV_TRUE@
HAVE_FLAC_FALSE = @HAVE_FLAC_FALSE@
HAVE_FLAC_TRUE = @HAVE_FLAC_TRUE@
HAVE_FREEBSD_CDROM = @HAVE_FREEBSD_CDROM@
HAVE_GNOME_VFS_FALSE = @HAVE_GNOME_VFS_FALSE@
HAVE_GNOME_VFS_TRUE = @HAVE_GNOME_VFS_TRUE@
HAVE_IRIXAL_FALSE = @HAVE_IRIXAL_FALSE@
HAVE_IRIXAL_TRUE = @HAVE_IRIXAL_TRUE@
HAVE_LIBFAME_FALSE = @HAVE_LIBFAME_FALSE@
HAVE_LIBFAME_TRUE = @HAVE_LIBFAME_TRUE@
HAVE_LIBMNG_FALSE = @HAVE_LIBMNG_FALSE@
HAVE_LIBMNG_TRUE = @HAVE_LIBMNG_TRUE@
HAVE_LIBPNG_FALSE = @HAVE_LIBPNG_FALSE@
HAVE_LIBPNG_TRUE = @HAVE_LIBPNG_TRUE@
HAVE_LIBRTE_FALSE = @HAVE_LIBRTE_FALSE@
HAVE_LIBRTE_TRUE = @HAVE_LIBRTE_TRUE@
HAVE_LIBSMBCLIENT_FALSE = @HAVE_LIBSMBCLIENT_FALSE@
HAVE_LIBSMBCLIENT_TRUE = @HAVE_LIBSMBCLIENT_TRUE@
HAVE_LINUX_CDROM = @HAVE_LINUX_CDROM@
HAVE_LINUX_FALSE = @HAVE_LINUX_FALSE@
HAVE_LINUX_TRUE = @HAVE_LINUX_TRUE@
HAVE_MACOSX_VIDEO_FALSE = @HAVE_MACOSX_VIDEO_FALSE@
HAVE_MACOSX_VIDEO_TRUE = @HAVE_MACOSX_VIDEO_TRUE@
HAVE_MLIB_FALSE = @HAVE_MLIB_FALSE@
HAVE_MLIB_TRUE = @HAVE_MLIB_TRUE@
HAVE_OPENGL_FALSE = @HAVE_OPENGL_FALSE@
HAVE_OPENGL_TRUE = @HAVE_OPENGL_TRUE@
HAVE_OSS_FALSE = @HAVE_OSS_FALSE@
HAVE_OSS_TRUE = @HAVE_OSS_TRUE@
HAVE_POLYPAUDIO_FALSE = @HAVE_POLYPAUDIO_FALSE@
HAVE_POLYPAUDIO_TRUE = @HAVE_POLYPAUDIO_TRUE@
HAVE_SDL_FALSE = @HAVE_SDL_FALSE@
HAVE_SDL_TRUE = @HAVE_SDL_TRUE@
HAVE_SGMLTOOLS_FALSE = @HAVE_SGMLTOOLS_FALSE@
HAVE_SGMLTOOLS_TRUE = @HAVE_SGMLTOOLS_TRUE@
HAVE_SOLARIS_CDROM = @HAVE_SOLARIS_CDROM@
HAVE_SPEEX_FALSE = @HAVE_SPEEX_FALSE@
HAVE_SPEEX_TRUE = @HAVE_SPEEX_TRUE@
HAVE_STK_FALSE = @HAVE_STK_FALSE@
HAVE_STK_TRUE = @HAVE_STK_TRUE@
HAVE_SUNAUDIO_FALSE = @HAVE_SUNAUDIO_FALSE@
HAVE_SUNAUDIO_TRUE = @HAVE_SUNAUDIO_TRUE@
HAVE_SUNDGA_FALSE = @HAVE_SUNDGA_FALSE@
HAVE_SUNDGA_TRUE = @HAVE_SUNDGA_TRUE@
HAVE_SUNFB_FALSE = @HAVE_SUNFB_FALSE@
HAVE_SUNFB_TRUE = @HAVE_SUNFB_TRUE@
HAVE_SYNCFB_FALSE = @HAVE_SYNCFB_FALSE@
HAVE_SYNCFB_TRUE = @HAVE_SYNCFB_TRUE@
HAVE_THEORA_FALSE = @HAVE_THEORA_FALSE@
HAVE_THEORA_TRUE = @HAVE_THEORA_TRUE@
HAVE_V4L_FALSE = @HAVE_V4L_FALSE@
HAVE_V4L_TRUE = @HAVE_V4L_TRUE@
HAVE_VCDNAV_FALSE = @HAVE_VCDNAV_FALSE@
HAVE_VCDNAV_TRUE = @HAVE_VCDNAV_TRUE@
HAVE_VIDIX_FALSE = @HAVE_VIDIX_FALSE@
HAVE_VIDIX_TRUE = @HAVE_VIDIX_TRUE@
HAVE_VLDXVMC_FALSE = @HAVE_VLDXVMC_FALSE@
HAVE_VLDXVMC_TRUE = @HAVE_VLDXVMC_TRUE@
HAVE_VORBIS_FALSE = @HAVE_VORBIS_FALSE@
HAVE_VORBIS_TRUE = @HAVE_VORBIS_TRUE@
HAVE_W32DLL_FALSE = @HAVE_W32DLL_FALSE@
HAVE_W32DLL_TRUE = @HAVE_W32DLL_TRUE@
HAVE_WIN32_CDROM = @HAVE_WIN32_CDROM@
HAVE_X11_FALSE = @HAVE_X11_FALSE@
HAVE_X11_TRUE = @HAVE_X11_TRUE@
HAVE_XVMC_FALSE = @HAVE_XVMC_FALSE@
HAVE_XVMC_TRUE = @HAVE_XVMC_TRUE@
HAVE_XV_FALSE = @HAVE_XV_FALSE@
HAVE_XV_TRUE = @HAVE_XV_TRUE@
HAVE_XXMC_FALSE = @HAVE_XXMC_FALSE@
HAVE_XXMC_TRUE = @HAVE_XXMC_TRUE@
HAVE_ZLIB_FALSE = @HAVE_ZLIB_FALSE@
HAVE_ZLIB_TRUE = @HAVE_ZLIB_TRUE@
HOST_OS_DARWIN_FALSE = @HOST_OS_DARWIN_FALSE@
HOST_OS_DARWIN_TRUE = @HOST_OS_DARWIN_TRUE@
INCLUDED_INTL_FALSE = @INCLUDED_INTL_FALSE@
INCLUDED_INTL_TRUE = @INCLUDED_INTL_TRUE@
INCLUDES = @INCLUDES@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_M4_FALSE = @INSTALL_M4_FALSE@
INSTALL_M4_TRUE = @INSTALL_M4_TRUE@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INSTOBJEXT = @INSTOBJEXT@
INTLBISON = @INTLBISON@
INTLDIR = @INTLDIR@
INTLLIBS = @INTLLIBS@
INTLOBJS = @INTLOBJS@
INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
IRIXAL_CFLAGS = @IRIXAL_CFLAGS@
IRIXAL_LIBS = @IRIXAL_LIBS@
IRIXAL_STATIC_LIB = @IRIXAL_STATIC_LIB@
KSTAT_LIBS = @KSTAT_LIBS@
LDFLAGS = @LDFLAGS@
LIBCDIO_CFLAGS = @LIBCDIO_CFLAGS@
LIBCDIO_LIBS = @LIBCDIO_LIBS@
LIBFAME_CFLAGS = @LIBFAME_CFLAGS@
LIBFAME_CONFIG = @LIBFAME_CONFIG@
LIBFAME_LIBS = @LIBFAME_LIBS@
LIBFFMPEG_CFLAGS = @LIBFFMPEG_CFLAGS@
LIBFLAC_CFLAGS = @LIBFLAC_CFLAGS@
LIBFLAC_LIBS = @LIBFLAC_LIBS@
LIBICONV = @LIBICONV@
LIBISO9660_LIBS = @LIBISO9660_LIBS@
LIBMODPLUG_CFLAGS = @LIBMODPLUG_CFLAGS@
LIBMODPLUG_LIBS = @LIBMODPLUG_LIBS@
LIBMPEG2_CFLAGS = @LIBMPEG2_CFLAGS@
LIBNAME = @LIBNAME@
LIBOBJS = @LIBOBJS@
LIBPNG_CONFIG = @LIBPNG_CONFIG@
LIBS = @LIBS@
LIBSMBCLIENT_LIBS = @LIBSMBCLIENT_LIBS@
LIBSTK_CFLAGS = @LIBSTK_CFLAGS@
LIBSTK_LIBS = @LIBSTK_LIBS@
LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIBVCDINFO_LIBS = @LIBVCDINFO_LIBS@
LIBVCD_CFLAGS = @LIBVCD_CFLAGS@
LIBVCD_LIBS = @LIBVCD_LIBS@
LIBVCD_SYSDEP = @LIBVCD_SYSDEP@
LINUX_CDROM_TIMEOUT = @LINUX_CDROM_TIMEOUT@
LINUX_INCLUDE = @LINUX_INCLUDE@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_AGE = @LT_AGE@
LT_CURRENT = @LT_CURRENT@
LT_REVISION = @LT_REVISION@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
MKNOD = @MKNOD@
MLIB_CFLAGS = @MLIB_CFLAGS@
MLIB_LIBS = @MLIB_LIBS@
MNG_LIBS = @MNG_LIBS@
MSGFMT = @MSGFMT@
NET_LIBS = @NET_LIBS@
OBJC = @OBJC@
OBJCDEPMODE = @OBJCDEPMODE@
OBJCFLAGS = @OBJCFLAGS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OGG_CFLAGS = @OGG_CFLAGS@
OGG_LIBS = @OGG_LIBS@
OPENGL_CFLAGS = @OPENGL_CFLAGS@
OPENGL_LIBS = @OPENGL_LIBS@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PASS1_CFLAGS = @PASS1_CFLAGS@
PASS2_CFLAGS = @PASS2_CFLAGS@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PNG_CFLAGS = @PNG_CFLAGS@
PNG_LIBS = @PNG_LIBS@
POFILES = @POFILES@
POLYPAUDIO_CFLAGS = @POLYPAUDIO_CFLAGS@
POLYPAUDIO_LIBS = @POLYPAUDIO_LIBS@
POSUB = @POSUB@
PPC_ARCH_FALSE = @PPC_ARCH_FALSE@
PPC_ARCH_TRUE = @PPC_ARCH_TRUE@
RANLIB = @RANLIB@
RT_LIBS = @RT_LIBS@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SGMLTOOLS = @SGMLTOOLS@
SHELL = @SHELL@
SPEC_VERSION = @SPEC_VERSION@
SPEEX_CFLAGS = @SPEEX_CFLAGS@
SPEEX_LIBS = @SPEEX_LIBS@
STATIC = @STATIC@
STRIP = @STRIP@
SUNDGA_CFLAGS = @SUNDGA_CFLAGS@
SUNDGA_LIBS = @SUNDGA_LIBS@
TAR_NAME = @TAR_NAME@
THEORAENC_LIBS = @THEORAENC_LIBS@
THEORAFILE_LIBS = @THEORAFILE_LIBS@
THEORA_CFLAGS = @THEORA_CFLAGS@
THEORA_LIBS = @THEORA_LIBS@
THREAD_CFLAGS = @THREAD_CFLAGS@
THREAD_CFLAGS_CONFIG = @THREAD_CFLAGS_CONFIG@
THREAD_INCLUDES = @THREAD_INCLUDES@
THREAD_LIBS = @THREAD_LIBS@
THREAD_LIBS_CONFIG = @THREAD_LIBS_CONFIG@
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
VORBISENC_LIBS = @VORBISENC_LIBS@
VORBISFILE_LIBS = @VORBISFILE_LIBS@
VORBIS_CFLAGS = @VORBIS_CFLAGS@
VORBIS_LIBS = @VORBIS_LIBS@
W32DLL_DEP = @W32DLL_DEP@
W32_NO_OPTIMIZE = @W32_NO_OPTIMIZE@
WIN32_CPPFLAGS = @WIN32_CPPFLAGS@
WIN32_FALSE = @WIN32_FALSE@
WIN32_TRUE = @WIN32_TRUE@
XGETTEXT = @XGETTEXT@
XINE_ACFLAGS = @XINE_ACFLAGS@
XINE_BIN_AGE = @XINE_BIN_AGE@
XINE_BUILD_CC = @XINE_BUILD_CC@
XINE_BUILD_DATE = @XINE_BUILD_DATE@
XINE_BUILD_OS = @XINE_BUILD_OS@
XINE_CONFIG_PREFIX = @XINE_CONFIG_PREFIX@
XINE_DATADIR = @XINE_DATADIR@
XINE_FONTDIR = @XINE_FONTDIR@
XINE_FONTPATH = @XINE_FONTPATH@
XINE_IFACE_AGE = @XINE_IFACE_AGE@
XINE_LOCALEDIR = @XINE_LOCALEDIR@
XINE_LOCALEPATH = @XINE_LOCALEPATH@
XINE_MAJOR = @XINE_MAJOR@
XINE_MINOR = @XINE_MINOR@
XINE_PLUGINDIR = @XINE_PLUGINDIR@
XINE_PLUGINPATH = @XINE_PLUGINPATH@
XINE_PLUGIN_MIN_SYMS = @XINE_PLUGIN_MIN_SYMS@
XINE_SCRIPTPATH = @XINE_SCRIPTPATH@
XINE_SUB = @XINE_SUB@
XVMC_LIB = @XVMC_LIB@
XV_LIB = @XV_LIB@
XXMC_LIB = @XXMC_LIB@
X_CFLAGS = @X_CFLAGS@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_LIBS = @X_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@
ZLIB_INCLUDES = @ZLIB_INCLUDES@
ZLIB_LIBS = @ZLIB_LIBS@
ZLIB_LIBS_CONFIG = @ZLIB_LIBS_CONFIG@
ac_ct_AR = @ac_ct_AR@
ac_ct_AS = @ac_ct_AS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DLLTOOL = @ac_ct_DLLTOOL@
ac_ct_F77 = @ac_ct_F77@
ac_ct_OBJDUMP = @ac_ct_OBJDUMP@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__fastdepOBJC_FALSE = @am__fastdepOBJC_FALSE@
am__fastdepOBJC_TRUE = @am__fastdepOBJC_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = $(XINE_PLUGINDIR)/post
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
w32_path = @w32_path@
XINE_LIB = $(top_builddir)/src/xine-engine/libxine.la
noinst_HEADERS = dsp.h filter.h window.h audio_filters.h
lib_LTLIBRARIES = xineplug_post_audio_filters.la
xineplug_post_audio_filters_la_SOURCES = \
        upmix.c filter.c window.c stretch.c audio_filters.c

xineplug_post_audio_filters_la_LIBADD = $(XINE_LIB)
xineplug_post_audio_filters_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ -lm
all: all-am

.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am $(top_srcdir)/misc/Makefile.common $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
		&& exit 0; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  src/post/audio/Makefile'; \
	cd $(top_srcdir) && \
	  $(AUTOMAKE) --gnu  src/post/audio/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
	@$(NORMAL_INSTALL)
	test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
	  if test -f $$p; then \
	    f=$(am__strip_dir) \
	    echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
	    $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
	  else :; fi; \
	done

uninstall-libLTLIBRARIES:
	@$(NORMAL_UNINSTALL)
	@set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
	  p=$(am__strip_dir) \
	  echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
	  $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
	done

clean-libLTLIBRARIES:
	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
	  test "$$dir" != "$$p" || dir=.; \
	  echo "rm -f \"$${dir}/so_locations\""; \
	  rm -f "$${dir}/so_locations"; \
	done
xineplug_post_audio_filters.la: $(xineplug_post_audio_filters_la_OBJECTS) $(xineplug_post_audio_filters_la_DEPENDENCIES) 
	$(LINK) -rpath $(libdir) $(xineplug_post_audio_filters_la_LDFLAGS) $(xineplug_post_audio_filters_la_OBJECTS) $(xineplug_post_audio_filters_la_LIBADD) $(LIBS)

mostlyclean-compile:
	-rm -f *.$(OBJEXT)

distclean-compile:
	-rm -f *.tab.c

@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audio_filters.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stretch.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upmix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/window.Plo@am__quote@

.c.o:
@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@	$(COMPILE) -c $<

.c.obj:
@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`

.c.lo:
@am__fastdepCC_TRUE@	if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs

distclean-libtool:
	-rm -f libtool
uninstall-info-am:

ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '    { files[$$0] = 1; } \
	       END { for (i in files) print i; }'`; \
	mkid -fID $$unique
tags: TAGS

TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
		$(TAGS_FILES) $(LISP)
	tags=; \
	here=`pwd`; \
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '    { files[$$0] = 1; } \
	       END { for (i in files) print i; }'`; \
	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
	  test -n "$$unique" || unique=$$empty_fix; \
	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	    $$tags $$unique; \
	fi
ctags: CTAGS
CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
		$(TAGS_FILES) $(LISP)
	tags=; \
	here=`pwd`; \
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '    { files[$$0] = 1; } \
	       END { for (i in files) print i; }'`; \
	test -z "$(CTAGS_ARGS)$$tags$$unique" \
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
	     $$tags $$unique

GTAGS:
	here=`$(am__cd) $(top_builddir) && pwd` \
	  && cd $(top_srcdir) \
	  && gtags -i $(GTAGS_ARGS) $$here

distclean-tags:
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags

distdir: $(DISTFILES)
	$(mkdir_p) $(distdir)/../../../misc
	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
	list='$(DISTFILES)'; for file in $$list; do \
	  case $$file in \
	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
	  esac; \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
	    dir="/$$dir"; \
	    $(mkdir_p) "$(distdir)$$dir"; \
	  else \
	    dir=''; \
	  fi; \
	  if test -d $$d/$$file; then \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
	    fi; \
	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
	  else \
	    test -f $(distdir)/$$file \
	    || cp -p $$d/$$file $(distdir)/$$file \
	    || exit 1; \
	  fi; \
	done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
	for dir in "$(DESTDIR)$(libdir)"; do \
	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
	done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	  `test -z '$(STRIP)' || \
	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
clean: clean-am

clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
	mostlyclean-am

distclean: distclean-am
	-rm -rf ./$(DEPDIR)
	-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
	distclean-libtool distclean-tags

dvi: dvi-am

dvi-am:

html: html-am

info: info-am

info-am:

install-data-am:
	@$(NORMAL_INSTALL)
	$(MAKE) $(AM_MAKEFLAGS) install-data-hook

install-exec-am: install-libLTLIBRARIES

install-info: install-info-am

install-man:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -rf ./$(DEPDIR)
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-compile mostlyclean-generic \
	mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES
	@$(NORMAL_INSTALL)
	$(MAKE) $(AM_MAKEFLAGS) uninstall-hook

.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
	clean-libLTLIBRARIES clean-libtool ctags distclean \
	distclean-compile distclean-generic distclean-libtool \
	distclean-tags distdir dvi dvi-am html html-am info info-am \
	install install-am install-data install-data-am \
	install-data-hook install-exec install-exec-am install-info \
	install-info-am install-libLTLIBRARIES install-man \
	install-strip installcheck installcheck-am installdirs \
	maintainer-clean maintainer-clean-generic mostlyclean \
	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
	pdf pdf-am ps ps-am tags uninstall uninstall-am uninstall-hook \
	uninstall-info-am uninstall-libLTLIBRARIES


$(XINE_LIB):
	@cd $(top_srcdir)/src/xine-engine && $(MAKE)

install-data-hook:
	@if test $$MAKELEVEL -le 4 ; then \
	  if test -x "$(top_srcdir)/post-install.sh" ; then \
	    $(top_srcdir)/post-install.sh ; \
	  fi \
	fi

pass1:
	@$(MAKE) MULTIPASS_CFLAGS="$(PASS1_CFLAGS)"

pass2:
	@$(MAKE) MULTIPASS_CFLAGS="$(PASS2_CFLAGS)"

debug:
	@$(MAKE) CFLAGS="$(DEBUG_CFLAGS)"

install-debug: debug
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
	@list='$(SUBDIRS)'; for subdir in $$list; do \
	  (cd $$subdir && $(MAKE) $@) || exit; \
	done;
	$(MAKE) $(AM_MAKEFLAGS) install-data-hook

install-includeHEADERS: $(include_HEADERS)
	@$(NORMAL_INSTALL)
	$(install_sh) -d $(DESTDIR)$(includedir)/xine
	@list='$(include_HEADERS)'; for p in $$list; do \
	  if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
	  echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p"; \
	  $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p; \
	done

uninstall-includeHEADERS:
	@$(NORMAL_UNINSTALL)
	list='$(include_HEADERS)'; for p in $$list; do \
	  rm -f $(DESTDIR)$(includedir)/xine/$$p; \
	done

uninstall-hook:
	@if echo '$(libdir)' | egrep ^'$(XINE_PLUGINDIR)' >/dev/null; then \
	  list='$(lib_LTLIBRARIES)'; for p in $$list; do \
	    p="`echo $$p | sed -e 's/\.la$$/\.so/g;s|^.*/||'`"; \
	    echo " rm -f $(DESTDIR)$(libdir)/$$p"; \
	    rm -f $(DESTDIR)$(libdir)/$$p; \
	  done; \
	fi

mostlyclean-generic:
	-rm -f *~ \#* .*~ .\#*

maintainer-clean-generic:
	-@echo "This command is intended for maintainers to use;"
	-@echo "it deletes files that may require special tools to rebuild."
	-rm -f Makefile.in
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

--- NEW FILE: filter.h ---
/*=============================================================================
 *	
 *  This software has been released under the terms of the GNU Public
 *  license. See http://www.gnu.org/copyleft/gpl.html for details.
 *
 *  Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au
 *
 *=============================================================================
 */

#if !defined _DSP_H
# error "Never use <filter.h> directly; include <dsp.h> instead"
#endif

#ifndef _FILTER_H
#define _FILTER_H	1

/* Design and implementation of different types of digital filters */

/* Flags used for filter design */

/* Filter characteristics */
#define LP          0x00010000 /* Low pass */
#define HP          0x00020000 /* High pass */
#define BP          0x00040000 /* Band pass */
#define BS          0x00080000 /* Band stop */
#define TYPE_MASK   0x000F0000

/* Window types */
#define BOXCAR      0x00000001
#define TRIANG      0x00000002
#define HAMMING     0x00000004
#define HANNING     0x00000008
#define BLACKMAN    0x00000010
#define FLATTOP     0x00000011
#define KAISER      0x00000012
#define WINDOW_MASK 0x0000001F

/* Parallel filter design */
#define	FWD   	    0x00000001 /* Forward indexing of polyphase filter */
#define REW         0x00000002 /* Reverse indexing of polyphase filter */
#define ODD         0x00000010 /* Make filter HP */

/* Exported functions */
extern _ftype_t fir(unsigned int n, _ftype_t* w, _ftype_t* x);

extern _ftype_t* pfir(unsigned int n, unsigned int k, unsigned int xi, _ftype_t** w, _ftype_t** x, _ftype_t* y, unsigned int s);

extern int updateq(unsigned int n, unsigned int xi, _ftype_t* xq, _ftype_t* in);
extern int updatepq(unsigned int n, unsigned int k, unsigned int xi, _ftype_t** xq, _ftype_t* in, unsigned int s);

extern int design_fir(unsigned int n, _ftype_t* w, _ftype_t* fc, unsigned int flags, _ftype_t opt);

extern int design_pfir(unsigned int n, unsigned int k, _ftype_t* w, _ftype_t** pw, _ftype_t g, unsigned int flags);
extern void prewarp(_ftype_t* a, _ftype_t fc, _ftype_t fs);
void bilinear(_ftype_t* a, _ftype_t* b, _ftype_t* k, _ftype_t fs, _ftype_t *coef);

extern int szxform(_ftype_t* a, _ftype_t* b, _ftype_t Q, _ftype_t fc, _ftype_t fs, _ftype_t *k, _ftype_t *coef);

/* Add new data to circular queue designed to be used with a FIR
 * filter. xq is the circular queue, in pointing at the new sample, xi
 * current index for xq and n the length of the filter. xq must be n*2
 * long. 
 */
#define updateq(n,xi,xq,in)\
  xq[xi]=(xq)[(xi)+(n)]=*(in);\
  xi=(++(xi))&((n)-1);

#endif

--- NEW FILE: stretch.c ---
/*
 * Copyright (C) 2000-2004 the xine project
 * 
 * This file is part of xine, a free video player.
 * 
 * xine is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * xine is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
 *
 * Time stretch by a given factor, optionally preserving pitch
 *
 * $Id: stretch.c,v 1.1 2005/04/04 22:38:18 dsalt-guest Exp $
 *
 */

#include <stdio.h>

#include "xine_internal.h"
#include "xineutils.h"
#include "post.h"
#include "dsp.h"
#include "resample.h"

#include "audio_filters.h"

#define AUDIO_FRAGMENT  120/1000  /* ms of audio */

#define CLIP_INT16(s) ((s) < INT16_MIN) ? INT16_MIN : \
                      (((s) > INT16_MAX) ? INT16_MAX : (s))

/*
 * ***************************************************
 * stretchable unix System Clock Reference
 * use stretch factor to calculate speed
 * ***************************************************
 */

struct stretchscr_s {
  scr_plugin_t     scr;

  struct timeval   cur_time;
  int64_t          cur_pts;
  int              xine_speed;
  double           speed_factor;
  double           *stretch_factor;

  pthread_mutex_t  lock;

};

typedef struct stretchscr_s stretchscr_t;

static int stretchscr_get_priority (scr_plugin_t *scr) {
  return 10; /* high priority */
}

/* Only call this when already mutex locked */
static void stretchscr_set_pivot (stretchscr_t *this) {

  struct   timeval tv;
  int64_t  pts;
  double   pts_calc; 

  xine_monotonic_clock(&tv, NULL);
  pts_calc = (tv.tv_sec  - this->cur_time.tv_sec) * this->speed_factor;
  pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6;
  pts = this->cur_pts + pts_calc;

/* This next part introduces a one off inaccuracy 
 * to the scr due to rounding tv to pts. 
 */
  this->cur_time.tv_sec=tv.tv_sec;
  this->cur_time.tv_usec=tv.tv_usec;
  this->cur_pts=pts; 

  return ;
}

static int stretchscr_set_speed (scr_plugin_t *scr, int speed) {
  stretchscr_t *this = (stretchscr_t*) scr;

  pthread_mutex_lock (&this->lock);

  stretchscr_set_pivot( this );
  this->xine_speed   = speed;
  this->speed_factor = (double) speed * 90000.0 / XINE_FINE_SPEED_NORMAL / 
                       (*this->stretch_factor);

  pthread_mutex_unlock (&this->lock);

  return speed;
}

static void stretchscr_adjust (scr_plugin_t *scr, int64_t vpts) {
  stretchscr_t *this = (stretchscr_t*) scr;
  struct   timeval tv;

  pthread_mutex_lock (&this->lock);

  xine_monotonic_clock(&tv, NULL);
  this->cur_time.tv_sec=tv.tv_sec;
  this->cur_time.tv_usec=tv.tv_usec;
  this->cur_pts = vpts;

  pthread_mutex_unlock (&this->lock);
}

static void stretchscr_start (scr_plugin_t *scr, int64_t start_vpts) {
  stretchscr_t *this = (stretchscr_t*) scr;

  pthread_mutex_lock (&this->lock);

  xine_monotonic_clock(&this->cur_time, NULL);
  this->cur_pts = start_vpts;

  pthread_mutex_unlock (&this->lock);
  
  stretchscr_set_speed (&this->scr, XINE_FINE_SPEED_NORMAL);
}

static int64_t stretchscr_get_current (scr_plugin_t *scr) {
  stretchscr_t *this = (stretchscr_t*) scr;

  struct   timeval tv;
  int64_t pts;
  double   pts_calc; 
  pthread_mutex_lock (&this->lock);

  xine_monotonic_clock(&tv, NULL);
  
  pts_calc = (tv.tv_sec  - this->cur_time.tv_sec) * this->speed_factor;
  pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6;

  pts = this->cur_pts + pts_calc;
  
  pthread_mutex_unlock (&this->lock);

  return pts;
}

static void stretchscr_exit (scr_plugin_t *scr) {
  stretchscr_t *this = (stretchscr_t*) scr;

  pthread_mutex_destroy (&this->lock);
  free(this);
}

static stretchscr_t* stretchscr_init (double *stretch_factor) {
  stretchscr_t *this;

  this = (stretchscr_t *) xine_xmalloc(sizeof(stretchscr_t));

  this->scr.interface_version = 3;
  this->scr.get_priority      = stretchscr_get_priority;
  this->scr.set_fine_speed    = stretchscr_set_speed;
  this->scr.adjust            = stretchscr_adjust;
  this->scr.start             = stretchscr_start;
  this->scr.get_current       = stretchscr_get_current;
  this->scr.exit              = stretchscr_exit;
  
  pthread_mutex_init (&this->lock, NULL);
  
  this->stretch_factor = stretch_factor;
  stretchscr_set_speed (&this->scr, XINE_SPEED_PAUSE);

  return this;
}

/*****************************************************/


typedef struct post_plugin_stretch_s post_plugin_stretch_t;

typedef struct post_class_stretch_s post_class_stretch_t;

struct post_class_stretch_s {
  post_class_t        post_class;

  xine_t             *xine;
};


typedef struct stretch_parameters_s {
  int preserve_pitch;
  double factor;
} stretch_parameters_t;

/*
 * description of params struct
 */
START_PARAM_DESCR( stretch_parameters_t )
PARAM_ITEM( POST_PARAM_TYPE_BOOL, preserve_pitch, NULL, 0, 1, 0,
            "Preserve pitch" )
PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, factor, NULL, 0.5, 1.5, 0, 
            "Time stretch factor (<1.0 shorten duration)" )
END_PARAM_DESCR( param_descr )

/* plugin structure */
struct post_plugin_stretch_s {
  post_plugin_t        post;
  
  stretchscr_t*        scr;

  /* private data */
  stretch_parameters_t params;
  xine_post_in_t       params_input;
  int                  params_changed;
  
  int                  channels;
  int                  bytes_per_frame;

  int16_t             *audiofrag;         /* audio fragment to work on */
  int16_t             *outfrag;           /* processed audio fragment  */
  _ftype_t            *w;
  int                  frames_per_frag;
  int                  frames_per_outfrag;
  int                  num_frames;        /* current # of frames on audiofrag */
 
  int64_t              pts;               /* pts for audiofrag */
      
  pthread_mutex_t      lock;
};

/**************************************************************************
 * stretch parameters functions
 *************************************************************************/
static int set_parameters (xine_post_t *this_gen, void *param_gen) {
  post_plugin_stretch_t *this = (post_plugin_stretch_t *)this_gen;
  stretch_parameters_t *param = (stretch_parameters_t *)param_gen;

  pthread_mutex_lock (&this->lock);
  memcpy( &this->params, param, sizeof(stretch_parameters_t) );
  this->params_changed = 1;
  pthread_mutex_unlock (&this->lock);

  return 1;
}
static int get_parameters (xine_post_t *this_gen, void *param_gen) {
  post_plugin_stretch_t *this = (post_plugin_stretch_t *)this_gen;
  stretch_parameters_t *param = (stretch_parameters_t *)param_gen;

  pthread_mutex_lock (&this->lock);
  memcpy( param, &this->params, sizeof(stretch_parameters_t) );
  pthread_mutex_unlock (&this->lock);

  return 1;
}

static xine_post_api_descr_t * get_param_descr (void) {
  return &param_descr;
}

static char * get_help (void) {
  return _("This filter will perform a time stretch, playing the "
           "stream faster or slower by a factor. Pitch is optionally "
           "preserved, so it is possible, for example, to use it to "
           "watch a movie in less time than it was originaly shot.\n"
           );
}

static xine_post_api_t post_api = {
  set_parameters,
  get_parameters,
  get_param_descr,
  get_help,
};



/**************************************************************************
 * xine audio post plugin functions
 *************************************************************************/

static int stretch_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream,
		   uint32_t bits, uint32_t rate, int mode) {

  post_audio_port_t  *port = (post_audio_port_t *)port_gen;
  post_plugin_stretch_t *this = (post_plugin_stretch_t *)port->post;
  int64_t time;
  
  _x_post_rewire(&this->post);
  _x_post_inc_usage(port);
  
  port->stream = stream;
  port->bits = bits;
  port->rate = rate;
  port->mode = mode;
  
  /* register our own scr provider */   
  time = port->stream->xine->clock->get_current_time(port->stream->xine->clock);
  this->scr = stretchscr_init(&this->params.factor);
  this->scr->scr.start(&this->scr->scr, time);
  port->stream->xine->clock->register_scr(port->stream->xine->clock, &this->scr->scr);

  /* force updating on stretch_port_put_buffer */
  this->params_changed = 1;
    
  return port->original_port->open(port->original_port, stream, bits, rate, mode);
}

static void stretch_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream ) {

  post_audio_port_t  *port = (post_audio_port_t *)port_gen;
  post_plugin_stretch_t *this = (post_plugin_stretch_t *)port->post;

  if (this->scr) {
    port->stream->xine->clock->unregister_scr(port->stream->xine->clock, &this->scr->scr);
    this->scr->scr.exit(&this->scr->scr);
  }
  
  if(this->audiofrag) {
    free(this->audiofrag);
    this->audiofrag = NULL;
  }
  
  if(this->outfrag) {
    free(this->outfrag);
    this->outfrag = NULL;
  }
  
  if(this->w) {
    free(this->w);
    this->w = NULL;
  }
  
  port->stream = NULL;

  port->original_port->close(port->original_port, stream );
  
  _x_post_dec_usage(port);
}

static void stretch_process_fragment( post_audio_port_t *port, 
  xine_stream_t *stream, extra_info_t *extra_info )
{
  post_plugin_stretch_t *this = (post_plugin_stretch_t *)port->post;
  
  audio_buffer_t  *outbuf;
  int16_t         *data_out = this->outfrag;
  int num_frames_in = this->num_frames;
  int num_frames_out = this->num_frames * this->frames_per_outfrag /
                         this->frames_per_frag;

  if( !this->params.preserve_pitch ) {
     if( this->channels == 2 )
       _x_audio_out_resample_stereo(this->audiofrag, num_frames_in,
                                    this->outfrag, num_frames_out);
     else if( this->channels == 1 )
        _x_audio_out_resample_mono(this->audiofrag, num_frames_in,
                                   this->outfrag, num_frames_out);
  } else {
     if( num_frames_in > num_frames_out )
     {
       /*
        * time compressing strategy
        *
        * input chunk has two halves, A and B.
        * output chunk is composed as follow:
        * - some frames copied directly from A
        * - some frames copied from A merged with frames from B 
        *   weighted by an increasing factor (0 -> 1.0)
        * - frames from A weighted by a decreasing factor (1.0 -> 0)
        *   merged with frames copied from B
        * - some frames copied directly from B
        */
        
       int merge_frames = num_frames_in - num_frames_out;
       int copy_frames;
       int16_t *src = this->audiofrag;
       int16_t *dst = this->outfrag;
       int i, j;
       
       if( merge_frames > num_frames_out )
         merge_frames = num_frames_out;
       copy_frames = num_frames_out - merge_frames;
       
       memcpy(dst, src, copy_frames/2 * this->bytes_per_frame);
       dst += copy_frames/2 * this->channels;
       src += copy_frames/2 * this->channels;
 
       for( i = 0; i < merge_frames/2; i++ )
       {
         for( j = 0; j < this->channels; j++, src++, dst++ ) {
                                          
           int32_t  s = (int32_t) ((_ftype_t) src[0] +
                                    src[merge_frames * this->channels] * this->w[i]);
           *dst = CLIP_INT16(s);
         }
       }
       
       for( ; i < merge_frames; i++ )
       {
         for( j = 0; j < this->channels; j++, src++, dst++ ) {
                                          
           int32_t  s = (int32_t) ((_ftype_t) src[0] * this->w[i] +
                                    src[merge_frames * this->channels]);
           *dst = CLIP_INT16(s);
         }
       }
       
       src += merge_frames * this->channels;
       
       memcpy(dst, src, (copy_frames - copy_frames/2) *
                        this->bytes_per_frame);
     
     } else {
       /*
        * time expansion strategy
        *
        * output chunk is composed of two versions of the
        * input chunk:
        * - first part copied directly from input, and then
        *   merged with the second (delayed) part using a 
        *   decreasing factor (1.0 -> 0)
        * - the delayed version of the input is merged with
        *   an increasing factor (0 -> 1.0) and then (when 
        *   factor reaches 1.0) just copied until the end. 
        */
       
       int merge_frames = num_frames_out - num_frames_in;
       int copy_frames = num_frames_out - merge_frames;
       int16_t *src1 = this->audiofrag;
       int16_t *src2;
       int16_t *dst = this->outfrag;
       int i, j;

       memcpy(dst, src1, copy_frames/2 * this->bytes_per_frame);
       dst += copy_frames/2 * this->channels;
       src1 += copy_frames/2 * this->channels;
       src2 = src1 - merge_frames * this->channels;

       for( i = 0; i < merge_frames/2; i++ )
       {
         for( j = 0; j < this->channels; j++, src1++, src2++, dst++ ) {
                                          
           int32_t  s = (int32_t) ((_ftype_t) *src1 +
                                    *src2 * this->w[i]);
           *dst = CLIP_INT16(s);
         }
       }
       
       for( ; i < merge_frames; i++ )
       {
         for( j = 0; j < this->channels; j++, src1++, src2++, dst++ ) {
                                          
           int32_t  s = (int32_t) ((_ftype_t) *src1 * this->w[i] +
                                    *src2);
           *dst = CLIP_INT16(s);
         }
       }
              
       memcpy(dst, src2, (copy_frames - copy_frames/2) *
                         this->bytes_per_frame);

    }
  }
      
  /* copy processed fragment into multiple audio buffers, if needed */
  while( num_frames_out ) {
    outbuf = port->original_port->get_buffer(port->original_port); 
  
    outbuf->num_frames = outbuf->mem_size / this->bytes_per_frame;
    if( outbuf->num_frames > num_frames_out )
      outbuf->num_frames = num_frames_out;
        
    memcpy( outbuf->mem, data_out, 
            outbuf->num_frames * this->bytes_per_frame );
    num_frames_out -= outbuf->num_frames;
    (uint8_t *)data_out += outbuf->num_frames * this->bytes_per_frame;
                
    outbuf->vpts        = this->pts;
    this->pts           = 0;
    outbuf->stream      = stream;
    outbuf->format.bits = port->bits;
    outbuf->format.rate = port->rate;
    outbuf->format.mode = port->mode;
    
    _x_extra_info_merge( outbuf->extra_info, extra_info );
    
    port->original_port->put_buffer(port->original_port, outbuf, stream );  
  }
  
  this->num_frames = 0;
}

static void stretch_port_put_buffer (xine_audio_port_t *port_gen, 
                             audio_buffer_t *buf, xine_stream_t *stream) {
  
  post_audio_port_t  *port = (post_audio_port_t *)port_gen;
  post_plugin_stretch_t *this = (post_plugin_stretch_t *)port->post;
  int16_t               *data_in;
  
  pthread_mutex_lock (&this->lock);

  
  if( this->params_changed ) {
    int64_t audio_step;

    if( this->num_frames && this->audiofrag && this->outfrag ) {
      /* output whatever we have before changing parameters */
      stretch_process_fragment( port, stream, buf->extra_info );
    }
            
    this->channels = _x_ao_mode2channels(port->mode);
    this->bytes_per_frame = port->bits / 8 * this->channels;
  
    audio_step = ((int64_t)90000 * (int64_t)32768) / (int64_t)port->rate;
    audio_step = (int64_t) ((double)audio_step / this->params.factor);
    stream->metronom->set_audio_rate(stream->metronom, audio_step);

    stretchscr_set_speed(&this->scr->scr, this->scr->xine_speed);
        
    if(this->audiofrag) {
      free(this->audiofrag);
      this->audiofrag = NULL;
    }
    
    if(this->outfrag) {
      free(this->outfrag);
      this->outfrag = NULL;
    }
    
    if(this->w) {
      free(this->w);
      this->w = NULL;
    }
      
    this->frames_per_frag = port->rate * AUDIO_FRAGMENT;
    this->frames_per_outfrag = (int) ((double)this->params.factor * this->frames_per_frag);

    if( this->frames_per_frag != this->frames_per_outfrag ) {
      int wsize;
      
      this->audiofrag = malloc( this->frames_per_frag * this->bytes_per_frame ); 
      this->outfrag = malloc( this->frames_per_outfrag * this->bytes_per_frame ); 
  
      if( this->frames_per_frag > this->frames_per_outfrag )
        wsize = this->frames_per_frag - this->frames_per_outfrag;
      else
        wsize = this->frames_per_outfrag - this->frames_per_frag;

      this->w = (_ftype_t*) malloc( wsize * sizeof(_ftype_t) );
      triang(wsize, this->w);
    }
                
    this->num_frames = 0;
    this->pts = 0;
    
    this->params_changed = 0;
  }
  
  pthread_mutex_unlock (&this->lock);

  /* just pass data through if we have nothing to do */
  if( this->frames_per_frag == this->frames_per_outfrag ||
      /* FIXME: we only handle 1 or 2 channels, 16 bits for now */
      (this->channels != 1 && this->channels != 2) || 
      port->bits != 16 ) {
  
    port->original_port->put_buffer(port->original_port, buf, stream );  
  
    return;
  }
  
  /* update pts for our current audio fragment */
  if( buf->vpts )
    this->pts = buf->vpts - (this->num_frames * 90000 / port->rate);
  
  data_in = buf->mem;
  while( buf->num_frames ) {
    int frames_to_copy = this->frames_per_frag - this->num_frames;
    
    if( frames_to_copy > buf->num_frames )
      frames_to_copy = buf->num_frames;

    /* copy up to one fragment from input buf to our buffer */
    memcpy( (uint8_t *)this->audiofrag + this->num_frames * this->bytes_per_frame,
            data_in, frames_to_copy * this->bytes_per_frame );
    
    (uint8_t *)data_in += frames_to_copy * this->bytes_per_frame;
    this->num_frames += frames_to_copy;
    buf->num_frames -= frames_to_copy;

    /* check if we have a complete audio fragment to process */
    if( this->num_frames == this->frames_per_frag ) {
      stretch_process_fragment( port, stream, buf->extra_info );
    }
  }
  
  buf->num_frames=0; /* UNDOCUMENTED, but hey, it works! Force old audio_out buffer free. */
  port->original_port->put_buffer(port->original_port, buf, stream );  
  
  return;
}

static void stretch_dispose(post_plugin_t *this_gen)
{
  post_plugin_stretch_t *this = (post_plugin_stretch_t *)this_gen;

  if (_x_post_dispose(this_gen)) {
    free(this);
  }
}

/* plugin class functions */
static post_plugin_t *stretch_open_plugin(post_class_t *class_gen, int inputs,
					 xine_audio_port_t **audio_target,
					 xine_video_port_t **video_target)
{
  post_plugin_stretch_t *this  = (post_plugin_stretch_t *)xine_xmalloc(sizeof(post_plugin_stretch_t));
  post_in_t            *input;
  post_out_t           *output;
  xine_post_in_t       *input_api;
  post_audio_port_t    *port;
  stretch_parameters_t  init_params;
  
  if (!this || !audio_target || !audio_target[0] ) {
    free(this);
    return NULL;
  }
  
  _x_post_init(&this->post, 1, 0);

  init_params.preserve_pitch = 1;
  init_params.factor = 0.80;
  
  pthread_mutex_init (&this->lock, NULL);

  set_parameters ((xine_post_t *)&this->post, &init_params);
  
  port = _x_post_intercept_audio_port(&this->post, audio_target[0], &input, &output);
  port->new_port.open       = stretch_port_open;
  port->new_port.close      = stretch_port_close;
  port->new_port.put_buffer = stretch_port_put_buffer;

  input_api       = &this->params_input;
  input_api->name = "parameters";
  input_api->type = XINE_POST_DATA_PARAMETERS;
  input_api->data = &post_api;
  xine_list_append_content(this->post.input, input_api);

  this->post.xine_post.audio_input[0] = &port->new_port;

  this->post.dispose = stretch_dispose;

  return &this->post;
}

static char *stretch_get_identifier(post_class_t *class_gen)
{
  return "stretch";
}

static char *stretch_get_description(post_class_t *class_gen)
{
  return "Time stretch by a given factor, optionally preserving pitch";
}

static void stretch_class_dispose(post_class_t *class_gen)
{
  free(class_gen);
}

/* plugin class initialization function */
void *stretch_init_plugin(xine_t *xine, void *data)
{
  post_class_stretch_t *class = (post_class_stretch_t *)malloc(sizeof(post_class_stretch_t));
  
  if (!class)
    return NULL;
  
  class->post_class.open_plugin     = stretch_open_plugin;
  class->post_class.get_identifier  = stretch_get_identifier;
  class->post_class.get_description = stretch_get_description;
  class->post_class.dispose         = stretch_class_dispose;
  
  class->xine                       = xine;
  
  return class;
}

--- NEW FILE: dsp.h ---
/*=============================================================================
 *	
 *  This software has been released under the terms of the GNU Public
 *  license. See http://www.gnu.org/copyleft/gpl.html for details.
 *
 *  Copyright 2002 Anders Johansson ajh@atri.curtin.edu.au
 *
 *=============================================================================
 */

#ifndef	_DSP_H
#define	_DSP_H 	1

/* Implementation of routines used for DSP */

/* Size of floating point type used in routines */
#define _ftype_t float

#include <window.h>
#include <filter.h>

#endif