Skip to content

Commit

Permalink
Add MIDI generation module
Browse files Browse the repository at this point in the history
  • Loading branch information
dashodanger committed Jun 26, 2024
1 parent b8f6453 commit be687b5
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 30 deletions.
55 changes: 55 additions & 0 deletions modules/midi_generation.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
MIDI_CONFIG = {}

MIDI_CONFIG.CHOICES =
{
"safe", _("Safe Defaults"),
"all", _("Relaxed (May Sound Weird)")
}

function MIDI_CONFIG.setup(self)
module_param_up(self)
end

function MIDI_CONFIG.all_done()
for _,song in pairs(GAME.RESOURCES.MUSIC_LUMPS) do
if gui.generate_midi_track("scripts/midi/" .. PARAM.midi_config_selection .. ".json", "temp/" .. song .. ".mid") == 1 then
if ob_mod_enabled("compress_output") == 1 then
gui.pk3_insert_file("temp/" .. song .. ".mid", "music/" .. song .. ".mid")
else
gui.wad_insert_file("temp/" .. song .. ".mid", song)
end
gui.remove_temp_file(song .. ".mid")
end
end
end

OB_MODULES["midi_generation"] =
{

name = "midi_generation",

label = _("MIDI Generation"),

where = "experimental",
engine = "!idtech_0",
priority = 5,

tooltip = _("Procedurally generate replacement MIDI tracks"),

hooks =
{
setup = MIDI_CONFIG.setup,
all_done = MIDI_CONFIG.all_done
},

options =
{
{
name = "midi_config_selection",
label=_("Generator Config"),
choices=MIDI_CONFIG.CHOICES,
default = "safe",
tooltip = _("Choose which procedural MIDI config to use")
},
},
}
File renamed without changes.
1 change: 0 additions & 1 deletion scripts/midi/sane.steve.json → scripts/midi/safe.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"parents": ["all.steve.json"],
"min_tempo": 80,
"max_tempo": 160,
"time_signatures": {
Expand Down
2 changes: 1 addition & 1 deletion source/g_doom.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1384,7 +1384,7 @@ bool Doom::game_interface_c::Start(const char *preset)

if (file_per_map)
{
filename = PathAppend(home_dir, "resources.wad");
filename = PathAppend(home_dir, "temp/resources.wad");
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions source/lib_argv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ void argv::Init(const int argc, const char *const *argv)
}

// support DOS-style short options
if (cur[0] == '/' && (isalnum(cur[1]) || cur[1] == '?') && cur[2] == '\0')
if (cur[0] == '/' && (IsAlphanumericASCII(cur[1]) || cur[1] == '?') && cur[2] == '\0')
{
list.emplace_back(std::string{"-"} + std::string{&cur[1], 1});
}
Expand Down Expand Up @@ -185,7 +185,7 @@ void argv::Init(const int argc, const char *const *argv)
}

// support DOS-style short options
if (cur[0] == '/' && (isalnum(cur[1]) || cur[1] == '?') && cur[2] == '\0')
if (cur[0] == '/' && (IsAlphanumericASCII(cur[1]) || cur[1] == '?') && cur[2] == '\0')
{
list.emplace_back(std::string{"-"} + std::string{&cur[1], 1});
}
Expand Down
79 changes: 65 additions & 14 deletions source/lib_midi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,78 @@
#include "ConfigJson.h"
#include "Music.h"
#include "Steve.h"
#include "lib_util.h"
#include "main.h"
#include "physfs.h"
#include "sys_assert.h"
#include "sys_debug.h"

