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

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

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

revision 2 by schoenebeck, Sat Oct 25 20:15:04 2003 UTC revision 241 by schoenebeck, Wed Sep 15 13:49:21 2004 UTC
# Line 2  Line 2 
2   *                                                                         *   *                                                                         *
3   *   libgig - C++ cross-platform Gigasampler format file loader library    *   *   libgig - C++ cross-platform Gigasampler format file loader library    *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003 by Christian Schoenebeck                           *   *   Copyright (C) 2003, 2004 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  *
9   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 45  namespace gig { Line 45  namespace gig {
45          Product           = smpl->ReadInt32();          Product           = smpl->ReadInt32();
46          SamplePeriod      = smpl->ReadInt32();          SamplePeriod      = smpl->ReadInt32();
47          MIDIUnityNote     = smpl->ReadInt32();          MIDIUnityNote     = smpl->ReadInt32();
48          MIDIPitchFraction = smpl->ReadInt32();          FineTune          = smpl->ReadInt32();
49          smpl->Read(&SMPTEFormat, 1, 4);          smpl->Read(&SMPTEFormat, 1, 4);
50          SMPTEOffset       = smpl->ReadInt32();          SMPTEOffset       = smpl->ReadInt32();
51          Loops             = smpl->ReadInt32();          Loops             = smpl->ReadInt32();
52            uint32_t manufByt = smpl->ReadInt32();
53          LoopID            = smpl->ReadInt32();          LoopID            = smpl->ReadInt32();
54          smpl->Read(&LoopType, 1, 4);          smpl->Read(&LoopType, 1, 4);
55          LoopStart         = smpl->ReadInt32();          LoopStart         = smpl->ReadInt32();
# Line 71  namespace gig { Line 72  namespace gig {
72              }              }
73          }          }
74          FrameOffset = 0; // just for streaming compressed samples          FrameOffset = 0; // just for streaming compressed samples
75    
76            LoopSize = LoopEnd - LoopStart;
77      }      }
78    
79      /// Scans compressed samples for mandatory informations (e.g. actual number of total sample points).      /// Scans compressed samples for mandatory informations (e.g. actual number of total sample points).
# Line 310  namespace gig { Line 313  namespace gig {
313      }      }
314    
315      /**      /**
316         * Reads \a SampleCount number of sample points from the position stored
317         * in \a pPlaybackState into the buffer pointed by \a pBuffer and moves
318         * the position within the sample respectively, this method honors the
319         * looping informations of the sample (if any). The sample wave stream
320         * will be decompressed on the fly if using a compressed sample. Use this
321         * method if you don't want to load the sample into RAM, thus for disk
322         * streaming. All this methods needs to know to proceed with streaming
323         * for the next time you call this method is stored in \a pPlaybackState.
324         * You have to allocate and initialize the playback_state_t structure by
325         * yourself before you use it to stream a sample:
326         *
327         * <i>
328         * gig::playback_state_t playbackstate;                           <br>
329         * playbackstate.position         = 0;                            <br>
330         * playbackstate.reverse          = false;                        <br>
331         * playbackstate.loop_cycles_left = pSample->LoopPlayCount;       <br>
332         * </i>
333         *
334         * You don't have to take care of things like if there is actually a loop
335         * defined or if the current read position is located within a loop area.
336         * The method already handles such cases by itself.
337         *
338         * @param pBuffer          destination buffer
339         * @param SampleCount      number of sample points to read
340         * @param pPlaybackState   will be used to store and reload the playback
341         *                         state for the next ReadAndLoop() call
342         * @returns                number of successfully read sample points
343         */
344        unsigned long Sample::ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState) {
345            unsigned long samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
346            uint8_t* pDst = (uint8_t*) pBuffer;
347    
348            SetPos(pPlaybackState->position); // recover position from the last time
349    
350            if (this->Loops && GetPos() <= this->LoopEnd) { // honor looping if there are loop points defined
351    
352                switch (this->LoopType) {
353    
354                    case loop_type_bidirectional: { //TODO: not tested yet!
355                        do {
356                            // if not endless loop check if max. number of loop cycles have been passed
357                            if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
358    
359                            if (!pPlaybackState->reverse) { // forward playback
360                                do {
361                                    samplestoloopend  = this->LoopEnd - GetPos();
362                                    readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend));
363                                    samplestoread    -= readsamples;
364                                    totalreadsamples += readsamples;
365                                    if (readsamples == samplestoloopend) {
366                                        pPlaybackState->reverse = true;
367                                        break;
368                                    }
369                                } while (samplestoread && readsamples);
370                            }
371                            else { // backward playback
372    
373                                // as we can only read forward from disk, we have to
374                                // determine the end position within the loop first,
375                                // read forward from that 'end' and finally after
376                                // reading, swap all sample frames so it reflects
377                                // backward playback
378    
379                                unsigned long swapareastart       = totalreadsamples;
380                                unsigned long loopoffset          = GetPos() - this->LoopStart;
381                                unsigned long samplestoreadinloop = Min(samplestoread, loopoffset);
382                                unsigned long reverseplaybackend  = GetPos() - samplestoreadinloop;
383    
384                                SetPos(reverseplaybackend);
385    
386                                // read samples for backward playback
387                                do {
388                                    readsamples          = Read(&pDst[totalreadsamples * this->FrameSize], samplestoreadinloop);
389                                    samplestoreadinloop -= readsamples;
390                                    samplestoread       -= readsamples;
391                                    totalreadsamples    += readsamples;
392                                } while (samplestoreadinloop && readsamples);
393    
394                                SetPos(reverseplaybackend); // pretend we really read backwards
395    
396                                if (reverseplaybackend == this->LoopStart) {
397                                    pPlaybackState->loop_cycles_left--;
398                                    pPlaybackState->reverse = false;
399                                }
400    
401                                // reverse the sample frames for backward playback
402                                SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
403                            }
404                        } while (samplestoread && readsamples);
405                        break;
406                    }
407    
408                    case loop_type_backward: { // TODO: not tested yet!
409                        // forward playback (not entered the loop yet)
410                        if (!pPlaybackState->reverse) do {
411                            samplestoloopend  = this->LoopEnd - GetPos();
412                            readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend));
413                            samplestoread    -= readsamples;
414                            totalreadsamples += readsamples;
415                            if (readsamples == samplestoloopend) {
416                                pPlaybackState->reverse = true;
417                                break;
418                            }
419                        } while (samplestoread && readsamples);
420    
421                        if (!samplestoread) break;
422    
423                        // as we can only read forward from disk, we have to
424                        // determine the end position within the loop first,
425                        // read forward from that 'end' and finally after
426                        // reading, swap all sample frames so it reflects
427                        // backward playback
428    
429                        unsigned long swapareastart       = totalreadsamples;
430                        unsigned long loopoffset          = GetPos() - this->LoopStart;
431                        unsigned long samplestoreadinloop = (this->LoopPlayCount) ? Min(samplestoread, pPlaybackState->loop_cycles_left * LoopSize - loopoffset)
432                                                                                  : samplestoread;
433                        unsigned long reverseplaybackend  = this->LoopStart + Abs((loopoffset - samplestoreadinloop) % this->LoopSize);
434    
435                        SetPos(reverseplaybackend);
436    
437                        // read samples for backward playback
438                        do {
439                            // if not endless loop check if max. number of loop cycles have been passed
440                            if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
441                            samplestoloopend     = this->LoopEnd - GetPos();
442                            readsamples          = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoreadinloop, samplestoloopend));
443                            samplestoreadinloop -= readsamples;
444                            samplestoread       -= readsamples;
445                            totalreadsamples    += readsamples;
446                            if (readsamples == samplestoloopend) {
447                                pPlaybackState->loop_cycles_left--;
448                                SetPos(this->LoopStart);
449                            }
450                        } while (samplestoreadinloop && readsamples);
451    
452                        SetPos(reverseplaybackend); // pretend we really read backwards
453    
454                        // reverse the sample frames for backward playback
455                        SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
456                        break;
457                    }
458    
459                    default: case loop_type_normal: {
460                        do {
461                            // if not endless loop check if max. number of loop cycles have been passed
462                            if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
463                            samplestoloopend  = this->LoopEnd - GetPos();
464                            readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend));
465                            samplestoread    -= readsamples;
466                            totalreadsamples += readsamples;
467                            if (readsamples == samplestoloopend) {
468                                pPlaybackState->loop_cycles_left--;
469                                SetPos(this->LoopStart);
470                            }
471                        } while (samplestoread && readsamples);
472                        break;
473                    }
474                }
475            }
476    
477            // read on without looping
478            if (samplestoread) do {
479                readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoread);
480                samplestoread    -= readsamples;
481                totalreadsamples += readsamples;
482            } while (readsamples && samplestoread);
483    
484            // store current position
485            pPlaybackState->position = GetPos();
486    
487            return totalreadsamples;
488        }
489    
490        /**
491       * Reads \a SampleCount number of sample points from the current       * Reads \a SampleCount number of sample points from the current
492       * position into the buffer pointed by \a pBuffer and increments the       * position into the buffer pointed by \a pBuffer and increments the
493       * position within the sample. The sample wave stream will be       * position within the sample. The sample wave stream will be
# Line 323  namespace gig { Line 501  namespace gig {
501       * @see                SetPos()       * @see                SetPos()
502       */       */
503      unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) {      unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) {
504          if (!Compressed) return pCkData->Read(pBuffer, SampleCount, FrameSize);          if (SampleCount == 0) return 0;
505            if (!Compressed) return pCkData->Read(pBuffer, SampleCount, FrameSize); //FIXME: channel inversion due to endian correction?
506          else { //FIXME: no support for mono compressed samples yet, are there any?          else { //FIXME: no support for mono compressed samples yet, are there any?
507                if (this->SamplePos >= this->SamplesTotal) return 0;
508              //TODO: efficiency: we simply assume here that all frames are compressed, maybe we should test for an average compression rate              //TODO: efficiency: we simply assume here that all frames are compressed, maybe we should test for an average compression rate
509              // best case needed buffer size (all frames compressed)              // best case needed buffer size (all frames compressed)
510              unsigned long assumedsize      = (SampleCount << 1)  + // *2 (16 Bit, stereo, but assume all frames compressed)              unsigned long assumedsize      = (SampleCount << 1)  + // *2 (16 Bit, stereo, but assume all frames compressed)
# Line 353  namespace gig { Line 533  namespace gig {
533                  // reload from disk to local buffer if needed                  // reload from disk to local buffer if needed
534                  if (remainingbytes < 8194) {                  if (remainingbytes < 8194) {
535                      if (pCkData->GetState() != RIFF::stream_ready) {                      if (pCkData->GetState() != RIFF::stream_ready) {
536                          this->SamplePos += (SampleCount - remainingsamples);                          this->SamplePos = this->SamplesTotal;
                         //if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;  
537                          return (SampleCount - remainingsamples);                          return (SampleCount - remainingsamples);
538                      }                      }
539                      assumedsize    = remainingsamples;                      assumedsize    = remainingsamples;
# Line 474  namespace gig { Line 653  namespace gig {
653                  }                  }
654              }              }
655              this->SamplePos += (SampleCount - remainingsamples);              this->SamplePos += (SampleCount - remainingsamples);
656              //if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;              if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
657              return (SampleCount - remainingsamples);              return (SampleCount - remainingsamples);
658          }          }
659      }      }
# Line 491  namespace gig { Line 670  namespace gig {
670  // *************** DimensionRegion ***************  // *************** DimensionRegion ***************
671  // *  // *
672    
673        uint                               DimensionRegion::Instances       = 0;
674        DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
675    
676      DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {      DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
677            Instances++;
678    
679          memcpy(&Crossfade, &SamplerOptions, 4);          memcpy(&Crossfade, &SamplerOptions, 4);
680            if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
681    
682          RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);          RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
683          _3ewa->ReadInt32(); // unknown, allways 0x0000008C ?          _3ewa->ReadInt32(); // unknown, always 0x0000008C ?
684          LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());          LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
685          EG3Attack     = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());          EG3Attack     = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
686          _3ewa->ReadInt16(); // unknown          _3ewa->ReadInt16(); // unknown
# Line 511  namespace gig { Line 696  namespace gig {
696          _3ewa->ReadInt16(); // unknown          _3ewa->ReadInt16(); // unknown
697          EG1Sustain          = _3ewa->ReadUint16();          EG1Sustain          = _3ewa->ReadUint16();
698          EG1Release          = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());          EG1Release          = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
699          EG1Controller       = static_cast<eg1_ctrl_t>(_3ewa->ReadUint8());          EG1Controller       = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
700          uint8_t eg1ctrloptions        = _3ewa->ReadUint8();          uint8_t eg1ctrloptions        = _3ewa->ReadUint8();
701          EG1ControllerInvert           = eg1ctrloptions & 0x01;          EG1ControllerInvert           = eg1ctrloptions & 0x01;
702          EG1ControllerAttackInfluence  = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);          EG1ControllerAttackInfluence  = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
703          EG1ControllerDecayInfluence   = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);          EG1ControllerDecayInfluence   = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
704          EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);          EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
705          EG2Controller       = static_cast<eg2_ctrl_t>(_3ewa->ReadUint8());          EG2Controller       = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
706          uint8_t eg2ctrloptions        = _3ewa->ReadUint8();          uint8_t eg2ctrloptions        = _3ewa->ReadUint8();
707          EG2ControllerInvert           = eg2ctrloptions & 0x01;          EG2ControllerInvert           = eg2ctrloptions & 0x01;
708          EG2ControllerAttackInfluence  = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);          EG2ControllerAttackInfluence  = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
# Line 579  namespace gig { Line 764  namespace gig {
764              ReleaseVelocityResponseDepth = 0;              ReleaseVelocityResponseDepth = 0;
765          }          }
766          VelocityResponseCurveScaling = _3ewa->ReadUint8();          VelocityResponseCurveScaling = _3ewa->ReadUint8();
767          AttenuationControlTreshold   = _3ewa->ReadInt8();          AttenuationControllerThreshold = _3ewa->ReadInt8();
768          _3ewa->ReadInt32(); // unknown          _3ewa->ReadInt32(); // unknown
769          SampleStartOffset = (uint16_t) _3ewa->ReadInt16();          SampleStartOffset = (uint16_t) _3ewa->ReadInt16();
770          _3ewa->ReadInt16(); // unknown          _3ewa->ReadInt16(); // unknown
# Line 595  namespace gig { Line 780  namespace gig {
780          uint8_t lfo3ctrl = _3ewa->ReadUint8();          uint8_t lfo3ctrl = _3ewa->ReadUint8();
781          LFO3Controller           = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits          LFO3Controller           = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits
782          LFO3Sync                 = lfo3ctrl & 0x20; // bit 5          LFO3Sync                 = lfo3ctrl & 0x20; // bit 5
783          InvertAttenuationControl = lfo3ctrl & 0x80; // bit 7          InvertAttenuationController = lfo3ctrl & 0x80; // bit 7
784          if (VCFType == vcf_type_lowpass) {          if (VCFType == vcf_type_lowpass) {
785              if (lfo3ctrl & 0x40) // bit 6              if (lfo3ctrl & 0x40) // bit 6
786                  VCFType = vcf_type_lowpassturbo;                  VCFType = vcf_type_lowpassturbo;
787          }          }
788          AttenuationControl = static_cast<attenuation_ctrl_t>(_3ewa->ReadUint8());          AttenuationController  = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
789          uint8_t lfo2ctrl       = _3ewa->ReadUint8();          uint8_t lfo2ctrl       = _3ewa->ReadUint8();
790          LFO2Controller         = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits          LFO2Controller         = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits
791          LFO2FlipPhase          = lfo2ctrl & 0x80; // bit 7          LFO2FlipPhase          = lfo2ctrl & 0x80; // bit 7
# Line 644  namespace gig { Line 829  namespace gig {
829          VCFVelocityDynamicRange = vcfvelocity % 5;          VCFVelocityDynamicRange = vcfvelocity % 5;
830          VCFVelocityCurve        = static_cast<curve_type_t>(vcfvelocity / 5);          VCFVelocityCurve        = static_cast<curve_type_t>(vcfvelocity / 5);
831          VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());          VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
832    
833            // get the corresponding velocity->volume table from the table map or create & calculate that table if it doesn't exist yet
834            uint32_t tableKey = (VelocityResponseCurve<<16) | (VelocityResponseDepth<<8) | VelocityResponseCurveScaling;
835            if (pVelocityTables->count(tableKey)) { // if key exists
836                pVelocityAttenuationTable = (*pVelocityTables)[tableKey];
837            }
838            else {
839                pVelocityAttenuationTable = new double[128];
840                switch (VelocityResponseCurve) { // calculate the new table
841                    case curve_type_nonlinear:
842                        for (int velocity = 0; velocity < 128; velocity++) {
843                            pVelocityAttenuationTable[velocity] =
844                                GIG_VELOCITY_TRANSFORM_NONLINEAR(((double)velocity),((double)VelocityResponseDepth),((double)VelocityResponseCurveScaling));
845                            if      (pVelocityAttenuationTable[velocity] > 1.0)   pVelocityAttenuationTable[velocity] = 1.0;
846                            else if (pVelocityAttenuationTable[velocity] < 1e-15) pVelocityAttenuationTable[velocity] = 0.0;
847                         }
848                         break;
849                    case curve_type_linear:
850                        for (int velocity = 0; velocity < 128; velocity++) {
851                            pVelocityAttenuationTable[velocity] =
852                                GIG_VELOCITY_TRANSFORM_LINEAR(((double)velocity),((double)VelocityResponseDepth),((double)VelocityResponseCurveScaling));
853                            if      (pVelocityAttenuationTable[velocity] > 1.0)   pVelocityAttenuationTable[velocity] = 1.0;
854                            else if (pVelocityAttenuationTable[velocity] < 1e-15) pVelocityAttenuationTable[velocity] = 0.0;
855                        }
856                        break;
857                    case curve_type_special:
858                        for (int velocity = 0; velocity < 128; velocity++) {
859                            pVelocityAttenuationTable[velocity] =
860                                GIG_VELOCITY_TRANSFORM_SPECIAL(((double)velocity),((double)VelocityResponseDepth),((double)VelocityResponseCurveScaling));
861                            if      (pVelocityAttenuationTable[velocity] > 1.0)   pVelocityAttenuationTable[velocity] = 1.0;
862                            else if (pVelocityAttenuationTable[velocity] < 1e-15) pVelocityAttenuationTable[velocity] = 0.0;
863                        }
864                        break;
865                    case curve_type_unknown:
866                    default:
867                        throw gig::Exception("Unknown transform curve type.");
868                }
869                (*pVelocityTables)[tableKey] = pVelocityAttenuationTable; // put the new table into the tables map
870            }
871        }
872    
873        leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
874            leverage_ctrl_t decodedcontroller;
875            switch (EncodedController) {
876                // special controller
877                case _lev_ctrl_none:
878                    decodedcontroller.type = leverage_ctrl_t::type_none;
879                    decodedcontroller.controller_number = 0;
880                    break;
881                case _lev_ctrl_velocity:
882                    decodedcontroller.type = leverage_ctrl_t::type_velocity;
883                    decodedcontroller.controller_number = 0;
884                    break;
885                case _lev_ctrl_channelaftertouch:
886                    decodedcontroller.type = leverage_ctrl_t::type_channelaftertouch;
887                    decodedcontroller.controller_number = 0;
888                    break;
889    
890                // ordinary MIDI control change controller
891                case _lev_ctrl_modwheel:
892                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
893                    decodedcontroller.controller_number = 1;
894                    break;
895                case _lev_ctrl_breath:
896                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
897                    decodedcontroller.controller_number = 2;
898                    break;
899                case _lev_ctrl_foot:
900                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
901                    decodedcontroller.controller_number = 4;
902                    break;
903                case _lev_ctrl_effect1:
904                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
905                    decodedcontroller.controller_number = 12;
906                    break;
907                case _lev_ctrl_effect2:
908                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
909                    decodedcontroller.controller_number = 13;
910                    break;
911                case _lev_ctrl_genpurpose1:
912                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
913                    decodedcontroller.controller_number = 16;
914                    break;
915                case _lev_ctrl_genpurpose2:
916                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
917                    decodedcontroller.controller_number = 17;
918                    break;
919                case _lev_ctrl_genpurpose3:
920                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
921                    decodedcontroller.controller_number = 18;
922                    break;
923                case _lev_ctrl_genpurpose4:
924                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
925                    decodedcontroller.controller_number = 19;
926                    break;
927                case _lev_ctrl_portamentotime:
928                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
929                    decodedcontroller.controller_number = 5;
930                    break;
931                case _lev_ctrl_sustainpedal:
932                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
933                    decodedcontroller.controller_number = 64;
934                    break;
935                case _lev_ctrl_portamento:
936                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
937                    decodedcontroller.controller_number = 65;
938                    break;
939                case _lev_ctrl_sostenutopedal:
940                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
941                    decodedcontroller.controller_number = 66;
942                    break;
943                case _lev_ctrl_softpedal:
944                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
945                    decodedcontroller.controller_number = 67;
946                    break;
947                case _lev_ctrl_genpurpose5:
948                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
949                    decodedcontroller.controller_number = 80;
950                    break;
951                case _lev_ctrl_genpurpose6:
952                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
953                    decodedcontroller.controller_number = 81;
954                    break;
955                case _lev_ctrl_genpurpose7:
956                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
957                    decodedcontroller.controller_number = 82;
958                    break;
959                case _lev_ctrl_genpurpose8:
960                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
961                    decodedcontroller.controller_number = 83;
962                    break;
963                case _lev_ctrl_effect1depth:
964                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
965                    decodedcontroller.controller_number = 91;
966                    break;
967                case _lev_ctrl_effect2depth:
968                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
969                    decodedcontroller.controller_number = 92;
970                    break;
971                case _lev_ctrl_effect3depth:
972                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
973                    decodedcontroller.controller_number = 93;
974                    break;
975                case _lev_ctrl_effect4depth:
976                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
977                    decodedcontroller.controller_number = 94;
978                    break;
979                case _lev_ctrl_effect5depth:
980                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
981                    decodedcontroller.controller_number = 95;
982                    break;
983    
984                // unknown controller type
985                default:
986                    throw gig::Exception("Unknown leverage controller type.");
987            }
988            return decodedcontroller;
989        }
990    
991        DimensionRegion::~DimensionRegion() {
992            Instances--;
993            if (!Instances) {
994                // delete the velocity->volume tables
995                VelocityTableMap::iterator iter;
996                for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
997                    double* pTable = iter->second;
998                    if (pTable) delete[] pTable;
999                }
1000                pVelocityTables->clear();
1001                delete pVelocityTables;
1002                pVelocityTables = NULL;
1003            }
1004        }
1005    
1006        /**
1007         * Returns the correct amplitude factor for the given \a MIDIKeyVelocity.
1008         * All involved parameters (VelocityResponseCurve, VelocityResponseDepth
1009         * and VelocityResponseCurveScaling) involved are taken into account to
1010         * calculate the amplitude factor. Use this method when a key was
1011         * triggered to get the volume with which the sample should be played
1012         * back.
1013         *
1014         * @param MIDIKeyVelocity  MIDI velocity value of the triggered key (between 0 and 127)
1015         * @returns                amplitude factor (between 0.0 and 1.0)
1016         */
1017        double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
1018            return pVelocityAttenuationTable[MIDIKeyVelocity];
1019      }      }
1020    
1021    
# Line 681  namespace gig { Line 1053  namespace gig {
1053                      pDimensionDefinitions[i].bits      = bits;                      pDimensionDefinitions[i].bits      = bits;
1054                      pDimensionDefinitions[i].zones     = 0x01 << bits; // = pow(2,bits)                      pDimensionDefinitions[i].zones     = 0x01 << bits; // = pow(2,bits)
1055                      pDimensionDefinitions[i].split_type = (dimension == dimension_layer ||                      pDimensionDefinitions[i].split_type = (dimension == dimension_layer ||
1056                                                             dimension == dimension_samplechannel) ? split_type_bit                                                             dimension == dimension_samplechannel ||
1057                                                                                                   : split_type_normal;                                                             dimension == dimension_releasetrigger) ? split_type_bit
1058                                                                                                      : split_type_normal;
1059                      pDimensionDefinitions[i].ranges = NULL; // it's not possible to check velocity dimensions for custom defined ranges at this point                      pDimensionDefinitions[i].ranges = NULL; // it's not possible to check velocity dimensions for custom defined ranges at this point
1060                      pDimensionDefinitions[i].zone_size  =                      pDimensionDefinitions[i].zone_size  =
1061                          (pDimensionDefinitions[i].split_type == split_type_normal) ? 128 / pDimensionDefinitions[i].zones                          (pDimensionDefinitions[i].split_type == split_type_normal) ? 128 / pDimensionDefinitions[i].zones
# Line 780  namespace gig { Line 1153  namespace gig {
1153       * @see             Dimensions       * @see             Dimensions
1154       */       */
1155      DimensionRegion* Region::GetDimensionRegionByValue(uint Dim4Val, uint Dim3Val, uint Dim2Val, uint Dim1Val, uint Dim0Val) {      DimensionRegion* Region::GetDimensionRegionByValue(uint Dim4Val, uint Dim3Val, uint Dim2Val, uint Dim1Val, uint Dim0Val) {
1156          unsigned int bits[5] = {Dim0Val,Dim1Val,Dim2Val,Dim3Val,Dim4Val};          uint8_t bits[5] = {Dim0Val,Dim1Val,Dim2Val,Dim3Val,Dim4Val};
1157          for (uint i = 0; i < Dimensions; i++) {          for (uint i = 0; i < Dimensions; i++) {
1158              switch (pDimensionDefinitions[i].split_type) {              switch (pDimensionDefinitions[i].split_type) {
1159                  case split_type_normal:                  case split_type_normal:
# Line 789  namespace gig { Line 1162  namespace gig {
1162                  case split_type_customvelocity:                  case split_type_customvelocity:
1163                      bits[i] = VelocityTable[bits[i]];                      bits[i] = VelocityTable[bits[i]];
1164                      break;                      break;
1165                  // else the value is already the sought dimension bit number                  case split_type_bit: // the value is already the sought dimension bit number
1166                        const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
1167                        bits[i] = bits[i] & limiter_mask; // just make sure the value don't uses more bits than allowed
1168                        break;
1169              }              }
1170          }          }
1171          return GetDimensionRegionByBit(bits[4],bits[3],bits[2],bits[1],bits[0]);          return GetDimensionRegionByBit(bits[4],bits[3],bits[2],bits[1],bits[0]);
# Line 995  namespace gig { Line 1371  namespace gig {
1371          return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;          return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
1372      }      }
1373    
1374        /**
1375         * Returns the instrument with the given index.
1376         *
1377         * @returns  sought instrument or NULL if there's no such instrument
1378         */
1379        Instrument* File::GetInstrument(uint index) {
1380            if (!pInstruments) LoadInstruments();
1381            if (!pInstruments) return NULL;
1382            InstrumentsIterator = pInstruments->begin();
1383            for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
1384                if (i == index) return *InstrumentsIterator;
1385                InstrumentsIterator++;
1386            }
1387            return NULL;
1388        }
1389    
1390      void File::LoadInstruments() {      void File::LoadInstruments() {
1391          RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);          RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
1392          if (lstInstruments) {          if (lstInstruments) {

Legend:
Removed from v.2  
changed lines
  Added in v.241

  ViewVC Help
Powered by ViewVC