diff --git a/ruby/lib/jam_ruby/jam_track_importer.rb b/ruby/lib/jam_ruby/jam_track_importer.rb index 5d51ec6fe..0ab427d09 100644 --- a/ruby/lib/jam_ruby/jam_track_importer.rb +++ b/ruby/lib/jam_ruby/jam_track_importer.rb @@ -76,7 +76,8 @@ module JamRuby tracks = [] - # tmp_dir = Dir.mktmpdir + #tmp_dir = Dir.mktmpdir + #tmp_dir = "/var/folders/05/1jpzfcln1hq9p666whnd7chr0000gn/T/d20150809-4962-15lgwru" Dir.mktmpdir do |tmp_dir| @@log.debug("downloading all audio files in #{tmp_dir}") audio_files.each do |s3_track| @@ -85,8 +86,38 @@ module JamRuby JamTrackImporter.song_storage_manager.download(s3_track, track) end + # first have to check if all are the same sample rate. If not, we have to make it so + + first_sample_rate = nil + normalize_needed = false + tracks.each do |track| + sample_rate = `soxi -r "#{track}"`.strip + + if first_sample_rate.nil? + first_sample_rate = sample_rate + else + if first_sample_rate != sample_rate + # we need to normalize all of them + normalized_needed = true + break + end + end + end + + normalized_tracks = [] + if normalize_needed + tracks.each do |track| + normalized_track = File.join(tmp_dir, File.basename('normalized-' + track)) + output = `sox "#{track}" "#{normalized_track}" rate #{first_sample_rate}` + @@log.debug("resampling #{normalized_track}; output: #{output}") + end + tracks = normalized_tracks + end + + + temp_file = File.join(tmp_dir, "temp.wav") - output_filename = "#{self.name} Master Mix.wav" + output_filename = JamTrackImporter.remove_s3_special_chars("#{self.name} Master Mix.wav") output_file = File.join(tmp_dir, output_filename) command = "sox -m " tracks.each do |track| @@ -123,9 +154,7 @@ module JamRuby end end - end - end def dry_run(metadata, metalocation) @@ -465,7 +494,7 @@ module JamRuby instrument = 'bass guitar' part = 'Fretless' elsif potential_instrument == 'lap steel' || potential_instrument == 'pedal steel' - instrument = 'Steel Guitar' + instrument = 'steel guitar' elsif potential_instrument == 'clock percussion' instrument = 'computer' part = 'Clock' @@ -603,6 +632,13 @@ module JamRuby instrument = mapping[:instrument] part = mapping[:part] end + + # tency mapping didn't work; let's retry with our own home-grown mapping + if instrument.nil? + result = determine_instrument(possible_instrument, possible_part) + instrument = result[:instrument] + part = result[:part] + end end end @@ -1013,44 +1049,61 @@ module JamRuby def synchronize_track_preview(track, tmp_dir, ogg_44100) out_wav = File.join(tmp_dir, 'stripped.wav') - command_strip_lead_silence = "sox \"#{ogg_44100}\" \"#{out_wav}\" silence 1 0.3 1%" - @@log.debug("stripping silence: " + command_strip_lead_silence) + burp_gaps = ['0.3', '0.2', '0.1', '0.05'] - output = `#{command_strip_lead_silence}` + total_time_command = "soxi -D \"#{ogg_44100}\"" + total_time = `#{total_time_command}`.to_f - result_code = $?.to_i + result_code = -20 + stripped_time = total_time # default to the case where we just start the preview at the beginning - if result_code == 0 + burp_gaps.each do |gap| + command_strip_lead_silence = "sox \"#{ogg_44100}\" \"#{out_wav}\" silence 1 #{gap} 1%" - total_time_command = "soxi -D \"#{ogg_44100}\"" - stripped_time_command = "soxi -D \"#{out_wav}\"" + @@log.debug("stripping silence: " + command_strip_lead_silence) - total_time = `#{total_time_command}` - stripped_time = `#{stripped_time_command}` + output = `#{command_strip_lead_silence}` - preview_start_time = total_time.to_f - stripped_time.to_f + result_code = $?.to_i - # this is in seconds; convert to integer milliseconds - preview_start_time = (preview_start_time * 1000).to_i + if result_code == 0 + stripped_time_command = "soxi -D \"#{out_wav}\"" + stripped_time_test = `#{stripped_time_command}`.to_f - preview_start_time = nil 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}") + 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.debug("determined track start time to be #{track.preview_start_time}") + @@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 - track.process_preview(ogg_44100, tmp_dir) if track.preview_start_time + end - if track.preview_generate_error - @@log.warn(track.preview_generate_error) - end + preview_start_time = total_time - stripped_time + + # 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 + + 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.warn("unable to determine silence for jam_track #{track.original_filename}, #{output}") + @@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 + @@log.warn(track.preview_generate_error) end end @@ -1148,6 +1201,9 @@ module JamRuby finish("success", nil) end + # do a last check on any problems with the jamtrack + jam_track.sync_onboarding_exceptions + end def synchronize_recurly(jam_track) @@ -1353,6 +1409,16 @@ module JamRuby end end + def create_master(path) + metalocation = "#{path}/meta.yml" + + metadata = load_metalocation(metalocation) + + jam_track_importer = JamTrackImporter.new(@storage_format) + + jam_track_importer.create_master(metadata, metalocation) + end + def dry_run_original s3_manager.list_directories('audio').each do |original_artist| @@log.debug("searching through artist directory '#{original_artist}'") @@ -1560,6 +1626,9 @@ module JamRuby end end + def remove_s3_special_chars(filename) + filename.tr('/&@:,$=+?;\^`><{}[]#%~|', '') + end def onboarding_exceptions JamTrack.all.each do |jam_track| jam_track.onboarding_exceptions @@ -1573,10 +1642,13 @@ module JamRuby next if metadata.nil? && is_tency_storage? - count+=1 importer = synchronize_from_meta(metalocation, options) importers << importer + if importer.reason != 'jam_track_exists' + count+=1 + end + if count > 100 break end diff --git a/ruby/lib/jam_ruby/models/jam_track.rb b/ruby/lib/jam_ruby/models/jam_track.rb index db2a581fe..3338124be 100644 --- a/ruby/lib/jam_ruby/models/jam_track.rb +++ b/ruby/lib/jam_ruby/models/jam_track.rb @@ -75,7 +75,7 @@ module JamRuby # 1) the reproduction_royalty_amount has to stay in sync based on duration # 2) the onboarding_exceptions JSON column after_save :sync_reproduction_royalty - after_save :onboarding_exceptions + after_save :sync_onboarding_exceptions def sync_reproduction_royalty @@ -95,14 +95,14 @@ module JamRuby minutes = (self.duration - 1) / 60 extra_minutes = minutes - 4 extra_minutes = 0 if extra_minutes < 0 - royalty = 0.091 + (0.0175 * extra_minutes) + royalty = (0.091 + (0.0175 * extra_minutes)).round(5) end self.update_column(:reproduction_royalty_amount, royalty) true end - def onboarding_exceptions + def sync_onboarding_exceptions exceptions = {} if self.duration.nil? diff --git a/ruby/spec/jam_ruby/models/jam_track_spec.rb b/ruby/spec/jam_ruby/models/jam_track_spec.rb index 9cc16c444..c1aecf71d 100644 --- a/ruby/spec/jam_ruby/models/jam_track_spec.rb +++ b/ruby/spec/jam_ruby/models/jam_track_spec.rb @@ -274,7 +274,7 @@ describe JamTrack do end it "100.1234" do - jam_track = FactoryGirl.build(:jam_track, reproduction_royalty_amount: 100.1234) + jam_track = FactoryGirl.build(:jam_track, reproduction_royalty_amount: 100.12345) jam_track.valid?.should be_false jam_track.errors[:reproduction_royalty_amount].should == ['is invalid'] end diff --git a/ruby/spec/jam_ruby/models/jam_track_track_spec.rb b/ruby/spec/jam_ruby/models/jam_track_track_spec.rb index 6fb4343f6..67a50ec22 100644 --- a/ruby/spec/jam_ruby/models/jam_track_track_spec.rb +++ b/ruby/spec/jam_ruby/models/jam_track_track_spec.rb @@ -7,6 +7,7 @@ describe JamTrackTrack do it "created" do jam_track_track = FactoryGirl.create(:jam_track_track) jam_track_track.jam_track.should_not be_nil + jam_track_track.jam_track.reload jam_track_track.jam_track.jam_track_tracks.should == [jam_track_track] end diff --git a/web/lib/tasks/jam_tracks.rake b/web/lib/tasks/jam_tracks.rake index 315d02b25..1774cfc64 100644 --- a/web/lib/tasks/jam_tracks.rake +++ b/web/lib/tasks/jam_tracks.rake @@ -14,6 +14,21 @@ namespace :jam_tracks do JamTrackImporter.create_masters end + + task tency_create_master: :environment do |task, args| + JamTrackImporter.storage_format = 'Tency' + + path = ENV['TRACK_PATH'] + + if !path + puts "TRACK_PATH must be set to something like audio/AC DC/Back in Black or mapped/50 Cent - In Da Club - 12401" + exit(1) + end + + JamTrackImporter.create_master(path) + end + + task tency_delta: :environment do |task, args| JamTrackImporter.storage_format = 'Tency' JamTrackImporter.tency_delta