<div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div id="m_-7469217834499292024m_-6180359470555117579m_4119729739945599233gmail-m_-7089655903888513253gmail-m_-2883518047673735885x_divtagdefaultwrapper" dir="ltr" style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif"><p>Underscore selectors in the Trunk? Is this really necessary?<span style="font-family:Arial,Helvetica,sans-serif;font-size:small;color:rgb(34,34,34)"> </span></p></div></div></blockquote></div></div></div></div></div></div></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div class="gmail_quote"><div><font face="arial, sans-serif" size="4">No, but it leads to a much nicer sounding selector name than any of <span style="color:rgb(0,0,0)">sixtyFourBitMixSampleCount:</span><span style="color:rgb(0,0,0)">into:</span><span style="color:rgb(0,0,0)">startingAt:leftVol:rightVol:, m</span><span style="color:rgb(0,0,0)">ix64BitSampleCount:</span><span style="color:rgb(0,0,0)">into:</span><span style="color:rgb(0,0,0)">startingAt:leftVol:rightVol:, or </span><span style="color:rgb(0,0,0)">m</span><span style="color:rgb(0,0,0)">ixSampleCount64:</span><span style="color:rgb(0,0,0)">into:</span><span style="color:rgb(0,0,0)">startingAt:leftVol:rightVol:.  I can change it if it really </span></font></div></div></div></div></div></div></div></div></blockquote><div><br></div><div>IMO, underscores should NOT be any part of the OOTB API!  All three of those alternatives are better Smalltalk convention than the underscore name.  Underscore selectors should be reserved for external frameworks that need it to do their meta stuff.  This blurs any chance for such a convention, while moving the entire trunk community across this line into needing to set Allow Underscore Selectors, and yet, leaves the Preference in the image, extraneous, I guess..?  All for the aesthetic of one selector?</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div class="gmail_quote"><div><font face="arial, sans-serif" size="4"><span style="color:rgb(0,0,0)">offends you, but I did it for a reason.  I wanted it to read as "this is the 64-bit version of </span></font><font size="4"><span style="color:rgb(0,0,0)">m</span><span style="color:rgb(0,0,0)">ixSampleCount:</span><span style="color:rgb(0,0,0)">into:</span><span style="color:rgb(0,0,0)">startingAt:leftVol:rightVol:", and I didn't want it to be over long.  Note that "mix64BitSampleCOunt:" et al are ambiguous.  The samples are not 64-bits, the algorithm is for 64-bits.  But remember that this is a strange method anyway, a translated primitive, with lots of C weirdness in it.  Complaining about the selector is the least of the problems with it ;-)</span></font></div><div><font size="4"><span style="color:rgb(0,0,0)"><br></span></font></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div dir="ltr"><div id="m_-7469217834499292024m_-6180359470555117579m_4119729739945599233gmail-m_-7089655903888513253gmail-m_-2883518047673735885x_divtagdefaultwrapper" dir="ltr" style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif"><p>Depending on your preferences, you might not even be able to load this code, and I would not consider this Smalltalkish at all ... Is this a known idiom? :-)</p></div></div></div></blockquote><div><br></div><div style="font-size:large">Well, underscores have neen allowed in Smalltalk for a long time now.  It does lead to some nice usage when interfacing with C.  I certwinly do not use it for normal SMalltalk code. But I would miss it badly if it didn't exist.  I use selectors such as strcpy:_:_: (which maps to strcpy(3)) routinely in the VMMaker.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div dir="ltr"><div id="m_-7469217834499292024m_-6180359470555117579m_4119729739945599233gmail-m_-7089655903888513253gmail-m_-2883518047673735885x_divtagdefaultwrapper" dir="ltr" style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif">
<p style="font-size:12pt"><span style="font-size:12pt">Best,</span><br></p>
<p style="font-size:12pt">Christoph</p>
<div id="m_-7469217834499292024m_-6180359470555117579m_4119729739945599233gmail-m_-7089655903888513253gmail-m_-2883518047673735885x_Signature" style="font-size:12pt">
<div id="m_-7469217834499292024m_-6180359470555117579m_4119729739945599233gmail-m_-7089655903888513253gmail-m_-2883518047673735885x_divtagdefaultwrapper" dir="ltr" style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Segoe UI Symbol","Android Emoji",EmojiSymbols">
<div name="x_divtagdefaultwrapper">
<div><font size="2" color="#808080"></font></div>
</div>
</div>
</div>
</div>
<hr style="display:inline-block;width:98%">
<div id="m_-7469217834499292024m_-6180359470555117579m_4119729739945599233gmail-m_-7089655903888513253gmail-m_-2883518047673735885x_divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>Von:</b> Squeak-dev <<a href="mailto:squeak-dev-bounces@lists.squeakfoundation.org" target="_blank">squeak-dev-bounces@lists.squeakfoundation.org</a>> im Auftrag von <a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a> <<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>><br>
<b>Gesendet:</b> Samstag, 19. September 2020 18:11:42<br>
<b>An:</b> <a href="mailto:squeak-dev@lists.squeakfoundation.org" target="_blank">squeak-dev@lists.squeakfoundation.org</a>; <a href="mailto:packages@lists.squeakfoundation.org" target="_blank">packages@lists.squeakfoundation.org</a><br>
<b>Betreff:</b> [squeak-dev] The Trunk: Sound-eem.74.mcz</font>
<div> </div>
</div>
</div>
<font size="2"><span style="font-size:10pt">
<div>Eliot Miranda uploaded a new version of Sound to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Sound-eem.74.mcz" target="_blank">http://source.squeak.org/trunk/Sound-eem.74.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Sound-eem.74<br>
Author: eem<br>
Time: 19 September 2020, 9:11:40.666386 am<br>
UUID: 42a3c2d9-0bed-4310-bcf1-cbe0f3d0653b<br>
Ancestors: Sound-eem.73<br>
<br>
Oops! stopPlayerProcess *must* stop the sound system when sent from startPlayerProcessBufferSize:rate:stereo:sound:.  Spo refactor a bit, renaming stopPlayerProcess to stopPlayerProcess: to take a hardStop boolean.  When quitting the argument is false.<br>
<br>
Add a 64-bit specific, integer-overflow agnostic version of mixSampleCount:into:startingAt:leftVol:rightVol:, for creating a simpler inline primitive in the 64-bit VM.<br>
<br>
=============== Diff against Sound-eem.73 ===============<br>
<br>
Item was changed:<br>
  ----- Method: AbstractSound class>>translatedPrimitives (in category 'primitive generation') -----<br>
  translatedPrimitives<br>
         ^#(<br>
                 (FMSound mixSampleCount:into:startingAt:leftVol:rightVol:)<br>
                 (PluckedSound mixSampleCount:into:startingAt:leftVol:rightVol:)<br>
                 (LoopedSampledSound mixSampleCount:into:startingAt:leftVol:rightVol:)<br>
                 (SampledSound mixSampleCount:into:startingAt:leftVol:rightVol:)<br>
