Next: imageop Prev: MULTIMEDIA EXTENSIONS Up: MULTIMEDIA EXTENSIONS Top: Top
audioop
al
and sunaudiodev
modules. All
scalar items are integers, unless specified otherwise.
A few of the more complicated operations only take 16-bit samples, otherwise the sample size (in bytes) is always a parameter of the operation.
The module defines the following variables and functions:
1
, 2
or 4
. Both fragments should have the same length.
lin2adpcm
for details on ADPCM
coding. The routine returns a tuple
(sample, newstate)
where the sample has the width specified in width.
lin2adpcm3
for details.
rms(add(fragment, mul(reference, -F)))
is minimal, i.e. it calculates the factor with which you should
multiply reference to make it match as good as possible to
fragment. The fragments should be the same size.
The time taken by this routine is proportional to len(fragment)
.
findfactor
to compute the best match, and minimizing the
result.
It returns a tuple (offset, factor)
with offset the
(integer) offset into fragment where the optimal match started
and factor the floating-point factor as per findfactor.
rms(fragment[i*2:(i+length)*2])
is maximal.
The routine takes time proportional to len(fragment)
.
State
is a tuple containing the state of the coder. The coder
returns a tuple (adpcmfrag, newstate)
, and the
newstate should be passed to the next call of lin2adpcm. In the
initial call None
can be passed as the state. adpcmfrag is
the ADPCM coded fragment packed 2 4-bit values per byte.
mul
or max
make no
distinction between mono and stereo fragments, i.e. all samples are
treated equal. If this is a problem the stereo fragment should be split
into two mono fragments first and recombined later. Here is an example
of how to do that:
def mul_stereo(sample, width, lfactor, rfactor):
lsample = audioop.tomono(sample, width, 1, 0)
rsample = audioop.tomono(sample, width, 0, 1)
lsample = audioop.mul(sample, width, lfactor)
rsample = audioop.mul(sample, width, rfactor)
lsample = audioop.tostereo(lsample, width, 1, 0)
rsample = audioop.tostereo(rsample, width, 0, 1)
return audioop.add(lsample, rsample, width)
struct
to store the state in
binary you can code the first element (the predicted value) in 16 bits
and the second (the delta index) in 8.
The ADPCM coders have never been tried against other ADPCM coders, only against themselves. It could well be that I misinterpreted the standards in which case they will not be interoperable with the respective standards.
The find...
routines might look a bit funny at first sight.
They are primarily meant for doing echo cancellation. A reasonably
fast way to do this is to pick the most energetic piece of the output
sample, locate that in the input sample and subtract the whole output
sample from the input sample:
def echocancel(outputdata, inputdata):
pos = audioop.findmax(outputdata, 800) # one tenth second
out_test = outputdata[pos*2:]
in_test = inputdata[pos*2:]
ipos, factor = audioop.findfit(in_test, out_test)
# Optional (for better cancellation):
# factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)],
# out_test)
prefill = '\0'*(pos+ipos)*2
postfill = '\0'*(len(inputdata)-len(prefill)-len(outputdata))
outputdata = prefill + audioop.mul(outputdata,2,-factor) + postfill
return audioop.add(inputdata, outputdata, 2)