📄 qmmadplayer.cpp
字号:
/* qmmadplayer.cpp * * $Id: qmmadplayer.cpp,v 1.6.2.2 2002/10/10 21:40:52 kyllingstad Exp $ * * Apollo sound player: http://www.apolloplayer.org * Copyright(C) 2000-2002 Apollo Team. See CREDITS file. * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * The GNU General Public License is also available online at: * * http://www.gnu.org/copyleft/gpl.html */#ifdef ENABLE_MAD#include "qmmadplayer.h"#include <iostream>#include <sys/mman.h>#include <sys/stat.h>#include <unistd.h>extern "C" {#include <mad.h>}#include <qfile.h>/*! \class QmMadPlayer qmmadplayer.h \brief MP3 player that uses the MAD library. MP3 player class that uses the MAD library. The code is based on minimad.c from MAD 0.14b. http://www.mars.org/home/rob/proj/mpeg/ http://sourceforge.net/projects/mad/*//*!*/QmMadPlayer::QmMadPlayer() : QmPlayer(), m_Playing(false), m_Paused(false){ cout << "MAD player ctor" << std::endl;}/*!*/QmMadPlayer::~QmMadPlayer(){}/*! */boolQmMadPlayer::isPlaying() const{ return m_Playing;}/*! */boolQmMadPlayer::isPaused() const{ return m_Paused;}/*! */voidQmMadPlayer::play( const QString &Filename){ m_Filename = Filename; QFile file(Filename); if(file.exists() == false || file.size() == 0 || file.open(IO_ReadOnly) == false) return; std::cerr << "mad play: " << m_Filename << " " << file.handle() << std::endl; // Map file into memory. void *fdm = mmap(0, file.size(), PROT_READ, MAP_SHARED, file.handle(), 0); if(fdm == MAP_FAILED) { std::cerr << "MAP failed.\n"; return; } decode(reinterpret_cast<const unsigned char*>(fdm), file.size()); if(munmap(fdm, file.size()) == -1) { std::cerr << "munmap failed.\n"; return; } m_Playing = true;}/*voidQmMadPlayer::map(QFile &file){}voidQmMadPlayer::unmap(QFile &file){}*//*! */voidQmMadPlayer::play(){ play(m_Filename);}/*! */voidQmMadPlayer::stop(){}/*! */voidQmMadPlayer::pause(){}/*! */voidQmMadPlayer::restart(){}/*! */voidQmMadPlayer::jump( int pos ){}/*! Decode buffer. */voidQmMadPlayer::decode( unsigned char const *start, unsigned long length){ struct buffer buffer; struct mad_decoder decoder; buffer.start = start; buffer.length = length; /* configure input, output, and error functions */ mad_decoder_init(&decoder, &buffer, QmMadPlayer::input, 0 /* header */, 0 /* filter */, 0 /*QmMadPlayer::output*/, QmMadPlayer::error, 0 /* message */); /* start the decoder */ mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC); mad_decoder_finish(&decoder); }/*! Called when more input is needed; refill stream buffer.*/ enum mad_flowQmMadPlayer::input( void *data, struct mad_stream *stream){ struct buffer *buffer = reinterpret_cast<struct buffer*>(data); if ( ! buffer->length) return MAD_FLOW_STOP; mad_stream_buffer(stream, buffer->start, buffer->length); buffer->length = 0; return MAD_FLOW_CONTINUE;}/*! \warning The following routine performs simple rounding, clipping, and scaling of MAD's high-resolution samples down to 16 bits. It does not perform any dithering or noise shaping, which would be recommended to obtain any exceptional audio quality. It is therefore not recommended to use this routine if high-quality output is desired.*/ signed intQmMadPlayer::scale( mad_fixed_t sample){ /* round */ sample += (1L << (MAD_F_FRACBITS - 16)); /* clip */ if (sample >= MAD_F_ONE) sample = MAD_F_ONE - 1; else if (sample < -MAD_F_ONE) sample = -MAD_F_ONE; /* quantize */ return sample >> (MAD_F_FRACBITS + 1 - 16);}/*! Called to process output*/ enum mad_flowQmMadPlayer::output( void *data, struct mad_header const *header, struct mad_pcm *pcm){ unsigned int nchannels, nsamples; mad_fixed_t const *left_ch, *right_ch; // pcm->samplerate contains the sampling frequency nchannels = pcm->channels; nsamples = pcm->length; left_ch = pcm->samples[0]; right_ch = pcm->samples[1]; while (nsamples--) { signed int sample; // output sample(s) in 16-bit signed little-endian PCM sample = scale(*left_ch++); putchar((sample >> 0) & 0xff); putchar((sample >> 8) & 0xff); if (nchannels == 2) { sample = scale(*right_ch++); putchar((sample >> 0) & 0xff); putchar((sample >> 8) & 0xff); } } return MAD_FLOW_CONTINUE;}/*! Called to handle a decoding error*/ enum mad_flowQmMadPlayer::error( void *data, struct mad_stream *stream, struct mad_frame *frame){ struct buffer *buffer = reinterpret_cast<struct buffer*>(data); fprintf(stderr, "decoding error 0x%04x at byte offset %u\n", stream->error, stream->this_frame - buffer->start); return MAD_FLOW_STOP;}#endif // ENABLE_MAD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -