diff wdf/upsample.c @ 0:5242703e91d3 tip

Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author tomwalters
date Fri, 20 May 2011 15:19:45 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wdf/upsample.c	Fri May 20 15:19:45 2011 +0100
@@ -0,0 +1,203 @@
+/*
+    Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989
+    ===========================================================================
+
+    Permission to use, copy, modify, and distribute this software without fee 
+    is hereby granted for research purposes, provided that this copyright 
+    notice appears in all copies and in all supporting documentation, and that 
+    the software is not redistributed for any fee (except for a nominal shipping 
+    charge). Anyone wanting to incorporate all or part of this software in a
+    commercial product must obtain a license from the Medical Research Council.
+
+    The MRC makes no representations about the suitability of this 
+    software for any purpose.  It is provided "as is" without express or implied 
+    warranty.
+ 
+    THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 
+    ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE
+    A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 
+    DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
+    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+/*  
+    Acknowledgment:
+    ==============
+
+    The source code provided in this file was originally developed by 
+    Christian Giguere as part of a Ph.D degree at the Department of
+    Engineering of the University of Cambridge from April 1990 to
+    November 1993. The code was subsequently adapted under a grant
+    from the Hearing Research Trust for full compatibility with 
+    AIM Release 6.15.
+
+    Christian Giguere 25/03/94
+
+*/
+
+/*
+    ===========================================================
+    upsample.c
+    ===========================================================
+
+    Upsampling module (FIR filter interpolation method).
+
+    Author        : Christian Giguere
+    First written : 23rd November, 1990 
+    Last edited   : 09th February, 1994
+
+    Reference:
+    (1) L.R.Rabiner and R.W.Schafer (1978). Digital Processing of
+	Speech Signals (Prentice-Hall), Section 2.4.2.
+    ===========================================================
+*/
+
+/***** includes *****/
+
+#include <math.h>
+#include <stdio.h>
+#include "stitch.h"
+#include "source.h"
+#include "calc.h"
+#include "calc_tl.h"
+#include "fir.h"
+#include "upsample.h"
+
+
+/***** defines *****/
+
+#define   SEGMENT    ( 2048 )    /* number of new points allocated and retained */
+				 /* on each call to input source */
+
+
+/***** functions *****/
+
+/*******************************************************************************
+* name:                  function:
+*
+* upsample_callback()    Callable procedure returning pointer to upsampled data.  
+* 
+* UpSample()             Setup and initialization function for the design of an
+*                        FIR interpolation filter. Returns pointer to a new source.
+********************************************************************************/
+
+struct _upsample_state {
+  struct _fillable_source parent ;
+  Source  source ; 
+  Pointer input ; 
+  int     iptr, inout_size ;
+  int     zerocount, upsample_factor, sample_delay, active ;
+  void    (*proc)(), (*close)() ;  
+  FIRfilterState *states ;  
+  } ;
+
+
+/************************* upsample_callback() ******************************/
+
+static Pointer upsample_callback( state, bytes, buffer )
+  struct _upsample_state  *state ;
+  ByteCount *bytes ;
+  Pointer   buffer ;
+{
+  register DataType *optr, *eptr, *pstart ;
+  register int      last = *bytes == 0 ;
+  register int      points, bytecount ;   
+
+ /***** process *****/
+  if( !last ) {
+
+     for( bytecount=0 ; bytecount<*bytes ; ) {
+
+	/*** get input data ***/
+	 points = ( *bytes - bytecount ) / state->inout_size ;
+	 points = MIN( points, state->upsample_factor * SEGMENT ) ;
+
+	 if( !state->active ) {
+
+	     if( state->sample_delay == 0 )
+		 state->active = 1 ;
+
+	     else if( state->sample_delay > points )
+		      state->sample_delay -= points ;
+
+		  else {
+		      points = state->sample_delay ;
+		      state->sample_delay = 0 ;
+		  }
+	 }
+
+	 if( state->iptr + ( points - 1 ) / state->upsample_factor >= SEGMENT ) {
+	     state->input = Pull( state->source, SEGMENT * state->inout_size ) ;
+	     state->iptr -= SEGMENT ;
+	 }
+
+	/*** fill output buffer with input points interspaced with zeros prior to FIR filtering ***/
+	 pstart =  ( DataType * ) state->input ;       
+	 optr = ( DataType * ) ( buffer + bytecount ) ;
+	 eptr = optr + points ;
+
+	 while( optr < eptr ) {
+       
+	     if( ( state->zerocount %= state->upsample_factor ) > 0 ) 
+		 *optr++ = 0 ;
+
+	     else
+		 *optr++ = pstart[state->iptr++] ; 
+
+	     state->zerocount++ ; 
+	 }
+
+	/*** filter data ***/
+	 state->proc( state->states, buffer+bytecount, points ) ; 
+	    
+	/*** loop counts ***/ 
+	 bytecount += points * state->inout_size * state->active ;
+     }
+
+     return ( buffer ) ;
+  }
+
+
+ /***** close *****/
+  else {
+     Pull( state->source, 0 ) ;
+     state->close( state->states ) ;
+
+     return ( DeleteFillableSource( state ) ) ;
+  }
+
+}
+
+
+/****************************** UpSample() **********************************/
+
+Source UpSample( source, oldsamplerate, cutoff_freq, upsample_factor )
+  Source source ;
+  double oldsamplerate, cutoff_freq ;
+  int    upsample_factor ;
+{
+  DeclareNew( struct _upsample_state *, state ) ;
+  double filterGain, wc ;
+
+ /***** initialise input-related parameters *****/
+  state->inout_size = sizeof ( DataType ) ;
+  state->input  = ( Pointer ) 0 ;
+  state->iptr = SEGMENT ;
+  state->source = NewRetainingSource( source, SEGMENT * state->inout_size ) ;
+  state->zerocount = 0 ;
+  state->upsample_factor = upsample_factor ;    
+
+ /***** Specify FIR filter design parameters *****/
+  wc = cutoff_freq / ( state->upsample_factor * oldsamplerate ) * TwoPi ;
+  state->states = NewLpFIRfilter( wc, upsample_factor, &state->sample_delay ) ; 
+  state->active = 0 ;
+  state->proc = DoFIRfilter ;
+  state->close = CloseFIRfilter ;
+
+ /***** return *****/
+  source = SetFillableSource( state, upsample_callback, "upsample buffering" ) ;
+  return ( source ) ;
+
+}
+