handle mono

This commit is contained in:
Glenn Maynard
2004-07-24 02:01:12 +00:00
parent 27243e074c
commit 69cf82de49
3 changed files with 41 additions and 22 deletions
+26 -3
View File
@@ -281,7 +281,7 @@ void RageSound::RateChange(char *buf, int &cnt,
/* Fill the buffer by about "bytes" worth of data. (We might go a little
* over, and we won't overflow our buffer.) Return the number of bytes
* actually read; 0 = EOF. */
* actually read; 0 = EOF. Convert mono input to stereo. */
int RageSound::FillBuf( int frames )
{
ASSERT(Sample);
@@ -295,7 +295,6 @@ int RageSound::FillBuf( int frames )
char inbuf[10240];
unsigned read_size = read_block_size;
int cnt = 0;
if( m_Param.speed_input_samples != m_Param.speed_output_samples )
{
@@ -309,12 +308,36 @@ int RageSound::FillBuf( int frames )
ASSERT(read_size < sizeof(inbuf));
}
/* channels == 2; we want stereo. If the input data is mono, read half as many
* samples. */
if( Sample->GetNumChannels() == 1 )
read_size /= 2;
ASSERT(read_size < sizeof(inbuf));
cnt = Sample->Read(inbuf, read_size);
int cnt = Sample->Read(inbuf, read_size);
if(cnt == 0)
return got_something; /* EOF */
if( Sample->GetNumChannels() == 1 )
{
/* Dupe mono to stereo in-place; do it in reverse, to handle overlap. */
int num_samples = cnt / sizeof(int16_t);
float *input = (float *) inbuf;
float *output = input;
input += num_samples;
output += num_samples*2;
while( num_samples-- )
{
input -= 1;
output -= 2;
output[0] = input[0];
output[1] = input[0];
}
cnt *= 2;
}
if(cnt == -1)
{
Fail(Sample->GetError());
+13 -19
View File
@@ -54,8 +54,6 @@ static long OggRageFile_tell_func( void *datasource )
return f->Tell();
}
const int channels = 2;
const int read_block_size = 1024;
@@ -131,6 +129,10 @@ SoundReader_FileReader::OpenResult RageSoundReader_Vorbisfile::Open(CString file
eof = false;
read_offset = (int) ov_pcm_tell(vf);
vorbis_info *vi = ov_info( vf, -1 );
ASSERT_M( vi->channels == 1 || vi->channels == 2, ssprintf("%i", vi->channels) );
channels = vi->channels;
return OPEN_OK;
}
@@ -183,9 +185,12 @@ bool RageSoundReader_Vorbisfile::FillBuf()
vorbis_info *vi = ov_info( vf, -1 );
ASSERT( vi != NULL );
const int bytes_per_frame = 2*vi->channels;
char tmpbuf[4096];
if( (unsigned) vi->channels != channels )
RageException::Throw( "File \"%s\" changes channel count from %i to %i; not supported", channels, vi->channels );
const int bytes_per_frame = sizeof(int16_t)*vi->channels;
int ret = 0;
{
@@ -207,9 +212,9 @@ bool RageSoundReader_Vorbisfile::FillBuf()
/* In bytes: */
int silence = (curofs - read_offset) * bytes_per_frame;
CHECKPOINT_M( ssprintf("p %i,%i: %i frames of silence needed", curofs, read_offset, silence) );
silence = min( silence, (int) sizeof(tmpbuf) );
silence = min( silence, (int) sizeof(buffer) );
memset( tmpbuf, 0, silence );
memset( buffer, 0, silence );
ret = silence;
}
}
@@ -218,9 +223,9 @@ bool RageSoundReader_Vorbisfile::FillBuf()
{
int bstream;
#if defined(INTEGER_VORBIS)
ret = ov_read( vf, tmpbuf, sizeof(tmpbuf), &bstream );
ret = ov_read( vf, buffer, sizeof(buffer), &bstream );
#else // float vorbis decoder
ret = ov_read( vf, tmpbuf, sizeof(tmpbuf), (BYTE_ORDER == BIG_ENDIAN)?1:0, 2, 1, &bstream );
ret = ov_read( vf, buffer, sizeof(buffer), (BYTE_ORDER == BIG_ENDIAN)?1:0, 2, 1, &bstream );
#endif
if( ret == OV_HOLE )
@@ -242,17 +247,6 @@ bool RageSoundReader_Vorbisfile::FillBuf()
/* If we have a different number of channels, we need to convert. */
ASSERT( vi->channels == 1 || vi->channels == 2 );
if( vi->channels == 1 )
{
int16_t *indata = (int16_t *)tmpbuf;
int16_t *outdata = (int16_t *)buffer;
int size = ret / sizeof(int16_t);
for( unsigned pos = 0; pos < unsigned(size); ++pos )
outdata[pos*2] = outdata[pos*2+1] = indata[pos];
ret *= 2;
}
else
memcpy( buffer, tmpbuf, ret );
avail = ret;
return true;
@@ -18,6 +18,7 @@ class RageSoundReader_Vorbisfile: public SoundReader_FileReader {
bool FillBuf();
CString filename;
int read_offset;
unsigned channels;
public:
OpenResult Open(CString filename);
@@ -27,6 +28,7 @@ public:
int SetPosition_Fast(int ms) { return SetPosition(ms, false); }
int Read(char *buf, unsigned len);
int GetSampleRate() const;
unsigned GetNumChannels() const { return channels; }
RageSoundReader_Vorbisfile();
~RageSoundReader_Vorbisfile();
SoundReader *Copy() const;