10 Commits

Author SHA1 Message Date
6f14678c1d wip 2020-11-01 16:55:06 +00:00
fb374f6a1f wip 2020-10-06 21:18:19 +01:00
183f1064ec todo 2020-09-30 12:47:26 +01:00
c7d94235e9 move readme again 2020-09-26 11:44:32 +01:00
575f0887df update readme 2020-09-26 11:26:45 +01:00
f54853fea2 move audio credits to separate readme 2020-09-26 11:24:40 +01:00
5fe1bcbf2c todo icon 2020-09-24 12:38:37 +01:00
47fd032f90 mark these sounds as done 2020-09-24 12:38:19 +01:00
937c7614a0 MIT license 2020-09-24 10:54:56 +01:00
31deb7929e apparently this prevents a terminal window from popping up when running on windows 2020-09-24 09:49:34 +01:00
7 changed files with 223 additions and 140 deletions

4
.gitignore vendored
View File

@@ -1,6 +1,8 @@
/target /target
/Cargo.lock /Cargo.lock
/.idea/ /.idea/
/sounds/ /sounds/*.flac
/sounds/*.mp3
/sounds/*.wav
/sounds.zip /sounds.zip
/lull.zip /lull.zip

View File

@@ -3,11 +3,12 @@ name = "lull"
description = "a looping sound player for generating aural atmospheres" description = "a looping sound player for generating aural atmospheres"
version = "1.0.0" version = "1.0.0"
authors = ["Max Bradbury <max@tinybird.info>"] authors = ["Max Bradbury <max@tinybird.info>"]
license = "MIT"
edition = "2018" edition = "2018"
crate_type = "bin" crate_type = "bin"
[dependencies] [dependencies]
dirs = "^3.0.1" dirs = "^3.0.1"
gio = "^0" iced = "^0.1.1"
gtk = "^0"
rodio = "^0.11.0" rodio = "^0.11.0"
env_logger = "^0.8.1"

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Max Bradbury
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,8 +1,14 @@
# lull # lull
https://ruin.itch.io/lull
a looping sound player. a looping sound player.
add your own favourite noises and blend them to create your ideal ambience. add your own favourite noises and blend them to create your ideal ambience.
created by [Max Bradbury](mailto:max@tinybird.info).
released under the MIT license.
## to do ## to do
* save volume preferences to disk * save volume preferences to disk
@@ -11,17 +17,11 @@ add your own favourite noises and blend them to create your ideal ambience.
* disown file manager subcommand * disown file manager subcommand
* get some good nature sounds * get some good nature sounds
* rain on tin roof * rain on tin roof
* campfire
* wind * wind
* waves
* tape hiss * tape hiss
* vinyl crackle
* white noise? * white noise?
* fan * fan
* birdsong
## audio credits * set a window icon
* create a nice icon?
*rain under parasol* and *waterfall* by [Samuel Strågefors](https://freesound.org/people/straget/)
*waves* by [Florian Reichelt](https://freesound.org/people/florianreichelt/)
*campfire* by [sagetyrtle](https://freesound.org/people/sagetyrtle/)

19
SOUNDS.md Normal file
View File

@@ -0,0 +1,19 @@
# lull - basic sounds pack
## installation
1. open *lull*
2. click "manage sounds" and the sounds folder will open in your file manager.
3. extract these sounds to the sounds folder
you can skip/remove any unwanted sounds, and add your own.
## credits
*waterfall* and *rain on parasol* by [Samuel Strågefors](https://freesound.org/people/straget/)
*waves* by [Florian Reichelt](https://freesound.org/people/florianreichelt/)
*campfire* by [sagetyrtle](https://freesound.org/people/sagetyrtle/)
*rain on glass* by [Benboncan](https://freesound.org/people/Benboncan/)

2
build.sh Normal file → Executable file
View File

@@ -6,4 +6,4 @@ strip lull
zip -r lull.zip README.md lull zip -r lull.zip README.md lull
rm lull rm lull
zip -r sounds.zip README.md sounds/*.mp3 zip -r sounds.zip SOUNDS.md sounds/*.mp3

View File

@@ -1,6 +1,6 @@
use gio::prelude::*; #![windows_subsystem = "windows"]
use gtk::prelude::*;
use gtk::Orientation; use iced::{Settings, Application, Element, executor, Length, Container, Column, Scrollable, Slider};
use rodio::{Sink, Source}; use rodio::{Sink, Source};
use std::env::args; use std::env::args;
use std::fs::File; use std::fs::File;
@@ -10,27 +10,51 @@ use std::process::Command;
const SPACING: i32 = 16; const SPACING: i32 = 16;
fn error_popup(message: &str) { struct Sound {
let popup = gtk::Window::new(gtk::WindowType::Toplevel); name: String,
popup.set_title("error"); path: String, // bytes instead?
popup.set_border_width(SPACING as u32); sink: Sink,
popup.set_position(gtk::WindowPosition::Center); volume: f32,
popup.set_default_size(256, 64); }
let vertical = gtk::Box::new(Orientation::Vertical, SPACING); /// todo: maybe add a play/pause state or global volume? saved presets?
popup.add(&vertical); struct State {
sounds: Vec<Sound>
}
let message = gtk::Label::new(Some(message)); enum Lull {
vertical.add(&message); Loading,
Loaded(State),
}
let button_ok = gtk::Button::with_label("OK"); impl Application for Lull {
vertical.add(&button_ok); type Executor = executor::Default;
type Message = Message;
type Flags = ();
popup.show_all(); fn new(_flags: Self::Flags) -> (Self, Command) {
(
Lull {sounds: Vec::new()},
Command::none(),
)
}
button_ok.connect_clicked(move |_| unsafe { fn title(&self) -> String {
popup.destroy(); String::from("lull")
}); }
fn update(&mut self, message: Self::Message) -> Command {
match self {
self::Loading => {},
self::Loaded => {},
}
Command::none()
}
fn view(&mut self) -> Element<'_, Self::Message> {
unimplemented!()
}
} }
fn get_data_dir() -> PathBuf { fn get_data_dir() -> PathBuf {
@@ -45,114 +69,130 @@ fn get_data_dir() -> PathBuf {
data_dir data_dir
} }
fn build_ui(application: &gtk::Application) { pub fn main() -> iced::Result {
let window = gtk::ApplicationWindow::new(application); env_logger::init();
window.set_title("lull"); Lull::run(Settings::default())
window.set_border_width(SPACING as u32);
window.set_position(gtk::WindowPosition::Center);
window.set_default_size(256, 256);
let vertical = gtk::Box::new(Orientation::Vertical, SPACING);
vertical.set_homogeneous(true);
window.add(&vertical);
let device = rodio::default_output_device().unwrap();
let paths = std::fs::read_dir(get_data_dir())
.expect("Couldn't read from lull data directory");
for path in paths {
let path = path.unwrap().path();
let name: &str = path.file_stem().unwrap().to_str().unwrap();
let file = File::open(&path)
.expect("Couldn't open audio file");
let source = rodio::Decoder::new(
BufReader::new(file)
);
if source.is_err() {
error_popup(&format!(
"Couldn't parse file {}. \n{}.",
path.to_str().unwrap(),
source.err().unwrap()
));
continue;
}
let source = source.unwrap().repeat_infinite();
let sink = Sink::new(&device);
sink.append(source);
sink.pause();
let row = gtk::Box::new(Orientation::Horizontal, SPACING);
row.set_homogeneous(true);
let label = gtk::Label::new(Some(name));
row.add(&label);
let adjustment = gtk::Adjustment::new(
0.0,
0.0,
1.0,
0.0,
0.0,
0.0
);
let slider = gtk::Scale::new(
Orientation::Horizontal,
Some(&adjustment)
);
slider.set_draw_value(false);
slider.connect_value_changed(move |scale| {
let volume = scale.get_value();
if volume == 0. {
sink.pause();
} else {
sink.play();
sink.set_volume(volume as f32);
}
});
row.add(&slider);
vertical.add(&row);
}
let row_add = gtk::Box::new(Orientation::Horizontal, SPACING);
row_add.set_homogeneous(true);
let button_manage_sounds = gtk::Button::with_label("manage sounds");
button_manage_sounds.connect_clicked(|_| {
let mut file_manager = Command::new("xdg-open");
file_manager.arg(get_data_dir());
file_manager.output().unwrap();
});
row_add.add(&button_manage_sounds);
vertical.add(&row_add);
window.show_all();
} }
fn main() { // fn error_popup(message: &str) {
let application = gtk::Application::new( // let popup = gtk::Window::new(gtk::WindowType::Toplevel);
Some("dev.tinybird.max.lull"), // popup.set_title("error");
Default::default() // popup.set_border_width(SPACING as u32);
).expect("Initialization failed..."); // popup.set_position(gtk::WindowPosition::Center);
// popup.set_default_size(256, 64);
//
// let vertical = gtk::Box::new(Orientation::Vertical, SPACING);
// popup.add(&vertical);
//
// let message = gtk::Label::new(Some(message));
// vertical.add(&message);
//
// let button_ok = gtk::Button::with_label("OK");
// vertical.add(&button_ok);
//
// popup.show_all();
//
// button_ok.connect_clicked(move |_| unsafe {
// popup.destroy();
// });
// }
application.connect_activate(|app| { // fn build_ui(application: &gtk::Application) {
build_ui(app); // let window = gtk::ApplicationWindow::new(application);
}); //
// window.set_title("lull");
application.run(&args().collect::<Vec<_>>()); // window.set_border_width(SPACING as u32);
} // window.set_position(gtk::WindowPosition::Center);
// window.set_default_size(256, 256);
//
// let vertical = gtk::Box::new(Orientation::Vertical, SPACING);
// vertical.set_homogeneous(true);
//
// window.add(&vertical);
//
// let device = rodio::default_output_device().unwrap();
//
// let paths = std::fs::read_dir(get_data_dir())
// .expect("Couldn't read from lull data directory");
//
// for path in paths {
// let path = path.unwrap().path();
// let name: &str = path.file_stem().unwrap().to_str().unwrap();
//
// let file = File::open(&path)
// .expect("Couldn't open audio file");
//
// let source = rodio::Decoder::new(
// BufReader::new(file)
// );
//
// if source.is_err() {
// error_popup(&format!(
// "Couldn't parse file {}. \n{}.",
// path.to_str().unwrap(),
// source.err().unwrap()
// ));
// continue;
// }
//
// let source = source.unwrap().repeat_infinite();
//
// let sink = Sink::new(&device);
// sink.append(source);
// sink.pause();
//
// let row = gtk::Box::new(Orientation::Horizontal, SPACING);
// row.set_homogeneous(true);
//
// let label = gtk::Label::new(Some(name));
// row.add(&label);
//
// let adjustment = gtk::Adjustment::new(
// 0.0,
// 0.0,
// 1.0,
// 0.0,
// 0.0,
// 0.0
// );
//
// let slider = gtk::Scale::new(
// Orientation::Horizontal,
// Some(&adjustment)
// );
//
// slider.set_draw_value(false);
//
// slider.connect_value_changed(move |scale| {
// let volume = scale.get_value();
//
// if volume == 0. {
// sink.pause();
// } else {
// sink.play();
// sink.set_volume(volume as f32);
// }
// });
//
// row.add(&slider);
//
// vertical.add(&row);
// }
//
// let row_add = gtk::Box::new(Orientation::Horizontal, SPACING);
// row_add.set_homogeneous(true);
//
// let button_manage_sounds = gtk::Button::with_label("manage sounds");
//
// button_manage_sounds.connect_clicked(|_| {
// let mut file_manager = Command::new("xdg-open");
// file_manager.arg(get_data_dir());
// file_manager.output().unwrap();
// });
//
// row_add.add(&button_manage_sounds);
// vertical.add(&row_add);
//
// window.show_all();
// }