First time here? Check out the FAQ!
x

Is there a way to write a wav or aiff file using smalltalk?

0 votes
502 views
Just curious if I could write smalltalk generated arrays as a wav or aiff file using smalltalk? Haven't found a "wavwrite" message in Kyma X Revealed though..

Thanks!
asked Nov 9, 2015 in Capytalk & Smalltalk by kymaguy (Virtuoso) (10,580 points)

1 Answer

+1 vote
I would recommend to use the DiskRecorder Prototype to write data.

In Kyma you can only write to files via Smalltalk under speical circumstances, for example when you write a special state in a Tool for it.

Used in a normal sound smalltalk is always evalutated before the sound is started. What you could do is generate your data upfront with a Smalltalk script and "record" the data to a Diskwriter. If you just want to generate some values in Smalltalk you could try to write a smalltalk script  or code snippet which you "evualuate" with the Command+Y key combo.

Here is an acient script from the old forum which should do "offline comvolution" maybe this is helpfull for you to figure out how to write to a  samplesFiles.

I hope that helps a bit.

best

Chris

 

---

| 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.
answered Nov 9, 2015 by christian-schloesser (Adept) (2,920 points)
Thanks Christian! I already work with the DiskRecorder the way you describe it and it works fine. I want to end up with a tool, so the approach of writing the wav file using smalltalk would make things easier I guess.
From what I understand I just need to define a buffer using writeBuffer and write into it using writeLeftSample: rightSample: inside a loop. Or is there a way to write an array directly? (without iterating over its indices)
Why is there nothing about writeBuffer, writeHeader, writeLeftSample: rightSample: in the smalltalk reference?
Thanks a lot!
Thanks to Christian, SSC, and Christian Vogel I was able to come up with a concatenation script. I've placed in the Community Library – http://kyma.symbolicsound.com/library/concatenate-a-folder-of-files-into-one-audio-file/ – and am posting here just in case one wants more examples of Script style smalltalk to aiff files.
...