S32 ll_apr_file_read_ex(const std::string& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes) { if (pool == NULL) pool = gAPRPoolp; apr_file_t* filep = ll_apr_file_open(filename, APR_READ|APR_BINARY, pool); if (!filep) { return 0; } S32 off; if (offset < 0) off = ll_apr_file_seek(filep, APR_END, 0); else off = ll_apr_file_seek(filep, APR_SET, offset); S32 bytes_read; if (off < 0) { bytes_read = 0; } else { bytes_read = ll_apr_file_read(filep, buf, nbytes ); } apr_file_close(filep); return bytes_read; }
bool LLLFSThread::Request::processRequest() { bool complete = false; if (mOperation == FILE_READ) { llassert(mOffset >= 0); apr_file_t* filep = ll_apr_file_open(mFileName, LL_APR_RB, mThread->mAPRPoolp); if (!filep) { llwarns << "LLLFS: Unable to read file: " << mFileName << llendl; mBytesRead = 0; // fail return true; } S32 off; if (mOffset < 0) off = ll_apr_file_seek(filep, APR_END, 0); else off = ll_apr_file_seek(filep, APR_SET, mOffset); llassert_always(off >= 0); mBytesRead = ll_apr_file_read(filep, mBuffer, mBytes ); apr_file_close(filep); complete = true; // llinfos << "LLLFSThread::READ:" << mFileName << " Bytes: " << mBytesRead << llendl; } else if (mOperation == FILE_WRITE) { apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY; if (mOffset < 0) flags |= APR_APPEND; apr_file_t* filep = ll_apr_file_open(mFileName, flags, mThread->mAPRPoolp); if (!filep) { llwarns << "LLLFS: Unable to write file: " << mFileName << llendl; mBytesRead = 0; // fail return true; } if (mOffset >= 0) { S32 seek = ll_apr_file_seek(filep, APR_SET, mOffset); if (seek < 0) { apr_file_close(filep); llwarns << "LLLFS: Unable to write file (seek failed): " << mFileName << llendl; mBytesRead = 0; // fail return true; } } mBytesRead = ll_apr_file_write(filep, mBuffer, mBytes ); complete = true; apr_file_close(filep); // llinfos << "LLLFSThread::WRITE:" << mFileName << " Bytes: " << mBytesRead << "/" << mBytes << " Offset:" << mOffset << llendl; } else { llerrs << "LLLFSThread::unknown operation: " << (S32)mOperation << llendl; } return complete; }
S32 ll_apr_file_write_ex(const std::string& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes) { if (pool == NULL) pool = gAPRPoolp; apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY; if (offset < 0) { flags |= APR_APPEND; offset = 0; } apr_file_t* filep = ll_apr_file_open(filename, flags, pool); if (!filep) { return 0; } if (offset > 0) { offset = ll_apr_file_seek(filep, APR_SET, offset); } S32 bytes_written; if (offset < 0) { bytes_written = 0; } else { bytes_written = ll_apr_file_write(filep, buf, nbytes ); } apr_file_close(filep); return bytes_written; }
BOOL decode_vorbis_file(LLVFS *vfs, const LLUUID &in_uuid, char *out_fname) { ov_callbacks vfs_callbacks; vfs_callbacks.read_func = vfs_read; vfs_callbacks.seek_func = vfs_seek; vfs_callbacks.close_func = vfs_close; vfs_callbacks.tell_func = vfs_tell; char pcmout[4096]; /*Flawfinder: ignore*/ unsigned char temp[64]; /*Flawfinder: ignore*/ LLVFile *in_vfile; U32 data_length = 0; llinfos << "Vorbis decode from vfile: " << in_uuid << llendl; in_vfile = new LLVFile(vfs, in_uuid, LLAssetType::AT_SOUND); if (! in_vfile->getSize()) { llwarning("unable to open vorbis source vfile for reading",0); return(FALSE); } apr_file_t* outfp = ll_apr_file_open(out_fname,LL_APR_WPB); if (!outfp) { llwarning("unable to open vorbis destination file for writing",0); return(FALSE); } else { // write the .wav format header //"RIFF" temp[0] = 0x52; temp[1] = 0x49; temp[2] = 0x46; temp[3] = 0x46; // length = datalen + 36 (to be filled in later) temp[4] = 0x00; temp[5] = 0x00; temp[6] = 0x00; temp[7] = 0x00; //"WAVE" temp[8] = 0x57; temp[9] = 0x41; temp[10] = 0x56; temp[11] = 0x45; // "fmt " temp[12] = 0x66; temp[13] = 0x6D; temp[14] = 0x74; temp[15] = 0x20; // chunk size = 16 temp[16] = 0x10; temp[17] = 0x00; temp[18] = 0x00; temp[19] = 0x00; // format (1 = PCM) temp[20] = 0x01; temp[21] = 0x00; // number of channels temp[22] = 0x01; temp[23] = 0x00; // samples per second temp[24] = 0x44; temp[25] = 0xAC; temp[26] = 0x00; temp[27] = 0x00; // average bytes per second temp[28] = 0x88; temp[29] = 0x58; temp[30] = 0x01; temp[31] = 0x00; // bytes to output at a single time temp[32] = 0x02; temp[33] = 0x00; // 16 bits per sample temp[34] = 0x10; temp[35] = 0x00; // "data" temp[36] = 0x64; temp[37] = 0x61; temp[38] = 0x74; temp[39] = 0x61; // these are the length of the data chunk, to be filled in later temp[40] = 0x00; temp[41] = 0x00; temp[42] = 0x00; temp[43] = 0x00; ll_apr_file_write(outfp, temp, 44); } OggVorbis_File vf; int eof=0; int current_section; int r = ov_open_callbacks(in_vfile, &vf, NULL, 0, vfs_callbacks); if(r < 0) { llwarns << r << " Input to vorbis decode does not appear to be an Ogg bitstream: " << in_uuid << llendl; return(FALSE); } { char **ptr=ov_comment(&vf,-1)->user_comments; // vorbis_info *vi=ov_info(&vf,-1); while(*ptr){ fprintf(stderr,"%s\n",*ptr); ++ptr; } // fprintf(stderr,"\nBitstream is %d channel, %ldHz\n",vi->channels,vi->rate); // fprintf(stderr,"\nDecoded length: %ld samples\n", (long)ov_pcm_total(&vf,-1)); // fprintf(stderr,"Encoded by: %s\n\n",ov_comment(&vf,-1)->vendor); } while(!eof){ long ret=ov_read(&vf,pcmout,sizeof(pcmout),0,2,1,¤t_section); if (ret == 0) { /* EOF */ eof=1; // llinfos << "Vorbis EOF" << llendl; } else if (ret < 0) { /* error in the stream. Not a problem, just reporting it in case we (the app) cares. In this case, we don't. */ llwarning("Error in vorbis stream",0); break; } else { // llinfos << "Vorbis read " << ret << "bytes" << llendl; /* we don't bother dealing with sample rate changes, etc, but. you'll have to*/ data_length += ll_apr_file_write(outfp, pcmout, ret); } } ov_clear(&vf); // write "data" chunk length ll_apr_file_seek(outfp,APR_SET,40); ll_apr_file_write(outfp,&data_length,4); // write overall "RIFF" length data_length += 36; ll_apr_file_seek(outfp,APR_SET,4); ll_apr_file_write(outfp,&data_length,1*4); // F**K!!! Vorbis encode/decode messes up loop point transitions (pop) // do a cheap-and-cheesy crossfade S16 *samplep; S32 i; S32 fade_length; fade_length = llmin((S32)128,(S32)(data_length-36)/8); ll_apr_file_seek(outfp,APR_SET,44); ll_apr_file_read(outfp, pcmout,2*fade_length); //read first 16 samples samplep = (S16 *)pcmout; for (i = 0 ;i < fade_length; i++) { *samplep++ = ((F32)*samplep * ((F32)i/(F32)fade_length)); } ll_apr_file_seek(outfp,APR_SET,44); ll_apr_file_write(outfp,pcmout,2*fade_length); //write back xfaded first 16 samples ll_apr_file_seek(outfp,APR_END,-fade_length*2); ll_apr_file_read(outfp, pcmout,2*fade_length); //read last 16 samples samplep = (S16 *)pcmout; for (i = fade_length-1 ; i >= 0; i--) { *samplep++ = ((F32)*samplep * ((F32)i/(F32)fade_length)); } ll_apr_file_seek(outfp,SEEK_END,-fade_length*2); ll_apr_file_write(outfp,pcmout,2*fade_length); //write back xfaded last 16 samples apr_file_close(outfp); if ((36 == data_length) || (!(eof))) { llwarning("BAD Vorbis DECODE!, removing .wav!",0); LLFile::remove(out_fname); return (FALSE); } // fprintf(stderr,"Done.\n"); return(TRUE); }