The Inbox: Sound-dtl.67.mcz

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

The Inbox: Sound-dtl.67.mcz

commits-2
David T. Lewis uploaded a new version of Sound to project The Inbox:
http://source.squeak.org/inbox/Sound-dtl.67.mcz

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

Name: Sound-dtl.67
Author: dtl
Time: 10 December 2019, 10:51:04.985835 pm
UUID: ca970845-8428-41f9-b83c-f64a6cc732c1
Ancestors: Sound-eem.66

Sound mixing improvements by Stéphane Rollandin (spfa).
Allow adjusting volume of mixed sounds while playing.
Original discussion at http://forum.world.st/Adjusting-the-volume-of-a-sound-as-it-s-playing-td5102562.html
Patches posted to squeak-dev at http://lists.squeakfoundation.org/pipermail/squeak-dev/2019-December/205440.html

=============== Diff against Sound-eem.66 ===============

Item was changed:
  ----- Method: AbstractSound>>loudness (in category 'volume') -----
  loudness
  "Answer the current volume setting for this sound."
 
+ self hasVolumeEnvelope ifTrue: [^ self volumeEnvelope scale].
+
+ ^ scaledVol asFloat / ScaleFactor!
- ^ scaledVol asFloat / ScaleFactor asFloat!

Item was changed:
  ----- Method: MixedSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
  mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
  "Play a number of sounds concurrently. The level of each sound can be set independently for the left and right channels."
 
  | snd left right |
  1 to: sounds size do: [:i |
  (soundDone at: i) ifFalse: [
  snd := sounds at: i.
+ left := (leftVol * (leftVols at: i) * scaledVol / ScaleFactor) // ScaleFactor.
+ right := (rightVol * (rightVols at: i) * scaledVol / ScaleFactor) // ScaleFactor.
- left := (leftVol * (leftVols at: i)) // ScaleFactor.
- right := (rightVol * (rightVols at: i)) // ScaleFactor.
  snd samplesRemaining > 0
  ifTrue: [
  snd mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: left rightVol: right]
  ifFalse: [soundDone at: i put: true]]].
  !

Item was changed:
  ----- Method: RepeatingSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
  mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
  "Play a collection of sounds in sequence."
  "(RepeatingSound new
  setSound: FMSound majorScale
  iterations: 2) play"
 
  | i count samplesNeeded |
  iteration <= 0 ifTrue: [^ self].
  i := startIndex.
  samplesNeeded := n.
  [samplesNeeded > 0] whileTrue: [
  count := sound samplesRemaining min: samplesNeeded.
  count = 0 ifTrue: [
  iterationCount == #forever
  ifFalse: [
  iteration := iteration - 1.
  iteration <= 0 ifTrue: [^ self]].  "done"
  sound reset.
  count := sound samplesRemaining min: samplesNeeded.
  count = 0 ifTrue: [^ self]].  "zero length sound"
  sound mixSampleCount: count
  into: aSoundBuffer
  startingAt: i
+ leftVol: leftVol * scaledVol // ScaleFactor
+ rightVol: rightVol * scaledVol // ScaleFactor.
- leftVol: leftVol
- rightVol: rightVol.
  i := i + count.
  samplesNeeded := samplesNeeded - count].
  !

Item was changed:
  ----- Method: SequentialSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
  mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
  "Play a collection of sounds in sequence."
  "PluckedSound chromaticScale play"
 
+ | finalIndex i snd remaining count leftScaledVol rightScaledVol |
- | finalIndex i snd remaining count |
  currentIndex = 0 ifTrue: [^ self].  "already done"
+
+ leftScaledVol := leftVol * scaledVol /// ScaleFactor.
+ rightScaledVol := rightVol * scaledVol /// ScaleFactor.
+
  finalIndex := (startIndex + n) - 1.
  i := startIndex.
  [i <= finalIndex] whileTrue: [
  snd := (sounds at: currentIndex).
  [(remaining := snd samplesRemaining) <= 0] whileTrue: [
  "find next undone sound"
  currentIndex < sounds size
  ifTrue: [
  currentIndex := currentIndex + 1.
  snd := (sounds at: currentIndex)]
  ifFalse: [
  currentIndex := 0.
  ^ self]].  "no more sounds"
  count := (finalIndex - i) + 1.
  remaining < count ifTrue: [count := remaining].
+ snd mixSampleCount: count into: aSoundBuffer startingAt: i
+ leftVol: leftScaledVol
+ rightVol: rightScaledVol.
- snd mixSampleCount: count into: aSoundBuffer startingAt: i leftVol: leftVol rightVol: rightVol.
  i := i + count].
  !



Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

David T. Lewis
This commit harvests a fix by St?phane Rollandin, discussed on the
squeak-dev list.

We are in 5.3 feature freeze now, but it may be reasonable to move
this to trunk because the fix is of high value to the small number
of people who are affected by it.

@Christoph,
You have a number of other inbox submissions for the Sound package.
If you have the time, would you mind reviewing and commenting on
this one?

Thanks,
Dave


On Wed, Dec 11, 2019 at 03:51:05AM +0000, [hidden email] wrote:

