2 |
* * |
* * |
3 |
* libgig - C++ cross-platform Gigasampler format file access library * |
* libgig - C++ cross-platform Gigasampler format file access library * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003-2009 by Christian Schoenebeck * |
* Copyright (C) 2003-2013 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 * |
1581 |
*/ |
*/ |
1582 |
DimensionRegion::DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src) : DLS::Sampler(_3ewl) { |
DimensionRegion::DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src) : DLS::Sampler(_3ewl) { |
1583 |
Instances++; |
Instances++; |
1584 |
|
//NOTE: I think we cannot call CopyAssign() here (in a constructor) as long as its a virtual method |
1585 |
*this = src; // default memberwise shallow copy of all parameters |
*this = src; // default memberwise shallow copy of all parameters |
1586 |
pParentList = _3ewl; // restore the chunk pointer |
pParentList = _3ewl; // restore the chunk pointer |
1587 |
|
|
1597 |
pSampleLoops[k] = src.pSampleLoops[k]; |
pSampleLoops[k] = src.pSampleLoops[k]; |
1598 |
} |
} |
1599 |
} |
} |
1600 |
|
|
1601 |
|
/** |
1602 |
|
* Make a (semi) deep copy of the DimensionRegion object given by @a orig |
1603 |
|
* and assign it to this object. |
1604 |
|
* |
1605 |
|
* Note that all sample pointers referenced by @a orig are simply copied as |
1606 |
|
* memory address. Thus the respective samples are shared, not duplicated! |
1607 |
|
* |
1608 |
|
* @param orig - original DimensionRegion object to be copied from |
1609 |
|
*/ |
1610 |
|
void DimensionRegion::CopyAssign(const DimensionRegion* orig) { |
1611 |
|
// delete all allocated data first |
1612 |
|
if (VelocityTable) delete [] VelocityTable; |
1613 |
|
if (pSampleLoops) delete [] pSampleLoops; |
1614 |
|
|
1615 |
|
// backup parent list pointer |
1616 |
|
RIFF::List* p = pParentList; |
1617 |
|
|
1618 |
|
//NOTE: copy code copied from assignment constructor above, see comment there as well |
1619 |
|
|
1620 |
|
*this = *orig; // default memberwise shallow copy of all parameters |
1621 |
|
pParentList = p; // restore the chunk pointer |
1622 |
|
|
1623 |
|
// deep copy of owned structures |
1624 |
|
if (orig->VelocityTable) { |
1625 |
|
VelocityTable = new uint8_t[128]; |
1626 |
|
for (int k = 0 ; k < 128 ; k++) |
1627 |
|
VelocityTable[k] = orig->VelocityTable[k]; |
1628 |
|
} |
1629 |
|
if (orig->pSampleLoops) { |
1630 |
|
pSampleLoops = new DLS::sample_loop_t[orig->SampleLoops]; |
1631 |
|
for (int k = 0 ; k < orig->SampleLoops ; k++) |
1632 |
|
pSampleLoops[k] = orig->pSampleLoops[k]; |
1633 |
|
} |
1634 |
|
} |
1635 |
|
|
1636 |
/** |
/** |
1637 |
* Updates the respective member variable and updates @c SampleAttenuation |
* Updates the respective member variable and updates @c SampleAttenuation |
2961 |
} |
} |
2962 |
return NULL; |
return NULL; |
2963 |
} |
} |
2964 |
|
|
2965 |
|
/** |
2966 |
|
* Make a (semi) deep copy of the Region object given by @a orig |
2967 |
|
* and assign it to this object. |
2968 |
|
* |
2969 |
|
* Note that all sample pointers referenced by @a orig are simply copied as |
2970 |
|
* memory address. Thus the respective samples are shared, not duplicated! |
2971 |
|
* |
2972 |
|
* @param orig - original Region object to be copied from |
2973 |
|
*/ |
2974 |
|
void Region::CopyAssign(const Region* orig) { |
2975 |
|
// handle base classes |
2976 |
|
DLS::Region::CopyAssign(orig); |
2977 |
|
|
2978 |
|
// handle own member variables |
2979 |
|
for (int i = Dimensions - 1; i >= 0; --i) { |
2980 |
|
DeleteDimension(&pDimensionDefinitions[i]); |
2981 |
|
} |
2982 |
|
Layers = 0; // just to be sure |
2983 |
|
for (int i = 0; i < orig->Dimensions; i++) { |
2984 |
|
// we need to copy the dim definition here, to avoid the compiler |
2985 |
|
// complaining about const-ness issue |
2986 |
|
dimension_def_t def = orig->pDimensionDefinitions[i]; |
2987 |
|
AddDimension(&def); |
2988 |
|
} |
2989 |
|
for (int i = 0; i < 256; i++) { |
2990 |
|
if (pDimensionRegions[i] && orig->pDimensionRegions[i]) { |
2991 |
|
pDimensionRegions[i]->CopyAssign( |
2992 |
|
orig->pDimensionRegions[i] |
2993 |
|
); |
2994 |
|
} |
2995 |
|
} |
2996 |
|
Layers = orig->Layers; |
2997 |
|
} |
2998 |
|
|
2999 |
|
|
3000 |
// *************** MidiRule *************** |
// *************** MidiRule *************** |
3237 |
MidiRule* Instrument::GetMidiRule(int i) { |
MidiRule* Instrument::GetMidiRule(int i) { |
3238 |
return pMidiRules[i]; |
return pMidiRules[i]; |
3239 |
} |
} |
3240 |
|
|
3241 |
|
/** |
3242 |
|
* Make a (semi) deep copy of the Instrument object given by @a orig |
3243 |
|
* and assign it to this object. |
3244 |
|
* |
3245 |
|
* Note that all sample pointers referenced by @a orig are simply copied as |
3246 |
|
* memory address. Thus the respective samples are shared, not duplicated! |
3247 |
|
* |
3248 |
|
* @param orig - original Instrument object to be copied from |
3249 |
|
*/ |
3250 |
|
void Instrument::CopyAssign(const Instrument* orig) { |
3251 |
|
// handle base class |
3252 |
|
// (without copying DLS region stuff) |
3253 |
|
DLS::Instrument::CopyAssignCore(orig); |
3254 |
|
|
3255 |
|
// handle own member variables |
3256 |
|
Attenuation = orig->Attenuation; |
3257 |
|
EffectSend = orig->EffectSend; |
3258 |
|
FineTune = orig->FineTune; |
3259 |
|
PitchbendRange = orig->PitchbendRange; |
3260 |
|
PianoReleaseMode = orig->PianoReleaseMode; |
3261 |
|
DimensionKeyRange = orig->DimensionKeyRange; |
3262 |
|
|
3263 |
|
// free old midi rules |
3264 |
|
for (int i = 0 ; pMidiRules[i] ; i++) { |
3265 |
|
delete pMidiRules[i]; |
3266 |
|
} |
3267 |
|
//TODO: MIDI rule copying |
3268 |
|
pMidiRules[0] = NULL; |
3269 |
|
|
3270 |
|
// delete all old regions |
3271 |
|
while (Regions) DeleteRegion(GetFirstRegion()); |
3272 |
|
// create new regions and copy them from original |
3273 |
|
{ |
3274 |
|
RegionList::const_iterator it = orig->pRegions->begin(); |
3275 |
|
for (int i = 0; i < orig->Regions; ++i, ++it) { |
3276 |
|
Region* dstRgn = AddRegion(); |
3277 |
|
//NOTE: Region does semi-deep copy ! |
3278 |
|
dstRgn->CopyAssign( |
3279 |
|
static_cast<gig::Region*>(*it) |
3280 |
|
); |
3281 |
|
} |
3282 |
|
} |
3283 |
|
|
3284 |
|
UpdateRegionKeyTable(); |
3285 |
|
} |
3286 |
|
|
3287 |
|
|
3288 |
// *************** Group *************** |
// *************** Group *************** |
3682 |
pInstruments->push_back(pInstrument); |
pInstruments->push_back(pInstrument); |
3683 |
return pInstrument; |
return pInstrument; |
3684 |
} |
} |
3685 |
|
|
3686 |
|
/** @brief Add a duplicate of an existing instrument. |
3687 |
|
* |
3688 |
|
* Duplicates the instrument definition given by @a orig and adds it |
3689 |
|
* to this file. This allows in an instrument editor application to |
3690 |
|
* easily create variations of an instrument, which will be stored in |
3691 |
|
* the same .gig file, sharing i.e. the same samples. |
3692 |
|
* |
3693 |
|
* Note that all sample pointers referenced by @a orig are simply copied as |
3694 |
|
* memory address. Thus the respective samples are shared, not duplicated! |
3695 |
|
* |
3696 |
|
* You have to call Save() to make this persistent to the file. |
3697 |
|
* |
3698 |
|
* @param orig - original instrument to be copied |
3699 |
|
* @returns duplicated copy of the given instrument |
3700 |
|
*/ |
3701 |
|
Instrument* File::AddDuplicateInstrument(const Instrument* orig) { |
3702 |
|
Instrument* instr = AddInstrument(); |
3703 |
|
instr->CopyAssign(orig); |
3704 |
|
return instr; |
3705 |
|
} |
3706 |
|
|
3707 |
/** @brief Delete an instrument. |
/** @brief Delete an instrument. |
3708 |
* |
* |