Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Sequences #2066

Merged
merged 55 commits into from
Dec 9, 2022
Merged

Conversation

leggettc18
Copy link
Contributor

@leggettc18 leggettc18 commented Dec 1, 2022

Adds support for existing Custom Audio Sequences into the game, specifically any Sequences useable in N64 OoT Rando should be useable here. To create your custom sequence patch OTR, I have also written a small CLI utility that can be used until something more robust is made. Download the version built for your operating system here and follow the instructions on this page to create your patch OTR. You should end up with a file called custom-music.otr in the mods folder of your SoH installation. This tool is intended to parse pairs of .seq and .meta files, like N64 OoT Rando does (more details).

Once you have your patch OTR in your mods folder, you can select your custom sequences in the Sfx Editor, and they will be included in the randomization when you click the "Randomize All" button. They are also separated into BGM and Fanfare categories according to the .meta file contents, currently the custom BGM sequences are available for all BGM categories in the editor.

Additionally, this PR adds a few new things to the Sfx Editor.

  • Each individual track has their own Randomize button now. So if you click Randomize All and get a couple of tracks you don't like, you can just click Randomize on those tracks without having to change all of them again or scroll through the entire list to find a specific one you want.
  • Hyrule Field Morning is removed from the list, it will now play normally if Hyrule Field has not been swapped, or it will swap to the same sequence as Hyrule Field does. This way you will get the same track whether you enter Hyrule Field during the day, or enter at night and the music plays after transitioning to morning.
  • Added an Options Tab to the SfxEditor with two new options. Personally I recommend enabling both of them, but your mileage may vary:
    • Disable Enemy Proximity Music: This disables the switch to the enemy bgm that normally happens when you approach an enemy. This allows you to prevent your custom sequences being interrupted by getting close to an enemy, or you can even use it with no custom sequences if you just don't like the Battle BGM.
    • EXPERIMENTAL: Lower Octaves of Unplayable Notes: Certain sequences from well-known sources that I've tested have an issue where they will attempt to play a note with too high of a frequency. When this happens, the game will instead play the highest possible frequency, which usually sounds pretty bad. This isn't an SoH exclusive issue either, this happens on n64 emulators as well, but the resulting note is lower (presumably due to hardware quirks) so it isn't quite as noticeable there. Checking this box will cause it to halve the frequency instead of clamping it, causing it to play the right note at a lower octave, which usually sounds better. It seems to work pretty well in every sequence I've tested, but I've marked this feature as experimental because it may be possible for this to have undesired effects in some sequences.

I would like to thank the entire SoH Development team for helping me make this a reality. Additionally, I would like to give a Special Thanks to two specific people:

  • @MNGoldenEagle for sharing his extensive knowledge to help me debug issues related to OoT's audio engine.
  • @darkangel93x (of Darunia's Joy fame) for answering questions and helping me debug a few issues with specific custom sequences I was having.

EDIT: v0.2 of SequenceOTRizer has been released

Build Artifacts

Certain sequences wouldn't play on the file select and title screen
because they were too large to be cached.
Added octave drop to experimental features, which drops the octave of
a note that is too high for the audio engine to actually play. Without
this, some custom sequences have notes which cap at a specific value
and sound terrible. At least with this they will still harmonize with
the other notes. Experimental tab added to the SfxEditor to house
the checkbox for the octave drop feature.
To be clear, fixes the more rampant portable ocarina bug present in my earlier builds, not the authentic one.
For miniboss fights and SfxEditor previews.
Copy link
Contributor

@briaguya-ai briaguya-ai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall this is looking really great! (and from what i can tell testing is going quite well too!) left a few comments in there (nothing major, mostly just places where a comment or two would help clear up what's going on)

looking forward to getting this merged!

soh/soh/Enhancements/sfx-editor/SfxEditor.cpp Outdated Show resolved Hide resolved
Comment on lines +9 to +11
#include "../../OTRGlobals.h"
#include <Utils/StringHelper.h>
#include "../../UIWidgets.hpp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably not something that needs to be fixed in this PR (mostly because it's kind of an all over the place thing in the codebase at the moment), but it seems like we shouldn't need these relative paths with our cmake include dir config

soh/soh/Enhancements/sfx-editor/SfxEditor.cpp Outdated Show resolved Hide resolved
soh/soh/Enhancements/sfx-editor/SfxEditor.cpp Outdated Show resolved Hide resolved
soh/soh/Enhancements/sfx-editor/SfxEditor.h Outdated Show resolved Hide resolved
soh/src/code/audio_load.c Outdated Show resolved Hide resolved
Comment on lines 573 to 574
//index = ((u16*)gAudioContext.sequenceFontTable)[seqId];
//numFonts = gAudioContext.sequenceFontTable[index++];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i know this isn't part of the change but might as well delete these lines instead of just having them commented out

soh/src/code/audio_load.c Outdated Show resolved Hide resolved
@@ -1507,7 +1537,7 @@ s32 AudioLoad_SlowLoadSeq(s32 seqId, u8* ramAddr, s8* isDone) {

slowLoad->sample.sampleAddr = NULL;
slowLoad->isDone = isDone;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick, extra space

soh/src/code/audio_seqplayer.c Outdated Show resolved Hide resolved
Copy link
Contributor

@dcvz dcvz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments but looking great!

std::vector<std::string> splitFileName = StringHelper::Split(fileName, "_");
std::string sequenceName = splitFileName[0];
SeqType type = SEQ_BGM_CUSTOM;
if (splitFileName[splitFileName.size() - 1] == "fanfare" || splitFileName[splitFileName.size() - 1] == "Fanfare") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does tolower() not work here? then you can simplify this check

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually call tolower() in SequenceOTRizer now when actually writing the filename so technically I could get rid of the capital letter check here. Does retro lowercase the _tag at the end? If not I can refactor this to use tolower().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 376 to 380
if (seqId != newSeqId) {
gAudioContext.seqReplaced[playerIdx] = 1;
} else {
gAudioContext.seqReplaced[playerIdx] = 0;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (seqId != newSeqId) {
gAudioContext.seqReplaced[playerIdx] = 1;
} else {
gAudioContext.seqReplaced[playerIdx] = 0;
}
gAudioContext.seqReplaced[playerIdx] = seqId != newSeqId;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, definitely should've noticed this. Thanks for pointing it out.

leggettc18 and others added 3 commits December 8, 2022 13:51
Sort custom seqs by meta name
Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com>
Copy link
Contributor

@briaguya-ai briaguya-ai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wonderful! Let's :shipit: (assuming you're ready to call it good @leggettc18)

@leggettc18
Copy link
Contributor Author

One or two more formatting fixes from the review that I haven't applied yet but then I'd say it's good.

@leggettc18
Copy link
Contributor Author

OK, if CI is happy after this point it should be good enough.

@leggettc18
Copy link
Contributor Author

Whoops, one more tiny bug found fix already uploaded.

@briaguya-ai briaguya-ai merged commit 8c8c761 into HarbourMasters:develop Dec 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants