Compare commits

..

No commits in common. "f9b5ce45779018d17e719042dadc388e1c74ac28" and "480311b03ec5e064ccf0d002b74ee3a232c8f4a1" have entirely different histories.

18 changed files with 75 additions and 483 deletions

View file

@ -119,7 +119,6 @@ if(DEFINED ANDROID_NDK)
set(USE_SPEEX OFF CACHE BOOL "" FORCE) set(USE_SPEEX OFF CACHE BOOL "" FORCE)
set(USE_G719 OFF CACHE BOOL "" FORCE) set(USE_G719 OFF CACHE BOOL "" FORCE)
set(USE_VORBIS OFF CACHE BOOL "" FORCE) set(USE_VORBIS OFF CACHE BOOL "" FORCE)
set(BUILD_FMT ON CACHE BOOL "" FORCE)
endif() endif()
if (BUILD_SDL) if (BUILD_SDL)
set(SDL_SHARED OFF CACHE BOOL "" FORCE) set(SDL_SHARED OFF CACHE BOOL "" FORCE)

View file

@ -1,5 +0,0 @@
#!/bin/sh
OLDDIR="$(pwd)"
cd "$(dirname "$0")"
xdg-mime install assets/zsm-mime.xml
cd "$OLDDIR"

View file

@ -7,7 +7,7 @@ GenericName=Looping audio player
Exec=looper -n %f Exec=looper -n %f
Icon=looper Icon=looper
StartupWMClass=looper;com.complecwaft.Looper;com.complecwaft.Looper.GTK StartupWMClass=looper;com.complecwaft.Looper;com.complecwaft.Looper.GTK
MimeType=audio/x-wav;audio/ogg;audio/x-vorbis+ogg;audio/x-opus+ogg;audio/mpeg;audio/flac;audio/xm;audio/x-mod;audio/x-zsound; MimeType=audio/x-wav;audio/ogg;audio/x-vorbis+ogg;audio/x-opus+ogg;audio/mpeg;audio/flac;audio/xm;audio/x-mod;
Categories=Audio;AudioVideo; Categories=Audio;AudioVideo;
Terminal=false Terminal=false
SingleMainWindow=true SingleMainWindow=true

View file

@ -1,11 +0,0 @@
<?xml version="1.0"?>
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
<mime-type type="audio/x-zsound">
<comment>ZSound file for the Commander X16</comment>
<glob pattern="*.zsm"/>
<magic priority="50">
<match type="string" value="zm" offset="0" />
</magic>
</mime-type>
</mime-info>

View file

@ -1,10 +0,0 @@
#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

View file

