Compare commits
10 Commits
Author | SHA1 | Date |
---|---|---|
Sebastian | e18b23446c | |
Sebastian | 5561fc32cb | |
Sebastian | 00f020430f | |
Sebastian | c944f89ed3 | |
Sebastian | d3c66b6260 | |
Sebastian | 6fbe5949e6 | |
Sebastian | d34d2ee2cc | |
Sebastian | 84e7d85137 | |
Sebastian | 166846c622 | |
Sebastian | a26ff950c1 |
|
@ -0,0 +1,18 @@
|
||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
audit:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: forgejo.zenerdio.de/sebastian/apt-decoder-ci:v0.2.1
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/bin/
|
||||||
|
~/.cargo/registry/index/
|
||||||
|
~/.cargo/registry/cache/
|
||||||
|
~/.cargo/git/db/
|
||||||
|
target/
|
||||||
|
key: audit-apt-decoder
|
||||||
|
- run: CARGO_HOME=/root/.cargo cargo audit
|
|
@ -0,0 +1,55 @@
|
||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: forgejo.zenerdio.de/sebastian/apt-decoder-ci:v0.2.1
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/bin/
|
||||||
|
~/.cargo/registry/index/
|
||||||
|
~/.cargo/registry/cache/
|
||||||
|
~/.cargo/git/db/
|
||||||
|
target/
|
||||||
|
key: build-apt-decoder
|
||||||
|
restore-keys: audit-apt-decoder
|
||||||
|
- run: CARGO_HOME=~/.cargo cargo build --release
|
||||||
|
|
||||||
|
build-windows:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: forgejo.zenerdio.de/sebastian/apt-decoder-ci:v0.2.1
|
||||||
|
needs: build
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/cache/restore@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/bin/
|
||||||
|
~/.cargo/registry/index/
|
||||||
|
~/.cargo/registry/cache/
|
||||||
|
~/.cargo/git/db/
|
||||||
|
target/
|
||||||
|
key: build-apt-decoder
|
||||||
|
- run: CARGO_HOME=~/.cargo cargo build --target x86_64-pc-windows-gnu --release
|
||||||
|
|
||||||
|
build-appimage:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: forgejo.zenerdio.de/sebastian/apt-decoder-ci:v0.2.1
|
||||||
|
needs: build
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/cache/restore@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/bin/
|
||||||
|
~/.cargo/registry/index/
|
||||||
|
~/.cargo/registry/cache/
|
||||||
|
~/.cargo/git/db/
|
||||||
|
target/
|
||||||
|
key: build-apt-decoder
|
||||||
|
- run: CARGO_HOME=~/.cargo PATH=$PATH:$CARGO_HOME/bin x build -r --format appimage
|
|
@ -0,0 +1,31 @@
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags: 'v*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish-release:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: forgejo.zenerdio.de/sebastian/apt-decoder-ci:v0.2.1
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/cache/restore@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/bin/
|
||||||
|
~/.cargo/registry/index/
|
||||||
|
~/.cargo/registry/cache/
|
||||||
|
~/.cargo/git/db/
|
||||||
|
target/
|
||||||
|
key: build-apt-decoder
|
||||||
|
- run: CARGO_HOME=~/.cargo cargo build --target x86_64-pc-windows-gnu --release
|
||||||
|
- run: CARGO_HOME=~/.cargo PATH=$PATH:$CARGO_HOME/bin x build -r --format appimage
|
||||||
|
- run: mkdir -p release
|
||||||
|
- run: cp target/x/release/linux/x64/apt-decoder.AppImage release/apt-decoder-${{ github.ref_name }}.AppImage
|
||||||
|
- run: cp target/x86_64-pc-windows-gnu/release/apt-decoder.exe release/
|
||||||
|
- run: cd release && zip apt-decoder-win.zip apt-decoder.exe && rm apt-decoder.exe
|
||||||
|
- uses: actions/forgejo-release@v1
|
||||||
|
with:
|
||||||
|
direction: upload
|
||||||
|
release-dir: release
|
||||||
|
token: ${{ secrets.FORGEJO_RELEASE }}
|
|
@ -1 +1,4 @@
|
||||||
target
|
target
|
||||||
|
.vendor
|
||||||
|
*.AppImage
|
||||||
|
icon.png
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
pipeline:
|
|
||||||
build:
|
|
||||||
image: rust:bullseye
|
|
||||||
commands:
|
|
||||||
- apt update && apt install -y libgtk-3-dev libxcb-shape0-dev
|
|
||||||
libxcb-xfixes0-dev
|
|
||||||
- cargo build --release
|
|
||||||
|
|
||||||
build_appimage:
|
|
||||||
image: rust:bullseye
|
|
||||||
group: build_release_files
|
|
||||||
commands:
|
|
||||||
- apt update && apt install -y libgtk-3-dev libxcb-shape0-dev
|
|
||||||
libxcb-xfixes0-dev python3-pip python3-setuptools patchelf
|
|
||||||
desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse
|
|
||||||
# Install appimage tool
|
|
||||||
- (cd /tmp/ &&
|
|
||||||
wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage &&
|
|
||||||
chmod +x appimagetool-x86_64.AppImage &&
|
|
||||||
./appimagetool-x86_64.AppImage --appimage-extract &&
|
|
||||||
cp -avr squashfs-root/usr/* /usr/)
|
|
||||||
- export CARGO_HOME=/root/.cargo
|
|
||||||
- cargo install cargo-appimage --version 1.4.0
|
|
||||||
# Build appimage
|
|
||||||
- cargo appimage
|
|
||||||
- mkdir -p release
|
|
||||||
- cp *.AppImage release/
|
|
||||||
|
|
||||||
build_windows:
|
|
||||||
image: rust:bullseye
|
|
||||||
group: build_release_files
|
|
||||||
commands:
|
|
||||||
- apt update && apt install -y mingw-w64 zip
|
|
||||||
- rustup target add x86_64-pc-windows-gnu
|
|
||||||
- rustup toolchain install stable-x86_64-pc-windows-gnu
|
|
||||||
- cargo build --target x86_64-pc-windows-gnu --release
|
|
||||||
- mkdir -p release
|
|
||||||
- cp target/x86_64-pc-windows-gnu/release/apt-decoder.exe release/
|
|
||||||
- cd release && zip apt-decoder-win.zip apt-decoder.exe && rm apt-decoder.exe
|
|
||||||
|
|
||||||
release:
|
|
||||||
image: plugins/gitea-release
|
|
||||||
settings:
|
|
||||||
files: release/*
|
|
||||||
api_key:
|
|
||||||
from_secret: api_key
|
|
||||||
base_url:
|
|
||||||
from_secret: base_url
|
|
||||||
secrets: [api_key, base_url]
|
|
||||||
when:
|
|
||||||
event: tag
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,15 +1,15 @@
|
||||||
[package]
|
[package]
|
||||||
name = "apt-decoder"
|
name = "apt-decoder"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
authors = ["Sebastian <sebastian@sebastians-site.de>"]
|
authors = ["Sebastian <sebastian@sebastians-site.de>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = {version = "3.1.8", features = ["cargo"]}
|
clap = {version = "4.0.0", features = ["cargo"]}
|
||||||
indicatif = "0.16.2"
|
indicatif = "0.16.2"
|
||||||
hound = "3.4.0"
|
hound = "3.4.0"
|
||||||
image = "0.24.0"
|
image = "0.24.0"
|
||||||
eframe = {version = "0.16.0", optional = true}
|
eframe = {version = "0.18.0", optional = true}
|
||||||
rfd = "0.7.0"
|
rfd = "0.11.4"
|
||||||
thiserror = "1.0.30"
|
thiserror = "1.0.30"
|
||||||
|
|
||||||
|
|
||||||
|
|
65
src/main.rs
65
src/main.rs
|
@ -24,30 +24,19 @@ use clap::{arg, command};
|
||||||
#[cfg(not(feature = "ui"))]
|
#[cfg(not(feature = "ui"))]
|
||||||
fn main() {
|
fn main() {
|
||||||
let matches = command!()
|
let matches = command!()
|
||||||
.arg(
|
.arg(arg!([wavfile] "Input wav file with 48kHz samplingrate").required(true))
|
||||||
arg!([wavfile] "Input wav file with 48kHz samplingrate")
|
.arg(arg!([pngfile] "Output png file").default_value("output.png"))
|
||||||
.required(true)
|
|
||||||
.allow_invalid_utf8(true),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
arg!([pngfile] "Output png file")
|
|
||||||
.default_value("output.png")
|
|
||||||
.allow_invalid_utf8(true),
|
|
||||||
)
|
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
let input_file = matches
|
let input_file = matches
|
||||||
.value_of_os("wavfile")
|
.get_one::<String>("wavfile")
|
||||||
.expect("No input file given")
|
.expect("No input file given");
|
||||||
.to_str()
|
|
||||||
.unwrap();
|
|
||||||
let output_file = matches
|
|
||||||
.value_of_os("pngfile")
|
|
||||||
.expect("No output file given")
|
|
||||||
.to_str()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
cli::decode(input_file, output_file);
|
let output_file = matches
|
||||||
|
.get_one::<String>("pngfile")
|
||||||
|
.expect("No output file given");
|
||||||
|
|
||||||
|
cli::decode(&input_file, &output_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ui")]
|
#[cfg(feature = "ui")]
|
||||||
|
@ -59,35 +48,29 @@ use ui::DecoderApp;
|
||||||
#[cfg(feature = "ui")]
|
#[cfg(feature = "ui")]
|
||||||
fn main() {
|
fn main() {
|
||||||
let matches = command!()
|
let matches = command!()
|
||||||
.arg(
|
.arg(arg!([wavfile] "Input wav file with 48kHz samplingrate").default_value("input.wav"))
|
||||||
arg!([wavfile] "Input wav file with 48kHz samplingrate")
|
.arg(arg!([pngfile] "Output png file").default_value("output.png"))
|
||||||
.default_value("input.wav")
|
.arg(arg!(-n --nogui "Disable gui and run in command line mode"))
|
||||||
.allow_invalid_utf8(true),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
arg!([pngfile] "Output png file")
|
|
||||||
.default_value("output.png")
|
|
||||||
.allow_invalid_utf8(true),
|
|
||||||
)
|
|
||||||
.arg(arg!(-n --nogui ... "Disable gui and run in command line mode"))
|
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
let input_file = matches
|
let input_file = matches
|
||||||
.value_of_os("wavfile")
|
.get_one::<String>("wavfile")
|
||||||
.expect("No input file given")
|
.expect("No input file given")
|
||||||
.to_str()
|
.to_string();
|
||||||
.unwrap();
|
|
||||||
let output_file = matches
|
let output_file = matches
|
||||||
.value_of_os("pngfile")
|
.get_one::<String>("pngfile")
|
||||||
.expect("No output file given")
|
.expect("No output file given")
|
||||||
.to_str()
|
.to_string();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
if matches.is_present("nogui") {
|
if matches.get_flag("nogui") {
|
||||||
cli::decode(input_file, output_file);
|
cli::decode(&input_file, &output_file);
|
||||||
} else {
|
} else {
|
||||||
let app = DecoderApp::new(input_file, output_file);
|
|
||||||
let native_options = eframe::NativeOptions::default();
|
let native_options = eframe::NativeOptions::default();
|
||||||
eframe::run_native(Box::new(app), native_options);
|
|
||||||
|
eframe::run_native(
|
||||||
|
"APT-Decoder",
|
||||||
|
native_options,
|
||||||
|
Box::new(move |_cc| Box::new(DecoderApp::new(&input_file, &output_file))),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
43
src/ui.rs
43
src/ui.rs
|
@ -1,9 +1,11 @@
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use eframe::egui;
|
||||||
use eframe::egui::text_edit::TextEdit;
|
use eframe::egui::text_edit::TextEdit;
|
||||||
use eframe::egui::widgets::{Button, ProgressBar};
|
use eframe::egui::widgets::{Button, ProgressBar};
|
||||||
|
use eframe::egui::ColorImage;
|
||||||
|
use eframe::egui::Visuals;
|
||||||
use eframe::egui::{Color32, RichText};
|
use eframe::egui::{Color32, RichText};
|
||||||
use eframe::{egui, epi};
|
|
||||||
|
|
||||||
use decoder;
|
use decoder;
|
||||||
use errors::DecoderError;
|
use errors::DecoderError;
|
||||||
|
@ -18,7 +20,7 @@ enum DecoderRunState {
|
||||||
struct DecoderJobState {
|
struct DecoderJobState {
|
||||||
update_steps: u32,
|
update_steps: u32,
|
||||||
progress: f32,
|
progress: f32,
|
||||||
texture: Option<egui::TextureId>,
|
texture: Option<egui::TextureHandle>,
|
||||||
run_state: DecoderRunState,
|
run_state: DecoderRunState,
|
||||||
error: Option<DecoderError>,
|
error: Option<DecoderError>,
|
||||||
}
|
}
|
||||||
|
@ -57,23 +59,10 @@ impl DecoderApp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl epi::App for DecoderApp {
|
impl eframe::App for DecoderApp {
|
||||||
fn name(&self) -> &str {
|
|
||||||
"APT Decoder"
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Called once before the first frame.
|
|
||||||
fn setup(
|
|
||||||
&mut self,
|
|
||||||
_ctx: &egui::CtxRef,
|
|
||||||
_frame: &epi::Frame,
|
|
||||||
_storage: Option<&dyn epi::Storage>,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Called each time the UI needs repainting, which may be many times per second.
|
/// Called each time the UI needs repainting, which may be many times per second.
|
||||||
/// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`.
|
/// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`.
|
||||||
fn update(&mut self, ctx: &egui::CtxRef, frame: &epi::Frame) {
|
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||||
let Self {
|
let Self {
|
||||||
input_path,
|
input_path,
|
||||||
output_path,
|
output_path,
|
||||||
|
@ -89,6 +78,7 @@ impl epi::App for DecoderApp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx.set_visuals(Visuals::dark());
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
ui.heading("APT-Decoder");
|
ui.heading("APT-Decoder");
|
||||||
|
|
||||||
|
@ -130,16 +120,13 @@ impl epi::App for DecoderApp {
|
||||||
.add_enabled(!state.is_running(), Button::new("Decode"))
|
.add_enabled(!state.is_running(), Button::new("Decode"))
|
||||||
.clicked()
|
.clicked()
|
||||||
{
|
{
|
||||||
let frame = frame.clone();
|
let ctx = ctx.clone();
|
||||||
let decoding_state = decoding_state.clone();
|
let decoding_state = decoding_state.clone();
|
||||||
let input_path = input_path.clone();
|
let input_path = input_path.clone();
|
||||||
let output_path = output_path.clone();
|
let output_path = output_path.clone();
|
||||||
|
|
||||||
state.error = None;
|
state.error = None;
|
||||||
state.run_state = DecoderRunState::RUNNING;
|
state.run_state = DecoderRunState::RUNNING;
|
||||||
if let Some(old_texture) = state.texture {
|
|
||||||
frame.free_texture(old_texture);
|
|
||||||
}
|
|
||||||
state.texture = None;
|
state.texture = None;
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
|
@ -150,17 +137,15 @@ impl epi::App for DecoderApp {
|
||||||
state.progress = progress;
|
state.progress = progress;
|
||||||
|
|
||||||
let size = [image.width() as _, image.height() as _];
|
let size = [image.width() as _, image.height() as _];
|
||||||
let epi_img = epi::Image::from_rgba_unmultiplied(
|
let color_img = ColorImage::from_rgba_unmultiplied(
|
||||||
size,
|
size,
|
||||||
image.as_flat_samples().as_slice(),
|
image.as_flat_samples().as_slice(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(old_texture) = state.texture {
|
state.texture =
|
||||||
frame.free_texture(old_texture);
|
Some(ctx.load_texture("decoded-image", color_img));
|
||||||
}
|
|
||||||
state.texture = Some(frame.alloc_texture(epi_img));
|
|
||||||
|
|
||||||
frame.request_repaint();
|
ctx.request_repaint();
|
||||||
|
|
||||||
return (state.is_running(), state.update_steps);
|
return (state.is_running(), state.update_steps);
|
||||||
});
|
});
|
||||||
|
@ -172,7 +157,7 @@ impl epi::App for DecoderApp {
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
frame.request_repaint();
|
ctx.request_repaint();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if ui
|
if ui
|
||||||
|
@ -199,7 +184,7 @@ impl epi::App for DecoderApp {
|
||||||
let image_size = ui.available_size();
|
let image_size = ui.available_size();
|
||||||
state.update_steps = image_size[1] as u32;
|
state.update_steps = image_size[1] as u32;
|
||||||
|
|
||||||
if let Some(texture) = state.texture {
|
if let Some(texture) = &state.texture {
|
||||||
ui.image(texture, image_size);
|
ui.image(texture, image_size);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue