Files
ss/include/d/snd/d_snd_sound.h
T
2025-09-13 10:59:41 +02:00

233 lines
7.1 KiB
C++

#ifndef D_SND_SOUND_H
#define D_SND_SOUND_H
#include "common.h"
#include "d/snd/d_snd_types.h"
#include "nw4r/snd/snd_SeqTrack.h"
#include "nw4r/snd/snd_SoundHandle.h"
#include "nw4r/snd/snd_SoundStartable.h"
#include "nw4r/ut/ut_list.h"
// Not sure, handles a bunch of floats, exists in a ton of variants
class dSndControl_c {
public:
dSndControl_c(f32 value, f32 min, f32 max)
: mResetValue(value),
mMax(max),
mMin(min),
mCurrValue(value),
mStartValue(value),
mTargetValue(value),
mDuration(0),
mTimer(0),
mIsLinked(false) {}
~dSndControl_c() {}
virtual void configure(f32 value, f32 min, f32 max); // vt 0x08
virtual void reset(); // vt 0x0C
virtual void set(f32 value, s32 frames); // vt 0x10
virtual void calc(); // vt 0x14
virtual void stop(); // vt 0x18
bool isLinked() const {
return mIsLinked;
}
void setLinked(bool linked) {
mIsLinked = linked;
}
f32 getCurrentValue() const {
return mCurrValue;
}
f32 getTargetValue() const {
return mTargetValue;
}
bool isFinished() const {
return mTimer >= mDuration;
}
protected:
/* 0x04 */ f32 mResetValue;
/* 0x08 */ f32 mMax;
/* 0x0C */ f32 mMin;
/* 0x10 */ f32 mCurrValue;
/* 0x14 */ f32 mStartValue;
/* 0x18 */ f32 mTargetValue;
/* 0x1C */ s32 mDuration;
/* 0x20 */ s32 mTimer;
/* 0x24 */ nw4r::ut::Node mNode;
/* 0x2C */ bool mIsLinked;
};
class dSndControlSound_c : public dSndControl_c {
public:
dSndControlSound_c(f32 value, f32 min, f32 max) : dSndControl_c(value, min, max) {}
virtual void apply(dSndSound_c *pHandle) = 0; // vt 0x1C
private:
};
class dSndControlSoundVolume_c : public dSndControlSound_c {
public:
dSndControlSoundVolume_c() : dSndControlSound_c(1.0f, 0.0f, 2.0f) {}
virtual void apply(dSndSound_c *pHandle) override;
};
class dSndControlSoundPitch_c : public dSndControlSound_c {
public:
dSndControlSoundPitch_c() : dSndControlSound_c(1.0f, 0.25f, 4.0f) {}
virtual void apply(dSndSound_c *pHandle) override;
};
/** Stores pitch as a value from -24 to 24, exponentially scaling it to 0.25-4.0 */
class dSndControlSoundPitchLinear_c : public dSndControlSound_c {
public:
dSndControlSoundPitchLinear_c();
virtual void apply(dSndSound_c *pHandle) override;
virtual void set(f32 value, s32 frames) override;
void setControl(dSndControlSound_c *ctrl) {
mpOtherControl = ctrl;
}
private:
/* 0x30 */ dSndControlSound_c *mpOtherControl;
};
class dSndControlSoundSeqTempoRatio_c : public dSndControlSound_c {
public:
dSndControlSoundSeqTempoRatio_c() : dSndControlSound_c(1.0f, 0.25f, 4.0f) {}
virtual void apply(dSndSound_c *pHandle) override;
};
class dSndControlSoundSeqTrackVolume_c : public dSndControlSound_c {
public:
dSndControlSoundSeqTrackVolume_c() : dSndControlSound_c(1.0f, 0.0f, 2.0f) {}
virtual void apply(dSndSound_c *pHandle) override;
void setMask(u16 mask) {
mMask = mask;
}
private:
/* 0x2E */ u16 mMask;
};
class dSndControlSoundStrmTrackVolume_c : public dSndControlSound_c {
public:
dSndControlSoundStrmTrackVolume_c() : dSndControlSound_c(1.0f, 0.0f, 2.0f) {}
virtual void apply(dSndSound_c *pHandle) override;
void setMask(u16 mask) {
mMask = mask;
}
private:
/* 0x2E */ u16 mMask;
};
class dSndSound_c : public nw4r::snd::SoundHandle {
public:
dSndSound_c();
~dSndSound_c();
virtual void cancel(); // 0x08
virtual void calc(); // 0x0C
virtual void fadeIn(u32 id, s32 fadeFrames); // 0x10
virtual nw4r::snd::SoundStartable::StartResult prepareSound(u32 soundId, u32 startOffset); // 0x14
virtual nw4r::snd::SoundStartable::StartResult prepareSound(const char *label, u32 startOffset); // 0x18
virtual void onPreparing(u32 soundId, u32 startOffset); // 0x1C
virtual void stop(s32 fadeFrames); // 0x20
virtual void pause(bool pauseFlag, s32 fadeFrames); // 0x24
bool isStrmSound();
bool isWaveSound();
bool isSeqSound();
f32 getCurrentStrmTrackVolume(u32 index) const;
void setVolume(f32 volume, s32 frames);
void setPitchRelated(f32 pitch, s32 frames);
void setLinearPitch(f32 pitch, s32 frames);
void setTrackVolume(u16 trackFlags, f32 volume, s32 frames);
void setStrmTrackVolume(u16 trackFlags, f32 volume, s32 frames);
void setSingleSeqTrackVolume(u16 index, f32 volume, s32 frames);
void setSingleStrmTrackVolume(u16 index, f32 volume, s32 frames);
// why f32 frames?
void setEachSeqTrackVolume(u16 trackFlags, f32 frames);
void setEachStrmTrackVolume(u16 trackFlags, f32 frames);
void setSeqTempoRatio(f32 ratio, s32 frames);
void setSeqTrackMute(u16 trackFlags, nw4r::snd::SeqMute mute);
void forceStop();
s32 readSeqTrackVariable(int varNo);
void writeSeqTrackVariable(int varNo, s16 value);
void linkCtrl(dSndControlSound_c *);
void unlinkCtrl(dSndControlSound_c *);
bool isPlaying() const {
return mIsRunning && !mIsFadingOut && IsAttachedSound();
}
bool isPlayingSoundId(u32 soundId) const {
return mIsRunning && !mIsFadingOut && GetId() == soundId;
}
bool isPreparingSoundId(u32 soundId) const {
return mIsPreparing && !mIsRunning && GetId() == soundId;
}
bool isFadingOut() const {
return mIsFadingOut && IsAttachedSound();
}
bool isPreparingSoundIdWithStartOffset(u32 soundId, u32 offset) const {
return isPreparingSoundId(soundId) && (offset == 0 || mPrevStartOffset == offset);
}
bool hasState() const {
return mIsRunning || mIsPreparing || IsAttachedSound();
}
bool isPaused() const {
return mPauseFlag;
}
protected:
bool isRunning() const {
return mIsRunning && IsAttachedSound();
}
bool isPreparing() const {
return mIsPreparing && !mIsRunning;
}
void resetControls();
void resetTrackVolumes();
void setControlValue(dSndControlSound_c *ctrl, f32 value, s32 frames);
/* 0x08 */ nw4r::ut::Node mBgmMgrNode;
/* 0x10 */ u32 mPrevStartOffset;
/* 0x14 */ bool mIsPreparing;
/* 0x15 */ bool mPauseFlag;
/* 0x16 */ bool mIsRunning;
/* 0x17 */ bool mIsFadingOut;
/* 0x18 */ dSndControlSoundVolume_c mCtrlVolume;
/* 0x48 */ dSndControlSoundPitch_c mCtrlPitch;
/* 0x78 */ dSndControlSoundPitchLinear_c mLinearPitch;
/* 0xAC */ dSndControlSoundSeqTrackVolume_c *mpCtrlSeqTrackVolume;
/* 0xB0 */ dSndControlSoundStrmTrackVolume_c *mpCtrlStrmTrackVolume;
/* 0xB4 */ dSndControlSoundSeqTempoRatio_c mpCtrlSeqTempoRatio;
/* 0xE4 */ nw4r::ut::List mList;
};
#endif