> David T. Lewis uploaded a new version of Sound to project The Inbox:
> http://source.squeak.org/inbox/Sound-dtl.67.mcz
>
> ==================== Summary ====================
>
> Name: Sound-dtl.67
> Author: dtl
> Time: 10 December 2019, 10:51:04.985835 pm
> UUID: ca970845-8428-41f9-b83c-f64a6cc732c1
> Ancestors: Sound-eem.66
>
> Sound mixing improvements by St?phane Rollandin (spfa).
> Allow adjusting volume of mixed sounds while playing.
> Original discussion at http://forum.world.st/Adjusting-the-volume-of-a-sound-as-it-s-playing-td5102562.html
> Patches posted to squeak-dev at http://lists.squeakfoundation.org/pipermail/squeak-dev/2019-December/205440.html
>
> =============== Diff against Sound-eem.66 ===============
>
> Item was changed:
>   ----- Method: AbstractSound>>loudness (in category 'volume') -----
>   loudness
>   "Answer the current volume setting for this sound."
>  
> + self hasVolumeEnvelope ifTrue: [^ self volumeEnvelope scale].
> +
> + ^ scaledVol asFloat / ScaleFactor!
> - ^ scaledVol asFloat / ScaleFactor asFloat!
>
> Item was changed:
>   ----- Method: MixedSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
>   mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
>   "Play a number of sounds concurrently. The level of each sound can be set independently for the left and right channels."
>  
>   | snd left right |
>   1 to: sounds size do: [:i |
>   (soundDone at: i) ifFalse: [
>   snd := sounds at: i.
> + left := (leftVol * (leftVols at: i) * scaledVol / ScaleFactor) // ScaleFactor.
> + right := (rightVol * (rightVols at: i) * scaledVol / ScaleFactor) // ScaleFactor.
> - left := (leftVol * (leftVols at: i)) // ScaleFactor.
> - right := (rightVol * (rightVols at: i)) // ScaleFactor.
>   snd samplesRemaining > 0
>   ifTrue: [
>   snd mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: left rightVol: right]
>   ifFalse: [soundDone at: i put: true]]].
>   !
>
> Item was changed:
>   ----- Method: RepeatingSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
>   mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
>   "Play a collection of sounds in sequence."
>   "(RepeatingSound new
>   setSound: FMSound majorScale
>   iterations: 2) play"
>  
>   | i count samplesNeeded |
>   iteration <= 0 ifTrue: [^ self].
>   i := startIndex.
>   samplesNeeded := n.
>   [samplesNeeded > 0] whileTrue: [
>   count := sound samplesRemaining min: samplesNeeded.
>   count = 0 ifTrue: [
>   iterationCount == #forever
>   ifFalse: [
>   iteration := iteration - 1.
>   iteration <= 0 ifTrue: [^ self]].  "done"
>   sound reset.
>   count := sound samplesRemaining min: samplesNeeded.
>   count = 0 ifTrue: [^ self]].  "zero length sound"
>   sound mixSampleCount: count
>   into: aSoundBuffer
>   startingAt: i
> + leftVol: leftVol * scaledVol // ScaleFactor
> + rightVol: rightVol * scaledVol // ScaleFactor.
> - leftVol: leftVol
> - rightVol: rightVol.
>   i := i + count.
>   samplesNeeded := samplesNeeded - count].
>   !
>
> Item was changed:
>   ----- Method: SequentialSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
>   mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
>   "Play a collection of sounds in sequence."
>   "PluckedSound chromaticScale play"
>  
> + | finalIndex i snd remaining count leftScaledVol rightScaledVol |
> - | finalIndex i snd remaining count |
>   currentIndex = 0 ifTrue: [^ self].  "already done"
> +
> + leftScaledVol := leftVol * scaledVol /// ScaleFactor.
> + rightScaledVol := rightVol * scaledVol /// ScaleFactor.
> +
>   finalIndex := (startIndex + n) - 1.
>   i := startIndex.
>   [i <= finalIndex] whileTrue: [
>   snd := (sounds at: currentIndex).
>   [(remaining := snd samplesRemaining) <= 0] whileTrue: [
>   "find next undone sound"
>   currentIndex < sounds size
>   ifTrue: [
>   currentIndex := currentIndex + 1.
>   snd := (sounds at: currentIndex)]
>   ifFalse: [
>   currentIndex := 0.
>   ^ self]].  "no more sounds"
>   count := (finalIndex - i) + 1.
>   remaining < count ifTrue: [count := remaining].
> + snd mixSampleCount: count into: aSoundBuffer startingAt: i
> + leftVol: leftScaledVol
> + rightVol: rightScaledVol.
> - snd mixSampleCount: count into: aSoundBuffer startingAt: i leftVol: leftVol rightVol: rightVol.
>   i := i + count].
>   !
>

>


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

Christoph Thiede

Hi Dave,


I can take a look at it, but I have never really dived into sounds yet - I only polished a few interfaces so far.


However: Nice extension. I did not read the affected methods before, but the changes look reasonable to me :-)

What is #///? My image does not know it.


Best,

Christoph


Von: David T. Lewis <[hidden email]>
Gesendet: Mittwoch, 11. Dezember 2019 05:08:09
An: [hidden email]
Cc: Thiede, Christoph
Betreff: Re: [squeak-dev] The Inbox: Sound-dtl.67.mcz
 
This commit harvests a fix by St?phane Rollandin, discussed on the
squeak-dev list.

We are in 5.3 feature freeze now, but it may be reasonable to move
this to trunk because the fix is of high value to the small number
of people who are affected by it.

@Christoph,
You have a number of other inbox submissions for the Sound package.
If you have the time, would you mind reviewing and commenting on
this one?

Thanks,
Dave


On Wed, Dec 11, 2019 at 03:51:05AM +0000, [hidden email] wrote:
> David T. Lewis uploaded a new version of Sound to project The Inbox:
> http://source.squeak.org/inbox/Sound-dtl.67.mcz
>
> ==================== Summary ====================
>
> Name: Sound-dtl.67
> Author: dtl
> Time: 10 December 2019, 10:51:04.985835 pm
> UUID: ca970845-8428-41f9-b83c-f64a6cc732c1
> Ancestors: Sound-eem.66
>
> Sound mixing improvements by St?phane Rollandin (spfa).
> Allow adjusting volume of mixed sounds while playing.
> Original discussion at http://forum.world.st/Adjusting-the-volume-of-a-sound-as-it-s-playing-td5102562.html
> Patches posted to squeak-dev at http://lists.squeakfoundation.org/pipermail/squeak-dev/2019-December/205440.html
>
> =============== Diff against Sound-eem.66 ===============
>
> Item was changed:
>   ----- Method: AbstractSound>>loudness (in category 'volume') -----
>   loudness
>        "Answer the current volume setting for this sound."
>  
> +      self hasVolumeEnvelope ifTrue: [^ self volumeEnvelope scale].
> +
> +      ^ scaledVol asFloat / ScaleFactor!
> -      ^ scaledVol asFloat / ScaleFactor asFloat!
>
> Item was changed:
>   ----- Method: MixedSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
>   mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
>        "Play a number of sounds concurrently. The level of each sound can be set independently for the left and right channels."
>  
>        | snd left right |
>        1 to: sounds size do: [:i |
>                (soundDone at: i) ifFalse: [
>                        snd := sounds at: i.
> +                      left := (leftVol * (leftVols at: i) * scaledVol / ScaleFactor) // ScaleFactor.
> +                      right := (rightVol * (rightVols at: i) * scaledVol / ScaleFactor) // ScaleFactor.
> -                      left := (leftVol * (leftVols at: i)) // ScaleFactor.
> -                      right := (rightVol * (rightVols at: i)) // ScaleFactor.
>                        snd samplesRemaining > 0
>                                ifTrue: [
>                                        snd mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: left rightVol: right]
>                                ifFalse: [soundDone at: i put: true]]].
>   !
>
> Item was changed:
>   ----- Method: RepeatingSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
>   mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
>        "Play a collection of sounds in sequence."
>        "(RepeatingSound new
>                setSound: FMSound majorScale
>                iterations: 2) play"
>  
>        | i count samplesNeeded |
>        iteration <= 0 ifTrue: [^ self].
>        i := startIndex.
>        samplesNeeded := n.
>        [samplesNeeded > 0] whileTrue: [
>                count := sound samplesRemaining min: samplesNeeded.
>                count = 0 ifTrue: [
>                        iterationCount == #forever
>                                ifFalse: [
>                                        iteration := iteration - 1.
>                                        iteration <= 0 ifTrue: [^ self]].  "done"
>                        sound reset.
>                        count := sound samplesRemaining min: samplesNeeded.
>                        count = 0 ifTrue: [^ self]].  "zero length sound"
>                sound mixSampleCount: count
>                        into: aSoundBuffer
>                        startingAt: i
> +                      leftVol: leftVol * scaledVol // ScaleFactor
> +                      rightVol: rightVol * scaledVol // ScaleFactor.
> -                      leftVol: leftVol
> -                      rightVol: rightVol.
>                i := i + count.
>                samplesNeeded := samplesNeeded - count].
>   !
>
> Item was changed:
>   ----- Method: SequentialSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
>   mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
>        "Play a collection of sounds in sequence."
>        "PluckedSound chromaticScale play"
>  
> +      | finalIndex i snd remaining count leftScaledVol rightScaledVol |
> -      | finalIndex i snd remaining count |
>        currentIndex = 0 ifTrue: [^ self].  "already done"
> +
> +      leftScaledVol := leftVol * scaledVol /// ScaleFactor.
> +      rightScaledVol := rightVol * scaledVol /// ScaleFactor.
> +
>        finalIndex := (startIndex + n) - 1.
>        i := startIndex.
>        [i <= finalIndex] whileTrue: [
>                snd := (sounds at: currentIndex).
>                [(remaining := snd samplesRemaining) <= 0] whileTrue: [
>                        "find next undone sound"
>                        currentIndex < sounds size
>                                ifTrue: [
>                                        currentIndex := currentIndex + 1.
>                                        snd := (sounds at: currentIndex)]
>                                ifFalse: [
>                                        currentIndex := 0.
>                                        ^ self]].  "no more sounds"
>                count := (finalIndex - i) + 1.
>                remaining < count ifTrue: [count := remaining].
> +              snd mixSampleCount: count into: aSoundBuffer startingAt: i
> +                      leftVol: leftScaledVol
> +                      rightVol: rightScaledVol.
> -              snd mixSampleCount: count into: aSoundBuffer startingAt: i leftVol: leftVol rightVol: rightVol.
>                i := i + count].
>   !
>

>



Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

Nicolas Cellier
Hi Christoph,
I don't know about /// but we have \\\

\\\ has been deprecated for some time now (huh, it's still in Kernel, but not recommended!).
Once upon a time, large integer division was slow enough that we would prefer to skip the final attempt to normalize LargeInteger -> SmallInteger that normally has to happen on both quotient and remainder.
For example, if we just want the quotient or just the remainder, we can get a slight speed up by not normalizing the one we do not use...
But then it's programmer's responsibility to apply the normalization.
That's what \\\ did, same as \\ but omitting final normalization.

When I have accelerated the LargeInteger arithmetic, the minor speed up was not of any value, it would just complexify programmation at best (the normalization step was sender responsibility), or lead to broken contracts at worse (it prevents optimizations like a LargeInteger is not zero, can be compared very quickly with a SmallInteger etc...).

So maybe /// is to // what \\\ is to \\  ...

Le mer. 11 déc. 2019 à 09:12, Thiede, Christoph <[hidden email]> a écrit :

Hi Dave,


I can take a look at it, but I have never really dived into sounds yet - I only polished a few interfaces so far.


However: Nice extension. I did not read the affected methods before, but the changes look reasonable to me :-)

What is #///? My image does not know it.


Best,

Christoph


Von: David T. Lewis <[hidden email]>
Gesendet: Mittwoch, 11. Dezember 2019 05:08:09
An: [hidden email]
Cc: Thiede, Christoph
Betreff: Re: [squeak-dev] The Inbox: Sound-dtl.67.mcz
 
This commit harvests a fix by St?phane Rollandin, discussed on the
squeak-dev list.

We are in 5.3 feature freeze now, but it may be reasonable to move
this to trunk because the fix is of high value to the small number
of people who are affected by it.

@Christoph,
You have a number of other inbox submissions for the Sound package.
If you have the time, would you mind reviewing and commenting on
this one?

Thanks,
Dave


On Wed, Dec 11, 2019 at 03:51:05AM +0000, [hidden email] wrote:
> David T. Lewis uploaded a new version of Sound to project The Inbox:
> http://source.squeak.org/inbox/Sound-dtl.67.mcz
>
> ==================== Summary ====================
>
> Name: Sound-dtl.67
> Author: dtl
> Time: 10 December 2019, 10:51:04.985835 pm
> UUID: ca970845-8428-41f9-b83c-f64a6cc732c1
> Ancestors: Sound-eem.66
>
> Sound mixing improvements by St?phane Rollandin (spfa).
> Allow adjusting volume of mixed sounds while playing.
> Original discussion at http://forum.world.st/Adjusting-the-volume-of-a-sound-as-it-s-playing-td5102562.html
> Patches posted to squeak-dev at http://lists.squeakfoundation.org/pipermail/squeak-dev/2019-December/205440.html
>
> =============== Diff against Sound-eem.66 ===============
>
> Item was changed:
>   ----- Method: AbstractSound>>loudness (in category 'volume') -----
>   loudness
>        "Answer the current volume setting for this sound."
>  
> +      self hasVolumeEnvelope ifTrue: [^ self volumeEnvelope scale].
> +
> +      ^ scaledVol asFloat / ScaleFactor!
> -      ^ scaledVol asFloat / ScaleFactor asFloat!
>
> Item was changed:
>   ----- Method: MixedSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
>   mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
>        "Play a number of sounds concurrently. The level of each sound can be set independently for the left and right channels."
>  
>        | snd left right |
>        1 to: sounds size do: [:i |
>                (soundDone at: i) ifFalse: [
>                        snd := sounds at: i.
> +                      left := (leftVol * (leftVols at: i) * scaledVol / ScaleFactor) // ScaleFactor.
> +                      right := (rightVol * (rightVols at: i) * scaledVol / ScaleFactor) // ScaleFactor.
> -                      left := (leftVol * (leftVols at: i)) // ScaleFactor.
> -                      right := (rightVol * (rightVols at: i)) // ScaleFactor.
>                        snd samplesRemaining > 0
>                                ifTrue: [
>                                        snd mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: left rightVol: right]
>                                ifFalse: [soundDone at: i put: true]]].
>   !
>
> Item was changed:
>   ----- Method: RepeatingSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
>   mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
>        "Play a collection of sounds in sequence."
>        "(RepeatingSound new
>                setSound: FMSound majorScale
>                iterations: 2) play"
>  
>        | i count samplesNeeded |
>        iteration <= 0 ifTrue: [^ self].
>        i := startIndex.
>        samplesNeeded := n.
>        [samplesNeeded > 0] whileTrue: [
>                count := sound samplesRemaining min: samplesNeeded.
>                count = 0 ifTrue: [
>                        iterationCount == #forever
>                                ifFalse: [
>                                        iteration := iteration - 1.
>                                        iteration <= 0 ifTrue: [^ self]].  "done"
>                        sound reset.
>                        count := sound samplesRemaining min: samplesNeeded.
>                        count = 0 ifTrue: [^ self]].  "zero length sound"
>                sound mixSampleCount: count
>                        into: aSoundBuffer
>                        startingAt: i
> +                      leftVol: leftVol * scaledVol // ScaleFactor
> +                      rightVol: rightVol * scaledVol // ScaleFactor.
> -                      leftVol: leftVol
> -                      rightVol: rightVol.
>                i := i + count.
>                samplesNeeded := samplesNeeded - count].
>   !
>
> Item was changed:
>   ----- Method: SequentialSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
>   mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
>        "Play a collection of sounds in sequence."
>        "PluckedSound chromaticScale play"
>  
> +      | finalIndex i snd remaining count leftScaledVol rightScaledVol |
> -      | finalIndex i snd remaining count |
>        currentIndex = 0 ifTrue: [^ self].  "already done"
> +
> +      leftScaledVol := leftVol * scaledVol /// ScaleFactor.
> +      rightScaledVol := rightVol * scaledVol /// ScaleFactor.
> +
>        finalIndex := (startIndex + n) - 1.
>        i := startIndex.
>        [i <= finalIndex] whileTrue: [
>                snd := (sounds at: currentIndex).
>                [(remaining := snd samplesRemaining) <= 0] whileTrue: [
>                        "find next undone sound"
>                        currentIndex < sounds size
>                                ifTrue: [
>                                        currentIndex := currentIndex + 1.
>                                        snd := (sounds at: currentIndex)]
>                                ifFalse: [
>                                        currentIndex := 0.
>                                        ^ self]].  "no more sounds"
>                count := (finalIndex - i) + 1.
>                remaining < count ifTrue: [count := remaining].
> +              snd mixSampleCount: count into: aSoundBuffer startingAt: i
> +                      leftVol: leftScaledVol
> +                      rightVol: rightScaledVol.
> -              snd mixSampleCount: count into: aSoundBuffer startingAt: i leftVol: leftVol rightVol: rightVol.
>                i := i + count].
>   !
>

