MusicMaster 0.0.1.20101110
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +1 -0
- data/ChangeLog +5 -0
- data/Credits +6 -0
- data/LICENSE +31 -0
- data/README +18 -0
- data/ReleaseInfo +8 -0
- data/TODO +3 -0
- data/album.conf.rb.example +78 -0
- data/bin/Album.rb +81 -0
- data/bin/AnalyzeAlbum.rb +66 -0
- data/bin/DBConvert.rb +36 -0
- data/bin/Deliver.rb +42 -0
- data/bin/DeliverAlbum.rb +68 -0
- data/bin/Fct2Wave.rb +58 -0
- data/bin/Master.rb +60 -0
- data/bin/Mix.rb +99 -0
- data/bin/PrepareMix.rb +422 -0
- data/bin/Record.rb +145 -0
- data/lib/MusicMaster/Common.rb +197 -0
- data/lib/MusicMaster/ConfLoader.rb +56 -0
- data/lib/MusicMaster/Processes/AddSilence.rb +27 -0
- data/lib/MusicMaster/Processes/ApplyVolumeFct.rb +46 -0
- data/lib/MusicMaster/Processes/Compressor.rb +246 -0
- data/lib/MusicMaster/Processes/Custom.rb +31 -0
- data/lib/MusicMaster/Processes/CutFirstSignal.rb +27 -0
- data/lib/MusicMaster/Processes/GVerb.rb +30 -0
- data/lib/MusicMaster/Processes/Normalize.rb +51 -0
- data/lib/MusicMaster/Processes/VolCorrection.rb +30 -0
- data/lib/MusicMaster/musicmaster.conf.rb +96 -0
- data/master.conf.rb.example +13 -0
- data/musicmaster.conf.rb.example +95 -0
- data/record.conf.rb.example +45 -0
- metadata +104 -0
data/AUTHORS
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
= Muriel Salvan (murielsalvan@users.sourceforge.net)
|
data/ChangeLog
ADDED
data/Credits
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
The license stated herein is a copy of the BSD License (modified on July 1999).
|
3
|
+
The AUTHOR mentionned below refers to the list of people involved in the
|
4
|
+
creation and modification of any file included in the delivered package.
|
5
|
+
This list is found in the file named AUTHORS.
|
6
|
+
The AUTHORS and LICENSE files have to be included in any release of software
|
7
|
+
embedding source code of this package, or using it as a derivative software.
|
8
|
+
|
9
|
+
Copyright (c) 2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
10
|
+
|
11
|
+
Redistribution and use in source and binary forms, with or without
|
12
|
+
modification, are permitted provided that the following conditions are met:
|
13
|
+
|
14
|
+
1. Redistributions of source code must retain the above copyright notice,
|
15
|
+
this list of conditions and the following disclaimer.
|
16
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
17
|
+
this list of conditions and the following disclaimer in the documentation
|
18
|
+
and/or other materials provided with the distribution.
|
19
|
+
3. The name of the author may not be used to endorse or promote products
|
20
|
+
derived from this software without specific prior written permission.
|
21
|
+
|
22
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
23
|
+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
24
|
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
25
|
+
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
26
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
27
|
+
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
28
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
29
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
30
|
+
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
31
|
+
OF SUCH DAMAGE.
|
data/README
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
-- This file is best viewed when processed by rdoc.
|
2
|
+
++
|
3
|
+
|
4
|
+
= Music Master
|
5
|
+
|
6
|
+
Command-line utility handling Mixing, Mastering and Delivering processes of music projects.
|
7
|
+
|
8
|
+
== Where is the documentation ?
|
9
|
+
|
10
|
+
Check the website at http://musicmaster.sourceforge.net
|
11
|
+
|
12
|
+
== Who wrote it ?
|
13
|
+
|
14
|
+
Check the AUTHORS[link:files/AUTHORS.html] file.
|
15
|
+
|
16
|
+
== What is the license ?
|
17
|
+
|
18
|
+
You can find out in the LICENSE[link:files/LICENSE.html] file.
|
data/ReleaseInfo
ADDED
data/TODO
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
{
|
2
|
+
# Recorded files of a Track should be in directories <TracksDir>/<TrackName>/<TrackVersion>/<TracksFilesSubDir>
|
3
|
+
|
4
|
+
# Path to the Tracks directories.
|
5
|
+
# Each Track is a sub-directory of this one, with its version (ie. ./Track2/0.1)
|
6
|
+
:TracksDir => '/path/to/Tracks',
|
7
|
+
|
8
|
+
# Sub-path to the recorded files
|
9
|
+
# Each Track is a sub-directory of this one, with its version (ie. Record/Files/)
|
10
|
+
# !!! Don't forget trailing /
|
11
|
+
:TracksFilesSubDir => 'sub/path/to/files/',
|
12
|
+
|
13
|
+
# Tracks to include in the album
|
14
|
+
:Tracks => [
|
15
|
+
|
16
|
+
{ # 01
|
17
|
+
# Beginning of the Track's directory name
|
18
|
+
:TrackID => 'Track112',
|
19
|
+
# Track's version
|
20
|
+
:Version => '0.0.1.20100924',
|
21
|
+
# Additional steps for Mastering the Track in the album's scope
|
22
|
+
:AdditionalMastering => [
|
23
|
+
{ :Name => 'CutFirstSignal' },
|
24
|
+
{ :Name => 'Normalize' },
|
25
|
+
{ :Name => 'VolCorrection', :Factor => '-2db' },
|
26
|
+
{ :Name => 'Compressor' },
|
27
|
+
{ :Name => 'AddSilence', :Begin => '1.2s', :End => '2.4s' }
|
28
|
+
]
|
29
|
+
},
|
30
|
+
|
31
|
+
{ # 02
|
32
|
+
:TrackID => 'Track114',
|
33
|
+
:Version => '0.0.1.20100924',
|
34
|
+
:AdditionalMastering => [
|
35
|
+
{ :Name => 'CutFirstSignal' },
|
36
|
+
{ :Name => 'Normalize' },
|
37
|
+
{ :Name => 'VolCorrection', :Factor => '-2db' },
|
38
|
+
{ :Name => 'Compressor' },
|
39
|
+
{ :Name => 'AddSilence', :Begin => '1.2s', :End => '1s' }
|
40
|
+
]
|
41
|
+
}
|
42
|
+
],
|
43
|
+
|
44
|
+
# Specify in which formats this album should be delivered
|
45
|
+
:Deliveries => {
|
46
|
+
|
47
|
+
# Name of the delivery
|
48
|
+
'Wave 96k 24b' => {
|
49
|
+
# Parameters
|
50
|
+
:SampleRate => 96000
|
51
|
+
},
|
52
|
+
|
53
|
+
'Wave 48k 24b' => {
|
54
|
+
:SampleRate => 48000
|
55
|
+
},
|
56
|
+
|
57
|
+
'Wave 44k 16b' => {
|
58
|
+
# By default :FileFormat is :Wave
|
59
|
+
:FileFormat => :Wave,
|
60
|
+
:SampleRate => 44100,
|
61
|
+
:BitDepth => 16,
|
62
|
+
:Dither => true
|
63
|
+
},
|
64
|
+
|
65
|
+
'MP3 48k 320kbps' => {
|
66
|
+
:FileFormat => :MP3,
|
67
|
+
:SampleRate => 48000,
|
68
|
+
:BitRate => 320
|
69
|
+
},
|
70
|
+
|
71
|
+
'MP3 44k 128kbps' => {
|
72
|
+
:FileFormat => :MP3,
|
73
|
+
:SampleRate => 44100,
|
74
|
+
:BitRate => 128
|
75
|
+
}
|
76
|
+
|
77
|
+
}
|
78
|
+
}
|
data/bin/Album.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
#!env ruby
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
4
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'fileutils'
|
8
|
+
require 'MusicMaster/Common'
|
9
|
+
require 'rUtilAnts/Logging'
|
10
|
+
RUtilAnts::Logging::initializeLogging('', '')
|
11
|
+
require 'MusicMaster/ConfLoader'
|
12
|
+
|
13
|
+
module MusicMaster
|
14
|
+
|
15
|
+
# Execute the album
|
16
|
+
#
|
17
|
+
# Parameters:
|
18
|
+
# * *iConf* (<em>map<Symbol,Object></em>): Configuration of the album
|
19
|
+
def self.execute(iConf)
|
20
|
+
lTracksDir = iConf[:TracksDir]
|
21
|
+
if (!File.exists?(lTracksDir))
|
22
|
+
logErr "Missing directory #{lTracksDir}"
|
23
|
+
raise RuntimeError.new("Missing directory #{lTracksDir}")
|
24
|
+
else
|
25
|
+
iConf[:Tracks].each_with_index do |iTrackInfo, iIdxTrack|
|
26
|
+
logInfo "===== Mastering Track #{iIdxTrack}: #{iTrackInfo[:TrackID]} version #{iTrackInfo[:Version]} ====="
|
27
|
+
lAlbumFile = "#{$MusicMasterConf[:Album][:Dir]}/#{iIdxTrack}_#{iTrackInfo[:TrackID]}.wav"
|
28
|
+
lCancel = false
|
29
|
+
if (File.exists?(lAlbumFile))
|
30
|
+
puts "File #{lAlbumFile} already exists. Overwrite it by mastering a new one ? [y='yes']"
|
31
|
+
lCancel = ($stdin.gets.chomp != 'y')
|
32
|
+
end
|
33
|
+
if (!lCancel)
|
34
|
+
# Find the last Master file for this Track
|
35
|
+
lMasterFiles = Dir.glob("#{lTracksDir}/#{iTrackInfo[:TrackID]}*/#{iTrackInfo[:Version]}/#{iConf[:TracksFilesSubDir]}#{$MusicMasterConf[:Master][:Dir]}/*.wav")
|
36
|
+
if (lMasterFiles.empty?)
|
37
|
+
logErr "No Master files found for Track #{iTrackInfo[:TrackID]} version #{iTrackInfo[:Version]}"
|
38
|
+
else
|
39
|
+
# Find the last one
|
40
|
+
lFinalMasterFileName = lMasterFiles.sort[-1]
|
41
|
+
logInfo "Found final Master file from Track #{iTrackInfo[:TrackID]} version #{iTrackInfo[:Version]} in #{lFinalMasterFileName}"
|
42
|
+
# Copy it
|
43
|
+
logInfo "Copying Master file to #{lAlbumFile} ..."
|
44
|
+
FileUtils::cp(lFinalMasterFileName, lAlbumFile)
|
45
|
+
if (iTrackInfo[:AdditionalMastering] != nil)
|
46
|
+
lMasterTempDir = "#{$MusicMasterConf[:Album][:TempDir]}/#{iTrackInfo[:TrackID]}.#{iTrackInfo[:Version]}"
|
47
|
+
FileUtils::mkdir_p(lMasterTempDir)
|
48
|
+
MusicMaster::applyProcesses(iTrackInfo[:AdditionalMastering], lAlbumFile, lMasterTempDir)
|
49
|
+
end
|
50
|
+
# Done.
|
51
|
+
logInfo "Setting file #{iIdxTrack} for Track #{iTrackInfo[:TrackID]} from #{lAlbumFile}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
logInfo ''
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
rErrorCode = 0
|
62
|
+
lConfFile = ARGV[0]
|
63
|
+
if (lConfFile == nil)
|
64
|
+
logErr 'Usage: Album <ConfFile>'
|
65
|
+
rErrorCode = 1
|
66
|
+
elsif (!File.exists?(lConfFile))
|
67
|
+
logErr "File #{lConfFile} does not exist."
|
68
|
+
rErrorCode = 2
|
69
|
+
else
|
70
|
+
MusicMaster::parsePlugins
|
71
|
+
FileUtils::mkdir_p($MusicMasterConf[:Album][:Dir])
|
72
|
+
FileUtils::mkdir_p($MusicMasterConf[:Album][:TempDir])
|
73
|
+
lConf = nil
|
74
|
+
File.open(lConfFile, 'r') do |iFile|
|
75
|
+
lConf = eval(iFile.read)
|
76
|
+
end
|
77
|
+
MusicMaster::execute(lConf)
|
78
|
+
logInfo "===== Album finished in #{$MusicMasterConf[:Album][:Dir]}"
|
79
|
+
end
|
80
|
+
|
81
|
+
exit rErrorCode
|
data/bin/AnalyzeAlbum.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
#!env ruby
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
4
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'fileutils'
|
8
|
+
require 'MusicMaster/Common'
|
9
|
+
require 'rUtilAnts/Logging'
|
10
|
+
RUtilAnts::Logging::initializeLogging('', '')
|
11
|
+
require 'MusicMaster/ConfLoader'
|
12
|
+
|
13
|
+
module MusicMaster
|
14
|
+
|
15
|
+
# Execute the album
|
16
|
+
#
|
17
|
+
# Parameters:
|
18
|
+
# * *iConf* (<em>map<Symbol,Object></em>): Configuration of the album
|
19
|
+
def self.execute(iConf)
|
20
|
+
lTracksDir = iConf[:TracksDir]
|
21
|
+
if (!File.exists?(lTracksDir))
|
22
|
+
logErr "Missing directory #{lTracksDir}"
|
23
|
+
raise RuntimeError.new("Missing directory #{lTracksDir}")
|
24
|
+
else
|
25
|
+
# Analyze results, per Track
|
26
|
+
lAnalyzeResults = []
|
27
|
+
iConf[:Tracks].each_with_index do |iTrackInfo, iIdxTrack|
|
28
|
+
lTrackFileName = "#{$MusicMasterConf[:Album][:Dir]}/#{iIdxTrack}_#{iTrackInfo[:TrackID]}.wav"
|
29
|
+
MusicMaster::wsk(lTrackFileName, 'Dummy.wav', 'Analyze')
|
30
|
+
File.unlink('Dummy.wav')
|
31
|
+
File.open('analyze.result', 'rb') do |iFile|
|
32
|
+
lAnalyzeResults << Marshal.load(iFile.read)
|
33
|
+
end
|
34
|
+
File.unlink('analyze.result')
|
35
|
+
end
|
36
|
+
# Display analyze results
|
37
|
+
logInfo ''
|
38
|
+
logInfo '===== Analyze results:'
|
39
|
+
iConf[:Tracks].each_with_index do |iTrackInfo, iIdxTrack|
|
40
|
+
lStrDBRMSValues = lAnalyzeResults[iIdxTrack][:DBRMSValues].map do |iValue|
|
41
|
+
next sprintf('%.2f', iValue)
|
42
|
+
end
|
43
|
+
logInfo "[#{iIdxTrack} - #{iTrackInfo[:TrackID]}]: RMS=(#{lStrDBRMSValues.join('db, ')}db) Max=#{sprintf('%.2f', lAnalyzeResults[iIdxTrack][:DBAbsMaxValue])}db Length=#{sprintf('%.2f', lAnalyzeResults[iIdxTrack][:DataLength])}s"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
rErrorCode = 0
|
51
|
+
lConfFile = ARGV[0]
|
52
|
+
if (lConfFile == nil)
|
53
|
+
logErr 'Usage: AnalyzeAlbum <ConfFile>'
|
54
|
+
rErrorCode = 1
|
55
|
+
elsif (!File.exists?(lConfFile))
|
56
|
+
logErr "File #{lConfFile} does not exist."
|
57
|
+
rErrorCode = 2
|
58
|
+
else
|
59
|
+
lConf = nil
|
60
|
+
File.open(lConfFile, 'r') do |iFile|
|
61
|
+
lConf = eval(iFile.read)
|
62
|
+
end
|
63
|
+
MusicMaster::execute(lConf)
|
64
|
+
end
|
65
|
+
|
66
|
+
exit rErrorCode
|
data/bin/DBConvert.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!env ruby
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
4
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
5
|
+
#++
|
6
|
+
|
7
|
+
def val2db(iRatio)
|
8
|
+
if (iRatio == 0)
|
9
|
+
return -1.0/0
|
10
|
+
else
|
11
|
+
return (6*Math.log(iRatio))/Math.log(2.0)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def db2val(iDB)
|
16
|
+
return 2**(iDB/6)
|
17
|
+
end
|
18
|
+
|
19
|
+
lArg = ARGV[0]
|
20
|
+
|
21
|
+
if (lArg == nil)
|
22
|
+
puts 'Usage: DBConvert.rb <Value>'
|
23
|
+
puts ' <Value>: Either a ratio (0.43) or a db value (4.1db)'
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
|
27
|
+
lMatch = lArg.match(/^(.*)db$/)
|
28
|
+
if (lMatch == nil)
|
29
|
+
# The argument is a ratio
|
30
|
+
lRatio = lArg.to_f
|
31
|
+
puts "#{lRatio} = #{val2db(lRatio)}db"
|
32
|
+
else
|
33
|
+
lDB = lArg.to_f
|
34
|
+
puts "#{lDB}db = #{db2val(lDB)}"
|
35
|
+
end
|
36
|
+
|
data/bin/Deliver.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#!env ruby
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
4
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'MusicMaster/Common'
|
8
|
+
require 'rUtilAnts/Logging'
|
9
|
+
RUtilAnts::Logging::initializeLogging('', '')
|
10
|
+
require 'MusicMaster/ConfLoader'
|
11
|
+
|
12
|
+
module MusicMaster
|
13
|
+
|
14
|
+
# Execute the delivery
|
15
|
+
#
|
16
|
+
# Parameters:
|
17
|
+
# * *iWaveFile* (_String_): Wave file to deliver
|
18
|
+
def self.execute(iWaveFile)
|
19
|
+
lRealBaseName = File.basename(iWaveFile)[0..-5]
|
20
|
+
MusicMaster::src(iWaveFile, "#{$MusicMasterConf[:Deliver][:Dir]}/#{lRealBaseName}_96_24.wav", :SampleRate => 96000)
|
21
|
+
MusicMaster::src(iWaveFile, "#{$MusicMasterConf[:Deliver][:Dir]}/#{lRealBaseName}_48_24.wav", :SampleRate => 48000)
|
22
|
+
MusicMaster::src(iWaveFile, "#{$MusicMasterConf[:Deliver][:Dir]}/#{lRealBaseName}_44_16.wav", :SampleRate => 44100, :BitDepth => 16, :Dither => true)
|
23
|
+
# TODO: Deliver MP3 files too
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
rErrorCode = 0
|
29
|
+
lWaveFile = ARGV[0]
|
30
|
+
if (lWaveFile == nil)
|
31
|
+
logErr 'Please specify the WAVE file.'
|
32
|
+
rErrorCode = 1
|
33
|
+
elsif (!File.exists?(lWaveFile))
|
34
|
+
logErr "File #{lWaveFile} does not exist."
|
35
|
+
rErrorCode = 2
|
36
|
+
else
|
37
|
+
FileUtils::mkdir_p($MusicMasterConf[:Deliver][:Dir])
|
38
|
+
MusicMaster::execute(lWaveFile)
|
39
|
+
logInfo "===== Delivery finished in #{$MusicMasterConf[:Deliver][:Dir]}"
|
40
|
+
end
|
41
|
+
|
42
|
+
exit rErrorCode
|
data/bin/DeliverAlbum.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!env ruby
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
4
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'MusicMaster/Common'
|
8
|
+
require 'rUtilAnts/Logging'
|
9
|
+
RUtilAnts::Logging::initializeLogging('', '')
|
10
|
+
require 'MusicMaster/ConfLoader'
|
11
|
+
|
12
|
+
module MusicMaster
|
13
|
+
|
14
|
+
# Execute the delivery of the album
|
15
|
+
#
|
16
|
+
# Parameters:
|
17
|
+
# * *iConf* (<em>map<Symbol,Object></em>): Configuration of the album
|
18
|
+
def self.execute(iConf)
|
19
|
+
lDeliveries = iConf[:Deliveries]
|
20
|
+
if (lDeliveries == nil)
|
21
|
+
logWarn 'Configuration does not specify any delivery. Nothing to deliver.'
|
22
|
+
else
|
23
|
+
lTracksDir = iConf[:TracksDir]
|
24
|
+
if (!File.exists?(lTracksDir))
|
25
|
+
logErr "Missing directory #{lTracksDir}"
|
26
|
+
raise RuntimeError.new("Missing directory #{lTracksDir}")
|
27
|
+
else
|
28
|
+
iConf[:Tracks].each_with_index do |iTrackInfo, iIdxTrack|
|
29
|
+
lBaseFileName = "#{iIdxTrack}_#{iTrackInfo[:TrackID]}"
|
30
|
+
lSourceFile = "#{$MusicMasterConf[:Album][:Dir]}/#{lBaseFileName}.wav"
|
31
|
+
if (!File.exists?(lSourceFile))
|
32
|
+
logErr "Missing file #{lSourceFile}"
|
33
|
+
else
|
34
|
+
lDeliveries.each do |iDeliveryName, iDeliveryConf|
|
35
|
+
lExt = 'wav'
|
36
|
+
if ((iDeliveryConf[:FileFormat] != nil) and
|
37
|
+
(iDeliveryConf[:FileFormat] == :MP3))
|
38
|
+
lExt = 'mp3'
|
39
|
+
end
|
40
|
+
MusicMaster::src(lSourceFile, "#{$MusicMasterConf[:AlbumDeliver][:Dir]}/#{iDeliveryName}/#{lBaseFileName}.#{lExt}", iDeliveryConf)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
rErrorCode = 0
|
51
|
+
lConfFile = ARGV[0]
|
52
|
+
if (lConfFile == nil)
|
53
|
+
logErr 'Usage: DeliverAlbum <ConfFile>'
|
54
|
+
rErrorCode = 1
|
55
|
+
elsif (!File.exists?(lConfFile))
|
56
|
+
logErr "File #{lConfFile} does not exist."
|
57
|
+
rErrorCode = 2
|
58
|
+
else
|
59
|
+
FileUtils::mkdir_p($MusicMasterConf[:AlbumDeliver][:Dir])
|
60
|
+
lConf = nil
|
61
|
+
File.open(lConfFile, 'r') do |iFile|
|
62
|
+
lConf = eval(iFile.read)
|
63
|
+
end
|
64
|
+
MusicMaster::execute(lConf)
|
65
|
+
logInfo "===== Album delivered in #{$MusicMasterConf[:AlbumDeliver][:Dir]}"
|
66
|
+
end
|
67
|
+
|
68
|
+
exit rErrorCode
|
data/bin/Fct2Wave.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!env ruby
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
4
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'fileutils'
|
8
|
+
require 'MusicMaster/Common'
|
9
|
+
require 'rUtilAnts/Logging'
|
10
|
+
RUtilAnts::Logging::initializeLogging('', '')
|
11
|
+
require 'MusicMaster/ConfLoader'
|
12
|
+
|
13
|
+
module MusicMaster
|
14
|
+
|
15
|
+
# Execute the mastering
|
16
|
+
#
|
17
|
+
# Parameters:
|
18
|
+
# * *iConf* (<em>map<Symbol,Object></em>): Configuration of the master
|
19
|
+
# * *iWaveFile* (_String_): Wave file to master
|
20
|
+
# Return:
|
21
|
+
# * _String_: Name of the Wave file containing the result
|
22
|
+
def self.execute(iConf, iWaveFile)
|
23
|
+
rWaveFileToProcess = "#{$MusicMasterConf[:Master][:Dir]}/#{File.basename(iWaveFile)}"
|
24
|
+
|
25
|
+
logInfo 'Copying Master file ...'
|
26
|
+
FileUtils::cp(iWaveFile, rWaveFileToProcess)
|
27
|
+
# Execute each step of the mastering to the wave file
|
28
|
+
if (iConf[:Mastering] != nil)
|
29
|
+
self.applyProcesses(iConf[:Mastering], rWaveFileToProcess, $MusicMasterConf[:Master][:Dir])
|
30
|
+
end
|
31
|
+
|
32
|
+
return rWaveFileToProcess
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
rErrorCode = 0
|
38
|
+
lFctFile, lInputWaveFile, lOutputWaveFile, lUnitDB = ARGV[0..4]
|
39
|
+
if ((lFctFile == nil) or
|
40
|
+
(lInputWaveFile == nil) or
|
41
|
+
(lOutputWaveFile == nil))
|
42
|
+
logErr 'Usage: Master <FctFile> <InputWaveFile> <OutputWaveFile> [--unitdb]'
|
43
|
+
rErrorCode = 1
|
44
|
+
elsif (!File.exists?(lFctFile))
|
45
|
+
logErr "File #{lFctFile} does not exist."
|
46
|
+
rErrorCode = 2
|
47
|
+
elsif (!File.exists?(lInputWaveFile))
|
48
|
+
logErr "File #{lInputWaveFile} does not exist."
|
49
|
+
rErrorCode = 3
|
50
|
+
else
|
51
|
+
lStrUnitDB = '0'
|
52
|
+
if (lUnitDB == '--unitdb')
|
53
|
+
lStrUnitDB = '1'
|
54
|
+
end
|
55
|
+
MusicMaster::wsk(lInputWaveFile, lOutputWaveFile, 'DrawFct', "--function \"#{lFctFile}\" --unitdb #{lStrUnitDB}")
|
56
|
+
end
|
57
|
+
|
58
|
+
exit rErrorCode
|
data/bin/Master.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
#!env ruby
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
4
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'fileutils'
|
8
|
+
require 'MusicMaster/Common'
|
9
|
+
require 'rUtilAnts/Logging'
|
10
|
+
RUtilAnts::Logging::initializeLogging('', '')
|
11
|
+
require 'MusicMaster/ConfLoader'
|
12
|
+
|
13
|
+
module MusicMaster
|
14
|
+
|
15
|
+
# Execute the mastering
|
16
|
+
#
|
17
|
+
# Parameters:
|
18
|
+
# * *iConf* (<em>map<Symbol,Object></em>): Configuration of the master
|
19
|
+
# * *iWaveFile* (_String_): Wave file to master
|
20
|
+
# Return:
|
21
|
+
# * _String_: Name of the Wave file containing the result
|
22
|
+
def self.execute(iConf, iWaveFile)
|
23
|
+
rWaveFileToProcess = "#{$MusicMasterConf[:Master][:Dir]}/#{File.basename(iWaveFile)}"
|
24
|
+
|
25
|
+
logInfo 'Copying Master file ...'
|
26
|
+
FileUtils::cp(iWaveFile, rWaveFileToProcess)
|
27
|
+
# Execute each step of the mastering to the wave file
|
28
|
+
if (iConf[:Mastering] != nil)
|
29
|
+
self.applyProcesses(iConf[:Mastering], rWaveFileToProcess, $MusicMasterConf[:Master][:Dir])
|
30
|
+
end
|
31
|
+
|
32
|
+
return rWaveFileToProcess
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
rErrorCode = 0
|
38
|
+
lConfFile, lWaveFile = ARGV[0..1]
|
39
|
+
if ((lConfFile == nil) or
|
40
|
+
(lWaveFile == nil))
|
41
|
+
logErr 'Usage: Master <ConfFile> <WaveFile>'
|
42
|
+
rErrorCode = 1
|
43
|
+
elsif (!File.exists?(lConfFile))
|
44
|
+
logErr "File #{lConfFile} does not exist."
|
45
|
+
rErrorCode = 2
|
46
|
+
elsif (!File.exists?(lWaveFile))
|
47
|
+
logErr "File #{lWaveFile} does not exist."
|
48
|
+
rErrorCode = 3
|
49
|
+
else
|
50
|
+
MusicMaster::parsePlugins
|
51
|
+
FileUtils::mkdir_p($MusicMasterConf[:Master][:Dir])
|
52
|
+
lConf = nil
|
53
|
+
File.open(lConfFile, 'r') do |iFile|
|
54
|
+
lConf = eval(iFile.read)
|
55
|
+
end
|
56
|
+
lFinalWave = MusicMaster::execute(lConf, lWaveFile)
|
57
|
+
logInfo "===== Mastering finished in #{lFinalWave}"
|
58
|
+
end
|
59
|
+
|
60
|
+
exit rErrorCode
|
data/bin/Mix.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
#!env ruby
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
4
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'MusicMaster/Common'
|
8
|
+
require 'rUtilAnts/Logging'
|
9
|
+
RUtilAnts::Logging::initializeLogging('', '')
|
10
|
+
require 'MusicMaster/ConfLoader'
|
11
|
+
|
12
|
+
module MusicMaster
|
13
|
+
|
14
|
+
# Execute the Mix
|
15
|
+
#
|
16
|
+
# Parameters:
|
17
|
+
# * *iConfig* (<em>map<Symbol,Object></em>): The Mix configuration
|
18
|
+
# Return:
|
19
|
+
# * _String_: The resulting mix file
|
20
|
+
def self.execute(iConfig)
|
21
|
+
rPerformMixFile = nil
|
22
|
+
|
23
|
+
lMixInputFile = nil
|
24
|
+
lLstMixFiles = []
|
25
|
+
lMissingFiles = []
|
26
|
+
iConfig[:MixFiles].each do |iMixFileInfo|
|
27
|
+
if (!File.exists?(iMixFileInfo[:FileName]))
|
28
|
+
logErr "File #{iMixFileInfo[:FileName]} does not exist."
|
29
|
+
lMissingFiles << iMixFileInfo[:FileName]
|
30
|
+
else
|
31
|
+
lResultFileName = executeOperations(iMixFileInfo[:FileName], iMixFileInfo[:Operations])
|
32
|
+
if (lMixInputFile == nil)
|
33
|
+
lMixInputFile = lResultFileName
|
34
|
+
else
|
35
|
+
lLstMixFiles << lResultFileName
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
if (!lMissingFiles.empty?)
|
40
|
+
logErr "Mix will not be performed as some files were missing: #{lMissingFiles.join(', ')}"
|
41
|
+
else
|
42
|
+
if (lLstMixFiles.empty?)
|
43
|
+
logInfo "Single perform file to mix: #{lMixInputFile}"
|
44
|
+
rPerformMixFile = lMixInputFile
|
45
|
+
else
|
46
|
+
rPerformMixFile = "#{$MusicMasterConf[:Mix][:TempDir]}/Perform.Mix.wav"
|
47
|
+
wsk(lMixInputFile, rPerformMixFile, 'Mix', "--files \"#{lLstMixFiles.join('|1|')}|1\" ")
|
48
|
+
end
|
49
|
+
logInfo "Perform mix result in #{rPerformMixFile}"
|
50
|
+
end
|
51
|
+
|
52
|
+
return rPerformMixFile
|
53
|
+
end
|
54
|
+
|
55
|
+
# Execute operations on a Wave file, then give back the resulting file
|
56
|
+
#
|
57
|
+
# Parameters:
|
58
|
+
# * *iInputFile* (_String_): The input wave file
|
59
|
+
# * *iOperations* (<em>list<[String,String]></em>): The list of operations to execute: [Action,Parameters].
|
60
|
+
# Return:
|
61
|
+
# * _String_: The resulting file name
|
62
|
+
def self.executeOperations(iInputFile, iOperations)
|
63
|
+
rResultFileName = iInputFile
|
64
|
+
|
65
|
+
lBaseName = "#{$MusicMasterConf[:Mix][:TempDir]}/#{File.basename(iInputFile)[0..-5]}"
|
66
|
+
iOperations.each_with_index do |iOperationInfo, iIdxOperation|
|
67
|
+
iAction, iParameters = iOperationInfo
|
68
|
+
lInputFileName = rResultFileName.clone
|
69
|
+
rResultFileName = "#{lBaseName}.#{iIdxOperation}.#{iAction}.wav"
|
70
|
+
# Call wsk if the file does not exist already
|
71
|
+
if (!File.exists?(rResultFileName))
|
72
|
+
wsk(lInputFileName, rResultFileName, iAction, iParameters)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
return rResultFileName
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
rErrorCode = 0
|
82
|
+
lConfigFile = ARGV[0]
|
83
|
+
if (lConfigFile == nil)
|
84
|
+
logErr 'Please specify the configuration file.'
|
85
|
+
rErrorCode = 1
|
86
|
+
elsif (!File.exists?(lConfigFile))
|
87
|
+
logErr "File #{lConfigFile} does not exist."
|
88
|
+
rErrorCode = 2
|
89
|
+
else
|
90
|
+
FileUtils::mkdir_p($MusicMasterConf[:Mix][:TempDir])
|
91
|
+
lConfig = nil
|
92
|
+
File.open(lConfigFile, 'r') do |iFile|
|
93
|
+
lConfig = eval(iFile.read)
|
94
|
+
end
|
95
|
+
lMixFile = MusicMaster::execute(lConfig)
|
96
|
+
logInfo "===== Mix saved in #{lMixFile}"
|
97
|
+
end
|
98
|
+
|
99
|
+
exit rErrorCode
|