Lots of ADPCM bug fixes.
This commit is contained in:
@@ -50,7 +50,7 @@ enum
|
|||||||
Uint32 RageSoundReader_WAV::ConvertMsToBytePos(int BytesPerSample, int channels, Uint32 ms) const
|
Uint32 RageSoundReader_WAV::ConvertMsToBytePos(int BytesPerSample, int channels, Uint32 ms) const
|
||||||
{
|
{
|
||||||
const float frames_per_ms = ((float) SampleRate) / 1000.0f;
|
const float frames_per_ms = ((float) SampleRate) / 1000.0f;
|
||||||
const Uint32 frame_offset = (Uint32) (frames_per_ms * ((float) ms));
|
const Uint32 frame_offset = (Uint32) (frames_per_ms * float(ms) + 0.5f);
|
||||||
const Uint32 frame_size = (Uint32) BytesPerSample * channels;
|
const Uint32 frame_size = (Uint32) BytesPerSample * channels;
|
||||||
return frame_offset * frame_size;
|
return frame_offset * frame_size;
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ Uint32 RageSoundReader_WAV::ConvertBytePosToMs(int BytesPerSample, int channels,
|
|||||||
const Uint32 frame_size = (Uint32) BytesPerSample * channels;
|
const Uint32 frame_size = (Uint32) BytesPerSample * channels;
|
||||||
const Uint32 frame_no = pos / frame_size;
|
const Uint32 frame_no = pos / frame_size;
|
||||||
const float frames_per_ms = ((float) SampleRate) / 1000.0f;
|
const float frames_per_ms = ((float) SampleRate) / 1000.0f;
|
||||||
return (Uint32) (frame_no / frames_per_ms);
|
return (Uint32) ((frame_no / frames_per_ms) + 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Better than SDL_ReadLE16, since you can detect i/o errors... */
|
/* Better than SDL_ReadLE16, since you can detect i/o errors... */
|
||||||
@@ -332,34 +332,20 @@ Uint32 RageSoundReader_WAV::read_sample_fmt_adpcm(char *buf, unsigned len)
|
|||||||
|
|
||||||
while (bw < len)
|
while (bw < len)
|
||||||
{
|
{
|
||||||
/* write ongoing sample frame before reading more data... */
|
/* Read a new block. */
|
||||||
switch (this->adpcm.samples_left_in_block)
|
if( adpcm.samples_left_in_block == 0 )
|
||||||
{
|
|
||||||
case 0: /* need to read a new block... */
|
|
||||||
if (!read_adpcm_block_headers(adpcm))
|
if (!read_adpcm_block_headers(adpcm))
|
||||||
return bw;
|
return bw;
|
||||||
|
|
||||||
/* only write first sample frame for now. */
|
const bool first_sample_in_block = ( adpcm.samples_left_in_block == adpcm.wSamplesPerBlock );
|
||||||
put_adpcm_sample_frame( (Uint16 *) (buf + bw), 1 );
|
put_adpcm_sample_frame( (Uint16 *) (buf + bw), first_sample_in_block? 1:0 );
|
||||||
adpcm.samples_left_in_block--;
|
adpcm.samples_left_in_block--;
|
||||||
bw += this->fmt.adpcm_sample_frame_size;
|
bw += this->fmt.adpcm_sample_frame_size;
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: /* output last sample frame of block... */
|
|
||||||
put_adpcm_sample_frame( (Uint16 *) (buf + bw), 0 );
|
|
||||||
this->adpcm.samples_left_in_block--;
|
|
||||||
bw += this->fmt.adpcm_sample_frame_size;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: /* output latest sample frame and read a new one... */
|
|
||||||
put_adpcm_sample_frame( (Uint16 *) (buf + bw), 0 );
|
|
||||||
this->adpcm.samples_left_in_block--;
|
|
||||||
bw += this->fmt.adpcm_sample_frame_size;
|
|
||||||
|
|
||||||
|
if( !first_sample_in_block && adpcm.samples_left_in_block )
|
||||||
if (!decode_adpcm_sample_frame())
|
if (!decode_adpcm_sample_frame())
|
||||||
return bw;
|
return bw;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return bw;
|
return bw;
|
||||||
}
|
}
|
||||||
@@ -370,36 +356,41 @@ int RageSoundReader_WAV::seek_sample_fmt_adpcm( Uint32 ms )
|
|||||||
{
|
{
|
||||||
const int offset = ConvertMsToBytePos( BytesPerSample, Channels, ms );
|
const int offset = ConvertMsToBytePos( BytesPerSample, Channels, ms );
|
||||||
const int bpb = (adpcm.wSamplesPerBlock * this->fmt.adpcm_sample_frame_size);
|
const int bpb = (adpcm.wSamplesPerBlock * this->fmt.adpcm_sample_frame_size);
|
||||||
int skipsize = (offset / bpb) * this->fmt.wBlockAlign;
|
const int skipsize = (offset / bpb) * this->fmt.wBlockAlign;
|
||||||
|
|
||||||
const int pos = skipsize + this->fmt.data_starting_offset;
|
const int pos = skipsize + this->fmt.data_starting_offset;
|
||||||
int rc = fseek(this->rw, pos, SEEK_SET);
|
int rc = fseek(this->rw, pos, SEEK_SET);
|
||||||
BAIL_IF_MACRO(rc == -1, strerror(errno), -1);
|
BAIL_IF_MACRO(rc == -1, strerror(errno), -1);
|
||||||
|
|
||||||
/* The offset we need is in this block, so we need to decode to there. */
|
/* The offset we need is in this block, so we need to decode to there. */
|
||||||
skipsize += (offset % bpb);
|
rc = offset % bpb; /* bytes into this block we need to decode */
|
||||||
rc = (offset % bpb); /* bytes into this block we need to decode */
|
if( rc == 0 )
|
||||||
|
{
|
||||||
|
adpcm.samples_left_in_block = 0;
|
||||||
|
return ms;
|
||||||
|
}
|
||||||
|
|
||||||
if (!read_adpcm_block_headers(adpcm))
|
if (!read_adpcm_block_headers(adpcm))
|
||||||
{
|
{
|
||||||
fseek(this->rw, 0, SEEK_SET);
|
fseek(this->rw, fmt.data_starting_offset, SEEK_SET);
|
||||||
adpcm.samples_left_in_block = 0;
|
adpcm.samples_left_in_block = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first sample frame of block is a freebie. :) */
|
|
||||||
adpcm.samples_left_in_block--;
|
adpcm.samples_left_in_block--;
|
||||||
rc -= this->fmt.adpcm_sample_frame_size;
|
rc -= this->fmt.adpcm_sample_frame_size;
|
||||||
|
|
||||||
while (rc > 0)
|
while (rc > 0)
|
||||||
{
|
{
|
||||||
|
adpcm.samples_left_in_block--;
|
||||||
|
rc -= this->fmt.adpcm_sample_frame_size;
|
||||||
|
|
||||||
if (!decode_adpcm_sample_frame())
|
if (!decode_adpcm_sample_frame())
|
||||||
{
|
{
|
||||||
fseek(this->rw, 0, SEEK_SET);
|
fseek(this->rw, fmt.data_starting_offset, SEEK_SET);
|
||||||
adpcm.samples_left_in_block = 0;
|
adpcm.samples_left_in_block = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
adpcm.samples_left_in_block--;
|
|
||||||
rc -= this->fmt.adpcm_sample_frame_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ms;
|
return ms;
|
||||||
|
|||||||
Reference in New Issue
Block a user