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.
Files changed (88) hide show
  1. data/AUTHORS +1 -0
  2. data/ChangeLog +5 -0
  3. data/Credits +3 -0
  4. data/LICENSE +31 -0
  5. data/README +18 -0
  6. data/ReleaseInfo +8 -0
  7. data/TODO +2 -0
  8. data/bin/WSK.rb +14 -0
  9. data/ext/WSK/AnalyzeUtils/AnalyzeUtils.c +272 -0
  10. data/ext/WSK/AnalyzeUtils/AnalyzeUtils.o +0 -0
  11. data/ext/WSK/AnalyzeUtils/AnalyzeUtils.so +0 -0
  12. data/ext/WSK/AnalyzeUtils/Makefile +149 -0
  13. data/ext/WSK/AnalyzeUtils/build.rb +18 -0
  14. data/ext/WSK/ArithmUtils/ArithmUtils.c +862 -0
  15. data/ext/WSK/ArithmUtils/ArithmUtils.o +0 -0
  16. data/ext/WSK/ArithmUtils/ArithmUtils.so +0 -0
  17. data/ext/WSK/ArithmUtils/Makefile +149 -0
  18. data/ext/WSK/ArithmUtils/build.rb +20 -0
  19. data/ext/WSK/FFTUtils/FFTUtils.c +662 -0
  20. data/ext/WSK/FFTUtils/FFTUtils.o +0 -0
  21. data/ext/WSK/FFTUtils/FFTUtils.so +0 -0
  22. data/ext/WSK/FFTUtils/Makefile +149 -0
  23. data/ext/WSK/FFTUtils/build.rb +20 -0
  24. data/ext/WSK/FunctionUtils/FunctionUtils.c +182 -0
  25. data/ext/WSK/FunctionUtils/FunctionUtils.o +0 -0
  26. data/ext/WSK/FunctionUtils/FunctionUtils.so +0 -0
  27. data/ext/WSK/FunctionUtils/Makefile +149 -0
  28. data/ext/WSK/FunctionUtils/build.rb +20 -0
  29. data/ext/WSK/SilentUtils/Makefile +149 -0
  30. data/ext/WSK/SilentUtils/SilentUtils.c +431 -0
  31. data/ext/WSK/SilentUtils/SilentUtils.o +0 -0
  32. data/ext/WSK/SilentUtils/SilentUtils.so +0 -0
  33. data/ext/WSK/SilentUtils/build.rb +18 -0
  34. data/ext/WSK/VolumeUtils/Makefile +149 -0
  35. data/ext/WSK/VolumeUtils/VolumeUtils.c +494 -0
  36. data/ext/WSK/VolumeUtils/VolumeUtils.o +0 -0
  37. data/ext/WSK/VolumeUtils/VolumeUtils.so +0 -0
  38. data/ext/WSK/VolumeUtils/build.rb +20 -0
  39. data/lib/WSK/Actions/Analyze.rb +176 -0
  40. data/lib/WSK/Actions/ApplyMap.desc.rb +15 -0
  41. data/lib/WSK/Actions/ApplyMap.rb +57 -0
  42. data/lib/WSK/Actions/ApplyVolumeFct.desc.rb +30 -0
  43. data/lib/WSK/Actions/ApplyVolumeFct.rb +72 -0
  44. data/lib/WSK/Actions/Compare.desc.rb +25 -0
  45. data/lib/WSK/Actions/Compare.rb +238 -0
  46. data/lib/WSK/Actions/ConstantCompare.desc.rb +20 -0
  47. data/lib/WSK/Actions/ConstantCompare.rb +61 -0
  48. data/lib/WSK/Actions/Cut.desc.rb +20 -0
  49. data/lib/WSK/Actions/Cut.rb +60 -0
  50. data/lib/WSK/Actions/CutFirstSignal.desc.rb +25 -0
  51. data/lib/WSK/Actions/CutFirstSignal.rb +72 -0
  52. data/lib/WSK/Actions/DCShifter.desc.rb +15 -0
  53. data/lib/WSK/Actions/DCShifter.rb +67 -0
  54. data/lib/WSK/Actions/DrawFct.desc.rb +20 -0
  55. data/lib/WSK/Actions/DrawFct.rb +59 -0
  56. data/lib/WSK/Actions/FFT.rb +104 -0
  57. data/lib/WSK/Actions/GenAllValues.rb +67 -0
  58. data/lib/WSK/Actions/GenConstant.desc.rb +20 -0
  59. data/lib/WSK/Actions/GenConstant.rb +56 -0
  60. data/lib/WSK/Actions/GenSawtooth.rb +57 -0
  61. data/lib/WSK/Actions/GenSine.desc.rb +20 -0
  62. data/lib/WSK/Actions/GenSine.rb +73 -0
  63. data/lib/WSK/Actions/Identity.rb +43 -0
  64. data/lib/WSK/Actions/Mix.desc.rb +15 -0
  65. data/lib/WSK/Actions/Mix.rb +149 -0
  66. data/lib/WSK/Actions/Multiply.desc.rb +15 -0
  67. data/lib/WSK/Actions/Multiply.rb +73 -0
  68. data/lib/WSK/Actions/NoiseGate.desc.rb +35 -0
  69. data/lib/WSK/Actions/NoiseGate.rb +129 -0
  70. data/lib/WSK/Actions/SilenceInserter.desc.rb +20 -0
  71. data/lib/WSK/Actions/SilenceInserter.rb +87 -0
  72. data/lib/WSK/Actions/SilenceRemover.desc.rb +30 -0
  73. data/lib/WSK/Actions/SilenceRemover.rb +74 -0
  74. data/lib/WSK/Actions/VolumeProfile.desc.rb +35 -0
  75. data/lib/WSK/Actions/VolumeProfile.rb +63 -0
  76. data/lib/WSK/Common.rb +292 -0
  77. data/lib/WSK/FFT.rb +527 -0
  78. data/lib/WSK/Functions.rb +770 -0
  79. data/lib/WSK/Launcher.rb +216 -0
  80. data/lib/WSK/Maps.rb +29 -0
  81. data/lib/WSK/Model/CachedBufferReader.rb +151 -0
  82. data/lib/WSK/Model/Header.rb +133 -0
  83. data/lib/WSK/Model/InputData.rb +193 -0
  84. data/lib/WSK/Model/RawReader.rb +78 -0
  85. data/lib/WSK/Model/WaveReader.rb +91 -0
  86. data/lib/WSK/OutputInterfaces/DirectStream.rb +146 -0
  87. data/lib/WSK/RIFFReader.rb +60 -0
  88. 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