>




Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

Stéphane Rollandin
In reply to this post by Christoph Thiede
> What is #///? My image does not know it.

Ah, this is one reason why I insist my changes are to be reviewed :)

#/// is a method I came up with and that I use very often, it is simply
syntactic sugar for float conversion before division, to avoid
introducing Fractions in computation (this can slow things down
considerably)

In Number, it is simply

/// aNumber
  ^ self / aNumber asFloat

So you can get rid of it by adding a #asFloat and replacing it with #\

Stef

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

Stéphane Rollandin
> So you can get rid of it by adding a #asFloat and replacing it with #\

Of course I meant #/

Stef

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

Christoph Thiede

Interesting tool, I find myself struggling about unexpected fractions too often :) Do you think might be interesting for Trunk?


And by the way, is [a / b asFloat] preferable to [a asFloat / b] or [(a / b) asFloat]?


Von: Squeak-dev <[hidden email]> im Auftrag von Stéphane Rollandin <[hidden email]>
Gesendet: Mittwoch, 11. Dezember 2019 10:56:28
An: [hidden email]
Betreff: Re: [squeak-dev] The Inbox: Sound-dtl.67.mcz
 
> So you can get rid of it by adding a #asFloat and replacing it with #\

Of course I meant #/

Stef



Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

Stéphane Rollandin
> Interesting tool, I find myself struggling about unexpected fractions
> too often :) Do you think might be interesting for Trunk?

I think so, now I don't know if it should be called #/// (obviously I
got used to that).

I have it implemented in Collection, Float, Number and Point.

> And by the way, is [a / b asFloat] preferable to [a asFloat / b] or [(a
> / b) asFloat]?
(a / b) asFloat is definitely not good, because you get the Fraction
there...

Stef

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

Christoph Thiede

I think so, now I don't know if it should be called #/// (obviously I got used to that).


I can imagine that people who knew #\\\ before get confused. However, I did not, so for me, it looks fine:
#/ - simple divide
#// - divide to integer
#/// - divide to float

(a / b) asFloat is definitely not good, because you get the Fraction there...
Of course. :-)

Best,
Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von Stéphane Rollandin <[hidden email]>
Gesendet: Mittwoch, 11. Dezember 2019 12:01:33
An: [hidden email]
Betreff: Re: [squeak-dev] The Inbox: Sound-dtl.67.mcz
 
> Interesting tool, I find myself struggling about unexpected fractions
> too often :) Do you think might be interesting for Trunk?

I think so, now I don't know if it should be called #/// (obviously I
got used to that).

I have it implemented in Collection, Float, Number and Point.

> And by the way, is [a / b asFloat] preferable to [a asFloat / b] or [(a
> / b) asFloat]?
(a / b) asFloat is definitely not good, because you get the Fraction
there...

Stef



Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

Levente Uzonyi
In reply to this post by commits-2
On Wed, 11 Dec 2019, [hidden email] wrote:

