VedaLibSoundMP3/MP3SoundObject.h

Go to the documentation of this file.
00001 #ifndef COM_M4NKIND_MP3SoundObject_H
00002 #define COM_M4NKIND_MP3SoundObject_H
00003 /*! \file 
00004     \author victorien ferry & www.m4nkind.com
00005     \brief This file applies the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1 , read file COPYING.
00006 */
00007 #include "VirtualMedia.h"
00008 #include "PackResource.h"
00009 
00010 struct mad_decoder;
00011 struct mad_stream;
00012 struct mad_header;
00013 struct mad_frame;
00014 struct mad_synth;
00015 
00016 /*!
00017     \class  MP3SoundObject
00018     \ingroup BaseObjectInherited_VedaLibSoundMP3
00019     \brief  Class defining a MP3SoundObject to play. 
00020 */
00021 class MP3SoundObject : public VirtualMedia
00022 {
00023 /*==================================================================
00024                                 PUBLIC
00025 ==================================================================*/
00026 public:
00027     /*!
00028         \brief  Constructor. There should only be members initialisation there.
00029     */
00030     MP3SoundObject(void);
00031 
00032     /*!
00033         \brief  Class Inheritance Descriptors.
00034     */
00035     BASEOBJECT_DEFINE_CLASS(MP3SoundObject);
00036 
00037     /*!
00038         \brief   Process a media at a given date, 
00039                 or do anything) using a machine. You must process the media on machine this->GetMachine().
00040                 Note there are no play/pause or speed concept here, by default, a date is passed.
00041 
00042         \param  _frameDate a date, in second, which defines the effect cinematic.
00043         \param  _pViewPort the viewport to render. Can't be 0L.
00044     */
00045     virtual void ProcessMedia( double _frameDate,VirtualMachine::InternalViewPort *_pViewPort );
00046 
00047     /*!
00048         \brief   If the media had to generate real time sounds, 
00049                 ProcessSoundInterupt will be called by a machine. There is a default 
00050                 behaviour for this method, which does nothing. the float buffer 
00051                 accumulate the whole machine sound.
00052         \param  _SoundBufferToAddYourSignal description of the buffer to fill.
00053     */
00054     virtual void ProcessSoundInterupt( VirtualMachine::SoundBufferToAddYourSignal &_SoundBufferToAddYourSignal );
00055 
00056 /*==================================================================
00057                                 PROTECTED
00058 ==================================================================*/
00059 protected:
00060     //! the mp3 file:
00061     PackResource        mSer_MP3File;
00062     //! the mad input stream.
00063     struct mad_stream *m_pstream;
00064     //! the mad valid frame.
00065     struct mad_frame *m_pframe;
00066     //! the mad frame synthetiser.
00067     struct mad_synth *m_psynth;
00068 
00069     /*!
00070         \brief  Method that really build the object using the serializable parameters.
00071                 Close() should close everything opened by CreateInternal().
00072     */
00073     virtual bool CreateInternal(void);
00074 
00075 #ifdef _ENGINE_EDITABLE_
00076     /*!
00077         \brief  that closes everything. Still, the object exist and can be rebuild the same using Create()
00078     */
00079     virtual void    CloseInternal(void);
00080 #endif
00081     
00082 #ifdef _ENGINE_EDITABLE_
00083     /*!
00084         \brief  Extend this method to draw your preview !
00085                 a GUI could need to play, draw, print, or output from any way, a preview of a 
00086                 created object.sub classes can implement it (or not) in
00087                 any way, to explicit current shape of an object.
00088                 _pPreviewConfiguration can be read to follow  <br>          
00089 
00090         \param  _frameDate a date, in second, which defines the effect cinematic.
00091         \param  _pPreviewViewPort the viewport to render. Can't be 0L.
00092         \param  _pPreviewConfiguration Preview Configuration object. Never 0L. Do not keep a pointer to it.
00093     */
00094     virtual void ProcessPreview(double _frameDate,VirtualMachine::InternalViewPort *_pViewPort,const PreviewConfiguration *_pPreviewConfiguration);
00095 #endif
00096     //! total number of frames in the whole MP3 File, and size of ;
00097     unsigned    int m_NumberOfFrame;
00098     /*
00099         \struct FrameReference
00100         \brief  element of the frame reference table.
00101     */
00102     typedef struct {
00103         //! pointer to the begining chunk:
00104         unsigned char const *m_pFrameStart;
00105         //! time that correspond to the start of the frame, in milliseconds.
00106         unsigned int        m_TimeStart;
00107     } FrameReference;
00108     //! table that reference the frames in the MP3 binary. Created at init. Size is m_NumberOfFrame +1
00109     FrameReference  *m_pFrameReferenceTable;
00110 
00111     //! input
00112     static const unsigned int   m_InputStreamLength=1024*16;
00113     //! the whole input file.
00114     unsigned char const *m_pInputStart;
00115     //! the whole input length.
00116     unsigned long       m_InputLength;
00117     //! the current input stream position. 
00118     //unsigned char const *m_pCurrentInputStart;
00119     //! the rest of the file to stream.
00120     //unsigned long     m_CurrentInputLength;
00121     //! last frame index in m_pFrameReferenceTable, (which is current played.)
00122     //! if m_LastFrameIndex>=m_NumberOfFrame, we are after the song (silence.)
00123     //! if m_LastFrameIndex=0 we are at start.
00124     unsigned int        m_LastFrameIndex;
00125 
00126     //! output
00127     unsigned int m_nchannels;
00128     unsigned int m_nsamples;
00129     unsigned int m_samplerate;
00130     signed int const *m_pleft_ch;
00131     signed int const *m_pright_ch;
00132     // the synth left to run:
00133     int m_nsamplesRunner;
00134     signed int const *m_pleft_chRunner;
00135     signed int const *m_pright_chRunner;
00136     //! <<16
00137     unsigned int            m_RunnerVector;
00138     //! <<16
00139     unsigned int            m_RunnerIndex;
00140         
00141     //int   m_debugZeroedCase;
00142     /*
00143         \brief  Continue stream feed if stream not finished.
00144         \return true if feed OK, else if no more feed.
00145     */
00146     bool    FeedStream();
00147     /*
00148         \brief  If stream time is not synchro, reset the stream:
00149                 it will set it to the closest frame, which means
00150                 it has more or less a time error under 1/4 second.
00151                 it allows time-free random access.
00152         \param  _milliseconds
00153     */
00154     void    SeekStream(int _milliseconds);
00155 
00156     /*
00157         \brief tool used privately to determine full time length quickly:
00158     */
00159     static bool head_check(unsigned long head);
00160     /*
00161         \struct RawFrame
00162         \brief  used privately to determine full time length quickly:
00163     */
00164     struct RawFrame
00165     {
00166         int lsf;
00167         int mpeg25;
00168         int lay;
00169         int bitrate_index;
00170         int sampling_frequency;
00171         int padding;
00172         int framesize;
00173     };
00174     /*
00175         \brief  tool used privately to determine full time length quickly:
00176     */
00177     static int decode_header(struct RawFrame *fr, unsigned long newhead);
00178 };
00179 
00180 #endif

      /\/\        4         N         k         !         N         D
                      _______  _ __ ___  _____            ___ _ _  ____
     ___________  __//___   /________  |/    / ___________\_______/    \
    /   _   _   \/   _     /    _   /      _/_/____/    _       __     /
   /    /   /       /     /    /    \      \/     /    /    \   \     /
  \\___/___/___/    ¯    _____/_____/       ______\___/_____/\________\\
               \________/_ ___ __ l____\      /elD!  
                 http://www.m4nkind.com \____/