00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "DLS.h"
00025
00026 namespace DLS {
00027
00028
00029
00030
00031 void Connection::Init(conn_block_t* Header) {
00032 Source = (conn_src_t) Header->source;
00033 Control = (conn_src_t) Header->control;
00034 Destination = (conn_dst_t) Header->destination;
00035 Scale = Header->scale;
00036 SourceTransform = (conn_trn_t) CONN_TRANSFORM_SRC(Header->transform);
00037 ControlTransform = (conn_trn_t) CONN_TRANSFORM_CTL(Header->transform);
00038 DestinationTransform = (conn_trn_t) CONN_TRANSFORM_DST(Header->transform);
00039 SourceInvert = CONN_TRANSFORM_INVERT_SRC(Header->transform);
00040 SourceBipolar = CONN_TRANSFORM_BIPOLAR_SRC(Header->transform);
00041 ControlInvert = CONN_TRANSFORM_INVERT_CTL(Header->transform);
00042 ControlBipolar = CONN_TRANSFORM_BIPOLAR_CTL(Header->transform);
00043 }
00044
00045
00046
00047
00048
00049
00050 Articulation::Articulation(RIFF::List* artList) {
00051 if (artList->GetListType() != LIST_TYPE_ART2 &&
00052 artList->GetListType() != LIST_TYPE_ART1) {
00053 throw DLS::Exception("<art1-list> or <art2-list> chunk expected");
00054 }
00055 uint32_t headerSize = artList->ReadUint32();
00056 Connections = artList->ReadUint32();
00057 artList->SetPos(headerSize);
00058
00059 pConnections = new Connection[Connections];
00060 Connection::conn_block_t connblock;
00061 for (uint32_t i = 0; i <= Connections; i++) {
00062 artList->Read(&connblock.source, 1, 2);
00063 artList->Read(&connblock.control, 1, 2);
00064 artList->Read(&connblock.destination, 1, 2);
00065 artList->Read(&connblock.transform, 1, 2);
00066 artList->Read(&connblock.scale, 1, 4);
00067 pConnections[i].Init(&connblock);
00068 }
00069 }
00070
00071 Articulation::~Articulation() {
00072 if (pConnections) delete[] pConnections;
00073 }
00074
00075
00076
00077
00078
00079
00080 Articulator::Articulator(RIFF::List* ParentList) {
00081 pParentList = ParentList;
00082 pArticulations = NULL;
00083 }
00084
00085 Articulation* Articulator::GetFirstArticulation() {
00086 if (!pArticulations) LoadArticulations();
00087 if (!pArticulations) return NULL;
00088 ArticulationsIterator = pArticulations->begin();
00089 return (ArticulationsIterator != pArticulations->end()) ? *ArticulationsIterator : NULL;
00090 }
00091
00092 Articulation* Articulator::GetNextArticulation() {
00093 if (!pArticulations) return NULL;
00094 ArticulationsIterator++;
00095 return (ArticulationsIterator != pArticulations->end()) ? *ArticulationsIterator : NULL;
00096 }
00097
00098 void Articulator::LoadArticulations() {
00099
00100 RIFF::List* lart = pParentList->GetSubList(LIST_TYPE_LAR2);
00101 if (!lart) lart = pParentList->GetSubList(LIST_TYPE_LART);
00102 if (lart) {
00103 uint32_t artCkType = (lart->GetListType() == LIST_TYPE_LAR2) ? LIST_TYPE_ART2
00104 : LIST_TYPE_ART1;
00105 RIFF::List* art = lart->GetFirstSubList();
00106 while (art) {
00107 if (art->GetListType() == artCkType) {
00108 if (!pArticulations) pArticulations = new ArticulationList;
00109 pArticulations->push_back(new Articulation(art));
00110 }
00111 art = lart->GetNextSubList();
00112 }
00113 }
00114 }
00115
00116 Articulator::~Articulator() {
00117 if (pArticulations) {
00118 ArticulationList::iterator iter = pArticulations->begin();
00119 ArticulationList::iterator end = pArticulations->end();
00120 while (iter != end) {
00121 delete *iter;
00122 iter++;
00123 }
00124 delete pArticulations;
00125 }
00126 }
00127
00128
00129
00130
00131
00132
00133 Info::Info(RIFF::List* list) {
00134 if (list) {
00135 RIFF::List* lstINFO = list->GetSubList(LIST_TYPE_INFO);
00136 if (lstINFO) {
00137 LoadString(CHUNK_ID_INAM, lstINFO, Name);
00138 LoadString(CHUNK_ID_IARL, lstINFO, ArchivalLocation);
00139 LoadString(CHUNK_ID_ICRD, lstINFO, CreationDate);
00140 LoadString(CHUNK_ID_ICMT, lstINFO, Comments);
00141 LoadString(CHUNK_ID_IPRD, lstINFO, Product);
00142 LoadString(CHUNK_ID_ICOP, lstINFO, Copyright);
00143 LoadString(CHUNK_ID_IART, lstINFO, Artists);
00144 LoadString(CHUNK_ID_IGNR, lstINFO, Genre);
00145 LoadString(CHUNK_ID_IKEY, lstINFO, Keywords);
00146 LoadString(CHUNK_ID_IENG, lstINFO, Engineer);
00147 LoadString(CHUNK_ID_ITCH, lstINFO, Technician);
00148 LoadString(CHUNK_ID_ISFT, lstINFO, Software);
00149 LoadString(CHUNK_ID_IMED, lstINFO, Medium);
00150 LoadString(CHUNK_ID_ISRC, lstINFO, Source);
00151 LoadString(CHUNK_ID_ISRF, lstINFO, SourceForm);
00152 LoadString(CHUNK_ID_ICMS, lstINFO, Commissioned);
00153 }
00154 }
00155 }
00156
00157
00158
00159
00160
00161
00162 Resource::Resource(Resource* Parent, RIFF::List* lstResource) {
00163 pParent = Parent;
00164
00165 pInfo = new Info(lstResource);
00166
00167 RIFF::Chunk* ckDLSID = lstResource->GetSubChunk(CHUNK_ID_DLID);
00168 if (ckDLSID) {
00169 pDLSID = new dlsid_t;
00170 ckDLSID->Read(&pDLSID->ulData1, 1, 4);
00171 ckDLSID->Read(&pDLSID->usData2, 1, 2);
00172 ckDLSID->Read(&pDLSID->usData3, 1, 2);
00173 ckDLSID->Read(pDLSID->abData, 8, 1);
00174 }
00175 else pDLSID = NULL;
00176 }
00177
00178 Resource::~Resource() {
00179 if (pDLSID) delete pDLSID;
00180 if (pInfo) delete pInfo;
00181 }
00182
00183
00184
00185
00186
00187
00188 Sampler::Sampler(RIFF::List* ParentList) {
00189 RIFF::Chunk* wsmp = ParentList->GetSubChunk(CHUNK_ID_WSMP);
00190 if (!wsmp) throw DLS::Exception("Mandatory <wsmp> chunk not found.");
00191 uint32_t headersize = wsmp->ReadUint32();
00192 UnityNote = wsmp->ReadUint16();
00193 FineTune = wsmp->ReadInt16();
00194 Gain = wsmp->ReadInt32();
00195 SamplerOptions = wsmp->ReadUint32();
00196 NoSampleDepthTruncation = SamplerOptions & F_WSMP_NO_TRUNCATION;
00197 NoSampleCompression = SamplerOptions & F_WSMP_NO_COMPRESSION;
00198 SampleLoops = wsmp->ReadUint32();
00199 pSampleLoops = (SampleLoops) ? new sample_loop_t[SampleLoops] : NULL;
00200 wsmp->SetPos(headersize);
00201 for (uint32_t i = 0; i < SampleLoops; i++) {
00202 wsmp->Read(pSampleLoops + i, 4, 4);
00203 if (pSampleLoops[i].Size > sizeof(sample_loop_t)) {
00204 wsmp->SetPos(pSampleLoops[i].Size - sizeof(sample_loop_t), RIFF::stream_curpos);
00205 }
00206 }
00207 }
00208
00209 Sampler::~Sampler() {
00210 if (pSampleLoops) delete[] pSampleLoops;
00211 }
00212
00213
00214
00215
00216
00217
00218 Sample::Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset) : Resource(pFile, waveList) {
00219 ulWavePoolOffset = WavePoolOffset - LIST_HEADER_SIZE;
00220 pCkFormat = waveList->GetSubChunk(CHUNK_ID_FMT);
00221 pCkData = waveList->GetSubChunk(CHUNK_ID_DATA);
00222 if (!pCkFormat || !pCkData) throw DLS::Exception("Mandatory chunks in wave list not found.");
00223
00224
00225 FormatTag = pCkFormat->ReadUint16();
00226 Channels = pCkFormat->ReadUint16();
00227 SamplesPerSecond = pCkFormat->ReadUint32();
00228 AverageBytesPerSecond = pCkFormat->ReadUint32();
00229 BlockAlign = pCkFormat->ReadUint16();
00230
00231
00232 if (FormatTag == WAVE_FORMAT_PCM) {
00233 BitDepth = pCkFormat->ReadUint16();
00234 FrameSize = (FormatTag == WAVE_FORMAT_PCM) ? (BitDepth / 8) * Channels
00235 : 0;
00236 SamplesTotal = (FormatTag == WAVE_FORMAT_PCM) ? pCkData->GetSize() / FrameSize
00237 : 0;
00238 }
00239 else {
00240 BitDepth = 0;
00241 FrameSize = 0;
00242 SamplesTotal = 0;
00243 }
00244 }
00245
00246 void* Sample::LoadSampleData() {
00247 return pCkData->LoadChunkData();
00248 }
00249
00250 void Sample::ReleaseSampleData() {
00251 pCkData->ReleaseChunkData();
00252 }
00253
00262 unsigned long Sample::SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence) {
00263 if (FormatTag != WAVE_FORMAT_PCM) return 0;
00264 unsigned long orderedBytes = SampleCount * FrameSize;
00265 unsigned long result = pCkData->SetPos(orderedBytes, Whence);
00266 return (result == orderedBytes) ? SampleCount
00267 : result / FrameSize;
00268 }
00269
00279 unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) {
00280 if (FormatTag != WAVE_FORMAT_PCM) return 0;
00281 return pCkData->Read(pBuffer, SampleCount, FrameSize);
00282 }
00283
00284
00285
00286
00287
00288
00289 Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : Resource(pInstrument, rgnList), Articulator(rgnList), Sampler(rgnList) {
00290 pCkRegion = rgnList;
00291
00292 RIFF::Chunk* rgnh = rgnList->GetSubChunk(CHUNK_ID_RGNH);
00293 rgnh->Read(&KeyRange, 2, 2);
00294 rgnh->Read(&VelocityRange, 2, 2);
00295 uint16_t optionflags = rgnh->ReadUint16();
00296 SelfNonExclusive = optionflags & F_RGN_OPTION_SELFNONEXCLUSIVE;
00297 KeyGroup = rgnh->ReadUint16();
00298
00299 if (rgnh->RemainingBytes() >= sizeof(uint16_t)) {
00300 rgnh->Read(&Layer, 1, sizeof(uint16_t));
00301 }
00302 else Layer = 0;
00303
00304 RIFF::Chunk* wlnk = rgnList->GetSubChunk(CHUNK_ID_WLNK);
00305 optionflags = wlnk->ReadUint16();
00306 PhaseMaster = optionflags & F_WAVELINK_PHASE_MASTER;
00307 MultiChannel = optionflags & F_WAVELINK_MULTICHANNEL;
00308 PhaseGroup = wlnk->ReadUint16();
00309 Channel = wlnk->ReadUint32();
00310 WavePoolTableIndex = wlnk->ReadUint32();
00311
00312 pSample = NULL;
00313 }
00314
00315 Region::~Region() {
00316 }
00317
00318 Sample* Region::GetSample() {
00319 if (pSample) return pSample;
00320 File* file = (File*) GetParent()->GetParent();
00321 unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
00322 Sample* sample = file->GetFirstSample();
00323 while (sample) {
00324 if (sample->ulWavePoolOffset == soughtoffset) return (pSample = sample);
00325 sample = file->GetNextSample();
00326 }
00327 return NULL;
00328 }
00329
00330
00331
00332
00333
00334
00335 Instrument::Instrument(File* pFile, RIFF::List* insList) : Resource(pFile, insList), Articulator(insList) {
00336 pCkInstrument = insList;
00337
00338 RIFF::Chunk* insh = pCkInstrument->GetSubChunk(CHUNK_ID_INSH);
00339 if (!insh) throw DLS::Exception("Mandatory chunks in <lins> list chunk not found.");
00340 Regions = insh->ReadUint32();
00341 midi_locale_t locale;
00342 insh->Read(&locale, 2, 4);
00343 MIDIProgram = locale.instrument;
00344 IsDrum = locale.bank & DRUM_TYPE_MASK;
00345 MIDIBankCoarse = (uint8_t) MIDI_BANK_COARSE(locale.bank);
00346 MIDIBankFine = (uint8_t) MIDI_BANK_FINE(locale.bank);
00347 MIDIBank = MIDI_BANK_MERGE(MIDIBankCoarse, MIDIBankFine);
00348
00349 pRegions = NULL;
00350 }
00351
00352 Region* Instrument::GetFirstRegion() {
00353 if (!pRegions) LoadRegions();
00354 if (!pRegions) return NULL;
00355 RegionsIterator = pRegions->begin();
00356 return (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL;
00357 }
00358
00359 Region* Instrument::GetNextRegion() {
00360 if (!pRegions) return NULL;
00361 RegionsIterator++;
00362 return (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL;
00363 }
00364
00365 void Instrument::LoadRegions() {
00366 RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
00367 if (!lrgn) throw DLS::Exception("Mandatory chunks in <ins > chunk not found.");
00368 uint32_t regionCkType = (lrgn->GetSubList(LIST_TYPE_RGN2)) ? LIST_TYPE_RGN2 : LIST_TYPE_RGN;
00369 RIFF::List* rgn = lrgn->GetFirstSubList();
00370 while (rgn) {
00371 if (rgn->GetListType() == regionCkType) {
00372 if (!pRegions) pRegions = new RegionList;
00373 pRegions->push_back(new Region(this, rgn));
00374 }
00375 rgn = lrgn->GetNextSubList();
00376 }
00377 }
00378
00379 Instrument::~Instrument() {
00380 if (pRegions) {
00381 RegionList::iterator iter = pRegions->begin();
00382 RegionList::iterator end = pRegions->end();
00383 while (iter != end) {
00384 delete *iter;
00385 iter++;
00386 }
00387 delete pRegions;
00388 }
00389 }
00390
00391
00392
00393
00394
00395
00396 File::File(RIFF::File* pRIFF) : Resource(NULL, pRIFF) {
00397 if (!pRIFF) throw DLS::Exception("NULL pointer reference to RIFF::File object.");
00398 this->pRIFF = pRIFF;
00399
00400 RIFF::Chunk* ckVersion = pRIFF->GetSubChunk(CHUNK_ID_VERS);
00401 if (ckVersion) {
00402 pVersion = new version_t;
00403 ckVersion->Read(pVersion, 4, 2);
00404 }
00405 else pVersion = NULL;
00406
00407 RIFF::Chunk* colh = pRIFF->GetSubChunk(CHUNK_ID_COLH);
00408 if (!colh) throw DLS::Exception("Mandatory chunks in RIFF list chunk not found.");
00409 Instruments = colh->ReadUint32();
00410
00411 RIFF::Chunk* ptbl = pRIFF->GetSubChunk(CHUNK_ID_PTBL);
00412 if (!ptbl) throw DLS::Exception("Mandatory <ptbl> chunk not found.");
00413 uint32_t headersize = ptbl->ReadUint32();
00414 WavePoolCount = ptbl->ReadUint32();
00415 pWavePoolTable = new uint32_t[WavePoolCount];
00416 pWavePoolTableHi = new uint32_t[WavePoolCount];
00417 ptbl->SetPos(headersize);
00418
00419
00420 if (ptbl->GetSize() - headersize == WavePoolCount * 8) {
00421 for (int i = 0 ; i < WavePoolCount ; i++) {
00422 pWavePoolTableHi[i] = ptbl->ReadUint32();
00423 pWavePoolTable[i] = ptbl->ReadUint32();
00424 if (pWavePoolTable[i] & 0x80000000)
00425 throw DLS::Exception("Files larger than 2 GB not yet supported");
00426 }
00427 }
00428 else {
00429 ptbl->Read(pWavePoolTable, WavePoolCount, sizeof(uint32_t));
00430 for (int i = 0 ; i < WavePoolCount ; i++) pWavePoolTableHi[i] = 0;
00431 }
00432
00433 pSamples = NULL;
00434 pInstruments = NULL;
00435 }
00436
00437 File::~File() {
00438 if (pInstruments) {
00439 InstrumentList::iterator iter = pInstruments->begin();
00440 InstrumentList::iterator end = pInstruments->end();
00441 while (iter != end) {
00442 delete *iter;
00443 iter++;
00444 }
00445 delete pInstruments;
00446 }
00447
00448 if (pSamples) {
00449 SampleList::iterator iter = pSamples->begin();
00450 SampleList::iterator end = pSamples->end();
00451 while (iter != end) {
00452 delete *iter;
00453 iter++;
00454 }
00455 delete pSamples;
00456 }
00457
00458 if (pWavePoolTable) delete[] pWavePoolTable;
00459 if (pWavePoolTableHi) delete[] pWavePoolTableHi;
00460 if (pVersion) delete pVersion;
00461 }
00462
00463 Sample* File::GetFirstSample() {
00464 if (!pSamples) LoadSamples();
00465 if (!pSamples) return NULL;
00466 SamplesIterator = pSamples->begin();
00467 return (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL;
00468 }
00469
00470 Sample* File::GetNextSample() {
00471 if (!pSamples) return NULL;
00472 SamplesIterator++;
00473 return (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL;
00474 }
00475
00476 void File::LoadSamples() {
00477 RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
00478 if (wvpl) {
00479 unsigned long wvplFileOffset = wvpl->GetFilePos();
00480 RIFF::List* wave = wvpl->GetFirstSubList();
00481 while (wave) {
00482 if (wave->GetListType() == LIST_TYPE_WAVE) {
00483 if (!pSamples) pSamples = new SampleList;
00484 unsigned long waveFileOffset = wave->GetFilePos();
00485 pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset));
00486 }
00487 wave = wvpl->GetNextSubList();
00488 }
00489 }
00490 else {
00491 RIFF::List* dwpl = pRIFF->GetSubList(LIST_TYPE_DWPL);
00492 if (dwpl) {
00493 unsigned long dwplFileOffset = dwpl->GetFilePos();
00494 RIFF::List* wave = dwpl->GetFirstSubList();
00495 while (wave) {
00496 if (wave->GetListType() == LIST_TYPE_WAVE) {
00497 if (!pSamples) pSamples = new SampleList;
00498 unsigned long waveFileOffset = wave->GetFilePos();
00499 pSamples->push_back(new Sample(this, wave, waveFileOffset - dwplFileOffset));
00500 }
00501 wave = dwpl->GetNextSubList();
00502 }
00503 }
00504 }
00505 }
00506
00507 Instrument* File::GetFirstInstrument() {
00508 if (!pInstruments) LoadInstruments();
00509 if (!pInstruments) return NULL;
00510 InstrumentsIterator = pInstruments->begin();
00511 return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
00512 }
00513
00514 Instrument* File::GetNextInstrument() {
00515 if (!pInstruments) return NULL;
00516 InstrumentsIterator++;
00517 return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
00518 }
00519
00520 void File::LoadInstruments() {
00521 RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
00522 if (lstInstruments) {
00523 RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
00524 while (lstInstr) {
00525 if (lstInstr->GetListType() == LIST_TYPE_INS) {
00526 if (!pInstruments) pInstruments = new InstrumentList;
00527 pInstruments->push_back(new Instrument(this, lstInstr));
00528 }
00529 lstInstr = lstInstruments->GetNextSubList();
00530 }
00531 }
00532 }
00533
00534
00535
00536
00537
00538
00539 Exception::Exception(String Message) : RIFF::Exception(Message) {
00540 }
00541
00542 void Exception::PrintMessage() {
00543 std::cout << "DLS::Exception: " << Message << std::endl;
00544 }
00545
00546
00547
00548
00549
00555 String libraryName() {
00556 return PACKAGE;
00557 }
00558
00563 String libraryVersion() {
00564 return VERSION;
00565 }
00566
00567 }