<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-size:large">Hi Christoph,<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 21, 2020 at 12:35 PM Thiede, Christoph <<a href="mailto:Christoph.Thiede@student.hpi.uni-potsdam.de">Christoph.Thiede@student.hpi.uni-potsdam.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div>
<div dir="ltr">
<div id="gmail-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?</p></div></div></div></blockquote><div class="gmail_default"><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 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 class="gmail_default"><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-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div><div dir="ltr"><div id="gmail-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 class="gmail_default" 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-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div><div dir="ltr"><div id="gmail-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="gmail-m_-2883518047673735885x_Signature" style="font-size:12pt">
<div id="gmail-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="gmail-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" class="gmail_signature"><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>