diff options
Diffstat (limited to 'core/qmpmidiread.cpp')
-rw-r--r-- | core/qmpmidiread.cpp | 110 |
1 files changed, 27 insertions, 83 deletions
diff --git a/core/qmpmidiread.cpp b/core/qmpmidiread.cpp index 5add648..cd3ffa3 100644 --- a/core/qmpmidiread.cpp +++ b/core/qmpmidiread.cpp @@ -8,10 +8,10 @@ #include <cstdarg> #include <algorithm> #include "qmpmidiplay.hpp" -const char* GM1SysX={"\xF0\x7E\x7F\x09\x01\xF7"}; -const char* GM2SysX={"\xF0\x7E\x7F\x09\x03\xF7"}; -const char* GSSysEx={"\xF0\x41\x10\x42\x12\x40\x00\x7F\x00\x41\xF7"}; -const char* XGSysEx={"\xF0\x43\x10\x4C\x00\x00\x7E\x00\xF7"}; +const char* GM1SysX="\xF0\x7E\x7F\x09\x01\xF7"; +const char* GM2SysX="\xF0\x7E\x7F\x09\x03\xF7"; +const char* GSSysEx="\xF0\x41\x10\x42\x12\x40\x00\x7F\x00\x41\xF7"; +const char* XGSysEx="\xF0\x43\x10\x4C\x00\x00\x7E\x00\xF7"; void CSMFReader::error(int fatal,const char* format,...) { va_list ap; @@ -54,35 +54,17 @@ int CSMFReader::eventReader()//returns 0 if End of Track encountered switch(type&0xF0) { case 0x80://Note Off - p1=fgetc(f);p2=fgetc(f);byteread+=2; - ret->eventList.push_back(SEvent(curid,curt,type,p1,p2)); - break; case 0x90://Note On - p1=fgetc(f);p2=fgetc(f);byteread+=2; - if(p2) - ret->eventList.push_back(SEvent(curid,curt,type,p1,p2)); - else - ret->eventList.push_back(SEvent(curid,curt,(type&0x0F)|0x80,p1,p2)); - break; case 0xA0://Note Aftertouch - p1=fgetc(f);p2=fgetc(f);byteread+=2; - ret->eventList.push_back(SEvent(curid,curt,type,p1,p2)); - break; case 0xB0://Controller Change + case 0xE0://Pitch wheel p1=fgetc(f);p2=fgetc(f);byteread+=2; - ret->eventList.push_back(SEvent(curid,curt,type,p1,p2)); + curTrack->appendEvent(SEvent(curid,curt,type,p1,p2)); break; case 0xC0://Patch Change - p1=fgetc(f);++byteread; - ret->eventList.push_back(SEvent(curid,curt,type,p1,0)); - break; case 0xD0://Channel Aftertouch p1=fgetc(f);++byteread; - ret->eventList.push_back(SEvent(curid,curt,type,p1,0)); - break; - case 0xE0://Pitch wheel - p1=fgetc(f);p2=fgetc(f);byteread+=2; - ret->eventList.push_back(SEvent(curid,curt,type,p1,p2)); + curTrack->appendEvent(SEvent(curid,curt,type,p1,0)); break; case 0xF0: if((type&0x0F)==0x0F)//Meta Event @@ -103,7 +85,7 @@ int CSMFReader::eventReader()//returns 0 if End of Track encountered break; case 0x51://Set Tempo p1=readDW();p1&=0x00FFFFFF; - ret->eventList.push_back(SEvent(curid,curt,type,metatype,p1)); + curTrack->appendEvent(SEvent(curid,curt,type,metatype,p1)); break; case 0x54://SMTPE offset, not handled. fgetc(f);fgetc(f);fgetc(f); @@ -113,12 +95,12 @@ int CSMFReader::eventReader()//returns 0 if End of Track encountered case 0x58://Time signature fgetc(f);++byteread; p1=readDW(); - ret->eventList.push_back(SEvent(curid,curt,type,metatype,p1)); + curTrack->appendEvent(SEvent(curid,curt,type,metatype,p1)); break; case 0x59://Key signature fgetc(f);++byteread; p1=readSW(); - ret->eventList.push_back(SEvent(curid,curt,type,metatype,p1)); + curTrack->appendEvent(SEvent(curid,curt,type,metatype,p1)); break; case 0x01:case 0x02:case 0x03: case 0x04:case 0x05:case 0x06: @@ -130,7 +112,8 @@ int CSMFReader::eventReader()//returns 0 if End of Track encountered { ++byteread;if(str)str[c]=fgetc(f);else fgetc(f); } - if(str)str[c]='\0';ret->eventList.push_back(SEvent(curid,curt,type,metatype,0,str)); + if(str)str[c]='\0'; + curTrack->appendEvent(SEvent(curid,curt,type,metatype,0,str)); if(str&&metatype==0x03&&!ret->title) { ret->title=new char[len+8]; @@ -155,7 +138,7 @@ int CSMFReader::eventReader()//returns 0 if End of Track encountered for(c=1;c<len;++c){++byteread;str[c]=fgetc(f);} } else for(c=0;c<len;++c){++byteread;str[c]=fgetc(f);} - ret->eventList.push_back(SEvent(curid,curt,type,len,0,str)); + curTrack->appendEvent(SEvent(curid,curt,type,len,0,str)); if(!strcmp(str,GM1SysX))ret->std=1; if(!strcmp(str,GM2SysX))ret->std=2; if(!strcmp(str,GSSysEx))ret->std=3; @@ -168,9 +151,9 @@ int CSMFReader::eventReader()//returns 0 if End of Track encountered error(0,"W: Unknown event type %#x",type); } lasttype=type;++curid; - if(ret->eventList.size()) + if(curTrack->eventList.size()) { - SEvent& le=ret->eventList[ret->eventList.size()-1]; + SEvent& le=curTrack->eventList.back(); SEventCallBackData cbd(le.type,le.p1,le.p2,le.time); CMidiPlayer::getInstance()->callEventReaderCB(cbd); } @@ -178,6 +161,8 @@ int CSMFReader::eventReader()//returns 0 if End of Track encountered } void CSMFReader::trackChunkReader() { + ret->tracks.push_back(CMidiTrack()); + curTrack=&ret->tracks.back(); int chnklen=readDW();byteread=0;curt=0;curid=0; while(/*byteread<chnklen&&*/eventReader()); if(byteread<chnklen) @@ -239,7 +224,6 @@ CMidiFile* CSMFReader::readFile(const char* fn) chunkReader(1); for(uint32_t i=0;i<trk;i+=chunkReader(0)); fclose(f);f=NULL; - std::sort(ret->eventList.begin(),ret->eventList.end()); } catch(std::runtime_error&){fprintf(stderr,"E: %s is not a supported file.\n",fn);ret->valid=0;if(f)fclose(f);f=NULL;} return ret; @@ -251,44 +235,23 @@ CSMFReader::~CSMFReader() void CSMFReader::discardCurrentEvent() { if(eventdiscarded)return;eventdiscarded=1; - ret->eventList.pop_back(); + curTrack->eventList.pop_back(); } void CSMFReader::commitEventChange(SEventCallBackData d) { - ret->eventList[ret->eventList.size()-1].time=d.time; - ret->eventList[ret->eventList.size()-1].type=d.type; - ret->eventList[ret->eventList.size()-1].p1=d.p1; - ret->eventList[ret->eventList.size()-1].p2=d.p2; + curTrack->eventList.back().time=d.time; + curTrack->eventList.back().type=d.type; + curTrack->eventList.back().p1=d.p1; + curTrack->eventList.back().p2=d.p2; } -void CMidiFileReaderCollection::destructFile(CMidiFile*& f) -{ - if(!f)return; - if(f->copyright)delete[] f->copyright; - if(f->title)delete[] f->title; - delete f; - f=NULL; -} -void CMidiFileReaderCollection::dumpFile() -{ - if(!file)return; - std::vector<SEvent> &eventList=file->eventList; - for(uint32_t i=0;i<eventList.size();++i) - if(eventList[i].str.length()) - printf("type %x #%d @%d p1 %d p2 %d str %s\n",eventList[i].type, - eventList[i].iid,eventList[i].time,eventList[i].p1,eventList[i].p2,eventList[i].str.c_str()); - else - printf("type %x #%d @%d p1 %d p2 %d\n",eventList[i].type, - eventList[i].iid,eventList[i].time,eventList[i].p1,eventList[i].p2); -} CMidiFileReaderCollection::CMidiFileReaderCollection() { - file=NULL;readers.clear();currentReader=NULL; + readers.clear();currentReader=NULL; registerReader(new CSMFReader(),"Default SMF Reader"); } CMidiFileReaderCollection::~CMidiFileReaderCollection() { - if(file)destructFile(file); delete readers[0].first; } void CMidiFileReaderCollection::registerReader(IMidiFileReader* reader,std::string name) @@ -306,38 +269,19 @@ void CMidiFileReaderCollection::unregisterReader(std::string name) return; } } -void CMidiFileReaderCollection::readFile(const char* fn) +CMidiFile* CMidiFileReaderCollection::readFile(const char* fn) { - if(file)destructFile(file); + CMidiFile *file=NULL; for(unsigned i=0;i<readers.size();++i) { currentReader=readers[i].first; CMidiPlayer::getInstance()->notes=0; CMidiFile* t=readers[i].first->readFile(fn); if(t->valid){file=t;break;} - else destructFile(t); + else delete t; } currentReader=NULL; - if(file) - maxtk=file->eventList[file->eventList.size()-1].time; + return file; } -void CMidiFileReaderCollection::destructFile() -{destructFile(file);} IMidiFileReader* CMidiFileReaderCollection::getCurrentReader() {return currentReader;} -bool CMidiFileReaderCollection::isValid() -{return file&&file->valid;} -const char* CMidiFileReaderCollection::getTitle() -{return file?file->title:NULL;} -const char* CMidiFileReaderCollection::getCopyright() -{return file?file->copyright:NULL;} -const SEvent* CMidiFileReaderCollection::getEvent(uint32_t id) -{return file?&(file->eventList[id]):NULL;} -uint32_t CMidiFileReaderCollection::getEventCount() -{return file?file->eventList.size():0;} -uint32_t CMidiFileReaderCollection::getDivision() -{return file?file->divs:0;} -uint32_t CMidiFileReaderCollection::getMaxTick() -{return maxtk;} -uint32_t CMidiFileReaderCollection::getStandard() -{return file?file->std:0;} |