123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- #include "main.h"
- #include "../nu/AutoChar.h"
- extern CfgInt cfg_fullbuf;
- int VorbisFile::_f_close(void *) {return 0;}
- int VorbisFile::_f_seek(void* rs,__int64 offset,int whence)
- {
- return ((VorbisFile*)rs)->f_seek(offset,whence);
- }
- size_t VorbisFile::_f_read(void* ptr,size_t size,size_t nmemb,void * rs)
- {
- return ((VorbisFile*)rs)->f_read((UINT)(size*nmemb),ptr);
- }
- long VorbisFile::_f_tell(void* rs)
- {
- return ((VorbisFile*)rs)->f_tell();
- }
- ov_callbacks VorbisFile::oc={_f_read,_f_seek,_f_close,_f_tell};
- static __int64 Seek64(HANDLE hf, __int64 distance, DWORD MoveMethod)
- {
- LARGE_INTEGER li;
- li.QuadPart = distance;
- li.LowPart = SetFilePointer (hf, li.LowPart, &li.HighPart, MoveMethod);
- if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
- {
- li.QuadPart = -1;
- }
- return li.QuadPart;
- }
- static __int64 FileSize64(HANDLE file)
- {
- LARGE_INTEGER position;
- position.QuadPart=0;
- position.LowPart = GetFileSize(file, (LPDWORD)&position.HighPart);
-
- if (position.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
- return INVALID_FILE_SIZE;
- else
- return position.QuadPart;
- }
- class VorbisFile_Local : public VorbisFile
- {
- private:
- HANDLE hFile;
- protected:
- int f_seek(__int64 offset,int whence)
- {
- if(whence==SEEK_SET) offset+=baseoffs;
- if (Seek64(hFile,offset,whence) != INVALID_SET_FILE_POINTER) return 0;
- else return -1;
- }
- size_t f_read(UINT siz,void * ptr)
- {
- DWORD bw=0;
- ReadFile(hFile,ptr,siz,&bw,0);
- return bw;
- }
- UINT f_tell()
- {
- return (UINT)(SetFilePointer(hFile,0,0,FILE_CURRENT)-baseoffs);
- }
- UINT FileSize()
- {
- return (UINT)(FileSize64(hFile)-baseoffs);
- }
- public:
- virtual int GetType() {return TYPE_LOCAL;}
- VorbisFile_Local(HANDLE f,const wchar_t * u,bool is_info) : VorbisFile(u,is_info) {hFile=f;}
- ~VorbisFile_Local() {CloseHandle(hFile);}
- };
- class VorbisFile_Mem : public VorbisFile
- {
- BYTE * block;
- UINT size,ptr;
- protected:
- int f_seek(__int64 offset,int whence)
- {
- switch(whence)
- {
- case SEEK_SET:
- ptr=(UINT)(offset+baseoffs);
- break;
- case SEEK_CUR:
- ptr+=(UINT)offset;
- break;
- case SEEK_END:
- ptr=size+whence;
- break;
- }
- if (ptr<=size) return 0;
- else {ptr=size;return -1;}
- }
- size_t f_read(UINT siz,void * out)
- {
- UINT d=size-ptr;
- if (d>siz) d=siz;
- memcpy(out,block+ptr,d);
- ptr+=d;
- return d;
- }
- UINT f_tell()
- {
- return (UINT)(ptr-baseoffs);
- }
- UINT FileSize()
- {
- return (UINT)(size-baseoffs);
- }
- public:
- virtual int GetType() {return TYPE_LOCAL;}
- VorbisFile_Mem(HANDLE f,const wchar_t * u,bool is_info) : VorbisFile(u,is_info)
- {
- size=GetFileSize(f,0);
- ptr=0;
- block=(BYTE*)malloc(size);
- DWORD br = 0;
- ReadFile(f,block,size,&br,0);
- CloseHandle(f);
- }
- ~VorbisFile_Mem() {free(block);}
- };
- VorbisFile * VorbisFile::Create(const wchar_t *url, bool is_info)
- {
- VorbisFile * r;
- if (PathIsURLW(url))
- {
- if (is_info) return 0;
- r=Create_HTTP(AutoChar(url),is_info);
- }
- else
- {
- __int64 baseoffs=0;
- HANDLE f=CreateFileW(url,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
- if (f==INVALID_HANDLE_VALUE) return 0;
- {
- DWORD dw = 0, br = 0;
- ReadFile(f,&dw,4,&br,0);
- if(br==4 && dw=='SggO')
- {
- SetFilePointer(f,0,0,FILE_BEGIN);
- }
- else if(br==4 && dw=='FFIR')
- {
- //RIFF file
- DWORD wavhdr = 0, nb = 0;
- SetFilePointer(f,4,0,FILE_CURRENT);
- ReadFile(f,&wavhdr,4,&nb,0);
- if(nb!=4 || wavhdr!='EVAW')
- {
- goto abort;
- }
- //find data starting point
- char tmp[1024] = {0};
- ReadFile(f,&tmp,1024,&nb,0);
- for(int i=0;i<1020;i++)
- if(tmp[i]=='d'&&tmp[i+1]=='a'&&tmp[i+2]=='t'&&tmp[i+3]=='a')
- {
- baseoffs=i+12+8;
- Seek64(f, baseoffs, FILE_BEGIN);
- }
- if(!baseoffs) goto abort;
- }
- else
- {
- abort:
- CloseHandle(f);
- return 0;
- }
- }
- r=cfg_fullbuf ? (VorbisFile*)new VorbisFile_Mem(f,url,is_info) : (VorbisFile*)new VorbisFile_Local(f,url,is_info);
- r->setBaseOffset(baseoffs);
- }
- if (r && !r->init())
- {
- delete r;
- r=0;
- }
- return r;
- }
- bool VorbisFile::init()
- {
- if (ov_open_callbacks(this,&vf,0,0,oc)) return 0;
- //TODO bitrate
- UINT siz=FileSize();
- double len=Length();
- if (siz>0 && len>0)
- {
- UINT divisor = (UINT)(len*125.0);
- if (divisor)
- avg_kbps=siz/divisor;
- }
- post_init();
- return 1;
- }
- int is_http(const char* url)
- {
- return (!_strnicmp(url,"http://",7) || !_strnicmp(url,"https://",8));
- }
- void VorbisFile::set_meta(const vorbis_comment * vc,int links)
- {
- if (links == vf.links)
- {
- int n;
- for(n=0;n<links;n++)
- {
- vorbis_comment_clear(vf.vc+n);
- /*
- extern void vorbis_comment_init(vorbis_comment *vc);
- extern void vorbis_comment_add(vorbis_comment *vc, char *comment);
- extern void vorbis_comment_add_tag(vorbis_comment *vc,char *tag, char *contents);
- extern char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count);
- extern int vorbis_comment_query_count(vorbis_comment *vc, char *tag);
- extern void vorbis_comment_clear(vorbis_comment *vc);
- */
- }
- _ogg_free(vf.vc);
- vf.vc = (vorbis_comment*) _ogg_calloc(links,sizeof(vorbis_comment));
- for(n=0;n<links;n++)
- {
- vorbis_comment_init(vf.vc+n);
- int c;
- for(c=0;c<vc[n].comments;c++)
- {
- vorbis_comment_add(vf.vc+n,vc[n].user_comments[c]);
- }
- vf.vc[n].vendor = _strdup(vc[n].vendor);
- }
- }
- }
|