> David T. Lewis uploaded a new version of Sound to project The Inbox:
> http://source.squeak.org/inbox/Sound-dtl.67.mcz
>
> ==================== Summary ====================
>
> Name: Sound-dtl.67
> Author: dtl
> Time: 10 December 2019, 10:51:04.985835 pm
> UUID: ca970845-8428-41f9-b83c-f64a6cc732c1
> Ancestors: Sound-eem.66
>
> Sound mixing improvements by St?phane Rollandin (spfa).
> Allow adjusting volume of mixed sounds while playing.
> Original discussion at http://forum.world.st/Adjusting-the-volume-of-a-sound-as-it-s-playing-td5102562.html
> Patches posted to squeak-dev at http://lists.squeakfoundation.org/pipermail/squeak-dev/2019-December/205440.html
>
> =============== Diff against Sound-eem.66 ===============
>
> Item was changed:
>  ----- Method: AbstractSound>>loudness (in category 'volume') -----
>  loudness
>   "Answer the current volume setting for this sound."
>
> + self hasVolumeEnvelope ifTrue: [^ self volumeEnvelope scale].

I don't see #hasVolumeEnvelope and #volumeEnvelope in the Trunk.

> +
> + ^ scaledVol asFloat / ScaleFactor!
> - ^ scaledVol asFloat / ScaleFactor asFloat!

This seems to be a place where the currently unused FloatScaleFactor
variable could be used.

>
> Item was changed:
>  ----- Method: MixedSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
>  mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
>   "Play a number of sounds concurrently. The level of each sound can be set independently for the left and right channels."
>
>   | snd left right |
>   1 to: sounds size do: [:i |
>   (soundDone at: i) ifFalse: [
>   snd := sounds at: i.
> + left := (leftVol * (leftVols at: i) * scaledVol / ScaleFactor) // ScaleFactor.
> + right := (rightVol * (rightVols at: i) * scaledVol / ScaleFactor) // ScaleFactor.

Assuming that leftVol, rightVol are integers, and leftVols and rightVols
are arrays of integers, #/ is very likely to introduce Fractions, and the
triple multiplication may introduce LargeIntegers in 32-bit images.
(due to the use of #///, leftVol and rightVol are sometimes Floats, so
the above doesn't apply for those cases).

#// may introduce noise without dithering. Perhaps it would be better to
precalculate a constant outside the loop (e.g: scaledVol /
FloatScaleFactor / FloatScaleFactor), and inside the loop multiply with
that constant. I'm not an audio engineer, so I don't know if it's better
to round than to truncate there, but truncation (as it is happening now
via #//) will introduce some noise for sure, which could be masked by
dithering.

> - left := (leftVol * (leftVols at: i)) // ScaleFactor.
> - right := (rightVol * (rightVols at: i)) // ScaleFactor.
>   snd samplesRemaining > 0
>   ifTrue: [
>   snd mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: left rightVol: right]
>   ifFalse: [soundDone at: i put: true]]].
>  !
>
> Item was changed:
>  ----- Method: RepeatingSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
>  mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
>   "Play a collection of sounds in sequence."
>   "(RepeatingSound new
>   setSound: FMSound majorScale
>   iterations: 2) play"
>
>   | i count samplesNeeded |
>   iteration <= 0 ifTrue: [^ self].
>   i := startIndex.
>   samplesNeeded := n.
>   [samplesNeeded > 0] whileTrue: [
>   count := sound samplesRemaining min: samplesNeeded.
>   count = 0 ifTrue: [
>   iterationCount == #forever
>   ifFalse: [
>   iteration := iteration - 1.
>   iteration <= 0 ifTrue: [^ self]].  "done"
>   sound reset.
>   count := sound samplesRemaining min: samplesNeeded.
>   count = 0 ifTrue: [^ self]].  "zero length sound"
>   sound mixSampleCount: count
>   into: aSoundBuffer
>   startingAt: i
> + leftVol: leftVol * scaledVol // ScaleFactor
> + rightVol: rightVol * scaledVol // ScaleFactor.

Since this method is sent with Float leftVol and rightVol arguments,
perhaps it's worth keeping precision by not truncating to integers here
too.

Levente

> - leftVol: leftVol
> - rightVol: rightVol.
>   i := i + count.
>   samplesNeeded := samplesNeeded - count].
>  !
>
> Item was changed:
>  ----- Method: SequentialSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'sound generation') -----
>  mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
>   "Play a collection of sounds in sequence."
>   "PluckedSound chromaticScale play"
>
> + | finalIndex i snd remaining count leftScaledVol rightScaledVol |
> - | finalIndex i snd remaining count |
>   currentIndex = 0 ifTrue: [^ self].  "already done"
> +
> + leftScaledVol := leftVol * scaledVol /// ScaleFactor.
> + rightScaledVol := rightVol * scaledVol /// ScaleFactor.
> +
>   finalIndex := (startIndex + n) - 1.
>   i := startIndex.
>   [i <= finalIndex] whileTrue: [
>   snd := (sounds at: currentIndex).
>   [(remaining := snd samplesRemaining) <= 0] whileTrue: [
>   "find next undone sound"
>   currentIndex < sounds size
>   ifTrue: [
>   currentIndex := currentIndex + 1.
>   snd := (sounds at: currentIndex)]
>   ifFalse: [
>   currentIndex := 0.
>   ^ self]].  "no more sounds"
>   count := (finalIndex - i) + 1.
>   remaining < count ifTrue: [count := remaining].
> + snd mixSampleCount: count into: aSoundBuffer startingAt: i
> + leftVol: leftScaledVol
> + rightVol: rightScaledVol.
> - snd mixSampleCount: count into: aSoundBuffer startingAt: i leftVol: leftVol rightVol: rightVol.
>   i := i + count].
>  !
>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

