rewrote AV::Sound::decode() to be much more scalable and handle looping without small breaks

git-svn-id: svn://anubis/anaglym/trunk@289 99a6e188-d820-4881-8870-2d33a10e2619
This commit is contained in:
Josh Holtrop 2010-06-24 02:14:37 +00:00
parent 8a49a5089e
commit ed1f9c8f7f
2 changed files with 28 additions and 26 deletions

53
AV.cc
View File

@ -181,6 +181,7 @@ AV::Sound::Sound(AV & av)
{
m_rwops = NULL;
m_ss = NULL;
m_buff_bytes_left = 0;
}
AV::Sound::~Sound()
@ -251,39 +252,39 @@ void AV::Sound::rewind()
int AV::Sound::decode(Uint8 * stream, int len)
{
int len_decoded = 0, len_decoded_now;
int samples_decoded_now;
int spos = 0;
int len_samples = len / BYTES_PER_SAMPLE;
int16_t * s16stream = (int16_t *) stream;
int16_t * decoded_stream = (int16_t *) m_ss->buffer;
do
int len_decoded = 0;
int bytes_decoded_this_pass;
if (m_buff_bytes_left > 0)
{
len_decoded_now = Sound_Decode(m_ss);
if (len_decoded_now == 0)
int len_to_copy = min(len, m_buff_bytes_left);
int buff_offset = m_ss->buffer_size - m_buff_bytes_left;
memcpy(stream, ((int8_t *)m_ss->buffer) + buff_offset, len_to_copy);
m_buff_bytes_left -= len_to_copy;
len_decoded += len_to_copy;
}
while (len_decoded < len)
{
bytes_decoded_this_pass = Sound_Decode(m_ss);
if (bytes_decoded_this_pass == 0)
{
if (m_loop_count < INT_MAX)
{
m_loop_count--;
}
if (m_loop_count > 0)
{
rewind();
m_loop_count--;
len_decoded_now = Sound_Decode(m_ss);
Sound_Rewind(m_ss);
bytes_decoded_this_pass = Sound_Decode(m_ss);
}
}
samples_decoded_now = len_decoded_now / BYTES_PER_SAMPLE;
len_decoded += len_decoded_now;
for (int i = 0; i < samples_decoded_now; i++, spos++)
if (bytes_decoded_this_pass <= 0)
{
if (spos >= len_samples)
{
cerr << "Sorry, anaglym bug in " __FILE__ ":" << __LINE__
<< ": rework sound buffer sizes" << endl;
exit(33);
}
int val = s16stream[spos] + decoded_stream[i];
s16stream[spos] = (val > SHRT_MAX) ? SHRT_MAX : val;
return len_decoded;
}
} while ( (len_decoded_now == (int) m_ss->buffer_size)
&& (len_decoded < len) );
int len_to_copy = min(bytes_decoded_this_pass, len - len_decoded);
memcpy(stream + len_decoded, m_ss->buffer, len_to_copy);
len_decoded += len_to_copy;
m_buff_bytes_left = bytes_decoded_this_pass - len_to_copy;
}
return len_decoded;
}

1
AV.h
View File

@ -31,6 +31,7 @@ class AV
Sound_Sample * m_ss;
FileLoader::Buffer m_buff;
int m_loop_count;
int m_buff_bytes_left;
};
AV();