+                (SampledSound _64bitMixSampleCount:into:startingAt:leftVol:rightVol:)<br>
                 (ReverbSound applyReverbTo:startingAt:count:)<br>
         ).<br>
  !<br>
<br>
Item was added:<br>
+ ----- Method: SampledSound>>_64bitMixSampleCount:into:startingAt:leftVol:rightVol: (in category 'playing') -----<br>
+ _64bitMixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol<br>
+        "Mix the given number of samples with the samples already in the given buffer starting at the given index.<br>
+         Assume that the buffer size is at least (index + count) - 1."<br>
+ <br>
+        | lastIndex outIndex sampleIndex sample i s |<br>
+        <inline: #always><br>
+        <var: #aSoundBuffer type: #'short int *'><br>
+        <var: #samples type: #'short int *'><br>
+ <br>
+        lastIndex := (startIndex + n) - 1.<br>
+        outIndex := startIndex.    "index of next stereo output sample pair"<br>
+        sampleIndex := indexHighBits + (scaledIndex >> IncrementFractionBits).<br>
+        [(sampleIndex <= samplesSize) and: [outIndex <= lastIndex]] whileTrue:<br>
+                [sample := ((samples at: sampleIndex) * scaledVol) // ScaleFactor.<br>
+                leftVol > 0 ifTrue:<br>
+                        [i := (2 * outIndex) - 1.<br>
+                        s := (aSoundBuffer at: i) + ((sample * leftVol) // ScaleFactor).<br>
+                        s >  32767 ifTrue: [s :=  32767].  "clipping!!"<br>
+                        s < -32767 ifTrue: [s := -32767].  "clipping!!"<br>
+                        aSoundBuffer at: i put: s].<br>
+                rightVol > 0 ifTrue:<br>
+                        [i := 2 * outIndex.<br>
+                        s := (aSoundBuffer at: i) + ((sample * rightVol) // ScaleFactor).<br>
+                        s >  32767 ifTrue: [s :=  32767].  "clipping!!"<br>
+                        s < -32767 ifTrue: [s := -32767].  "clipping!!"<br>
+                        aSoundBuffer at: i put: s].<br>
+ <br>
+                scaledVolIncr ~= 0 ifTrue:<br>
+                        [scaledVol := scaledVol + scaledVolIncr.<br>
+                        ((scaledVolIncr > 0 and: [scaledVol >= scaledVolLimit]) or:<br>
+                         [scaledVolIncr < 0 and: [scaledVol <= scaledVolLimit]])<br>
+                                ifTrue:  "reached the limit; stop incrementing"<br>
+                                        [scaledVol := scaledVolLimit.<br>
+                                        scaledVolIncr := 0]].<br>
+ <br>
+                scaledIndex := scaledIndex + scaledIncrement.<br>
+ <br>
+                sampleIndex := indexHighBits + (scaledIndex >> IncrementFractionBits).<br>
+                outIndex := outIndex + 1].<br>
+        count := count - n<br>
+ !<br>
<br>
Item was changed:<br>
  ----- Method: SampledSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'playing') -----<br>
  mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol<br>
+        "Mix the given number of samples with the samples already in the given buffer starting at the given index.<br>
+         Assume that the buffer size is at least (index + count) - 1."<br>
-        "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."<br>
  <br>
         | lastIndex outIndex sampleIndex sample i s overflow |<br>
+        <primitive:'primitiveMixSampledSound' module: 'SoundGenerationPlugin'><br>
+        <var: #aSoundBuffer type: #'short int *'><br>
+        <var: #samples type: #'short int *'><br>
-        <primitive:'primitiveMixSampledSound' module:'SoundGenerationPlugin'><br>
-        <var: #aSoundBuffer declareC: 'short int *aSoundBuffer'><br>
-        <var: #samples declareC: 'short int *samples'><br>
  <br>
+        SmallInteger maxVal > 16r3FFFFFFF ifTrue: "In 64-bits we don't have to worry about 2^15 * 2^15 overflow"<br>
+                [^self _64bitMixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol].<br>
         lastIndex := (startIndex + n) - 1.<br>
         outIndex := startIndex.    "index of next stereo output sample pair"<br>
         sampleIndex := indexHighBits + (scaledIndex >> IncrementFractionBits).<br>
         [(sampleIndex <= samplesSize) and: [outIndex <= lastIndex]] whileTrue: [<br>
                 sample := ((samples at: sampleIndex) * scaledVol) // ScaleFactor.<br>
                 leftVol > 0 ifTrue: [<br>
                         i := (2 * outIndex) - 1.<br>
                         s := (aSoundBuffer at: i) + ((sample * leftVol) // ScaleFactor).<br>
                         s >  32767 ifTrue: [s :=  32767].  "clipping!!"<br>
                         s < -32767 ifTrue: [s := -32767].  "clipping!!"<br>
                         aSoundBuffer at: i put: s].<br>
                 rightVol > 0 ifTrue: [<br>
                         i := 2 * outIndex.<br>
                         s := (aSoundBuffer at: i) + ((sample * rightVol) // ScaleFactor).<br>
                         s >  32767 ifTrue: [s :=  32767].  "clipping!!"<br>
                         s < -32767 ifTrue: [s := -32767].  "clipping!!"<br>
                         aSoundBuffer at: i put: s].<br>
  <br>
                 scaledVolIncr ~= 0 ifTrue: [<br>
                         scaledVol := scaledVol + scaledVolIncr.<br>
                         ((scaledVolIncr > 0 and: [scaledVol >= scaledVolLimit]) or:<br>
                          [scaledVolIncr < 0 and: [scaledVol <= scaledVolLimit]])<br>
                                 ifTrue: [  "reached the limit; stop incrementing"<br>
                                         scaledVol := scaledVolLimit.<br>
                                         scaledVolIncr := 0]].<br>
  <br>
                 scaledIndex := scaledIndex + scaledIncrement.<br>
                 scaledIndex >= ScaledIndexOverflow ifTrue: [<br>
                         overflow := scaledIndex >> IncrementFractionBits.<br>
                         indexHighBits := indexHighBits + overflow.<br>
                         scaledIndex := scaledIndex - (overflow << IncrementFractionBits)].<br>
  <br>
                 sampleIndex := indexHighBits + (scaledIndex >> IncrementFractionBits).<br>
                 outIndex := outIndex + 1].<br>
+        count := count - n!<br>
-        count := count - n.<br>
- !<br>
<br>
Item was changed:<br>
  ----- Method: SoundPlayer class>>shutDown: (in category 'snapshotting') -----<br>
  shutDown: quitting<br>
         "Stop player process, for example before snapshotting."<br>
  <br>
+        quitting ifTrue:<br>
+                [self stopPlayerProcess: false.<br>
+                 ReverbState := nil]!<br>
-        quitting ifTrue: [<br>
-                self stopPlayerProcess.<br>
-                ReverbState := nil].!<br>
<br>
Item was changed:<br>
  ----- Method: SoundPlayer class>>startPlayerProcessBufferSize:rate:stereo:sound: (in category 'player process') -----<br>
  startPlayerProcessBufferSize: bufferSize rate: samplesPerSecond stereo: stereoFlag sound: aSound<br>
         "Start the sound player process. Terminate the old process, if any."<br>
         "SoundPlayer startPlayerProcessBufferSize: 1000 rate: 11025 stereo: false"<br>
  <br>
+        self stopPlayerProcess: true.<br>
+        aSound ifNotNil: "stopPlayerProcess: ensures ActiveSounds are empty..."<br>
+                [ActiveSounds add: aSound].<br>
-        self stopPlayerProcess.<br>
-        aSound<br>
-                ifNil:[ActiveSounds := OrderedCollection new]<br>
-                ifNotNil:[ActiveSounds := OrderedCollection with: aSound].<br>
         Buffer := SoundBuffer newStereoSampleCount: (bufferSize // 4) * 4.<br>
+        LastBuffer ifNotNil:<br>
+                [LastBuffer := SoundBuffer basicNew: Buffer basicSize].<br>
-        LastBuffer ifNotNil:[LastBuffer := SoundBuffer basicNew: Buffer basicSize].<br>
         PlayerSemaphore := Semaphore forMutualExclusion.<br>
         SamplingRate := samplesPerSecond.<br>
         Stereo := stereoFlag.<br>
         SoundSupported := true. "Assume so"<br>
         UseReadySemaphore := true.  "set to false if ready semaphore not supported by VM"<br>
         Smalltalk newExternalSemaphoreDo: [ :semaphore :index |<br>
                 ReadyForBuffer := semaphore.<br>
                 self primSoundStartBufferSize: Buffer stereoSampleCount<br>
                         rate: samplesPerSecond<br>
                         stereo: Stereo<br>
                         semaIndex: index ].<br>
         "Check if sound start prim was successful"<br>
         SoundSupported ifFalse:[<br>
                 Smalltalk unregisterExternalObject: ReadyForBuffer.<br>
                 ReadyForBuffer := nil.<br>
                 ^self ].<br>
         UseReadySemaphore<br>
                 ifTrue: [PlayerProcess := [SoundPlayer playLoop] newProcess]<br>
                 ifFalse: [PlayerProcess := [SoundPlayer oldStylePlayLoop] newProcess].<br>
         UseReverb ifTrue: [self startReverb].<br>
  <br>
         PlayerProcess<br>
                 name: 'Sound Player (', ActiveSounds size asString, ')';<br>
                 priority: Processor userInterruptPriority;<br>
                 resume!<br>
<br>
Item was removed:<br>
- ----- Method: SoundPlayer class>>stopPlayerProcess (in category 'player process') -----<br>
- stopPlayerProcess<br>
-        "Stop the sound player process."<br>
-        "SoundPlayer stopPlayerProcess"<br>
- <br>
-        PlayerProcess ifNotNil:<br>
-                [PlayerProcess ~~ Processor activeProcess ifTrue:<br>
-                        [PlayerProcess terminate].<br>
-                 PlayerProcess := nil].<br>
-        "Don't load the SoundPlugin if it is not in use..."<br>
-        self soundPluginActive ifTrue: [self primSoundStop].<br>
-        ActiveSounds isEmpty ifFalse:<br>
-                [ActiveSounds := OrderedCollection new].<br>
-        Buffer := nil.<br>
-        PlayerSemaphore isEmpty ifFalse:<br>
-                [PlayerSemaphore := Semaphore forMutualExclusion].<br>
-        ReadyForBuffer ifNotNil:<br>
-                [Smalltalk unregisterExternalObject: ReadyForBuffer.<br>
-                 ReadyForBuffer := nil]!<br>
<br>
Item was added:<br>
+ ----- Method: SoundPlayer class>>stopPlayerProcess: (in category 'player process') -----<br>
+ stopPlayerProcess: hardStop<br>
+        "Stop the sound player process."<br>
+        "SoundPlayer stopPlayerProcess"<br>
+ <br>
+        PlayerProcess ifNotNil:<br>
+                [PlayerProcess ~~ Processor activeProcess ifTrue:<br>
+                        [PlayerProcess terminate].<br>
+                 PlayerProcess := nil].<br>
+        (hardStop or: [self soundPluginActive]) ifTrue: [self primSoundStop].<br>
+        ActiveSounds isEmpty ifFalse:<br>
+                [ActiveSounds := OrderedCollection new].<br>
+        Buffer := nil.<br>
+        PlayerSemaphore isEmpty ifFalse:<br>
+                [PlayerSemaphore := Semaphore forMutualExclusion].<br>
+        ReadyForBuffer ifNotNil:<br>
+                [Smalltalk unregisterExternalObject: ReadyForBuffer.<br>
+                 ReadyForBuffer := nil]!<br>
<br>
<br>
</div>
</span></font>
</div>

<br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div></div></div></div></div></div></div>
<br>
</blockquote></div></div>