From 80e92d1cab560f77900f66a002e54ccc9a59d424 Mon Sep 17 00:00:00 2001 From: Anthony Wang Date: Mon, 3 Oct 2022 18:12:57 -0400 Subject: [PATCH] Commit all testing programs --- beepemu | 8 ++------ beepemu-pyaudio | 46 +++++++++++++++++++++++++++++++++++++++++++++ beepemu-pysinewave | 30 +++++++++++++++++++++++++++++ beepemu-sox | 26 +++++++++++++++++++++++++ test.py | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 151 insertions(+), 6 deletions(-) create mode 100755 beepemu-pyaudio create mode 100755 beepemu-pysinewave create mode 100755 beepemu-sox create mode 100644 test.py diff --git a/beepemu b/beepemu index b74d197..6fb9487 100755 --- a/beepemu +++ b/beepemu @@ -1,9 +1,8 @@ #!/usr/bin/python -import math +import os import sys import time -from pysinewave import SineWave i = 1 f = 0 @@ -20,11 +19,8 @@ while i < len(sys.argv): time.sleep(float(sys.argv[i])/1000) if f != 0 and l != 0: print(f, l) - s = SineWave(pitch_per_second=1000) - s.set_frequency(f) - s.play() + os.system(f'play -n synth {l} sawtooth {f} &') time.sleep(l) - s.stop() f = 0 l = 0 i += 1 diff --git a/beepemu-pyaudio b/beepemu-pyaudio new file mode 100755 index 0000000..f0d3347 --- /dev/null +++ b/beepemu-pyaudio @@ -0,0 +1,46 @@ +#!/usr/bin/python + +import math +import os +import sys +import time +import pyaudio + +p = pyaudio.PyAudio() +sample_rate=44100 +stream = p.open( + format=pyaudio.paInt16, + channels=1, + rate=sample_rate, + output=True +) +stream.start_stream() + +i = 1 +f = 0 +l = 0 +while i < len(sys.argv): + if sys.argv[i] == '-f': + i += 1 + f = float(sys.argv[i]) + elif sys.argv[i] == '-l': + i += 1 + l = float(sys.argv[i])/1000 + elif sys.argv[i] == '-D': + i += 1 + time.sleep(float(sys.argv[i])/1000) + if f != 0 and l != 0: + print(f, l) + # https://stackoverflow.com/questions/974071/python-library-for-playing-fixed-frequency-sound + num_samples = int(sample_rate * l) + rest_frames = num_samples % sample_rate + s = lambda i: 0.25 * math.sin(2 * math.pi * f * i / sample_rate) + samples = (int(s(i) * 0x7F + 0x80) for i in range(num_samples)) + # write several samples at a time + for buf in zip( *([samples] * sample_rate) ): + stream.write(bytes(buf)) + # fill remainder of frameset with silence + stream.write(b'\x80' * rest_frames) + f = 0 + l = 0 + i += 1 diff --git a/beepemu-pysinewave b/beepemu-pysinewave new file mode 100755 index 0000000..b74d197 --- /dev/null +++ b/beepemu-pysinewave @@ -0,0 +1,30 @@ +#!/usr/bin/python + +import math +import sys +import time +from pysinewave import SineWave + +i = 1 +f = 0 +l = 0 +while i < len(sys.argv): + if sys.argv[i] == '-f': + i += 1 + f = float(sys.argv[i]) + elif sys.argv[i] == '-l': + i += 1 + l = float(sys.argv[i])/1000 + elif sys.argv[i] == '-D': + i += 1 + time.sleep(float(sys.argv[i])/1000) + if f != 0 and l != 0: + print(f, l) + s = SineWave(pitch_per_second=1000) + s.set_frequency(f) + s.play() + time.sleep(l) + s.stop() + f = 0 + l = 0 + i += 1 diff --git a/beepemu-sox b/beepemu-sox new file mode 100755 index 0000000..6fb9487 --- /dev/null +++ b/beepemu-sox @@ -0,0 +1,26 @@ +#!/usr/bin/python + +import os +import sys +import time + +i = 1 +f = 0 +l = 0 +while i < len(sys.argv): + if sys.argv[i] == '-f': + i += 1 + f = float(sys.argv[i]) + elif sys.argv[i] == '-l': + i += 1 + l = float(sys.argv[i])/1000 + elif sys.argv[i] == '-D': + i += 1 + time.sleep(float(sys.argv[i])/1000) + if f != 0 and l != 0: + print(f, l) + os.system(f'play -n synth {l} sawtooth {f} &') + time.sleep(l) + f = 0 + l = 0 + i += 1 diff --git a/test.py b/test.py new file mode 100644 index 0000000..2849213 --- /dev/null +++ b/test.py @@ -0,0 +1,47 @@ +import math +from pyaudio import PyAudio, paUInt8 + +def generate_sine_wave(frequency, duration, volume=0.2, sample_rate=22050): + ''' Generate a tone at the given frequency. + + Limited to unsigned 8-bit samples at a given sample_rate. + The sample rate should be at least double the frequency. + ''' + if sample_rate < (frequency * 2): + print('Warning: sample_rate must be at least double the frequency ' + f'to accurately represent it:\n sample_rate {sample_rate}' + f' ≯ {frequency*2} (frequency {frequency}*2)') + + num_samples = int(sample_rate * duration) + rest_frames = num_samples % sample_rate + + pa = PyAudio() + stream = pa.open( + format=paUInt8, + channels=1, # mono + rate=sample_rate, + output=True, + ) + + # make samples + s = lambda i: volume * math.sin(2 * math.pi * frequency * i / sample_rate) + samples = (int(s(i) * 0x7F + 0x80) for i in range(num_samples)) + + # write several samples at a time + for buf in zip( *([samples] * sample_rate) ): + stream.write(bytes(buf)) + + # fill remainder of frameset with silence + stream.write(b'\x80' * rest_frames) + + stream.stop_stream() + stream.close() + pa.terminate() + +generate_sine_wave( + # see http://www.phy.mtu.edu/~suits/notefreqs.html + frequency=440, # Hz, waves per second C6 + duration=0.2, # seconds to play sound + volume=0.25, # 0..1 how loud it is + sample_rate=44100, # number of samples per second: 11025, 22050, 44100 +)