Regarding inability of Python Module Winsound to produce beep in decimal frequency

John O'Hagan research at johnohagan.com
Sat Aug 14 23:01:17 EDT 2021


On Fri, 13 Aug 2021 17:41:05 +0100
MRAB <python at mrabarnett.plus.com> wrote:

> On 2021-08-13 17:17, Chris Angelico wrote:
> > On Sat, Aug 14, 2021 at 2:11 AM Terry Reedy <tjreedy at udel.edu>
> > wrote:
> >>
> >> On 8/13/2021 6:53 AM, Umang Goswami wrote:
> >> > Hi There, Hope you find this mail in good health.
> >> >
> >> > I am Umang Goswami, a Python developer and student working on a
> >> > huge project for automation of music instruments. I am producing
> >> > the musical notes using the Beep function of Winsound Module(
> >> > https://docs.python.org/3/library/winsound.html) by passing
> >> > frequency as a argument to the function.
> >> >
> >> > Now whenever i provide frequency of any note in decimal(for
> >> > example 277.1826 for C4 note) it shows following error:
> >> > Traceback (most recent call last):
> >> >    File "C:\Users\Umang Goswami\Desktop\Umang  Goswami\test.py",
> >> > line 2, in <module>
> >> >      winsound.Beep(111.11,111111)
> >> > TypeError: integer argument expected, got float
> >> >
> >> > Now I have  to round up the frequencies. This is hurting the
> >> > quality, accuracy ,authenticity and future of the project.
> >> > Almost all the notes have the frequencies  in decimal parts.
> >> > Rounding up means changing semitones and quatertones thus whole
> >> > note itself. This problem is technically making my program
> >> > useless.
> >> >
> > 
> > Is it really? In my experience, no human ear can distinguish 277Hz
> > from 277.1826Hz when it's played on a one-bit PC speaker, which the
> > Beep function will be using.
> > 
> I've just tried it on my PC and I couldn't hear the difference,
> except that odd frequencies had a momentary break in them during
> longer notes whereas even frequencies didn't. Very odd...

Rounding to integer frequencies will produce disastrously out-of-tune
notes in a musical context! Particularly for low notes, where a whole
semitone is only a couple of Hz difference. Even for higher notes, when
they're played together any inaccuracies are much more apparent.

To the OP, there aren't too many options in pure python for playing
audio - to do anything complicated I've used applications such as
Fluidsynth and sox as python subprocesses. 

But for playing purely generated tones, here's an example that doesn't
limit frequency precision, using pyaudio to play a numpy array
representing a sine-wave:

import pyaudio, numpy as np

f = 555.555 #frequency
d = 1.0 # duration in seconds
rate = 44100 #sample rate
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paFloat32, channels=1, rate=rate,
output=True)
samples = np.sin(2*np.pi*np.arange(rate*d)*f/rate).astype(np.float32)
stream.write(samples)

Hope this helps

John


More information about the Python-list mailing list