The Trunk: Sound-ul.26.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

The Trunk: Sound-ul.26.mcz

commits-2
Levente Uzonyi uploaded a new version of Sound to project The Trunk:
http://source.squeak.org/trunk/Sound-ul.26.mcz

==================== Summary ====================

Name: Sound-ul.26
Author: ul
Time: 2 November 2010, 3:14:00.064 am
UUID: c8c0166b-85f4-9447-a360-c520fa1e4876
Ancestors: Sound-dtl.25

- use paragma declarations for #inline: and #var:declareC:

=============== Diff against Sound-dtl.25 ===============

Item was changed:
  ----- Method: ADPCMCodec>>indexForDeltaFrom:to: (in category 'private') -----
  indexForDeltaFrom: thisSample to: nextSample
  "Answer the best index to use for the difference between the given samples."
  "Details: Scan stepSizeTable for the first entry >= the absolute value of the difference between sample values. Since indexes are zero-based, the index used during decoding will be the one in the following stepSizeTable entry. Since the index field of a Flash frame header is only six bits, the maximum index value is 63."
  "Note: Since there does not appear to be any documentation of how Flash actually computes the indices used in its frame headers, this algorithm was guessed by reverse-engineering the Flash ADPCM decoder."
 
  | diff bestIndex |
+ <inline: true>
- self inline: true.
 
  diff := nextSample - thisSample.
  diff < 0 ifTrue: [diff := 0 - diff].
  bestIndex := 63.
  1 to: 62 do: [:j |
  bestIndex = 63 ifTrue: [
  (stepSizeTable at: j) >= diff ifTrue: [bestIndex := j]]].
  ^ bestIndex
  !

Item was changed:
  ----- Method: ADPCMCodec>>nextBits: (in category 'bit streaming') -----
  nextBits: n
  "Answer the next n bits of my bit stream as an unsigned integer."
 
  | result remaining shift |
+ <inline: true>
- self inline: true.
 
  result := 0.
  remaining := n.
  [true] whileTrue: [
  shift := remaining - bitPosition.
  result := result + (currentByte bitShift: shift).
  shift > 0
  ifTrue: [  "consumed currentByte buffer; fetch next byte"
  remaining := remaining - bitPosition.
  currentByte := (encodedBytes at: (byteIndex := byteIndex + 1)).
  bitPosition := 8]
  ifFalse: [  "still some bits left in currentByte buffer"
  bitPosition := bitPosition - remaining.
  "mask out the consumed bits:"
  currentByte := currentByte bitAnd: (255 bitShift: (bitPosition - 8)).
  ^ result]].
  !

Item was changed:
  ----- Method: ADPCMCodec>>nextBits:put: (in category 'bit streaming') -----
  nextBits: n put: anInteger
  "Write the next n bits to my bit stream."
 
  | buf bufBits bitsAvailable shift |
+ <inline: true>
- self inline: true.
 
  buf := anInteger.
  bufBits := n.
  [true] whileTrue: [
  bitsAvailable := 8 - bitPosition.
  shift := bitsAvailable - bufBits.  "either left or right shift"
  "append high bits of buf to end of currentByte:"
  currentByte := currentByte + (buf bitShift: shift).
  shift < 0
  ifTrue: [  "currentByte buffer filled; output it"
  encodedBytes at: (byteIndex := byteIndex + 1) put: currentByte.
  bitPosition := 0.
  currentByte := 0.
  "clear saved high bits of buf:"
  buf := buf bitAnd: (1 bitShift: 0 - shift) - 1.
  bufBits := bufBits - bitsAvailable]
  ifFalse: [  "still some bits available in currentByte buffer"
  bitPosition := bitPosition + bufBits.
  ^ self]].
  !

Item was changed:
  ----- Method: ADPCMCodec>>privateDecodeMono: (in category 'private') -----
  privateDecodeMono: count
 
  | delta step predictedDelta bit |
  <primitive: 'primitiveDecodeMono' module: 'ADPCMCodecPlugin'>
