sample_buffer: made MP3 decoder more robust

The mp3 decoder was using an uncomfortably large buffer,
laughably because of a negative overflow. Fixed this and
added a failsafe check to prevent buffer overflows.

Additionally changed printfs to qWarnings and fixed copyright
notice in audio_file_mp3.
This commit is contained in:
Andrew Kelley
2009-08-12 04:34:24 -07:00
parent c3100e36d0
commit 1c118f1a46
3 changed files with 28 additions and 14 deletions

View File

@@ -2,8 +2,7 @@
* audio_file_mp3.h - Audio-device which encodes mp3-stream and writes it
* into an mp3-file. This is used for song-export.
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* 2009 Andrew Kelley <superjoe30@gmail.com>
* Copyright (c) 2009 Andrew Kelley <superjoe30@gmail.com>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*

View File

@@ -97,12 +97,12 @@ bool AudioFileMp3::startEncoding( void )
// open any handles, files, etc
m_lgf = m_lame.lame_init();
if( m_lgf == NULL ){
printf("AudioFileMp3: Unable to initialize lame\n");
qWarning("AudioFileMp3: Unable to initialize lame\n");
return false;
}
if( channels() > 2 )
printf("I don't think lame can do more than 2 channels\n");
qWarning("I don't think lame can do more than 2 channels\n");
m_lame.lame_set_in_samplerate(m_lgf, sampleRate() );
m_lame.lame_set_num_channels(m_lgf, channels() );
@@ -136,12 +136,13 @@ bool AudioFileMp3::startEncoding( void )
m_outfile = new QFile( outputFile() );
if( ! m_outfile->open( QIODevice::WriteOnly ) )
{
printf("AudioFileMp3: unable to open file for output\n");
qWarning("AudioFileMp3: unable to open file for output\n");
return false;
}
// write the headers and such
// TODO: add a comment "created with LMMS"
// TODO: add meta information with artist, title, etc, and
// add a comment "created with LMMS"
return true;
@@ -174,16 +175,16 @@ void AudioFileMp3::writeBuffer( const surroundSampleFrame * _ab,
switch(rc){
case -1:
printf("AudioFileMp3: encode error: buffer too small.\n");
qWarning("AudioFileMp3: encode error: buffer too small.\n");
return;
case -2:
printf("AudioFileMp3: encode error: out of memory\n");
qWarning("AudioFileMp3: encode error: out of memory\n");
return;
case -3:
printf("AudioFileMp3: encode error: lame_init_params not called\n");
qWarning("AudioFileMp3: encode error: lame_init_params not called\n");
return;
case -4:
printf("AudioFileMp3: encode error: psycho acoustic problems\n");
qWarning("AudioFileMp3: encode error: psycho acoustic problems\n");
return;
}

View File

@@ -611,6 +611,7 @@ f_cnt_t sampleBuffer::decodeSampleMp3( QString & file, int_sample_t * & _buf,
// TODO: calc _buf size
int bufPos = 0;
int bufSize = 0;
bool initBuf = false;
while(1)
@@ -629,27 +630,40 @@ f_cnt_t sampleBuffer::decodeSampleMp3( QString & file, int_sample_t * & _buf,
{
if( mp3data.header_parsed == 0 )
{
printf("failed to parse header\n");
qWarning("MP3 decoder: failed to parse header\n");
return 0;
}
else
{
// calculate buffer size
int safetyPad = 7200;
int sampleSafetyPad = 1096;
bufSize = (int)( (float)in.size() /
((float)mp3data.bitrate * 1000.0 / 8.0) *
(float)mp3data.samplerate + sampleSafetyPad);
bufSize = (bufSize + safetyPad) * _channels;
// process header
_samplerate = mp3data.samplerate;
_channels = mp3data.stereo;
_buf = new int_sample_t[mp3data.totalframes *
mp3data.framesize * _channels];
_buf = new int_sample_t[bufSize];
initBuf = true;
}
}
// convert the decoded PCM into sample
for(int i = 0; i<ret; ++i)
for(int i = 0; i<ret && bufPos<bufSize; ++i)
{
_buf[bufPos++] = pcm_l[i];
if( _channels == 2 )
_buf[bufPos++] = pcm_r[i];
}
if( bufPos >= bufSize )
{
qWarning("MP3 file exceeded the calculated buffer size");
}
}
lame.lame_decode_exit();