Stéphane Rollandin
Le 11/12/2019 à 12:32, Levente Uzonyi a écrit :

> On Wed, 11 Dec 2019, [hidden email] wrote:
>
>> David T. Lewis uploaded a new version of Sound to project The Inbox:
>> http://source.squeak.org/inbox/Sound-dtl.67.mcz
>>
>> ==================== Summary ====================
>>
>> Name: Sound-dtl.67
>> Author: dtl
>> Time: 10 December 2019, 10:51:04.985835 pm
>> UUID: ca970845-8428-41f9-b83c-f64a6cc732c1
>> Ancestors: Sound-eem.66
>>
>> Sound mixing improvements by St?phane Rollandin (spfa).
>> Allow adjusting volume of mixed sounds while playing.
>> Original discussion at http://forum.world.st/Adjusting-the-volume-of-a-sound-as-it-s-playing-td5102562.html
>> Patches posted to squeak-dev at http://lists.squeakfoundation.org/pipermail/squeak-dev/2019-December/205440.html
>>
>> =============== Diff against Sound-eem.66 ===============
>>
>> Item was changed:
>>   ----- Method: AbstractSound>>loudness (in category 'volume') -----
>>   loudness
>>   "Answer the current volume setting for this sound."
>>
>> + self hasVolumeEnvelope ifTrue: [^ self volumeEnvelope scale].
>
> I don't see #hasVolumeEnvelope and #volumeEnvelope in the Trunk.

Ah, again my own stuff here...

I have

hasVolumeEnvelope

        ^ envelopes anySatisfy: [:e | e isKindOf: VolumeEnvelope]

and

volumeEnvelope

        ^ envelopes detect: [:e | e isKindOf: VolumeEnvelope]

but those are pretty ugly (isKindOf:)

Stef

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

