1

I am trying to put together some code in Python 3.6 to help test the computer hardware that passes through my hands as an IT tech.

I'd like to have a script that plays a simple sine wave tone on the left speaker, then the right and then the both speakers together.

I have found a potentially helpful script over at Pyaudio How to get sound on only one speaker but some of the code to actually run it is missing - chiefly the code for making sin wave tones. I have looked around online and have tried reverse-engineering this back into the code on that page but the maths is a little high-level for me! Sorry.

Thanks,

Will

Update: I think I have found a partial (albeit long-winded solution) with 'sounddevice' for python 3

#!/usr/bin/env python3
import argparse
import logging

parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("filename", help="audio file to be played back")
parser.add_argument("-d", "--device", type=int, help="device ID")
args = parser.parse_args()


try:
    import sounddevice as sd
    import soundfile as sf
    data, fs = sf.read(args.filename, dtype='float32')
    sd.play(data, fs, device=args.device, blocking=True, mapping=[1])
    status = sd.get_status()
    if status:
        logging.warning(str(status))
except BaseException as e:
    # This avoids printing the traceback, especially if Ctrl-C is used.
    raise SystemExit(str(e))

The main chunk of code is repeat twice more but with "mapping = [1]" changed to "mapping = [2]" to test the right speaker and finally with "mapping = [?]" removed in the final block to test both speakers.

I found this over at https://python-sounddevice.readthedocs.io/en/0.2.1/examples.html.

Of course, if anyone knows a quicker and graceful way of getting this done, please share!

William Lombard
  • 337
  • 1
  • 3
  • 14

1 Answers1

2

You could generate the sine tone directly in Python instead of loading it from a file. I've written some tutorials about creating simple sine tones:

Those tutorials use NumPy, because it makes manipulating the audio buffers very easy. But you can of course also do it in pure Python, if you prefer. Here's an example:

#!/usr/bin/env python3
import math
import sounddevice as sd

sd.default.device = None
sd.default.samplerate = samplerate = 48000

duration = 1.5
volume = 0.3
frequency = 440

# fade time in seconds:
fade_in = 0.01
fade_out = 0.3

buffer = memoryview(bytearray(int(duration * samplerate) * 4)).cast('f')

for i in range(len(buffer)):
    buffer[i] = volume * math.cos(2 * math.pi * frequency * i / samplerate)

fade_in_samples = int(fade_in * samplerate)
for i in range(fade_in_samples):
    buffer[i] *= i / fade_in_samples

fade_out_samples = int(fade_out * samplerate)
for i in range(fade_out_samples):
    buffer[-(i + 1)] *= i / fade_out_samples

for mapping in ([1], [2], [1, 2]):
    sd.play(buffer, blocking=True, mapping=mapping)
    sd.sleep(500)

Note that this code is using 32-bit floating point numbers (each one using 4 bytes), that's why we reserve 4 times more bytes in our bytearray than the required number of samples.

Matthias
  • 4,524
  • 2
  • 31
  • 50