@ -6,37 +6,14 @@ extern "C" {
#include "x16emu/vera_psg.h" #include "x16emu/vera_psg.h"
#include "x16emu/ymglue.h" #include "x16emu/ymglue.h"
} }
#include <ipc/common.pb.h>
#include <exception> #include <exception>
#include <filesystem> #include <filesystem>
#include "file_backend.hpp" #include "file_backend.hpp"
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include <file_backend.hpp> #include <file_backend.hpp>
#include <util.hpp>
#define HZ (AUDIO_SAMPLERATE) #define HZ (AUDIO_SAMPLERATE)
#define BUFFERS 32 #define BUFFERS 32
#define _PROPERTY(name, type, default_value) \
type ZsmBackend::name() { \
std::optional<google::protobuf::Any> value_maybe = get(#name); \
if (value_maybe.has_value()) { \
return resolve_value<type>(value_maybe.value()); \
} \
return default_value; \
}
#include "properties.inc"
#undef _PROPERTY
std::vector<Property> ZsmBackend::get_property_list() {
std::vector<Property> properties;
properties.push_back(make_property(PropertyType::Boolean, "Enable PCM channel", "pcm_enable"));
properties.push_back(make_property(PropertyType::Boolean, "Enable PSG channels", "psg_enable"));
properties.push_back(make_property(PropertyType::Boolean, "Enable FM channels", "fm_enable"));
properties.push_back(make_property(PropertyType::Double, "Volume of PCM channel", "pcm_volume", make_hint(0.0, 1.0)));
properties.push_back(make_property(PropertyType::Double, "Volume of PSG channels", "psg_volume", make_hint(0.0, 1.0)));
properties.push_back(make_property(PropertyType::Double, "Volume of FM channels", "fm_volume", make_hint(0.0, 1.0)));
return properties;
}
void ZsmBackend::load(const char *filename) { void ZsmBackend::load(const char *filename) {
memset(&spec, 0, sizeof(spec)); memset(&spec, 0, sizeof(spec));
spec.format = AUDIO_S16SYS; spec.format = AUDIO_S16SYS;
@ -138,22 +115,6 @@ void ZsmBackend::load(const char *filename) {
loop_start = this->loop_pos; loop_start = this->loop_pos;
fm_stream = SDL_NewAudioStream(AUDIO_S16SYS, 2, YM_FREQ, AUDIO_S16SYS, 2, PSG_FREQ); fm_stream = SDL_NewAudioStream(AUDIO_S16SYS, 2, YM_FREQ, AUDIO_S16SYS, 2, PSG_FREQ);
DEBUG.writefln("fm_stream: %ld -> %ld", YM_FREQ, 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"
} }
extern SDL_AudioSpec obtained; extern SDL_AudioSpec obtained;
void ZsmBackend::switch_stream(int idx) { void ZsmBackend::switch_stream(int idx) {
@ -206,7 +167,7 @@ void ZsmBackend::tick(bool step) {
for (uint8_t i = 0; i < cmd.fm_write.len; i++) { 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); YM_write_reg(cmd.fm_write.regs[i].reg, cmd.fm_write.regs[i].val);
while (YM_read_status()) { while (YM_read_status()) {
size_t clocksToAddForYm = 1; size_t clocksToAddForYm = 64;
ticks_remaining -= clocksToAddForYm; ticks_remaining -= clocksToAddForYm;
if (ticks_remaining < 0) { if (ticks_remaining < 0) {
delayTicks -= 1; delayTicks -= 1;
@ -424,61 +385,3 @@ double ZsmBackend::get_position() {
int ZsmBackend::get_stream_idx() { int ZsmBackend::get_stream_idx() {
return 0; 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<int16_t>(samples);
int16_t *pcm_ptr = pcm_buf.get_item_sized<int16_t>(samples);
psg_render(psg_ptr, samples / 2);
pcm_render(pcm_ptr, samples / 2);
int16_t *out_ptr = out_buf.get_item_sized<int16_t>(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<int16_t>(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<int16_t>(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);
}

View file

@ -93,13 +93,57 @@ class ZsmBackend : public PlaybackBackend {
SDL_AudioStream *fm_stream; SDL_AudioStream *fm_stream;
std::vector<pcm_instrument*> instruments; std::vector<pcm_instrument*> instruments;
uint8_t *audio_sample = nullptr; uint8_t *audio_sample = nullptr;
bool pcm_enable(); int16_t combine_audio(int16_t a, int16_t b) {
bool psg_enable(); return (int16_t)((((int32_t)a) + ((int32_t)b)) >> 1);
bool fm_enable(); }
double pcm_volume(); void audio_step(size_t samples) {
double psg_volume(); if (samples == 0) return;
double fm_volume(); while (remain != 0 && pcm_fifo_avail() < samples) {
void audio_step(size_t 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<int16_t>(samples);
int16_t *pcm_ptr = pcm_buf.get_item_sized<int16_t>(samples);
psg_render(psg_ptr, samples / 2);
pcm_render(pcm_ptr, samples / 2);
int16_t *out_ptr = out_buf.get_item_sized<int16_t>(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<int16_t>(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<int16_t>(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] = {psg_ptr[j] >> 1, psg_ptr[j + 1] >> 1};
int16_t pcm[2] = {pcm_ptr[j] >> 1, pcm_ptr[j + 1] >> 1};
int16_t vera[2] = {psg[0] + pcm[0], psg[1] + pcm[1]};
int16_t fm[2] = {ym_resample_ptr[j], ym_resample_ptr[j + 1]};
int16_t mix[2] = {vera[0] + (fm[0] >> 1), vera[1] + (fm[1] >> 1)};
out_ptr[j++] = mix[0];
out_ptr[j++] = mix[1];
}
audio_buf.push(out_ptr, samples);
}
inline void *reserve(size_t len) { inline void *reserve(size_t len) {
return (void*)audio_buf.reserve(len); return (void*)audio_buf.reserve(len);
} }
@ -133,7 +177,6 @@ class ZsmBackend : public PlaybackBackend {
inline std::string get_name() override { inline std::string get_name() override {
return "ZSM player"; return "ZSM player";
} }
std::vector<Property> get_property_list() override;
void seek(double position) override; void seek(double position) override;
void load(const char *filename) override; void load(const char *filename) override;
void switch_stream(int idx) override; void switch_stream(int idx) override;

View file

@ -4,7 +4,6 @@
#include <assets/assets.h> #include <assets/assets.h>
#include <filesystem> #include <filesystem>
#include <options.hpp> #include <options.hpp>
#include "imgui/imgui.h"
#include "ui_backend.hpp" #include "ui_backend.hpp"
#include "thirdparty/CLI11.hpp" #include "thirdparty/CLI11.hpp"
#include <web_functions.hpp> #include <web_functions.hpp>
@ -142,9 +141,6 @@ void MainLoop::FileLoaded() {
SetWindowTitle("Looper"); SetWindowTitle("Looper");
} }
streams = playback->get_streams(); streams = playback->get_streams();
properties = playback->get_property_list();
boolean_properties.clear();
double_properties.clear();
} }
void MainLoop::GuiFunction() { void MainLoop::GuiFunction() {
#if defined(__EMSCRIPTEN__)||defined(__ANDROID__) #if defined(__EMSCRIPTEN__)||defined(__ANDROID__)
@ -199,9 +195,6 @@ void MainLoop::GuiFunction() {
show_demo_window = !show_demo_window; show_demo_window = !show_demo_window;
set_option<double>("ui.imgui.demo_window", show_demo_window); set_option<double>("ui.imgui.demo_window", show_demo_window);
} }
if (ImGui::MenuItem(_TR_CTX("Main menu | Debug", "Edit properties"), nullptr, property_editor)) {
property_editor = !property_editor;
}
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (ImGui::BeginMenu(_TRI_CTX(ICON_FK_INFO_CIRCLE, "Main menu", "Help"))) { if (ImGui::BeginMenu(_TRI_CTX(ICON_FK_INFO_CIRCLE, "Main menu", "Help"))) {
@ -304,95 +297,6 @@ void MainLoop::GuiFunction() {
ImGui::PopItemWidth(); ImGui::PopItemWidth();
} }
ImGui::End(); ImGui::End();
if (property_editor) {
ImGui::SetNextWindowDockID(dockid);
ImGui::Begin("Property Editor", &property_editor);
{
for (auto property : properties) {
ImGui::PushID(property.path().c_str());
bool valid = false;
switch (property.type()) {
case PropertyType::Double: {
std::optional<double> min;
std::optional<double> max;
double value = 0.0;
if (double_properties.contains(property.path())) {
value = double_properties[property.path()];
} else {
auto value_to_resolve = playback->get_property(property.path());
if (value_to_resolve.has_value()) {
value = resolve_value<double>(value_to_resolve.value());
}
double_properties[property.path()] = value;
}
if (property.has_hint() && property.hint().has_range()) {
auto range = property.hint().range();
if (range.has_min() && range.has_max()) {
float flt = (float)value;
if (ImGui::SliderFloat(property.path().c_str(), &flt, (float)range.min(), (float)range.max())) {
double_properties[property.path()] = flt;
}
valid = true;
} else {
if (range.has_min()) min = range.min();
if (range.has_max()) max = range.max();
}
}
if (!valid) {
ImGui::InputDouble(property.path().c_str(), &value);
if (min.has_value() && value < min) {
value = min.value();
}
if (max.has_value() && value > max) {
value = max.value();
}
double_properties[property.path()] = value;
valid = true;
}
} break;
case PropertyType::Boolean: {
bool value = false;
if (boolean_properties.contains(property.path())) {
value = boolean_properties[property.path()];
} else {
auto value_to_resolve = playback->get_property(property.path());
if (value_to_resolve.has_value()) {
value = resolve_value<bool>(value_to_resolve.value());
}
boolean_properties[property.path()] = value;
}
if (ImGui::Checkbox(property.path().c_str(), &value)) {
boolean_properties[property.path()] = value;
}
valid = true;
} break;
}
if (valid) {
ImGui::SameLine();
if (ImGui::Button("Set")) {
switch (property.type()) {
case PropertyType::Double: {
DoubleProperty property_d;
property_d.set_value(double_properties[property.path()]);
google::protobuf::Any value;
value.PackFrom(property_d);
playback->set_property(property.path(), value);
} break;
case PropertyType::Boolean: {
BooleanProperty property_b;
property_b.set_value(boolean_properties[property.path()]);
google::protobuf::Any value;
value.PackFrom(property_b);
playback->set_property(property.path(), value);
} break;
}
}
}
ImGui::PopID();
}
}
ImGui::End();
}
if (prefs_window) { if (prefs_window) {
ImGui::SetNextWindowDockID(dockid); ImGui::SetNextWindowDockID(dockid);
ImGui::Begin(_TRI_CTX(ICON_FK_COG, "Window title, window opened by menu item", "Preferences..."), &prefs_window); ImGui::Begin(_TRI_CTX(ICON_FK_COG, "Window title, window opened by menu item", "Preferences..."), &prefs_window);

View file

@ -12,7 +12,7 @@
#include <cmath> #include <cmath>
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
#include <map>
#include <SDL.h> #include <SDL.h>
#include <SDL_image.h> #include <SDL_image.h>
#include <filesystem> #include <filesystem>
@ -46,16 +46,12 @@ class MainLoop : public RendererBackend {
bool theme_editor = false; bool theme_editor = false;
bool about_window = false; bool about_window = false;
bool debug_mode = false; bool debug_mode = false;
bool property_editor = false;
bool restart_needed = false; bool restart_needed = false;
bool stopped = true; bool stopped = true;
std::vector<UIBackend*> backends; std::vector<UIBackend*> backends;
UIBackend *cur_backend; UIBackend *cur_backend;
friend class ImGuiUIBackend; friend class ImGuiUIBackend;
std::atomic_bool exit_flag; std::atomic_bool exit_flag;
std::map<std::string, bool> boolean_properties;
std::map<std::string, double> double_properties;
std::vector<Property> properties;
std::vector<PlaybackStream> streams; std::vector<PlaybackStream> streams;
public: public:
Playback *playback; Playback *playback;

View file

@ -21,42 +21,6 @@ message StringProperty {
message DoubleProperty { message DoubleProperty {
double value = 1; double value = 1;
}; };
message BooleanProperty {
bool value = 1;
};
message BytesProperty {
bytes value = 1;
};
message PropertyHintRange {
optional double min = 1;
optional double max = 2;
};
message PropertyHintEnum {
repeated string data = 1;
};
message PropertyHint {
oneof hint {
PropertyHintRange range = 1;
fixed64 max_length = 2;
PropertyHintEnum enum = 3;
};
};
enum PropertyType {
Double = 0;
Boolean = 1;
String = 2;
Bytes = 3;
Stream = 4;
AudioSpec = 5;
StreamID = 6;
}
message Property {
PropertyType type = 1;
optional PropertyId id = 5;
optional string path = 2;
optional string name = 4;
optional PropertyHint hint = 3;
};
message StreamId { message StreamId {
uint64 id = 504; uint64 id = 504;
}; };
@ -68,6 +32,9 @@ message Stream {
message StreamList { message StreamList {
repeated Stream streams = 500; repeated Stream streams = 500;
} }
message Position {
double pos = 508;
};
enum EndianID { enum EndianID {
LITTLE = 0; LITTLE = 0;
BIG = 1; BIG = 1;

View file

@ -31,9 +31,6 @@ message SimpleAckResponse {
message InitCommand { message InitCommand {
string filename = 1; string filename = 1;
uint64 idx = 2; uint64 idx = 2;
};
message GetPropertyListCommand {
}; };
message RPCCall { message RPCCall {
uint64 cmdid = 1; uint64 cmdid = 1;
@ -44,12 +41,8 @@ message RPCCall {
ResetProperty reset = 5; ResetProperty reset = 5;
QuitCmd quit = 6; QuitCmd quit = 6;
InitCommand init = 7; InitCommand init = 7;
GetPropertyListCommand get_property_list = 8;
}; };
}; };
message PropertyList {
repeated Property list = 1;
}
message RPCResponse { message RPCResponse {
uint64 cmdid = 1; uint64 cmdid = 1;
oneof response { oneof response {
@ -58,6 +51,5 @@ message RPCResponse {
PropertyData data = 4; PropertyData data = 4;
ResetResponse reset = 5; ResetResponse reset = 5;
ErrorResponse err = 6; ErrorResponse err = 6;
PropertyList property_list = 7;
}; };
}; };

View file

@ -669,22 +669,3 @@ std::vector<PlaybackStream> PlaybackInstance::get_streams() {
int PlaybackInstance::get_current_stream() { int PlaybackInstance::get_current_stream() {
return current_stream; return current_stream;
} }
void PlaybackInstance::set_property(std::string path, google::protobuf::Any value) {
if (this->process != nullptr) {
this->process->set_property(path, value);
}
}
std::optional<google::protobuf::Any> PlaybackInstance::get_property(std::string path) {
if (this->process != nullptr) {
return this->process->get_property(path);
}
return {};
}
std::optional<google::protobuf::Any> PlaybackInstance::reset_property(std::string path) {
return {};
}
std::vector<Property> PlaybackInstance::get_property_list() {
if (process == nullptr) return {};
return process->get_property_list();
}

View file

@ -23,8 +23,6 @@ extern "C" {
#include "playback_backend.hpp" #include "playback_backend.hpp"
#include "config.hpp" #include "config.hpp"
#include "playback_process.hpp" #include "playback_process.hpp"
#include <google/protobuf/any.h>
#include <ipc/internal.pb.h>
using namespace soundtouch; using namespace soundtouch;
using std::span; using std::span;
using std::optional; using std::optional;
@ -197,15 +195,6 @@ class Playback {
} }
virtual void DeinitLoopFunction() { virtual void DeinitLoopFunction() {
}
virtual void set_property(std::string path, google::protobuf::Any value) {
}
virtual std::optional<google::protobuf::Any> get_property(std::string path) {
return {};
}
virtual std::optional<google::protobuf::Any> reset_property(std::string path) {
return {};
} }
bool loop_started = false; bool loop_started = false;
virtual void start_loop() { virtual void start_loop() {
@ -221,9 +210,6 @@ class Playback {
LoopFunction(); LoopFunction();
} }
} }
virtual std::vector<Property> get_property_list() {
return {};
}
static Playback *Create(bool *daemon_found, bool daemon = false); static Playback *Create(bool *daemon_found, bool daemon = false);
}; };
@ -334,10 +320,6 @@ public:
void InitLoopFunction() override; void InitLoopFunction() override;
void DeinitLoopFunction() override; void DeinitLoopFunction() override;
void LoopFunction() override; void LoopFunction() override;
void set_property(std::string path, google::protobuf::Any) override;
std::optional<google::protobuf::Any> get_property(std::string path) override;
std::optional<google::protobuf::Any> reset_property(std::string path) override;
std::vector<Property> get_property_list() override;
float volume; float volume;
float speed; float speed;
float tempo; float tempo;

View file

@ -77,9 +77,6 @@ class PlaybackBackend {
inline double get_rate() { inline double get_rate() {
return this->rate; return this->rate;
} }
inline virtual std::vector<Property> get_property_list() {
return std::vector<Property>();
}
inline virtual bool set(std::string path, google::protobuf::Any value) {properties[path] = value; return true;} inline virtual bool set(std::string path, google::protobuf::Any value) {properties[path] = value; return true;}
inline virtual std::optional<google::protobuf::Any> get(std::string path) {return properties.contains(path) ? properties[path] : std::optional<google::protobuf::Any>();} inline virtual std::optional<google::protobuf::Any> get(std::string path) {return properties.contains(path) ? properties[path] : std::optional<google::protobuf::Any>();}
inline virtual std::optional<google::protobuf::Any> reset(std::string path) { inline virtual std::optional<google::protobuf::Any> reset(std::string path) {

View file

@ -296,17 +296,6 @@ MaybeError PlaybackProcessServiceImpl::Quit(const QuitCmd *request) {
cur_backend_lock.get_unsafe()->cleanup(); cur_backend_lock.get_unsafe()->cleanup();
return MaybeError(); return MaybeError();
} }
PropertyList PlaybackProcessServiceImpl::GetPropertyList(const GetPropertyListCommand *cmd) {
std::vector<Property> list;
{
list = cur_backend_lock.lock()->get_property_list();
}
PropertyList output;
for (auto el : list) {
output.add_list()->CopyFrom(el);
}
return output;
}
MaybeError PlaybackProcessServiceImpl::Init(const InitCommand *cmd) { MaybeError PlaybackProcessServiceImpl::Init(const InitCommand *cmd) {
MaybeError ret; MaybeError ret;
MaybeError *response = &ret; MaybeError *response = &ret;
@ -496,9 +485,6 @@ RPCResponse PlaybackProcess::handle_command(RPCCall &call) {
} else { } else {
resp.mutable_render()->CopyFrom(output.output()); resp.mutable_render()->CopyFrom(output.output());
} }
} else if (call.has_get_property_list()) {
PropertyList output = impl.GetPropertyList(&call.get_property_list());
resp.mutable_property_list()->CopyFrom(output);
} }
if (!resp.has_ack()) { if (!resp.has_ack()) {
delete ack; delete ack;
@ -632,31 +618,6 @@ std::vector<PlaybackStream> PlaybackProcess::get_playback_streams() {
delete list; delete list;
return output; return output;
} }
bool PlaybackProcess::set_property(std::string path, google::protobuf::Any value) {
SetProperty set_property;
set_property.set_id(PropertyId::BackendSpecific);
set_property.mutable_value()->CopyFrom(value);
set_property.set_path(path);
RPCCall call;
call.mutable_set()->CopyFrom(set_property);
RPCResponse output = SendCommand(&call);
if (output.has_err()) {
return false;
}
return true;
}
std::optional<google::protobuf::Any> PlaybackProcess::get_property(std::string path) {
GetProperty get_property;
get_property.set_id(PropertyId::BackendSpecific);
get_property.set_path(path);
RPCCall call;
call.mutable_get()->CopyFrom(get_property);
RPCResponse output = SendCommand(&call);
if (output.has_err()) {
return {};
}
return output.data().value();
}
size_t PlaybackProcess::render(void *buf, size_t maxlen) { size_t PlaybackProcess::render(void *buf, size_t maxlen) {
RenderCommand rend_cmd = RenderCommand(); RenderCommand rend_cmd = RenderCommand();
rend_cmd.set_len(maxlen); rend_cmd.set_len(maxlen);
@ -715,18 +676,3 @@ double PlaybackProcess::get_cached_rate() {
void PlaybackProcess::set_rate(double value) { void PlaybackProcess::set_rate(double value) {
set_property_double(PropertyId::PlaybackRate, value); set_property_double(PropertyId::PlaybackRate, value);
} }
std::vector<Property> PlaybackProcess::get_property_list() {
RPCCall call;
GetPropertyListCommand cmd;
call.mutable_get_property_list()->CopyFrom(cmd);
RPCResponse resp = SendCommand(&call);
if (resp.has_property_list()) {
std::vector<Property> output;
for (size_t i = 0; i < resp.property_list().list_size(); i++) {
output.push_back(resp.property_list().list(i));
}
return output;
} else {
return std::vector<Property>();
}
}

View file

@ -30,8 +30,13 @@ class PlaybackProcessServiceImpl {
ResetResponse Reset(const ResetProperty *request); ResetResponse Reset(const ResetProperty *request);
MaybeError Quit(const QuitCmd *request); MaybeError Quit(const QuitCmd *request);
MaybeError Init(const InitCommand *cmd); MaybeError Init(const InitCommand *cmd);
PropertyList GetPropertyList(const GetPropertyListCommand *cmd);
}; };
template<class T>
inline T *resolve_any(google::protobuf::Any value) {
T *output = new T();
value.UnpackTo(output);
return output;
}
//#define DEBUG_PRINT_IPC //#define DEBUG_PRINT_IPC
void print_ipc_message(const google::protobuf::Message &msg, size_t level = 0); void print_ipc_message(const google::protobuf::Message &msg, size_t level = 0);
class PlaybackProcess { class PlaybackProcess {
@ -119,7 +124,6 @@ class PlaybackProcess {
std::optional<google::protobuf::Any> get_property(std::string path); std::optional<google::protobuf::Any> get_property(std::string path);
bool set_property(std::string path, google::protobuf::Any value); bool set_property(std::string path, google::protobuf::Any value);
std::vector<Property> get_property_list();
PlaybackProcess(std::string filename, int idx = 0); PlaybackProcess(std::string filename, int idx = 0);
~PlaybackProcess(); ~PlaybackProcess();
}; };

View file

@ -180,26 +180,3 @@ int NotSDL_ConvertAudioSamples(const SDL_AudioSpec *src_spec, const Uint8 *src_d
SDL_FreeAudioStream(stream); SDL_FreeAudioStream(stream);
return retval; return retval;
} }
PropertyHint make_hint(double min, double max) {
PropertyHint output;
auto range = output.mutable_range();
range->set_min(min);
range->set_max(max);
return output;
}
Property make_property(PropertyType type, std::string name, PropertyId id, std::optional<std::string> path, std::optional<PropertyHint> hint) {
Property output;
output.set_id(id);
output.set_name(name);
output.set_type(type);
if (path.has_value()) output.set_path(path.value());
if (hint.has_value()) output.mutable_hint()->CopyFrom(hint.value());
return output;
}
Property make_property(PropertyType type, std::string name, std::string path, std::optional<PropertyHint> hint) {
return make_property(type, name, PropertyId::BackendSpecific, path, hint)
}
Property make_property(PropertyType type, std::string name, PropertyId id, std::optional<PropertyHint> hint) {
return make_property(type, name, id, {}, hint)
}

View file

@ -17,7 +17,6 @@
#include <cassert> #include <cassert>
#include <SDL.h> #include <SDL.h>
#include "log.hpp" #include "log.hpp"
#include <ipc/common.pb.h>
namespace fs = std::filesystem; namespace fs = std::filesystem;
std::string PadZeros(std::string input, size_t required_length); std::string PadZeros(std::string input, size_t required_length);
uint8_t TimeToComponentCount(double time_code); uint8_t TimeToComponentCount(double time_code);
@ -334,9 +333,6 @@ class DynPtr {
DynPtr(size_t len) : DynPtr() { DynPtr(size_t len) : DynPtr() {
resize(len); resize(len);
} }
DynPtr(std::string input) : DynPtr(input.length()) {
memcpy(this->ptr, input.data(), input.length());
}
/// @brief Gets the pointer, but does not reallocate it. /// @brief Gets the pointer, but does not reallocate it.
/// @param T The type of pointer to return. May be void to return void*. /// @param T The type of pointer to return. May be void to return void*.
/// @returns The pointer, owned by the DynPtr object. /// @returns The pointer, owned by the DynPtr object.
@ -489,72 +485,3 @@ void blocking_write(int fd, const void *buf, const size_t len);
void blocking_read(int fd, void *buf, const size_t len); void blocking_read(int fd, void *buf, const size_t len);
int NotSDL_ConvertAudioSamples(const SDL_AudioSpec *src_spec, const Uint8 *src_data, int src_len, int NotSDL_ConvertAudioSamples(const SDL_AudioSpec *src_spec, const Uint8 *src_data, int src_len,
const SDL_AudioSpec *dst_spec, Uint8 **dst_data, int *dst_len); const SDL_AudioSpec *dst_spec, Uint8 **dst_data, int *dst_len);
template<class T>
inline T *resolve_any(google::protobuf::Any value) {
T *output = new T();
value.UnpackTo(output);
return output;
}
template<class T>
inline T resolve_value(google::protobuf::Any value) {
throw std::exception();
}
template<>
inline bool resolve_value<bool>(google::protobuf::Any value) {
BooleanProperty *property = resolve_any<BooleanProperty>(value);
bool output = property->value();
delete property;
return output;
}
template<>
inline std::string resolve_value<std::string>(google::protobuf::Any value) {
StringProperty *property = resolve_any<StringProperty>(value);
std::string output = property->value();
delete property;
return output;
}
template<>
inline DynPtr resolve_value<DynPtr>(google::protobuf::Any value) {
BytesProperty *property = resolve_any<BytesProperty>(value);
std::string output = property->value();
delete property;
return DynPtr(output);
}
template<>
inline double resolve_value(google::protobuf::Any value) {
DoubleProperty *property = resolve_any<DoubleProperty>(value);
double output = property->value();
delete property;
return output;
}
template<class T>
inline google::protobuf::Any value_to_any(T value) {
google::protobuf::Any output;
output.PackFrom(value);
return output;
}
template<>
inline google::protobuf::Any value_to_any<double>(double value) {
DoubleProperty output;
output.set_value(value);
return value_to_any<DoubleProperty>(output);
}
template<>
inline google::protobuf::Any value_to_any<bool>(bool value) {
BooleanProperty output;
output.set_value(value);
return value_to_any<BooleanProperty>(output);
}
template<>
inline google::protobuf::Any value_to_any<std::string>(std::string value) {
StringProperty output;
output.set_value(value);
return value_to_any<StringProperty>(output);
}
Property make_property(PropertyType type, std::string name, PropertyId id, std::optional<PropertyHint> hint);
Property make_property(PropertyType type, std::string name, std::string path, std::optional<PropertyHint> hint = {});
Property make_property(PropertyType type, std::string name, PropertyId id = PropertyId::BackendSpecific, std::optional<std::string> path = {}, std::optional<PropertyHint> hint = {});