Skip to content

Commit

Permalink
SOUND: Load XACT SoundBank transition parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
DrMcCoy committed Jan 6, 2019
1 parent de75868 commit 2267cb8
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 15 deletions.
60 changes: 55 additions & 5 deletions src/sound/xactsoundbank.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,31 @@ class XACTSoundBank {
kCrossfadeLogarithmic = 2
};

enum TransitionSource {
kTransitionSourceImmediate = 0x00, ///< Transition immediately.
kTransitionSourceMarker = 0x01, ///< Transition on a marker within a range.
kTransitionSourceRandomMarker = 0x02, ///< Transition on a random marker within a range.
kTransitionSourceEndOfLoop = 0x04, ///< Transition on a loop end.
kTransitionSourceEndOfSound = 0x08 ///< Transition at the end of the sound.
};

enum TransitionDestination {
kTransitionDestinationBeginning = 0x00, ///< Transition to the beginning.
kTransitionDestinationAlignedTime = 0x01, ///< Transition to the same time.
kTransitionDestinationAlignedMarker = 0x02, ///< Transition to the same marker.
kTransitionDestinationMarker = 0x04, ///< Transition to a marker within a range.
kTransitionDestinationRandomMarker = 0x08 ///< Transition to a random marker within a range.
};

enum TransitionEffect {
kTransitionEffectNone = 0x00, ///< No effect.
kTransitionEffectCrossfade = 0x01, ///< Crossfade.
kTransitionEffectSound = 0x02, ///< Use a transitional sound.
kTransitionEffectSoundFadeTo = 0x03, ///< Fade into a transitional sound.
kTransitionEffectSoundFadeFrom = 0x06, ///< Fade from a transitional sound.
kTransitionEffectSoundFadeToFrom = 0x07 ///< Fade into and from a transitional sound.
};