Stéphane Rollandin
In reply to this post by Levente Uzonyi
>>   mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
>>   "Play a number of sounds concurrently. The level of each sound can be set independently for the left and right channels."
>>
>>   | snd left right |
>>   1 to: sounds size do: [:i |
>>   (soundDone at: i) ifFalse: [
>>   snd := sounds at: i.
>> + left := (leftVol * (leftVols at: i) * scaledVol / ScaleFactor) // ScaleFactor.
>> + right := (rightVol * (rightVols at: i) * scaledVol / ScaleFactor) // ScaleFactor.
>
> Assuming that leftVol, rightVol are integers, and leftVols and rightVols
> are arrays of integers, #/ is very likely to introduce Fractions,

Yes, good catch.

> #// may introduce noise without dithering. Perhaps it would be better to
> precalculate a constant outside the loop (e.g: scaledVol /
> FloatScaleFactor / FloatScaleFactor),

I found this whole business of dividing twice by ScaleFactor very fishy...

Stef

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

Stéphane Rollandin
In reply to this post by Levente Uzonyi
>> + leftVol: leftVol * scaledVol // ScaleFactor
>> + rightVol: rightVol * scaledVol // ScaleFactor.
>
> Since this method is sent with Float leftVol and rightVol arguments,
> perhaps it's worth keeping precision by not truncating to integers here
> too.

On a related note, I saw when profiling sound-synthesis code that quite
some time is spent truncating values and checking for possible overflow
in sound buffers.

I implemented the following in SoundBuffer:

at: index add: aNumber

        | s |

        s := (self at: index) + aNumber truncated.
        s >  32767 ifTrue: [s :=  32767].  "clipping!"
        s < -32767 ifTrue: [s := -32767].  "clipping!"

        self at: index put: s

and also

at: index mult: aNumber

        | s |

        s := ((self at: index) * aNumber) truncated.
        s >  32767 ifTrue: [s :=  32767].  "clipping!"
        s < -32767 ifTrue: [s := -32767].  "clipping!"

        self at: index put: s

It would be nice if those where available as primitives. I guess they
would be much faster, and those operations are always required somewhere
in the chain when working with sound buffers, so I think such primitives
would be quite useful in general.

Stef


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

David T. Lewis
In reply to this post by Stéphane Rollandin
On Wed, Dec 11, 2019 at 01:28:08PM +0100, St??phane Rollandin wrote:

> Le 11/12/2019 ?? 12:32, Levente Uzonyi a ??crit??:
> >On Wed, 11 Dec 2019, [hidden email] wrote:
> >
> >>David T. Lewis uploaded a new version of Sound to project The Inbox:
> >>http://source.squeak.org/inbox/Sound-dtl.67.mcz
> >>
> >>==================== Summary ====================
> >>
> >>Name: Sound-dtl.67
> >>Author: dtl
> >>Time: 10 December 2019, 10:51:04.985835 pm
> >>UUID: ca970845-8428-41f9-b83c-f64a6cc732c1
> >>Ancestors: Sound-eem.66
> >>
> >>Sound mixing improvements by St?phane Rollandin (spfa).
> >>Allow adjusting volume of mixed sounds while playing.
> >>Original discussion at
> >>http://forum.world.st/Adjusting-the-volume-of-a-sound-as-it-s-playing-td5102562.html
> >>Patches posted to squeak-dev at
> >>http://lists.squeakfoundation.org/pipermail/squeak-dev/2019-December/205440.html
> >>
> >>=============== Diff against Sound-eem.66 ===============
> >>
> >>Item was changed:
> >>  ----- Method: AbstractSound>>loudness (in category 'volume') -----
> >>  loudness
> >>   "Answer the current volume setting for this sound."
> >>
> >>+ self hasVolumeEnvelope ifTrue: [^ self volumeEnvelope scale].
> >
> >I don't see #hasVolumeEnvelope and #volumeEnvelope in the Trunk.
>
> Ah, again my own stuff here...
>
> I have
>
> hasVolumeEnvelope
>
> ^ envelopes anySatisfy: [:e | e isKindOf: VolumeEnvelope]
>
> and
>
> volumeEnvelope
>
> ^ envelopes detect: [:e | e isKindOf: VolumeEnvelope]
>
> but those are pretty ugly (isKindOf:)
>
> Stef

Rather than add #hasVolumeEnvelope and #volumeEnvelope, would
this achieve the same thing?

    AbstractSound>>loudness
        "Answer the current volume setting for this sound."
        ^ envelopes detect: [:e | e isKindOf: VolumeEnvelope]
            ifFound: [ :envelope | envelope scale ]
            ifNone: [scaledVol asFloat / ScaleFactor]

Dave


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

Stéphane Rollandin
> Rather than add #hasVolumeEnvelope and #volumeEnvelope, would
> this achieve the same thing?
>
>      AbstractSound>>loudness
>          "Answer the current volume setting for this sound."
>          ^ envelopes detect: [:e | e isKindOf: VolumeEnvelope]
>              ifFound: [ :envelope | envelope scale ]
>              ifNone: [scaledVol asFloat / ScaleFactor]

Sure. It just happens I have other senders (well, one other) for
#hasVolumeEnvelope in muO. But for trunk it's fine. In fact, I do not
even know if this change to #loudness is needed in trunk. Is someone
else than me doing sound in Squeak at the moment?

Stef




Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

Squeak - Dev mailing list
I downloaded muO a while ago, and fiddled around with it a bit. I haven’t used it lately.

/————————————————————/
For encrypted mail use [hidden email]
Get a free account at ProtonMail.com
Web: www.objectnets.net and www.objectnets.org

On Dec 12, 2019, at 00:07, Stéphane Rollandin <[hidden email]> wrote:


Rather than add #hasVolumeEnvelope and #volumeEnvelope, would
this achieve the same thing?
    AbstractSound>>loudness
        "Answer the current volume setting for this sound."
        ^ envelopes detect: [:e | e isKindOf: VolumeEnvelope]
            ifFound: [ :envelope | envelope scale ]
            ifNone: [scaledVol asFloat / ScaleFactor]

Sure. It just happens I have other senders (well, one other) for #hasVolumeEnvelope in muO. But for trunk it's fine. In fact, I do not even know if this change to #loudness is needed in trunk. Is someone else than me doing sound in Squeak at the moment?

Stef






Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Sound-dtl.67.mcz

timrowledge
Likewise - it is fascinating but I have no musical talent and can't realistically do anything with it :-(

And typically the linux sound support on a Pi is so painful that I don't connect any speakers.

> On 2019-12-13, at 1:34 AM, John Pfersich via Squeak-dev <[hidden email]> wrote:
>
> I downloaded muO a while ago, and fiddled around with it a bit. I haven’t used it lately.
>
> /————————————————————/
> For encrypted mail use [hidden email]
> Get a free account at ProtonMail.com
> Web: www.objectnets.net and www.objectnets.org
>
>> On Dec 12, 2019, at 00:07, Stéphane Rollandin <[hidden email]> wrote:
>>
>> 
>>> Rather than add #hasVolumeEnvelope and #volumeEnvelope, would
>>> this achieve the same thing?
>>>     AbstractSound>>loudness
>>>         "Answer the current volume setting for this sound."
>>>         ^ envelopes detect: [:e | e isKindOf: VolumeEnvelope]
>>>             ifFound: [ :envelope | envelope scale ]
>>>             ifNone: [scaledVol asFloat / ScaleFactor]
>>
>> Sure. It just happens I have other senders (well, one other) for #hasVolumeEnvelope in muO. But for trunk it's fine. In fact, I do not even know if this change to #loudness is needed in trunk. Is someone else than me doing sound in Squeak at the moment?
>>
>> Stef
>>
>>
>>
>>
>


tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Strange OpCodes: YII: Yield to Irresistable Impulse