| impulseFile sf impulseResponse impulseLength sourceFile sampleCount inBuffer destFile outBuffer | "Ask for the impulse response file and read the samples into RAM. The samples file must be mono." impulseFile := HostDriverInterface getFileWithPrompt: 'Select the impulse response file:' fileTypes: (Array with: HostDriverInterface sampleFileType) ifCancel: [^ self]. sf := SamplesFile for: impulseFile ifAbsent: [^ self]. impulseLength := sf sampleFrames. impulseResponse := sf getSamplesFromMonoWavetableFileStartingAt: 0 length: impulseLength. "Ask for the file to be convolved." sourceFile := HostDriverInterface getFileWithPrompt: 'Select the source file:' fileTypes: (Array with: HostDriverInterface sampleFileType) ifCancel: [^ self]. sf := SamplesFile for: sourceFile ifAbsent: [^ self]. sampleCount := sf sampleFrames. inBuffer := sf readBuffer. "Ask for the name of the output file." destFile := HostDriverInterface putFileWithPrompt: 'Select the source file:' initially: sf filename fileTypes: (Array with: HostDriverInterface sampleFileType) ifCancel: [^ self]. sf := sf copyForFilename: destFile asFilename. sf writeHeader. outBuffer := sf writeBuffer. "Now, convolve. (This processes left channel only.)" self dialogClass displayStringWithThermometer: 'Now computing convolution...' while: [ | pastInputSamples samplePair progressScale sampleScale | pastInputSamples := Array new: impulseLength withAll: 0. samplePair := Array new: 2. progressScale := 1.0 / sampleCount. sampleScale := (impulseResponse inject: 0 into: [ :sum :x | sum + x abs]) inverse. 1 to: sampleCount do: [ :x | | sum | (x bitAnd: 16rFF) = 0 ifTrue: [self dialogClass thermometerSignal raiseRequestWith: x * progressScale]. pastInputSamples replaceFrom: 2 to: impulseLength with: pastInputSamples startingAt: 1. inBuffer nextSampleInto: samplePair. pastInputSamples at: 1 put: (samplePair at: 1). sum := 0. 1 to: impulseLength do: [ :i | sum := (impulseResponse at: i) * (pastInputSamples at: i) + sum]. sum := sum * sampleScale. outBuffer writeLeftSample: sum rightSample: sum]]. "Close the files, we are done." inBuffer close. outBuffer close.