From: ross-c@dcs.leeds.ac.uk (The Brown Bottle)
Subject: Re: Delivery Report (failure) for jlach@ee.WPI.EDU
Organization: The Ohio State University Department of Computer and Information Science
Date: Tue, 10 Nov 1992 09:46:51 GMT

Hi. Someone asked for help in transposing samples. Some of you DSP heads may
laugh at the idea of using linear interpolation to transpose samples, but I
find it quite adequate for computer based digital audio samplers. My mail
to him directly bounced, so I'll post.

Cheers,

Ross-c

In article <1depf4INN5rc@bigboote.WPI.EDU> you write:
>
>	I am building a Digital Audio Sampler. I am looking for C code or an algorithm that will reconstruct a sampled waveform at various frequencies.  The sampler is MIDI compatible therefore the MIDI data will de decoded and the appropriate waveform (up to 6
 key polyphony) will be produced to be sent to the Digital to Analog Converter.  I am open to any ideas or suggestions.  
>
>	Thanks in advance,
>			James
> 

I'm not sure what you mean by "waveform table reconstruction", but if you
want to take a sample and play it back, then I do that on SGI computers
using a straight linear interpolation. Works quite well (expected quality
about the same as an EPS-16 with 16 bit samples and an equivilent 
sampling rate).

If you want higher quality, I suggest you go for higher order interpolation
(e.g. quadratic). I've got a paper somewhere written by someone at Emu which
says that for a given amount of computation, polynomial interpolation whips
the pants of filter-based interpolation/decimation.

Also, I have other papers lying around with other methods (overlapping
windows etc).

Hoping this is something vaguely approximating help,

Ross-c

[included file, I've had a lot of requests for this code]

The following is for drop/add sample. The transposed sample is placed in the
array "dest", but the code could be modified to place the values into a DAC,
or write the buffer out to sound hardware occasionally. Note: It's up to the
calling software to ensure that the dest array is big enough to hold the 
transposed sample (which will change length inversely proportional to the
frequency change)

#define ACCURACY 1024
#define DIVIDE 10
#define MODULUS 01777

transpose( source, source_size, dest, transpose )
short int source[];		/* The original sample */
int source_size;		/* The number of samples */
short int dest[];		/* Where to put the transposed sample */
int transpose;			/* Playback frequency in 1/1024's of the */
				/* original frequency */
float amptitude;
{ register int counter;
  register int source_index;
  register int dest_index;

  source_index = dest_index = counter = 0;

  while ( source_index < source_size )
  { dest[ dest_index++ ] = source[ source_index ];
    counter += transpose;
    source_index += (counter >> DIVIDE);
    counter &= MODULUS;
  }
}

To modify the above code for linear interpolation, place the line:

  source[ source_size ] = source[ source_size - 1 ];

before the while loop (to prevent the very last sample clicking), and
replace the line:

  dest[ dest_index++ ] = source[ source_index ];

with:

  dest[ dest_index++ ] += amptitude * (
			source[source_index] + 
			(((source[source_index+1] - source[source_index] )
				     * counter ) >> DIVIDE));

(note, example assumes that short integers are 16 bit, and integer arithmetic
 is done in 32 bits)

This has two table lookups for source[source_index], so for efficiency you
may wish to store this value in a register before you calculate the
expression.

Ross Clement
ross-c@scs.leeds.ac.uk

------------------------------ End of forwarded message 1

Newsgroups: comp.music