Skip to content

Instantly share code, notes, and snippets.

@Ruin0x11
Created October 1, 2017 18:10
Show Gist options
  • Save Ruin0x11/7b6737149357228a33d92dbb31f2cf20 to your computer and use it in GitHub Desktop.
Save Ruin0x11/7b6737149357228a33d92dbb31f2cf20 to your computer and use it in GitHub Desktop.
Organize sound samples quickly
# 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