struct Parameters3D {
Mode3D mode;

Expand Down Expand Up @@ -408,12 +433,32 @@ class XACTSoundBank {
typedef std::vector<CueVariation> CueVariations;

struct Transition {
Common::UString from;
Common::UString to;
size_t from; ///< Sound index to transition from.
size_t to; ///< Sound index to transition to.

TransitionSource sourceWhen; ///< When to begin transitioning.
TransitionDestination destinationWhen; ///< When to transition to.

Common::UString style;
TransitionEffect effect; ///< The effect to use during transitioning.

Common::UString parameters[5];
size_t transitionSound; ///< Sound index to use as a transition.

uint16 sourceFadeDuration; ///< Source fade-out duration in milliseconds.
uint16 destinationFadeDuration; ///< Destination fade-in duration in milliseconds.

uint32 sourceMarkerLow; ///< Lower bound of a marker in the source.
uint32 sourceMarkerHigh; ///< Upper bound of a marker in the source.

uint32 destinationMarkerLow; ///< Lower bound of a marker in the destination.
uint32 destinationMarkerHigh; ///< Upper bound of a marker in the destination.

Transition() :
from(kSoundSilence), to(kSoundSilence),
sourceWhen(kTransitionSourceImmediate), destinationWhen(kTransitionDestinationBeginning),
effect(kTransitionEffectNone), transitionSound(kSoundSilence),
sourceFadeDuration(0), destinationFadeDuration(0),
sourceMarkerLow(0), sourceMarkerHigh(0), destinationMarkerLow(0), destinationMarkerHigh(0) {
}
};

typedef std::vector<Transition> Transitions;
Expand Down Expand Up @@ -444,9 +489,14 @@ class XACTSoundBank {
SelectMethod variationSelectMethod;

CueVariations variations; ///< All the cue variations in the cue.

uint8 transitionTrigger;
Transitions transitions;

Cue() : sequential(false), crossfade(false), stopOnStarve(false), interactive(false) { }
Cue() :
sequential(false), crossfade(false), stopOnStarve(false), interactive(false),
transitionTrigger(0) {
}
};

typedef std::vector<WaveBank> WaveBanks;
Expand Down
54 changes: 45 additions & 9 deletions src/sound/xactsoundbank_ascii.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,28 @@ static size_t getAmount(Common::StreamTokenizer &tokenizer, Common::SeekableRead
return getAmount(tokenizer.getToken(stream));
}

size_t XACTSoundBank_ASCII::findSound(const Common::UString &name, Cue &cue) const {
if (name == "0")
return kSoundSilence;

for (size_t i = 0; i < cue.variations.size(); i++)
if (cue.variations[i].soundName == name)
return i;

return kSoundSilence;
}

size_t XACTSoundBank_ASCII::findSound(const Common::UString &name) const {
if (name == "0")
return kSoundSilence;

SoundMap::const_iterator it = _soundMap.find(name);
if (it == _soundMap.end())
return kSoundSilence;

return it->second - _sounds.data();
}

void XACTSoundBank_ASCII::load(Common::SeekableReadStream &xsb) {
Common::StreamTokenizer tokenizer(Common::StreamTokenizer::kRuleIgnoreAll);
tokenizer.addSeparator(' ');
Expand Down Expand Up @@ -441,19 +463,33 @@ void XACTSoundBank_ASCII::load(Common::SeekableReadStream &xsb) {

cue->transitions.resize(transitionCount);
for (Transitions::iterator transition = cue->transitions.begin(); transition != cue->transitions.end(); ++transition) {
tokenizer.getTokens(xsb, tokens, 8);
tokenizer.getTokens(xsb, tokens, 2);
tokenizer.nextChunk(xsb);

transition->from = tokens[0];
transition->to = tokens[1];
transition->from = findSound(tokens[0], *cue);
transition->to = findSound(tokens[1], *cue);

if (tokens.size() > 2)
transition->transitionSound = findSound(tokens[2]);

if (tokens.size() > 3) {
if (tokens[3] == "Crossfade")
transition->effect = kTransitionEffectCrossfade;
else if (tokens[3] == "Sound")
transition->effect = kTransitionEffectSoundFadeTo;
}

transition->style = tokens[3];
// The 4th token might be destinationWhen, but it's always 0 in Jade Empire

transition->parameters[0] = tokens[2];
transition->parameters[1] = tokens[4];
transition->parameters[2] = tokens[5];
transition->parameters[3] = tokens[6];
transition->parameters[4] = tokens[7];
if (tokens.size() > 5) {
if (tokens[5] == "End")
transition->sourceWhen = kTransitionSourceEndOfSound;
}

if (tokens.size() > 7) {
transition->sourceFadeDuration = getNumber(tokens[6]);
transition->destinationFadeDuration = getNumber(tokens[7]);
}
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/sound/xactsoundbank_ascii.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ class XACTSoundBank_ASCII : public XACTSoundBank {

private:
void load(Common::SeekableReadStream &xsb);

size_t findSound(const Common::UString &name, Cue &cue) const;
size_t findSound(const Common::UString &name) const;
};

} // End of namespace Sound
Expand Down
50 changes: 49 additions & 1 deletion src/sound/xactsoundbank_binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,13 @@ void XACTSoundBank_Binary::readCues(Common::SeekableReadStream &xsb, uint32 xsbF
const uint16 fadeParamIndex = xsb.readUint16LE();

xsb.skip(2); // Unknown
xsb.skip(4); // Unknown. Some kind of offset? Can be 0x07FFFFFF.

uint32 offsetTransitions = 0;
offsetTransitions += xsb.readByte();
offsetTransitions += xsb.readByte() << 8;
offsetTransitions += xsb.readByte() << 16;

cue.transitionTrigger = xsb.readByte() >> 3;

if (!(xsbFlags & kXSBNoCueNames) && (offsetName != 0xFFFFFFFF)) {
xsb.seek(offsetName);
Expand Down Expand Up @@ -234,6 +240,48 @@ void XACTSoundBank_Binary::readCues(Common::SeekableReadStream &xsb, uint32 xsbF
cue.variations.back().weightMin = kWeightMinimum;
cue.variations.back().weightMax = kWeightMaximum;
}

if (cue.interactive && (offsetTransitions != 0x00FFFFFF)) {
xsb.seek(offsetTransitions);

const uint32 transitionCount = xsb.readUint32LE();
cue.transitions.resize(transitionCount);

size_t transFrom = kSoundSilence;
size_t transTo = 0;

for (Transitions::iterator t = cue.transitions.begin(); t != cue.transitions.end(); ++t) {
t->from = transFrom;
t->to = transTo;

const uint16 transFlags = xsb.readUint16LE();

t->sourceWhen = static_cast<TransitionSource> ((transFlags ) & 0xF);
t->destinationWhen = static_cast<TransitionDestination>( transFlags >> 7 & 0xF);
t->effect = static_cast<TransitionEffect> ((transFlags >> 4) & 0x7);

t->transitionSound = xsb.readUint16LE();
if (t->transitionSound == 0xFFFF)
t->transitionSound = kSoundSilence;

t->sourceFadeDuration = xsb.readUint16LE();
t->destinationFadeDuration = xsb.readUint16LE();

t->sourceMarkerLow = xsb.readUint32LE();
t->sourceMarkerHigh = xsb.readUint32LE();

t->destinationMarkerLow = xsb.readUint32LE();
t->destinationMarkerHigh = xsb.readUint32LE();

if (transFrom == ++transTo)
transTo++;

if (transTo >= cue.variations.size()) {
transFrom++;
transTo = kSoundSilence;
}
}
}
}
}

Expand Down

0 comments on commit 2267cb8

Please sign in to comment.