From 1c118f1a46c91245af28a296741a622f828d2972 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 12 Aug 2009 04:34:24 -0700 Subject: [PATCH] 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. --- include/audio_file_mp3.h | 3 +-- src/core/audio/audio_file_mp3.cpp | 17 +++++++++-------- src/core/sample_buffer.cpp | 22 ++++++++++++++++++---- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/include/audio_file_mp3.h b/include/audio_file_mp3.h index e15966903..c27092884 100644 --- a/include/audio_file_mp3.h +++ b/include/audio_file_mp3.h @@ -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 - * 2009 Andrew Kelley + * Copyright (c) 2009 Andrew Kelley * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * diff --git a/src/core/audio/audio_file_mp3.cpp b/src/core/audio/audio_file_mp3.cpp index fd0027e1c..d9d711791 100644 --- a/src/core/audio/audio_file_mp3.cpp +++ b/src/core/audio/audio_file_mp3.cpp @@ -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; } diff --git a/src/core/sample_buffer.cpp b/src/core/sample_buffer.cpp index 8f6b957a9..5958ea82c 100644 --- a/src/core/sample_buffer.cpp +++ b/src/core/sample_buffer.cpp @@ -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= bufSize ) + { + qWarning("MP3 file exceeded the calculated buffer size"); + } + } lame.lame_decode_exit();