+ <var: #stepSizeTable declareC: 'short int *stepSizeTable'>
+ <var: #indexTable declareC: 'short int *indexTable'>
+ <var: #samples declareC: 'short int *samples'>
+ <var: #encodedBytes declareC: 'unsigned char *encodedBytes'>
- self var: #stepSizeTable declareC: 'short int *stepSizeTable'.
- self var: #indexTable declareC: 'short int *indexTable'.
- self var: #samples declareC: 'short int *samples'.
- self var: #encodedBytes declareC: 'unsigned char *encodedBytes'.
 
  1 to: count do: [:i |
  (i bitAnd: frameSizeMask) = 1
  ifTrue: [  "start of frame; read frame header"
  predicted := self nextBits: 16.
  predicted > 32767 ifTrue: [predicted := predicted - 65536].
  index := self nextBits: 6.
  samples at: (sampleIndex := sampleIndex + 1) put: predicted]
  ifFalse: [
  delta := self nextBits: bitsPerSample.
  step := stepSizeTable at: index + 1.
  predictedDelta := 0.
  bit := deltaValueHighBit.
  [bit > 0] whileTrue: [
  (delta bitAnd: bit) > 0 ifTrue: [predictedDelta := predictedDelta + step].
  step := step bitShift: -1.
  bit := bit bitShift: -1].
  predictedDelta := predictedDelta + step.
 
  (delta bitAnd: deltaSignMask) > 0
  ifTrue: [predicted := predicted - predictedDelta]
  ifFalse: [predicted := predicted + predictedDelta].
  predicted > 32767
  ifTrue: [predicted := 32767]
  ifFalse: [predicted < -32768 ifTrue: [predicted := -32768]].
 
  index := index + (indexTable at: (delta bitAnd: deltaValueMask) + 1).
  index < 0
  ifTrue: [index := 0]
  ifFalse: [index > 88 ifTrue: [index := 88]].
 
  samples at: (sampleIndex := sampleIndex + 1) put: predicted]].
  !

Item was changed:
  ----- Method: ADPCMCodec>>privateDecodeStereo: (in category 'private') -----
  privateDecodeStereo: count
 
  | predictedLeft predictedRight indexLeft indexRight deltaLeft deltaRight
  stepLeft stepRight predictedDeltaLeft predictedDeltaRight bit |
 
  <primitive: 'primitiveDecodeStereo' module: 'ADPCMCodecPlugin'>
