aboutsummaryrefslogtreecommitdiff
path: root/core/qmpmidiread.cpp
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2017-06-16 23:51:26 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2017-06-16 23:51:26 +0800
commit64c91c7da66ba71e2bb32077680f234aba4ac65d (patch)
treedc44e44c4f2b1530952f57538d7164f712b61b02 /core/qmpmidiread.cpp
parent37ba9dd1ce449bc2c2f422dd04225bc68bd89c59 (diff)
downloadQMidiPlayer-64c91c7da66ba71e2bb32077680f234aba4ac65d.tar.xz
Code refactoring and fix to memory leaks.
Diffstat (limited to 'core/qmpmidiread.cpp')
-rw-r--r--core/qmpmidiread.cpp110
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;}