Skip to content

Instantly share code, notes, and snippets.

@keithrbennett
Created January 9, 2020 10:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keithrbennett/9ba7043792bfb2fcc92d615076a8413f to your computer and use it in GitHub Desktop.
Save keithrbennett/9ba7043792bfb2fcc92d615076a8413f to your computer and use it in GitHub Desktop.
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