@@ -61,61 +61,92 @@ func resolution(bitDepth BitDepth) int {
61
61
return 1 << (bitDepth - 1 ) - 1
62
62
}
63
63
64
- // AsFloat64 converts interleaved int signal to float64.
64
+ // Size of non-interleaved data.
65
+ func (ints InterInt ) Size () int {
66
+ return int (math .Ceil (float64 (len (ints .Data )) / float64 (ints .NumChannels )))
67
+ }
68
+
69
+ // AsFloat64 allocates new Float64 buffer of the same
70
+ // size and copies signal values there.
65
71
func (ints InterInt ) AsFloat64 () Float64 {
66
72
if ints .Data == nil || ints .NumChannels == 0 {
67
73
return nil
68
74
}
69
75
floats := make ([][]float64 , ints .NumChannels )
70
- bufSize := int (math .Ceil (float64 (len (ints .Data )) / float64 (ints .NumChannels )))
71
76
72
- // get resolution of bit depth
77
+ for i := range floats {
78
+ floats [i ] = make ([]float64 , ints .Size ())
79
+ }
80
+ ints .CopyToFloat64 (floats )
81
+ return floats
82
+ }
83
+
84
+ // CopyToFloat64 buffer the values of InterInt buffer.
85
+ // If number of channels is not equal, function will panic.
86
+ func (ints InterInt ) CopyToFloat64 (floats Float64 ) {
87
+ if ints .NumChannels != floats .NumChannels () {
88
+ panic (fmt .Errorf ("unexpected number of channels in destination buffer: expected %v got %v" , ints .NumChannels , floats .NumChannels ()))
89
+ }
90
+ // get resolution of bit depth.
73
91
res := resolution (ints .BitDepth )
74
- // determine the divider for bit depth conversion
92
+ // determine the divider for bit depth conversion.
75
93
divider := float64 (res )
76
- // determine the shift for signed-unsigned conversion
94
+ // determine the shift for signed-unsigned conversion.
77
95
shift := 0
78
96
if ints .Unsigned {
79
97
shift = res
80
98
}
81
99
82
100
for i := range floats {
83
- floats [i ] = make ([]float64 , bufSize )
84
- pos := 0
85
- for j := i ; j < len (ints .Data ); j = j + ints .NumChannels {
86
- floats [i ][pos ] = float64 (ints .Data [j ]- shift ) / divider
87
- pos ++
101
+ for pos , j := i , 0 ; pos < len (ints .Data ) && j < len (floats [i ]); pos , j = pos + ints .NumChannels , j + 1 {
102
+ floats [i ][j ] = float64 (ints .Data [pos ]- shift ) / divider
88
103
}
89
104
}
90
- return floats
91
105
}
92
106
93
- // AsInterInt converts float64 signal to interleaved int.
94
- // If unsigned is true, then all values are shifted and result will be in unsigned range.
95
- func (floats Float64 ) AsInterInt (bitDepth BitDepth , unsigned bool ) []int {
96
- var numChannels int
97
- if numChannels = len (floats ); numChannels == 0 {
98
- return nil
107
+ // AsInterInt allocates new interleaved int buffer of
108
+ // the same size and copies signal values there.
109
+ // If unsigned is true, then all values are shifted
110
+ // and result will be in unsigned range.
111
+ func (floats Float64 ) AsInterInt (bitDepth BitDepth , unsigned bool ) InterInt {
112
+ numChannels := floats .NumChannels ()
113
+ if numChannels == 0 {
114
+ return InterInt {}
99
115
}
100
116
117
+ ints := InterInt {
118
+ Data : make ([]int , len (floats [0 ])* numChannels ),
119
+ NumChannels : numChannels ,
120
+ BitDepth : bitDepth ,
121
+ Unsigned : unsigned ,
122
+ }
123
+
124
+ floats .CopyToInterInt (ints )
125
+ return ints
126
+ }
127
+
128
+ // CopyToInterInt buffer the values of Float64 buffer.
129
+ // If number of channels is not equal, function will panic.
130
+ func (floats Float64 ) CopyToInterInt (ints InterInt ) {
131
+ if floats .NumChannels () != ints .NumChannels {
132
+ panic (fmt .Errorf ("unexpected number of channels in destination buffer: expected %v got %v" , floats .NumChannels (), ints .NumChannels ))
133
+ }
101
134
// get resolution of bit depth
102
- res := resolution (bitDepth )
135
+ res := resolution (ints . BitDepth )
103
136
// determine the multiplier for bit depth conversion
104
137
multiplier := float64 (res )
105
138
// determine the shift for signed-unsigned conversion
106
139
shift := 0
107
- if unsigned {
140
+ if ints . Unsigned {
108
141
shift = res
109
142
}
110
143
111
- ints := make ([]int , len (floats [0 ])* numChannels )
112
-
144
+ size := ints .Size ()
113
145
for j := range floats {
114
- for i := range floats [j ] {
115
- ints [i * numChannels + j ] = int (floats [j ][i ]* multiplier ) + shift
146
+ for i := 0 ; i < len ( floats [j ]) && i < size ; i ++ {
147
+ ints . Data [i * ints . NumChannels + j ] = int (floats [j ][i ]* multiplier ) + shift
116
148
}
117
149
}
118
- return ints
119
150
}
120
151
121
152
// Float64Buffer returns an Float64 buffer of specified dimentions.
@@ -127,21 +158,21 @@ func Float64Buffer(numChannels, bufferSize int) Float64 {
127
158
return result
128
159
}
129
160
130
- // NumChannels returns number of channels in this sample slice
161
+ // NumChannels returns number of channels in this sample slice.
131
162
func (floats Float64 ) NumChannels () int {
132
163
return len (floats )
133
164
}
134
165
135
- // Size returns number of samples in single block in this sample slice
166
+ // Size returns number of samples in single block in this sample slice.
136
167
func (floats Float64 ) Size () int {
137
168
if floats .NumChannels () == 0 {
138
169
return 0
139
170
}
140
171
return len (floats [0 ])
141
172
}
142
173
143
- // Append buffers set to existing one one
144
- // new buffer is returned if b is nil
174
+ // Append buffers to existing one.
175
+ // New buffer is returned if b is nil.
145
176
func (floats Float64 ) Append (source Float64 ) Float64 {
146
177
if floats == nil {
147
178
floats = make ([][]float64 , source .NumChannels ())
@@ -155,13 +186,12 @@ func (floats Float64) Append(source Float64) Float64 {
155
186
return floats
156
187
}
157
188
158
- // Slice creates a new copy of buffer from start position with defined legth
159
- // if buffer doesn't have enough samples - shorten block is returned
160
- //
161
- // if start >= buffer size, nil is returned
162
- // if start + len >= buffer size, len is decreased till the end of slice
163
- // if start < 0, nil is returned
164
- func (floats Float64 ) Slice (start int , len int ) Float64 {
189
+ // Slice creates a new buffer that refers to floats data from start
190
+ // position with defined legth. Shorten block is returned if buffer
191
+ // doesn't have enough samples. If start is less than 0 or more than
192
+ // buffer size, nil is returned. If len goes beyond the buffer size,
193
+ // it's truncated up to length of the buffer.
194
+ func (floats Float64 ) Slice (start , len int ) Float64 {
165
195
if floats == nil || start >= floats .Size () || start < 0 {
166
196
return nil
167
197
}
@@ -171,7 +201,22 @@ func (floats Float64) Slice(start int, len int) Float64 {
171
201
if end > floats .Size () {
172
202
end = floats .Size ()
173
203
}
174
- result [i ] = append ( result [ i ], floats [i ][start :end ]... )
204
+ result [i ] = floats [i ][start :end ]
175
205
}
176
206
return result
177
207
}
208
+
209
+ // Sum adds values from one buffer to another.
210
+ // The lesser dimensions are used.
211
+ func (floats Float64 ) Sum (b Float64 ) Float64 {
212
+ if floats == nil {
213
+ return nil
214
+ }
215
+
216
+ for i := 0 ; i < len (floats ) && i < len (b ); i ++ {
217
+ for j := 0 ; j < len (floats [i ]) && j < len (b [i ]); j ++ {
218
+ floats [i ][j ] += b [i ][j ]
219
+ }
220
+ }
221
+ return floats
222
+ }
0 commit comments