diff --git a/.gitignore b/.gitignore index 7e3f0b5..6ce6e48 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ assets/*.h build* !build-env -.vscode +.vscode/settings.json .cache compile_commands.json .flatpak-builder @@ -23,4 +23,5 @@ cmake-build-*/ *_build local.properties hs_err_*.log -replay_pid*.log \ No newline at end of file +replay_pid*.log +assets/btcc \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..5eb07e8 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,33 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/default/looper", + "args": ["-m", "-l-2"], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ], + "preLaunchTask": "Build" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..ce6c129 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,20 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "cmake", + "label": "Build", + "command": "build", + "targets": [ + "all" + ], + "preset": "${command:cmake.activeBuildPresetName}", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [], + "detail": "CMake template build task", + } + ] +} \ No newline at end of file diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..acfc145 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,44 @@ +{ + "version": 10, + "cmakeMinimumRequired": { + "major": 3, + "minor": 23, + "patch": 0 + }, + "configurePresets": [ + { + "name": "default", + "displayName": "Default Config", + "description": "Default build using Ninja generator", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/default", + "cacheVariables": { + "CMAKE_POLICY_DEFAULT_CMP0069": "NEW", + "CMAKE_INTERPROCEDURAL_OPTIMIZATION": "ON", + "CMAKE_C_FLAGS": "-O2 -march=native -g", + "CMAKE_CXX_FLAGS": "-O2 -march=native -g", + "BUILD_SOUNDTOUCH": "ON", + "DISABLE_GTK_UI": "ON", + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + }, + "environment": { + "CMAKE_C_COMPILER_LAUNCHER": "ccache", + "CMAKE_CXX_COMPILER_LAUNCHER": "ccache" + } + } + ], + "buildPresets": [ + { + "name": "default", + "configurePreset": "default" + } + ], + "testPresets": [ + { + "name": "default", + "configurePreset": "default", + "output": {"outputOnFailure": true}, + "execution": {"noTestsAction": "error", "stopOnFailure": true} + } + ] + } \ No newline at end of file diff --git a/backends/playback/fluidsynth/fluidsynth_backend.cpp b/backends/playback/fluidsynth/fluidsynth_backend.cpp index 852900e..c33d3d9 100644 --- a/backends/playback/fluidsynth/fluidsynth_backend.cpp +++ b/backends/playback/fluidsynth/fluidsynth_backend.cpp @@ -8,463 +8,61 @@ #include #include #include -type FluidSynthBackend::name() { \ - std::optional value_maybe = get(#name); \ - if (value_maybe.has_value()) { \ - return resolve_value(value_maybe.value()); \ - } \ - return default_value; \ -} -void fluidsynth_get_property_list_wrapper(void *udata, const char *name, int type) { +void FluidSynthBackend::fluidsynth_get_property_list_wrapper(void *udata, const char *name, int type) { ((FluidSynthBackend*)udata)->fluidsynth_get_property_list(name, type); } +void FluidSynthBackend::fluidsynth_get_property_list(const char *name, int type) { + Property property; + property.set_path(fmt::format("fluidsynth/{0}", name)); + property.set_name(name); + switch (type) { + case FLUID_NUM_TYPE: { + property.set_type(PropertyType::Double); + } break; + case FLUID_INT_TYPE: { + property.set_type(PropertyType::Int); + } break; + case FLUID_STR_TYPE: { + property.set_type(PropertyType::String); + } break; + } + property.set_id(PropertyId::BackendSpecific); + fluidsynth_properties.push_back(property); +} std::vector FluidSynthBackend::get_property_list() { - fluid_settings_foreach(settings, (void*)this, &fluidsynth_get_property_list_wrapper); - return properties; + return fluidsynth_properties; } void FluidSynthBackend::load(const char *filename) { memset(&spec, 0, sizeof(spec)); current_file = filename; - spec.format = AUDIO_S16SYS; + spec.format = AUDIO_F32SYS; spec.samples = 100; spec.channels = 2; - spec.freq = PSG_FREQ; + spec.freq = 48000; spec.size = 100 * 2 * sizeof(int16_t); file = open_file(filename); - char magic[2]; - file->read(magic, 2, 1); - if (magic[0] != 0x7a || magic[1] != 0x6d) { - throw std::exception(); - } - uint8_t version; - file->read(&version, 1, 1); - uint8_t loop_point[3]; - file->read(loop_point, 3, 1); - this->loop_point = loop_point[0] | ((uint32_t)(loop_point[1]) << 8) | ((uint32_t)(loop_point[2]) << 16); - file->read(loop_point, 3, 1); - this->pcm_offset = loop_point[0] | ((uint32_t)(loop_point[1]) << 8) | ((uint32_t)(loop_point[2]) << 16); - pcm_offset += 3; - file->read(&fm_mask, 1, 1); - file->read(loop_point, 2, 1); - this->psg_channel_mask = loop_point[0] | ((uint16_t)(loop_point[1]) << 8); - file->read(loop_point, 2, 1); - this->tick_rate = loop_point[0] | ((uint16_t)(loop_point[1]) << 8); - file->read(loop_point, 2, 1); // Reserved. - music_data_start = file->get_pos(); - this->loop_point += music_data_start; - file->seek(pcm_offset, SeekType::SET); - file->read(loop_point, 1, 1); - pcm_offset++; - pcm_data_offs = ((((uint16_t)loop_point[0]) + 1) * 16) + pcm_offset; - for (uint8_t i = 0; i <= loop_point[0]; i++) { - uint16_t instdef = (i * 16) + 1; - pcm_instrument *inst = new pcm_instrument(); - file->seek(pcm_offset + instdef, SeekType::SET); - file->read(&inst->geom, 1, 1); - uint8_t bytes[10]; - file->read(bytes, 10, 1); - inst->loop_rem = bytes[9]; - inst->loop_rem <<= 8; - inst->loop_rem |= bytes[8]; - inst->loop_rem <<= 8; - inst->loop_rem |= bytes[7]; - inst->loop = loop_rem; - inst->islooped = bytes[6] & 0x80; - inst->remain = bytes[5]; - inst->remain <<= 8; - inst->remain |= bytes[4]; - inst->remain <<= 8; - inst->remain |= bytes[3]; - uint32_t cur = bytes[2]; - cur <<= 8; - cur |= bytes[1]; - cur <<= 8; - cur |= bytes[0]; - cur += pcm_data_offs; - inst->data = (uint8_t*)malloc(inst->remain); - file->seek(cur, SeekType::SET); - file->read(inst->data, 1, inst->remain); - inst->loop_rem = inst->remain - inst->loop_rem; - instruments.push_back(inst); - } - file->seek(music_data_start, SeekType::SET); - this->loop_point = std::max(this->loop_point, (uint32_t)music_data_start); - double prev_time = 0.0; - double time = 0.0; - double tmpDelayTicks = 0.0; - loop_pos = -1.0; - uint32_t prev_pos = music_data_start; - while (true) { - tmpDelayTicks -= get_delay_per_frame(); - if (tmpDelayTicks < 0.0) { - ZsmCommand cmd = get_command(); - size_t cur_pos = file->get_pos(); - if (cur_pos >= this->loop_point && this->loop_pos < 0) { - loop_pos = time; - this->loop_point = cur_pos; - } - if (cmd.id == ZsmEOF) { - break; - } else if (cmd.id == Delay) { - time += ((double)cmd.delay) / ((double)(tick_rate)); - tmpDelayTicks += cmd.delay; - } - prev_pos = file->get_pos(); - prev_time = time; - } - } - if (this->loop_pos < 0.0) { - this->loop_pos = 0.0; - this->loop_point = music_data_start; - } - length = time; - music_data_len = file->get_pos(); - switch_stream(0); - loop_end = length; - loop_start = this->loop_pos; - fm_stream = SDL_NewAudioStream(AUDIO_S16SYS, 2, YM_FREQ, AUDIO_S16SYS, 2, PSG_FREQ); - DEBUG.writefln("fm_stream: %ld -> %ld", YM_FREQ, PSG_FREQ); -#define _PROPERTY(name, type, default_value) \ - { \ - std::string type_str = #type; \ - google::protobuf::Any value; \ - if (type_str == "bool") { \ - BooleanProperty value_b; \ - value_b.set_value(default_value); \ - value.PackFrom(value_b); \ - } else if (type_str == "double") { \ - DoubleProperty value_d; \ - value_d.set_value(default_value); \ - value.PackFrom(value_d); \ - } \ - property_defaults[#name] = value; \ - } -#include "properties.inc" + this->settings = new_fluid_settings(); + fluid_settings_foreach(settings, (void*)this, &fluidsynth_get_property_list_wrapper); } extern SDL_AudioSpec obtained; -void ZsmBackend::switch_stream(int idx) { - YM_Create(YM_FREQ); - YM_init(YM_FREQ/64, 60); - YM_reset(); - psg_reset(); - pcm_reset(); - for (uint8_t i = 0; i < 16; i++) { - psg_writereg(i * 4 + 2, 0); - } - file->seek(music_data_start, SeekType::SET); - this->cpuClocks = 0.0; - this->delayTicks = 0.0; - this->ticks = 0.0; +void FluidSynthBackend::switch_stream(int idx) { } -void ZsmBackend::cleanup() { +void FluidSynthBackend::cleanup() { delete file; file = nullptr; - audio_buf.clear(); - SDL_FreeAudioStream(fm_stream); - fm_stream = nullptr; - audio_sample = nullptr; - for (auto inst : instruments) { - delete inst; - } - instruments.clear(); } -void ZsmBackend::tick(bool step) { - delayTicks -= 1; - const double ClocksPerTick = ((double)HZ) / ((double)tick_rate); - double prevCpuClocks = cpuClocks; - double nextCpuClocks = cpuClocks + ClocksPerTick; - double ticks_remaining = ClocksPerTick; - while (delayTicks <= 0) { - ZsmCommand cmd = get_command(); - switch (cmd.id) { - case ZsmEOF: { - if (step) { - file->seek(this->loop_point, SeekType::SET); - this->position = loop_pos; - } else { - throw std::exception(); - } - } break; - case PsgWrite: { - psg_writereg(cmd.psg_write.reg, cmd.psg_write.val); - } break; - case FmWrite: { - for (uint8_t i = 0; i < cmd.fm_write.len; i++) { - YM_write_reg(cmd.fm_write.regs[i].reg, cmd.fm_write.regs[i].val); - while (YM_read_status()) { - size_t clocksToAddForYm = 1; - ticks_remaining -= clocksToAddForYm; - if (ticks_remaining < 0) { - delayTicks -= 1; - nextCpuClocks += ClocksPerTick; - ticks_remaining += ClocksPerTick; - } - audio_step(clocksToAddForYm); - } - } - } break; - case Delay: { - delayTicks += cmd.delay; - position += ((double)cmd.delay) / ((double)(tick_rate)); - } break; - case ExtCmd: { - //cmd.extcmd.channel - switch (cmd.extcmd.channel) { - case 0: { - for (size_t i = 0; i < cmd.extcmd.bytes; i += 2) { - switch (cmd.extcmd.pcm[i]) { - case 0: { // ctrl - uint8_t ctrl = cmd.extcmd.pcm[i + 1]; - if (ctrl & 0x80) { - remain = 0; - } - pcm_write_ctrl(ctrl); - } break; - case 1: { // rate - pcm_write_rate(cmd.extcmd.pcm[i + 1]); - } break; - default: { // trigger - size_t file_pos = file->get_pos(); - uint8_t ctrl = pcm_read_ctrl(); - pcm_write_ctrl(ctrl | 0x80); - uint16_t pcm_idx = cmd.extcmd.pcm[i + 1]; - pcm_instrument *inst = instruments[pcm_idx]; - ctrl = pcm_read_ctrl() & 0x0F; - ctrl |= inst->geom & 0x30; - pcm_write_ctrl(ctrl); - audio_sample = inst->data; - loop = inst->loop; - loop_rem = inst->loop_rem; - remain = inst->remain; - islooped = inst->islooped; - cur = 0; - } break; - } - } break; - } - // Nothing handled yet. - } - } break; - } - } - size_t nextCpuClocksInt = std::floor(nextCpuClocks); - size_t prevCpuClocksInt = std::floor(prevCpuClocks); - size_t cpuClocksIntDelta = nextCpuClocksInt - prevCpuClocksInt; - audio_step(ticks_remaining); - cpuClocks = std::fmod(nextCpuClocks, ClocksPerTick); -} -size_t ZsmBackend::render(void *buf, size_t maxlen) { +size_t FluidSynthBackend::render(void *buf, size_t maxlen) { size_t sample_type_len = 2; maxlen /= sample_type_len; - while (audio_buf.size() <= maxlen) { - tick(true); - } - size_t copied = copy_out(buf, maxlen) * sample_type_len; maxlen *= sample_type_len; return copied; } -uint64_t ZsmBackend::get_min_samples() { - return spec.size; +void FluidSynthBackend::seek(double position) { + } -std::optional ZsmBackend::get_max_samples() { - return get_min_samples(); -} -ZsmCommand ZsmBackend::get_command() { - ZsmCommandId cmdid; - uint8_t cmd_byte; - file->read(&cmd_byte, 1, 1); - if (cmd_byte == 0x80) { - cmdid = ZsmEOF; - } else { - if ((cmd_byte >> 6) == 0) { - cmdid = PsgWrite; - } else if ((cmd_byte >> 6) == 0b01) { - if (cmd_byte == 0b01000000) { - cmdid = ExtCmd; - } else { - cmdid = FmWrite; - } - } else { - cmdid = Delay; - } - } - ZsmCommand output; - output.id = cmdid; - if (cmdid == ZsmEOF) { - return output; - } else if (cmdid == PsgWrite) { - uint8_t value; - file->read(&value, 1, 1); - output.psg_write.reg = cmd_byte & 0x3F; - output.psg_write.val = value; - } else if (cmdid == FmWrite) { - uint16_t _value; - uint8_t *value = (uint8_t*)(void*)(&_value); - uint8_t pairs = cmd_byte & 0b111111; - output.fm_write.len = pairs; - output.fm_write.regs = (reg_pair*)malloc((sizeof(reg_pair))*pairs); - for (uint8_t i = 0; i < pairs; i++) { - file->read(value, 2, 1); - output.fm_write.regs[i].reg = value[0]; - output.fm_write.regs[i].val = value[1]; - } - } else if (cmdid == ExtCmd) { - uint8_t ext_cmd_byte; - file->read(&ext_cmd_byte, 1, 1); - uint8_t bytes = ext_cmd_byte & 0x3F; - uint8_t ch = ext_cmd_byte >> 6; - output.extcmd.channel = ch; - output.extcmd.bytes = bytes; - if (ch == 1) { - output.extcmd.expansion.write_bytes = NULL; - } else { - output.extcmd.pcm = (uint8_t*)malloc(bytes); // Handles all other cases due to them being in a union, and each having the same type. - } - for (size_t i = 0; i < bytes; i++) { - uint8_t byte; - file->read(&byte, 1, 1); - switch (ch) { - case 0: { - output.extcmd.pcm[i] = byte; - } break; - case 1: { - if (i == 0) { - output.extcmd.expansion.chip_id = byte; - } else if (i == 1) { - output.extcmd.expansion.writes = byte; - output.extcmd.expansion.write_bytes = (uint8_t*)malloc(byte); - } else { - output.extcmd.expansion.write_bytes[i - 2] = byte; - } - } break; - case 2: { - output.extcmd.sync[i] = byte; - } break; - case 3: { - output.extcmd.custom[i] = byte; - } break; - } - } - } else if (cmdid == Delay) { - output.delay = cmd_byte & 0x7F; - } - return output; -} -ZsmCommand::~ZsmCommand() { - switch (id) { - case ExtCmd: { - if (extcmd.channel == 1) { - if (extcmd.expansion.write_bytes != NULL) { - free(extcmd.expansion.write_bytes); - } - } else { - free(extcmd.pcm); - } - } break; - case FmWrite: { - free(fm_write.regs); - } - } -} -void ZsmBackend::seek_internal(double position, bool loop) { - this->position = std::floor(this->position * PSG_FREQ) / PSG_FREQ; - position = std::floor(position * PSG_FREQ) / PSG_FREQ; - if (this->position > position) { - switch_stream(0); - file->seek(music_data_start, SeekType::SET); - this->cpuClocks = 0.0; - this->delayTicks = 0; - this->ticks = 0.0; - this->position = 0.0; - } else if (this->position == position) { - audio_buf.clear(); - return; - } - while (this->position < position) { - audio_buf.clear(); - try { - tick(false); - } catch (std::exception) { - switch_stream(0); - file->seek(music_data_start, SeekType::SET); - this->cpuClocks = 0.0; - this->delayTicks = 0; - this->ticks = 0.0; - this->position = 0.0; - audio_buf.clear(); - return; - } - } - size_t samples = std::min((size_t)((this->position - position) * PSG_FREQ), audio_buf.size()); - while (samples--) { - audio_buf.pop(); - } - this->position = position; -} -void ZsmBackend::seek(double position) { - seek_internal(position, false); -} -double ZsmBackend::get_position() { +double FluidSynthBackend::get_position() { return position; } -int ZsmBackend::get_stream_idx() { +int FluidSynthBackend::get_stream_idx() { return 0; -} - -void ZsmBackend::audio_step(size_t samples) { - if (samples == 0) return; - while (remain != 0 && pcm_fifo_avail() < samples) { - if (pcm_read_rate() == 0) break; - if ((--remain) == 0) { - if (islooped) { - cur = loop; - remain = loop_rem; - } else { - break; - } - } - size_t oldpos = file->get_pos(); - uint8_t sample = audio_sample[cur++]; - pcm_write_fifo(sample); - } - samples *= 2; - int16_t *psg_ptr = psg_buf.get_item_sized(samples); - int16_t *pcm_ptr = pcm_buf.get_item_sized(samples); - psg_render(psg_ptr, samples / 2); - pcm_render(pcm_ptr, samples / 2); - int16_t *out_ptr = out_buf.get_item_sized(samples); - // The exact amount of samples needed for the stream. - double ratio = ((double)YM_FREQ) / ((double)PSG_FREQ); - size_t needed_samples = ((size_t)std::floor(samples * ratio)) / 2; - int16_t *ym_ptr = ym_buf.get_item_sized(needed_samples * 2); - YM_stream_update(ym_ptr, needed_samples); - assert(SDL_AudioStreamPut(fm_stream, ym_ptr, needed_samples * 2 * sizeof(int16_t)) == 0); - while (SDL_AudioStreamAvailable(fm_stream) < ((samples + 2) * sizeof(int16_t))) { - YM_stream_update(ym_ptr, 1); - assert(SDL_AudioStreamPut(fm_stream, ym_ptr, 2 * sizeof(int16_t)) == 0); - } - int16_t *ym_resample_ptr = ym_resample_buf.get_item_sized(samples); - ssize_t ym_resample_len = SDL_AudioStreamGet(fm_stream, ym_resample_ptr, (samples + 2) * sizeof(int16_t)); - assert(ym_resample_len >= 0); - ym_resample_len /= sizeof(int16_t); - for (size_t i = 0; i < samples / 2; i++) { - size_t j = i * 2; - int16_t psg[2] = {(int16_t)(psg_ptr[j] >> 1), (int16_t)(psg_ptr[j + 1] >> 1)}; - int16_t pcm[2] = {(int16_t)(pcm_ptr[j] >> 2), (int16_t)(pcm_ptr[j + 1] >> 2)}; - if (!pcm_enable()) memset(pcm, 0, sizeof(pcm)); - if (!psg_enable()) memset(psg, 0, sizeof(psg)); - pcm[0] *= pcm_volume(); - pcm[1] *= pcm_volume(); - psg[0] *= psg_volume(); - psg[1] *= psg_volume(); - int16_t vera[2] = {(int16_t)(psg[0] + pcm[0]), (int16_t)(psg[1] + pcm[1])}; - int16_t fm[2] = {ym_resample_ptr[j], ym_resample_ptr[j + 1]}; - if (!fm_enable()) memset(fm, 0, sizeof(fm)); - fm[0] *= fm_volume(); - fm[1] *= fm_volume(); - int16_t mix[2] = {(int16_t)(vera[0] + (fm[0] >> 1)), (int16_t)(vera[1] + (fm[1] >> 1))}; - out_ptr[j++] = mix[0]; - out_ptr[j++] = mix[1]; - } - audio_buf.push(out_ptr, samples); -} +} \ No newline at end of file diff --git a/backends/playback/fluidsynth/fluidsynth_backend.hpp b/backends/playback/fluidsynth/fluidsynth_backend.hpp index 4e4b4d1..5da04f1 100644 --- a/backends/playback/fluidsynth/fluidsynth_backend.hpp +++ b/backends/playback/fluidsynth/fluidsynth_backend.hpp @@ -11,21 +11,20 @@ #include #include #include "file_backend.hpp" +#include class FluidSynthBackend : public PlaybackBackend { File *file; - void seek_internal(double position, bool loop = true); + static void fluidsynth_get_property_list_wrapper(void *udata, const char *name, int type); std::vector fluidsynth_properties; fluid_settings_t *settings; void fluidsynth_get_property_list(const char *name, int type); public: - uint64_t get_min_samples() override; void set_fluidsynth_property_str(std::string path, std::string val); void set_fluidsynth_property_num(std::string path, double val); void set_fluidsynth_property_int(std::string path, int val); std::string get_fluidsynth_property_str(std::string path); double get_fluidsynth_property_num(std::string path); int get_fluidsynth_property_int(std::string path); - std::optional get_max_samples() override; inline std::string get_id() override { return "fluidsynth"; } @@ -43,5 +42,5 @@ class FluidSynthBackend : public PlaybackBackend { inline double get_length() override { return length; } - inline ~ZsmBackend() override { } + inline ~FluidSynthBackend() override { } }; diff --git a/build.sh b/build.sh index a680f62..447e3d4 100755 --- a/build.sh +++ b/build.sh @@ -27,6 +27,6 @@ trap on_err ERR cd "$(dirname "$0")" mkdir -p build cd build -run_command cmake .. -DDISABLE_GTK_UI=ON -DCMAKE_BUILD_TYPE=Debug +run_command cmake .. -DDISABLE_GTK_UI=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DCMAKE_C{,XX}_FLAGS="-O2 -march=native" -DBUILD_SOUNDTOUCH=ON run_command cmake --build . "$@" cd "$OLD_DIR" diff --git a/ipc/common.proto b/ipc/common.proto index 58e7755..8ff58b7 100644 --- a/ipc/common.proto +++ b/ipc/common.proto @@ -27,6 +27,9 @@ message BooleanProperty { message BytesProperty { bytes value = 1; }; +message IntProperty { + int64 value = 1; +} message PropertyHintRange { optional double min = 1; optional double max = 2; @@ -49,6 +52,7 @@ enum PropertyType { StreamType = 4; AudioSpecType = 5; StreamID = 6; + Int = 7; } message Property { PropertyType type = 1; diff --git a/playback_process.cpp b/playback_process.cpp index a6f7924..a4e06b1 100644 --- a/playback_process.cpp +++ b/playback_process.cpp @@ -412,7 +412,7 @@ PlaybackProcess::PlaybackProcess(std::vector args) { } PlaybackProcess::PlaybackProcess(std::string filename, int idx) { // multi_process = Looper::Options::get_option("playback.multi_process", true); - multi_process = false; + multi_process = true; done = false; this->done = false; if (multi_process) { diff --git a/sdl-android-project/app/build.gradle b/sdl-android-project/app/build.gradle index ac3ef3f..f63d0f8 100644 --- a/sdl-android-project/app/build.gradle +++ b/sdl-android-project/app/build.gradle @@ -25,19 +25,12 @@ android { standardOutput revListStdout } def revParseStdout = new ByteArrayOutputStream(); - def versionNameData = "" exec { - commandLine "git", "rev-parse", "--abbrev-ref", "HEAD" - standardOutput revParseStdout - } - versionNameData = revParseStdout.toString() + "-" - revParseStdout = new ByteArrayOutputStream() - exec { - commandLine "git", "rev-parse", "--short", "HEAD" + commandLine "./app/jni/version.sh" standardOutput revParseStdout } versionCode revListStdout.toString() as Integer - versionName versionNameData + revParseStdout.toString() + versionName revParseStdout.toString() externalNativeBuild { cmake { arguments "-DUSE_GLES=ON", "-DUSE_PORTALS=OFF", "-DDOWNLOAD_AUDIO_CODECS_DEPENDENCY=ON", "-DENABLE_DBUS=OFF", "-DBUILD_SDL=ON", "-DBUILD_SDL_IMAGE=ON", "-DDISABLE_GTK_UI=ON", "-DDISABLE_IMGUI_UI=OFF" diff --git a/version.sh b/version.sh index 69b066b..a135489 100755 --- a/version.sh +++ b/version.sh @@ -1,2 +1,2 @@ #!/bin/sh -git describe --tags --all | tr -d '\n' \ No newline at end of file +printf "%s-%s" "$(git rev-parse --abbrev-ref HEAD)" "$(git rev-parse --short HEAD)" \ No newline at end of file