diff --git a/src/sources/soundsourcemp3.cpp b/src/sources/soundsourcemp3.cpp index 3b37c9e51735..7b6aca310400 100644 --- a/src/sources/soundsourcemp3.cpp +++ b/src/sources/soundsourcemp3.cpp @@ -164,10 +164,25 @@ SoundSourceMp3::SoundSourceMp3(QUrl url) m_curFrameIndex(kFrameIndexMin), m_madSynthCount(0) { m_seekFrameList.reserve(kSeekFrameListCapacity); + initDecoding(); } SoundSourceMp3::~SoundSourceMp3() { close(); + finishDecoding(); +} + +void SoundSourceMp3::initDecoding() { + mad_stream_init(&m_madStream); + mad_frame_init(&m_madFrame); + mad_synth_init(&m_madSynth); +} + +void SoundSourceMp3::finishDecoding() { + m_madSynthCount = 0; + mad_synth_finish(&m_madSynth); + mad_frame_finish(&m_madFrame); + mad_stream_finish(&m_madStream); } Result SoundSourceMp3::tryOpen(const AudioSourceConfig& /*audioSrcCfg*/) { @@ -185,12 +200,9 @@ Result SoundSourceMp3::tryOpen(const AudioSourceConfig& /*audioSrcCfg*/) { m_pFileData = m_file.map(0, m_fileSize); // Transfer it to the mad stream-buffer: - mad_stream_init(&m_madStream); mad_stream_options(&m_madStream, MAD_OPTION_IGNORECRC); mad_stream_buffer(&m_madStream, m_pFileData, m_fileSize); DEBUG_ASSERT(m_pFileData == m_madStream.this_frame); - mad_frame_init(&m_madFrame); - mad_synth_init(&m_madSynth); DEBUG_ASSERT(m_seekFrameList.empty()); m_avgSeekFrameCount = 0; @@ -370,10 +382,9 @@ Result SoundSourceMp3::tryOpen(const AudioSourceConfig& /*audioSrcCfg*/) { } void SoundSourceMp3::close() { + finishDecoding(); + if (m_pFileData) { - mad_synth_finish(&m_madSynth); - mad_frame_finish(&m_madFrame); - mad_stream_finish(&m_madStream); m_file.unmap(m_pFileData); m_pFileData = NULL; } @@ -381,6 +392,10 @@ void SoundSourceMp3::close() { m_file.close(); m_seekFrameList.clear(); + + // Re-init the decoder, because the SoundSource might be reopened and + // the destructor calls finishDecoding() after close(). + initDecoding(); } SINT SoundSourceMp3::restartDecoding( diff --git a/src/sources/soundsourcemp3.h b/src/sources/soundsourcemp3.h index d29616f8981a..9eb2fbd70430 100644 --- a/src/sources/soundsourcemp3.h +++ b/src/sources/soundsourcemp3.h @@ -66,7 +66,14 @@ class SoundSourceMp3: public SoundSource { SINT m_curFrameIndex; + // NOTE(uklotzde): Each invocation of initDecoding() must be + // followed by an invocation of finishDecoding(). In between + // 2 matching invocations restartDecoding() might invoked any + // number of times, but only if the files has been opened + // successfully. + void initDecoding(); SINT restartDecoding(const SeekFrameType& seekFrame); + void finishDecoding(); // MAD decoder mad_stream m_madStream; diff --git a/src/sources/soundsourcesndfile.cpp b/src/sources/soundsourcesndfile.cpp index efa04cdfb2e7..50170b2a113c 100644 --- a/src/sources/soundsourcesndfile.cpp +++ b/src/sources/soundsourcesndfile.cpp @@ -22,15 +22,15 @@ SoundSourceSndFile::~SoundSourceSndFile() { Result SoundSourceSndFile::tryOpen(const AudioSourceConfig& /*audioSrcCfg*/) { DEBUG_ASSERT(!m_pSndFile); - memset(&m_sfInfo, 0, sizeof(m_sfInfo)); #ifdef __WINDOWS__ // Pointer valid until string changed const QString fileName(getLocalFileName()); LPCWSTR lpcwFilename = (LPCWSTR) fileName.utf16(); m_pSndFile = sf_wchar_open(lpcwFilename, SFM_READ, &m_sfInfo); #else - m_pSndFile = sf_open(getLocalFileNameBytes().constData(), SFM_READ, - &m_sfInfo); + SF_INFO sfInfo; + memset(&sfInfo, 0, sizeof(sfInfo)); + m_pSndFile = sf_open(getLocalFileNameBytes().constData(), SFM_READ, &sfInfo); #endif if (!m_pSndFile) { // sf_format_check is only for writes @@ -45,9 +45,9 @@ Result SoundSourceSndFile::tryOpen(const AudioSourceConfig& /*audioSrcCfg*/) { return ERR; } - setChannelCount(m_sfInfo.channels); - setFrameRate(m_sfInfo.samplerate); - setFrameCount(m_sfInfo.frames); + setChannelCount(sfInfo.channels); + setFrameRate(sfInfo.samplerate); + setFrameCount(sfInfo.frames); return OK; } diff --git a/src/sources/soundsourcesndfile.h b/src/sources/soundsourcesndfile.h index 81e8824fe78d..cec8a6156150 100644 --- a/src/sources/soundsourcesndfile.h +++ b/src/sources/soundsourcesndfile.h @@ -31,7 +31,6 @@ class SoundSourceSndFile: public Mixxx::SoundSource { Result tryOpen(const AudioSourceConfig& audioSrcCfg) /*override*/; SNDFILE* m_pSndFile; - SF_INFO m_sfInfo; }; } // namespace Mixxx