123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- #include "ogg.h"
- void OGGFreeFunction(IMaxModMusic* music){
- delete static_cast<OggPlayer*>(music);
- }
- // -----------------------------------------------------------------------------------
- size_t readfunc( void* buf,size_t size,size_t nmemb,void* src ){
- IMaxModStream* stream = (IMaxModStream*)src;
- long int bytes = stream->Read(buf,size*nmemb);
- return bytes/size;
- }
- int seekfunc( void* src, ogg_int64_t off, int whence ){
- // cout << "seekfunc " << whence << endl;
- IMaxModStream* stream=(IMaxModStream*)src;
- int res=-1;
- switch(whence) {
- // case 0: res=stream->SeekFrom(off,SEEK_SET); cout << "seekfunc SET res=" << res << " offset=" << off << endl; break;
- // case 1: res=stream->SeekFrom(off,SEEK_CUR); cout << "seekfunc CUR res=" << res << " offset=" << off << endl; break;
- // case 2: res=stream->SeekFrom(off,SEEK_END); cout << "seekfunc END res=" << res << " offset=" << off << endl; break;
- case 0: res=stream->SeekFrom(off,SEEK_SET); break;
- case 1: res=stream->SeekFrom(off,SEEK_CUR); break;
- case 2: res=stream->SeekFrom(off,SEEK_END); break;
- }
- if (res>=0) return 0;
- return -1;
- // return res;
- }
- int closefunc( void* src ){}
- long int tellfunc( void* src ){
- IMaxModStream* stream=(IMaxModStream*)src;
- return stream->Position();
- }
- // -----------------------------------------------------------------------------------
- OggPlayer::OggPlayer(){
- Stream = NULL;
- FreeFunction = OGGFreeFunction;
- }
- OggPlayer::~OggPlayer(){
- mmPrint("~OggPlayer");
- Stop();
- if (Stream!=NULL) {
- Stream->Close();
- delete Stream;
- }
- }
- // -----------------------------------------------------------------------------------
- int OggPlayer::FillBuffer(void* buffer,int Length) {
- if (Length==0 or STATUS==0) {return 0;}
- short* buf = (short*)buffer;
- int res,bs,got=0;
- while (Length>0){
- res=ov_read(&vf,(char*)buf,Length,endian,bits/8,sign,&bs);
- if(bs) return 0;
- if (res<=0) {
- POS=0;
- if (LOOP==0) {STATUS=0;return got;}
- } else {
- got+=res;
- buf+=(res/(bits/8));
- Length-=res;
- POS+=res;
- }
- if (Stream->Eof()) {
- Stream->Seek(0);
- }
- }
- return got;
- }
- // -----------------------------------------------------------------------------------
- void OggPlayer::Stop() {
- ov_clear(&vf);
- POS=0;
- }
- // -----------------------------------------------------------------------------------
- int OggPlayer::Seek(int Pos,int mode) {
- // convert Pos into samples
- int position = 0;
- switch(mode) {
- case MM_BYTES: position=Pos/(BITS/8)/CHANNELS ; break;
- case MM_SAMPLES: position=Pos ; break;
- // case MM_MILLISECS: position=Pos*(SAMPLERATE/1000.0) ; break;
- }
- mmPrint("Ogg seek to:",position);
- ogg_int64_t pos = position;
- int res = ov_pcm_seek_lap(&vf,pos);
- STATUS=1;
- POS = pos*((BITS/8)*CHANNELS);
- return res;
- }
- // -----------------------------------------------------------------------------------
- extern "C" {
- IMaxModMusic* LoadMusic_Ogg(IMaxModStream* Stream) {
- mmPrint("OGG Loader...");
- OggPlayer* This = new OggPlayer;
- This->cb.read_func = readfunc;
- This->cb.seek_func = seekfunc;
- This->cb.close_func = closefunc;
- This->cb.tell_func = tellfunc;
- Stream->Seek(0);
- if (ov_open_callbacks(Stream,&This->vf,NULL,0,This->cb)<0) {
- mmPrint("OGG decoder rejected");
- delete This;
- return NULL;
- }
- This->Stream = Stream;
- This->SAMPLERATE = ov_info(&This->vf,-1)->rate;
- This->CHANNELS = ov_info(&This->vf,-1)->channels;
- This->BITS = 16;
- This->SIZE = ov_pcm_total(&This->vf,-1)*((This->BITS/8)*This->CHANNELS);
- This->SEEKABLE = 1;
- This->STATUS = 1;
- mmPrint("OGG accepted! samples=",This->SIZE);
- mmPrint("channels=",This->CHANNELS);
- mmPrint("freq=",This->SAMPLERATE);
- return This;
- }
- }
|