* generate jmep automatically

This commit is contained in:
Seth Call 2015-11-18 15:22:06 -06:00
parent d4cdab8d6b
commit d3d2fbb210
4 changed files with 186 additions and 68 deletions

View File

@ -2,28 +2,5 @@ class JamRuby::JamTrack
# add a custom validation
attr_accessor :preview_generate_error
before_save :jmep_json_generate
validate :jmep_text_validate
def jmep_text_validate
begin
JmepManager.execute(self.jmep_text)
rescue ArgumentError => err
errors.add(:jmep_text, err.to_s)
end
end
def jmep_json_generate
self.licensor_id = nil if self.licensor_id == ''
self.jmep_json = nil if self.jmep_json == ''
self.time_signature = nil if self.time_signature == ''
begin
self[:jmep_json] = JmepManager.execute(self.jmep_text)
rescue ArgumentError => err
#errors.add(:jmep_text, err.to_s)
end
end
end

View File

@ -33,6 +33,123 @@ module JamRuby
self.detail = detail
end
def generate_jmep(jam_track)
if jam_track.jmep_text
finish('success', 'jmep already exists')
return
else
# we need to download the click track, if it exists.
Dir.mktmpdir do |tmp_dir|
master_track = jam_track.master_track
click_track = jam_track.click_track
if master_track.nil?
finish('no_master_track', nil)
return
end
master_track_file = File.join(tmp_dir, File.basename(master_track[:url_48]))
begin
JamTrackImporter.private_s3_manager.download(master_track.url_by_sample_rate(44), master_track_file)
rescue Exception => e
@@log.error("unable to download master track")
finish("no-download-master", master_track.url_by_sample_rate(44))
return
end
if click_track
click_track_file = File.join(tmp_dir, File.basename(click_track[:url]))
JamTrackImporter.song_storage_manager.download(click_track[:url], click_track_file)
else
# we'll use the master for click analysis. not ideal, but would work
click_track_file = master_track_file
end
start_time = determine_start_time(master_track_file, tmp_dir, master_track[:url])
# bpm comes from git clone http://www.pogo.org.uk/~mark/bpm-tools.git
sox="sox #{Shellwords.escape(click_track_file)} -t raw -r 44100 -e float -c 1 - | bpm"
cmd = "bash -c #{Shellwords.escape(sox)}"
@@log.debug("executing cmd #{cmd}")
output=`#{cmd}`
result_code = $?.to_i
if result_code == 0
bpm = output.to_f
@@log.debug("bpm: #{bpm} start_time: #{start_time}")
metro_fin = "#{Time.at(start_time).utc.strftime("%H:%M:%S")}:#{((start_time - start_time.to_i) * 1000).round}"
jmep = ""
jmep << "# created via code using bpm/silence detection (bpm:#{bpm})\r\n"
jmep << "prelude@10.0 #number of seconds before music starts\r\n"
jmep << "metro_fin@#{metro_fin} bpm=#{bpm.round}, ticks=4, pmode=stream, name=Beep, play=mono"
@@log.info("jmep generated: #{jmep}")
jam_track.jmep_text = jmep
if jam_track.save
else
@@log.error("jamtrack did not save. #{jam_track.errors.inspect}")
finish("no-save", "jamtrack did not save. #{jam_track.errors.inspect}")
return
end
else
finish("bpm-fail", "failed to run bpm: #{output}")
return
end
end
end
end
def determine_start_time(audio_file, tmp_dir, original_filename)
burp_gaps = ['0.3', '0.2', '0.1', '0.05']
out_wav = File.join(tmp_dir, 'stripped.wav')
total_time_command = "soxi -D \"#{audio_file}\""
total_time = `#{total_time_command}`.to_f
result_code = -20
stripped_time = total_time # default to the case where we just start the preview at the beginning
burp_gaps.each do |gap|
command_strip_lead_silence = "sox \"#{audio_file}\" \"#{out_wav}\" silence 1 #{gap} 1%"
@@log.debug("stripping silence: " + command_strip_lead_silence)
output = `#{command_strip_lead_silence}`
result_code = $?.to_i
if result_code == 0
stripped_time_command = "soxi -D \"#{out_wav}\""
stripped_time_test = `#{stripped_time_command}`.to_f
if stripped_time_test < 1 # meaning a very short duration
@@log.warn("could not determine the start of non-silence. assuming beginning")
stripped_time = total_time # default to the case where we just start the preview at the beginning
else
stripped_time = stripped_time_test # accept the measured time of the stripped file and move on by using break
break
end
else
@@log.warn("unable to determine silence for jam_track #{original_filename}, #{output}")
stripped_time = total_time # default to the case where we just start the preview at the beginning
end
end
preview_start_time = total_time - stripped_time
preview_start_time
end
def synchronize_preview_dev(jam_track)
jam_track.jam_track_tracks.each do |track|
@ -1341,58 +1458,15 @@ module JamRuby
def synchronize_track_preview(track, tmp_dir, ogg_44100)
out_wav = File.join(tmp_dir, 'stripped.wav')
burp_gaps = ['0.3', '0.2', '0.1', '0.05']
total_time_command = "soxi -D \"#{ogg_44100}\""
total_time = `#{total_time_command}`.to_f
result_code = -20
stripped_time = total_time # default to the case where we just start the preview at the beginning
burp_gaps.each do |gap|
command_strip_lead_silence = "sox \"#{ogg_44100}\" \"#{out_wav}\" silence 1 #{gap} 1%"
@@log.debug("stripping silence: " + command_strip_lead_silence)
output = `#{command_strip_lead_silence}`
result_code = $?.to_i
if result_code == 0
stripped_time_command = "soxi -D \"#{out_wav}\""
stripped_time_test = `#{stripped_time_command}`.to_f
if stripped_time_test < 1 # meaning a very short duration
@@log.warn("could not determine the start of non-silencea. assuming beginning")
stripped_time = total_time # default to the case where we just start the preview at the beginning
else
stripped_time = stripped_time_test # accept the measured time of the stripped file and move on by using break
break
end
else
@@log.warn("unable to determine silence for jam_track #{track.original_filename}, #{output}")
stripped_time = total_time # default to the case where we just start the preview at the beginning
end
end
preview_start_time = total_time - stripped_time
preview_start_time = determine_start_time(ogg_44100, tmp_dir, track.original_filename)
# this is in seconds; convert to integer milliseconds
preview_start_time = (preview_start_time * 1000).to_i
preview_start_time = nil if preview_start_time < 0
preview_start_time = 0 if preview_start_time < 0
track.preview_start_time = preview_start_time
if track.preview_start_time
@@log.debug("determined track start time to be #{track.preview_start_time}")
else
@@log.debug("determined track start time to be #{track.preview_start_time}")
end
track.process_preview(ogg_44100, tmp_dir) if track.preview_start_time
if track.preview_generate_error
@ -1915,6 +1989,39 @@ module JamRuby
end
end
def generate_jmep(jam_track)
importer = JamTrackImporter.new
importer.name = jam_track.name
importer.generate_jmep(jam_track)
importer
end
def generate_jmeps
importers = []
JamTrack.all.each do |jam_track|
importers << generate_jmep(jam_track)
end
@@log.info("SUMMARY")
@@log.info("-------")
importers.each do |importer|
if importer
if importer.reason == "success"
@@log.info("#{importer.name} #{importer.reason}")
else
@@log.error("#{importer.name} failed to generate jmep.")
@@log.error("#{importer.name} reason=#{importer.reason}")
@@log.error("#{importer.name} detail=#{importer.detail}")
end
else
@@log.error("NULL IMPORTER")
end
end
end
def synchronize_previews
importers = []
@ -2395,3 +2502,4 @@ module JamRuby
end
end
end

