4.1 KiB
title | date | draft | ShowToc | cover | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Developing a Free Alternative for Splice | 2023-05-31T12:05:44+02:00 | true | true |
|
Intro
I think that almost everybody knows what Splice is. Basically, it's just a huge library of sounds and VST presets with some additional sweets. I can't say that I'm not satisfied by Splice, it's an applications that is doing pretty good, until you want to use it on Linux. That's something that I don't understand, (I'm almost sure that )it's an Electron application with and some binary running a gRPC server in a background, that I believe is written in GO. Both technologies are working on Linux, so basically, they could have just built a version without promising any real support for that. But they haven't. I've decided to try running it with WINE, but it didn't work. And then I though: There is awesome freesound, and why wouldn't I use it?
Freesound is a collaborative database of Creative Commons Licensed sounds. Browse, download and share sounds.
But downloading samples using a browser it not something I'd like to do. I love Splice for their drag-n-drop app. And I've decided to develop one that will work with Freesound.
Starting the project
I've decided to use Rust and try the Iced for the UI. Here you will find the project git repository: https://git.badhouseplants.net/allanger/frice
Basically, there are two things to do so the MVP is ready
- Make correct API requests to the Freesound
- Create a UI
So the very first thing that I'm doing, I'm initializing a project and creating a very simple Iced app using examples
cargo init
cargo add iced
# Cargo.toml
[package]
name = "frice"
version = "0.1.0"
edition = "2021"
[dependencies]
iced = "0.9.0"
// ./src/main.rs
use iced::{Sandbox, Settings, widget::Container};
fn main() -> Result<(), iced::Error> {
Frice::run(Settings::default())
}
struct Frice {}
impl Sandbox for Frice {
type Message = String;
fn new() -> Self {
Frice {}
}
fn title(&self) -> String {
"Frice".to_string()
}
fn update(&mut self, message: Self::Message) {
println!("Updating")
}
fn view(&self) -> iced::Element<'_, Self::Message> {
Container::new("frice").center_x().center_y().width(iced::Length::Fill).height(iced::Length::Fill).into() }
}
API
And now I want to switch to the API, because the UI without API requests won't be able to do anything. As I see now, I'll need to implement two API calls for the MVP:
- Search sounds
- Download a sound
So let's start with the first one. They have a basic example of searching on their documentation page
curl "https://freesound.org/apiv2/search/text/?query=dogs&token=YOUR_API_KEY"
API key can be created here: https://freesound.org/apiv2/apply
So let's create a FreesoundAPI struct and add two methods there
struct FreesoundAPI {}
impl FreesoundAPI {
fn new() -> Self {
Self {}
}
fn search() {
todo!()
}
fn download() {
todo!()
}
}
To create an API call I'll need a token, so I need to add a new field to the FreesoundAPI struct
struct FreesoundAPI {
token: String
}
impl FreesoundAPI {
fn new(token: String) -> Self {
Self { token }
}
...
}
I also need a library for making API calls cargo add reqwest
pub(crate) fn search(&self) {
let client = reqwest::blocking::Client::builder().build().unwrap();
let res = client.get("https://freesound.org/apiv2/search/text")
.query(&[("token", self.token.as_str()), ("query", "dogs")])
.send().unwrap();
println!("{:?}", res.text());
}
Let's leave it like this for a moment, and try to implement the download
method. Freesound API sais that we need to use Oauth
to download sounds. Let's try.
cargo add oauth2