Skip to content

Commit

Permalink
Merge pull request #161 from Eiton/main
Browse files Browse the repository at this point in the history
Fix halved sample value for 16/24bit wav audio
  • Loading branch information
MarkKremer authored Jul 10, 2024
2 parents 0f05e5d + 2db85b5 commit f7a7d8c
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 15 deletions.
12 changes: 6 additions & 6 deletions buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,26 +128,26 @@ func decodeFloat(signed bool, precision int, p []byte) (x float64, n int) {

func floatToSigned(precision int, x float64) uint64 {
if x < 0 {
compl := uint64(-x * (math.Exp2(float64(precision)*8-1) - 1))
compl := uint64(-x * math.Exp2(float64(precision)*8-1))
return uint64(1<<uint(precision*8)) - compl
}
return uint64(x * (math.Exp2(float64(precision)*8-1) - 1))
return uint64(math.Min(x*math.Exp2(float64(precision)*8-1), math.Exp2(float64(precision)*8-1)-1))
}

func floatToUnsigned(precision int, x float64) uint64 {
return uint64((x + 1) / 2 * (math.Exp2(float64(precision)*8) - 1))
return uint64(math.Min((x+1)/2*math.Exp2(float64(precision)*8), math.Exp2(float64(precision)*8)-1))
}

func signedToFloat(precision int, xUint64 uint64) float64 {
if xUint64 >= 1<<uint(precision*8-1) {
compl := 1<<uint(precision*8) - xUint64
return -float64(int64(compl)) / (math.Exp2(float64(precision)*8-1) - 1)
return -float64(int64(compl)) / math.Exp2(float64(precision)*8-1)
}
return float64(int64(xUint64)) / (math.Exp2(float64(precision)*8-1) - 1)
return float64(int64(xUint64)) / math.Exp2(float64(precision)*8-1)
}

func unsignedToFloat(precision int, xUint64 uint64) float64 {
return float64(xUint64)/(math.Exp2(float64(precision)*8)-1)*2 - 1
return float64(xUint64)/(math.Exp2(float64(precision)*8))*2 - 1
}

func norm(x float64) float64 {
Expand Down
18 changes: 9 additions & 9 deletions wav/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,36 +219,36 @@ func (d *decoder) Stream(samples [][2]float64) (n int, ok bool) {
switch {
case d.h.BitsPerSample == 8 && d.h.NumChans == 1:
for i, j := 0, 0; i <= n-bytesPerFrame; i, j = i+bytesPerFrame, j+1 {
val := float64(p[i])/(1<<8-1)*2 - 1
val := float64(p[i])/(1<<8)*2 - 1
samples[j][0] = val
samples[j][1] = val
}
case d.h.BitsPerSample == 8 && d.h.NumChans >= 2:
for i, j := 0, 0; i <= n-bytesPerFrame; i, j = i+bytesPerFrame, j+1 {
samples[j][0] = float64(p[i+0])/(1<<8-1)*2 - 1
samples[j][1] = float64(p[i+1])/(1<<8-1)*2 - 1
samples[j][0] = float64(p[i+0])/(1<<8)*2 - 1
samples[j][1] = float64(p[i+1])/(1<<8)*2 - 1
}
case d.h.BitsPerSample == 16 && d.h.NumChans == 1:
for i, j := 0, 0; i <= n-bytesPerFrame; i, j = i+bytesPerFrame, j+1 {
val := float64(int16(p[i+0])+int16(p[i+1])*(1<<8)) / (1<<16 - 1)
val := float64(int16(p[i+0])+int16(p[i+1])*(1<<8)) / (1 << 15)
samples[j][0] = val
samples[j][1] = val
}
case d.h.BitsPerSample == 16 && d.h.NumChans >= 2:
for i, j := 0, 0; i <= n-bytesPerFrame; i, j = i+bytesPerFrame, j+1 {
samples[j][0] = float64(int16(p[i+0])+int16(p[i+1])*(1<<8)) / (1<<16 - 1)
samples[j][1] = float64(int16(p[i+2])+int16(p[i+3])*(1<<8)) / (1<<16 - 1)
samples[j][0] = float64(int16(p[i+0])+int16(p[i+1])*(1<<8)) / (1 << 15)
samples[j][1] = float64(int16(p[i+2])+int16(p[i+3])*(1<<8)) / (1 << 15)
}
case d.h.BitsPerSample == 24 && d.h.NumChans == 1:
for i, j := 0, 0; i <= n-bytesPerFrame; i, j = i+bytesPerFrame, j+1 {
val := float64((int32(p[i+0])<<8)+(int32(p[i+1])<<16)+(int32(p[i+2])<<24)) / (1 << 8) / (1<<24 - 1)
val := float64((int32(p[i+0])<<8)+(int32(p[i+1])<<16)+(int32(p[i+2])<<24)) / (1 << 8) / (1 << 23)
samples[j][0] = val
samples[j][1] = val
}
case d.h.BitsPerSample == 24 && d.h.NumChans >= 2:
for i, j := 0, 0; i <= n-bytesPerFrame; i, j = i+bytesPerFrame, j+1 {
samples[j][0] = float64((int32(p[i+0])<<8)+(int32(p[i+1])<<16)+(int32(p[i+2])<<24)) / (1 << 8) / (1<<24 - 1)
samples[j][1] = float64((int32(p[i+3])<<8)+(int32(p[i+4])<<16)+(int32(p[i+5])<<24)) / (1 << 8) / (1<<24 - 1)
samples[j][0] = float64((int32(p[i+0])<<8)+(int32(p[i+1])<<16)+(int32(p[i+2])<<24)) / (1 << 8) / (1 << 23)
samples[j][1] = float64((int32(p[i+3])<<8)+(int32(p[i+4])<<16)+(int32(p[i+5])<<24)) / (1 << 8) / (1 << 23)
}
}
d.pos += int32(n)
Expand Down

0 comments on commit f7a7d8c

Please sign in to comment.