Created
October 1, 2017 18:10
-
-
Save Ruin0x11/7b6737149357228a33d92dbb31f2cf20 to your computer and use it in GitHub Desktop.
Organize sound samples quickly
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Requires mpv. | |
require "optparse" | |
require "find" | |
require "pathname" | |
require "ostruct" | |
require "fileutils" | |
require "io/console" | |
def is_num?(str) | |
!!Integer(str) | |
rescue ArgumentError, TypeError | |
false | |
end | |
def clamp(x, min, max) | |
[min, x, max].sort[1] | |
end | |
def play_sound(filename, speed) | |
Process.fork do | |
system "mpv #{filename} --no-audio-pitch-correction --speed #{speed}", out: "/dev/null", err: "/dev/null" | |
end | |
end | |
# Organizer for sound samples | |
class Organize | |
def initialize(dir) | |
@org_dir = "./#{dir}_organized" | |
@history = [] | |
@wav_files = [] | |
@speed = 1.0 | |
@page = 0 | |
Dir.mkdir @org_dir unless File.exist?(@org_dir) | |
refresh_categories | |
get_wavs dir | |
end | |
def get_wavs(dir) | |
Find.find(dir) do |path| | |
@wav_files << path if path =~ /.*\.wav$/ | |
end | |
end | |
def refresh_categories | |
@categories = Pathname.new(@org_dir).children.select(&:directory?) | |
end | |
def category_page | |
return [] if @categories.empty? | |
@categories.each_slice(10).to_a[@page] | |
end | |
def next_page | |
(@page + 1) % (@categories.count / 10.0).ceil | |
end | |
def prev_page | |
(@page - 1) % (@categories.count / 10.0).ceil | |
end | |
def create_category | |
puts | |
print "Name? " | |
name = STDIN.gets.chomp | |
return if name.empty? | |
return if @categories.map(&:basename).include? Pathname.new(name) | |
path = File.join(@org_dir, name) | |
Dir.mkdir path | |
@categories << Pathname.new(path) | |
end | |
def print_categories | |
category_page.each_with_index do |cat, i| | |
puts "#{i}) #{cat.basename}" | |
end | |
end | |
def print_history | |
@history.each do |h| | |
puts "#{h.file} => #{@categories[h.category]}" | |
end | |
end | |
def try_categorize(file, command) | |
i = Integer(command) | |
if i < 0 || i >= [10, @categories.count].min | |
puts "Unknown category" | |
return false | |
else | |
cat = category_page[i] | |
puts "Label \"#{file}\" as \"#{cat.basename}\"." | |
new_dir = File.join(cat.cleanpath, File.basename(file)) | |
@history << OpenStruct.new(category: i + (10 * @page), file: file) | |
begin | |
FileUtils.mv(file, new_dir) | |
rescue ArgumentError | |
puts "(Same file, nothing moved.)" | |
end | |
end | |
true | |
end | |
def undo | |
if @history.empty? | |
puts "No history." | |
return | |
end | |
hist = @history.pop | |
wav_name = File.basename(hist.file) | |
moved_file = File.join(@categories[hist.category].cleanpath, wav_name) | |
puts "undo: => #{moved_file}" | |
@wav_files.unshift moved_file | |
end | |
def go | |
until @wav_files.empty? | |
file = @wav_files.shift | |
size = File.size(file) / 1000.0 | |
puts "File: #{file} size: #{size.round(1)}kb" | |
play_sound(file, @speed) | |
query file | |
end | |
end | |
def change_speed(amount) | |
@speed = clamp(@speed + amount, 0, 10) | |
puts "Playback speed: #{@speed}" | |
end | |
def query(file) | |
done = false | |
until done | |
print_categories | |
print "Command? [p]lay [c]ategory [u]ndo [s]low [f]ast [q]uit ]/[ pages " | |
command = STDIN.getch | |
if command == "p" | |
play_sound(file, @speed) | |
elsif command == "s" | |
change_speed(-0.1) | |
play_sound(file, @speed) | |
elsif command == "f" | |
change_speed(0.1) | |
play_sound(file, @speed) | |
elsif command == "c" | |
create_category | |
elsif command == "u" | |
@wav_files.unshift file | |
undo | |
done = true | |
elsif command == "[" | |
@page = prev_page | |
elsif command == "]" | |
@page = next_page | |
elsif is_num? command | |
done = try_categorize(file, command) | |
elsif command == "q" | |
exit 0 | |
else | |
puts "unknown command" | |
end | |
puts | |
end | |
end | |
@speed = 1.0 | |
end | |
if ARGV.count != 1 | |
puts "Usage: organize.rb [directory]" | |
exit 1 | |
end | |
dir = ARGV[0].chomp("/") | |
org = Organize.new(dir) | |
org.go |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment