@@ -156,6 +156,111 @@ function setupPitchActions(activity) {
156156 return ;
157157 }
158158
159+ /**
160+ * Gets the current temperament for the turtle.
161+ *
162+ * @param {Object } turtle - Turtle object
163+ * @returns {String } temperament name (e.g. "eqaul", "just", "pythagorean", "meantone")
164+ */
165+ static getTemperament ( turtle ) {
166+ return turtle . singer . temperament || "equal" ;
167+ }
168+
169+ /**
170+ * Gets the current the key signature for the turtle.
171+ *
172+ * @param {Object } turtle - Turtle object
173+ * @returns {String } key signature (e.g. "C Major")
174+ */
175+ static getKeySignature ( turtle ) {
176+ return turtle . singer . keySignature || "C Major" ;
177+ }
178+
179+ /**
180+ * Gets the last played pitch for the turtle.
181+ *
182+ * @param {Object } turtle - Turtle object
183+ * @returns {Array } [note, octave]
184+ */
185+ static getCurrentPitch ( turtle ) {
186+ return turtle . singer . lastNotePlayed || [ "C" , 4 ] ;
187+ }
188+
189+ /**
190+ * Sets the last played pitch for the turtle.
191+ *
192+ * @param {String } note - Note name (e.g. "C", "G", "A")
193+ * @param {Number } octave - Octave number
194+ * @param {Object } turtle - Turtle object
195+ */
196+ static setCurrentPitch ( note , octave , turtle ) {
197+ turtle . singer . lastNotePlayed = [ note , octave ] ;
198+ }
199+
200+ /**
201+ * Calculates the frequency for a note using temperament-specific logic.
202+ *
203+ * @param {String } note - Note name
204+ * @param {Number } octave - Octave number
205+ * @param {String } temperament - Temperament name
206+ * @param {String } keySignature - key signature
207+ * @returns {Array } [note, octave, frequency]
208+ */
209+ static calculateTemperamentFrequency ( note , octave , temperament , keySignature , step ) {
210+ let frequency = 0 ;
211+ if ( temperament === "equal" ) {
212+ frequency = pitchToFrequency ( note , octave , keySignature , "equal" ) ;
213+ } else if ( temperament == "just" ) {
214+ frequency = pitchToFrequency ( note , octave , keySignature , "just" ) ;
215+ } else if ( temperament === "pythagorean" ) {
216+ frequency = pitchToFrequency ( note , octave , keySignature , "pythagorean" ) ;
217+ } else if ( temperament === "meantone" ) {
218+ frequency = pitchToFrequency ( note , octave , keySignature , "meantone" ) ;
219+ } else {
220+ frequency = pitchToFrequency ( note , octave , keySignature , "equal" ) ;
221+ }
222+ return [ note , octave , frequency ] ;
223+ }
224+
225+ /**
226+ * Steps by Scalar degree using temperament-aware logic.
227+ *
228+ * @param {Number } step - number of scale degrees to step
229+ * @param {Number } turtle - Turtle index in turtles.turtleList
230+ * @param {Number|String } blk - corresponding Block object index in block.blockList or custom blockName
231+ * @returns {* } result of playPitch
232+ */
233+ static stepPitchTemperamentAware ( step , turtle , blk ) {
234+ const temperament = this . getTemperament ( activity . turtles . ithTurtle ( turtle ) ) ;
235+ const keySignature = this . getKeySignature ( activity . turtles . ithTurtle ( turtle ) ) ;
236+ const [ currentNote , currentOctave ] = this . getCurrentPitch ( activity . turtles . ithTurtle ( turtle ) ) ;
237+
238+ const scale = buildScale ( keySignature ) [ 0 ] ;
239+ let idx = scale . indexOf ( currentNote ) ;
240+ if ( idx === - 1 ) idx = 0 ;
241+
242+ let newIdx = idx + step ;
243+ let octaveShift = 0 ;
244+ while ( newIdx < 0 ) {
245+ newIdx += scale . length ;
246+ octaveShift -= 1 ;
247+ }
248+ while ( newIdx >= scale . length ) {
249+ newIdx -= scale . length ;
250+ octaveShift += 1 ;
251+ }
252+ const newNote = scale [ newIdx ] ;
253+ const newOctave = currentOctave + octaveShift ;
254+
255+ const [ note , octave , frequency ] = this . calculateTemperamentFrequency (
256+ newNote , newOctave , temperament , keySignature , step
257+ ) ;
258+
259+ this . setCurrentPitch ( note , octave , activity . turtles . ithTurtle ( turtle ) ) ;
260+
261+ return this . playPitch ( note , octave , 0 , turtle , blk ) ;
262+ }
263+
159264 /**
160265 * Plays a nth modal pitch block.
161266 *
0 commit comments