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 ¶m_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 ¶m_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