⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oggtremor.h

📁 OggPlay for Symbian 是symbian上的一个媒体播放程序的源码。它支持ogg,wav等等多媒体格式。
💻 H
字号:
/*
 *  Copyright (c) 2003 L. H. Wilden.
 *
 *  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.
 */

#ifndef _OggTremor_h
#define _OggTremor_h

#include "e32des8.h"
#include "eikenv.h"
#include "bassnd.h"
#include "ivorbisfile.h"
#include "OggMsgEnv.h"
#include "OggHelperFcts.h"
#include "OggRateConvert.h"
// V0.2:  3 @ 4096   
// V0.3:  ?
// V0.4:  6 @ 4096*10  (not sure?!)
// V0.5:  3 @ 4096*40
// V0.6:  6 @ 4096*10
// V0.9:  12 @ 4096*10
#include "TremorDecoder.h"
#include "OggAbsPlayback.h"
#include "OggMultiThread.h"


#if defined(MULTI_THREAD_PLAYBACK)

  // Total number of buffers
  const TInt KNoBuffers= 1;
  const TInt KSingleThreadBuffers = 16;
  const TInt KMultiThreadBuffers = 64;

  // The actual number of buffers to use
#if defined(SERIES60V3)
  const TInt KSingleThreadBuffersToUse = 16;
  const TInt KMultiThreadBuffersToUse = 64;
#else
  // Set to one less than KBuffers
  // This is a workaround for a bug in Symbian's buffering code
  // MaoscBufferCopied gets called before it has actually copied the buffer
  const TInt KSingleThreadBuffersToUse = 15;
  const TInt KMultiThreadBuffersToUse = 63;
#endif

  // Number of buffers to fetch before starting playback (one seems to be enough)
  const TInt KPreBuffers = 1;

  // Number of buffers to keep in the audio stream (provides a small amount of underflow protection)
  const TInt KSingleThreadStreamBuffers = 3;
  const TInt KMultiThreadStreamBuffers = 5;

  // Number of buffers to fetch before transferring the buffering to the buffering thread
  const TInt KPrimeBuffers = 12;

  // Number of buffers required to cause the thread priority of the buffering thread to be reduced
  // The buffering thread priority will remain at a reduced level as long as the number of buffers remains above KBufferLowThreshold
  const TInt KBufferThreadHighThreshold = 32;

  // Number of buffers required to cause the thread priority of the buffering thread to be increased
  // The buffering thread priority will remain at an increased level until the number of buffers reaches KBufferHighThreshold
  const TInt KBufferThreadLowThreshold = 10;

  // The number of buffers at which to resume buffering
  const TInt KSingleThreadLowThreshold = 5;
  const TInt KMultiThreadLowThreshold = 16;

#else // ! MULTI_THREAD_PLAYBACK

#if defined(SERIES60)
  const TInt KBuffers= 2;
  const TInt KBufferSize = 4096;
#else
  const TInt KBuffers= 12;
  const TInt KBufferSize = 4096*10;
#endif

#endif // ! MULTI_THREAD_PLAYBACK

#if defined(SERIES60)
  const TInt KAudioPriority = 70; // S60 audio players typically uses 60-75.
#elif !defined(MOTOROLA)
  const TInt KAudioPriority = EMdaPriorityMax;
#endif

  // Buffer sizes to use
  // (approx. 0.1s of audio per buffer)
  const TInt KBufferSize48K = 16384;
  const TInt KBufferSize32K = 12288;
  const TInt KBufferSize22K = 8192;
  const TInt KBufferSize16K = 6144;
  const TInt KBufferSize11K = 4096;

// frequency of canvas Refresh() for graphics updating - need to get FreqBin
const TInt KOggControlFreq = 14;

// Stream start delays
// Avoid buffer underflows at stream startup and stop multiple starts when the user moves quickly between tracks
const TInt KStreamStartDelay = 100000;
const TInt KSendoStreamStartDelay = 275000;

// Stream stop delay
// OggPlay doesn't wait for a play complete message so wait a little while before "stopping"
const TInt KStreamStopDelay = 100000;

// Stream restart delay (the time to wait after running out of buffers before attempting to play again)
const TInt KStreamRestartDelay = 100000;


#if defined(MOTOROLA)
#include "OggTremor_Motorola.h"
#else

#include "mdaaudiooutputstream.h"
#include "mda/common/audio.h"
#include "OggThreadClasses.h"

// COggPlayback:
// An implementation of CAbsPlayback for the Ogg/Vorbis format:
//-------------------------------------------------------------

