DrawWaveform — wiki
How to draw a sound wave form onto a surface.
# python built in array type is useful for storing sound data.
import array
# a square wave tone, with sample values between -32766 and 32766.
samples = array.array('h', [32766, 32766, 32766, 32766, 32766, 32766,
32766, 32766, 32766, 32766, 32766, 32766, 32766, 32766, 32766,
32766, 32766, 32766, 32766, 32766, 32766, 32766, 32766, 32766,
32766, 32766, 32766, 32766, -32766, -32766, -32766, -32766,
-32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766,
-32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766,
-32766, -32766, -32766, -32766, -32766, -32766, -32766])
def scale_samples_to_surf(width, height, samples):
""" Returns a generator containing (x, y) to draw a waveform.
:param width: width of surface to scale points to.
:param height: height of surface to scale points to.
:param samples: an array of signed 1 byte or signed 2 byte.
"""
assert samples.typecode in ['h', 'b']
# precalculate a bunch of variables, so not done in the loop.
len_samples = len(samples)
width_per_sample = width / len_samples
height_1 = height - 1
if samples.typecode == 'h':
# for array typecode 'h', -32768 to 32768
factor = 1.0 / 65532
normalize_modifier = int(65532 / 2)
elif samples.typecode == 'b':
# for array typecode 'b', -127 to 127
factor = 1.0 / 256
normalize_modifier = int(256 / 2)
return ((
int((sample_number + 1) * width_per_sample),
int(
(1.0 -
(factor *
(samples[sample_number] + normalize_modifier)))
* (height_1)
))
for sample_number in range(len_samples))
def draw_wave(surf,
samples,
wave_color = (0, 0, 0),
background_color = pg.Color('white')):
"""Draw array of sound samples as waveform into the 'surf'.
:param surf: Surface we want to draw the wave form onto.
:param samples: an array of signed 1 byte or signed 2 byte.
:param wave_color: color to draw the wave form.
:param background_color: to fill the 'surf' with.
"""
assert samples.typecode in ['h', 'b']
if background_color is not None:
surf.fill(background_color)
width, height = surf.get_size()
points = tuple(scale_samples_to_surf(width, height, samples))
pg.draw.lines(surf, wave_color, False, points)
# Here we should how to draw it onto a screen.
waveform = pg.Surface((320, 200)).convert_alpha()
draw_wave(waveform, samples)
screen.fill((255, 255, 255))
screen.blit(waveform, (160, 100))