lib/baw-audio-tools/audio_wavpack.rb
module BawAudioTools
class AudioWavpack
ERROR_NOT_COMPATIBLE = 'not compatible with this version of WavPack file!'
ERROR_NOT_VALID = 'not a valid WavPack file!'
ERROR_CANNOT_OPEN = 'can\'t open file'
def initialize(wavpack_executable, temp_dir)
@wavpack_executable = wavpack_executable
@temp_dir = temp_dir
end
public
def info_command(source)
"#{@wavpack_executable} -s \"#{source}\""
end
def integrity_command(source)
"#{@wavpack_executable} -v \"#{source}\""
end
def parse_info_output(output)
# wvunpack std out contains info (separate on first colon(:))
result = {}
output.strip.split(/\r?\n|\r/).each do |line|
line.strip!
current_key = line[0, line.index(':')].strip
current_value = line[line.index(':')+1, line.length].strip
result[current_key] = current_value
end
result
end
def parse_error_output(output)
output.strip!.split(/\r?\n|\r/).last
end
def check_for_errors(execute_msg)
#stdout = execute_msg[:stdout]
stderr = execute_msg[:stderr]
if !stderr.blank? && stderr.include?(ERROR_CANNOT_OPEN)
fail Exceptions::FileCorruptError, "Wavpack could not open the file.\n\t#{execute_msg[:execute_msg]}"
end
if !stderr.blank? && stderr.include?(ERROR_NOT_VALID)
fail Exceptions::AudioToolError, "Wavpack was given a non-wavpack file.\n\t#{execute_msg[:execute_msg]}"
end
if !stderr.blank? && stderr.include?(ERROR_NOT_COMPATIBLE)
fail Exceptions::AudioToolError, "Wavpack was given a non-compatible wavpack file.\n\t#{execute_msg[:execute_msg]}"
end
end
def check_integrity_output(execute_msg)
#stdout = execute_msg[:stdout]
stderr = execute_msg[:stderr]
result = {
errors: [],
info: {
operation: '',
time: 0,
mode: '',
ratio: ''
}
}
return result if stderr.blank?
stderr.each_line do |line|
info_match = /([^\s]+?) [^ ]+? in ([^ ]+?) secs \((.*?), (.*?)\)/i.match(line)
if info_match.blank?
#result.errors.push(line)
else
result[:info][:operation] = info_match[1]
result[:info][:time] = info_match[2]
result[:info][:mode] = info_match[3]
result[:info][:ratio] = info_match[4]
end
end
# consider verification failed if info is not populated
if result[:info][:operation].blank?
result[:errors].push('Verification failed')
end
result
end
def modify_command(source, source_info, target, start_offset = nil, end_offset = nil)
fail ArgumentError, "Source is not a wavpack file: #{source}" unless source.match(/\.wv$/)
fail ArgumentError, "Target is not a wav file: : #{target}" unless target.match(/\.wav$/)
fail Exceptions::FileNotFoundError, "Source does not exist: #{source}" unless File.exists? source
fail Exceptions::FileAlreadyExistsError, "Target exists: #{target}" if File.exists? target
fail ArgumentError "Source and Target are the same file: #{target}" if source == target
cmd_offsets = arg_offsets(start_offset, end_offset)
if OS.windows?
wvunpack_command = "#{@wavpack_executable} #{cmd_offsets} \"#{source}\" \"#{target}\""
else
wvunpack_command = "#{@wavpack_executable} #{cmd_offsets} \"#{source}\" -o \"#{target}\""
end
wvunpack_command = wvunpack_command.gsub(%r{/}) { "\\" } if OS.windows?
wvunpack_command
end
def arg_offsets(start_offset, end_offset)
# formatted time: hh:mm:ss.ss
cmd_arg = '-t -q'
unless start_offset.blank?
start_offset_formatted = Time.at(start_offset.to_f).utc.strftime('%H:%M:%S.%2N')
cmd_arg += " --skip=#{start_offset_formatted}"
end
unless end_offset.blank?
end_offset_formatted = Time.at(end_offset.to_f).utc.strftime('%H:%M:%S.%2N')
cmd_arg += " --until=#{end_offset_formatted}"
end
cmd_arg
end
def parse_duration(duration_string)
# 0:01:10.02
duration_match = /(?<hour>\d+):(?<minute>\d+):(?<second>\d+)\.(?<fraction>\d+)/i.match(duration_string)
duration = 0
if !duration_match.nil? && duration_match.size == 5
duration = (duration_match[:hour].to_f * 60 * 60) + (duration_match[:minute].to_f * 60) + duration_match[:second].to_f + (duration_match[:fraction].to_f / 100)
end
duration
end
end
end