llaudiodecodemgr.cpp

Go to the documentation of this file.
00001 
00031 #include "linden_common.h"
00032 
00033 #include "llaudiodecodemgr.h"
00034 
00035 #include "vorbisdecode.h"
00036 #include "audioengine.h"
00037 #include "lllfsthread.h"
00038 #include "llvfile.h"
00039 #include "llstring.h"
00040 #include "lldir.h"
00041 #include "llendianswizzle.h"
00042 #include "audioengine.h"
00043 #include "llassetstorage.h"
00044 
00045 #include "vorbis/codec.h"
00046 #include "vorbis/vorbisfile.h"
00047 
00048 extern LLAudioEngine *gAudiop;
00049 
00050 LLAudioDecodeMgr *gAudioDecodeMgrp = NULL;
00051 
00052 static const S32 WAV_HEADER_SIZE = 44;
00053 
00054 
00056 
00057 
00058 class LLVorbisDecodeState : public LLRefCount
00059 {
00060 public:
00061         class WriteResponder : public LLLFSThread::Responder
00062         {
00063         public:
00064                 WriteResponder(LLVorbisDecodeState* decoder) : mDecoder(decoder) {}
00065                 ~WriteResponder() {}
00066                 void completed(S32 bytes)
00067                 {
00068                         mDecoder->ioComplete(bytes);
00069                 }
00070                 LLPointer<LLVorbisDecodeState> mDecoder;
00071         };
00072         
00073         LLVorbisDecodeState(const LLUUID &uuid, const LLString &out_filename);
00074 
00075         BOOL initDecode();
00076         BOOL decodeSection(); // Return TRUE if done.
00077         BOOL finishDecode();
00078 
00079         void flushBadFile();
00080 
00081         void ioComplete(S32 bytes)                      { mBytesRead = bytes; }
00082         BOOL isValid() const                            { return mValid; }
00083         BOOL isDone() const                                     { return mDone; }
00084         const LLUUID &getUUID() const           { return mUUID; }
00085 
00086 protected:
00087         virtual ~LLVorbisDecodeState();
00088 
00089         BOOL mValid;
00090         BOOL mDone;
00091         LLAtomicS32 mBytesRead;
00092         LLUUID mUUID;
00093 
00094         std::vector<U8> mWAVBuffer;
00095 #if !defined(USE_WAV_VFILE)
00096         LLString mOutFilename;
00097         LLLFSThread::handle_t mFileHandle;
00098 #endif
00099         
00100         LLVFile *mInFilep;
00101         OggVorbis_File mVF;
00102         S32 mCurrentSection;
00103 };
00104 
00105 size_t vfs_read(void *ptr, size_t size, size_t nmemb, void *datasource)
00106 {
00107         LLVFile *file = (LLVFile *)datasource;
00108 
00109         if (file->read((U8*)ptr, (S32)(size * nmemb)))  /*Flawfinder: ignore*/
00110         {
00111                 S32 read = file->getLastBytesRead();
00112                 return  read / size;    /*Flawfinder: ignore*/
00113         }
00114         else
00115         {
00116                 return 0;
00117         }
00118 }
00119 
00120 int vfs_seek(void *datasource, ogg_int64_t offset, int whence)
00121 {
00122         LLVFile *file = (LLVFile *)datasource;
00123 
00124         // vfs has 31-bit files
00125         if (offset > S32_MAX)
00126         {
00127                 return -1;
00128         }
00129 
00130         S32 origin;
00131         switch (whence) {
00132         case SEEK_SET:
00133                 origin = 0;
00134                 break;
00135         case SEEK_END:
00136                 origin = file->getSize();
00137                 break;
00138         case SEEK_CUR:
00139                 origin = -1;
00140                 break;
00141         default:
00142                 llerrs << "Invalid whence argument to vfs_seek" << llendl;
00143                 return -1;
00144         }
00145 
00146         if (file->seek((S32)offset, origin))
00147         {
00148                 return 0;
00149         }
00150         else
00151         {
00152                 return -1;
00153         }
00154 }
00155 
00156 int vfs_close (void *datasource)
00157 {
00158         LLVFile *file = (LLVFile *)datasource;
00159         delete file;
00160         return 0;
00161 }
00162 
00163 long vfs_tell (void *datasource)
00164 {
00165         LLVFile *file = (LLVFile *)datasource;
00166         return file->tell();
00167 }
00168 
00169 LLVorbisDecodeState::LLVorbisDecodeState(const LLUUID &uuid, const LLString &out_filename)
00170 {
00171         mDone = FALSE;
00172         mValid = FALSE;
00173         mBytesRead = -1;
00174         mUUID = uuid;
00175         mInFilep = NULL;
00176         mCurrentSection = 0;
00177 #if !defined(USE_WAV_VFILE)
00178         mOutFilename = out_filename;
00179         mFileHandle = LLLFSThread::nullHandle();
00180 #endif
00181         // No default value for mVF, it's an ogg structure?
00182 }
00183 
00184 LLVorbisDecodeState::~LLVorbisDecodeState()
00185 {
00186         if (!mDone)
00187         {
00188                 delete mInFilep;
00189                 mInFilep = NULL;
00190         }
00191 }
00192 
00193 
00194 BOOL LLVorbisDecodeState::initDecode()
00195 {
00196         ov_callbacks vfs_callbacks;
00197         vfs_callbacks.read_func = vfs_read;
00198         vfs_callbacks.seek_func = vfs_seek;
00199         vfs_callbacks.close_func = vfs_close;
00200         vfs_callbacks.tell_func = vfs_tell;
00201 
00202         //llinfos << "Initing decode from vfile: " << mUUID << llendl;
00203 
00204         mInFilep = new LLVFile(gVFS, mUUID, LLAssetType::AT_SOUND);
00205         if (!mInFilep || !mInFilep->getSize())
00206         {
00207                 llwarns << "unable to open vorbis source vfile for reading" << llendl;
00208                 delete mInFilep;
00209                 mInFilep = NULL;
00210                 return FALSE;
00211         }
00212 
00213         int r = ov_open_callbacks(mInFilep, &mVF, NULL, 0, vfs_callbacks);
00214         if(r < 0) 
00215         {
00216                 llwarns << r << " Input to vorbis decode does not appear to be an Ogg bitstream: " << mUUID << llendl;
00217                 return(FALSE);
00218         }
00219         
00220         size_t size_guess = (size_t)ov_pcm_total(&mVF, -1);
00221         vorbis_info* vi = ov_info(&mVF, -1);
00222         size_guess *= vi->channels;
00223         size_guess *= 2;
00224         size_guess += 2048;
00225         mWAVBuffer.reserve(size_guess);
00226         mWAVBuffer.resize(WAV_HEADER_SIZE);
00227 
00228         {
00229                 // write the .wav format header
00230                 //"RIFF"
00231                 mWAVBuffer[0] = 0x52;
00232                 mWAVBuffer[1] = 0x49;
00233                 mWAVBuffer[2] = 0x46;
00234                 mWAVBuffer[3] = 0x46;
00235 
00236                 // length = datalen + 36 (to be filled in later)
00237                 mWAVBuffer[4] = 0x00;
00238                 mWAVBuffer[5] = 0x00;
00239                 mWAVBuffer[6] = 0x00;
00240                 mWAVBuffer[7] = 0x00;
00241 
00242                 //"WAVE"
00243                 mWAVBuffer[8] = 0x57;
00244                 mWAVBuffer[9] = 0x41;
00245                 mWAVBuffer[10] = 0x56;
00246                 mWAVBuffer[11] = 0x45;
00247 
00248                 // "fmt "
00249                 mWAVBuffer[12] = 0x66;
00250                 mWAVBuffer[13] = 0x6D;
00251                 mWAVBuffer[14] = 0x74;
00252                 mWAVBuffer[15] = 0x20;
00253 
00254                 // chunk size = 16
00255                 mWAVBuffer[16] = 0x10;
00256                 mWAVBuffer[17] = 0x00;
00257                 mWAVBuffer[18] = 0x00;
00258                 mWAVBuffer[19] = 0x00;
00259 
00260                 // format (1 = PCM)
00261                 mWAVBuffer[20] = 0x01;
00262                 mWAVBuffer[21] = 0x00;
00263 
00264                 // number of channels
00265                 mWAVBuffer[22] = 0x01;
00266                 mWAVBuffer[23] = 0x00;
00267 
00268                 // samples per second
00269                 mWAVBuffer[24] = 0x44;
00270                 mWAVBuffer[25] = 0xAC;
00271                 mWAVBuffer[26] = 0x00;
00272                 mWAVBuffer[27] = 0x00;
00273 
00274                 // average bytes per second
00275                 mWAVBuffer[28] = 0x88;
00276                 mWAVBuffer[29] = 0x58;
00277                 mWAVBuffer[30] = 0x01;
00278                 mWAVBuffer[31] = 0x00;
00279 
00280                 // bytes to output at a single time
00281                 mWAVBuffer[32] = 0x02;
00282                 mWAVBuffer[33] = 0x00;
00283                  
00284                 // 16 bits per sample
00285                 mWAVBuffer[34] = 0x10;
00286                 mWAVBuffer[35] = 0x00;
00287 
00288                 // "data"
00289                 mWAVBuffer[36] = 0x64;
00290                 mWAVBuffer[37] = 0x61;
00291                 mWAVBuffer[38] = 0x74;
00292                 mWAVBuffer[39] = 0x61;
00293 
00294                 // these are the length of the data chunk, to be filled in later
00295                 mWAVBuffer[40] = 0x00;
00296                 mWAVBuffer[41] = 0x00;
00297                 mWAVBuffer[42] = 0x00;
00298                 mWAVBuffer[43] = 0x00;
00299         }
00300         
00301         //{
00302                 //char **ptr=ov_comment(&mVF,-1)->user_comments;
00303 //              vorbis_info *vi=ov_info(&vf,-1);
00304                 //while(*ptr){
00305                 //      fprintf(stderr,"%s\n",*ptr);
00306                 //      ++ptr;
00307                 //}
00308 //    fprintf(stderr,"\nBitstream is %d channel, %ldHz\n",vi->channels,vi->rate);
00309 //    fprintf(stderr,"\nDecoded length: %ld samples\n", (long)ov_pcm_total(&vf,-1));
00310 //    fprintf(stderr,"Encoded by: %s\n\n",ov_comment(&vf,-1)->vendor);
00311         //}
00312         return TRUE;
00313 }
00314 
00315 BOOL LLVorbisDecodeState::decodeSection()
00316 {
00317         if (!mInFilep)
00318         {
00319                 llwarns << "No VFS file to decode in vorbis!" << llendl;
00320                 return TRUE;
00321         }
00322         if (mDone)
00323         {
00324 //              llwarns << "Already done with decode, aborting!" << llendl;
00325                 return TRUE;
00326         }
00327         char pcmout[4096];      /*Flawfinder: ignore*/
00328 
00329         BOOL eof = FALSE;
00330         long ret=ov_read(&mVF, pcmout, sizeof(pcmout), 0, 2, 1, &mCurrentSection);
00331         if (ret == 0)
00332         {
00333                 /* EOF */
00334                 eof = TRUE;
00335                 mDone = TRUE;
00336                 mValid = TRUE;
00337 //                      llinfos << "Vorbis EOF" << llendl;
00338         }
00339         else if (ret < 0)
00340         {
00341                 /* error in the stream.  Not a problem, just reporting it in
00342                    case we (the app) cares.  In this case, we don't. */
00343 
00344                 llwarns << "BAD vorbis decode in decodeSection." << llendl;
00345 
00346                 mValid = FALSE;
00347                 mDone = TRUE;
00348                 // We're done, return TRUE.
00349                 return TRUE;
00350         }
00351         else
00352         {
00353 //                      llinfos << "Vorbis read " << ret << "bytes" << llendl;
00354                 /* we don't bother dealing with sample rate changes, etc, but.
00355                    you'll have to*/
00356                 std::copy(pcmout, pcmout+ret, std::back_inserter(mWAVBuffer));
00357         }
00358         return eof;
00359 }
00360 
00361 BOOL LLVorbisDecodeState::finishDecode()
00362 {
00363         if (!isValid())
00364         {
00365                 llwarns << "Bogus vorbis decode state for " << getUUID() << ", aborting!" << llendl;
00366                 return TRUE; // We've finished
00367         }
00368 
00369 #if !defined(USE_WAV_VFILE)     
00370         if (mFileHandle == LLLFSThread::nullHandle())
00371 #endif
00372         {
00373                 ov_clear(&mVF);
00374   
00375                 // write "data" chunk length, in little-endian format
00376                 S32 data_length = mWAVBuffer.size() - WAV_HEADER_SIZE;
00377                 mWAVBuffer[40] = (data_length) & 0x000000FF;
00378                 mWAVBuffer[41] = (data_length >> 8) & 0x000000FF;
00379                 mWAVBuffer[42] = (data_length >> 16) & 0x000000FF;
00380                 mWAVBuffer[43] = (data_length >> 24) & 0x000000FF;
00381                 // write overall "RIFF" length, in little-endian format
00382                 data_length += 36;
00383                 mWAVBuffer[4] = (data_length) & 0x000000FF;
00384                 mWAVBuffer[5] = (data_length >> 8) & 0x000000FF;
00385                 mWAVBuffer[6] = (data_length >> 16) & 0x000000FF;
00386                 mWAVBuffer[7] = (data_length >> 24) & 0x000000FF;
00387 
00388                 //
00389                 // FUCK!!! Vorbis encode/decode messes up loop point transitions (pop)
00390                 // do a cheap-and-cheesy crossfade 
00391                 //
00392                 {
00393                         S16 *samplep;
00394                         S32 i;
00395                         S32 fade_length;
00396                         char pcmout[4096];              /*Flawfinder: ignore*/  
00397 
00398                         fade_length = llmin((S32)128,(S32)(data_length-36)/8);                  
00399                         if((S32)mWAVBuffer.size() >= (WAV_HEADER_SIZE + 2* fade_length))
00400                         {
00401                                 memcpy(pcmout, &mWAVBuffer[WAV_HEADER_SIZE], (2 * fade_length));        /*Flawfinder: ignore*/
00402                         }
00403                         llendianswizzle(&pcmout, 2, fade_length);
00404         
00405                         samplep = (S16 *)pcmout;
00406                         for (i = 0 ;i < fade_length; i++)
00407                         {
00408                                 *samplep = llfloor((F32)*samplep * ((F32)i/(F32)fade_length));
00409                                 samplep++;
00410                         }
00411 
00412                         llendianswizzle(&pcmout, 2, fade_length);                       
00413                         if((WAV_HEADER_SIZE+(2 * fade_length)) < (S32)mWAVBuffer.size())
00414                         {
00415                                 memcpy(&mWAVBuffer[WAV_HEADER_SIZE], pcmout, (2 * fade_length));        /*Flawfinder: ignore*/
00416                     }
00417                         S32 near_end = mWAVBuffer.size() - (2 * fade_length);
00418                         if ((S32)mWAVBuffer.size() >= ( near_end + 2* fade_length))
00419                         {
00420                                 memcpy(pcmout, &mWAVBuffer[near_end], (2 * fade_length));       /*Flawfinder: ignore*/
00421                     }
00422                         llendianswizzle(&pcmout, 2, fade_length);
00423 
00424                         samplep = (S16 *)pcmout;
00425                         for (i = fade_length-1 ; i >=  0; i--)
00426                         {
00427                                 *samplep = llfloor((F32)*samplep * ((F32)i/(F32)fade_length));
00428                                 samplep++;
00429                         }
00430         
00431                         llendianswizzle(&pcmout, 2, fade_length);                       
00432                         if (near_end + (2 * fade_length) < (S32)mWAVBuffer.size())
00433                         {
00434                                 memcpy(&mWAVBuffer[near_end], pcmout, (2 * fade_length));/*Flawfinder: ignore*/
00435                         }
00436                 }
00437 
00438                 if (36 == data_length)
00439                 {
00440                         llwarns << "BAD Vorbis decode in finishDecode!" << llendl;
00441                         mValid = FALSE;
00442                         return TRUE; // we've finished
00443                 }
00444 #if !defined(USE_WAV_VFILE)
00445                 mBytesRead = -1;
00446                 mFileHandle = LLLFSThread::sLocal->write(mOutFilename, &mWAVBuffer[0], 0, data_length,
00447                                                                                                  new WriteResponder(this));
00448 #endif
00449         }
00450 
00451         if (mFileHandle != LLLFSThread::nullHandle())
00452         {
00453                 if (mBytesRead >= 0)
00454                 {
00455                         if (mBytesRead == 0)
00456                         {
00457                                 llwarns << "Unable to write file in LLVorbisDecodeState::finishDecode" << llendl;
00458                                 mValid = FALSE;
00459                                 return TRUE; // we've finished
00460                         }
00461                 }
00462                 else
00463                 {
00464                         return FALSE; // not done
00465                 }
00466         }
00467         
00468         mDone = TRUE;
00469 
00470 #if defined(USE_WAV_VFILE)
00471         // write the data.
00472         LLVFile output(gVFS, mUUID, LLAssetType::AT_SOUND_WAV);
00473         output.write(&mWAVBuffer[0], mWAVBuffer.size());
00474 #endif
00475         //llinfos << "Finished decode for " << getUUID() << llendl;
00476 
00477         return TRUE;
00478 }
00479 
00480 void LLVorbisDecodeState::flushBadFile()
00481 {
00482         if (mInFilep)
00483         {
00484                 llwarns << "Flushing bad vorbis file from VFS for " << mUUID << llendl;
00485                 mInFilep->remove();
00486         }
00487 }
00488 
00490 
00491 class LLAudioDecodeMgr::Impl
00492 {
00493         friend class LLAudioDecodeMgr;
00494 public:
00495         Impl() {};
00496         ~Impl() {};
00497 
00498         void processQueue(const F32 num_secs = 0.005);
00499 
00500 protected:
00501         LLLinkedQueue<LLUUID> mDecodeQueue;
00502         LLPointer<LLVorbisDecodeState> mCurrentDecodep;
00503 };
00504 
00505 
00506 void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs)
00507 {
00508         LLUUID uuid;
00509 
00510         LLTimer decode_timer;
00511 
00512         BOOL done = FALSE;
00513         while (!done)
00514         {
00515                 if (mCurrentDecodep)
00516                 {
00517                         BOOL res;
00518 
00519                         // Decode in a loop until we're done or have run out of time.
00520                         while(!(res = mCurrentDecodep->decodeSection()) && (decode_timer.getElapsedTimeF32() < num_secs))
00521                         {
00522                                 // decodeSection does all of the work above
00523                         }
00524 
00525                         if (mCurrentDecodep->isDone() && !mCurrentDecodep->isValid())
00526                         {
00527                                 // We had an error when decoding, abort.
00528                                 llwarns << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << llendl;
00529                                 mCurrentDecodep->flushBadFile();
00530                                 LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
00531                                 adp->setHasValidData(FALSE);
00532                                 mCurrentDecodep = NULL;
00533                                 done = TRUE;
00534                         }
00535 
00536                         if (!res)
00537                         {
00538                                 // We've used up out time slice, bail...
00539                                 done = TRUE;
00540                         }
00541                         else if (mCurrentDecodep)
00542                         {
00543                                 if (mCurrentDecodep->finishDecode())
00544                                 {
00545                                         // We finished!
00546                                         if (mCurrentDecodep->isValid() && mCurrentDecodep->isDone())
00547                                         {
00548                                                 LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
00549                                                 adp->setHasDecodedData(TRUE);
00550                                                 adp->setHasValidData(TRUE);
00551 
00552                                                 // At this point, we could see if anyone needs this sound immediately, but
00553                                                 // I'm not sure that there's a reason to - we need to poll all of the playing
00554                                                 // sounds anyway.
00555                                                 //llinfos << "Finished the vorbis decode, now what?" << llendl;
00556                                         }
00557                                         else
00558                                         {
00559                                                 llinfos << "Vorbis decode failed!!!" << llendl;
00560                                         }
00561                                         mCurrentDecodep = NULL;
00562                                 }
00563                                 done = TRUE; // done for now
00564                         }
00565                 }
00566 
00567                 if (!done)
00568                 {
00569                         if (!mDecodeQueue.getLength())
00570                         {
00571                                 // Nothing else on the queue.
00572                                 done = TRUE;
00573                         }
00574                         else
00575                         {
00576                                 LLUUID uuid;
00577                                 mDecodeQueue.pop(uuid);
00578                                 if (gAudiop->hasDecodedFile(uuid))
00579                                 {
00580                                         // This file has already been decoded, don't decode it again.
00581                                         continue;
00582                                 }
00583 
00584                                 lldebugs << "Decoding " << uuid << " from audio queue!" << llendl;
00585 
00586                                 char uuid_str[64];                      /*Flawfinder: ignore*/
00587                                 char d_path[LL_MAX_PATH];       /*Flawfinder: ignore*/
00588 
00589                                 LLTimer timer;
00590                                 timer.reset();
00591 
00592                                 uuid.toString(uuid_str);
00593                                 snprintf(d_path, LL_MAX_PATH, "%s.dsf", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str).c_str());        /* Flawfinder: ignore */
00594 
00595                                 mCurrentDecodep = new LLVorbisDecodeState(uuid, d_path);
00596                                 if (!mCurrentDecodep->initDecode())
00597                                 {
00598                                         mCurrentDecodep = NULL;
00599                                 }
00600                         }
00601                 }
00602         }
00603 }
00604 
00606 
00607 LLAudioDecodeMgr::LLAudioDecodeMgr()
00608 {
00609         mImpl = new Impl;
00610 }
00611 
00612 LLAudioDecodeMgr::~LLAudioDecodeMgr()
00613 {
00614         delete mImpl;
00615 }
00616 
00617 void LLAudioDecodeMgr::processQueue(const F32 num_secs)
00618 {
00619         mImpl->processQueue(num_secs);
00620 }
00621 
00622 BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid)
00623 {
00624         if (gAudiop->hasDecodedFile(uuid))
00625         {
00626                 // Already have a decoded version, don't need to decode it.
00627                 return TRUE;
00628         }
00629 
00630         if (gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
00631         {
00632                 // Just put it on the decode queue.
00633                 mImpl->mDecodeQueue.push(uuid);
00634                 return TRUE;
00635         }
00636 
00637         return FALSE;
00638 }
00639 
00640 

Generated on Thu Jul 1 06:08:19 2010 for Second Life Viewer by  doxygen 1.4.7