/[svn]/libgig/trunk/src/DLS.cpp
ViewVC logotype

Diff of /libgig/trunk/src/DLS.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 929 by schoenebeck, Tue Oct 24 22:24:45 2006 UTC revision 1183 by persson, Sun May 13 10:34:29 2007 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   libgig - C++ cross-platform Gigasampler format file loader library    *   *   libgig - C++ cross-platform Gigasampler format file access library    *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003-2006 by Christian Schoenebeck                      *   *   Copyright (C) 2003-2007 by Christian Schoenebeck                      *
6   *                              <cuse@users.sourceforge.net>               *   *                              <cuse@users.sourceforge.net>               *
7   *                                                                         *   *                                                                         *
8   *   This library is free software; you can redistribute it and/or modify  *   *   This library is free software; you can redistribute it and/or modify  *
# Line 142  namespace DLS { Line 142  namespace DLS {
142          const int iEntrySize = 12; // 12 bytes per connection block          const int iEntrySize = 12; // 12 bytes per connection block
143          pArticulationCk->Resize(HeaderSize + Connections * iEntrySize);          pArticulationCk->Resize(HeaderSize + Connections * iEntrySize);
144          uint8_t* pData = (uint8_t*) pArticulationCk->LoadChunkData();          uint8_t* pData = (uint8_t*) pArticulationCk->LoadChunkData();
145          memcpy(&pData[0], &HeaderSize, 2);          store16(&pData[0], HeaderSize);
146          memcpy(&pData[2], &Connections, 2);          store16(&pData[2], Connections);
147          for (uint32_t i = 0; i < Connections; i++) {          for (uint32_t i = 0; i < Connections; i++) {
148              Connection::conn_block_t c = pConnections[i].ToConnBlock();              Connection::conn_block_t c = pConnections[i].ToConnBlock();
149              memcpy(&pData[HeaderSize + i * iEntrySize],     &c.source, 2);              store16(&pData[HeaderSize + i * iEntrySize],     c.source);
150              memcpy(&pData[HeaderSize + i * iEntrySize + 2], &c.control, 2);              store16(&pData[HeaderSize + i * iEntrySize + 2], c.control);
151              memcpy(&pData[HeaderSize + i * iEntrySize + 4], &c.destination, 2);              store16(&pData[HeaderSize + i * iEntrySize + 4], c.destination);
152              memcpy(&pData[HeaderSize + i * iEntrySize + 6], &c.transform, 2);              store16(&pData[HeaderSize + i * iEntrySize + 6], c.transform);
153              memcpy(&pData[HeaderSize + i * iEntrySize + 8], &c.scale, 4);              store32(&pData[HeaderSize + i * iEntrySize + 8], c.scale);
154          }          }
155      }      }
156    
# Line 233  namespace DLS { Line 233  namespace DLS {
233       * @param list - pointer to a list chunk which contains an INFO list chunk       * @param list - pointer to a list chunk which contains an INFO list chunk
234       */       */
235      Info::Info(RIFF::List* list) {      Info::Info(RIFF::List* list) {
236          UseFixedLengthStrings = false;          FixedStringLengths = NULL;
237          pResourceListChunk = list;          pResourceListChunk = list;
238          if (list) {          if (list) {
239              RIFF::List* lstINFO = list->GetSubList(LIST_TYPE_INFO);              RIFF::List* lstINFO = list->GetSubList(LIST_TYPE_INFO);
# Line 286  namespace DLS { Line 286  namespace DLS {
286       * @param lstINFO  - parent (INFO) RIFF list chunk       * @param lstINFO  - parent (INFO) RIFF list chunk
287       * @param s        - current value of info field       * @param s        - current value of info field
288       * @param sDefault - default value       * @param sDefault - default value
      * @param bUseFixedLengthStrings - should a specific string size be forced in the chunk?  
      * @param size     - wanted size of the INFO chunk. This is ignored if bUseFixedLengthStrings is false.  
289       */       */
290      void Info::SaveString(uint32_t ChunkID, RIFF::List* lstINFO, const String& s, const String& sDefault, bool bUseFixedLengthStrings, int size) {      void Info::SaveString(uint32_t ChunkID, RIFF::List* lstINFO, const String& s, const String& sDefault) {
291            int size = 0;
292            if (FixedStringLengths) {
293                for (int i = 0 ; FixedStringLengths[i].length ; i++) {
294                    if (FixedStringLengths[i].chunkId == ChunkID) {
295                        size = FixedStringLengths[i].length;
296                    }
297                }
298            }
299          RIFF::Chunk* ck = lstINFO->GetSubChunk(ChunkID);          RIFF::Chunk* ck = lstINFO->GetSubChunk(ChunkID);
300          ::SaveString(ChunkID, ck, lstINFO, s, sDefault, bUseFixedLengthStrings, size); // function from helper.h          ::SaveString(ChunkID, ck, lstINFO, s, sDefault, size != 0, size); // function from helper.h
301      }      }
302    
303      /** @brief Update chunks with current info values.      /** @brief Update chunks with current info values.
# Line 336  namespace DLS { Line 342  namespace DLS {
342    
343          // save values          // save values
344    
345          // (the string size values are for gig files; they are only          SaveString(CHUNK_ID_IARL, lstINFO, ArchivalLocation, String(""));
346          // used if UseFixedLengthStrings is set to true)          SaveString(CHUNK_ID_IART, lstINFO, Artists, String(""));
347          SaveString(CHUNK_ID_INAM, lstINFO, Name, defaultName, UseFixedLengthStrings,          SaveString(CHUNK_ID_ICMS, lstINFO, Commissioned, String(""));
348                     resourceType == RIFF_TYPE_DLS ? 128 : 64);          SaveString(CHUNK_ID_ICMT, lstINFO, Comments, defaultComments);
349          SaveString(CHUNK_ID_IARL, lstINFO, ArchivalLocation, String(""), UseFixedLengthStrings, 256);          SaveString(CHUNK_ID_ICOP, lstINFO, Copyright, String(""));
350          SaveString(CHUNK_ID_ICRD, lstINFO, CreationDate, defaultCreationDate, UseFixedLengthStrings, 128);          SaveString(CHUNK_ID_ICRD, lstINFO, CreationDate, defaultCreationDate);
351          SaveString(CHUNK_ID_ICMT, lstINFO, Comments, defaultComments, UseFixedLengthStrings, 1024);          SaveString(CHUNK_ID_IENG, lstINFO, Engineer, String(""));
352          SaveString(CHUNK_ID_IPRD, lstINFO, Product, String(""), UseFixedLengthStrings, 128);          SaveString(CHUNK_ID_IGNR, lstINFO, Genre, String(""));
353          SaveString(CHUNK_ID_ICOP, lstINFO, Copyright, String(""), UseFixedLengthStrings, 128);          SaveString(CHUNK_ID_IKEY, lstINFO, Keywords, String(""));
354          SaveString(CHUNK_ID_IART, lstINFO, Artists, String(""), UseFixedLengthStrings, 128);          SaveString(CHUNK_ID_IMED, lstINFO, Medium, String(""));
355          SaveString(CHUNK_ID_IGNR, lstINFO, Genre, String(""), UseFixedLengthStrings, 128);          SaveString(CHUNK_ID_INAM, lstINFO, Name, defaultName);
356          SaveString(CHUNK_ID_IKEY, lstINFO, Keywords, String(""), UseFixedLengthStrings, 128);          SaveString(CHUNK_ID_IPRD, lstINFO, Product, String(""));
357          SaveString(CHUNK_ID_IENG, lstINFO, Engineer, String(""), UseFixedLengthStrings, 128);          SaveString(CHUNK_ID_ISBJ, lstINFO, Subject, String(""));
358          SaveString(CHUNK_ID_ITCH, lstINFO, Technician, String(""), UseFixedLengthStrings, 128);          SaveString(CHUNK_ID_ISFT, lstINFO, Software, defaultSoftware);
359          SaveString(CHUNK_ID_ISFT, lstINFO, Software, defaultSoftware, UseFixedLengthStrings,          SaveString(CHUNK_ID_ISRC, lstINFO, Source, String(""));
360                     resourceType == LIST_TYPE_INS ?          SaveString(CHUNK_ID_ISRF, lstINFO, SourceForm, String(""));
361                     (Software == "" ? defaultSoftware.length() : Software.length()) : 128);          SaveString(CHUNK_ID_ITCH, lstINFO, Technician, String(""));
         SaveString(CHUNK_ID_IMED, lstINFO, Medium, String(""), UseFixedLengthStrings, 128);  
         SaveString(CHUNK_ID_ISRC, lstINFO, Source, String(""), UseFixedLengthStrings, 128);  
         SaveString(CHUNK_ID_ISRF, lstINFO, SourceForm, String(""), UseFixedLengthStrings, 128);  
         SaveString(CHUNK_ID_ICMS, lstINFO, Commissioned, String(""), UseFixedLengthStrings, 128);  
         SaveString(CHUNK_ID_ISBJ, lstINFO, Subject, String(""), UseFixedLengthStrings, 128);  
362      }      }
363    
364    
# Line 463  namespace DLS { Line 464  namespace DLS {
464          }          }
465          uint8_t* pData = (uint8_t*) wsmp->LoadChunkData();          uint8_t* pData = (uint8_t*) wsmp->LoadChunkData();
466          // update headers size          // update headers size
467          memcpy(&pData[0], &uiHeaderSize, 4);          store32(&pData[0], uiHeaderSize);
468          // update respective sampler options bits          // update respective sampler options bits
469          SamplerOptions = (NoSampleDepthTruncation) ? SamplerOptions | F_WSMP_NO_TRUNCATION          SamplerOptions = (NoSampleDepthTruncation) ? SamplerOptions | F_WSMP_NO_TRUNCATION
470                                                     : SamplerOptions & (~F_WSMP_NO_TRUNCATION);                                                     : SamplerOptions & (~F_WSMP_NO_TRUNCATION);
471          SamplerOptions = (NoSampleCompression) ? SamplerOptions | F_WSMP_NO_COMPRESSION          SamplerOptions = (NoSampleCompression) ? SamplerOptions | F_WSMP_NO_COMPRESSION
472                                                 : SamplerOptions & (~F_WSMP_NO_COMPRESSION);                                                 : SamplerOptions & (~F_WSMP_NO_COMPRESSION);
473          memcpy(&pData[4], &UnityNote, 2);          store16(&pData[4], UnityNote);
474          memcpy(&pData[6], &FineTune, 2);          store16(&pData[6], FineTune);
475          memcpy(&pData[8], &Gain, 4);          store32(&pData[8], Gain);
476          memcpy(&pData[12], &SamplerOptions, 4);          store32(&pData[12], SamplerOptions);
477          memcpy(&pData[16], &SampleLoops, 4);          store32(&pData[16], SampleLoops);
478          // update loop definitions          // update loop definitions
479          for (uint32_t i = 0; i < SampleLoops; i++) {          for (uint32_t i = 0; i < SampleLoops; i++) {
480              //FIXME: this does not handle extended loop structs correctly              //FIXME: this does not handle extended loop structs correctly
481              memcpy(&pData[uiHeaderSize + i * 16], pSampleLoops + i, 4 * 4);              store32(&pData[uiHeaderSize + i * 16], pSampleLoops[i].Size);
482                store32(&pData[uiHeaderSize + i * 16 + 4], pSampleLoops[i].LoopType);
483                store32(&pData[uiHeaderSize + i * 16 + 8], pSampleLoops[i].LoopStart);
484                store32(&pData[uiHeaderSize + i * 16 + 12], pSampleLoops[i].LoopLength);
485          }          }
486      }      }
487    
488        /**
489         * Adds a new sample loop with the provided loop definition.
490         *
491         * @param - points to a loop definition that is to be copied
492         */
493        void Sampler::AddSampleLoop(sample_loop_t* pLoopDef) {
494            sample_loop_t* pNewLoops = new sample_loop_t[SampleLoops + 1];
495            // copy old loops array
496            for (int i = 0; i < SampleLoops; i++) {
497                pNewLoops[i] = pSampleLoops[i];
498            }
499            // add the new loop
500            pNewLoops[SampleLoops] = *pLoopDef;
501            // auto correct size field
502            pNewLoops[SampleLoops].Size = sizeof(DLS::sample_loop_t);
503            // free the old array and update the member variables
504            if (SampleLoops) delete[] pSampleLoops;
505            pSampleLoops = pNewLoops;
506            SampleLoops++;
507        }
508    
509        /**
510         * Deletes an existing sample loop.
511         *
512         * @param pLoopDef - pointer to existing loop definition
513         * @throws Exception - if given loop definition does not exist
514         */
515        void Sampler::DeleteSampleLoop(sample_loop_t* pLoopDef) {
516            sample_loop_t* pNewLoops = new sample_loop_t[SampleLoops - 1];
517            // copy old loops array (skipping given loop)
518            for (int i = 0, o = 0; i < SampleLoops; i++) {
519                if (&pSampleLoops[i] == pLoopDef) continue;
520                if (o == SampleLoops - 1)
521                    throw Exception("Could not delete Sample Loop, because it does not exist");
522                pNewLoops[o] = pSampleLoops[i];
523                o++;
524            }
525            // free the old array and update the member variables
526            if (SampleLoops) delete[] pSampleLoops;
527            pSampleLoops = pNewLoops;
528            SampleLoops--;
529        }
530    
531    
532    
533  // *************** Sample ***************  // *************** Sample ***************
# Line 514  namespace DLS { Line 561  namespace DLS {
561              AverageBytesPerSecond  = pCkFormat->ReadUint32();              AverageBytesPerSecond  = pCkFormat->ReadUint32();
562              BlockAlign             = pCkFormat->ReadUint16();              BlockAlign             = pCkFormat->ReadUint16();
563              // PCM format specific              // PCM format specific
564              if (FormatTag == WAVE_FORMAT_PCM) {              if (FormatTag == DLS_WAVE_FORMAT_PCM) {
565                  BitDepth     = pCkFormat->ReadUint16();                  BitDepth     = pCkFormat->ReadUint16();
566                  FrameSize    = (BitDepth / 8) * Channels;                  FrameSize    = (BitDepth / 8) * Channels;
567              } else { // unsupported sample data format              } else { // unsupported sample data format
# Line 522  namespace DLS { Line 569  namespace DLS {
569                  FrameSize    = 0;                  FrameSize    = 0;
570              }              }
571          } else { // 'fmt' chunk missing          } else { // 'fmt' chunk missing
572              FormatTag              = WAVE_FORMAT_PCM;              FormatTag              = DLS_WAVE_FORMAT_PCM;
573              BitDepth               = 16;              BitDepth               = 16;
574              Channels               = 1;              Channels               = 1;
575              SamplesPerSecond       = 44100;              SamplesPerSecond       = 44100;
# Line 530  namespace DLS { Line 577  namespace DLS {
577              FrameSize              = (BitDepth / 8) * Channels;              FrameSize              = (BitDepth / 8) * Channels;
578              BlockAlign             = FrameSize;              BlockAlign             = FrameSize;
579          }          }
580          SamplesTotal = (pCkData) ? (FormatTag == WAVE_FORMAT_PCM) ? pCkData->GetSize() / FrameSize          SamplesTotal = (pCkData) ? (FormatTag == DLS_WAVE_FORMAT_PCM) ? pCkData->GetSize() / FrameSize
581                                                                    : 0                                                                        : 0
582                                   : 0;                                   : 0;
583      }      }
584    
# Line 591  namespace DLS { Line 638  namespace DLS {
638       * the RIFF chunk which encapsulates the sample's wave data. The       * the RIFF chunk which encapsulates the sample's wave data. The
639       * returned value is dependant to the current FrameSize value.       * returned value is dependant to the current FrameSize value.
640       *       *
641       * @returns number of sample points or 0 if FormatTag != WAVE_FORMAT_PCM       * @returns number of sample points or 0 if FormatTag != DLS_WAVE_FORMAT_PCM
642       * @see FrameSize, FormatTag       * @see FrameSize, FormatTag
643       */       */
644      unsigned long Sample::GetSize() {      unsigned long Sample::GetSize() {
645          if (FormatTag != WAVE_FORMAT_PCM) return 0;          if (FormatTag != DLS_WAVE_FORMAT_PCM) return 0;
646          return (pCkData) ? pCkData->GetSize() / FrameSize : 0;          return (pCkData) ? pCkData->GetSize() / FrameSize : 0;
647      }      }
648    
# Line 617  namespace DLS { Line 664  namespace DLS {
664       * calling File::Save() as this might exceed the current sample's       * calling File::Save() as this might exceed the current sample's
665       * boundary!       * boundary!
666       *       *
667       * Also note: only WAVE_FORMAT_PCM is currently supported, that is       * Also note: only DLS_WAVE_FORMAT_PCM is currently supported, that is
668       * FormatTag must be WAVE_FORMAT_PCM. Trying to resize samples with       * FormatTag must be DLS_WAVE_FORMAT_PCM. Trying to resize samples with
669       * other formats will fail!       * other formats will fail!
670       *       *
671       * @param iNewSize - new sample wave data size in sample points (must be       * @param iNewSize - new sample wave data size in sample points (must be
672       *                   greater than zero)       *                   greater than zero)
673       * @throws Excecption if FormatTag != WAVE_FORMAT_PCM       * @throws Excecption if FormatTag != DLS_WAVE_FORMAT_PCM
674       * @throws Exception if \a iNewSize is less than 1       * @throws Exception if \a iNewSize is less than 1
675       * @see File::Save(), FrameSize, FormatTag       * @see File::Save(), FrameSize, FormatTag
676       */       */
677      void Sample::Resize(int iNewSize) {      void Sample::Resize(int iNewSize) {
678          if (FormatTag != WAVE_FORMAT_PCM) throw Exception("Sample's format is not WAVE_FORMAT_PCM");          if (FormatTag != DLS_WAVE_FORMAT_PCM) throw Exception("Sample's format is not DLS_WAVE_FORMAT_PCM");
679          if (iNewSize < 1) throw Exception("Sample size must be at least one sample point");          if (iNewSize < 1) throw Exception("Sample size must be at least one sample point");
680          const int iSizeInBytes = iNewSize * FrameSize;          const int iSizeInBytes = iNewSize * FrameSize;
681          pCkData = pWaveList->GetSubChunk(CHUNK_ID_DATA);          pCkData = pWaveList->GetSubChunk(CHUNK_ID_DATA);
# Line 641  namespace DLS { Line 688  namespace DLS {
688       * bytes). Use this method and <i>Read()</i> if you don't want to load       * bytes). Use this method and <i>Read()</i> if you don't want to load
689       * the sample into RAM, thus for disk streaming.       * the sample into RAM, thus for disk streaming.
690       *       *
691       * Also note: only WAVE_FORMAT_PCM is currently supported, that is       * Also note: only DLS_WAVE_FORMAT_PCM is currently supported, that is
692       * FormatTag must be WAVE_FORMAT_PCM. Trying to reposition the sample       * FormatTag must be DLS_WAVE_FORMAT_PCM. Trying to reposition the sample
693       * with other formats will fail!       * with other formats will fail!
694       *       *
695       * @param SampleCount  number of sample points       * @param SampleCount  number of sample points
696       * @param Whence       to which relation \a SampleCount refers to       * @param Whence       to which relation \a SampleCount refers to
697       * @returns new position within the sample, 0 if       * @returns new position within the sample, 0 if
698       *          FormatTag != WAVE_FORMAT_PCM       *          FormatTag != DLS_WAVE_FORMAT_PCM
699       * @throws Exception if no data RIFF chunk was created for the sample yet       * @throws Exception if no data RIFF chunk was created for the sample yet
700       * @see FrameSize, FormatTag       * @see FrameSize, FormatTag
701       */       */
702      unsigned long Sample::SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence) {      unsigned long Sample::SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence) {
703          if (FormatTag != WAVE_FORMAT_PCM) return 0; // failed: wave data not PCM format          if (FormatTag != DLS_WAVE_FORMAT_PCM) return 0; // failed: wave data not PCM format
704          if (!pCkData) throw Exception("No data chunk created for sample yet, call Sample::Resize() to create one");          if (!pCkData) throw Exception("No data chunk created for sample yet, call Sample::Resize() to create one");
705          unsigned long orderedBytes = SampleCount * FrameSize;          unsigned long orderedBytes = SampleCount * FrameSize;
706          unsigned long result = pCkData->SetPos(orderedBytes, Whence);          unsigned long result = pCkData->SetPos(orderedBytes, Whence);
# Line 671  namespace DLS { Line 718  namespace DLS {
718       * @param SampleCount  number of sample points to read       * @param SampleCount  number of sample points to read
719       */       */
720      unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) {      unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) {
721          if (FormatTag != WAVE_FORMAT_PCM) return 0; // failed: wave data not PCM format          if (FormatTag != DLS_WAVE_FORMAT_PCM) return 0; // failed: wave data not PCM format
722          return pCkData->Read(pBuffer, SampleCount, FrameSize); // FIXME: channel inversion due to endian correction?          return pCkData->Read(pBuffer, SampleCount, FrameSize); // FIXME: channel inversion due to endian correction?
723      }      }
724    
# Line 691  namespace DLS { Line 738  namespace DLS {
738       * @see LoadSampleData()       * @see LoadSampleData()
739       */       */
740      unsigned long Sample::Write(void* pBuffer, unsigned long SampleCount) {      unsigned long Sample::Write(void* pBuffer, unsigned long SampleCount) {
741          if (FormatTag != WAVE_FORMAT_PCM) return 0; // failed: wave data not PCM format          if (FormatTag != DLS_WAVE_FORMAT_PCM) return 0; // failed: wave data not PCM format
742          if (GetSize() < SampleCount) throw Exception("Could not write sample data, current sample size to small");          if (GetSize() < SampleCount) throw Exception("Could not write sample data, current sample size to small");
743          return pCkData->Write(pBuffer, SampleCount, FrameSize); // FIXME: channel inversion due to endian correction?          return pCkData->Write(pBuffer, SampleCount, FrameSize); // FIXME: channel inversion due to endian correction?
744      }      }
# Line 700  namespace DLS { Line 747  namespace DLS {
747       * Apply sample and its settings to the respective RIFF chunks. You have       * Apply sample and its settings to the respective RIFF chunks. You have
748       * to call File::Save() to make changes persistent.       * to call File::Save() to make changes persistent.
749       *       *
750       * @throws Exception if FormatTag != WAVE_FORMAT_PCM or no sample data       * @throws Exception if FormatTag != DLS_WAVE_FORMAT_PCM or no sample data
751       *                   was provided yet       *                   was provided yet
752       */       */
753      void Sample::UpdateChunks() {      void Sample::UpdateChunks() {
754          if (FormatTag != WAVE_FORMAT_PCM)          if (FormatTag != DLS_WAVE_FORMAT_PCM)
755              throw Exception("Could not save sample, only PCM format is supported");              throw Exception("Could not save sample, only PCM format is supported");
756          // we refuse to do anything if not sample wave form was provided yet          // we refuse to do anything if not sample wave form was provided yet
757          if (!pCkData)          if (!pCkData)
# Line 716  namespace DLS { Line 763  namespace DLS {
763          if (!pCkFormat) pCkFormat = pWaveList->AddSubChunk(CHUNK_ID_FMT, 16); // assumes PCM format          if (!pCkFormat) pCkFormat = pWaveList->AddSubChunk(CHUNK_ID_FMT, 16); // assumes PCM format
764          uint8_t* pData = (uint8_t*) pCkFormat->LoadChunkData();          uint8_t* pData = (uint8_t*) pCkFormat->LoadChunkData();
765          // update 'fmt' chunk          // update 'fmt' chunk
766          memcpy(&pData[0], &FormatTag, 2);          store16(&pData[0], FormatTag);
767          memcpy(&pData[2], &Channels,  2);          store16(&pData[2], Channels);
768          memcpy(&pData[4], &SamplesPerSecond, 4);          store32(&pData[4], SamplesPerSecond);
769          memcpy(&pData[8], &AverageBytesPerSecond, 4);          store32(&pData[8], AverageBytesPerSecond);
770          memcpy(&pData[12], &BlockAlign, 2);          store16(&pData[12], BlockAlign);
771          memcpy(&pData[14], &BitDepth, 2); // assuming PCM format          store16(&pData[14], BitDepth); // assuming PCM format
772      }      }
773    
774    
# Line 819  namespace DLS { Line 866  namespace DLS {
866                                  ? FormatOptionFlags | F_RGN_OPTION_SELFNONEXCLUSIVE                                  ? FormatOptionFlags | F_RGN_OPTION_SELFNONEXCLUSIVE
867                                  : FormatOptionFlags & (~F_RGN_OPTION_SELFNONEXCLUSIVE);                                  : FormatOptionFlags & (~F_RGN_OPTION_SELFNONEXCLUSIVE);
868          // update 'rgnh' chunk          // update 'rgnh' chunk
869          memcpy(&pData[0], &KeyRange, 2 * 2);          store16(&pData[0], KeyRange.low);
870          memcpy(&pData[4], &VelocityRange, 2 * 2);          store16(&pData[2], KeyRange.high);
871          memcpy(&pData[8], &FormatOptionFlags, 2);          store16(&pData[4], VelocityRange.low);
872          memcpy(&pData[10], &KeyGroup, 2);          store16(&pData[6], VelocityRange.high);
873          if (rgnh->GetSize() >= 14) memcpy(&pData[12], &Layer, 2);          store16(&pData[8], FormatOptionFlags);
874            store16(&pData[10], KeyGroup);
875            if (rgnh->GetSize() >= 14) store16(&pData[12], Layer);
876    
877          // update chunks of base classes as well (but skip Resource,          // update chunks of base classes as well (but skip Resource,
878          // as a rgn doesn't seem to have dlid and INFO chunks)          // as a rgn doesn't seem to have dlid and INFO chunks)
# Line 856  namespace DLS { Line 905  namespace DLS {
905          if (index < 0) throw Exception("Could not save Region, could not find Region's sample");          if (index < 0) throw Exception("Could not save Region, could not find Region's sample");
906          WavePoolTableIndex = index;          WavePoolTableIndex = index;
907          // update 'wlnk' chunk          // update 'wlnk' chunk
908          memcpy(&pData[0], &WaveLinkOptionFlags, 2);          store16(&pData[0], WaveLinkOptionFlags);
909          memcpy(&pData[2], &PhaseGroup, 2);          store16(&pData[2], PhaseGroup);
910          memcpy(&pData[4], &Channel, 4);          store32(&pData[4], Channel);
911          memcpy(&pData[8], &WavePoolTableIndex, 4);          store32(&pData[8], WavePoolTableIndex);
912      }      }
913    
914    
# Line 942  namespace DLS { Line 991  namespace DLS {
991          return pNewRegion;          return pNewRegion;
992      }      }
993    
994        void Instrument::MoveRegion(Region* pSrc, Region* pDst) {
995            RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
996            lrgn->MoveSubChunk(pSrc->pCkRegion, pDst ? pDst->pCkRegion : 0);
997    
998            pRegions->remove(pSrc);
999            RegionList::iterator iter = find(pRegions->begin(), pRegions->end(), pDst);
1000            pRegions->insert(iter, pSrc);
1001        }
1002    
1003      void Instrument::DeleteRegion(Region* pRegion) {      void Instrument::DeleteRegion(Region* pRegion) {
1004          if (!pRegions) return;          if (!pRegions) return;
1005          RegionList::iterator iter = find(pRegions->begin(), pRegions->end(), pRegion);          RegionList::iterator iter = find(pRegions->begin(), pRegions->end(), pRegion);
# Line 972  namespace DLS { Line 1030  namespace DLS {
1030          locale.bank       = MIDI_BANK_ENCODE(MIDIBankCoarse, MIDIBankFine);          locale.bank       = MIDI_BANK_ENCODE(MIDIBankCoarse, MIDIBankFine);
1031          locale.bank       = (IsDrum) ? locale.bank | DRUM_TYPE_MASK : locale.bank & (~DRUM_TYPE_MASK);          locale.bank       = (IsDrum) ? locale.bank | DRUM_TYPE_MASK : locale.bank & (~DRUM_TYPE_MASK);
1032          MIDIBank          = MIDI_BANK_MERGE(MIDIBankCoarse, MIDIBankFine); // just a sync, when we're at it          MIDIBank          = MIDI_BANK_MERGE(MIDIBankCoarse, MIDIBankFine); // just a sync, when we're at it
1033          memcpy(&pData[0], &Regions, 4);          store32(&pData[0], Regions);
1034          memcpy(&pData[4], &locale, 2 * 4);          store32(&pData[4], locale.bank);
1035            store32(&pData[8], locale.instrument);
1036          // update Region's chunks          // update Region's chunks
1037          if (!pRegions) return;          if (!pRegions) return;
1038          RegionList::iterator iter = pRegions->begin();          RegionList::iterator iter = pRegions->begin();
# Line 1014  namespace DLS { Line 1073  namespace DLS {
1073       * to add samples, instruments and finally call Save() to actually write       * to add samples, instruments and finally call Save() to actually write
1074       * a DLS file.       * a DLS file.
1075       */       */
1076      File::File() : Resource(NULL, pRIFF = new RIFF::File(RIFF_TYPE_DLS)) {      File::File() : Resource(NULL, pRIFF = new RIFF::File(RIFF_TYPE_DLS, RIFF::endian_little)) {
1077          pVersion = new version_t;          pVersion = new version_t;
1078          pVersion->major   = 0;          pVersion->major   = 0;
1079          pVersion->minor   = 0;          pVersion->minor   = 0;
# Line 1269  namespace DLS { Line 1328  namespace DLS {
1328              RIFF::Chunk* ckVersion    = pRIFF->GetSubChunk(CHUNK_ID_VERS);              RIFF::Chunk* ckVersion    = pRIFF->GetSubChunk(CHUNK_ID_VERS);
1329              if (!ckVersion) ckVersion = pRIFF->AddSubChunk(CHUNK_ID_VERS, 8);              if (!ckVersion) ckVersion = pRIFF->AddSubChunk(CHUNK_ID_VERS, 8);
1330              uint8_t* pData = (uint8_t*) ckVersion->LoadChunkData();              uint8_t* pData = (uint8_t*) ckVersion->LoadChunkData();
1331              memcpy(pData, pVersion, 2 * 4);              store16(&pData[0], pVersion->minor);
1332                store16(&pData[2], pVersion->major);
1333                store16(&pData[4], pVersion->build);
1334                store16(&pData[6], pVersion->release);
1335          }          }
1336    
1337          // update 'colh' chunk          // update 'colh' chunk
# Line 1277  namespace DLS { Line 1339  namespace DLS {
1339          RIFF::Chunk* colh = pRIFF->GetSubChunk(CHUNK_ID_COLH);          RIFF::Chunk* colh = pRIFF->GetSubChunk(CHUNK_ID_COLH);
1340          if (!colh)   colh = pRIFF->AddSubChunk(CHUNK_ID_COLH, 4);          if (!colh)   colh = pRIFF->AddSubChunk(CHUNK_ID_COLH, 4);
1341          uint8_t* pData = (uint8_t*) colh->LoadChunkData();          uint8_t* pData = (uint8_t*) colh->LoadChunkData();
1342          memcpy(pData, &Instruments, 4);          store32(pData, Instruments);
1343    
1344          // update instrument's chunks          // update instrument's chunks
1345          if (pInstruments) {          if (pInstruments) {
# Line 1297  namespace DLS { Line 1359  namespace DLS {
1359          ptbl->Resize(iPtblSize);          ptbl->Resize(iPtblSize);
1360          pData = (uint8_t*) ptbl->LoadChunkData();          pData = (uint8_t*) ptbl->LoadChunkData();
1361          WavePoolCount = iSamples;          WavePoolCount = iSamples;
1362          memcpy(&pData[4], &WavePoolCount, 4);          store32(&pData[4], WavePoolCount);
1363          // we actually update the sample offsets in the pool table when we Save()          // we actually update the sample offsets in the pool table when we Save()
1364          memset(&pData[WavePoolHeaderSize], 0, iPtblSize - WavePoolHeaderSize);          memset(&pData[WavePoolHeaderSize], 0, iPtblSize - WavePoolHeaderSize);
1365    
# Line 1386  namespace DLS { Line 1448  namespace DLS {
1448          unsigned long ulOriginalPos = ptbl->GetPos();          unsigned long ulOriginalPos = ptbl->GetPos();
1449          // update headers          // update headers
1450          ptbl->SetPos(0);          ptbl->SetPos(0);
1451          ptbl->WriteUint32(&WavePoolHeaderSize);          uint32_t tmp = WavePoolHeaderSize;
1452          ptbl->WriteUint32(&WavePoolCount);          ptbl->WriteUint32(&tmp);
1453            tmp = WavePoolCount;
1454            ptbl->WriteUint32(&tmp);
1455          // update offsets          // update offsets
1456          ptbl->SetPos(WavePoolHeaderSize);          ptbl->SetPos(WavePoolHeaderSize);
1457          if (b64BitWavePoolOffsets) {          if (b64BitWavePoolOffsets) {
1458              for (int i = 0 ; i < WavePoolCount ; i++) {              for (int i = 0 ; i < WavePoolCount ; i++) {
1459                  ptbl->WriteUint32(&pWavePoolTableHi[i]);                  tmp = pWavePoolTableHi[i];
1460                  ptbl->WriteUint32(&pWavePoolTable[i]);                  ptbl->WriteUint32(&tmp);
1461                    tmp = pWavePoolTable[i];
1462                    ptbl->WriteUint32(&tmp);
1463              }              }
1464          } else { // conventional 32 bit offsets          } else { // conventional 32 bit offsets
1465              for (int i = 0 ; i < WavePoolCount ; i++)              for (int i = 0 ; i < WavePoolCount ; i++) {
1466                  ptbl->WriteUint32(&pWavePoolTable[i]);                  tmp = pWavePoolTable[i];
1467                    ptbl->WriteUint32(&tmp);
1468                }
1469          }          }
1470          // restore 'ptbl' chunk's original read/write position          // restore 'ptbl' chunk's original read/write position
1471          ptbl->SetPos(ulOriginalPos);          ptbl->SetPos(ulOriginalPos);

Legend:
Removed from v.929  
changed lines
  Added in v.1183

  ViewVC Help
Powered by ViewVC