Class: SampledSound

Environment: Siren
Superclass: Siren.Sound
Category: Music-Sound
Instance variables: name rate format channels samplesInMemory firstIndex
Indexed variables: objects
Class variables: MagicNumbers MaxIntSample MinIntSample
Imports: private SoundConstants.*

Instances of SampledSound represent digitally-sampled sound objects. Their "samples" are stored in the "data" instance variable inherited from Function. They can be read/written to/from files (using SoundFile objects), displayed (in SoundViews) and played (via SoundPorts).

The class SampledSound is concrete and assumes 16-bit linear encoding of samples; there are subclasses for floating-point and 8-bit Mu-law sample types. There are useful class methods for creating a number of standard sounds such as silence, impulses, swept sine waves, etc. Note that SampledSound uses the 'range' instance variable inherited from Function as its (integer) size.

Instance variables:
name the file name or object ID
rate the sample rate
format the sample format, e.g., #lin16Bit
channels the # of channels
samplesInMemory The number of samples held in memory (may be smaller than
size for very large sounds)
firstIndex The sample index of the start of the in-memory samples (may be non-zero
for very large "paged" sounds)

Other properties, such as the sound's (optional) file name, its sample rate, or the number of channels, are stored in the property list dictionary that is inherited by virtue of being an event subclass.

KNOWN BUGS:

Note that not all of this class is finished--there are methods that call non-existent user primitives and have no Smalltalk implementations (like the heavy DSP).

accessing

allocateData

channels
Answer the receiver's 'channels'.

channels: anObject
Set the receiver's instance variable 'channels' to be anObject.

copy
Answer a 'clean' copy of the receiver.

copyAllButSamples
Answer a 'clean' copy of the receiver, but don't write in the samples yet.

copyFrom: start to: stop
Answer a copy of the receiver for the given sample range.

cueNamed: cName
Answer a sound derived from the receiver using the samples between the named cue points.

envelope
Answer the receiver's envelope.

envelope: anEnv
Set the receiver's envelope property.

file
Answer the sound file for the receiver (if present).

firstIndex
Answer the receiver's 'firstIndex'.

firstIndex: anObject
Set the receiver's instance variable 'firstIndex' to be anObject.

floatsFrom: aStart to: aStop
Answer a copy of the receiver's data within the given sample range.

format
Answer the receiver's 'format'.

format: fSymbol
Set the receiver's instance variable 'format' to be fSymbol.

frameRate
Answer the receiver's 'rate'.

from: aStart to: aStop
Answer a copy of the receiver within the given time range.

fromSample: start toSample: finish
Answer a copy of the receiver within the given sample range.

hasFile
Answer whether the receiver is stored on a file of the same name.

longFormat
Answer the receiver's format as a descriptive string.

name
Answer the receiver's 'name'.

name: anObject
Set the receiver's instance variable 'name' to be anObject.

rate
Answer the receiver's 'rate'.

rate: anObject
Set the receiver's instance variable 'rate' to be anObject.

sampleRate
Answer the receiver's 'rate'.

samples
Answer the instance variable 'data'.

samples: theArray
Accept the argument, 'theArray', (a Byte, Word, or Float array, or an UninterpretedBytes)
as the new instance variable 'samples'.

samplesInMemory
Answer the receiver's 'samplesInMemory'.

samplesInMemory: anObject
Set the receiver's instance variable 'samplesInMemory' to be anObject.

sampleSize
Answer the size in bytes of the receiver's samples (2).

size
Return the receiver's size in sample frames.

size: aNumber
Set the receiver's 'size' in samples.

sizeInBytes
Answer the size in bytes of the receiver.

sizeInFrames
Return the receiver's size in sample frames.

sample accessing

at: anIndex
Answer the value at the given index (between 0 and 1).

at: anIndex put: aValue
Stuff the given sample at the given index (after lots of checking and testing).

cutFrom: startSample to: stopSample
Cut the designated section from the receiver; answer a new sound (!).

floatSampleAt: index
Answer the sample at the given index as a normalized floating-point number.

floatSampleAt: index put: aValue
Stuff the given floating-point sample at the given index after scaling.

intSampleAt: index
Answer the sample at the given index as an integer.

intSampleAt: index put: aValue
Stuff the given integer sample at the given index.

