DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

resample.cpp (15212B)


      1 /*
      2 
      3 TiMidity -- Experimental MIDI to WAVE converter
      4 Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
      5 
      6 This program is free software; you can redistribute it and/or modify
      7 it under the terms of the GNU General Public License as published by
      8 the Free Software Foundation; either version 2 of the License, or
      9 (at your option) any later version.
     10 
     11 This program is distributed in the hope that it will be useful,
     12 but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 GNU General Public License for more details.
     15 
     16 You should have received a copy of the GNU General Public License
     17 along with this program; if not, write to the Free Software
     18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     19 
     20 resample.c
     21 */
     22 
     23 #include <math.h>
     24 #include <stdio.h>
     25 #include <stdlib.h>
     26 
     27 #include "config.h"
     28 #include "common.h"
     29 #include "instrum.h"
     30 #include "playmidi.h"
     31 #include "output.h"
     32 #include "controls.h"
     33 #include "tables.h"
     34 #include "resample.h"
     35 
     36 #ifdef LINEAR_INTERPOLATION
     37 # if defined(LOOKUP_HACK) && defined(LOOKUP_INTERPOLATION)
     38 #   define RESAMPLATION \
     39 	v1=src[ofs>>FRACTION_BITS];\
     40 	v2=src[(ofs>>FRACTION_BITS)+1];\
     41 	*dest++ = v1 + (iplookup[(((v2-v1)<<5) & 0x03FE0) | \
     42 	((ofs & FRACTION_MASK) >> (FRACTION_BITS-5))]);
     43 # else
     44 #   define RESAMPLATION \
     45 	v1=src[ofs>>FRACTION_BITS];\
     46 	v2=src[(ofs>>FRACTION_BITS)+1];\
     47 	*dest++ = v1 + (((v2-v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS);
     48 # endif
     49 #  define INTERPVARS sample_t v1, v2
     50 #else
     51 /* Earplugs recommended for maximum listening enjoyment */
     52 #  define RESAMPLATION *dest++=src[ofs>>FRACTION_BITS];
     53 #  define INTERPVARS
     54 #endif
     55 
     56 #define FINALINTERP if (ofs == le) *dest++=src[ofs>>FRACTION_BITS];
     57 /* So it isn't interpolation. At least it's final. */
     58 
     59 extern sample_t *resample_buffer;
     60 void Real_Tim_Free( void *pt );
     61 
     62 
     63 /*************** resampling with fixed increment *****************/
     64 
     65 static sample_t *rs_plain(int v,  int32_t *countptr)
     66 {
     67 
     68 	/* Play sample until end, then free the voice. */
     69 
     70 	INTERPVARS;
     71 	Voice 
     72 		*vp=&voice[v];
     73 	sample_t 
     74 		*dest=resample_buffer,
     75 		*src=vp->sample->data;
     76 	 int32_t 
     77 		ofs=vp->sample_offset,
     78 		incr=vp->sample_increment,
     79 		le=vp->sample->data_length,
     80 		count=*countptr;
     81 
     82 #ifdef PRECALC_LOOPS
     83 	 int32_t i;
     84 
     85 	if (incr<0) incr = -incr; /* In case we're coming out of a bidir loop */
     86 
     87 	/* Precalc how many times we should go through the loop.
     88 	NOTE: Assumes that incr > 0 and that ofs <= le */
     89 	i = (le - ofs) / incr + 1;
     90 
     91 	if (i > count)
     92 	{
     93 		i = count;
     94 		count = 0;
     95 	} 
     96 	else count -= i;
     97 
     98 	while (i--) 
     99 	{
    100 		RESAMPLATION;
    101 		ofs += incr;
    102 	}
    103 
    104 	if (ofs >= le) 
    105 	{
    106 		FINALINTERP;
    107 		vp->status=VOICE_FREE;
    108 		ctl->note(v);
    109 		*countptr-=count+1;
    110 	}
    111 
    112 #else /* PRECALC_LOOPS */
    113 	while (count--)
    114 	{
    115 		RESAMPLATION;
    116 		ofs += incr;
    117 		if (ofs >= le)
    118 		{
    119 			FINALINTERP;
    120 			vp->status=VOICE_FREE;
    121 			ctl->note(v);
    122 			*countptr-=count+1;
    123 			break;
    124 		}
    125 	}
    126 #endif /* PRECALC_LOOPS */
    127 
    128 	vp->sample_offset=ofs; /* Update offset */
    129 	return resample_buffer;
    130 }
    131 
    132 static sample_t *rs_loop(Voice *vp,  int32_t count)
    133 {
    134 
    135 	/* Play sample until end-of-loop, skip back and continue. */
    136 
    137 	INTERPVARS;
    138 	 int32_t 
    139 		ofs=vp->sample_offset, 
    140 		incr=vp->sample_increment,
    141 		le=vp->sample->loop_end, 
    142 		ll=le - vp->sample->loop_start;
    143 	sample_t
    144 		*dest=resample_buffer,
    145 		*src=vp->sample->data;
    146 
    147 #ifdef PRECALC_LOOPS
    148 	 int32_t i;
    149 
    150 	while (count) 
    151 	{
    152 		if (ofs >= le)
    153 			/* NOTE: Assumes that ll > incr and that incr > 0. */
    154 			ofs -= ll;
    155 		/* Precalc how many times we should go through the loop */
    156 		i = (le - ofs) / incr + 1;
    157 		if (i > count) 
    158 		{
    159 			i = count;
    160 			count = 0;
    161 		} 
    162 		else count -= i;
    163 		while (i--) 
    164 		{
    165 			RESAMPLATION;
    166 			ofs += incr;
    167 		}
    168 	}
    169 #else
    170 	while (count--)
    171 	{
    172 		RESAMPLATION;
    173 		ofs += incr;
    174 		if (ofs>=le)
    175 			ofs -= ll; /* Hopefully the loop is longer than an increment. */
    176 	}
    177 #endif
    178 
    179 	vp->sample_offset=ofs; /* Update offset */
    180 	return resample_buffer;
    181 }
    182 
    183 static sample_t *rs_bidir(Voice *vp,  int32_t count)
    184 {
    185 	INTERPVARS;
    186 	 int32_t 
    187 		ofs=vp->sample_offset,
    188 		incr=vp->sample_increment,
    189 		le=vp->sample->loop_end,
    190 		ls=vp->sample->loop_start;
    191 	sample_t 
    192 		*dest=resample_buffer, 
    193 		*src=vp->sample->data;
    194 
    195 #ifdef PRECALC_LOOPS
    196 	int32_t
    197 		le2 = le<<1, 
    198 		ls2 = ls<<1,
    199 		i;
    200 	/* Play normally until inside the loop region */
    201 
    202 	if (ofs <= ls) 
    203 	{
    204 		/* NOTE: Assumes that incr > 0, which is NOT always the case
    205 		when doing bidirectional looping.  I have yet to see a case
    206 		where both ofs <= ls AND incr < 0, however. */
    207 		i = (ls - ofs) / incr + 1;
    208 		if (i > count) 
    209 		{
    210 			i = count;
    211 			count = 0;
    212 		} 
    213 		else count -= i;
    214 		while (i--) 
    215 		{
    216 			RESAMPLATION;
    217 			ofs += incr;
    218 		}
    219 	}
    220 
    221 	/* Then do the bidirectional looping */
    222 
    223 	while(count) 
    224 	{
    225 		/* Precalc how many times we should go through the loop */
    226 		i = ((incr > 0 ? le : ls) - ofs) / incr + 1;
    227 		if (i > count) 
    228 		{
    229 			i = count;
    230 			count = 0;
    231 		} 
    232 		else count -= i;
    233 		while (i--) 
    234 		{
    235 			RESAMPLATION;
    236 			ofs += incr;
    237 		}
    238 		if (ofs>=le) 
    239 		{
    240 			/* fold the overshoot back in */
    241 			ofs = le2 - ofs;
    242 			incr *= -1;
    243 		} 
    244 		else if (ofs <= ls) 
    245 		{
    246 			ofs = ls2 - ofs;
    247 			incr *= -1;
    248 		}
    249 	}
    250 
    251 #else /* PRECALC_LOOPS */
    252 	/* Play normally until inside the loop region */
    253 
    254 	if (ofs < ls)
    255 	{
    256 		while (count--)
    257 		{
    258 			RESAMPLATION;
    259 			ofs += incr;
    260 			if (ofs>=ls)
    261 				break;
    262 		}
    263 	}
    264 
    265 	/* Then do the bidirectional looping */
    266 
    267 	if (count>0)
    268 		while (count--)
    269 		{
    270 			RESAMPLATION;
    271 			ofs += incr;
    272 			if (ofs>=le)
    273 			{
    274 				/* fold the overshoot back in */
    275 				ofs = le - (ofs - le);
    276 				incr = -incr;
    277 			}
    278 			else if (ofs <= ls)
    279 			{
    280 				ofs = ls + (ls - ofs);
    281 				incr = -incr;
    282 			}
    283 		}  
    284 #endif /* PRECALC_LOOPS */
    285 		vp->sample_increment=incr;
    286 		vp->sample_offset=ofs; /* Update offset */
    287 		return resample_buffer;
    288 }
    289 
    290 /*********************** vibrato versions ***************************/
    291 
    292 /* We only need to compute one half of the vibrato sine cycle */
    293 static int vib_phase_to_inc_ptr(int phase)
    294 {
    295 	if (phase < VIBRATO_SAMPLE_INCREMENTS/2)
    296 		return VIBRATO_SAMPLE_INCREMENTS/2-1-phase;
    297 	else if (phase >= 3*VIBRATO_SAMPLE_INCREMENTS/2)
    298 		return 5*VIBRATO_SAMPLE_INCREMENTS/2-1-phase;
    299 	else
    300 		return phase-VIBRATO_SAMPLE_INCREMENTS/2;
    301 }
    302 
    303 static  int32_t update_vibrato(Voice *vp, int sign)
    304 {
    305 	 int32_t depth;
    306 	int phase, pb;
    307 	double a;
    308 
    309 	if (vp->vibrato_phase++ >= 2*VIBRATO_SAMPLE_INCREMENTS-1)
    310 		vp->vibrato_phase=0;
    311 	phase=vib_phase_to_inc_ptr(vp->vibrato_phase);
    312 
    313 	if (vp->vibrato_sample_increment[phase])
    314 	{
    315 		if (sign)
    316 			return -vp->vibrato_sample_increment[phase];
    317 		else
    318 			return vp->vibrato_sample_increment[phase];
    319 	}
    320 
    321 	/* Need to compute this sample increment. */
    322 
    323 	depth=vp->sample->vibrato_depth<<7;
    324 
    325 	if (vp->vibrato_sweep)
    326 	{
    327 		/* Need to update sweep */
    328 		vp->vibrato_sweep_position += vp->vibrato_sweep;
    329 		if (vp->vibrato_sweep_position >= (1<<SWEEP_SHIFT))
    330 			vp->vibrato_sweep=0;
    331 		else
    332 		{
    333 			/* Adjust depth */
    334 			depth *= vp->vibrato_sweep_position;
    335 			depth >>= SWEEP_SHIFT;
    336 		}
    337 	}
    338 
    339 	a = FSCALE(((double)(vp->sample->sample_rate) *
    340 		(double)(vp->frequency)) /
    341 		((double)(vp->sample->root_freq) *
    342 		(double)(play_mode->rate)),
    343 		FRACTION_BITS);
    344 
    345 	pb=(int)((sine(vp->vibrato_phase * 
    346 		(SINE_CYCLE_LENGTH/(2*VIBRATO_SAMPLE_INCREMENTS)))
    347 		* (double)(depth) * VIBRATO_AMPLITUDE_TUNING));
    348 
    349 	if (pb<0)
    350 	{
    351 		pb=-pb;
    352 		a /= bend_fine[(pb>>5) & 0xFF] * bend_coarse[pb>>13];
    353 	}
    354 	else
    355 		a *= bend_fine[(pb>>5) & 0xFF] * bend_coarse[pb>>13];
    356 
    357 	/* If the sweep's over, we can store the newly computed sample_increment */
    358 	if (!vp->vibrato_sweep)
    359 		vp->vibrato_sample_increment[phase]=(int32_t) a;
    360 
    361 	if (sign)
    362 		a = -a; /* need to preserve the loop direction */
    363 
    364 	return (int32_t) a;
    365 }
    366 
    367 static sample_t *rs_vib_plain(int v,  int32_t *countptr)
    368 {
    369 
    370 	/* Play sample until end, then free the voice. */
    371 
    372 	INTERPVARS;
    373 	Voice *vp=&voice[v];
    374 	sample_t 
    375 		*dest=resample_buffer, 
    376 		*src=vp->sample->data;
    377 	 int32_t 
    378 		le=vp->sample->data_length,
    379 		ofs=vp->sample_offset, 
    380 		incr=vp->sample_increment, 
    381 		count=*countptr;
    382 	int 
    383 		cc=vp->vibrato_control_counter;
    384 
    385 	/* This has never been tested */
    386 
    387 	if (incr<0) incr = -incr; /* In case we're coming out of a bidir loop */
    388 
    389 	while (count--)
    390 	{
    391 		if (!cc--)
    392 		{
    393 			cc=vp->vibrato_control_ratio;
    394 			incr=update_vibrato(vp, 0);
    395 		}
    396 		RESAMPLATION;
    397 		ofs += incr;
    398 		if (ofs >= le)
    399 		{
    400 			FINALINTERP;
    401 			vp->status=VOICE_FREE;
    402 			ctl->note(v);
    403 			*countptr-=count+1;
    404 			break;
    405 		}
    406 	}
    407 
    408 	vp->vibrato_control_counter=cc;
    409 	vp->sample_increment=incr;
    410 	vp->sample_offset=ofs; /* Update offset */
    411 	return resample_buffer;
    412 }
    413 
    414 static sample_t *rs_vib_loop(Voice *vp,  int32_t count)
    415 {
    416 
    417 	/* Play sample until end-of-loop, skip back and continue. */
    418 
    419 	INTERPVARS;
    420 	 int32_t 
    421 		ofs=vp->sample_offset, 
    422 		incr=vp->sample_increment, 
    423 		le=vp->sample->loop_end,
    424 		ll=le - vp->sample->loop_start;
    425 	sample_t 
    426 		*dest=resample_buffer, 
    427 		*src=vp->sample->data;
    428 	int 
    429 		cc=vp->vibrato_control_counter;
    430 
    431 #ifdef PRECALC_LOOPS
    432 	 int32_t i;
    433 	int
    434 		vibflag=0;
    435 
    436 	while (count) 
    437 	{
    438 		/* Hopefully the loop is longer than an increment */
    439 		if(ofs >= le)
    440 			ofs -= ll;
    441 		/* Precalc how many times to go through the loop, taking
    442 		the vibrato control ratio into account this time. */
    443 		i = (le - ofs) / incr + 1;
    444 		if(i > count) i = count;
    445 		if(i > cc)
    446 		{
    447 			i = cc;
    448 			vibflag = 1;
    449 		} 
    450 		else cc -= i;
    451 		count -= i;
    452 		while(i--) 
    453 		{
    454 			RESAMPLATION;
    455 			ofs += incr;
    456 		}
    457 		if(vibflag) 
    458 		{
    459 			cc = vp->vibrato_control_ratio;
    460 			incr = update_vibrato(vp, 0);
    461 			vibflag = 0;
    462 		}
    463 	}
    464 
    465 #else /* PRECALC_LOOPS */
    466 	while (count--)
    467 	{
    468 		if (!cc--)
    469 		{
    470 			cc=vp->vibrato_control_ratio;
    471 			incr=update_vibrato(vp, 0);
    472 		}
    473 		RESAMPLATION;
    474 		ofs += incr;
    475 		if (ofs>=le)
    476 			ofs -= ll; /* Hopefully the loop is longer than an increment. */
    477 	}
    478 #endif /* PRECALC_LOOPS */
    479 
    480 	vp->vibrato_control_counter=cc;
    481 	vp->sample_increment=incr;
    482 	vp->sample_offset=ofs; /* Update offset */
    483 	return resample_buffer;
    484 }
    485 
    486 static sample_t *rs_vib_bidir(Voice *vp,  int32_t count)
    487 {
    488 	INTERPVARS;
    489 	 int32_t 
    490 		ofs=vp->sample_offset, 
    491 		incr=vp->sample_increment,
    492 		le=vp->sample->loop_end, 
    493 		ls=vp->sample->loop_start;
    494 	sample_t 
    495 		*dest=resample_buffer, 
    496 		*src=vp->sample->data;
    497 	int 
    498 		cc=vp->vibrato_control_counter;
    499 
    500 #ifdef PRECALC_LOOPS
    501 	int32_t
    502 		le2=le<<1,
    503 		ls2=ls<<1,
    504 		i;
    505 	int
    506 		vibflag = 0;
    507 
    508 	/* Play normally until inside the loop region */
    509 	while (count && (ofs <= ls)) 
    510 	{
    511 		i = (ls - ofs) / incr + 1;
    512 		if (i > count) i = count;
    513 		if (i > cc) 
    514 		{
    515 			i = cc;
    516 			vibflag = 1;
    517 		} 
    518 		else cc -= i;
    519 		count -= i;
    520 		while (i--) 
    521 		{
    522 			RESAMPLATION;
    523 			ofs += incr;
    524 		}
    525 		if (vibflag) 
    526 		{
    527 			cc = vp->vibrato_control_ratio;
    528 			incr = update_vibrato(vp, 0);
    529 			vibflag = 0;
    530 		}
    531 	}
    532 
    533 	/* Then do the bidirectional looping */
    534 
    535 	while (count) 
    536 	{
    537 		/* Precalc how many times we should go through the loop */
    538 		i = ((incr > 0 ? le : ls) - ofs) / incr + 1;
    539 		if(i > count) i = count;
    540 		if(i > cc) 
    541 		{
    542 			i = cc;
    543 			vibflag = 1;
    544 		} 
    545 		else cc -= i;
    546 		count -= i;
    547 		while (i--) 
    548 		{
    549 			RESAMPLATION;
    550 			ofs += incr;
    551 		}
    552 		if (vibflag) 
    553 		{
    554 			cc = vp->vibrato_control_ratio;
    555 			incr = update_vibrato(vp, (incr < 0));
    556 			vibflag = 0;
    557 		}
    558 		if (ofs >= le) 
    559 		{
    560 			/* fold the overshoot back in */
    561 			ofs = le2 - ofs;
    562 			incr *= -1;
    563 		} 
    564 		else if (ofs <= ls) 
    565 		{
    566 			ofs = ls2 - ofs;
    567 			incr *= -1;
    568 		}
    569 	}
    570 
    571 #else /* PRECALC_LOOPS */
    572 	/* Play normally until inside the loop region */
    573 
    574 	if (ofs < ls)
    575 	{
    576 		while (count--)
    577 		{
    578 			if (!cc--)
    579 			{
    580 				cc=vp->vibrato_control_ratio;
    581 				incr=update_vibrato(vp, 0);
    582 			}
    583 			RESAMPLATION;
    584 			ofs += incr;
    585 			if (ofs>=ls)
    586 				break;
    587 		}
    588 	}
    589 
    590 	/* Then do the bidirectional looping */
    591 
    592 	if (count>0)
    593 		while (count--)
    594 		{
    595 			if (!cc--)
    596 			{
    597 				cc=vp->vibrato_control_ratio;
    598 				incr=update_vibrato(vp, (incr < 0));
    599 			}
    600 			RESAMPLATION;
    601 			ofs += incr;
    602 			if (ofs>=le)
    603 			{
    604 				/* fold the overshoot back in */
    605 				ofs = le - (ofs - le);
    606 				incr = -incr;
    607 			}
    608 			else if (ofs <= ls)
    609 			{
    610 				ofs = ls + (ls - ofs);
    611 				incr = -incr;
    612 			}
    613 		}
    614 #endif /* PRECALC_LOOPS */
    615 
    616 		vp->vibrato_control_counter=cc;
    617 		vp->sample_increment=incr;
    618 		vp->sample_offset=ofs; /* Update offset */
    619 		return resample_buffer;
    620 }
    621 
    622 sample_t *resample_voice(int v,  int32_t *countptr)
    623 {
    624 	 int32_t ofs;
    625 	uint8_t modes;
    626 	Voice *vp=&voice[v];
    627 
    628 	if (!(vp->sample->sample_rate))
    629 	{
    630 		/* Pre-resampled data -- just update the offset and check if
    631 		we're out of data. */
    632 		ofs=vp->sample_offset >> FRACTION_BITS; /* Kind of silly to use
    633 												FRACTION_BITS here... */
    634 		if (*countptr >= (vp->sample->data_length>>FRACTION_BITS) - ofs)
    635 		{
    636 			/* Note finished. Free the voice. */
    637 			vp->status = VOICE_FREE;
    638 			ctl->note(v);
    639 
    640 			/* Let the caller know how much data we had left */
    641 			*countptr = (vp->sample->data_length>>FRACTION_BITS) - ofs;
    642 		}
    643 		else
    644 			vp->sample_offset += *countptr << FRACTION_BITS;
    645 
    646 		return vp->sample->data+ofs;
    647 	}
    648 
    649 	/* Need to resample. Use the proper function. */
    650 	modes=vp->sample->modes;
    651 
    652 	if (vp->vibrato_control_ratio)
    653 	{
    654 		if ((modes & MODES_LOOPING) &&
    655 			((modes & MODES_ENVELOPE) ||
    656 			(vp->status==VOICE_ON || vp->status==VOICE_SUSTAINED)))
    657 		{
    658 			if (modes & MODES_PINGPONG)
    659 				return rs_vib_bidir(vp, *countptr);
    660 			else
    661 				return rs_vib_loop(vp, *countptr);
    662 		}
    663 		else
    664 			return rs_vib_plain(v, countptr);
    665 	}
    666 	else
    667 	{
    668 		if ((modes & MODES_LOOPING) &&
    669 			((modes & MODES_ENVELOPE) ||
    670 			(vp->status==VOICE_ON || vp->status==VOICE_SUSTAINED)))
    671 		{
    672 			if (modes & MODES_PINGPONG)
    673 				return rs_bidir(vp, *countptr);
    674 			else
    675 				return rs_loop(vp, *countptr);
    676 		}
    677 		else
    678 			return rs_plain(v, countptr);
    679 	}
    680 }
    681 
    682 void pre_resample(Sample * sp)
    683 {
    684 	double a, xdiff;
    685 	 int32_t incr, ofs, newlen, count;
    686 	int16_t *newdata, *dest, *src = (int16_t *) sp->data;
    687 	int16_t v1, v2, v3, v4, *vptr;
    688 	static const char note_name[12][3] =
    689 	{
    690 		"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
    691 	};
    692 
    693 	ctl->cmsg(CMSG_INFO, VERB_NOISY, " * pre-resampling for note %d (%s%d)",
    694 		sp->note_to_use,
    695 		note_name[sp->note_to_use % 12], (sp->note_to_use & 0x7F) / 12);
    696 
    697 	a = ((double) (sp->sample_rate) * freq_table[(int) (sp->note_to_use)]) /
    698 		((double) (sp->root_freq) * play_mode->rate);
    699 	newlen = (int32_t)(sp->data_length / a);
    700 	dest = newdata = (int16_t*)safe_malloc(newlen >> (FRACTION_BITS - 1));
    701 
    702 	count = (newlen >> FRACTION_BITS) - 1;
    703 	ofs = incr = (sp->data_length - (1 << FRACTION_BITS)) / count;
    704 
    705 	if (--count)
    706 		*dest++ = src[0];
    707 
    708 	/* Since we're pre-processing and this doesn't have to be done in
    709 	real-time, we go ahead and do the full sliding cubic interpolation. */
    710 	while (--count)
    711 	{
    712 		vptr = src + (ofs >> FRACTION_BITS);
    713 		v1 = *(vptr - 1);
    714 		v2 = *vptr;
    715 		v3 = *(vptr + 1);
    716 		v4 = *(vptr + 2);
    717 		xdiff = FSCALENEG(ofs & FRACTION_MASK, FRACTION_BITS);
    718 		*dest++ = (int16_t)(v2 + (xdiff / 6.0) * (-2 * v1 - 3 * v2 + 6 * v3 - v4 +
    719 			xdiff * (3 * (v1 - 2 * v2 + v3) + xdiff * (-v1 + 3 * (v2 - v3) + v4))));
    720 		ofs += incr;
    721 	}
    722 
    723 	if (ofs & FRACTION_MASK)
    724 	{
    725 		v1 = src[ofs >> FRACTION_BITS];
    726 		v2 = src[(ofs >> FRACTION_BITS) + 1];
    727 		*dest++ = v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS);
    728 	}
    729 	else
    730 		*dest++ = src[ofs >> FRACTION_BITS];
    731 
    732 	sp->data_length = newlen;
    733 	sp->loop_start = (int32_t)(sp->loop_start / a);
    734 	sp->loop_end = (int32_t)(sp->loop_end / a);
    735 	Real_Tim_Free(sp->data);
    736 	sp->data = (sample_t *) newdata;
    737 	sp->sample_rate = 0;
    738 }