+ <var: #stepSizeTable declareC: 'short int *stepSizeTable'>
+ <var: #indexTable declareC: 'short int *indexTable'>
+ <var: #samples declareC: 'short int *samples'>
+ <var: #encodedBytes declareC: 'unsigned char *encodedBytes'>
+ <var: #rightSamples declareC: 'short int *rightSamples'>
+ <var: #predicted declareC: 'short int *predicted'>
+ <var: #index declareC: 'short int *index'>
- self var: #stepSizeTable declareC: 'short int *stepSizeTable'.
- self var: #indexTable declareC: 'short int *indexTable'.
- self var: #samples declareC: 'short int *samples'.
- self var: #encodedBytes declareC: 'unsigned char *encodedBytes'.
- self var: #rightSamples declareC: 'short int *rightSamples'.
- self var: #predicted declareC: 'short int *predicted'.
- self var: #index declareC: 'short int *index'.
 
  "make local copies of decoder state variables"
  predictedLeft := predicted at: 1.
  predictedRight := predicted at: 2.
  indexLeft := index at: 1.
  indexRight := index at: 2.
 
  1 to: count do: [:i |
  (i bitAnd: frameSizeMask) = 1
  ifTrue: [  "start of frame; read frame header"
  predictedLeft := self nextBits: 16.
  indexLeft := self nextBits: 6.
  predictedRight := self nextBits: 16.
  indexRight := self nextBits: 6.
  predictedLeft > 32767 ifTrue: [predictedLeft := predictedLeft - 65536].
  predictedRight > 32767 ifTrue: [predictedRight := predictedRight - 65536].
  samples at: (sampleIndex := sampleIndex + 1) put: predictedLeft.
  rightSamples at: sampleIndex put: predictedRight]
  ifFalse: [
  deltaLeft := self nextBits: bitsPerSample.
  deltaRight := self nextBits: bitsPerSample.
  stepLeft := stepSizeTable at: indexLeft + 1.
  stepRight := stepSizeTable at: indexRight + 1.
  predictedDeltaLeft := predictedDeltaRight := 0.
  bit := deltaValueHighBit.
  [bit > 0] whileTrue: [
  (deltaLeft bitAnd: bit) > 0 ifTrue: [
  predictedDeltaLeft := predictedDeltaLeft + stepLeft].
  (deltaRight bitAnd: bit) > 0 ifTrue: [
  predictedDeltaRight := predictedDeltaRight + stepRight].
  stepLeft := stepLeft bitShift: -1.
  stepRight := stepRight bitShift: -1.
  bit := bit bitShift: -1].
  predictedDeltaLeft := predictedDeltaLeft + stepLeft.
  predictedDeltaRight := predictedDeltaRight + stepRight.
 
  (deltaLeft bitAnd: deltaSignMask) > 0
  ifTrue: [predictedLeft := predictedLeft - predictedDeltaLeft]
  ifFalse: [predictedLeft := predictedLeft + predictedDeltaLeft].
  (deltaRight bitAnd: deltaSignMask) > 0
  ifTrue: [predictedRight := predictedRight - predictedDeltaRight]
  ifFalse: [predictedRight := predictedRight + predictedDeltaRight].
  predictedLeft > 32767
  ifTrue: [predictedLeft := 32767]
  ifFalse: [predictedLeft < -32768 ifTrue: [predictedLeft := -32768]].
  predictedRight > 32767
  ifTrue: [predictedRight := 32767]
  ifFalse: [predictedRight < -32768 ifTrue: [predictedRight := -32768]].
 
  indexLeft := indexLeft + (indexTable at: (deltaLeft bitAnd: deltaValueMask) + 1).
  indexLeft < 0
  ifTrue: [indexLeft := 0]
  ifFalse: [indexLeft > 88 ifTrue: [indexLeft := 88]].
  indexRight := indexRight + (indexTable at: (deltaRight bitAnd: deltaValueMask) + 1).
  indexRight < 0
  ifTrue: [indexRight := 0]
  ifFalse: [indexRight > 88 ifTrue: [indexRight := 88]].
 
  samples at: (sampleIndex := sampleIndex + 1) put: predictedLeft.
  rightSamples at: sampleIndex put: predictedRight]].
 
  "save local copies of decoder state variables"
  predicted at: 1 put: predictedLeft.
  predicted at: 2 put: predictedRight.
  index at: 1 put: indexLeft.
  index at: 2 put: indexRight.
  !

Item was changed:
  ----- Method: ADPCMCodec>>privateEncodeMono: (in category 'private') -----
  privateEncodeMono: count
 
  | step sign diff delta predictedDelta bit p |
  <primitive: 'primitiveEncodeMono' module: 'ADPCMCodecPlugin'>
+ <var: #stepSizeTable declareC: 'short int *stepSizeTable'>
+ <var: #indexTable declareC: 'short int *indexTable'>
+ <var: #samples declareC: 'short int *samples'>
+ <var: #encodedBytes declareC: 'unsigned char *encodedBytes'>
- self var: #stepSizeTable declareC: 'short int *stepSizeTable'.
- self var: #indexTable declareC: 'short int *indexTable'.
- self var: #samples declareC: 'short int *samples'.
- self var: #encodedBytes declareC: 'unsigned char *encodedBytes'.
 
  step := stepSizeTable at: 1.
  1 to: count do: [:i |
  (i bitAnd: frameSizeMask) = 1 ifTrue: [
  predicted := samples at: (sampleIndex := sampleIndex + 1).
  (p := predicted) < 0 ifTrue: [p := p + 65536].
  self nextBits: 16 put: p.
  i < count ifTrue: [
  index := self indexForDeltaFrom: predicted to: (samples at: sampleIndex + 1)].
  self nextBits: 6 put: index.
  ] ifFalse: [
  "compute sign and magnitude of difference from the predicted sample"
  sign := 0.
  diff := (samples at: (sampleIndex := sampleIndex + 1)) - predicted.
  diff < 0 ifTrue: [
  sign := deltaSignMask.
  diff := 0 - diff].
 
  "Compute encoded delta and the difference that this will cause in the predicted sample value during decoding. Note that this code approximates:
  delta := (4 * diff) / step.
  predictedDelta := ((delta + 0.5) * step) / 4;
  but in the shift step bits are dropped. Thus, even if you have fast mul/div hardware you cannot use it since you would get slightly different bits what than the algorithm defines."
  delta := 0.
  predictedDelta := 0.
  bit := deltaValueHighBit.
  [bit > 0] whileTrue: [
  diff >= step ifTrue: [
  delta := delta + bit.
  predictedDelta := predictedDelta + step.
  diff := diff - step].
  step := step bitShift: -1.
  bit := bit bitShift: -1].
  predictedDelta := predictedDelta + step.
 
  "compute and clamp new prediction"
  sign > 0
  ifTrue: [predicted := predicted - predictedDelta]
  ifFalse: [predicted := predicted + predictedDelta].
  predicted > 32767
  ifTrue: [predicted := 32767]
  ifFalse: [predicted < -32768 ifTrue: [predicted := -32768]].
 
  "compute new index and step values"
  index := index + (indexTable at: delta + 1).
  index < 0
  ifTrue: [index := 0]
  ifFalse: [index > 88 ifTrue: [index := 88]].
  step := stepSizeTable at: index + 1.
 
  "output encoded, signed delta"
  self nextBits: bitsPerSample put: (sign bitOr: delta)]].
 
  bitPosition > 0 ifTrue: [  "flush the last output byte, if necessary"
  encodedBytes at: (byteIndex := byteIndex + 1) put: currentByte].
  !

