Looking for a (simple) Python tone generator to use in following script running on the RaspberryPi with USB sound card. On-fly tone on/off and frequency change are required.
import serial, time
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=0.1)
def monitor(inp=0):
if inp != inpold:
if inp != 0:
ser.setDTR(1) # LED on (GPIO?)
# start tone here, generate tone forever or change tone freq
else:
ser.setDTR(0) # LED off
# stop tone without clicks
inpold = inp
while True:
time.sleep(0.01) # min length tone pulse 10 milliseconds
input = ser.getCTS() # or GPIO input
monitor(input)
So I've found several ways to do this and I am going to lay them in order of feasibility (easiest to apply first):-
Assumptions about the tone:-
Wave type = Sinusodial
Frequency = 440Hz
1- Use the Audacity software (or any similar software) to create a particular tone and export it to a file.
2- From Audacity, pick "Generate" from the tabs above then choose "Tone" and put 440 next to the frequency.
3- From Audacity, pick "File" from the tabs above then choose "Export" and select export as any extension you like, preferably mp3. 'out.mp3'
4- pip install playsound
5- In python
import playsound
playsound.playsound('out.mp3')
1- pip install pygame
2- If you're working under a Linux environment then please make sure you install the following libraries
libsdl1.2-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev
3- In python
import numpy
import pygame
sampleRate = 44100
freq = 440
pygame.mixer.init(44100,-16,2,512)
# sampling frequency, size, channels, buffer
# Sampling frequency
# Analog audio is recorded by sampling it 44,100 times per second,
# and then these samples are used to reconstruct the audio signal
# when playing it back.
# size
# The size argument represents how many bits are used for each
# audio sample. If the value is negative then signed sample
# values will be used.
# channels
# 1 = mono, 2 = stereo
# buffer
# The buffer argument controls the number of internal samples
# used in the sound mixer. It can be lowered to reduce latency,
# but sound dropout may occur. It can be raised to larger values
# to ensure playback never skips, but it will impose latency on sound playback.
arr = numpy.array([4096 * numpy.sin(2.0 * numpy.pi * freq * x / sampleRate) for x in range(0, sampleRate)]).astype(numpy.int16)
arr2 = numpy.c_[arr,arr]
sound = pygame.sndarray.make_sound(arr2)
sound.play(-1)
pygame.time.delay(1000)
sound.stop()
use this if all you need is a sinusoidal wave
1- pip install pysine
2- if you're working under a Linux environment then please make sure you install the following library
portaudio19-dev
however, if you're working under a Windows environment then please make sure you install this using pipwin
pipwin install pysine
3- In python
import pysine
pysine.sine(frequency=440.0, duration=1.0)
Try pysinewave. It allows you to start, stop, and smoothly change pitch and volume of a tone.
Example:
from pysinewave import SineWave
import time
sinewave = SineWave(pitch = 12)
sinewave.play()
time.sleep(1)
sinewave.stop()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With