Add Game Music Emu backend
Some checks failed
Build / build-gentoo (push) Failing after 14s
Build / download-system-deps (push) Successful in 4m36s
Build / get-source-code (push) Successful in 17m33s
Build / build-deb (push) Failing after 12m45s
Build / build-appimage (push) Successful in 5m23s
Build / build-android (push) Failing after 3m11s
Build / build-windows (push) Failing after 7m37s
Some checks failed
Build / build-gentoo (push) Failing after 14s
Build / download-system-deps (push) Successful in 4m36s
Build / get-source-code (push) Successful in 17m33s
Build / build-deb (push) Failing after 12m45s
Build / build-appimage (push) Successful in 5m23s
Build / build-android (push) Failing after 3m11s
Build / build-windows (push) Failing after 7m37s
This commit is contained in:
parent
53332db3e6
commit
8d9cf9372e
9 changed files with 233 additions and 0 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -57,3 +57,6 @@
|
|||
[submodule "subprojects/protobuf-c"]
|
||||
path = subprojects/protobuf-c
|
||||
url = https://github.com/protobuf-c/protobuf-c.git
|
||||
[submodule "backends/playback/gme/game-music-emu"]
|
||||
path = backends/playback/gme/game-music-emu
|
||||
url = https://github.com/libgme/game-music-emu.git
|
||||
|
|
|
@ -529,6 +529,7 @@ playback_backend_subdir(NAME "VGMSTREAM" READABLE_NAME "VgmStream" SUBDIR backen
|
|||
playback_backend_subdir(NAME "SDL_MIXER_X" READABLE_NAME "SDL Mixer X" SUBDIR backends/playback/sdl_mixer_x)
|
||||
playback_backend_subdir(NAME "ZSM" READABLE_NAME "ZSM" SUBDIR backends/playback/zsm)
|
||||
playback_backend_subdir(NAME "FLUIDSYNTH" READABLE_NAME "Fluidsynth" SUBDIR backends/playback/fluidsynth)
|
||||
playback_backend_subdir(NAME "GME" READABLE_NAME "Game Music Emu" SUBDIR backends/playback/gme)
|
||||
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/gen_ui_backend_inc.py ${CMAKE_CURRENT_BINARY_DIR} --ui ${ENABLED_UIS} --playback ${ENABLED_PLAYBACK_BACKENDS})
|
||||
prefix_all(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/ main.cpp daemon_backend.cpp daemon_backend.hpp proxy_backend.cpp proxy_backend.hpp)
|
||||
list(APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/backend_glue.cpp)
|
||||
|
|
8
backends/playback/gme/CMakeLists.txt
Normal file
8
backends/playback/gme/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
set(BACKEND_GME_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gme_backend.cpp)
|
||||
set(BACKEND_GME_INC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_subdirectory(game-music-emu)
|
||||
add_playback_backend(gme_backend ${BACKEND_GME_SRC})
|
||||
target_include_directories(gme_backend PRIVATE ${BACKEND_GME_INC})
|
||||
find_package(OpenMP)
|
||||
target_include_directories(gme_backend PUBLIC game-music-emu/gme)
|
||||
target_link_libraries(gme_backend PUBLIC gme OpenMP::OpenMP_CXX)
|
4
backends/playback/gme/backend.json
Normal file
4
backends/playback/gme/backend.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"class_name": "GmeBackend",
|
||||
"include_path": "gme_backend.hpp"
|
||||
}
|
39
backends/playback/gme/cmake_install.cmake
Normal file
39
backends/playback/gme/cmake_install.cmake
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Install script for directory: /boot/home/Desktop/looper/backends/playback/zsm
|
||||
|
||||
# Set the install prefix
|
||||
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
set(CMAKE_INSTALL_PREFIX "/boot/system")
|
||||
endif()
|
||||
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
# Set the install configuration name.
|
||||
if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
if(BUILD_TYPE)
|
||||
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
||||
else()
|
||||
set(CMAKE_INSTALL_CONFIG_NAME "RelWithDebInfo")
|
||||
endif()
|
||||
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
||||
endif()
|
||||
|
||||
# Set the component getting installed.
|
||||
if(NOT CMAKE_INSTALL_COMPONENT)
|
||||
if(COMPONENT)
|
||||
message(STATUS "Install component: \"${COMPONENT}\"")
|
||||
set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
||||
else()
|
||||
set(CMAKE_INSTALL_COMPONENT)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Is this installation the result of a crosscompile?
|
||||
if(NOT DEFINED CMAKE_CROSSCOMPILING)
|
||||
set(CMAKE_CROSSCOMPILING "FALSE")
|
||||
endif()
|
||||
|
||||
# Set path to fallback-tool for dependency-resolution.
|
||||
if(NOT DEFINED CMAKE_OBJDUMP)
|
||||
set(CMAKE_OBJDUMP "/system/bin/objdump")
|
||||
endif()
|
||||
|
1
backends/playback/gme/game-music-emu
Submodule
1
backends/playback/gme/game-music-emu
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit e76bdc0cb916e79aa540290e6edd0c445879d3ba
|
123
backends/playback/gme/gme_backend.cpp
Normal file
123
backends/playback/gme/gme_backend.cpp
Normal file
|
@ -0,0 +1,123 @@
|
|||
#include "gme_backend.hpp"
|
||||
#include <algorithm>
|
||||
#include <ipc/common.pb.h>
|
||||
#include <exception>
|
||||
#include <filesystem>
|
||||
#include "file_backend.hpp"
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <file_backend.hpp>
|
||||
#include <util.hpp>
|
||||
#include <license.hpp>
|
||||
#include <assets/assets.h>
|
||||
#include <limits.h>
|
||||
#include <gme.h>
|
||||
void GmeBackend::load(const char *filename) {
|
||||
memset(&spec, 0, sizeof(spec));
|
||||
current_file = filename;
|
||||
spec.format = AUDIO_S16SYS;
|
||||
spec.samples = 100;
|
||||
spec.channels = 2;
|
||||
spec.freq = 48000;
|
||||
spec.size = 100 * 2 * sizeof(int16_t);
|
||||
gme_open_file(filename, &gme_backend, spec.freq);
|
||||
if (gme_backend == NULL) {
|
||||
throw std::exception();
|
||||
}
|
||||
int track_count = gme_track_count(gme_backend);
|
||||
streams.clear();
|
||||
for (int i = 0; i < track_count; i++) {
|
||||
gme_info_t *info;
|
||||
gme_track_info(gme_backend, &info, i);
|
||||
PlaybackStream stream;
|
||||
if (info->song[0] == '\0') {
|
||||
stream.name = fmt::format("Song {}", i);
|
||||
} else {
|
||||
stream.name = info->song;
|
||||
}
|
||||
|
||||
stream.length = ((double)info->length) / 1000.0;
|
||||
if (stream.length < 0.0) stream.length = 0.0;
|
||||
stream.id = i;
|
||||
streams.push_back(stream);
|
||||
gme_free_info(info);
|
||||
}
|
||||
}
|
||||
extern SDL_AudioSpec obtained;
|
||||
void GmeBackend::switch_stream(int idx) {
|
||||
if (gme_backend == NULL) {
|
||||
throw std::exception();
|
||||
}
|
||||
if (idx > streams.size()) {
|
||||
throw std::exception();
|
||||
}
|
||||
gme_start_track(gme_backend, idx);
|
||||
gme_info_t *info;
|
||||
gme_track_info(gme_backend, &info, idx);
|
||||
if (info->length < 0) {
|
||||
info->length = 0;
|
||||
}
|
||||
uint64_t tmp = info->length;
|
||||
tmp *= spec.freq;
|
||||
tmp /= 1000;
|
||||
this->length = tmp;
|
||||
this->loop_len = info->loop_length;
|
||||
this->loop_start = info->intro_length;
|
||||
if (info->song[0] == '\0') {
|
||||
this->current_title = {};
|
||||
} else {
|
||||
this->current_title = info->song;
|
||||
}
|
||||
gme_free_info(info);
|
||||
gme_ignore_silence(gme_backend, true);
|
||||
open = true;
|
||||
}
|
||||
void GmeBackend::cleanup() {
|
||||
gme_delete(gme_backend);
|
||||
gme_backend = NULL;
|
||||
streams.clear();
|
||||
}
|
||||
size_t GmeBackend::render(void *buf, size_t maxlen) {
|
||||
if (gme_backend == NULL) return 0;
|
||||
const char *err;
|
||||
size_t sample_type_len = 4;
|
||||
maxlen /= sample_type_len;
|
||||
if (err = gme_play(gme_backend, maxlen * 2, (short*)buf)) {
|
||||
ERROR.writefln("Failed to play audio: %s", err);
|
||||
return 0;
|
||||
}
|
||||
int pos_samples = gme_tell_samples(gme_backend);
|
||||
int loop_end = loop_len + loop_start;
|
||||
uint64_t loop_end_samples = loop_end;
|
||||
loop_end_samples *= spec.freq;
|
||||
loop_end_samples /= 1000;
|
||||
uint64_t loop_start_samples = loop_start;
|
||||
loop_start_samples *= spec.freq;
|
||||
loop_start_samples /= 1000;
|
||||
if (pos_samples >= loop_end_samples || gme_track_ended(gme_backend)) {
|
||||
gme_seek_samples(gme_backend, loop_start_samples + (pos_samples - loop_end_samples));
|
||||
}
|
||||
maxlen *= sample_type_len;
|
||||
return maxlen;
|
||||
}
|
||||
uint64_t GmeBackend::get_min_samples() {
|
||||
return spec.size;
|
||||
}
|
||||
std::optional<uint64_t> GmeBackend::get_max_samples() {
|
||||
return get_min_samples();
|
||||
}
|
||||
void GmeBackend::seek_samples(uint64_t position) {
|
||||
gme_seek_samples(gme_backend, position);
|
||||
}
|
||||
uint64_t GmeBackend::get_position_samples() {
|
||||
return gme_tell_samples(gme_backend);
|
||||
}
|
||||
int GmeBackend::get_stream_idx() {
|
||||
return streamidx;
|
||||
}
|
||||
void GmeBackend::add_licenses() {
|
||||
auto &license_data = get_license_data();
|
||||
auto gme = LicenseData("gme", "lgpl-2.1");
|
||||
LOAD_LICENSE(gme, lgpl_2_1);
|
||||
license_data.insert(gme);
|
||||
}
|
44
backends/playback/gme/gme_backend.hpp
Normal file
44
backends/playback/gme/gme_backend.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
#include "playback_backend.hpp"
|
||||
#include <omp.h>
|
||||
#include <cstdint>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <streambuf>
|
||||
#include <vector>
|
||||
#include <util.hpp>
|
||||
#include <SDL.h>
|
||||
#include <gme.h>
|
||||
#include "file_backend.hpp"
|
||||
class GmeBackend : public PlaybackBackend {
|
||||
File *file;
|
||||
Fifo<int16_t> audio_buf;
|
||||
Music_Emu *gme_backend;
|
||||
int streamidx;
|
||||
int loop_len, loop_start;
|
||||
std::map<std::string, int> voices;
|
||||
public:
|
||||
uint64_t get_min_samples() override;
|
||||
std::optional<uint64_t> get_max_samples() override;
|
||||
inline std::string get_id() override {
|
||||
return "gme";
|
||||
}
|
||||
inline std::string get_name() override {
|
||||
return "Game Music Emu";
|
||||
}
|
||||
void add_licenses() override;
|
||||
//std::vector<Property> get_property_list() override;
|
||||
void seek_samples(uint64_t position) override;
|
||||
void load(const char *filename) override;
|
||||
void switch_stream(int idx) override;
|
||||
void cleanup() override;
|
||||
int get_stream_idx() override;
|
||||
size_t render(void *buf, size_t maxlen) override;
|
||||
uint64_t get_position_samples() override;
|
||||
inline uint64_t get_length_samples() override {
|
||||
return length;
|
||||
}
|
||||
inline ~GmeBackend() override { }
|
||||
};
|
10
backends/playback/gme/properties.inc
Normal file
10
backends/playback/gme/properties.inc
Normal file
|
@ -0,0 +1,10 @@
|
|||
#define BOOL_PROPERTY(name, default_value) _PROPERTY(name, bool, default_value)
|
||||
#define DOUBLE_PROPERTY(name, default_value) _PROPERTY(name, double, default_value)
|
||||
BOOL_PROPERTY(pcm_enable, true)
|
||||
BOOL_PROPERTY(psg_enable, true)
|
||||
BOOL_PROPERTY(fm_enable, true)
|
||||
DOUBLE_PROPERTY(pcm_volume, 1.0)
|
||||
DOUBLE_PROPERTY(psg_volume, 1.0)
|
||||
DOUBLE_PROPERTY(fm_volume, 1.0)
|
||||
#undef BOOL_PROPERTY
|
||||
#undef DOUBLE_PROPERTY
|
Loading…
Reference in a new issue