Item was changed:
  ----- Method: ADPCMCodec>>privateEncodeStereo: (in category 'private') -----
  privateEncodeStereo: count
 
  <primitive: 'primitiveEncodeStereo' module: 'ADPCMCodecPlugin'>
+ <inline: false>
  "not yet implemented"
- self inline: false.
  self success: false.!

Item was changed:
  ----- Method: FMSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
  mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
  "Play samples from a wave table by stepping a fixed amount through the table on every sample. The table index and increment are scaled to allow fractional increments for greater pitch accuracy."
  "(FMSound pitch: 440.0 dur: 1.0 loudness: 0.5) play"
 
  | doingFM lastIndex sample offset i s |
  <primitive:'primitiveMixFMSound' module:'SoundGenerationPlugin'>
+ <var: #aSoundBuffer declareC: 'short int *aSoundBuffer'>
+ <var: #waveTable declareC: 'short int *waveTable'>
- self var: #aSoundBuffer declareC: 'short int *aSoundBuffer'.
- self var: #waveTable declareC: 'short int *waveTable'.
 
  doingFM := (normalizedModulation ~= 0) and: [scaledOffsetIndexIncr ~= 0].
  lastIndex := (startIndex + n) - 1.
  startIndex to: lastIndex do: [:sliceIndex |
  sample := (scaledVol * (waveTable at: (scaledIndex // ScaleFactor) + 1)) // ScaleFactor.
  doingFM
  ifTrue: [
  offset := normalizedModulation * (waveTable at: (scaledOffsetIndex // ScaleFactor) + 1).
  scaledOffsetIndex := (scaledOffsetIndex + scaledOffsetIndexIncr) \\ scaledWaveTableSize.
  scaledOffsetIndex < 0
  ifTrue: [scaledOffsetIndex := scaledOffsetIndex + scaledWaveTableSize].
  scaledIndex := (scaledIndex + scaledIndexIncr + offset) \\ scaledWaveTableSize.
  scaledIndex < 0
  ifTrue: [scaledIndex := scaledIndex + scaledWaveTableSize]]
  ifFalse: [
  scaledIndex := (scaledIndex + scaledIndexIncr) \\ scaledWaveTableSize].
 
  leftVol > 0 ifTrue: [
  i := (2 * sliceIndex) - 1.
  s := (aSoundBuffer at: i) + ((sample * leftVol) // ScaleFactor).
  s >  32767 ifTrue: [s :=  32767].  "clipping!!"
  s < -32767 ifTrue: [s := -32767].  "clipping!!"
  aSoundBuffer at: i put: s].
  rightVol > 0 ifTrue: [
  i := 2 * sliceIndex.
  s := (aSoundBuffer at: i) + ((sample * rightVol) // ScaleFactor).
  s >  32767 ifTrue: [s :=  32767].  "clipping!!"
  s < -32767 ifTrue: [s := -32767].  "clipping!!"
  aSoundBuffer at: i put: s].
 
  scaledVolIncr ~= 0 ifTrue: [
  scaledVol := scaledVol + scaledVolIncr.
  ((scaledVolIncr > 0 and: [scaledVol >= scaledVolLimit]) or:
  [scaledVolIncr < 0 and: [scaledVol <= scaledVolLimit]])
  ifTrue: [  "reached the limit; stop incrementing"
  scaledVol := scaledVolLimit.
  scaledVolIncr := 0]]].
 
  count := count - n.
  !

Item was changed:
  ----- Method: LoopedSampledSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
  mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
  "Play samples from a wave table by stepping a fixed amount through the table on every sample. The table index and increment are scaled to allow fractional increments for greater pitch accuracy.  If a loop length is specified, then the index is looped back when the loopEnd index is reached until count drops below releaseCount. This allows a short sampled sound to be sustained indefinitely."
  "(LoopedSampledSound pitch: 440.0 dur: 5.0 loudness: 0.5) play"
 
  | lastIndex sampleIndex i s compositeLeftVol compositeRightVol nextSampleIndex m isInStereo rightVal leftVal |
  <primitive:'primitiveMixLoopedSampledSound' module:'SoundGenerationPlugin'>
+ <var: #aSoundBuffer declareC: 'short int *aSoundBuffer'>
+ <var: #leftSamples declareC: 'short int *leftSamples'>
+ <var: #rightSamples declareC: 'short int *rightSamples'>
- self var: #aSoundBuffer declareC: 'short int *aSoundBuffer'.
- self var: #leftSamples declareC: 'short int *leftSamples'.
- self var: #rightSamples declareC: 'short int *rightSamples'.
 
  isInStereo := leftSamples ~~ rightSamples.
  compositeLeftVol := (leftVol * scaledVol) // ScaleFactor.
  compositeRightVol :=  (rightVol * scaledVol) // ScaleFactor.
 
  i := (2 * startIndex) - 1.
  lastIndex := (startIndex + n) - 1.
  startIndex to: lastIndex do: [:sliceIndex |
  sampleIndex := (scaledIndex := scaledIndex + scaledIndexIncr) // LoopIndexScaleFactor.
  ((sampleIndex > loopEnd) and: [count > releaseCount]) ifTrue: [
  "loop back if not within releaseCount of the note end"
  "note: unlooped sounds will have loopEnd = lastSample"
  sampleIndex := (scaledIndex := scaledIndex - scaledLoopLength) // LoopIndexScaleFactor].
  (nextSampleIndex := sampleIndex + 1) > lastSample ifTrue: [
  sampleIndex > lastSample ifTrue: [count := 0. ^ nil].  "done!!"
  scaledLoopLength = 0
  ifTrue: [nextSampleIndex := sampleIndex]
  ifFalse: [nextSampleIndex := ((scaledIndex - scaledLoopLength) // LoopIndexScaleFactor) + 1]].
 
  m := scaledIndex bitAnd: LoopIndexFractionMask.
  rightVal := leftVal :=
  (((leftSamples at: sampleIndex) * (LoopIndexScaleFactor - m)) +
  ((leftSamples at: nextSampleIndex) * m)) // LoopIndexScaleFactor.
  isInStereo ifTrue: [
  rightVal :=
  (((rightSamples at: sampleIndex) * (LoopIndexScaleFactor - m)) +
  ((rightSamples at: nextSampleIndex) * m)) // LoopIndexScaleFactor].
 
  leftVol > 0 ifTrue: [
  s := (aSoundBuffer at: i) + ((compositeLeftVol * leftVal) // ScaleFactor).
  s >  32767 ifTrue: [s :=  32767].  "clipping!!"
  s < -32767 ifTrue: [s := -32767].  "clipping!!"
  aSoundBuffer at: i put: s].
  i := i + 1.
  rightVol > 0 ifTrue: [
  s := (aSoundBuffer at: i) + ((compositeRightVol * rightVal) // ScaleFactor).
  s >  32767 ifTrue: [s :=  32767].  "clipping!!"
  s < -32767 ifTrue: [s := -32767].  "clipping!!"
  aSoundBuffer at: i put: s].
  i := i + 1.
 
  scaledVolIncr ~= 0 ifTrue: [  "update volume envelope if it is changing"
  scaledVol := scaledVol + scaledVolIncr.
  ((scaledVolIncr > 0 and: [scaledVol >= scaledVolLimit]) or:
  [scaledVolIncr < 0 and: [scaledVol <= scaledVolLimit]])
  ifTrue: [  "reached the limit; stop incrementing"
  scaledVol := scaledVolLimit.
  scaledVolIncr := 0].
  compositeLeftVol := (leftVol * scaledVol) // ScaleFactor.
  compositeRightVol :=  (rightVol * scaledVol) // ScaleFactor]].
 
  count := count - n.
  !

Item was changed:
  ----- Method: PluckedSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
  mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
  "The Karplus-Strong plucked string algorithm: start with a buffer full of random noise and repeatedly play the contents of that buffer while averaging adjacent samples. High harmonics damp out more quickly, transfering their energy to lower ones. The length of the buffer corresponds to the length of the string."
  "(PluckedSound pitch: 220.0 dur: 6.0 loudness: 0.8) play"
 
  | lastIndex scaledThisIndex scaledNextIndex average sample i s |
  <primitive:'primitiveMixPluckedSound' module:'SoundGenerationPlugin'>
+ <var: #aSoundBuffer declareC: 'short int *aSoundBuffer'>
+ <var: #ring declareC: 'short int *ring'>
- self var: #aSoundBuffer declareC: 'short int *aSoundBuffer'.
- self var: #ring declareC: 'short int *ring'.
 
  lastIndex := (startIndex + n) - 1.
  scaledThisIndex := scaledNextIndex := scaledIndex.
  startIndex to: lastIndex do: [:sliceIndex |
  scaledNextIndex := scaledThisIndex + scaledIndexIncr.
  scaledNextIndex >= scaledIndexLimit
  ifTrue: [scaledNextIndex := ScaleFactor + (scaledNextIndex - scaledIndexLimit)].
  average :=
  ((ring at: scaledThisIndex // ScaleFactor) +
  (ring at: scaledNextIndex // ScaleFactor)) // 2.
  ring at: scaledThisIndex // ScaleFactor put: average.
  sample := (average * scaledVol) // ScaleFactor.  "scale by volume"
  scaledThisIndex := scaledNextIndex.
 
  leftVol > 0 ifTrue: [
  i := (2 * sliceIndex) - 1.
  s := (aSoundBuffer at: i) + ((sample * leftVol) // ScaleFactor).
  s >  32767 ifTrue: [s :=  32767].  "clipping!!"
  s < -32767 ifTrue: [s := -32767].  "clipping!!"
  aSoundBuffer at: i put: s].
  rightVol > 0 ifTrue: [
  i := 2 * sliceIndex.
  s := (aSoundBuffer at: i) + ((sample * rightVol) // ScaleFactor).
  s >  32767 ifTrue: [s :=  32767].  "clipping!!"
  s < -32767 ifTrue: [s := -32767].  "clipping!!"
  aSoundBuffer at: i put: s].
 
  scaledVolIncr ~= 0 ifTrue: [
  scaledVol := scaledVol + scaledVolIncr.
  ((scaledVolIncr > 0 and: [scaledVol >= scaledVolLimit]) or:
  [scaledVolIncr < 0 and: [scaledVol <= scaledVolLimit]])
  ifTrue: [  "reached the limit; stop incrementing"
  scaledVol := scaledVolLimit.
  scaledVolIncr := 0]]].
 
  scaledIndex := scaledNextIndex.
  count := count - n.
  !

Item was changed:
  ----- Method: ReverbSound>>applyReverbTo:startingAt:count: (in category 'private') -----
  applyReverbTo: aSoundBuffer startingAt: startIndex count: n
 
  | delayedLeft delayedRight i tapGain j out |
  <primitive: 'primitiveApplyReverb' module:'SoundGenerationPlugin'>
+ <var: #aSoundBuffer declareC: 'short int *aSoundBuffer'>
+ <var: #tapDelays declareC: 'int *tapDelays'>
+ <var: #tapGains declareC: 'int *tapGains'>
+ <var: #leftBuffer declareC: 'short int *leftBuffer'>
+ <var: #rightBuffer declareC: 'short int *rightBuffer'>
- self var: #aSoundBuffer declareC: 'short int *aSoundBuffer'.
- self var: #tapDelays declareC: 'int *tapDelays'.
- self var: #tapGains declareC: 'int *tapGains'.
- self var: #leftBuffer declareC: 'short int *leftBuffer'.
- self var: #rightBuffer declareC: 'short int *rightBuffer'.
 
  startIndex to: ((startIndex + n) - 1) do: [:sliceIndex |
  delayedLeft := delayedRight := 0.
  1 to: tapCount do: [:tapIndex |
  i := bufferIndex - (tapDelays at: tapIndex).
  i < 1 ifTrue: [i := i + bufferSize].  "wrap"
  tapGain := tapGains at: tapIndex.
  delayedLeft := delayedLeft + (tapGain * (leftBuffer at: i)).
  delayedRight := delayedRight + (tapGain * (rightBuffer at: i))].
 
  "left channel"
  j := (2 * sliceIndex) - 1.
  out := (aSoundBuffer at: j) + (delayedLeft // ScaleFactor).
  out >  32767 ifTrue: [out :=  32767].  "clipping!!"
  out < -32767 ifTrue: [out := -32767].  "clipping!!"
  aSoundBuffer at: j put: out.
  leftBuffer at: bufferIndex put: out.
 
  "right channel"
  j := j + 1.
  out := (aSoundBuffer at: j) + (delayedRight // ScaleFactor).
  out >  32767 ifTrue: [out :=  32767].  "clipping!!"
  out < -32767 ifTrue: [out := -32767].  "clipping!!"
  aSoundBuffer at: j put: out.
  rightBuffer at: bufferIndex put: out.
 
  bufferIndex := (bufferIndex \\ bufferSize) + 1].
  !

Item was changed:
  ----- Method: SampledSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'playing') -----
  mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
  "Mix the given number of samples with the samples already in the given buffer starting at the given index. Assume that the buffer size is at least (index + count) - 1."
 
  | lastIndex outIndex sampleIndex sample i s overflow |
  <primitive:'primitiveMixSampledSound' module:'SoundGenerationPlugin'>
+ <var: #aSoundBuffer declareC: 'short int *aSoundBuffer'>
+ <var: #samples declareC: 'short int *samples'>
- self var: #aSoundBuffer declareC: 'short int *aSoundBuffer'.
- self var: #samples declareC: 'short int *samples'.
 
  lastIndex := (startIndex + n) - 1.
  outIndex := startIndex.    "index of next stereo output sample pair"
  sampleIndex := indexHighBits + (scaledIndex >> IncrementFractionBits).
  [(sampleIndex <= samplesSize) and: [outIndex <= lastIndex]] whileTrue: [
  sample := ((samples at: sampleIndex) * scaledVol) // ScaleFactor.
  leftVol > 0 ifTrue: [
  i := (2 * outIndex) - 1.
  s := (aSoundBuffer at: i) + ((sample * leftVol) // ScaleFactor).
  s >  32767 ifTrue: [s :=  32767].  "clipping!!"
  s < -32767 ifTrue: [s := -32767].  "clipping!!"
  aSoundBuffer at: i put: s].
  rightVol > 0 ifTrue: [
  i := 2 * outIndex.
  s := (aSoundBuffer at: i) + ((sample * rightVol) // ScaleFactor).
  s >  32767 ifTrue: [s :=  32767].  "clipping!!"
  s < -32767 ifTrue: [s := -32767].  "clipping!!"
  aSoundBuffer at: i put: s].
 
  scaledVolIncr ~= 0 ifTrue: [
  scaledVol := scaledVol + scaledVolIncr.
  ((scaledVolIncr > 0 and: [scaledVol >= scaledVolLimit]) or:
  [scaledVolIncr < 0 and: [scaledVol <= scaledVolLimit]])
  ifTrue: [  "reached the limit; stop incrementing"
  scaledVol := scaledVolLimit.
  scaledVolIncr := 0]].
 
  scaledIndex := scaledIndex + scaledIncrement.
  scaledIndex >= ScaledIndexOverflow ifTrue: [
  overflow := scaledIndex >> IncrementFractionBits.
  indexHighBits := indexHighBits + overflow.
  scaledIndex := scaledIndex - (overflow << IncrementFractionBits)].
 
  sampleIndex := indexHighBits + (scaledIndex >> IncrementFractionBits).
  outIndex := outIndex + 1].
  count := count - n.
  !