examples/sfexamples/oggvorbiscodec/src/OggVorbisUtil/VorbisInfo.cpp

00001 // VorbisInfo.cpp
00002 //
00003 // Copyright (c) Symbian Software Ltd 2005-2008.  All rights reserved.
00004 //
00005 
00006 
00007 #include <e32base.h>
00008 
00009 #include <oggutil.h>
00010 #include "OggUtilBody.h"
00011 #include <vorbisinfo.h>
00012 #include "VorbisBody.h"
00013 
00014 #ifdef SYMBIAN_CODEC_FLOAT_POINT
00015 #include "vorbis/codec.h"
00016 #include "vorbis/vorbisenc.h"
00017 #else
00018 #include "tremor/ivorbiscodec.h"
00019 #endif
00020 
00021 //-------------------------- CVorbisInfo --------------------------
00022 
00023 EXPORT_C CVorbisInfo* CVorbisInfo::NewL()
00024     {
00025     CVorbisInfo* self = new(ELeave)CVorbisInfo;
00026     CleanupStack::PushL(self);
00027     self->ConstructL();
00028     CleanupStack::Pop(self);
00029     return self;
00030     }
00031 
00032 CVorbisInfo::CVorbisInfo()
00033     {
00034     }
00035 
00036 void CVorbisInfo::ConstructL()
00037     {
00038     iBody = new(ELeave)CBody;
00039     iBody->Construct3L();
00040     }
00041 
00042 CVorbisInfo::~CVorbisInfo()
00043     {
00044     delete iBody;
00045     }
00046 
00047 EXPORT_C void CVorbisInfo::InitializeL(const TOggPacket& aPckt1,
00048                                        const TOggPacket& aPckt2,
00049                                        const TOggPacket& aPckt3)
00050     {
00051     iBody->InitializeL(aPckt1);
00052     iBody->InitializeL(aPckt2);
00053     iBody->InitializeL(aPckt3);
00054     }
00055 
00056 EXPORT_C void CVorbisInfo::InitializeL(const TOggPacket& aNextPacket)
00057     {
00058     iBody->InitializeL(aNextPacket);
00059     }
00060 
00061 EXPORT_C void CVorbisInfo::InitializeL(TUint aSampleRate, TUint aBitRate, TUint aNumChannels)
00062     {
00063     return iBody->InitializeL(aSampleRate, aBitRate, aNumChannels);
00064     }
00065     
00066 EXPORT_C TInt CVorbisInfo::SampleRate()
00067     {
00068     return iBody->SampleRate();
00069     }
00070 
00071 EXPORT_C TInt CVorbisInfo::Channels()
00072     {
00073     return iBody->Channels();
00074     }
00075 
00076 EXPORT_C TDesC& CVorbisInfo::Vendor()
00077     {
00078     return iBody->Vendor();
00079     }
00080 
00081 EXPORT_C TInt CVorbisInfo::Comments()
00082     {
00083     return iBody->Comments();
00084     }
00085 
00086 EXPORT_C CVorbisComment& CVorbisInfo::GetComment(TInt aIndex)
00087     {
00088     return iBody->GetComment(aIndex);
00089     }
00090 
00091 EXPORT_C TInt CVorbisInfo::BitRateNominal()
00092     {
00093     return iBody->BitRateNominal();
00094     }
00095 
00096 EXPORT_C TInt CVorbisInfo::BitRateUpper()
00097     {
00098     return iBody->BitRateUpper();
00099     }
00100 
00101 EXPORT_C TInt CVorbisInfo::BitRateLower()
00102     {
00103     return iBody->BitRateLower();
00104     }
00105 
00106 EXPORT_C void CVorbisInfo::SetSampleRate(TUint aSampleRate)
00107     {
00108     iBody->SetSampleRate(aSampleRate);
00109     }
00110 EXPORT_C void CVorbisInfo::SetChannels(TUint aChannels)
00111     {
00112     iBody->SetChannels(aChannels);
00113     }
00114 EXPORT_C void CVorbisInfo::SetBitRate(TUint aBitRate)
00115     {
00116     iBody->SetBitRate(aBitRate);
00117     }
00118 
00119 //---------------------- CVorbisInfo::CBody -----------------------
00120 
00121 CVorbisInfo::CBody::CBody()
00122     : iPcktsRcvd(0)
00123     {
00124     }
00125 
00126 CVorbisInfo::CBody::~CBody()
00127     {
00128     #ifdef SYMBIAN_CODEC_FLOAT_POINT
00129     vorbis_block_clear(&iBlock);
00130         vorbis_dsp_clear(&iDspState);
00131     #endif
00132     vorbis_comment_clear(&iComment);
00133     vorbis_info_clear(&iInfo);
00134 
00135     for (TInt i=0; i<iComments->Count(); ++i)
00136         {
00137         delete (*iComments)[i]; 
00138         }
00139     delete iComments;
00140     delete iVendor;
00141     }
00142 
00143 void CVorbisInfo::CBody::Construct3L()
00144     {
00145     vorbis_comment_init(&iComment);
00146     vorbis_info_init(&iInfo);
00147 
00148     iComments = new(ELeave)CArrayPtrFlat<CVorbisComment>(1);
00149     }
00150 
00151 void CVorbisInfo::CBody::InitializeL(const TOggPacket& aNextPacket)
00152     {
00153     if (iPcktsRcvd==KPcktsRqrd) 
00154         {
00155         User::Leave(KErrAlreadyExists); 
00156         }
00157     ogg_packet packet;
00158     OggUtil::Make_ogg_packet(aNextPacket, packet);
00159     TInt err = vorbis_synthesis_headerin(&iInfo, &iComment, &packet);
00160     
00161     if (err != KErrNone)
00162         {
00163         User::Leave(TranslateOggVorbisError(err));
00164         }
00165     ++iPcktsRcvd;
00166     if (iPcktsRcvd==KPcktsRqrd) 
00167         {
00168         ConvertCommentDataL();  
00169         }
00170     }
00171 
00172 void CVorbisInfo::CBody::InitializeL(TUint aSampleRate, TUint aBitRate, TUint aNumChannels)
00173     {
00174     iInfo.rate = aSampleRate;
00175     iInfo.bitrate_nominal = aBitRate;
00176     iInfo.channels = aNumChannels;
00177     }
00178     
00179 void CVorbisInfo::CBody::ConvertCommentDataL()
00180     {
00181     iComments->SetReserveL(iComment.comments);
00182     for (TInt i=0; i<iComment.comments; ++i)
00183         {
00184         iComments->ExtendL() =
00185           CVorbisComment::NewL(iComment.user_comments[i],
00186                                iComment.comment_lengths[i]);
00187         }
00188 
00189     // convert vendor to a descriptor...
00190     // work out how long it is
00191     TInt length = 0;
00192     while (iComment.vendor[length]) 
00193         {
00194         ++length;       
00195         }
00196     // allocate space
00197     iVendor = HBufC::NewL(length);
00198     TPtr ven = iVendor->Des();
00199     ven.SetLength(length);
00200     // copy and convert to 16-bit
00201     for (TInt i=0; i<length; ++i) 
00202         {
00203         ven[i]=iComment.vendor[i];      
00204         }
00205     }
00206 
00207 
00208 TInt CVorbisInfo::CBody::SampleRate()
00209     {
00210     return iInfo.rate;
00211     }
00212 
00213 TInt CVorbisInfo::CBody::Channels()
00214     {
00215     return iInfo.channels;
00216     }
00217 
00218 TDesC& CVorbisInfo::CBody::Vendor()
00219     {
00220     return *iVendor;
00221     }
00222 
00223 TInt CVorbisInfo::CBody::Comments()
00224     {
00225     return iComments->Count();
00226     }
00227 
00228 CVorbisComment& CVorbisInfo::CBody::GetComment(TInt aIndex)
00229     {
00230     return *(iComments->At(aIndex));
00231     }
00232 
00233 TInt CVorbisInfo::CBody::BitRateNominal()
00234     {
00235     return iInfo.bitrate_nominal;
00236     }
00237 
00238 TInt CVorbisInfo::CBody::BitRateUpper()
00239     {
00240     return iInfo.bitrate_upper;
00241     }
00242 
00243 TInt CVorbisInfo::CBody::BitRateLower()
00244     {
00245     return iInfo.bitrate_lower;
00246     }
00247 
00248 /*
00249  This translates the errors returned by the ogglibaries into the Symbian errors
00250  */
00251 TInt CVorbisInfo::CBody::TranslateOggVorbisError(TInt aError)
00252         {
00253         //reference libvorbis\doc\vorbis-errors.txt
00254         switch (aError)
00255                 {
00256                 case OV_EIMPL:
00257                         return KErrNotSupported;
00258                 case OV_EINVAL:
00259                         return KErrArgument;
00260                 default:
00261                 return KErrUnknown;
00262                 }       
00263         }
00264 
00265 void CVorbisInfo::CBody::SetSampleRate(TUint aSampleRate)
00266     {
00267     iInfo.rate = aSampleRate;
00268     }
00269 void CVorbisInfo::CBody::SetChannels(TUint aNumChannels)
00270     {
00271     iInfo.channels = aNumChannels;
00272     }
00273 void CVorbisInfo::CBody::SetBitRate(TUint aBitRate)
00274     {
00275     iInfo.bitrate_nominal = aBitRate;
00276     }
00277 
00278 //------------------------ CVorbisComment -------------------------
00279 
00280 CVorbisComment* CVorbisComment::NewL(TDesC& aName, TDesC& aValue)
00281     {
00282     CVorbisComment* self = new(ELeave)CVorbisComment;
00283     CleanupStack::PushL(self);
00284     self->ConstructL(aName, aValue);
00285     CleanupStack::Pop(self);
00286     return self;
00287     }
00288 
00289 CVorbisComment* CVorbisComment::NewL(char* aComment, int aLength)
00290     {
00291     CVorbisComment* self = new(ELeave)CVorbisComment;
00292     CleanupStack::PushL(self);
00293     self->ConstructL(aComment, aLength);
00294     CleanupStack::Pop(self);
00295     return self;
00296     }
00297 
00298 CVorbisComment::CVorbisComment()
00299     {
00300     }
00301 
00302 CVorbisComment::~CVorbisComment()
00303     {
00304     delete iName;
00305     delete iValue;
00306     }
00307 
00308 void CVorbisComment::ConstructL(TDesC& aName, TDesC& aValue)
00309     {
00310     iName = aName.AllocL();
00311     iValue = aValue.AllocL();
00312     }
00313 
00314 void CVorbisComment::ConstructL(char* aComment, int aLength)
00315     {
00316     // find the '='
00317     TInt eqPos = -1;
00318     TInt sp = 0;
00319     while ((eqPos<0)&&(sp<aLength))
00320         {
00321         if (aComment[sp]=='=') eqPos=sp;
00322         ++sp;
00323         }
00324     if (eqPos<0) 
00325         {
00326         //comments are in wrong format. So leave with KErrCorrupt
00327         User::Leave(KErrCorrupt);       
00328         }
00329     // allocate memory
00330     iName = HBufC::NewL(eqPos);
00331     iValue = HBufC::NewL(aLength-eqPos-1);
00332 
00333     TPtr name = iName->Des();
00334     TPtr val = iValue->Des();
00335 
00336     // copy data, converting from 8 to 16 bit
00337     name.SetLength(eqPos);
00338     for (TInt i=0; i<eqPos; ++i)
00339         {
00340         name[i]=aComment[i];
00341         }
00342 
00343     val.SetLength(aLength-eqPos-1);
00344     for (TInt i=0; i<val.Length(); ++i)
00345         {
00346         val[i]=aComment[i+eqPos+1];
00347         }
00348     }
00349 
00350 EXPORT_C TDesC& CVorbisComment::Name()
00351     {
00352     return *iName;
00353     }
00354 
00355 EXPORT_C TDesC& CVorbisComment::Value()
00356     {
00357     return *iValue;
00358     }

Generated by  doxygen 1.6.2