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]. ! |
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]. > ! > > |
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]. > ! > >
Carpe Squeak!
|
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 :
|
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 |
> So you can get rid of it by adding a #asFloat and replacing it with #\
Of course I meant #/ Stef |
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
Carpe Squeak!
|
> 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 |
> 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
Carpe Squeak!
|
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]. > ! > > |
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 |
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 |
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 |
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 |
> 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 |
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:
|
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 |
Free forum by Nabble | Edit this page |