View File

@ -433,6 +433,10 @@ module JamRuby
end
def click_track
JamTrackFile.where(jam_track_id: self.id).where(file_type: 'ClickWav').first
end
def master_track
JamTrackTrack.where(jam_track_id: self.id).where(track_type: 'Master').first
end
@ -471,5 +475,29 @@ module JamRuby
"#{self.name} (#{self.original_artist})"
end
attr_accessor :preview_generate_error
before_save :jmep_json_generate
validate :jmep_text_validate
def jmep_text_validate
begin
JmepManager.execute(self.jmep_text)
rescue ArgumentError => err
errors.add(:jmep_text, err.to_s)
end
end
def jmep_json_generate
self.licensor_id = nil if self.licensor_id == ''
self.jmep_json = nil if self.jmep_json == ''
self.time_signature = nil if self.time_signature == ''
begin
self[:jmep_json] = JmepManager.execute(self.jmep_text)
rescue ArgumentError => err
#errors.add(:jmep_text, err.to_s)
end
end
end
end

View File

@ -1,5 +1,10 @@
namespace :jam_tracks do
task generate_jmep: :environment do |task, args|
JamTrackImporter.storage_format = 'Tency'
JamTrackImporter.generate_jmeps
end
task dry_run: :environment do |task, args|
JamTrackImporter.dry_run
end