#if defined(MULTI_THREAD_PLAYBACK)
class TStreamingThreadData;
class CStreamingThreadCommandHandler;
class CBufferingThreadAO;
class CStreamingThreadListener;
class COggPlayback : public CAbsPlayback, public MOggSampleRateFillBuffer, public MThreadPanicObserver
#else
class COggPlayback : public CAbsPlayback, public MMdaAudioOutputStreamCallback, public MOggSampleRateFillBuffer
#endif
{
public: 
  COggPlayback(COggMsgEnv* anEnv, MPlaybackObserver* anObserver = NULL);
  virtual ~COggPlayback();
  void ConstructL();

  virtual TInt   Info(const TDesC& aFileName, TBool silent= EFalse);
  virtual TInt   Open(const TDesC& aFileName);

  virtual void   Pause();
  virtual void   Play(); 
  virtual void   Resume();
  virtual void   Stop();

  virtual void   SetVolume(TInt aVol);
  virtual void   SetPosition(TInt64 aPos);

  virtual TInt64 Position();
  virtual TInt64 Time();
  virtual TInt   Volume();

#ifdef MDCT_FREQ_ANALYSER
  virtual const TInt32 * GetFrequencyBins();
#else
  virtual const void* GetDataChunk();
#endif

  virtual TInt GetNewSamples(TDes8 &aBuffer, TBool aRequestFrequencyBins);
  virtual void SetVolumeGain(TGainType aGain);

private:
  TBool GetNextLowerRate(TInt& usedRate, TMdaAudioDataSettings::TAudioCaps& rt);
  TInt SetAudioCaps(TInt theChannels, TInt theRate);

  void SamplingRateSupportedMessage(TBool aConvertRate, TInt aRate, TBool aConvertChannel, TInt aNbOfChannels);
  MDecoder* GetDecoderL(const TDesC& aFileName);

  COggMsgEnv*               iEnv;
  COggSampleRateConverter *iOggSampleRateConverter;

   // There is something wrong with Nokia Audio Streaming (NGage)
   // First buffers are somehow swallowed.
   // To avoid that, wait a short time before streaming, so that AppView
   // draw have been done. Also send few empty (zeroed) buffers .
  TInt iFirstBuffers;

  void StartAudioStreamingCallBack();
  static TInt StartAudioStreamingCallBack(TAny* aPtr);
  COggTimer* iStartAudioStreamingTimer;

  void RestartAudioStreamingCallBack();
  static TInt RestartAudioStreamingCallBack(TAny* aPtr);
  COggTimer* iRestartAudioStreamingTimer;

  void StopAudioStreamingCallBack();
  static TInt StopAudioStreamingCallBack(TAny* aPtr);
  COggTimer* iStopAudioStreamingTimer;

  void CancelTimers();

#ifdef MDCT_FREQ_ANALYSER
#if ! defined(MULTI_THREAD_PLAYBACK)
   TReal  iLatestPlayTime;
   TReal  iTimeBetweenTwoSamples;
#endif
   
class TFreqBins 
{
public:
    TInt64 iPcmByte;
    TInt32 iFreqCoefs[KNumberOfFreqBins];
};

  TFreqBins iFreqArray[KFreqArrayLength];
  TInt iLastFreqArrayIdx;

  TInt64 iLastPlayTotalBytes, iLastPlayBufferBytes;
  TBool iRequestingFrequencyBins;
  TInt iBytesSinceLastFrequencyBin, iMaxBytesBetweenFrequencyBins;
#endif

  // Communication with the decoder
  // ------------------------------
  RFile*                   iFile;

  TInt iOutStreamByteRate;  // for converting time/position in buffers
  TBool                     iEof; // true after ov_read has encounted the eof

  MDecoder*             iDecoder;

  // Machine uid (for identifying the phone model)
  TInt iMachineUid;
  RFs iFs;

#if defined(MULTI_THREAD_PLAYBACK)
public:
  TBool PrimeBuffer(HBufC8& buf);

  TInt SetBufferingMode(TBufferingMode aNewBufferingMode);
  void SetThreadPriority(TStreamingThreadPriority aNewThreadPriority);

  TBool FlushBuffers(TFlushBufferEvent aFlushBufferEvent);
  TBool FlushBuffers(TInt64 aNewPosition);
  void FlushBuffers(TGainType aNewGain);

  void SetDecoderPosition(TInt64 aPos);
  void SetSampleRateConverterVolumeGain(TGainType aGain);

  void NotifyOpenComplete(TInt aErr);
  void NotifyStreamingStatus(TInt aErr);

public:
  HBufC8* iBuffer[KMultiThreadBuffers];

private:
  TInt AttachToFs();

  TInt SetAudioProperties(TInt aSampleRate, TInt aChannels);
  void StartStreaming();
  void StopStreaming();

  TInt BufferingModeChanged();

  static TInt StreamingThread(TAny* aThreadData);
  static void StreamingThreadL(TStreamingThreadData& aSharedData);

  // From MThreadPanicHandler 
  void HandleThreadPanic(RThread& aPanicThread, TInt aErr);

private:
  TBool iStreamingErrorDetected;

  RThread iThread;
  RThread iUIThread;
  RThread iBufferingThread;
  RThread iStreamingThread;

  CThreadPanicHandler* iStreamingThreadPanicHandler;
  CStreamingThreadCommandHandler* iStreamingThreadCommandHandler;
  CBufferingThreadAO* iBufferingThreadAO;
  CStreamingThreadListener* iStreamingThreadListener;

  TBool iStreamingThreadRunning;
  TStreamingThreadData iSharedData;
#else
  void SendBuffer(HBufC8& buf);

  // these are abstract methods in MMdaAudioOutputStreamCallback:
  virtual void MaoscPlayComplete(TInt aErr);
  virtual void MaoscBufferCopied(TInt aErr, const TDesC8& aBuffer);
  virtual void MaoscOpenComplete(TInt aErr);

  // communication with symbian's media streaming framework:
  //--------------------------------------------------------
  CMdaAudioOutputStream*   iStream;
  TMdaAudioDataSettings    iSettings;
  HBufC8* iBuffer[KBuffers];
  HBufC8* iSent[KBuffers];
  TInt iMaxVolume;
  TInt iSentIdx;

  TBool iUnderflowing;
  TInt iFirstUnderflowBuffer;
  TInt iLastUnderflowBuffer;
#endif
};
    
#endif // !MOTOROLA
#endif // _OggTremor_h

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -