mirror of
				https://github.com/vsariola/sointu.git
				synced 2025-11-04 00:45:35 -05:00 
			
		
		
		
	fix(compiler): calculate unit target correctly in case there are missing units (type == "")
This commit is contained in:
		@ -25,7 +25,7 @@ type SampleOffset struct {
 | 
			
		||||
func Encode(patch *sointu.Patch, featureSet FeatureSet) (*EncodedPatch, error) {
 | 
			
		||||
	var c EncodedPatch
 | 
			
		||||
	sampleOffsetMap := map[SampleOffset]int{}
 | 
			
		||||
	for _, instr := range patch.Instruments {
 | 
			
		||||
	for instrIndex, instr := range patch.Instruments {
 | 
			
		||||
		if len(instr.Units) > 63 {
 | 
			
		||||
			return nil, errors.New("An instrument can have a maximum of 63 units")
 | 
			
		||||
		}
 | 
			
		||||
@ -61,31 +61,9 @@ func Encode(patch *sointu.Patch, featureSet FeatureSet) (*EncodedPatch, error) {
 | 
			
		||||
					c.DelayTimes = append(c.DelayTimes, uint16(v))
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			command, values, err := EncodeUnit(unit, featureSet)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, fmt.Errorf(`encoding unit failed: %v`, err)
 | 
			
		||||
			}
 | 
			
		||||
			c.Commands = append(c.Commands, command)
 | 
			
		||||
			c.Values = append(c.Values, values...)
 | 
			
		||||
		}
 | 
			
		||||
		c.Commands = append(c.Commands, byte(0)) // advance
 | 
			
		||||
		c.NumVoices += uint32(instr.NumVoices)
 | 
			
		||||
		for k := 0; k < instr.NumVoices-1; k++ {
 | 
			
		||||
			c.PolyphonyBitmask = (c.PolyphonyBitmask << 1) + 1
 | 
			
		||||
		}
 | 
			
		||||
		c.PolyphonyBitmask <<= 1
 | 
			
		||||
	}
 | 
			
		||||
	if c.NumVoices > 32 {
 | 
			
		||||
		return nil, fmt.Errorf("Sointu does not support more than 32 concurrent voices; patch uses %v", c.NumVoices)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &c, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func EncodeUnit(unit sointu.Unit, featureSet FeatureSet) (byte, []byte, error) {
 | 
			
		||||
			opcode, ok := featureSet.Opcode(unit.Type)
 | 
			
		||||
			if !ok {
 | 
			
		||||
		return 0, nil, fmt.Errorf(`the targeted virtual machine is not configured to support unit type "%v"`, unit.Type)
 | 
			
		||||
				return nil, fmt.Errorf(`the targeted virtual machine is not configured to support unit type "%v"`, unit.Type)
 | 
			
		||||
			}
 | 
			
		||||
			var values []byte
 | 
			
		||||
			for _, v := range sointu.UnitTypes[unit.Type] {
 | 
			
		||||
@ -135,7 +113,29 @@ func EncodeUnit(unit sointu.Unit, featureSet FeatureSet) (byte, []byte, error) {
 | 
			
		||||
				}
 | 
			
		||||
				values = append(values, byte(flags))
 | 
			
		||||
			} else if unit.Type == "send" {
 | 
			
		||||
		address := ((unit.Parameters["unit"] + 1) << 4) + unit.Parameters["port"] // each unit is 16 dwords, 8 workspace followed by 8 ports. +1 is for skipping the note/release/inputs
 | 
			
		||||
				targetVoice := unit.Parameters["voice"]
 | 
			
		||||
				var targetInstrument int
 | 
			
		||||
				if targetVoice == 0 {
 | 
			
		||||
					targetInstrument = instrIndex
 | 
			
		||||
				} else {
 | 
			
		||||
					var err error
 | 
			
		||||
					targetInstrument, err = patch.InstrumentForVoice(targetVoice - 1)
 | 
			
		||||
					if err != nil {
 | 
			
		||||
						return nil, fmt.Errorf("send targeted a voice %v, which out of the range of instruments", targetVoice-1)
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				origTarget := unit.Parameters["unit"]
 | 
			
		||||
				targetUnit := origTarget
 | 
			
		||||
				for k := 0; k < origTarget; k++ {
 | 
			
		||||
					units := patch.Instruments[targetInstrument].Units
 | 
			
		||||
					if k >= len(units) {
 | 
			
		||||
						break
 | 
			
		||||
					}
 | 
			
		||||
					if units[k].Type == "" {
 | 
			
		||||
						targetUnit--
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				address := ((targetUnit + 1) << 4) + unit.Parameters["port"] // each unit is 16 dwords, 8 workspace followed by 8 ports. +1 is for skipping the note/release/inputs
 | 
			
		||||
				if unit.Parameters["voice"] > 0 {
 | 
			
		||||
					address += 0x8000 + 16 + (unit.Parameters["voice"]-1)*1024 // global send, +16 is for skipping the out/aux ports
 | 
			
		||||
				}
 | 
			
		||||
@ -147,5 +147,19 @@ func EncodeUnit(unit sointu.Unit, featureSet FeatureSet) (byte, []byte, error) {
 | 
			
		||||
				countTrack := (unit.Parameters["count"] << 1) - 1 + unit.Parameters["notetracking"] // 1 means no note tracking and 1 delay, 2 means notetracking with 1 delay, 3 means no note tracking and 2 delays etc.
 | 
			
		||||
				values = append(values, byte(unit.Parameters["delay"]), byte(countTrack))
 | 
			
		||||
			}
 | 
			
		||||
	return byte(opcode + unit.Parameters["stereo"]), values, nil
 | 
			
		||||
			c.Commands = append(c.Commands, byte(opcode+unit.Parameters["stereo"]))
 | 
			
		||||
			c.Values = append(c.Values, values...)
 | 
			
		||||
		}
 | 
			
		||||
		c.Commands = append(c.Commands, byte(0)) // advance
 | 
			
		||||
		c.NumVoices += uint32(instr.NumVoices)
 | 
			
		||||
		for k := 0; k < instr.NumVoices-1; k++ {
 | 
			
		||||
			c.PolyphonyBitmask = (c.PolyphonyBitmask << 1) + 1
 | 
			
		||||
		}
 | 
			
		||||
		c.PolyphonyBitmask <<= 1
 | 
			
		||||
	}
 | 
			
		||||
	if c.NumVoices > 32 {
 | 
			
		||||
		return nil, fmt.Errorf("Sointu does not support more than 32 concurrent voices; patch uses %v", c.NumVoices)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &c, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user