Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Changes the pitch of an audio file; uses ffmpeg but simplifies building the command.
#!/usr/bin/env ruby
require 'awesome_print'
require 'optparse'
require 'ostruct'
require 'shellwords'
# Uses approach specified at
# https://superuser.com/questions/292833/how-to-change-audio-frequency/1076762#1076762
class PitchChanger
BASE_FREQUENCY = 44100.0
attr_reader :input, :output, :factor, :noexec
def parse
OptionParser.new do |parser|
parser.on('-i', '--input_file INPUT_FILE', "Input file") do |v|
@input = v
end
parser.on('-o', '--output_file OUTPUT_FILE', "Output file") do |v|
@output = v
end
parser.on('-f', '--conversion_factor FACTOR', "Conversion factor (decimal)") do |v|
@factor = Float(v)
end
parser.on('-n', '--noexec', "Don't execute, just output command") do |v|
@noexec = v
end
end.parse!
end
def validate_options
errors = []
unless noexec
unless File.file?(input)
errors << "Input file not specified (with -i) or does not exist."
end
unless output
errors << "Output file not specified (with -o) or does not exist."
end
end
unless factor.is_a?(Float)
errors << "Conversion factor relative to 1.0 not specified (with -f)"
end
unless errors.empty?
raise "Error(s):\n\n#{errors.join("\n")}\n\n"
end
end
def build_command_line
ffmpeg_option = "-af 'asetrate=#{BASE_FREQUENCY * factor},atempo=#{1 / factor}'"
"ffmpeg -i #{input} #{ffmpeg_option} #{output}"
end
def call
parse
validate_options
command = build_command_line
puts command
`#{command}` unless noexec
end
end
PitchChanger.new.call
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.