Skip to content
This repository was archived by the owner on Mar 18, 2024. It is now read-only.

Commit e7e21c9

Browse files
author
Jason Crawford
committed
Add support for overflow protection
1 parent f2eaf1b commit e7e21c9

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

volume/volume.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ type Volume float32
77

88
var (
99
// VolumeUseInstVol tells the system to use the volume stored on the instrument
10+
// This is useful for trackers and other musical applications
1011
VolumeUseInstVol = Volume(math.Inf(-1))
1112
)
1213

@@ -21,31 +22,33 @@ type Int24 struct {
2122

2223
// ToSample returns a volume as a typed value supporting the bits per sample provided
2324
func (v Volume) ToSample(bitsPerSample int) interface{} {
25+
val := v.withOverflowProtection()
2426
switch bitsPerSample {
2527
case 8:
26-
return int8(v * 128.0)
28+
return int8(val * 128.0)
2729
case 16:
28-
return int16(v * 32678.0)
30+
return int16(val * 32678.0)
2931
case 24:
30-
s := int32(v * 8388608.0)
32+
s := int32(val * 8388608.0)
3133
return Int24{Hi: int8(s >> 16), Lo: uint16(s & 65535)}
3234
case 32:
33-
return int32(v * 2147483648.0)
35+
return int32(val * 2147483648.0)
3436
}
3537
return 0
3638
}
3739

3840
// ToIntSample returns a volume as an int32 value ranged to the bits per sample provided
3941
func (v Volume) ToIntSample(bitsPerSample int) int32 {
42+
val := v.withOverflowProtection()
4043
switch bitsPerSample {
4144
case 8:
42-
return int32(v * 128.0)
45+
return int32(val * 128.0)
4346
case 16:
44-
return int32(v * 32678.0)
47+
return int32(val * 32678.0)
4548
case 24:
46-
return int32(v * 8388608.0)
49+
return int32(val * 8388608.0)
4750
case 32:
48-
return int32(v * 2147483648.0)
51+
return int32(val * 2147483648.0)
4952
}
5053
return 0
5154
}
@@ -69,3 +72,16 @@ func (m Matrix) Apply(samp ...Volume) Matrix {
6972
}
7073
return o
7174
}
75+
76+
func (v Volume) withOverflowProtection() float64 {
77+
val := float64(v)
78+
if math.Abs(val) <= 1.0 {
79+
// likely case
80+
return val
81+
} else if math.Signbit(val) {
82+
// overflow, negative
83+
return -1.0
84+
}
85+
// overflow, positive
86+
return 1.0
87+
}

0 commit comments

Comments
 (0)