App-Music-ChordPro

 view release on metacpan or  search on metacpan

lib/ChordPro/res/abc/abc2svg/swing-1.js  view on Meta::CPAN

// swing.js - module to set a swing feel
//
// Copyright (C) 2025 Jean-François Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg.  If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%playswing" appears in a ABC source.
//
// Parameters
//	%%playswing duration_1 restart_time duration_2
// with the durations and time in percent of the duration of the two notes.
//
// This command may appear globally or in a voice.

"use strict"
if (typeof abc2svg == "undefined")
    var	abc2svg = {}

abc2svg.swing = {
// this function is called from sndgen
    swing: function(first, voice_tb, cfmt) {
    var	v, p_v, sw, s, s2, d, m, beat, anac,
	C = abc2svg.C,
	a_dur = [],
	nv = voice_tb.length

	// set the times of the notes subject to swing adjustment
	function set_dur(s) {
		if (!s.a_meter[0] || s.a_meter[0].top[0] == 'C'
		 || !s.a_meter[0].bot)
			beat = C.BLEN / 4		// quarter note
		else if (s.a_meter[0].bot[0] == 8
		      && s.a_meter[0].top[0] % 3 == 0)
			return 1			// no swing
		else
			beat = C.BLEN / s.a_meter[0].bot[0] |0
		a_dur[0] = beat / 2			// x/n/
		a_dur[1] = beat / 4			// x3//n//

		// check if there is an anacrusis
		if (!s.time) {
			anac = 0
		    var	wm = s.wmeasure
			while (s && s.time < wm) {
				if (s.bar_type) {
					anac = wm - s.time
					break
				}
				s = s.next
			} 
		}
	} // set_dur()

	for (v = 0; v < nv; v++) {
		p_v = voice_tb[v]
		sw = cfmt.swing || p_v.swing
		if (!sw || !p_v.sym)
			continue
		if (set_dur(p_v.meter))
			continue			// no swing
		for (s = p_v.sym; s.next; s = s.next) {
			if (s.subtype == "swing")
				sw = s.sw
			if (!sw
			 || !s.dur) {
				if (s.a_meter)
					set_dur(s)
				continue
			}
			if ((s.time + anac - a_dur[0]) % beat
			 && (s.time + anac - a_dur[1]) % beat) {



( run in 1.005 second using v1.01-cache-2.11-cpan-5fbc6bb55f2 )