* VRFS-3725 - frontend support for click tracks and tap-in creation
This commit is contained in:
parent
ebdde28f85
commit
54a437d6e1
|
|
@ -19,7 +19,7 @@ module JamRuby
|
|||
:reproduction_royalty, :public_performance_royalty, :reproduction_royalty_amount,
|
||||
:licensor_royalty_amount, :pro_royalty_amount, :plan_code, :initial_play_silence, :jam_track_tracks_attributes,
|
||||
:jam_track_tap_ins_attributes, :genre_ids, :version, :jmep_json, :jmep_text, :pro_ascap, :pro_bmi, :pro_sesac, :duration,
|
||||
:server_fixation_date, :hfa_license_status, :hfa_license_desired, :alternative_license_status, :hfa_license_number, :hfa_song_code, :album_title, as: :admin
|
||||
:server_fixation_date, :hfa_license_status, :hfa_license_desired, :alternative_license_status, :hfa_license_number, :hfa_song_code, :album_title, :year, as: :admin
|
||||
|
||||
validates :name, presence: true, length: {maximum: 200}
|
||||
validates :plan_code, presence: true, uniqueness: true, length: {maximum: 50 }
|
||||
|
|
@ -451,7 +451,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
def stem_tracks
|
||||
JamTrackTrack.where(jam_track_id: self.id).where(track_type: 'Track')
|
||||
JamTrackTrack.where(jam_track_id: self.id).where("track_type = 'Track' or track_type = 'Click'")
|
||||
end
|
||||
|
||||
def can_download?(user)
|
||||
|
|
|
|||
|
|
@ -83,6 +83,11 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
if parsed["count-in"]
|
||||
all_quiet = false
|
||||
tweaked = true
|
||||
end
|
||||
|
||||
if all_quiet
|
||||
errors.add(:settings, 'are all muted')
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,9 +10,11 @@ module JamRuby
|
|||
|
||||
include JamRuby::S3ManagerMixin
|
||||
|
||||
TAP_IN_PADDING = 2
|
||||
|
||||
MAX_PAN = 90
|
||||
MIN_PAN = -90
|
||||
KNOCK_SECONDS = 0.035
|
||||
|
||||
attr_accessor :mixdown_package_id, :settings, :mixdown_package, :mixdown, :step
|
||||
@queue = :jam_track_mixdown_packager
|
||||
|
|
@ -55,6 +57,8 @@ module JamRuby
|
|||
@mixdown = @mixdown_package.jam_track_mixdown
|
||||
@settings = JSON.parse(@mixdown.settings)
|
||||
|
||||
process_jmep
|
||||
|
||||
track_settings
|
||||
|
||||
# compute the step count
|
||||
|
|
@ -102,31 +106,234 @@ module JamRuby
|
|||
vol != 1.0 || pan != 0
|
||||
end
|
||||
|
||||
def create_tapin_track
|
||||
def process_jmep
|
||||
@start_points = []
|
||||
@initial_padding = 0.0
|
||||
|
||||
speed = @settings['speed'] || 0
|
||||
|
||||
@speed_factor = 1.0 + (-speed.to_f / 100.0)
|
||||
@inverse_speed_factor = 1 - (-speed.to_f / 100)
|
||||
|
||||
log.info("speed factor #{@speed_factor}")
|
||||
|
||||
jmep = @mixdown.jam_track.jmep_json
|
||||
if jmep
|
||||
jmep = JSON.parse(jmep)
|
||||
end
|
||||
|
||||
if jmep.nil?
|
||||
return nil
|
||||
log.debug("no jmep")
|
||||
return
|
||||
end
|
||||
|
||||
events = jmep["Events"]
|
||||
|
||||
return nil if events.nil? || events.length == 0
|
||||
return if events.nil? || events.length == 0
|
||||
|
||||
metronome = nil
|
||||
events.each do |event|
|
||||
if event.has_key?("Metronome")
|
||||
metronome = event
|
||||
if event.has_key?("metronome")
|
||||
metronome = event["metronome"]
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return nil if metronome.nil? || metronome.length == 0
|
||||
if metronome.nil? || metronome.length == 0
|
||||
log.debug("no metronome events for jmep", jmep)
|
||||
return
|
||||
end
|
||||
|
||||
cmd("sox -n -r 44100 -c 2 silence.wav trim 0.0 0.05", "bpm_silence")
|
||||
@start_points = metronome.select { |x| puts x.inspect; x["action"] == "start" }
|
||||
|
||||
log.debug("found #{@start_points.length} metronome start points")
|
||||
|
||||
start_point = @start_points[0]
|
||||
|
||||
if start_point
|
||||
start_time = parse_time(start_point["ts"])
|
||||
|
||||
if start_time < 2.0
|
||||
padding = start_time - 2.0
|
||||
@initial_padding = padding.abs
|
||||
@initial_tap_in = start_time
|
||||
end
|
||||
end
|
||||
|
||||
if @speed_factor != 1.0
|
||||
metronome.length.times do |count|
|
||||
|
||||
# we expect to find metronome start/stop grouped
|
||||
if count % 2 == 0
|
||||
|
||||
start = metronome[count]
|
||||
stop = metronome[count + 1]
|
||||
|
||||
if start["action"] != "start" || stop["action"] != "stop"
|
||||
# bail out
|
||||
log.error("found de-coupled metronome events #{start.to_json} | #{stop.to_json}")
|
||||
next
|
||||
end
|
||||
|
||||
bpm = start["bpm"].to_f
|
||||
stop_time = parse_time(stop['ts'])
|
||||
ticks = stop['ticks'].to_i
|
||||
|
||||
|
||||
new_bpm = bpm * @inverse_speed_factor
|
||||
new_stop_time = stop_time * @speed_factor
|
||||
new_start_time = new_stop_time - (60.0/new_bpm * ticks)
|
||||
|
||||
log.info("original bpm:#{bpm} start: #{parse_time(start["ts"])} stop: #{stop_time}")
|
||||
log.info("updated bpm:#{new_bpm} start: #{new_start_time} stop: #{new_stop_time}")
|
||||
|
||||
stop["ts"] = new_stop_time
|
||||
start["ts"] = new_start_time
|
||||
start["bpm"] = new_bpm
|
||||
stop["bpm"] = new_bpm
|
||||
|
||||
@tap_in_initial_silence = (@initial_tap_in + @initial_padding) * @speed_factor
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@start_points = metronome.select { |x| puts x.inspect; x["action"] == "start" }
|
||||
|
||||
end
|
||||
|
||||
# format like: "-0:00:02:820"
|
||||
def parse_time(ts)
|
||||
|
||||
if ts.is_a?(Float)
|
||||
return ts
|
||||
end
|
||||
|
||||
time = 0.0
|
||||
negative = false
|
||||
|
||||
if ts.start_with?('-')
|
||||
negative = true
|
||||
end
|
||||
|
||||
# parse time_format
|
||||
bits = ts.split(':').reverse
|
||||
|
||||
bit_position = 0
|
||||
bits.each do |bit|
|
||||
if bit_position == 0
|
||||
# milliseconds
|
||||
milliseconds = bit.to_f
|
||||
time += milliseconds/1000
|
||||
elsif bit_position == 1
|
||||
# seconds
|
||||
time += bit.to_f
|
||||
elsif bit_position == 2
|
||||
# minutes
|
||||
time += 60 * bit.to_f
|
||||
elsif bit_position == 3
|
||||
# hours
|
||||
# not bothering
|
||||
end
|
||||
|
||||
bit_position += 1
|
||||
end
|
||||
|
||||
if negative
|
||||
time = 0.0 - time
|
||||
end
|
||||
|
||||
time
|
||||
end
|
||||
|
||||
def path_to_resources
|
||||
File.join(File.dirname(File.expand_path(__FILE__)), '../../../lib/jam_ruby/app/assets/sounds')
|
||||
end
|
||||
|
||||
def knock_file
|
||||
if long_sample_rate == 44100
|
||||
knock = File.join(path_to_resources, 'knock44.wav')
|
||||
else
|
||||
knock = File.join(path_to_resources, 'knock48.wav')
|
||||
end
|
||||
|
||||
log.debug("knock file path: " + knock)
|
||||
knock
|
||||
end
|
||||
|
||||
def create_silence(tmp_dir, segment_count, duration)
|
||||
file = File.join(tmp_dir, "#{segment_count}.wav")
|
||||
|
||||
# -c 2 means stereo
|
||||
cmd("sox -n -r #{long_sample_rate} -c 2 #{file} trim 0.0 #{duration}", "silence")
|
||||
|
||||
file
|
||||
end
|
||||
|
||||
def create_tapin_track(tmp_dir)
|
||||
|
||||
return nil if @start_points.length == 0
|
||||
|
||||
segment_count = 0
|
||||
|
||||
|
||||
#initial_silence = @initial_tap_in + @initial_padding
|
||||
|
||||
initial_silence = @tap_in_initial_silence
|
||||
|
||||
#log.info("tapin data: initial_tap_in: #{@initial_tap_in}, initial_padding: #{@initial_padding}, initial_silence: #{initial_silence}")
|
||||
|
||||
time_points = []
|
||||
files = []
|
||||
if initial_silence > 0
|
||||
|
||||
files << create_silence(tmp_dir, segment_count, initial_silence)
|
||||
|
||||
time_points << {type: :silence, ts: initial_silence}
|
||||
segment_count += 1
|
||||
end
|
||||
|
||||
|
||||
time_cursor = nil
|
||||
@start_points.each do |start_point|
|
||||
tap_time = parse_time(start_point["ts"])
|
||||
if !time_cursor.nil?
|
||||
between_silence = tap_time - time_cursor
|
||||
files << create_silence(tmp_dir, segment_count, between_silence)
|
||||
time_points << {type: :silence, ts: between_silence}
|
||||
end
|
||||
time_cursor = tap_time
|
||||
bpm = start_point["bpm"].to_f
|
||||
|
||||
tick_silence = 60.0/bpm - KNOCK_SECONDS
|
||||
|
||||
ticks = start_point["ticks"].to_i
|
||||
|
||||
ticks.times do |tick|
|
||||
files << knock_file
|
||||
files << create_silence(tmp_dir, segment_count, tick_silence)
|
||||
time_points << {type: :knock, ts: KNOCK_SECONDS}
|
||||
time_points << {type: :silence, ts: tick_silence}
|
||||
time_cursor + 60.0/bpm
|
||||
segment_count += 1
|
||||
end
|
||||
end
|
||||
|
||||
log.info("time points for tap-in: #{time_points.inspect}")
|
||||
# do we need to pad with time? not sure
|
||||
|
||||
sequence_cmd = "sox "
|
||||
files.each do |file|
|
||||
sequence_cmd << "\"#{file}\" "
|
||||
end
|
||||
|
||||
count_in = File.join(tmp_dir, "count-in.wav")
|
||||
sequence_cmd << "\"#{count_in}\""
|
||||
|
||||
cmd(sequence_cmd, "count_in")
|
||||
@count_in_file = count_in
|
||||
count_in
|
||||
end
|
||||
|
||||
# creates a list of tracks to actually mix
|
||||
|
|
@ -140,6 +347,15 @@ module JamRuby
|
|||
stems = @mixdown.jam_track.stem_tracks
|
||||
@track_count = stems.length
|
||||
|
||||
@include_count_in = @settings["count-in"] && @start_points.length > 0 && @mixdown_package.encrypt_type.nil?
|
||||
|
||||
# temp
|
||||
# @include_count_in = true
|
||||
|
||||
if @include_count_in
|
||||
@track_count += 1
|
||||
end
|
||||
|
||||
stems.each do |stem|
|
||||
|
||||
vol = 1.0
|
||||
|
|
@ -166,10 +382,14 @@ module JamRuby
|
|||
|
||||
# if we didn't deliberately skip this one, and if there was no 'match' (meaning user did not specify), then we leave this in unchanged
|
||||
if !skipped && !match
|
||||
@track_settings << {stem:stem, vol:vol, pan:pan}
|
||||
@track_settings << {stem: stem, vol: vol, pan: pan}
|
||||
end
|
||||
end
|
||||
|
||||
if @include_count_in
|
||||
@track_settings << {count_in: true, vol: 1.0, pan: 0}
|
||||
end
|
||||
|
||||
@track_settings
|
||||
end
|
||||
|
||||
|
|
@ -180,14 +400,14 @@ module JamRuby
|
|||
# k = f(i) = (i)/(2*MAX_PAN) + 0.5
|
||||
# so f(MIN_PAN) = -0.5 + 0.5 = 0
|
||||
|
||||
k = ((pan * (1.0))/ (2.0 * MAX_PAN )) + 0.5
|
||||
k = ((pan * (1.0))/ (2.0 * MAX_PAN)) + 0.5
|
||||
l, r = 0
|
||||
|
||||
if k == 0
|
||||
l = 0.0
|
||||
r = 1.0
|
||||
else
|
||||
l = Math.sqrt(k)
|
||||
l = Math.sqrt(k)
|
||||
r = Math.sqrt(1-k)
|
||||
end
|
||||
|
||||
|
|
@ -196,24 +416,26 @@ module JamRuby
|
|||
|
||||
def package
|
||||
|
||||
puts @settings.inspect
|
||||
puts @track_count
|
||||
puts @track_settings
|
||||
puts @track_settings.count
|
||||
log.info("Settings: #{@settings.to_json}")
|
||||
|
||||
Dir.mktmpdir do |tmp_dir|
|
||||
|
||||
# download all files
|
||||
@track_settings.each do |track|
|
||||
jam_track_track = track[:stem]
|
||||
|
||||
file = File.join(tmp_dir, jam_track_track.id + '.ogg')
|
||||
if track[:count_in]
|
||||
file = create_tapin_track(tmp_dir)
|
||||
bump_step(@mixdown_package)
|
||||
else
|
||||
jam_track_track = track[:stem]
|
||||
|
||||
bump_step(@mixdown_package)
|
||||
file = File.join(tmp_dir, jam_track_track.id + '.ogg')
|
||||
|
||||
# download each track needed
|
||||
s3_manager.download(jam_track_track.url_by_sample_rate(@mixdown_package.sample_rate), file)
|
||||
bump_step(@mixdown_package)
|
||||
|
||||
# download each track needed
|
||||
s3_manager.download(jam_track_track.url_by_sample_rate(@mixdown_package.sample_rate), file)
|
||||
end
|
||||
|
||||
track[:file] = file
|
||||
end
|
||||
|
|
@ -233,6 +455,8 @@ module JamRuby
|
|||
|
||||
apply_vol_and_pan tmp_dir
|
||||
|
||||
create_silence_padding tmp_dir
|
||||
|
||||
mix tmp_dir
|
||||
|
||||
pitch_speed tmp_dir
|
||||
|
|
@ -245,6 +469,7 @@ module JamRuby
|
|||
@track_settings.each do |track|
|
||||
|
||||
jam_track_track = track[:stem]
|
||||
count_in = track[:count_in]
|
||||
file = track[:file]
|
||||
|
||||
unless should_alter_volume? track
|
||||
|
|
@ -262,7 +487,11 @@ module JamRuby
|
|||
|
||||
# sox claps.wav claps-remixed.wav remix 1v1.0 2v1.0
|
||||
|
||||
volumed_file = File.join(tmp_dir, jam_track_track.id + '-volumed.ogg')
|
||||
if count_in
|
||||
volumed_file = File.join(tmp_dir, 'count-in' + '-volumed.ogg')
|
||||
else
|
||||
volumed_file = File.join(tmp_dir, jam_track_track.id + '-volumed.ogg')
|
||||
end
|
||||
|
||||
cmd("sox \"#{file}\" \"#{volumed_file}\" remix 1v#{channel_r} 2v#{channel_l}", 'vol_pan')
|
||||
|
||||
|
|
@ -271,6 +500,29 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
def create_silence_padding(tmp_dir)
|
||||
if @initial_padding > 0 && @include_count_in
|
||||
|
||||
@padding_file = File.join(tmp_dir, "initial_padding.ogg")
|
||||
|
||||
# -c 2 means stereo
|
||||
cmd("sox -n -r #{long_sample_rate} -c 2 #{@padding_file} trim 0.0 #{@initial_padding}", "initial_padding")
|
||||
|
||||
@track_settings.each do |track|
|
||||
|
||||
next if track[:count_in]
|
||||
|
||||
input = track[:volumed_file]
|
||||
output = input[0..-5] + '-padded.ogg'
|
||||
|
||||
padd_cmd = "sox '#{@padding_file}' '#{input}' '#{output}'"
|
||||
|
||||
cmd(padd_cmd, "pad_track_with_silence")
|
||||
track[:volumed_file] = output
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# output is @mix_file
|
||||
def mix(tmp_dir)
|
||||
|
||||
|
|
@ -278,6 +530,11 @@ module JamRuby
|
|||
|
||||
@mix_file = File.join(tmp_dir, "mix.ogg")
|
||||
|
||||
|
||||
pitch = @settings['pitch'] || 0
|
||||
speed = @settings['speed'] || 0
|
||||
|
||||
|
||||
# if there is only one track to mix, we need to skip mixing (sox will barf if you try to mix one file), but still divide by number of tracks
|
||||
if @track_settings.count == 1
|
||||
mix_divide = 1.0/@track_count
|
||||
|
|
@ -290,6 +547,11 @@ module JamRuby
|
|||
cmd = "sox -m"
|
||||
mix_divide = 1.0/@track_count
|
||||
@track_settings.each do |track|
|
||||
|
||||
# if pitch/shifted, we lay the tap-in after pitch/speed shift
|
||||
# next if (pitch != 0 || speed != 0) && track[:count_in]
|
||||
next if track[:count_in]
|
||||
|
||||
volumed_file = track[:volumed_file]
|
||||
cmd << " -v #{mix_divide} \"#{volumed_file}\""
|
||||
end
|
||||
|
|
@ -302,6 +564,13 @@ module JamRuby
|
|||
|
||||
end
|
||||
|
||||
def long_sample_rate
|
||||
sample_rate = 48000
|
||||
if @mixdown_package.sample_rate != 48
|
||||
sample_rate = 44100
|
||||
end
|
||||
sample_rate
|
||||
end
|
||||
|
||||
# output is @speed_mix_file
|
||||
def pitch_speed tmp_dir
|
||||
|
|
@ -327,17 +596,21 @@ module JamRuby
|
|||
|
||||
# usage: sbsms infile<.wav|.aif|.mp3|.ogg> outfile<.ogg> rate[0.01:100] halfsteps[-48:48] outSampleRateInHz
|
||||
|
||||
sample_rate = 48000
|
||||
if @mixdown_package.sample_rate != 48
|
||||
sample_rate = 44100
|
||||
end
|
||||
sample_rate = long_sample_rate
|
||||
|
||||
# rate comes in as a percent (like 5, -5 for 5%, -5%). We need to change that to 1.05/
|
||||
sbsms_speed = speed/100.0
|
||||
sbsms_speed = 1.0 + sbsms_speed
|
||||
|
||||
sbsms_pitch = pitch
|
||||
cmd( "sbsms \"#{@mix_file}\" \"#{@speed_mix_file}\" #{sbsms_speed} #{sbsms_pitch} #{sample_rate}", 'speed_pitch_shift')
|
||||
cmd("sbsms \"#{@mix_file}\" \"#{@speed_mix_file}\" #{sbsms_speed} #{sbsms_pitch} #{sample_rate}", 'speed_pitch_shift')
|
||||
end
|
||||
|
||||
if @include_count_in
|
||||
# lay the tap-ins over the recording
|
||||
layered = File.join(tmp_dir, "layered_speed_mix.ogg")
|
||||
cmd("sox -m '#{@count_in_file}' '#{@speed_mix_file}' '#{layered}'", "layer_tap_in")
|
||||
@speed_mix_file = layered
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -364,7 +637,7 @@ module JamRuby
|
|||
|
||||
length = File.size(output)
|
||||
computed_md5 = Digest::MD5.new
|
||||
File.open(output, 'rb').each {|line| computed_md5.update(line)}
|
||||
File.open(output, 'rb').each { |line| computed_md5.update(line) }
|
||||
md5 = computed_md5.to_s
|
||||
|
||||
@mixdown_package.finish_sign(s3_url, private_key, length, md5.to_s)
|
||||
|
|
@ -426,7 +699,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
private_key_file = File.join(tmp_dir, 'skey.pem')
|
||||
File.open(private_key_file, 'w') {|f| f.write(private_key) }
|
||||
File.open(private_key_file, 'w') { |f| f.write(private_key) }
|
||||
|
||||
log.debug("PRIVATE KEY")
|
||||
log.debug(private_key)
|
||||
|
|
|
|||
|
|
@ -298,6 +298,14 @@ mixins.push(Reflux.listenTo(JamTrackPlayerStore, 'onJamTrackPlayerStoreChanged')
|
|||
<td className="mute"><input type="checkbox" className="stem-mute" data-stem-id={track.id} defaultChecked={track.track_type == 'Click'}/></td>
|
||||
</tr>`)
|
||||
|
||||
if jamTrack?.jmep?.Events? && jamTrack.jmep.Events[0].metronome?
|
||||
# tap-in detected; show user tap-in option
|
||||
tracks.push(`
|
||||
<tr className="stem">
|
||||
<td><img src={context.JK.getInstrumentIcon24('computer')} className="instrument-icon" /> Count-in</td>
|
||||
<td className="mute"><input type="checkbox" className="stem-mute" data-stem-id="count-in" /></td>
|
||||
</tr>`)
|
||||
|
||||
stems = `<div key="stems" className="stems">
|
||||
<table>
|
||||
<thead>
|
||||
|
|
@ -647,6 +655,7 @@ mixins.push(Reflux.listenTo(JamTrackPlayerStore, 'onJamTrackPlayerStoreChanged')
|
|||
else
|
||||
pitch = parseInt(pitch)
|
||||
|
||||
count_in = false
|
||||
|
||||
# get mute state of all tracks
|
||||
$mutes = $(@getDOMNode()).find('.stems .stem .stem-mute')
|
||||
|
|
@ -657,10 +666,13 @@ mixins.push(Reflux.listenTo(JamTrackPlayerStore, 'onJamTrackPlayerStoreChanged')
|
|||
stemId = $mute.attr('data-stem-id')
|
||||
muted = $mute.is(':checked')
|
||||
|
||||
tracks.push({id: stemId, mute: muted})
|
||||
if stemId == 'count-in'
|
||||
count_in = !muted
|
||||
else
|
||||
tracks.push({id: stemId, mute: muted})
|
||||
)
|
||||
|
||||
mixdown = {jamTrackID: @state.jamTrackState.jamTrack.id, name: name, settings: {speed:speed, pitch: pitch, tracks:tracks}}
|
||||
mixdown = {jamTrackID: @state.jamTrackState.jamTrack.id, name: name, settings: {speed:speed, pitch: pitch, "count-in": count_in, tracks:tracks}}
|
||||
|
||||
JamTrackPlayerActions.createMixdown(mixdown, @createMixdownDone, @createMixdownFail)
|
||||
|
||||
|
|
|
|||
|
|
@ -276,8 +276,7 @@ ChannelGroupIds = context.JK.ChannelGroupIds
|
|||
# All the JamTracks
|
||||
mediaTracks.push(`<SessionJamTrackCategory key="JamTrackCategory" jamTrackName={this.state.jamTrackName} mixers={this.state.mediaCategoryMixer} mode={MIX_MODES.PERSONAL} />`)
|
||||
|
||||
# show metronome only if it's a full jamtrack
|
||||
if @state.metronome? && @state.jamTrackMixdown.id == null
|
||||
if @state.metronome? # && @state.jamTrackMixdown.id == null
|
||||
@state.metronome.mode = MIX_MODES.PERSONAL
|
||||
mediaTracks.push(`<SessionMetronome key="JamTrackMetronome" {...this.state.metronome} location="jam-track" />`)
|
||||
|
||||
|
|
|
|||
|
|
@ -165,6 +165,20 @@ JamTrackActions = @JamTrackActions
|
|||
# JamTrackPlay means 'load'
|
||||
logger.debug("JamTrackStore: loading mixdown")
|
||||
context.jamClient.JamTrackStopPlay();
|
||||
|
||||
if @jamTrack.jmep
|
||||
|
||||
if @jamTrack.activeMixdown.settings.speed?
|
||||
@jamTrack.jmep.speed = @jamTrack.activeMixdown.settings.speed
|
||||
else
|
||||
@jamTrack.jmep.speed = 0
|
||||
|
||||
logger.debug("setting jmep data. speed:" + @jamTrack.jmep.speed)
|
||||
|
||||
context.jamClient.JamTrackLoadJmep(fqId, @jamTrack.jmep)
|
||||
else
|
||||
logger.debug("no jmep data for jamtrack")
|
||||
|
||||
result = context.jamClient.JamTrackPlay(fqId);
|
||||
if !result
|
||||
@jamTrack.activeMixdown.client_state = 'cant_open'
|
||||
|
|
|
|||
|
|
@ -196,6 +196,12 @@ namespace :jam_tracks do
|
|||
mapper.correlate
|
||||
end
|
||||
|
||||
task touch: :environment do |task, arg|
|
||||
JamTrack.all.each do |jt|
|
||||
jt.touch # causes jmep re-spin
|
||||
end
|
||||
end
|
||||
|
||||
task generate_private_key: :environment do |task, arg|
|
||||
JamTrackRight.all.each do |right|
|
||||
if right.private_key_44.nil? || right.private_key_48.nil?
|
||||
|
|
|
|||
Loading…
Reference in New Issue