- // general case
- Con_DPrintf("ResampleSfx: resampling sound %s\n", name);
- samplefrac = 0;
- if ((fracstep & 255) == 0) // skipping points on perfect multiple
- {
- srcsample = 0;
- fracstep >>= 8;
- if (sc->width == 2)
- {
- short *out = (void *)sc->data, *in = (void *)data;
- if (sc->stereo) // LordHavoc: stereo sound support
- {
- fracstep <<= 1;
- for (i=0 ; i<outcount ; i++)
- {
- *out++ = LittleShort (in[srcsample ]);
- *out++ = LittleShort (in[srcsample+1]);
- srcsample += fracstep;
- }
- }
- else
- {
- for (i=0 ; i<outcount ; i++)
- {
- *out++ = LittleShort (in[srcsample ]);
- srcsample += fracstep;
- }
- }
- }
- else
- {
- signed char *out = (void *)sc->data;
- unsigned char *in = (void *)data;
- if (sc->stereo) // LordHavoc: stereo sound support
- {
- fracstep <<= 1;
- for (i=0 ; i<outcount ; i++)
- {
- *out++ = in[srcsample ] - 128;
- *out++ = in[srcsample+1] - 128;
- srcsample += fracstep;
- }
- }
- else
- {
- for (i=0 ; i<outcount ; i++)
- {
- *out++ = in[srcsample ] - 128;
- srcsample += fracstep;
- }
- }
- }
- }
- else
+ const unsigned int fracstep = (double)in_format->speed / shm->format.speed * (1 << FRACTIONAL_BITS);
+ size_t remain_in = srclength, total_out = 0;
+ unsigned int samplefrac;
+ const qbyte *in_ptr = in_data;
+ qbyte *out_ptr = out_data;
+
+ // Check that we can handle one second of that sound
+ if (in_format->speed * in_format->channels > (1 << INTEGER_BITS))
+ Sys_Error ("ResampleSfx: sound quality too high for resampling (%uHz, %u channel(s))",
+ in_format->speed, in_format->channels);
+
+ // We work 1 sec at a time to make sure we don't accumulate any
+ // significant error when adding "fracstep" over several seconds, and
+ // also to be able to handle very long sounds.
+ while (total_out < outcount)