AudioStream and Buffer objects have nearly all of their mathematical operators overloaded. It is easy to manipulate the data they contain. Every operation that can be done on a Buffer can be done on an AudioStream. In the following examples, only the Buffer case will be demonstrated, but it can easily be done to an AudioStream as well.
After creating an empty Buffer, one can insert samples into it with concatenation:
import Nsound as ns
b = ns.Buffer()
b << 1 << 2 << 3
print b.getLength()
# 3
print b.toList()
# [1.0, 2.0, 3.0]
Buffers can be concatenated together:
b2 = ns.Buffer()
b2 << 6 << 7 << 8
b << b2
print b.getLength()
# 6
print b.toList()
# [1.0, 2.0, 3.0, 6.0, 7.0, 8.0]
When a scaler is applied to a Buffer or AudioStream, the scalar is applied element-wise for all the samples contained in the Buffer:
import Nsound as ns
b = ns.Buffer()
b << 1 << 2 << 3 << 6 << 7 << 8
print b.toList()
# [1.0, 2.0, 3.0, 6.0, 7.0, 8.0]
b += 1.0 # b = b + 1.0 would also work
print b.toList()
# [2.0, 3.0, 6.0, 7.0, 8.0, 9.0]
b *= 2.0
print b.toList()
# [4.0, 6.0, 12.0, 14.0, 16.0, 18.0]
b /= 3.0
print b.toList()
# [1.3333, 2.0, 2.6666, 4.6666, 5.3333, 6.0]
Nsound also allows element-wise math between two Buffers. Unlike other packages such as Numpy or Matlab, the Buffers don’t have to be the same length:
import Nsound as ns
b1 = ns.Buffer()
b1 << 1 << 1 << 1
b2 = ns.Buffer()
b2 << 0 << 1 << 1 << 1
# Addition
b3 = b1 + b2
print b3.toList()
# [1.0, 2.0, 2.0]
b3 = b2 + b1
print b3
# [1.0, 2.0, 2.0, 1.0]
# Subtraction
b3 = b1 - b2
print b3.toList()
# [1.0, 0.0, 0.0]
b3 = b2 - b1
print b3.toList()
# [-1.0, 0.0, 0.0, 1.0]
# Products
b3 = b1 * b2
print b3.toList()
# [0.0, 1.0, 1.0]
b3 = b2 * b1
print b3.toList()
# [0.0, 1.0, 1.0, 1.0]
# Quotients
b3 = b1 / b2
print b3.toList()
# [1e+20, 1.0, 1.0]
b3 = b2 / b1
print b3.toList()
# [0.0, 1.0, 1.0, 1.0]