WaveSwissKnife 0.0.1.20101110-x86-cygwin
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +1 -0
- data/ChangeLog +5 -0
- data/Credits +3 -0
- data/LICENSE +31 -0
- data/README +18 -0
- data/ReleaseInfo +8 -0
- data/TODO +2 -0
- data/bin/WSK.rb +14 -0
- data/ext/WSK/AnalyzeUtils/AnalyzeUtils.c +272 -0
- data/ext/WSK/AnalyzeUtils/AnalyzeUtils.o +0 -0
- data/ext/WSK/AnalyzeUtils/AnalyzeUtils.so +0 -0
- data/ext/WSK/AnalyzeUtils/Makefile +149 -0
- data/ext/WSK/AnalyzeUtils/build.rb +18 -0
- data/ext/WSK/ArithmUtils/ArithmUtils.c +862 -0
- data/ext/WSK/ArithmUtils/ArithmUtils.o +0 -0
- data/ext/WSK/ArithmUtils/ArithmUtils.so +0 -0
- data/ext/WSK/ArithmUtils/Makefile +149 -0
- data/ext/WSK/ArithmUtils/build.rb +20 -0
- data/ext/WSK/FFTUtils/FFTUtils.c +662 -0
- data/ext/WSK/FFTUtils/FFTUtils.o +0 -0
- data/ext/WSK/FFTUtils/FFTUtils.so +0 -0
- data/ext/WSK/FFTUtils/Makefile +149 -0
- data/ext/WSK/FFTUtils/build.rb +20 -0
- data/ext/WSK/FunctionUtils/FunctionUtils.c +182 -0
- data/ext/WSK/FunctionUtils/FunctionUtils.o +0 -0
- data/ext/WSK/FunctionUtils/FunctionUtils.so +0 -0
- data/ext/WSK/FunctionUtils/Makefile +149 -0
- data/ext/WSK/FunctionUtils/build.rb +20 -0
- data/ext/WSK/SilentUtils/Makefile +149 -0
- data/ext/WSK/SilentUtils/SilentUtils.c +431 -0
- data/ext/WSK/SilentUtils/SilentUtils.o +0 -0
- data/ext/WSK/SilentUtils/SilentUtils.so +0 -0
- data/ext/WSK/SilentUtils/build.rb +18 -0
- data/ext/WSK/VolumeUtils/Makefile +149 -0
- data/ext/WSK/VolumeUtils/VolumeUtils.c +494 -0
- data/ext/WSK/VolumeUtils/VolumeUtils.o +0 -0
- data/ext/WSK/VolumeUtils/VolumeUtils.so +0 -0
- data/ext/WSK/VolumeUtils/build.rb +20 -0
- data/lib/WSK/Actions/Analyze.rb +176 -0
- data/lib/WSK/Actions/ApplyMap.desc.rb +15 -0
- data/lib/WSK/Actions/ApplyMap.rb +57 -0
- data/lib/WSK/Actions/ApplyVolumeFct.desc.rb +30 -0
- data/lib/WSK/Actions/ApplyVolumeFct.rb +72 -0
- data/lib/WSK/Actions/Compare.desc.rb +25 -0
- data/lib/WSK/Actions/Compare.rb +238 -0
- data/lib/WSK/Actions/ConstantCompare.desc.rb +20 -0
- data/lib/WSK/Actions/ConstantCompare.rb +61 -0
- data/lib/WSK/Actions/Cut.desc.rb +20 -0
- data/lib/WSK/Actions/Cut.rb +60 -0
- data/lib/WSK/Actions/CutFirstSignal.desc.rb +25 -0
- data/lib/WSK/Actions/CutFirstSignal.rb +72 -0
- data/lib/WSK/Actions/DCShifter.desc.rb +15 -0
- data/lib/WSK/Actions/DCShifter.rb +67 -0
- data/lib/WSK/Actions/DrawFct.desc.rb +20 -0
- data/lib/WSK/Actions/DrawFct.rb +59 -0
- data/lib/WSK/Actions/FFT.rb +104 -0
- data/lib/WSK/Actions/GenAllValues.rb +67 -0
- data/lib/WSK/Actions/GenConstant.desc.rb +20 -0
- data/lib/WSK/Actions/GenConstant.rb +56 -0
- data/lib/WSK/Actions/GenSawtooth.rb +57 -0
- data/lib/WSK/Actions/GenSine.desc.rb +20 -0
- data/lib/WSK/Actions/GenSine.rb +73 -0
- data/lib/WSK/Actions/Identity.rb +43 -0
- data/lib/WSK/Actions/Mix.desc.rb +15 -0
- data/lib/WSK/Actions/Mix.rb +149 -0
- data/lib/WSK/Actions/Multiply.desc.rb +15 -0
- data/lib/WSK/Actions/Multiply.rb +73 -0
- data/lib/WSK/Actions/NoiseGate.desc.rb +35 -0
- data/lib/WSK/Actions/NoiseGate.rb +129 -0
- data/lib/WSK/Actions/SilenceInserter.desc.rb +20 -0
- data/lib/WSK/Actions/SilenceInserter.rb +87 -0
- data/lib/WSK/Actions/SilenceRemover.desc.rb +30 -0
- data/lib/WSK/Actions/SilenceRemover.rb +74 -0
- data/lib/WSK/Actions/VolumeProfile.desc.rb +35 -0
- data/lib/WSK/Actions/VolumeProfile.rb +63 -0
- data/lib/WSK/Common.rb +292 -0
- data/lib/WSK/FFT.rb +527 -0
- data/lib/WSK/Functions.rb +770 -0
- data/lib/WSK/Launcher.rb +216 -0
- data/lib/WSK/Maps.rb +29 -0
- data/lib/WSK/Model/CachedBufferReader.rb +151 -0
- data/lib/WSK/Model/Header.rb +133 -0
- data/lib/WSK/Model/InputData.rb +193 -0
- data/lib/WSK/Model/RawReader.rb +78 -0
- data/lib/WSK/Model/WaveReader.rb +91 -0
- data/lib/WSK/OutputInterfaces/DirectStream.rb +146 -0
- data/lib/WSK/RIFFReader.rb +60 -0
- metadata +151 -0
@@ -0,0 +1,61 @@
|
|
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
|
+
module WSK
|
7
|
+
|
8
|
+
module Actions
|
9
|
+
|
10
|
+
class ConstantCompare
|
11
|
+
|
12
|
+
include WSK::Common
|
13
|
+
|
14
|
+
# Get the number of samples that will be written.
|
15
|
+
# This is called before execute, as it is needed to write the output file.
|
16
|
+
# It is possible to give a majoration: it will be padded with silence.
|
17
|
+
#
|
18
|
+
# Parameters:
|
19
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
20
|
+
# Return:
|
21
|
+
# * _Integer_: The number of samples to be written
|
22
|
+
def getNbrSamples(iInputData)
|
23
|
+
return 0
|
24
|
+
end
|
25
|
+
|
26
|
+
# Execute
|
27
|
+
#
|
28
|
+
# Parameters:
|
29
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
30
|
+
# * *oOutputData* (_Object_): The output data to fill
|
31
|
+
# Return:
|
32
|
+
# * _Exception_: An error, or nil if success
|
33
|
+
def execute(iInputData, oOutputData)
|
34
|
+
if (iInputData.NbrSamples != @NbrSamples)
|
35
|
+
logErr "Input data has #{iInputData.NbrSamples} samples. It should be #{@NbrSamples}"
|
36
|
+
end
|
37
|
+
lRawSample = iInputData.Header.getEncodedString([@Value]*iInputData.Header.NbrChannels)
|
38
|
+
lCompareBuffer = nil
|
39
|
+
lNbrSamplesProcessed = 0
|
40
|
+
iInputData.eachRawBuffer do |iRawBuffer, iNbrSamples, iNbrChannels|
|
41
|
+
if ((lCompareBuffer == nil) or
|
42
|
+
(lCompareBuffer.size != iRawBuffer.size))
|
43
|
+
# Create the comparison buffer
|
44
|
+
lCompareBuffer = lRawSample*iNbrSamples
|
45
|
+
end
|
46
|
+
if (lCompareBuffer != iRawBuffer)
|
47
|
+
logErr "Differences found between samples #{lNbrSamplesProcessed} and #{lNbrSamplesProcessed+iNbrSamples-1}"
|
48
|
+
end
|
49
|
+
lNbrSamplesProcessed += iNbrSamples
|
50
|
+
$stdout.write("#{(lNbrSamplesProcessed*100)/iInputData.NbrSamples} %\015")
|
51
|
+
$stdout.flush
|
52
|
+
end
|
53
|
+
|
54
|
+
return nil
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,20 @@
|
|
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
|
+
:OutputInterface => 'DirectStream',
|
8
|
+
:Options => {
|
9
|
+
:BeginSample => [
|
10
|
+
'--begin <BeginSample>', String,
|
11
|
+
'<BeginSample>: Index of sample to begin with [default = 0]. Can be specified in float seconds (ie. 12.3s).',
|
12
|
+
'Specify the first sample to write'
|
13
|
+
],
|
14
|
+
:EndSample => [
|
15
|
+
'--end <EndSample>', String,
|
16
|
+
'<EndSample>: Index of sample to end with [default = 256]. Can be specified in float seconds (ie. 12.3s).',
|
17
|
+
'Specify the last sample to write'
|
18
|
+
]
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,60 @@
|
|
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
|
+
module WSK
|
7
|
+
|
8
|
+
module Actions
|
9
|
+
|
10
|
+
class Cut
|
11
|
+
|
12
|
+
include WSK::Common
|
13
|
+
|
14
|
+
# Get the number of samples that will be written.
|
15
|
+
# This is called before execute, as it is needed to write the output file.
|
16
|
+
# It is possible to give a majoration: it will be padded with silence.
|
17
|
+
#
|
18
|
+
# Parameters:
|
19
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
20
|
+
# Return:
|
21
|
+
# * _Integer_: The number of samples to be written
|
22
|
+
def getNbrSamples(iInputData)
|
23
|
+
@IdxBeginSample = readDuration(@BeginSample, iInputData.Header.SampleRate)
|
24
|
+
@IdxEndSample = readDuration(@EndSample, iInputData.Header.SampleRate)
|
25
|
+
|
26
|
+
return @IdxEndSample-@IdxBeginSample+1
|
27
|
+
end
|
28
|
+
|
29
|
+
# Execute
|
30
|
+
#
|
31
|
+
# Parameters:
|
32
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
33
|
+
# * *oOutputData* (_Object_): The output data to fill
|
34
|
+
# Return:
|
35
|
+
# * _Exception_: An error, or nil if success
|
36
|
+
def execute(iInputData, oOutputData)
|
37
|
+
lChannelsSampleSize = (iInputData.Header.NbrChannels*iInputData.Header.NbrBitsPerSample)/8
|
38
|
+
lIdxFirstSample = @IdxBeginSample
|
39
|
+
iInputData.eachRawBuffer(@IdxBeginSample) do |iInputRawBuffer, iNbrSamples, iNbrChannels|
|
40
|
+
# If the end sample is in this buffer, write only up to it
|
41
|
+
if (@IdxEndSample < lIdxFirstSample + iNbrSamples - 1)
|
42
|
+
oOutputData.pushRawBuffer(iInputRawBuffer[0..(@IdxEndSample-lIdxFirstSample+1)*lChannelsSampleSize-1])
|
43
|
+
else
|
44
|
+
oOutputData.pushRawBuffer(iInputRawBuffer)
|
45
|
+
end
|
46
|
+
if (@IdxEndSample < lIdxFirstSample + iNbrSamples)
|
47
|
+
# Nothing left to write
|
48
|
+
break
|
49
|
+
end
|
50
|
+
lIdxFirstSample += iNbrSamples
|
51
|
+
end
|
52
|
+
|
53
|
+
return nil
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,25 @@
|
|
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
|
+
:OutputInterface => 'DirectStream',
|
8
|
+
:Options => {
|
9
|
+
:SilenceThreshold => [
|
10
|
+
'--silencethreshold <SilenceThreshold>', String,
|
11
|
+
'<SilenceThreshold>: Threshold to use to identify silent parts [default = 0]. It is possible to specify several values, for each channel, sperated with | (ie. 34|35). It is also possible to specify a range instead of a threshold with , (ie. -128,126 or -128,126|-127,132)',
|
12
|
+
'Specify the silence threshold'
|
13
|
+
],
|
14
|
+
:NoiseFFTFileName => [
|
15
|
+
'--noisefft <FFTFile>', String,
|
16
|
+
'<FFTFile>: File containing the FFT profile of the reference noise. Can be set to \'none\' if no file.',
|
17
|
+
'This is used to compare potential noise profile with the real noise profile.'
|
18
|
+
],
|
19
|
+
:SilenceMin => [
|
20
|
+
'--silencemin <SilenceDuration>', String,
|
21
|
+
'<SilenceDuration>: Silence duration in samples or in float seconds (ie. 234 or 25.3s).',
|
22
|
+
'Specify the minimum duration a silent part must have to be interpreted as a silence.'
|
23
|
+
],
|
24
|
+
}
|
25
|
+
}
|
@@ -0,0 +1,72 @@
|
|
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
|
+
module WSK
|
7
|
+
|
8
|
+
module Actions
|
9
|
+
|
10
|
+
class CutFirstSignal
|
11
|
+
|
12
|
+
include WSK::Common
|
13
|
+
include WSK::FFT
|
14
|
+
|
15
|
+
# Get the number of samples that will be written.
|
16
|
+
# This is called before execute, as it is needed to write the output file.
|
17
|
+
# It is possible to give a majoration: it will be padded with silence.
|
18
|
+
#
|
19
|
+
# Parameters:
|
20
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
21
|
+
# Return:
|
22
|
+
# * _Integer_: The number of samples to be written
|
23
|
+
def getNbrSamples(iInputData)
|
24
|
+
@IdxStartSample = 0
|
25
|
+
lSilenceThresholds = readThresholds(@SilenceThreshold, iInputData.Header.NbrChannels)
|
26
|
+
# Find the first signal
|
27
|
+
lIdxSignalSample, lIdxNextAboveThresholds = getNextNonSilentSample(iInputData, 0, lSilenceThresholds, nil, nil, false)
|
28
|
+
if (lIdxSignalSample == nil)
|
29
|
+
logWarn 'No signal found. Keeping the whole file.'
|
30
|
+
else
|
31
|
+
lNoiseFFTMaxDistance, lNoiseFFTProfile = readFFTProfile(@NoiseFFTFileName)
|
32
|
+
lSilenceDuration = readDuration(@SilenceMin, iInputData.Header.SampleRate)
|
33
|
+
lIdxSilenceSample, lSilenceLength, lIdxNextAboveThresholds = getNextSilentSample(iInputData, lIdxSignalSample, lSilenceThresholds, lSilenceDuration, lNoiseFFTProfile, lNoiseFFTMaxDistance, false)
|
34
|
+
if (lIdxSilenceSample == nil)
|
35
|
+
logWarn "No silence found after the signal beginning at #{lIdxSignalSample}. Keeping the whole file."
|
36
|
+
elsif (lSilenceLength == nil)
|
37
|
+
# Find the silence length by parsing following data
|
38
|
+
lIdxNonSilentSample, lIdxNextAboveThresholds = getNextNonSilentSample(iInputData, lIdxSilenceSample+1, lSilenceThresholds, lNoiseFFTProfile, lNoiseFFTMaxDistance, false)
|
39
|
+
if (lIdxNonSilentSample == nil)
|
40
|
+
# The file should be empty
|
41
|
+
@IdxStartSample = iInputData.NbrSamples-1
|
42
|
+
else
|
43
|
+
@IdxStartSample = lIdxNonSilentSample
|
44
|
+
end
|
45
|
+
else
|
46
|
+
@IdxStartSample = lIdxSilenceSample + lSilenceLength
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
return iInputData.NbrSamples-@IdxStartSample
|
51
|
+
end
|
52
|
+
|
53
|
+
# Execute
|
54
|
+
#
|
55
|
+
# Parameters:
|
56
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
57
|
+
# * *oOutputData* (_Object_): The output data to fill
|
58
|
+
# Return:
|
59
|
+
# * _Exception_: An error, or nil if success
|
60
|
+
def execute(iInputData, oOutputData)
|
61
|
+
iInputData.eachRawBuffer(@IdxStartSample) do |iInputRawBuffer, iNbrSamples, iNbrChannels|
|
62
|
+
oOutputData.pushRawBuffer(iInputRawBuffer)
|
63
|
+
end
|
64
|
+
|
65
|
+
return nil
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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
|
+
:OutputInterface => 'DirectStream',
|
8
|
+
:Options => {
|
9
|
+
:Offset => [
|
10
|
+
'--offset <DCOffset>', String,
|
11
|
+
'<DCOffset>: Offset to use for the shift [default = 0]. It is possible to specify several values, for each channel, sperated with | (ie. 34|35).',
|
12
|
+
'Specify the offset'
|
13
|
+
]
|
14
|
+
}
|
15
|
+
}
|
@@ -0,0 +1,67 @@
|
|
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
|
+
module WSK
|
7
|
+
|
8
|
+
module Actions
|
9
|
+
|
10
|
+
class DCShifter
|
11
|
+
|
12
|
+
include WSK::Maps
|
13
|
+
|
14
|
+
# Get the number of samples that will be written.
|
15
|
+
# This is called before execute, as it is needed to write the output file.
|
16
|
+
# It is possible to give a majoration: it will be padded with silence.
|
17
|
+
#
|
18
|
+
# Parameters:
|
19
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
20
|
+
# Return:
|
21
|
+
# * _Integer_: The number of samples to be written
|
22
|
+
def getNbrSamples(iInputData)
|
23
|
+
return iInputData.NbrSamples
|
24
|
+
end
|
25
|
+
|
26
|
+
# Execute
|
27
|
+
#
|
28
|
+
# Parameters:
|
29
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
30
|
+
# * *oOutputData* (_Object_): The output data to fill
|
31
|
+
# Return:
|
32
|
+
# * _Exception_: An error, or nil if success
|
33
|
+
def execute(iInputData, oOutputData)
|
34
|
+
# The offset, per channel
|
35
|
+
# list< Integer >
|
36
|
+
lOffsets = nil
|
37
|
+
if (@Offset.split('|').size == 1)
|
38
|
+
lOffsets = [@Offset.to_i] * iInputData.Header.NbrChannels
|
39
|
+
else
|
40
|
+
lOffsets = @Offset.split('|').map { |iStrValue| iStrValue.to_i }
|
41
|
+
end
|
42
|
+
|
43
|
+
# List of functions to apply, per channel
|
44
|
+
lMaxValue = 2**(iInputData.Header.NbrBitsPerSample-1) - 1
|
45
|
+
lMinValue = -2**(iInputData.Header.NbrBitsPerSample-1)
|
46
|
+
lFunctions = []
|
47
|
+
lOffsets.each do |iOffset|
|
48
|
+
lFunctions << {
|
49
|
+
:FunctionType => WSK::Functions::FCTTYPE_PIECEWISE_LINEAR,
|
50
|
+
:MinValue => lMinValue,
|
51
|
+
:MaxValue => lMaxValue,
|
52
|
+
:Points => {
|
53
|
+
lMinValue => lMinValue + iOffset,
|
54
|
+
lMaxValue => lMaxValue + iOffset
|
55
|
+
}
|
56
|
+
}
|
57
|
+
end
|
58
|
+
applyMapFunctions(iInputData, oOutputData, lFunctions)
|
59
|
+
|
60
|
+
return nil
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,20 @@
|
|
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
|
+
:OutputInterface => 'DirectStream',
|
8
|
+
:Options => {
|
9
|
+
:FctFileName => [
|
10
|
+
'--function <FunctionFileName>', String,
|
11
|
+
'<FunctionFileName>: File containing the function definition',
|
12
|
+
'Specify the function to draw'
|
13
|
+
],
|
14
|
+
:UnitDB => [
|
15
|
+
'--unitdb <Switch>', Integer,
|
16
|
+
'<Switch>: 0 means that units used in the function are ratios. 1 means that units used in the functions are db.',
|
17
|
+
'Specify the unit used in the function'
|
18
|
+
]
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,59 @@
|
|
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
|
+
module WSK
|
7
|
+
|
8
|
+
module Actions
|
9
|
+
|
10
|
+
class DrawFct
|
11
|
+
|
12
|
+
include WSK::Common
|
13
|
+
include WSK::Functions
|
14
|
+
|
15
|
+
# Get the number of samples that will be written.
|
16
|
+
# This is called before execute, as it is needed to write the output file.
|
17
|
+
# It is possible to give a majoration: it will be padded with silence.
|
18
|
+
#
|
19
|
+
# Parameters:
|
20
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
21
|
+
# Return:
|
22
|
+
# * _Integer_: The number of samples to be written
|
23
|
+
def getNbrSamples(iInputData)
|
24
|
+
@Function = WSK::Functions::Function.new
|
25
|
+
@Function.readFromFile(@FctFileName)
|
26
|
+
lMinX, lMinY, lMaxX, lMaxY = @Function.getBounds
|
27
|
+
@NbrSamplesOut = lMaxX.to_i-lMinX.to_i+1
|
28
|
+
|
29
|
+
return @NbrSamplesOut
|
30
|
+
end
|
31
|
+
|
32
|
+
# Execute
|
33
|
+
#
|
34
|
+
# Parameters:
|
35
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
36
|
+
# * *oOutputData* (_Object_): The output data to fill
|
37
|
+
# Return:
|
38
|
+
# * _Exception_: An error, or nil if success
|
39
|
+
def execute(iInputData, oOutputData)
|
40
|
+
rError = nil
|
41
|
+
|
42
|
+
# Then draw it
|
43
|
+
lMaxY = @Function.getBounds[3]
|
44
|
+
if (@UnitDB == 1)
|
45
|
+
lMaxY = (2**(lMaxY.to_f/6)).to_r
|
46
|
+
end
|
47
|
+
lMedianValue = ((2**(iInputData.Header.NbrBitsPerSample-1)-1)/lMaxY).to_i
|
48
|
+
logInfo "Draw function with maximal ratio #{lMaxY.to_f}, using median value #{lMedianValue}"
|
49
|
+
# Take the median value as a fraction of the maximal value
|
50
|
+
@Function.draw(iInputData, oOutputData, 0, @NbrSamplesOut-1, (@UnitDB == 1), lMedianValue)
|
51
|
+
|
52
|
+
return rError
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,104 @@
|
|
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
|
+
module WSK
|
7
|
+
|
8
|
+
module Actions
|
9
|
+
|
10
|
+
class FFT
|
11
|
+
|
12
|
+
include WSK::Common
|
13
|
+
include WSK::FFT
|
14
|
+
|
15
|
+
# Get the number of samples that will be written.
|
16
|
+
# This is called before execute, as it is needed to write the output file.
|
17
|
+
# It is possible to give a majoration: it will be padded with silence.
|
18
|
+
#
|
19
|
+
# Parameters:
|
20
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
21
|
+
# Return:
|
22
|
+
# * _Integer_: The number of samples to be written
|
23
|
+
def getNbrSamples(iInputData)
|
24
|
+
return 0
|
25
|
+
end
|
26
|
+
|
27
|
+
# Execute
|
28
|
+
#
|
29
|
+
# Parameters:
|
30
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
31
|
+
# * *oOutputData* (_Object_): The output data to fill
|
32
|
+
# Return:
|
33
|
+
# * _Exception_: An error, or nil if success
|
34
|
+
def execute(iInputData, oOutputData)
|
35
|
+
|
36
|
+
# 1. Create the whole FFT profile
|
37
|
+
logInfo 'Creating FFT profile ...'
|
38
|
+
# Object that will create the FFT
|
39
|
+
lFFTComputing = FFTComputing.new(false, iInputData.Header)
|
40
|
+
# Parse the data
|
41
|
+
lIdxSample = 0
|
42
|
+
iInputData.eachRawBuffer do |iInputRawBuffer, iNbrSamples, iNbrChannels|
|
43
|
+
lFFTComputing.completeFFT(iInputRawBuffer, iNbrSamples)
|
44
|
+
lIdxSample += iNbrSamples
|
45
|
+
$stdout.write("#{(lIdxSample*100)/iInputData.NbrSamples} %\015")
|
46
|
+
$stdout.flush
|
47
|
+
end
|
48
|
+
# Compute the result
|
49
|
+
require 'WSK/FFTUtils/FFTUtils'
|
50
|
+
lFFTUtils = FFTUtils::FFTUtils.new
|
51
|
+
lFFTProfile = lFFTComputing.getFFTProfile
|
52
|
+
lFFTReferenceProfile = lFFTUtils.createCFFTProfile(lFFTProfile)
|
53
|
+
|
54
|
+
# 2. Compute the distance obtained by comparing this profile with a normal file pass
|
55
|
+
logInfo 'Computing average distance ...'
|
56
|
+
lFFTComputing2 = FFTComputing.new(true, iInputData.Header)
|
57
|
+
lIdxSample = 0
|
58
|
+
lNbrTimes = 0
|
59
|
+
lSumDist = 0
|
60
|
+
while (lIdxSample < iInputData.NbrSamples)
|
61
|
+
# Compute the number of samples needed to have a valid FFT.
|
62
|
+
# Modify this number if it exceeds the range we have
|
63
|
+
lNbrSamplesFFTMax = iInputData.Header.SampleRate/FFTSAMPLE_FREQ
|
64
|
+
lIdxBeginFFTSample = lIdxSample
|
65
|
+
lIdxEndFFTSample = lIdxSample+lNbrSamplesFFTMax-1
|
66
|
+
if (lIdxEndFFTSample >= iInputData.NbrSamples)
|
67
|
+
lIdxEndFFTSample = iInputData.NbrSamples-1
|
68
|
+
end
|
69
|
+
lNbrSamplesFFT = lIdxEndFFTSample-lIdxBeginFFTSample+1
|
70
|
+
# Load an FFT buffer of this
|
71
|
+
lFFTBuffer = ''
|
72
|
+
iInputData.eachRawBuffer(lIdxBeginFFTSample, lIdxEndFFTSample, :NbrSamplesPrefetch => iInputData.NbrSamples-lIdxBeginFFTSample) do |iInputRawBuffer, iNbrSamples, iNbrChannels|
|
73
|
+
lFFTBuffer.concat(iInputRawBuffer)
|
74
|
+
end
|
75
|
+
# Compute its FFT profile
|
76
|
+
lFFTComputing2.resetData
|
77
|
+
lFFTComputing2.completeFFT(lFFTBuffer, lNbrSamplesFFT)
|
78
|
+
lSumDist += lFFTUtils.distFFTProfiles(lFFTReferenceProfile, lFFTUtils.createCFFTProfile(lFFTComputing2.getFFTProfile), FFTDIST_MAX).abs
|
79
|
+
lNbrTimes += 1
|
80
|
+
lIdxSample = lIdxEndFFTSample+1
|
81
|
+
$stdout.write("#{(lIdxSample*100)/iInputData.NbrSamples} %\015")
|
82
|
+
$stdout.flush
|
83
|
+
end
|
84
|
+
lAverageDist = lSumDist/lNbrTimes
|
85
|
+
logDebug "Average distance with silence: #{lAverageDist}"
|
86
|
+
|
87
|
+
# Display results
|
88
|
+
(FREQINDEX_FIRST..FREQINDEX_LAST).each_with_index do |iIdx, iIdxFreq|
|
89
|
+
logDebug "[#{(440*(2**(iIdx/12.0))).round} Hz]: #{lFFTProfile[2][iIdxFreq].join(', ')}"
|
90
|
+
end
|
91
|
+
|
92
|
+
# Write the result in a file
|
93
|
+
File.open('fft.result', 'wb') do |oFile|
|
94
|
+
oFile.write(Marshal.dump([lAverageDist, lFFTProfile]))
|
95
|
+
end
|
96
|
+
|
97
|
+
return nil
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,67 @@
|
|
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
|
+
module WSK
|
7
|
+
|
8
|
+
module Actions
|
9
|
+
|
10
|
+
class GenAllValues
|
11
|
+
|
12
|
+
MAX_BUFFER_SAMPLES = 65536
|
13
|
+
|
14
|
+
# Get the number of samples that will be written.
|
15
|
+
# This is called before execute, as it is needed to write the output file.
|
16
|
+
# It is possible to give a majoration: it will be padded with silence.
|
17
|
+
#
|
18
|
+
# Parameters:
|
19
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
20
|
+
# Return:
|
21
|
+
# * _Integer_: The number of samples to be written
|
22
|
+
def getNbrSamples(iInputData)
|
23
|
+
@MaxValue = 2**(iInputData.Header.NbrBitsPerSample-1)-1
|
24
|
+
@MinValue = -2**(iInputData.Header.NbrBitsPerSample-1)
|
25
|
+
|
26
|
+
return @MaxValue-@MinValue+1
|
27
|
+
end
|
28
|
+
|
29
|
+
# Execute
|
30
|
+
#
|
31
|
+
# Parameters:
|
32
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
33
|
+
# * *oOutputData* (_Object_): The output data to fill
|
34
|
+
# Return:
|
35
|
+
# * _Exception_: An error, or nil if success
|
36
|
+
def execute(iInputData, oOutputData)
|
37
|
+
# Create buffer
|
38
|
+
lNbrBuffers = ((@MaxValue-@MinValue+1) / MAX_BUFFER_SAMPLES)+1
|
39
|
+
lSizeofLastBuffer = ((@MaxValue-@MinValue+1) % MAX_BUFFER_SAMPLES)
|
40
|
+
lIdxValue = @MinValue
|
41
|
+
logDebug "Will output #{@MaxValue-@MinValue+1} samples in #{lNbrBuffers} buffers."
|
42
|
+
lNbrBuffers.times do |iIdxBuffer|
|
43
|
+
lBuffer = []
|
44
|
+
lSamplesInBuffer = nil
|
45
|
+
if (iIdxBuffer == lNbrBuffers-1)
|
46
|
+
# The last one
|
47
|
+
lSamplesInBuffer = lSizeofLastBuffer
|
48
|
+
else
|
49
|
+
lSamplesInBuffer = MAX_BUFFER_SAMPLES
|
50
|
+
end
|
51
|
+
lSamplesInBuffer.times do |iIdxSampleBuffer|
|
52
|
+
iInputData.Header.NbrChannels.times do |iIdxChannel|
|
53
|
+
lBuffer << lIdxValue
|
54
|
+
end
|
55
|
+
lIdxValue += 1
|
56
|
+
end
|
57
|
+
oOutputData.pushBuffer(lBuffer)
|
58
|
+
end
|
59
|
+
|
60
|
+
return nil
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,20 @@
|
|
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
|
+
:OutputInterface => 'DirectStream',
|
8
|
+
:Options => {
|
9
|
+
:Value => [
|
10
|
+
'--value <Value>', Integer,
|
11
|
+
'<Value>: Constant value to write',
|
12
|
+
'Specify the value to write in the wave file.'
|
13
|
+
],
|
14
|
+
:NbrSamples => [
|
15
|
+
'--nbrsamples <NbrSamples>', Integer,
|
16
|
+
'<NbrSamples>: Number of samples used to write this value',
|
17
|
+
'Specify the number of samples during the value will be written.'
|
18
|
+
]
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,56 @@
|
|
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
|
+
module WSK
|
7
|
+
|
8
|
+
module Actions
|
9
|
+
|
10
|
+
class GenConstant
|
11
|
+
|
12
|
+
MAX_BUFFER_SAMPLES = 65536
|
13
|
+
|
14
|
+
# Get the number of samples that will be written.
|
15
|
+
# This is called before execute, as it is needed to write the output file.
|
16
|
+
# It is possible to give a majoration: it will be padded with silence.
|
17
|
+
#
|
18
|
+
# Parameters:
|
19
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
20
|
+
# Return:
|
21
|
+
# * _Integer_: The number of samples to be written
|
22
|
+
def getNbrSamples(iInputData)
|
23
|
+
return @NbrSamples
|
24
|
+
end
|
25
|
+
|
26
|
+
# Execute
|
27
|
+
#
|
28
|
+
# Parameters:
|
29
|
+
# * *iInputData* (<em>WSK::Model::InputData</em>): The input data
|
30
|
+
# * *oOutputData* (_Object_): The output data to fill
|
31
|
+
# Return:
|
32
|
+
# * _Exception_: An error, or nil if success
|
33
|
+
def execute(iInputData, oOutputData)
|
34
|
+
lRawSample = iInputData.Header.getEncodedString([@Value]*iInputData.Header.NbrChannels)
|
35
|
+
# Write complete buffers
|
36
|
+
lNbrCompleteBuffers = @NbrSamples/MAX_BUFFER_SAMPLES
|
37
|
+
if (lNbrCompleteBuffers > 0)
|
38
|
+
lCompleteRawBuffer = lRawSample*MAX_BUFFER_SAMPLES
|
39
|
+
lNbrCompleteBuffers.times do |iIdx|
|
40
|
+
oOutputData.pushRawBuffer(lCompleteRawBuffer)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
# Write last buffer
|
44
|
+
lLastBufferSize = @NbrSamples % MAX_BUFFER_SAMPLES
|
45
|
+
if (lLastBufferSize > 0)
|
46
|
+
oOutputData.pushRawBuffer(lRawSample*lLastBufferSize)
|
47
|
+
end
|
48
|
+
|
49
|
+
return nil
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|