Skip to content

Instantly share code, notes, and snippets.

@ejschmitt
Created May 22, 2009 10:26
Show Gist options
  • Save ejschmitt/116052 to your computer and use it in GitHub Desktop.
Save ejschmitt/116052 to your computer and use it in GitHub Desktop.
require "rubygems"
require "term/ansicolor"
require "tempfile"
class Array
def split(length=self.length/2)
sets = Array.new
self.each_slice(length){|s| sets << s}
sets
end
end
class Sound
include Term::ANSIColor
attr_accessor :path, :start_sample, :end_sample, :temp
TEMP_DIR = "temp/"
`mkdir #{TEMP_DIR}`
Tempfile.class_eval do
# overwrite so tempfiles use the extension of the basename.
# important for conversion
def make_tmpname(basename, n)
ext = nil
sprintf("%s%d-%d%s", basename.to_s.gsub(/\.\w+$/) { |s| ext = s; '' }, $$, n, ext)
end
end
# start and end samples are really for when the clip
# is part of another file, but it doesnt really
# matter since you can just use
# :start_sample => 0, :end_sample => (start+length)
# temp defines if this is a temporary file or not...
# if temp then it can be closed, otherwise close does nothing
#
def initialize(file_path = false, extension = ".wav", remove_file = true)
unless file_path
s = Tempfile.new("sound" + extension, TEMP_DIR)
self.path = s.path
self.temp = s
else
self.path = file_path
self.temp = false
end
`rm -f #{s.path}` if (remove_file && !file_path) # if we want to use as a holder
end
def to_s
self.path
end
def slice(start_sample, end_sample)
# return a new Sound class that is just a snipet
s = Sound.new
len = end_sample - start_sample
`sox #{path} #{s.path} trim #{start_sample}s #{len}s`
# trim the sound file and save to the new one
s.temp = temp # save, so we can close it later
s.start_sample, s.end_sample = start_sample, end_sample
return s
end
def split(n)
# split the sound file into n sounds
end
def self.concat(sounds)
# concatinate an array of sound clips
sets = sounds[1..-1].split(32)
# copy the first one to the temp
final = Sound.new
temp = Sound.new
`mv #{sounds[0].path} #{final.path}`
for set in sets
`cp #{final.path} #{temp.path}` # make a copy for writing
`sox #{temp.path} #{set.map{|s| s.path + " "} } #{final.path}`
puts "Appending set starting with chunk #{set[0].id}, #{set.length} chunks in the set"
end
return final
end
def length
# return clip length (IN SAMPLES, not time)
(start_sample - end_sample)
end
def encode(extension, file_path = nil)
# let mmpeg pick the file type based on the extention given
# returns new Sound object
return unless path
s = Sound.new file_path, extension
`ffmpeg -i #{path} #{s.path}` # -y to overwrite the temp file
return s
end
def play
temp = self.encode(".wav")
`play #{temp}`
temp.close
end
def apply_effect(effect)
# simple way to apply effect to sound clip in, just append to command line
puts " Applying effect #{effect} to clip...".yellow
temp = Tempfile.new("transfer_file")
`cp #{path} #{temp.path}` # make a copy for writing
`sox #{temp.path} #{path} #{effect}`
temp.close(true) # get rid of the temp file
end
def close
(self.temp).close(true) if self.temp
end
end
# Usage:
# require "sound"
# a = Sound.new("song.mp3")
# a.play
# ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment