MusicMaster 0.0.1.20101110 → 1.0.0.20120307
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +4 -1
- data/ChangeLog +28 -0
- data/LICENSE +1 -1
- data/README +2 -5
- data/ReleaseInfo +8 -8
- data/bin/Calibrate.rb +55 -0
- data/bin/Clean.rb +55 -0
- data/bin/DBConvert.rb +3 -1
- data/bin/Deliver.rb +73 -42
- data/bin/Mix.rb +39 -78
- data/bin/Process.rb +55 -0
- data/bin/Record.rb +63 -116
- data/bin/{Album.rb → old/Album.rb} +18 -18
- data/bin/{AnalyzeAlbum.rb → old/AnalyzeAlbum.rb} +11 -11
- data/bin/{DeliverAlbum.rb → old/DeliverAlbum.rb} +12 -12
- data/bin/{Fct2Wave.rb → old/Fct2Wave.rb} +11 -11
- data/{album.conf.rb.example → bin/old/album.conf.rb.example} +0 -0
- data/lib/MusicMaster/FilesNamer.rb +253 -0
- data/lib/MusicMaster/Formats/MP3.rb +50 -0
- data/lib/MusicMaster/Formats/Test.rb +44 -0
- data/lib/MusicMaster/Formats/Wave.rb +80 -0
- data/lib/MusicMaster/Hash.rb +20 -0
- data/lib/MusicMaster/Launcher.rb +241 -0
- data/lib/MusicMaster/Processes/ApplyVolumeFct.rb +4 -8
- data/lib/MusicMaster/Processes/Compressor.rb +50 -47
- data/lib/MusicMaster/Processes/Custom.rb +3 -3
- data/lib/MusicMaster/Processes/{AddSilence.rb → Cut.rb} +8 -4
- data/lib/MusicMaster/Processes/CutFirstSignal.rb +6 -3
- data/lib/MusicMaster/Processes/DCShifter.rb +30 -0
- data/lib/MusicMaster/Processes/GVerb.rb +3 -2
- data/lib/MusicMaster/Processes/Normalize.rb +7 -6
- data/lib/MusicMaster/Processes/SilenceInserter.rb +31 -0
- data/lib/MusicMaster/Processes/Test.rb +39 -0
- data/lib/MusicMaster/Processes/VolCorrection.rb +3 -3
- data/lib/MusicMaster/RakeProcesses.rb +1014 -0
- data/lib/MusicMaster/Symbol.rb +12 -0
- data/lib/MusicMaster/Task.rb +29 -0
- data/lib/MusicMaster/Utils.rb +467 -0
- data/lib/MusicMaster/old/Common.rb +101 -0
- data/musicmaster.conf.rb.example +42 -59
- data/record.conf.rb.example +374 -30
- metadata +91 -41
- data/TODO +0 -3
- data/bin/Master.rb +0 -60
- data/bin/PrepareMix.rb +0 -422
- data/lib/MusicMaster/Common.rb +0 -197
- data/lib/MusicMaster/ConfLoader.rb +0 -56
- data/lib/MusicMaster/musicmaster.conf.rb +0 -96
- data/master.conf.rb.example +0 -13
data/lib/MusicMaster/Common.rb
DELETED
@@ -1,197 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
3
|
-
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
-
#++
|
5
|
-
|
6
|
-
require 'fileutils'
|
7
|
-
require 'rational'
|
8
|
-
|
9
|
-
module MusicMaster
|
10
|
-
|
11
|
-
# Call WSK
|
12
|
-
#
|
13
|
-
# Parameters:
|
14
|
-
# * *iInputFile* (_String_): The input file
|
15
|
-
# * *iOutputFile* (_String_): The output file
|
16
|
-
# * *iAction* (_String_): The action
|
17
|
-
# * *iParams* (_String_): Action parameters [optional = '']
|
18
|
-
def self.wsk(iInputFile, iOutputFile, iAction, iParams = '')
|
19
|
-
logInfo ''
|
20
|
-
logInfo "========== Processing #{iInputFile} ==#{iAction}==> #{iOutputFile} | #{iParams} ..."
|
21
|
-
system("#{$MusicMasterConf[:WSKCmdLine]} --input \"#{iInputFile}\" --output \"#{iOutputFile}\" --action #{iAction} -- #{iParams}")
|
22
|
-
lErrorCode = $?.exitstatus
|
23
|
-
if (lErrorCode == 0)
|
24
|
-
logInfo "========== Processing #{iInputFile} ==#{iAction}==> #{iOutputFile} | #{iParams} ... OK"
|
25
|
-
else
|
26
|
-
logErr "========== Processing #{iInputFile} ==#{iAction}==> #{iOutputFile} | #{iParams} ... ERROR #{lErrorCode}"
|
27
|
-
raise RuntimeError, "Processing #{iInputFile} ==#{iAction}==> #{iOutputFile} | #{iParams} ... ERROR #{lErrorCode}"
|
28
|
-
end
|
29
|
-
logInfo ''
|
30
|
-
end
|
31
|
-
|
32
|
-
# Parse plugins
|
33
|
-
def self.parsePlugins
|
34
|
-
require 'rUtilAnts/Plugins'
|
35
|
-
RUtilAnts::Plugins::initializePlugins
|
36
|
-
lLibDir = File.expand_path(File.dirname(__FILE__))
|
37
|
-
parsePluginsFromDir('Processes', "#{lLibDir}/Processes", 'MusicMaster::Processes')
|
38
|
-
end
|
39
|
-
|
40
|
-
# Apply given record effects on a Wave file.
|
41
|
-
# It modifies the given Wave file.
|
42
|
-
# It saves original and intermediate Wave files before modifications.
|
43
|
-
#
|
44
|
-
# Parameters:
|
45
|
-
# * *iEffects* (<em>list<map<Symbol,Object>></em>): List of effects to apply
|
46
|
-
# * *iFileName* (_String_): File name to apply effects to
|
47
|
-
# * *iDir* (_String_): The directory where temporary files are stored
|
48
|
-
def self.applyProcesses(iEffects, iFileName, iDir)
|
49
|
-
lFileNameNoExt = File.basename(iFileName[0..-5])
|
50
|
-
iEffects.each_with_index do |iEffectInfo, iIdxEffect|
|
51
|
-
begin
|
52
|
-
accessPlugin('Processes', iEffectInfo[:Name]) do |ioActionPlugin|
|
53
|
-
# Save the file before using the plugin
|
54
|
-
lSave = true
|
55
|
-
lSaveFileName = "#{iDir}/#{lFileNameNoExt}.Before_#{iIdxEffect}_#{iEffectInfo[:Name]}.wav"
|
56
|
-
if (File.exists?(lSaveFileName))
|
57
|
-
puts "!!! File #{lSaveFileName} already exists. Overwrite and apply effect ? [y='yes']"
|
58
|
-
lSave = ($stdin.gets.chomp == 'y')
|
59
|
-
end
|
60
|
-
if (lSave)
|
61
|
-
logInfo "Saving file #{iFileName} to #{lSaveFileName} ..."
|
62
|
-
FileUtils::mv(iFileName, lSaveFileName)
|
63
|
-
logInfo "===== Apply Effect #{iEffectInfo[:Name]} to #{iFileName} ====="
|
64
|
-
ioActionPlugin.execute(lSaveFileName, iFileName, iDir, iEffectInfo.clone.delete_if{|iKey, iValue| next (iKey == :Name)})
|
65
|
-
end
|
66
|
-
end
|
67
|
-
rescue Exception
|
68
|
-
logErr "An error occurred while processing #{iFileName} with process #{iEffectInfo[:Name]}: #{$!}."
|
69
|
-
raise
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
# Read record configuration.
|
75
|
-
# Perform basic checks on it.
|
76
|
-
#
|
77
|
-
# Parameters:
|
78
|
-
# * *iConfFile* (_String_): Configuration file
|
79
|
-
# Return:
|
80
|
-
# * _Exception_: Error, or nil in case of success
|
81
|
-
# * <em>map<Symbol,Object></em>: The configuration
|
82
|
-
def self.readRecordConf(iConfFile)
|
83
|
-
rError = nil
|
84
|
-
rConf = nil
|
85
|
-
|
86
|
-
if (!File.exists?(iConfFile))
|
87
|
-
rError = RuntimeError.new("Missing configuration file: #{iConfFile}")
|
88
|
-
else
|
89
|
-
File.open(iConfFile, 'r') do |iFile|
|
90
|
-
rConf = eval(iFile.read)
|
91
|
-
end
|
92
|
-
# Check that all tracks are assigned somewhere, just once
|
93
|
-
lLstTracks = nil
|
94
|
-
if (rConf[:Patches] != nil)
|
95
|
-
lLstTracks = rConf[:Patches].keys.clone
|
96
|
-
else
|
97
|
-
lLstTracks = []
|
98
|
-
end
|
99
|
-
if (rConf[:Performs] != nil)
|
100
|
-
rConf[:Performs].each do |iLstPerform|
|
101
|
-
lLstTracks.concat(iLstPerform)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
lAssignedTracks = {}
|
105
|
-
lLstTracks.each do |iIdxTrack|
|
106
|
-
if (lAssignedTracks.has_key?(iIdxTrack))
|
107
|
-
rError = RuntimeError.new("Track #{iIdxTrack} is recorded twice.")
|
108
|
-
break
|
109
|
-
else
|
110
|
-
lAssignedTracks[iIdxTrack] = nil
|
111
|
-
end
|
112
|
-
end
|
113
|
-
if (rError == nil)
|
114
|
-
if (rConf[:Patches] != nil)
|
115
|
-
rConf[:Patches].each do |iIdxTrack, iTrackConf|
|
116
|
-
if ((iTrackConf.has_key?(:VolCorrection)) and
|
117
|
-
(iTrackConf.has_key?(:VolCompareCuts)))
|
118
|
-
rError = RuntimeError.new("Patch track #{iIdxTrack} has both :VolCorrection and :VolCompareCuts values defined.")
|
119
|
-
elsif ((!iTrackConf.has_key?(:VolCorrection)) and
|
120
|
-
(!iTrackConf.has_key?(:VolCompareCuts)))
|
121
|
-
rError = RuntimeError.new("Patch track #{iIdxTrack} has neither :VolCorrection nor :VolCompareCuts values defined.")
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
if (rError == nil)
|
126
|
-
lAssignedTracks.size.times do |iIdxTrack|
|
127
|
-
if (!lAssignedTracks.has_key?(iIdxTrack+1))
|
128
|
-
logWarn "Track #{iIdxTrack+1} is never recorded."
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
return rError, rConf
|
136
|
-
end
|
137
|
-
|
138
|
-
# Convert a Wave file to another
|
139
|
-
#
|
140
|
-
# Parameters:
|
141
|
-
# * *iSrcFile* (_String_): Source WAVE file
|
142
|
-
# * *iDstFile* (_String_): Destination WAVE file
|
143
|
-
# * *iParams* (<em>map<Symbol,Object></em>): The parameters:
|
144
|
-
# ** *:SampleRate* (_Integer_): The new sample rate in Hz
|
145
|
-
# ** *:BitDepth* (_Integer_): The new bit depth (only for Wave) [optional = nil]
|
146
|
-
# ** *:Dither* (_Boolean_): Do we apply dither (only for Wave) ? [optional = false]
|
147
|
-
# ** *:BitRate* (_Integer_): Bit rate in kbps (only for MP3) [optional = 320]
|
148
|
-
# ** *:FileFormat* (_Symbol_); File format. Here are the possible values: [optional = :Wave]
|
149
|
-
# *** *:Wave*: Uncompressed PCM Wave file
|
150
|
-
# *** *:MP3*: MP3 file
|
151
|
-
def self.src(iSrcFile, iDstFile, iParams)
|
152
|
-
if ((iParams[:FileFormat] != nil) and
|
153
|
-
(iParams[:FileFormat] == :MP3))
|
154
|
-
# MP3 conversion
|
155
|
-
lTranslatedParams = []
|
156
|
-
iParams.each do |iParam, iValue|
|
157
|
-
case iParam
|
158
|
-
when :SampleRate
|
159
|
-
lTranslatedParams << "Sample rate: #{iValue} Hz"
|
160
|
-
when :BitRate
|
161
|
-
lTranslatedParams << "Bit rate: #{iValue} kbps"
|
162
|
-
when :FileFormat
|
163
|
-
# Nothing to do
|
164
|
-
else
|
165
|
-
logErr "Unknown MP3 parameter: #{iParam} (value #{iValue.inspect}). Ignoring it."
|
166
|
-
end
|
167
|
-
end
|
168
|
-
puts "Convert file #{iSrcFile} into file #{iDstFile} in MP3 format with following parameters: #{lTranslatedParams.join(', ')}"
|
169
|
-
puts 'Press Enter when done.'
|
170
|
-
$stdin.gets
|
171
|
-
else
|
172
|
-
# Wave conversion
|
173
|
-
lTranslatedParams = [ '--profile standard', '--twopass' ]
|
174
|
-
iParams.each do |iParam, iValue|
|
175
|
-
case iParam
|
176
|
-
when :SampleRate
|
177
|
-
lTranslatedParams << "--rate #{iValue}"
|
178
|
-
when :BitDepth
|
179
|
-
lTranslatedParams << "--bits #{iValue}"
|
180
|
-
when :Dither
|
181
|
-
if (iValue == true)
|
182
|
-
lTranslatedParams << '--dither 4'
|
183
|
-
end
|
184
|
-
when :FileFormat
|
185
|
-
# Nothing to do
|
186
|
-
else
|
187
|
-
logErr "Unknown Wave parameter: #{iParam} (value #{iValue.inspect}). Ignoring it."
|
188
|
-
end
|
189
|
-
end
|
190
|
-
FileUtils::mkdir_p(File.dirname(iDstFile))
|
191
|
-
lCmd = "#{$MusicMasterConf[:SRCCmdLine]} #{lTranslatedParams.join(' ')} \"#{iSrcFile}\" \"#{iDstFile}\""
|
192
|
-
logInfo "=> #{lCmd}"
|
193
|
-
system(lCmd)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
3
|
-
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
-
#++
|
5
|
-
|
6
|
-
# This file is required by MusicMaster binaries to load the MusicMaster configuration.
|
7
|
-
# This sets the $MusicMasterConf object that can then be accessed from anywhere.
|
8
|
-
|
9
|
-
module MusicMaster
|
10
|
-
|
11
|
-
def self.loadConf
|
12
|
-
$MusicMasterConf = nil
|
13
|
-
lConfSource = nil
|
14
|
-
# 1. Find from the environment
|
15
|
-
lConfigFileName = ENV['MUSICMASTER_CONF_PATH']
|
16
|
-
if (lConfigFileName == nil)
|
17
|
-
# 2. Find from the MusicMaster directory
|
18
|
-
lConfigFileName = "#{File.dirname(__FILE__)}/musicmaster.conf.rb"
|
19
|
-
if (File.exists?(lConfigFileName))
|
20
|
-
lConfSource = 'MusicMaster package local libraries'
|
21
|
-
else
|
22
|
-
# 3. Find from the current directory
|
23
|
-
lConfigFileName = "musicmaster.conf.rb"
|
24
|
-
if (File.exists?(lConfigFileName))
|
25
|
-
lConfSource = 'current directory'
|
26
|
-
else
|
27
|
-
# 4. Failure
|
28
|
-
end
|
29
|
-
end
|
30
|
-
else
|
31
|
-
lConfSource = 'MUSICMASTER_CONF_PATH environment variable'
|
32
|
-
end
|
33
|
-
|
34
|
-
# Check the configuration
|
35
|
-
if (lConfSource == nil)
|
36
|
-
logErr "No MusicMaster configuration file could be found. You can set it by setting MUSICMASTER_CONF_PATH environment variable, or create a musicmaster.conf.rb file either in #{File.dirname(__FILE__)} or the current directory."
|
37
|
-
else
|
38
|
-
if (File.exists?(lConfigFileName))
|
39
|
-
File.open(lConfigFileName, 'r') do |iFile|
|
40
|
-
begin
|
41
|
-
$MusicMasterConf = eval(iFile.read)
|
42
|
-
rescue Exception
|
43
|
-
logErr "Invalid configuration file #{lConfigFileName} specified in #{lConfSource}: #{$!}"
|
44
|
-
$MusicMasterConf = nil
|
45
|
-
end
|
46
|
-
end
|
47
|
-
else
|
48
|
-
logErr "Missing file #{lConfigFileName}, specified in #{lConfSource}"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
MusicMaster::loadConf
|
@@ -1,96 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
3
|
-
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
-
#++
|
5
|
-
|
6
|
-
{
|
7
|
-
|
8
|
-
# Command line to run WSK tool
|
9
|
-
:WSKCmdLine => 'ruby -w -I/cygdrive/f/RR/Source/rutilants/svn/rutilants/lib -I/cygdrive/f/RR/Source/waveswissknife/svn/waveswissknife/lib -I/cygdrive/f/RR/Source/waveswissknife/svn/waveswissknife/ext /cygdrive/f/RR/Source/waveswissknife/svn/waveswissknife/bin/WSK.rb',
|
10
|
-
|
11
|
-
# Command line to run Sample Rate Converter tool
|
12
|
-
:SRCCmdLine => '/cygdrive/e/Temp/Projects/Music/Tools/SSRC/ssrc.exe',
|
13
|
-
|
14
|
-
# Record options
|
15
|
-
:Record => {
|
16
|
-
|
17
|
-
# Method returning the name of the next recorded file
|
18
|
-
:RecordedFileGetter => Proc.new do
|
19
|
-
next `ls -rt /cygdrive/e/Temp/Tests\\ M-Audio/TestFramework\\ Project/Samples/Recorded/*.wav | tail -2 | head -1`.chomp
|
20
|
-
end
|
21
|
-
|
22
|
-
},
|
23
|
-
|
24
|
-
# PrepareMix options
|
25
|
-
:PrepareMix => {
|
26
|
-
|
27
|
-
# Directory in which temporary files will be generated
|
28
|
-
:TempDir => 'PrepareMixTemp',
|
29
|
-
|
30
|
-
# Percentage of values added as a margin of the silence thresholds (arbitrary value)
|
31
|
-
:MarginSilenceThresholds => 0.1,
|
32
|
-
|
33
|
-
},
|
34
|
-
|
35
|
-
# Mix options
|
36
|
-
:Mix => {
|
37
|
-
|
38
|
-
# Directory in which temporary files will be generated
|
39
|
-
:TempDir => 'MixTemp'
|
40
|
-
|
41
|
-
},
|
42
|
-
|
43
|
-
# Master options
|
44
|
-
:Master => {
|
45
|
-
|
46
|
-
# Directory in which files will be generated
|
47
|
-
:Dir => 'Master'
|
48
|
-
|
49
|
-
},
|
50
|
-
|
51
|
-
# Album options
|
52
|
-
:Album => {
|
53
|
-
|
54
|
-
# Directory in which temporary files will be generated
|
55
|
-
:TempDir => 'AlbumTemp',
|
56
|
-
|
57
|
-
# Directory in which files will be generated
|
58
|
-
:Dir => 'Album'
|
59
|
-
|
60
|
-
},
|
61
|
-
|
62
|
-
# Album delivery options
|
63
|
-
:AlbumDeliver => {
|
64
|
-
|
65
|
-
# Directory in which files will be generated
|
66
|
-
:Dir => 'AlbumDeliver'
|
67
|
-
|
68
|
-
},
|
69
|
-
|
70
|
-
# Single Track delivery options
|
71
|
-
:Deliver => {
|
72
|
-
|
73
|
-
# Directory in which files will be generated
|
74
|
-
:Dir => 'Deliver'
|
75
|
-
|
76
|
-
},
|
77
|
-
|
78
|
-
# Options for NoiseGate processes
|
79
|
-
:NoiseGate => {
|
80
|
-
|
81
|
-
# Durations used for noise gates
|
82
|
-
# !!! Attack + Release should be < SilenceMin !!!
|
83
|
-
:Attack => '0.1s',
|
84
|
-
:Release => '0.1s',
|
85
|
-
:SilenceMin => '1s'
|
86
|
-
|
87
|
-
},
|
88
|
-
|
89
|
-
# Options for Compressor processes
|
90
|
-
:Compressor => {
|
91
|
-
|
92
|
-
:Interval => '0.1s'
|
93
|
-
|
94
|
-
}
|
95
|
-
|
96
|
-
}
|
data/master.conf.rb.example
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
{
|
2
|
-
# Mastering effects
|
3
|
-
:Mastering => [
|
4
|
-
# Useful to remove starting beats
|
5
|
-
{ :Name => 'CutFirstSignal' },
|
6
|
-
# Normalization
|
7
|
-
{ :Name => 'Normalize' },
|
8
|
-
# Volume correction, either in ratio (ie. '4/5') or in db (ie. -2db)
|
9
|
-
{ :Name => 'VolCorrection', :Factor => '-2db' },
|
10
|
-
# Compression
|
11
|
-
{ :Name => 'Compressor' }
|
12
|
-
]
|
13
|
-
}
|