use std::process::Command;
use crate::converters::scad::which_tool;
use crate::{Error, Job, Result, extension_of};
pub fn midi_to_wav(job: &Job) -> Result<()> {
if which_tool("fluidsynth") {
let soundfont =
std::env::var("UNIVERT_SOUNDFONT").unwrap_or_else(|_| default_sf2());
let status = Command::new("fluidsynth")
.args(["-ni", "-g", "0.8", "-F"])
.arg(job.output)
.arg(&soundfont)
.arg(job.input)
.status()
.map_err(|e| Error::ToolFailed {
tool: "fluidsynth",
message: e.to_string(),
})?;
if !status.success() {
return Err(Error::ToolFailed {
tool: "fluidsynth",
message: format!("fluidsynth exited with status {status}"),
});
}
return Ok(());
}
Err(Error::MissingTool {
from: extension_of(job.input).unwrap_or_default(),
to: extension_of(job.output).unwrap_or_default(),
tool: "fluidsynth",
})
}
pub fn wav_to_aac(job: &Job) -> Result<()> {
if which_tool("ffmpeg") {
let status = Command::new("ffmpeg")
.args(["-y", "-hide_banner", "-loglevel", "error", "-i"])
.arg(job.input)
.args(["-c:a", "aac", "-f", "adts"])
.arg(job.output)
.status()
.map_err(|e| Error::ToolFailed {
tool: "ffmpeg",
message: e.to_string(),
})?;
if !status.success() {
return Err(Error::ToolFailed {
tool: "ffmpeg",
message: format!("ffmpeg exited with status {status}"),
});
}
return Ok(());
}
Err(Error::MissingTool {
from: extension_of(job.input).unwrap_or_default(),
to: extension_of(job.output).unwrap_or_default(),
tool: "ffmpeg",
})
}
pub fn wav_to_mp3(job: &Job) -> Result<()> {
if which_tool("ffmpeg") {
let status = Command::new("ffmpeg")
.args(["-y", "-hide_banner", "-loglevel", "error", "-i"])
.arg(job.input)
.args(["-c:a", "libmp3lame"])
.arg(job.output)
.status()
.map_err(|e| Error::ToolFailed {
tool: "ffmpeg",
message: e.to_string(),
})?;
if !status.success() {
return Err(Error::ToolFailed {
tool: "ffmpeg",
message: format!("ffmpeg exited with status {status}"),
});
}
return Ok(());
}
Err(Error::MissingTool {
from: extension_of(job.input).unwrap_or_default(),
to: extension_of(job.output).unwrap_or_default(),
tool: "ffmpeg",
})
}
pub fn mp3_to_png(job: &Job) -> Result<()> {
let from = extension_of(job.input).unwrap_or_default();
let to = extension_of(job.output).unwrap_or_default();
Err(Error::NotImplemented { from, to })
}
fn default_sf2() -> String {
for p in [
"/usr/share/sounds/sf2/FluidR3_GM.sf2",
"/usr/share/soundfonts/default.sf2",
"/opt/homebrew/share/fluid-soundfont/FluidR3_GM.sf2",
"/usr/local/share/fluid-soundfont/FluidR3_GM.sf2",
] {
if std::path::Path::new(p).is_file() {
return p.to_string();
}
}
"default.sf2".to_string()
}