00001
00002
00003
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
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
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
00190
00191 TInt length = 0;
00192 while (iComment.vendor[length])
00193 {
00194 ++length;
00195 }
00196
00197 iVendor = HBufC::NewL(length);
00198 TPtr ven = iVendor->Des();
00199 ven.SetLength(length);
00200
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
00250
00251 TInt CVorbisInfo::CBody::TranslateOggVorbisError(TInt aError)
00252 {
00253
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
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
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
00327 User::Leave(KErrCorrupt);
00328 }
00329
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
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 }