The Trunk: Sound-tpr.45.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-tpr.45.mcz

commits-2
tim Rowledge uploaded a new version of Sound to project The Trunk:
http://source.squeak.org/trunk/Sound-tpr.45.mcz

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

Name: Sound-tpr.45
Author: tpr
Time: 13 November 2015, 3:50:17.879 pm
UUID: 257002b4-8961-45b2-86d2-9b8e1f85cd1f
Ancestors: Sound-tpr.44

Sounds changes ported across from Scratch work; you really don't want an error raising prim call inside a critical block if possible.

=============== Diff against Sound-topa.43 ===============

Item was added:
+ ----- Method: Envelope>>computeSustainValueAtMSecs: (in category 'applying') -----
+ computeSustainValueAtMSecs: mSecs
+ "Return the value of this envelope at the given number of milliseconds from its onset. Return zero for times outside the time range of this envelope."
+ "Note: Unlike the private method incrementalComputeValueAtMSecs:, this method does is not increment. Thus it is slower, but it doesn't depend on being called sequentially at fixed time intervals.
+ Note: this is the same as computeValueAtMSecs: apart from removing the first  section that requires loopEndMSecs t obe nil; this appears to cause a problem when a sound in playing and is stopped whilst the #computeSlopeAtMSecs: method is run inside the SoundPlayer loop"
+
+ | t i |
+ mSecs < 0 ifTrue: [^ 0.0].
+
+ mSecs < loopStartMSecs ifTrue: [  "attack phase"
+ i := self indexOfPointAfterMSecs: mSecs startingAt: 1.
+ i = 1 ifTrue: [^ (points at: 1) y * scale].
+ ^ self interpolate: mSecs between: (points at: i - 1) and: (points at: i)].
+
+ "sustain phase"
+ loopMSecs = 0 ifTrue: [^ (points at: loopEndIndex) y * scale].  "looping on a single point"
+ t := loopStartMSecs + ((mSecs - loopStartMSecs) \\ loopMSecs).
+ i := self indexOfPointAfterMSecs: t startingAt: loopStartIndex.
+
+ ^ self interpolate: t between: (points at: i - 1) and: (points at: i)
+ !

Item was removed:
- ----- Method: Envelope>>computeValueAtMSecs: (in category 'applying') -----
- computeValueAtMSecs: mSecs
- "Return the value of this envelope at the given number of milliseconds from its onset. Return zero for times outside the time range of this envelope."
- "Note: Unlike the private method incrementalComputeValueAtMSecs:, this method does is not increment. Thus it is slower, but it doesn't depend on being called sequentially at fixed time intervals."
-
- | t i |
- mSecs < 0 ifTrue: [^ 0.0].
-
- ((loopEndMSecs ~~ nil) and: [mSecs >= loopEndMSecs]) ifTrue: [  "decay phase"
- t := (points at: loopEndIndex) x + (mSecs - loopEndMSecs).
- i := self indexOfPointAfterMSecs: t startingAt: loopEndIndex.
- i == nil ifTrue: [^ 0.0].  "past end"
- ^ (self interpolate: t between: (points at: i - 1) and: (points at: i)) * decayScale].
-
- mSecs < loopStartMSecs ifTrue: [  "attack phase"
- i := self indexOfPointAfterMSecs: mSecs startingAt: 1.
- i = 1 ifTrue: [^ (points at: 1) y * scale].
- ^ self interpolate: mSecs between: (points at: i - 1) and: (points at: i)].
-
- "sustain phase"
- loopMSecs = 0 ifTrue: [^ (points at: loopEndIndex) y * scale].  "looping on a single point"
- t := loopStartMSecs + ((mSecs - loopStartMSecs) \\ loopMSecs).
- i := self indexOfPointAfterMSecs: t startingAt: loopStartIndex.
-
- ^ self interpolate: t between: (points at: i - 1) and: (points at: i)
- !

Item was changed:
  ----- Method: Envelope>>sustainEnd: (in category 'applying') -----
  sustainEnd: mSecs
+ "Set the ending time of the sustain phase of this envelope; the decay phase will start this
+ point. Typically derived from a note's duration.
+ Details: to avoid a sharp transient, the decay phase is scaled so that the beginning of the
+ decay matches the envelope's instantaneous value when the decay phase starts."
- "Set the ending time of the sustain phase of this envelope; the decay phase will start this point. Typically derived from a note's duration."
- "Details: to avoid a sharp transient, the decay phase is scaled so that the beginning of the decay matches the envelope's instantaneous value when the decay phase starts."
 
  | vIfSustaining firstVOfDecay |
+ loopEndMSecs := mSecs. "no longer set to nil in order to pretend to be sustaining"
- loopEndMSecs := nil. "pretend to be sustaining"
  decayScale := 1.0.
  nextRecomputeTime := 0.
+ vIfSustaining := self computeSustainValueAtMSecs: mSecs.  "get value at end of sustain phase"
+ "loopEndMSecs := mSecs. not required any more"
- vIfSustaining := self computeValueAtMSecs: mSecs.  "get value at end of sustain phase"
- loopEndMSecs := mSecs.
  firstVOfDecay := (points at: loopEndIndex) y * scale.
  firstVOfDecay = 0.0
  ifTrue: [decayScale := 1.0]
  ifFalse: [decayScale := vIfSustaining / firstVOfDecay].
  !

Item was changed:
  ----- Method: SimpleMIDIPort>>midiCmd:channel:byte: (in category 'output') -----
  midiCmd: cmd channel: channel byte: dataByte
+ "Immediately output the given MIDI command with the given channel and
+ argument byte to this MIDI port. Assume that the port is open."
- "Immediately output the given MIDI command with the given channel and argument byte to this MIDI port. Assume that the port is open."
 
  accessSema critical: [
+ self primMIDIWriteNoErrorPort: portNumber
- self primMIDIWritePort: portNumber
  from: (ByteArray
  with: (cmd bitOr: channel)
  with: dataByte)
  at: 0].
  !

Item was changed:
  ----- Method: SimpleMIDIPort>>midiCmd:channel:byte:byte: (in category 'output') -----
  midiCmd: cmd channel: channel byte: dataByte1 byte: dataByte2
+ "Immediately output the given MIDI command with the given channel
+ and argument bytes to this MIDI port. Assume that the port is open."
- "Immediately output the given MIDI command with the given channel and argument bytes to this MIDI port. Assume that the port is open."
 
  accessSema critical: [
+ self primMIDIWriteNoErrorPort: portNumber
- self primMIDIWritePort: portNumber
  from: (ByteArray
  with: (cmd bitOr: channel)
  with: dataByte1
  with: dataByte2)
  at: 0].
  !