From a53a04badd824b8037999d401a7c34cb8e482ef1 Mon Sep 17 00:00:00 2001 From: trialuser02 Date: Fri, 29 Dec 2017 21:43:20 +0000 Subject: removed mad and mpg123 plugins git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7812 90c681e8-e032-0410-971d-27865f9a5e38 --- src/plugins/Input/mad/decoder_mad.cpp | 554 ---------------------------------- 1 file changed, 554 deletions(-) delete mode 100644 src/plugins/Input/mad/decoder_mad.cpp (limited to 'src/plugins/Input/mad/decoder_mad.cpp') diff --git a/src/plugins/Input/mad/decoder_mad.cpp b/src/plugins/Input/mad/decoder_mad.cpp deleted file mode 100644 index 6f57cdc6b..000000000 --- a/src/plugins/Input/mad/decoder_mad.cpp +++ /dev/null @@ -1,554 +0,0 @@ -/*************************************************************************** - * Based on mq3 and madplay projects * - * * - * Copyright (c) 2000-2001 Brad Hughes * - * Copyright (C) 2000-2004 Robert Leslie * - * Copyright (C) 2009-2017 Ilya Kotov forkotov02@ya.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - ***************************************************************************/ - -#include -#include -#include -#include -#include "tagextractor.h" -#include "decoder_mad.h" - -#define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g') -#define XING_MAGIC2 (('I' << 24) | ('n' << 16) | ('f' << 8) | 'o') -#define LAME_MAGIC (('L' << 24) | ('A' << 16) | ('M' << 8) | 'E') -#define INPUT_BUFFER_SIZE (32*1024) - -DecoderMAD::DecoderMAD(QIODevice *i) : Decoder(i) -{ - m_inited = false; - m_totalTime = 0; - m_channels = 0; - m_bitrate = 0; - m_freq = 0; - m_len = 0; - m_input_buf = 0; - m_input_bytes = 0; - m_skip_frames = 0; - m_eof = false; - m_skip_bytes = 0; - m_play_bytes = -1; -} - -DecoderMAD::~DecoderMAD() -{ - deinit(); - if (m_input_buf) - { - qDebug("DecoderMAD: deleting input_buf"); - delete [] m_input_buf; - m_input_buf = 0; - } -} - -bool DecoderMAD::initialize() -{ - m_inited = false; - m_totalTime = 0; - m_channels = 0; - m_bitrate = 0; - m_freq = 0; - m_len = 0; - m_input_bytes = 0; - - if (!input()) - { - qWarning("DecoderMAD: cannot initialize. No input."); - return false; - } - - if (!m_input_buf) - m_input_buf = new char[INPUT_BUFFER_SIZE]; - - if (input()->isSequential ()) //for streams only - { - TagExtractor extractor(input()); - if(!extractor.id3v2tag().isEmpty()) - addMetaData(extractor.id3v2tag()); - } - - mad_stream_init(&m_stream); - mad_frame_init(&m_frame); - mad_synth_init(&m_synth); - - if (!findHeader()) - { - qDebug("DecoderMAD: Can't find a valid MPEG header."); - return false; - } - mad_stream_buffer(&m_stream, (unsigned char *) m_input_buf, m_input_bytes); - m_stream.error = MAD_ERROR_BUFLEN; - mad_frame_mute (&m_frame); - m_stream.next_frame = 0; - m_stream.sync = 0; - ChannelMap map; - if(m_channels == 1) - map << Qmmp::CHAN_FRONT_LEFT; - else - map << Qmmp::CHAN_FRONT_LEFT << Qmmp::CHAN_FRONT_RIGHT; - configure(m_freq, map, Qmmp::PCM_FLOAT); - m_inited = true; - return true; -} - -void DecoderMAD::deinit() -{ - if (!m_inited) - return; - - mad_synth_finish(&m_synth); - mad_frame_finish(&m_frame); - mad_stream_finish(&m_stream); - - m_inited = false; - m_totalTime = 0; - m_channels = 0; - m_bitrate = 0; - m_freq = 0; - m_len = 0; - m_input_bytes = 0; - m_skip_frames = 0; - m_eof = false; - if(m_xing.lame) - { - delete m_xing.lame; - m_xing.lame = 0; - } -} - -bool DecoderMAD::findXingHeader(struct mad_bitptr ptr, unsigned int bitlen) -{ - if (bitlen < 64) - return false; - - quint32 xing_magic = mad_bit_read(&ptr, 32); - if(xing_magic != XING_MAGIC && xing_magic != XING_MAGIC2) - return false; - - m_xing.flags = mad_bit_read(&ptr, 32); - bitlen -= 64; - - if (m_xing.flags & XING_FRAMES) - { - if (bitlen < 32) - return false; - - m_xing.frames = mad_bit_read(&ptr, 32); - bitlen -= 32; - - if(!m_xing.frames) - { - qDebug("DecoderMAD: invalid xing header (zero number of frames)"); - return false; - } - } - - if (m_xing.flags & XING_BYTES) - { - if (bitlen < 32) - return false; - - m_xing.bytes = mad_bit_read(&ptr, 32); - bitlen -= 32; - - if(!m_xing.bytes) - { - qDebug("DecoderMAD: invalid xing header (zero number of bytes)"); - return false; - } - } - - if (m_xing.flags & XING_TOC) - { - if (bitlen < 800) - return false; - - for (int i = 0; i < 100; ++i) - m_xing.toc[i] = mad_bit_read(&ptr, 8); - - bitlen -= 800; - } - - if (m_xing.flags & XING_SCALE) - { - if (bitlen < 32) - return false; - - m_xing.scale = mad_bit_read(&ptr, 32); - bitlen -= 32; - } - - m_xing.lame = findLameHeader(ptr, bitlen); - return true; -} - -DecoderMAD::LameHeader* DecoderMAD::findLameHeader(mad_bitptr ptr, unsigned int bitlen) -{ - if(bitlen < 272) - return 0; - - if(mad_bit_read (&ptr, 32) != LAME_MAGIC) - return 0; - - LameHeader header; - mad_bit_skip (&ptr, 40); //version - - header.revision = mad_bit_read (&ptr, 4); - if (header.revision == 15) - return 0; - - mad_bit_skip(&ptr, 12); //VBR,Lowpass filter value - header.peak = mad_bit_read(&ptr, 32) << 5; //Peak amplitude - mad_bit_skip(&ptr, 32); //Replay Gain - mad_bit_skip(&ptr, 16); //Encoding flags, ATH Type, bitrate - header.start_delay = mad_bit_read (&ptr, 12); //Start delay - header.end_padding = mad_bit_read (&ptr, 12); //End padding - mad_bit_skip (&ptr, 8); //Misc - header.gain = mad_bit_read (&ptr, 8); //MP3 Gain - mad_bit_skip (&ptr, 64); //Preset and surroud info, MusicLength, Music CRC - return new LameHeader(header); -} - -bool DecoderMAD::findHeader() -{ - bool result = false; - int count = 0; - bool has_xing = false; - bool is_vbr = false; - mad_timer_t duration = mad_timer_zero; - struct mad_header header; - mad_header_init (&header); - uint id3v2Size = 0; - - forever - { - m_input_bytes = 0; - if (m_stream.error == MAD_ERROR_BUFLEN || !m_stream.buffer) - { - size_t remaining = 0; - - if (m_stream.next_frame) - { - remaining = m_stream.bufend - m_stream.next_frame; - memmove (m_input_buf, m_stream.next_frame, remaining); - } - - m_input_bytes = input()->read(m_input_buf + remaining, INPUT_BUFFER_SIZE - remaining); - - if (m_input_bytes <= 0) - break; - - mad_stream_buffer(&m_stream, (unsigned char *) m_input_buf + remaining, m_input_bytes); - m_stream.error = MAD_ERROR_NONE; - } - - if (mad_header_decode(&header, &m_stream) < 0) - { - if(m_stream.error == MAD_ERROR_LOSTSYNC) - { - uint tagSize = findID3v2((uchar *)m_stream.this_frame, - (ulong) (m_stream.bufend - m_stream.this_frame)); - if (tagSize > 0) - { - mad_stream_skip(&m_stream, tagSize); - id3v2Size = tagSize; - } - continue; - } - else if (m_stream.error == MAD_ERROR_BUFLEN || MAD_RECOVERABLE(m_stream.error)) - continue; - else - { - qDebug ("DecoderMAD: Can't decode header: %s", mad_stream_errorstr(&m_stream)); - break; - } - } - result = true; - - if (input()->isSequential()) - break; - - count ++; - //try to detect xing header - if (count == 1) - { - m_frame.header = header; - if (mad_frame_decode(&m_frame, &m_stream) != -1 && - findXingHeader(m_stream.anc_ptr, m_stream.anc_bitlen)) - { - is_vbr = true; - - qDebug("DecoderMAD: Xing header found"); - - if (m_xing.flags & XING_FRAMES) - { - has_xing = true; - count = m_xing.frames; - - if(m_xing.lame) - { - qDebug("DecoderMAD: LAME header found"); - m_skip_bytes = m_xing.lame->start_delay * sizeof(float) * MAD_NCHANNELS(&header); - m_play_bytes = (m_xing.frames * 1152 - m_xing.lame->start_delay - m_xing.lame->end_padding) * - sizeof(float) * MAD_NCHANNELS(&header); - qDebug("DecoderMAD: samples to skip: %d, padding: %d", - m_xing.lame->start_delay, m_xing.lame->end_padding); - } - break; - } - } - } - //try to detect VBR - if (!is_vbr && !(count > 15)) - { - if (m_bitrate && header.bitrate != m_bitrate) - { - qDebug ("DecoderMAD: VBR detected"); - is_vbr = true; - } - else - m_bitrate = header.bitrate; - } - else if (!is_vbr) - { - qDebug ("DecoderMAD: Fixed rate detected"); - break; - } - mad_timer_add (&duration, header.duration); - } - - if (!result) - return false; - - if (!is_vbr && !input()->isSequential()) - { - double time = ((input()->size() - id3v2Size) * 8.0) / (header.bitrate); - double timefrac = (double)time - ((long)(time)); - mad_timer_set(&duration, (long)time, (long)(timefrac*100), 100); - } - else if (has_xing) - { - mad_timer_multiply (&header.duration, count); - duration = header.duration; - } - - m_totalTime = mad_timer_count(duration, MAD_UNITS_MILLISECONDS); - qDebug ("DecoderMAD: Total time: %ld", long(m_totalTime)); - m_freq = header.samplerate; - m_channels = MAD_NCHANNELS(&header); - m_bitrate = header.bitrate / 1000; - mad_header_finish(&header); - input()->seek(0); - m_input_bytes = 0; - return true; -} - -qint64 DecoderMAD::totalTime() const -{ - if (!m_inited) - return 0; - return m_totalTime; -} - -int DecoderMAD::bitrate() const -{ - return int(m_bitrate); -} - -qint64 DecoderMAD::read(unsigned char *data, qint64 size) -{ - while(m_skip_bytes > 0) - { - if(!decodeFrame()) - return 0; - - qint64 l = madOutputFloat((float*)data, size / sizeof(float)) * sizeof(float); - - if(m_skip_bytes > l) - { - m_skip_bytes -= l; - continue; - } - else if(m_skip_bytes < l) - { - l -= m_skip_bytes; - memmove(data, data + m_skip_bytes, l); - m_skip_bytes = 0; - m_play_bytes -= l; - return l; - } - } - - if(!decodeFrame()) - return 0; - - qint64 l = madOutputFloat((float*)data, size / sizeof(float)) * sizeof(float); - - if(m_play_bytes > 0) - { - if(m_play_bytes > l) - m_play_bytes -= l; - else - { - l -= m_play_bytes; - m_play_bytes = 0; - } - - } - return l; -} - -void DecoderMAD::seek(qint64 pos) -{ - if(m_totalTime > 0) - { - qint64 seek_pos = qint64(pos * input()->size() / m_totalTime); - input()->seek(seek_pos); - mad_frame_mute(&m_frame); - mad_synth_mute(&m_synth); - m_stream.error = MAD_ERROR_BUFLEN; - m_stream.sync = 0; - m_input_bytes = 0; - m_stream.next_frame = 0; - m_skip_frames = 2; - m_skip_bytes = 0; - m_play_bytes = -1; - } -} - -bool DecoderMAD::fillBuffer() -{ - if (m_stream.next_frame) - { - m_input_bytes = &m_input_buf[m_input_bytes] - (char *) m_stream.next_frame; - memmove(m_input_buf, m_stream.next_frame, m_input_bytes); - } - int len = input()->read((char *) m_input_buf + m_input_bytes, INPUT_BUFFER_SIZE - m_input_bytes); - if (!len) - { - qDebug("DecoderMAD: end of file"); - return false; - } - else if(len < 0) - { - qWarning("DecoderMAD: error"); - return false; - } - m_input_bytes += len; - mad_stream_buffer(&m_stream, (unsigned char *) m_input_buf, m_input_bytes); - return true; -} - -uint DecoderMAD::findID3v2(uchar *data, ulong size) //retuns ID3v2 tag size -{ - if (size < 10) - return 0; - - if (((data[0] == 'I' && data[1] == 'D' && data[2] == '3') || //ID3v2 tag - (data[0] == '3' && data[1] == 'D' && data[2] == 'I')) && //ID3v2 footer - data[3] < 0xff && data[4] < 0xff && data[6] < 0x80 && - data[7] < 0x80 && data[8] < 0x80 && data[9] < 0x80) - { - TagLib::ByteVector byteVector((char *)data, size); - TagLib::ID3v2::Header header(byteVector); - return header.tagSize(); - } - return 0; -} - -bool DecoderMAD::decodeFrame() -{ - forever - { - if(((m_stream.error == MAD_ERROR_BUFLEN) || !m_stream.buffer) && !m_eof) - { - m_eof = !fillBuffer(); - } - if(mad_frame_decode(&m_frame, &m_stream) < 0) - { - switch((int) m_stream.error) - { - case MAD_ERROR_LOSTSYNC: - { - //skip ID3v2 tag - uint tagSize = findID3v2((uchar *)m_stream.this_frame, - (ulong) (m_stream.bufend - m_stream.this_frame)); - if (tagSize > 0) - { - mad_stream_skip(&m_stream, tagSize); - qDebug("DecoderMAD: %d bytes skipped", tagSize); - } - continue; - } - case MAD_ERROR_BUFLEN: - if(m_eof) - return false; - continue; - default: - if (!MAD_RECOVERABLE(m_stream.error)) - return false; - else - continue; - } - } - if(m_skip_frames) - { - m_skip_frames--; - continue; - } - mad_synth_frame(&m_synth, &m_frame); - break; - } - return true; -} - -qint64 DecoderMAD::madOutputFloat(float *data, qint64 samples) -{ - float *data_it = data; - unsigned int samples_per_channel, channels; - mad_fixed_t const *left, *right; - - samples_per_channel = m_synth.pcm.length; - channels = m_synth.pcm.channels; - left = m_synth.pcm.samples[0]; - right = m_synth.pcm.samples[1]; - m_bitrate = m_frame.header.bitrate / 1000; - qint64 output_samples = 0; - - if(samples_per_channel * channels > samples) - { - qWarning("DecoderMad: input buffer is too small"); - samples_per_channel = samples / channels; - } - - while (samples_per_channel--) - { - *data_it++ = mad_f_todouble(*left++); - output_samples++; - if (channels == 2) - { - *data_it++ = mad_f_todouble(*right++); - output_samples++; - } - } - return output_samples; -} -- cgit v1.2.3-13-gbd6f