00001
00032 #include "linden_common.h"
00033
00034 #include "vorbis/codec.h"
00035 #include "vorbis/vorbisfile.h"
00036 #include "llerror.h"
00037 #include "llmath.h"
00038 #include "llvfile.h"
00039
00040 #if 0
00041
00042 size_t vfs_read(void *ptr, size_t size, size_t nmemb, void *datasource)
00043 {
00044 LLVFile *file = (LLVFile *)datasource;
00045
00046 if (size > 0 && file->read((U8*)ptr, size * nmemb))
00047 {
00048 S32 read = file->getLastBytesRead();
00049 return read / size;
00050 }
00051 else
00052 {
00053 return 0;
00054 }
00055 }
00056
00057 int vfs_seek(void *datasource, ogg_int64_t offset, int whence)
00058 {
00059 LLVFile *file = (LLVFile *)datasource;
00060
00061
00062 if (offset > S32_MAX)
00063 {
00064 return -1;
00065 }
00066
00067 S32 origin;
00068 switch (whence) {
00069 case SEEK_SET:
00070 origin = 0;
00071 break;
00072 case SEEK_END:
00073 origin = file->getSize();
00074 break;
00075 case SEEK_CUR:
00076 origin = -1;
00077 break;
00078 default:
00079 llerrs << "Invalid whence argument to vfs_seek" << llendl;
00080 return -1;
00081 }
00082
00083 if (file->seek((S32)offset, origin))
00084 {
00085 return 0;
00086 }
00087 else
00088 {
00089 return -1;
00090 }
00091 }
00092
00093 int vfs_close (void *datasource)
00094 {
00095 LLVFile *file = (LLVFile *)datasource;
00096
00097 delete file;
00098
00099 return 0;
00100 }
00101
00102 long vfs_tell (void *datasource)
00103 {
00104 LLVFile *file = (LLVFile *)datasource;
00105
00106 return file->tell();
00107 }
00108
00109
00110 BOOL decode_vorbis_file(LLVFS *vfs, const LLUUID &in_uuid, char *out_fname)
00111 {
00112 ov_callbacks vfs_callbacks;
00113 vfs_callbacks.read_func = vfs_read;
00114 vfs_callbacks.seek_func = vfs_seek;
00115 vfs_callbacks.close_func = vfs_close;
00116 vfs_callbacks.tell_func = vfs_tell;
00117
00118 char pcmout[4096];
00119
00120 unsigned char temp[64];
00121
00122 LLVFile *in_vfile;
00123
00124 U32 data_length = 0;
00125
00126 llinfos << "Vorbis decode from vfile: " << in_uuid << llendl;
00127
00128 in_vfile = new LLVFile(vfs, in_uuid, LLAssetType::AT_SOUND);
00129 if (! in_vfile->getSize())
00130 {
00131 llwarning("unable to open vorbis source vfile for reading",0);
00132 return(FALSE);
00133 }
00134 apr_file_t* outfp = ll_apr_file_open(out_fname,LL_APR_WPB);
00135 if (!outfp)
00136 {
00137 llwarning("unable to open vorbis destination file for writing",0);
00138 return(FALSE);
00139 }
00140 else
00141 {
00142
00143
00144 temp[0] = 0x52;
00145 temp[1] = 0x49;
00146 temp[2] = 0x46;
00147 temp[3] = 0x46;
00148
00149
00150 temp[4] = 0x00;
00151 temp[5] = 0x00;
00152 temp[6] = 0x00;
00153 temp[7] = 0x00;
00154
00155
00156 temp[8] = 0x57;
00157 temp[9] = 0x41;
00158 temp[10] = 0x56;
00159 temp[11] = 0x45;
00160
00161
00162 temp[12] = 0x66;
00163 temp[13] = 0x6D;
00164 temp[14] = 0x74;
00165 temp[15] = 0x20;
00166
00167
00168 temp[16] = 0x10;
00169 temp[17] = 0x00;
00170 temp[18] = 0x00;
00171 temp[19] = 0x00;
00172
00173
00174 temp[20] = 0x01;
00175 temp[21] = 0x00;
00176
00177
00178 temp[22] = 0x01;
00179 temp[23] = 0x00;
00180
00181
00182 temp[24] = 0x44;
00183 temp[25] = 0xAC;
00184 temp[26] = 0x00;
00185 temp[27] = 0x00;
00186
00187
00188 temp[28] = 0x88;
00189 temp[29] = 0x58;
00190 temp[30] = 0x01;
00191 temp[31] = 0x00;
00192
00193
00194 temp[32] = 0x02;
00195 temp[33] = 0x00;
00196
00197
00198 temp[34] = 0x10;
00199 temp[35] = 0x00;
00200
00201
00202 temp[36] = 0x64;
00203 temp[37] = 0x61;
00204 temp[38] = 0x74;
00205 temp[39] = 0x61;
00206
00207
00208
00209 temp[40] = 0x00;
00210 temp[41] = 0x00;
00211 temp[42] = 0x00;
00212 temp[43] = 0x00;
00213
00214
00215 ll_apr_file_write(outfp, temp, 44);
00216 }
00217
00218 OggVorbis_File vf;
00219 int eof=0;
00220 int current_section;
00221
00222 int r = ov_open_callbacks(in_vfile, &vf, NULL, 0, vfs_callbacks);
00223 if(r < 0)
00224 {
00225 llwarns << r << " Input to vorbis decode does not appear to be an Ogg bitstream: " << in_uuid << llendl;
00226 return(FALSE);
00227 }
00228
00229 {
00230 char **ptr=ov_comment(&vf,-1)->user_comments;
00231
00232 while(*ptr){
00233 fprintf(stderr,"%s\n",*ptr);
00234 ++ptr;
00235 }
00236
00237
00238
00239 }
00240
00241 while(!eof){
00242 long ret=ov_read(&vf,pcmout,sizeof(pcmout),0,2,1,¤t_section);
00243 if (ret == 0) {
00244
00245 eof=1;
00246
00247 } else if (ret < 0) {
00248
00249
00250 llwarning("Error in vorbis stream",0);
00251 break;
00252
00253 } else {
00254
00255
00256
00257 data_length += ll_apr_file_write(outfp, pcmout, ret);
00258 }
00259 }
00260
00261 ov_clear(&vf);
00262
00263
00264 ll_apr_file_seek(outfp,APR_SET,40);
00265 ll_apr_file_write(outfp,&data_length,4);
00266
00267
00268 data_length += 36;
00269 ll_apr_file_seek(outfp,APR_SET,4);
00270 ll_apr_file_write(outfp,&data_length,1*4);
00271
00272
00273
00274
00275
00276 S16 *samplep;
00277 S32 i;
00278 S32 fade_length;
00279
00280 fade_length = llmin((S32)128,(S32)(data_length-36)/8);
00281
00282 ll_apr_file_seek(outfp,APR_SET,44);
00283 ll_apr_file_read(outfp, pcmout,2*fade_length);
00284
00285 samplep = (S16 *)pcmout;
00286
00287 for (i = 0 ;i < fade_length; i++)
00288 {
00289 *samplep++ = ((F32)*samplep * ((F32)i/(F32)fade_length));
00290 }
00291
00292 ll_apr_file_seek(outfp,APR_SET,44);
00293 ll_apr_file_write(outfp,pcmout,2*fade_length);
00294
00295 ll_apr_file_seek(outfp,APR_END,-fade_length*2);
00296 ll_apr_file_read(outfp, pcmout,2*fade_length);
00297
00298 samplep = (S16 *)pcmout;
00299
00300 for (i = fade_length-1 ; i >= 0; i--)
00301 {
00302 *samplep++ = ((F32)*samplep * ((F32)i/(F32)fade_length));
00303 }
00304
00305 ll_apr_file_seek(outfp,SEEK_END,-fade_length*2);
00306 ll_apr_file_write(outfp,pcmout,2*fade_length);
00307
00308 apr_file_close(outfp);
00309
00310 if ((36 == data_length) || (!(eof)))
00311 {
00312 llwarning("BAD Vorbis DECODE!, removing .wav!",0);
00313 LLFile::remove(out_fname);
00314 return (FALSE);
00315 }
00316
00317
00318
00319 return(TRUE);
00320 }
00321 #endif