void steve_generate(const char *config_file, const char *out_file) {
bool steve_generate(const char *config_file, const char *out_file) {

int num = 1;
SYS_ASSERT(config_file && out_file);

steve::note_name_init();

steve::ConfigJson config;
config.parse_file(config_file);
config.compute_cache();

for(uint32_t i = 0; i < num; i++) {
std::string music_path;
steve::Music music(config);
if(!out_file) {
music_path = music.to_short_string();
music_path.append(".mid");
// all.json must be read in regardless; load additional config afterwards if selected
PHYSFS_File *config_fp = PHYSFS_openRead("scripts/midi/all.json");

if (!config_fp)
{
LogPrint("Unable to open MIDI generator config scripts/midi/all.json!\n");
return false;
}

size_t len = PHYSFS_fileLength(config_fp);
uint8_t *buf = new uint8_t[len];

if (PHYSFS_readBytes(config_fp, buf, len) != len)
{
PHYSFS_close(config_fp);
delete[] buf;
LogPrint("Unable to read MIDI generator config scripts/midi/all.json!!\n");
return false;
}

PHYSFS_close(config_fp);

config.parse_buffer((const char *)buf, len);
delete[] buf;

if (GetFilename(config_file) != "all.json")
{
config_fp = PHYSFS_openRead(config_file);
if (!config_fp)
{
LogPrint("Unable to open MIDI generator config %s!\n", config_file);
return false;
}
else
music_path = out_file;
std::ofstream fs(music_path, std::ofstream::binary);
music.write_mid(fs);

len = PHYSFS_fileLength(config_fp);
buf = new uint8_t[len];

if (PHYSFS_readBytes(config_fp, buf, len) != len)
{
PHYSFS_close(config_fp);
delete[] buf;
LogPrint("Unable to read MIDI generator config %s!\n", config_file);
return false;
}

PHYSFS_close(config_fp);

config.parse_buffer((const char *)buf, len);

delete[] buf;
}

config.compute_cache();

steve::Music music(config);
std::ofstream fs(PathAppend(home_dir, out_file), std::ofstream::binary);
music.write_mid(fs);

return true;

}
2 changes: 1 addition & 1 deletion source/lib_midi.h
Original file line number Diff line number Diff line change
@@ -1 +1 @@
void steve_generate(const char *config_file, const char *out_file);
bool steve_generate(const char *config_file, const char *out_file);
1 change: 1 addition & 0 deletions source/m_addons.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ void VFS_InitAddons()
VFS_AddFolder("ports");
VFS_AddBothFolders("presets");
VFS_AddBothFolders("addons");
VFS_AddBothFolders("temp");

LogPrint("DONE.\n\n");
}
Expand Down
40 changes: 36 additions & 4 deletions source/m_lua.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <algorithm>

#include "ff_main.h"
#include "lib_midi.h"
#include "lib_util.h"
#include "m_trans.h"
#include "main.h"
Expand Down Expand Up @@ -95,7 +96,7 @@ int gui_console_print(lua_State *L)
SYS_ASSERT(res);

// strip off colorizations
if (res[0] == '@' && isdigit(res[1]))
if (res[0] == '@' && IsDigitASCII(res[1]))
{
res += 2;
}
Expand All @@ -118,7 +119,7 @@ int gui_ref_print(lua_State *L)
SYS_ASSERT(res);

// strip off colorizations
if (res[0] == '@' && isdigit(res[1]))
if (res[0] == '@' && IsDigitASCII(res[1]))
{
res += 2;
}
Expand All @@ -141,7 +142,7 @@ int gui_raw_log_print(lua_State *L)
SYS_ASSERT(res);

// strip off colorizations
if (res[0] == '@' && isdigit(res[1]))
if (res[0] == '@' && IsDigitASCII(res[1]))
{
res += 2;
}
Expand Down Expand Up @@ -364,7 +365,7 @@ static bool scan_dir_process_name(const std::string &name, const std::string &pa
{
return true;
}
else if (match[0] == '*' && match[1] == '.' && isalnum(match[2]))
else if (match[0] == '*' && match[1] == '.' && IsAlphanumericASCII(match[2]))
{
return GetExtension(name) == "." + std::string{match.begin() + 2, match.end()};
}
Expand Down Expand Up @@ -1432,6 +1433,31 @@ int gui_minimap_fill_box(lua_State *L)
return 0;
}

int generate_midi_track(lua_State *L)
{
const char *midi_config = luaL_checkstring(L, 1);
const char *midi_file = luaL_checkstring(L, 2);

int value = steve_generate(midi_config, midi_file) ? 1 : 0;
lua_pushinteger(L, value);

return 1;
}

int remove_temp_file(lua_State *L)
{
std::string path = PathAppend(home_dir, "temp");

const char *temp_file = luaL_checkstring(L, 1);

path = PathAppend(path, GetFilename(temp_file));

if (FileExists(path))
FileDelete(path);

return 0;
}

//------------------------------------------------------------------------

extern int SPOT_begin(lua_State *L);
Expand Down Expand Up @@ -1656,6 +1682,12 @@ static const luaL_Reg gui_script_funcs[] = {
{"v094_add_sidedef", Doom::v094_add_sidedef},
{"v094_add_sector", Doom::v094_add_sector},

// MIDI generation
{"generate_midi_track", generate_midi_track},

// Miscellany
{"remove_temp_file", remove_temp_file},

{NULL, NULL} // the end
};

Expand Down
2 changes: 1 addition & 1 deletion source/m_theme.cc
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ static bool Theme_Options_ParseLine(std::string buf)
buf.erase(std::find(buf.begin(), buf.end(), ' '));
}

if (!(isalpha(buf.front()) || buf.front() == '@'))
if (!(IsAlphaASCII(buf.front()) || buf.front() == '@'))
{
LogPrint("Weird theme option line: [%s]\n", buf.c_str());
return false;
Expand Down
2 changes: 1 addition & 1 deletion source/m_trans.cc
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ struct po_parse_state_t

dest = dest + d_len;

while (*p && isspace(*p))
while (*p && IsSpaceASCII(*p))
{
p++;
}
Expand Down
7 changes: 2 additions & 5 deletions source/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@
#include "ui_window.h"
#endif

#include "lib_midi.h" // test - Dasho

/**
* \brief Ticker time in milliseconds
*/
Expand Down Expand Up @@ -372,6 +370,8 @@ void Determine_WorkingPath()
#else
home_dir = PHYSFS_getPrefDir("Obsidian Team", "Obsidian");
#endif
// ensure scratch folder exists
MakeDirectory(PathAppend(home_dir, "temp"));
}

std::string Resolve_DefaultOutputPath()
Expand Down Expand Up @@ -1929,9 +1929,6 @@ softrestart:;
old_pixels = new uint8_t[map_size];
memcpy(old_pixels, main_win->build_box->mini_map->pixels, map_size);
}

// test - Dasho
steve_generate(PathAppend(install_dir, "scripts/midi/all.steve.json").c_str(), NULL);
}
else
{
Expand Down

0 comments on commit be687b5

Please sign in to comment.