paste: aSound from: startSample to: stopSample at: index
Paste the given sound into the receiver; answer a new sound (!).

sampleAt: index
Answer the sample at the given index, mapping and paging as necessary.

sampleAt: anIndex put: aValue
Stuff the given sample at the given index (after lots of checking and testing).

interpolating

autoCorrelationBetween: index1 and: index2 length: length
Answer the cummulative error between the portions of my waveform starting at the given two indices and extending for the given length. The larger this error, the greater the difference between the two waveforms.

errorBetween: sampleArray1 and: sampleArray2
Answer the cummulative error between the two sample arrays, which are assumed to be the same size.

fadeInOver: fTime
Apply a fade-in ramp to the receiver with the given time.

fadeOutOver: fTime
Apply a fade-in ramp to the receiver with the given time.

interpolatedWindowAt: anIndex width: nSamples
Return an array of N samples starting at the given index in my data.

sampledFrom: aStart to: aStop into: anArray
Place a down-sampled version of the receiver in the argument array.

sampledTo: anArray
Place a down-sampled version of the receiver in the argument array.

sampleMaxFrom: aStart to: aStop into: anArray
Place a version of the root-mean-square energy of the receiver in the argument array.

merging

extractChannel: cNumber into: aSound
Extract the given channel from the receiver into the argument sound.

mergeChannel: cNumber from: aSound
Merge the argument sound into the given channel of the receiver.

envelopes

average
Answer the average sample value of the receiver (normally the DC offset).

computeEnvelope: type
Compute a sample envelope for the receiver with 128 points per second.

computePeakEnvelope
Compute a windowed peak sample envelope for the receiver with 1024 points per 4 seconds.

computeRMSEnvelope
Compute a windowed root-mean-square sample envelope for the receiver.

edit
Edit the receiver.

max
Answer the maximum value of the samples.

offsetBy: aFactor
Answer a copy of the receiver offset by the given factor.

offsetFrom: aStart to: aStop by: anOffset
Answer a copy of the receiver offset by the given factor.

peakEnvelope
Answer the receiver's peak-detected envelope, or compute a new one.

peaksFrom: aStart to: aStop into: anArray
Place a version of the root-mean-square energy of the receiver in the argument array.

readEnvelope: type
Try to read the sample envelope for the receiver from a file named XXX.env.

rmsEnvelope
Answer the receiver's envelope, or compute a new one.

rmsFrom: aStart to: aStop into: anArray
Place a version of the root-mean-square energy of the receiver in the argument array.

rmsTo: anArray
Place a version of the root-mean-square energy of the receiver in the argument array.

scaleBy: aScaleFactor
Scale the receiver's samples by the given factor.

scaledBy: aScaleFactor
Answer a copy of the receiver scaled by the given factor.

scaledByEnvelopeArray: anArray
Answer a copy of the receiver scaled by the given envelope array.

scaledByFunction: aFunction
Answer a copy of the receiver scaled by the given breakpoint envelope expressed as points.

scaledFrom: aStart to: aStop by: aScaleFactor
Answer a copy of the receiver scaled by the given factor.

scaledFrom: aStart to: aStop byEnvelopeArray: anArray
Answer a copy of the receiver scaled by the given envelope array.

scaledFrom: aStart to: aStop byFunction: aFunction
Answer a copy of the receiver scaled by the given breakpoint envelope expressed as points.

scaleFrom: aStart to: aStop by: aScaleFactor
Scale the receiver's damples by the given factor.

writeEnvelope: type
Write the sample envelope for the receiver to a file named XXX.env or XXX.pk.

enumerating

do: aBlock
Evaluate aBlock with each of the receiver's elements as the argument.

printing

printOn: aStream
pretty-print the receiver.

printSamples
pretty-print a few samples.

printSamplesOn: aStream
Pretty-print a few samples--32 by default, 1024 if shift-down, *all* of ctrl and shift down.

storeOnFileNamed: aName
Save the receiver on the sound file named by the argument.

private

getData
Read samples in from the file if none in memory.

mapSampleIndex: index
Map the given sample index according to the 'page' (firstIndex) of the receiver.

privateSampleAt: anIndex
Answer the sample at the given index as an integer.

privateSampleAt: anIndex in: cPtr bigEndian: isBE
Answer the sample at the given index as an integer,
assuming the output is a cPointer; handle endianness.

