Class: WSK::Actions::Mix
- Inherits:
-
Object
- Object
- WSK::Actions::Mix
- Includes:
- Common
- Defined in:
- lib/WSK/Actions/Mix.rb
Instance Method Summary collapse
-
#execute(iInputData, oOutputData) ⇒ Object
Execute.
-
#get_nbr_samples(iInputData) ⇒ Object
Get the number of samples that will be written.
Methods included from Common
#accessInputWaveFile, #accessOutputWaveFile, #getWaveFileAccesses, #parsePlugins, #readDuration, #readFFTProfile, #readThresholds, #val2db
Instance Method Details
#execute(iInputData, oOutputData) ⇒ Object
Execute
- Parameters
-
iInputData (WSK::Model::InputData): The input data
-
oOutputData (Object): The output data to fill
- Return
-
Exception: An error, or nil if success
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/WSK/Actions/Mix.rb', line 74 def execute(iInputData, oOutputData) rError = nil # Store the list of opened files, and initialize it with the input data (first file) # list< [ IO, InputData, Coeff, Buffer, NbrSamplesInBuffer ] > lLstOpenedFiles = [ [ nil, iInputData, 1.0, nil, nil ] ] @LstFiles.each do |iFileInfo| iFileName, iCoeff = iFileInfo lFileHandle = File.open(iFileName, 'rb') rError, lHeader, lInputData = getWaveFileAccesses(lFileHandle) if (rError == nil) lLstOpenedFiles << [ lFileHandle, lInputData, iCoeff, nil, nil ] else break end end if (rError == nil) require 'WSK/ArithmUtils/ArithmUtils' lArithmUtils = WSK::ArithmUtils::ArithmUtils.new # Loop until we meet the maximal number of samples # !!! We assume that buffers have the same size when read # Initialize buffers lLstOpenedFiles.each do |ioFileInfo| lFileHandle, lInputData, lCoeff, lBuffer = ioFileInfo lInputData.each_raw_buffer do |iRawBuffer, iNbrSamples, iNbrChannels| break end lRawBuffer, lNbrSamples, lNbrChannels2 = lInputData.get_current_raw_buffer ioFileInfo[3] = lRawBuffer ioFileInfo[4] = lNbrSamples end # Sort the list based on the number of samples of each file. # This is a prerequisite of the C function mixing. lLstOpenedFiles.sort! do |iOF1, iOF2| next (iOF2[1].NbrSamples <=> iOF1[1].NbrSamples) end lLstRemainingOpenedFiles = lLstOpenedFiles.clone lNbrSamplesProcessed = 0 while (!lLstRemainingOpenedFiles.empty?) # Mix all buffers lMixRawBuffer, lNbrSamplesWritten = lArithmUtils.mixBuffers(lLstRemainingOpenedFiles, iInputData.Header.NbrBitsPerSample, iInputData.Header.NbrChannels) # Remove the ones that don't have data anymore lLstRemainingOpenedFiles.delete_if do |ioFileInfo| lFileHandle, lInputData, lCoeff, lRawBuffer = ioFileInfo rToBeDeleted = false # Set the next buffer of this file if (lNbrSamplesProcessed + lNbrSamplesWritten >= lInputData.NbrSamples) # Close the handle if it is not the main input if (lFileHandle != nil) lFileHandle.close end rToBeDeleted = true else # Read next Buffer lInputData.each_raw_buffer(lNbrSamplesProcessed + lNbrSamplesWritten) do |iRawBuffer, iNbrSamples, iNbrChannels| break end lRawBuffer, lNbrSamples, lNbrChannels2 = lInputData.get_current_raw_buffer ioFileInfo[3] = lRawBuffer ioFileInfo[4] = lNbrSamples end next rToBeDeleted end oOutputData.pushRawBuffer(lMixRawBuffer) lNbrSamplesProcessed += lNbrSamplesWritten end end return rError end |
#get_nbr_samples(iInputData) ⇒ Object
Get the number of samples that will be written. This is called before execute, as it is needed to write the output file. It is possible to give a majoration: it will be padded with silence.
- Parameters
-
iInputData (WSK::Model::InputData): The input data
- Return
-
Integer: The number of samples to be written
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/WSK/Actions/Mix.rb', line 22 def get_nbr_samples(iInputData) @NbrSamples = iInputData.NbrSamples # Decode the files list # list< [ String, Float ] > @LstFiles = [] lLstParams = @MixFiles.split('|') if (lLstParams.size % 2 != 0) raise RuntimeError, 'Invalid mix parameters. Example: File1.wav|1|File2.wav|0.4' else (lLstParams.size/2).times do |iIdxFile| lFileName = lLstParams[iIdxFile*2] lCoeff = lLstParams[iIdxFile*2+1].to_f if (lCoeff == 0) log_warn "File #{lFileName} has a null coefficient. It won't be part of the mix." else # Check if the file exists if (File.exists?(lFileName)) # Check the file's header lError = accessInputWaveFile(lFileName) do |iInputHeader2, iInputData2| rSubError = nil # Check that headers are the same if (iInputHeader2 != iInputData.Header) rSubError = RuntimeError.new("Mismatch headers with file #{lFileName}: First input file: #{iInputData.Header.inspect} Mix file: #{iInputHeader2.inspect}") end # OK, keep this file @LstFiles << [ lFileName, lCoeff ] if (iInputData2.NbrSamples > @NbrSamples) @NbrSamples = iInputData2.NbrSamples end next rSubError end if (lError != nil) raise lError end else raise RuntimeError, "Missing file: #{lFileName}" end end end end return @NbrSamples end |