privateSampleAt: anIndex in: cPtr put: value bigEndian: isBE
Answer the sample at the given index as an integer,
assuming the output is a cPointer; handle endianness.

privateSampleAt: anIndex put: aValue
Stuff the given sample at the given index (safely).

readSamplesFrom: index
Read in samples from disk starting a bit before the given index.

realSound
Answer the real sound for the receiver (overridden in virtual subclasses).

scaleSampleIndex: index
Scale the given sample index according to the sample size of the receiver.

play/record

nextBufferInto: outBuffer frames: bufferSize channels: outChannels format: sformat startingAt: startFrame
Copy data from the receiver into the given output buffer; answer the current sample index.

play
Play the receiver out over the default sound port.

testing

hasGaps
Answer whether the receiver has any gaps.

isComposite
Answer whether the receiver is a composite sound.

isEmpty
Answer whether the receiver is empty.

isVirtual
Answer whether the receiver is a virtual sound.

initialize-release

initialize
Set up a default sound.

MetaClass: SampledSound class

instance creation

default
Answer the default empty sound.

duration: aDur named: nameString rate: aRate channels: aChannels format: aFormat
Answer a new 16-bit linear sound with the given properties.

duration: aDur rate: aRate channels: aChannels
Answer a new sound with the given properties.

duration: aDur rate: aRate channels: aChannels format: aFormat
Answer a new sound with the given properties.

fromData: anArray named: nameString rate: aRate channels: aChannels format: aFormat
Answer a new sound from the given data.

fromData: anArray rate: aRate channels: aChannels format: aFormat
Answer a new 16-bit linear sound from the given data.

fromDblData: anArray rate: aRate channels: aChannels size: siz
Answer a new sound from the given data.

headerFromFile: nameString
Open the given file (EBICSF, NeXT, or SPARC soundfile format)

named: aName size: aSize format: formatSymbol
Answer a new Sound with the given name and storage size.

named: nameString size: size rate: rate channels: chans format: formatSymbol
Answer a new Sound with the given storage size (in sample frames), etc.

named: nameString size: size rate: rate channels: chans format: formatSymbol data: data
Answer a new Sound with the given storage size (in sample frames), etc.

size: size format: formatSymbol channels: chans
Answer a new Sound with the given storage size, etc.

size: size rate: aRate channels: chans
Answer a new Sound with the given storage size, etc.

size: size rate: rate channels: chans format: formatSymbol
Answer a new Sound with the given storage size, etc.

size: size rate: rate format: formatSymbol channels: chans
Answer a new Sound with the given storage size, etc.

examples

immediateInspect
Answer a sampled sound from immediate data; inspect it.

rmsViewExample
Read a sampled sound from the file, take the rms into 64 values, and edit that.

sweepExample
Open a sound view on a swept sine wave.

sweepView
Open a sound view on a swept sine wave.

standard wave forms

constantOfDur: dur value: value rate: rate chans: chans
Answer a sound with a constant value.

expSweepDur: dur rate: rate from: start to: stop chans: chans
Answer a SampledSound with a swept sine wave.

impulseOfDur: dur width: width rate: rate chans: chans
Create a sound with an impulse of the given characteristics.

linearSweepDur: dur rate: rate from: start to: stop chans: chans
Answer a StoredSound with a swept sine wave.

pulseTrainDur: dur rate: rate freq: freq width: width chans: chans
Answer a StoredSound with a pulse train.

pulseTrainDur: dur rate: rate freq: freq width: width chans: chans zero: zero
Answer a StoredSound with a pulse train.

rampDur: dur rate: rate chans: chans
Answer a StoredSound with a single ramp of samples.

sawtooth
Answer a StoredSound with raw sawtooth samples.

sawtoothDur: dur rate: rate freq: freq chans: chans
Answer a StoredSound with raw sawtooth samples.

sineDur: dur rate: rate freq: freq chans: chans
Answer a StoredSound with a pulse train.

squareDur: dur rate: rate freq: freq chans: chans
Answer a StoredSound with a square wave.

sweepDur: dur rate: rate from: start to: stop chans: chans
Answer a StoredSound with a swept sine wave.

class constants

formatSymbol
Answer the symbolic code used for the format of the receiver's instances.

maxSample
Answer the maximum value of the receiver class.

minSample
Answer the minimum value of the receiver class.