Re: [Tutor] Sigh first real python task

2012-09-13 Thread eryksun
On Wed, Sep 12, 2012 at 11:06 PM, Mike S  wrote:

> try:
> ret = subprocess.call("smbclient //reportingmachine/Dashboard/; put
> %s\" -U Username%Password" % (fileName), shell=True)
> if ret < 0:
> print >>sys.stderr, "Child was terminated by signal", -ret
> else:
> os.unlink(path+fileName)
> except OSError, e:
> print >>sys.stderr, "Execution failed:", e

I don't see a need to run this through the shell. I'd just use a list
of arguments.

Do you only want to delete the file if smbclient is killed by a
signal? What if it fails for some other reason with a return code of
1? In the example below I assume the file is removed only if the put
command succeeds.

>From what I gather using "man smbclient", the basic template here is
the following:

smbclient servicename password -U username -c "put filename"

The code below uses subprocess.check_call, which raises a
CalledProcessError if the return code is non-zero. The variables
username, password, filename, and path are strings.

import sys
import os
from subprocess import check_call, CalledProcessError

servicename = "//reportingmachine/Dashboard/"

try:
check_call(["smbclient", servicename, password, "-U", username,
"-c", "put %s" % filename])

os.unlink(os.path.join(path, filename))

except CalledProcessError as e:
print >>sys.stderr, "call failed:", e

except OSError as e:
print >>sys.stderr, "unlink failed:", e
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Print List

2012-09-13 Thread Alan Gauld

On 13/09/12 00:36, aklei...@sonic.net wrote:


To make it even more generic I would suggest replacing
"""   print(theHeader) """
with
"""   if theHeader:
   print(theHeader)
"""
to avoid a blank line if you don't need/want a header line.


Good catch, yes, that would be better.


--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Sigh first real python task

2012-09-13 Thread Alan Gauld

On 13/09/12 04:06, Mike S wrote:

ret = subprocess.call("smbclient //metricsmachine/reports/; put %s\" -U
metrics%%" % (fileName), shell=True)


Isn't there a mismatched quote in there?



--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Musical note on python

2012-09-13 Thread D . V . N . Sarma డి . వి . ఎన్ . శర్మ
I want to thank all of you who have come forward to help me.


-- 
regards,
Sarma.

On Thu, Sep 13, 2012 at 10:46 AM, D.V.N.Sarma డి.వి.ఎన్.శర్మ <
dvnsa...@gmail.com> wrote:

> Yes. As far as I can see it does not contain any thing which
> concerns the volume of sound.
>
>
> --
> regards,
> Sarma.
>
> On Thu, Sep 13, 2012 at 5:42 AM, Mark Lawrence wrote:
>
>> On 13/09/2012 00:57, D.V.N.Sarma డి.వి.ఎన్.శర్మ wrote:
>>
>>> The Beep attribute of winsound module is useful. But the volume is
>>> feeble.
>>> Is there anyway to control the loudness.
>>>
>>>
>> Have you read 
>> http://docs.python.org/**library/winsound.html?
>>
>> --
>> Cheers.
>>
>> Mark Lawrence.
>>
>>
>> __**_
>> Tutor maillist  -  Tutor@python.org
>> To unsubscribe or change subscription options:
>> http://mail.python.org/**mailman/listinfo/tutor
>>
>
>
>
>
>
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] simon game issues

2012-09-13 Thread Matthew Ngaha
Hi guys. my Python tutorial set me a task to recreate a simon game
using livewires.
http://www.youtube.com/watch?v=agUABjGAJww
this is quite long, i understand if you can't help right away

summary:
i create 4 squared shaped objects(red, blue, green, yellow) as
instances for a class derived from the Sprite class
i create 4 animation objects to represent the 4 colour shaped objects.
the animations get brighter in colour so the user can understand which
colour he has to follow
the animations also light up when the user presses the keyboard key
they are assigned too.
they are instances for a class derived from the Animation class.
i have also included 4 sound files, assigned to 1 animation object to
be played each time that animation lights up

My problems:
everytime i want to play a sequence for the user to follow. i run into
this problem. i create 1 animation say red, so the user can see the
1st colour he has to follow. then i put a timed delay time.sleep(1)
before i display the next animation, say blue. i have tried many other
timing methods to achieve this, but once there is some sort of timer,
the whole screen pauses for the duration of the timed delay (but the
sound files play simultaneously during that freeze) then after that,
the sequence is displayed at the same time. not 1 after the other. so
even though i put the timer after the creation of the 1st animation,
the timer for some reason happens before it. is there a way i can get
around this?

I also start the game/program by displaying the 4 square objects
(Sprite Class) before adding their animation. after the creation of
the sprites i play the animation sequence. The problem is they play as
soon as the game starts before the Sprites are even displayed, and
also simultaneously (not in a sequnce) making it confusng. so after
creating the sprites, i added a timer so the animations happens after
the sprites are shown. But again because of this timer, which is meant
to occur after the creation of the sprites, when i start the game, i
get a blank screen for the duration of the timer((but the sound files,
again play simultaneously during that time). After that i still don't
get the sprites, i get their animatons instead, then finally the
sprites are displayed. i dont understand, the Sprites are meant to be
the 1st things on the screen, is there a solution?

Getting user input:
the last problem i have is when the user presses a key to select a
colour. i have the script check for the key press, then return the
colour to a function/method called def result(self, color): that
determines if he got the right colour. if he does i increase score by
1. to check results i create 2 lists. one with all 4 colours:

self.animation = [Pressed.dict_red, Pressed.dict_blue,
Pressed.dict_green, Pressed.dict_yellow]
then i create an empty list to append the sequence in the order i
randomly played them, so i can check if the user got each colour:
self.get_animation = [] < they append from the 1st list above and my
result function uses it to check colours

here's how it goes.
if keyboard for colour red is pressed:
create red animation:
send results back to result method: self.game.result(red)

my result method and its class:
self.stage = 3   ..#say if we were on stage 3. i would play 3
colours. stage 4 would be 4 colours

self.counter = -1 .#to correctly index list
def result(self, COLOUR):
self.counter += 1#count is now at 0
self.end_testing = self.stage..#this will count down from
the stages value. once it reaches 0, there is no more colours to check
for

if COLOUR in self.get_animation[self.counter]:
self.score.value += 1
self.end_testing -= 1

even though i am using a counter here to count down: self.end_testing
< i have used while and for loops also. My problem is none of these
work because a keypress from the user, even if tapped, registers as
multiple key presses, the self.score that i increment by 1 flies to
about 40 from 1 key press. as a result my counter i use to index the
list is way out of range. i tried to add a time.sleep(.03) as soon as
a key is pressed, so it would register once. it managed to limit it to
4 presses, so self.score would equal 4 after 1 press, 8 after 2.. in
that i started my counter at -4. then the code self.counter /= 4 would
give me 0. after the next 4 presses, my counter would be at 4, the
same code self.counter /= 4 would give me 1. after the next 4 presses,
my counter would be at 8, the same code self.counter /= 4 would give
me 2. this successfully fixed my indexing issue, but it needs A LOT of
if statements and it is getting to confusing. isnt there a way to make
1 key press mean 1? and not 40? other wise how can i keep track of the
score. any help? do i quit this exercise and blame it on the program
just not following my instructions?
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python

Re: [Tutor] Musical note on python

2012-09-13 Thread Mark Lawrence

On 13/09/2012 13:29, D.V.N.Sarma డి.వి.ఎన్.శర్మ wrote:

I want to thank all of you who have come forward to help me.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor



No problem :)  If you have found a solution could you please publish it 
here for the benefit of others, or at least provide a link.


--
Cheers.

Mark Lawrence.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Musical note on python

2012-09-13 Thread D . V . N . Sarma డి . వి . ఎన్ . శర్మ
As far as programming volume is concerned winsound.Beep has only frequency
and duration.
pyaudio module appears to have provision for volume control. Please refer
to eryksun's post.

-- 
regards,
Sarma.

On Thu, Sep 13, 2012 at 8:42 PM, Mark Lawrence wrote:

> On 13/09/2012 13:29, D.V.N.Sarma డి.వి.ఎన్.శర్మ wrote:
>
>> I want to thank all of you who have come forward to help me.
>>
>> __**_
>> Tutor maillist  -  Tutor@python.org
>> To unsubscribe or change subscription options:
>> http://mail.python.org/**mailman/listinfo/tutor
>>
>>
> No problem :)  If you have found a solution could you please publish it
> here for the benefit of others, or at least provide a link.
>
>
> --
> Cheers.
>
> Mark Lawrence.
>
> __**_
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/**mailman/listinfo/tutor
>



-- 
regards,
Sarma.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Does anyone use UML?

2012-09-13 Thread Modulok
List,

Does anyone use UML (Unified Modeling Language) with python? If so, what tools
do you use? Is it worth the added effort?

-Modulok-
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Musical note on python

2012-09-13 Thread eryksun
On Thu, Sep 13, 2012 at 11:48 AM, D.V.N.Sarma డి.వి.ఎన్.శర్మ
 wrote:
>
> As far as programming volume is concerned winsound.Beep has only frequency
> and duration. pyaudio module appears to have provision for volume control.

You should be able to add a wave header to a raw byte string. For example:


import wave
import winsound
from cStringIO import StringIO

def get_wave(data):
f = StringIO()
w = wave.open(f, 'w')
w.setnchannels(1) # mono
w.setsampwidth(2) # 2 bytes
w.setframerate(48000) # samples/second
w.writeframes(data)
return f.getvalue()


Then play the sound like this (_untested_):


wave_data = get_wave(data)
windsound.PlaySound(wave_data, winsound.SND_MEMORY)



I've modified my previous script to add simple polyphonic sound. I
included a basic square wave and a sawtooth wave, plus a random
polyphonic wave. It's the kind of sound you might hear in a cheesy
greeting card. Also, since you're looking to use winsound.PlaySound(),
I changed the byte packing to use a little endian signed short
(int16). I think that's what Windows wave files use.

My demo below still uses pyaudio, which wraps the cross-platform
PortAudio library. To me it seems like a better solution than relying
on the standard library (e.g. the standard lib uses OSS on Linux; I
don't even have that installed).

Hopefully it performs OK on your computer. Using NumPy arrays would
speed up the number crunching.


import pyaudio
from math import sin, pi
from struct import pack
from random import sample, randrange

def polywave(freqs, amps, f0, fs):
"""create a polyphonic waveform

freqs: sequence of frequencies (Hz)
amps: sequence of amplitudes
f0: fundamental frequency (Hz)
fs: samples/second

output is normalized to the range [-1,1].
"""
N = int(fs / f0)
rad_step = 2 * pi / fs  # radians / (Hz * sample)
wave = [0.0] * N
for f, a in zip(freqs, amps):
for n in xrange(N):
wave[n] += a * sin(rad_step * f * n)
maxamp = abs(max(wave, key=lambda x: abs(x)))
return [samp / maxamp for samp in wave]

def packwave(wave, vol=1, duration=None, fs=None):
"""pack a waveform as bytes (int16)

wave: sample sequence, |mag| <= 1
vol: optional volume scale, |mag| <= 1
duration: optional loop time (seconds)
fs: samples/second

fs is required to set duration.
"""
scale = min(vol * 32767, 32767)
ncycles = 1
if not (duration is None or fs is None):
ncycles = int(round(1.0 * duration * fs / len(wave)))
data = b''.join(pack('http://en.wikipedia.org/wiki/
# Equal_temperament#Calculating_absolute_frequencies

note = lambda n: 440 * (2**(1/12.)) ** (-21 + n)

scale = [note(n) for n in range(12)]
rscale = [note(13-n) for n in range(12)]
vols = [0.2 + 0.05*n for n in range(len(scale))]
rvols = list(reversed(vols))

def play_scale(scale, vols, wave_func, master_vol=1):
duration = 0.5
nharmonics = 30
for f0, vol in zip(scale, vols):
freqs, amps = wave_func(nharmonics, f0, fs)
wave = polywave(freqs, amps, f0, fs)
data = packwave(wave, master_vol * vol, duration, fs)
play(data, stream)
sleep(0.5)

play_scale(scale, vols, make_square, 0.5)
play_scale(rscale, rvols, make_saw, 0.5)
play_scale(scale, vols, make_rand, 0.75)
play_scale(rscale, rvols, make_rand, 0.75)

stream.close()
p.terminate()
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] index of elements in numpy array

2012-09-13 Thread Bala subramanian
Friends,
I have a 2D matrix (a numpy array) and i am looping over each row in
the matrix. I would like to know how i can find the index of each
element in a while looping a row. Is there any function in numpy.

Thanks

-- 
C. Balasubramanian
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] index of elements in numpy array

2012-09-13 Thread Oscar Benjamin
On 13 September 2012 21:16, Bala subramanian wrote:

> Friends,
> I have a 2D matrix (a numpy array) and i am looping over each row in
> the matrix. I would like to know how i can find the index of each
> element in a while looping a row. Is there any function in numpy.
>

Your question could mean several things. Could you post a small piece of
example code and clarify what it is you're unable to do?

Here's an example that loops over all elements of a 2D Matrix:

>>> import numpy
>>> M = numpy.array([[1, 1], [2, 3], [5, 8]])
>>> M
array([[1, 1],
   [2, 3],
   [5, 8]])
>>> numrows, numcols = M.shape
>>> for i in range(numrows):
...   for j in range(numcols):
...  print M[i, j]
...
1
1
2
3
5
8

Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Does anyone use UML?

2012-09-13 Thread Alan Gauld

On 13/09/12 18:23, Modulok wrote:


Does anyone use UML (Unified Modeling Language) with python? If so, what tools
do you use? Is it worth the added effort?


I use UML with most things and even in situations where I'm not writing 
code or developing software. It is a good general purpose modelling 
notation for understanding co0mplex problems.


And the last phrase is key. If the problem isn't complex you don't 
really need UML. If you can hold the concept in your head or explain it 
with text/pseudo code you don;t need UML.


If you have a dozen or more classes all interacting and multi-level 
state machines and dozens of different user roles interacting or a 6 or 
7 level deep inheritance lattice or a multi site distributed system then 
UML is invaluable. If you have less than 4 classes and only one level of 
inheritance then you probably don't need it.


In between its a matter of taste and situation.

As for tools I've used everything from Visio/Dia through to IBM RSA and 
Borland Together, and of course whiteboards!


The fact its Python makes no difference at all, what matters is how 
complex is the problem? How many people need to share the understanding? 
Do you even understand it? If you don't understand what you are being 
asked to solve(*) then UML is possibly essential since it gives you the 
analytical tools needed to break the complexity into something you can 
get your head around and the notation to record the result.


(*)The vast majority of the projects I work on start out with
something I don't even begin to comprehendIt often takes 3-6 months 
of analysis before I'm even at the stage of starting a design.


--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] simon game issues

2012-09-13 Thread Dave Angel
On 09/13/2012 10:07 AM, Matthew Ngaha wrote:
> Hi guys. my Python tutorial set me a task to recreate a simon game
> using livewires.
> http://www.youtube.com/watch?v=agUABjGAJww
> this is quite long, i understand if you can't help right away
>
> summary:
> i create 4 squared shaped objects(red, blue, green, yellow) as
> instances for a class derived from the Sprite class
> i create 4 animation objects to represent the 4 colour shaped objects.
> the animations get brighter in colour so the user can understand which
> colour he has to follow
> the animations also light up when the user presses the keyboard key
> they are assigned too.
> they are instances for a class derived from the Animation class.
> i have also included 4 sound files, assigned to 1 animation object to
> be played each time that animation lights up
>
> My problems:
> everytime i want to play a sequence for the user to follow. i run into
> this problem. i create 1 animation say red, so the user can see the
> 1st colour he has to follow. then i put a timed delay time.sleep(1)
> before i display the next animation, say blue. i have tried many other
> timing methods to achieve this, but once there is some sort of timer,
> the whole screen pauses for the duration of the timed delay (but the
> sound files play simultaneously during that freeze) then after that,
> the sequence is displayed at the same time. not 1 after the other. so
> even though i put the timer after the creation of the 1st animation,
> the timer for some reason happens before it. is there a way i can get
> around this?
>
> I also start the game/program by displaying the 4 square objects
> (Sprite Class) before adding their animation. after the creation of
> the sprites i play the animation sequence. The problem is they play as
> soon as the game starts before the Sprites are even displayed, and
> also simultaneously (not in a sequnce) making it confusng. so after
> creating the sprites, i added a timer so the animations happens after
> the sprites are shown. But again because of this timer, which is meant
> to occur after the creation of the sprites, when i start the game, i
> get a blank screen for the duration of the timer((but the sound files,
> again play simultaneously during that time). After that i still don't
> get the sprites, i get their animatons instead, then finally the
> sprites are displayed. i dont understand, the Sprites are meant to be
> the 1st things on the screen, is there a solution?
>
> Getting user input:
> the last problem i have is when the user presses a key to select a
> colour. i have the script check for the key press, then return the
> colour to a function/method called def result(self, color): that
> determines if he got the right colour. if he does i increase score by
> 1. to check results i create 2 lists. one with all 4 colours:
>
> self.animation = [Pressed.dict_red, Pressed.dict_blue,
> Pressed.dict_green, Pressed.dict_yellow]
> then i create an empty list to append the sequence in the order i
> randomly played them, so i can check if the user got each colour:
> self.get_animation = [] < they append from the 1st list above and my
> result function uses it to check colours
>
> here's how it goes.
> if keyboard for colour red is pressed:
> create red animation:
> send results back to result method: self.game.result(red)
>
> my result method and its class:
> self.stage = 3   ..#say if we were on stage 3. i would play 3
> colours. stage 4 would be 4 colours
>
> self.counter = -1 .#to correctly index list
> def result(self, COLOUR):
> self.counter += 1#count is now at 0
> self.end_testing = self.stage..#this will count down from
> the stages value. once it reaches 0, there is no more colours to check
> for
>
> if COLOUR in self.get_animation[self.counter]:
> self.score.value += 1
> self.end_testing -= 1
>
> even though i am using a counter here to count down: self.end_testing
> < i have used while and for loops also. My problem is none of these
> work because a keypress from the user, even if tapped, registers as
> multiple key presses, the self.score that i increment by 1 flies to
> about 40 from 1 key press. as a result my counter i use to index the
> list is way out of range. i tried to add a time.sleep(.03) as soon as
> a key is pressed, so it would register once. it managed to limit it to
> 4 presses, so self.score would equal 4 after 1 press, 8 after 2.. in
> that i started my counter at -4. then the code self.counter /= 4 would
> give me 0. after the next 4 presses, my counter would be at 4, the
> same code self.counter /= 4 would give me 1. after the next 4 presses,
> my counter would be at 8, the same code self.counter /= 4 would give
> me 2. this successfully fixed my indexing issue, but it needs A LOT of
> if statements and it is getting to confusing. isnt there a way to make
> 1 key press mean 1? and not 40? other wise how can i keep track of the
> score. any help? do i quit this

Re: [Tutor] index of elements in numpy array

2012-09-13 Thread akleider
> On 13 September 2012 21:16, Bala subramanian
> wrote:
>
>> Friends,
>> I have a 2D matrix (a numpy array) and i am looping over each row in
>> the matrix. I would like to know how i can find the index of each
>> element in a while looping a row. Is there any function in numpy.
>>
>
> Your question could mean several things. Could you post a small piece of
> example code and clarify what it is you're unable to do?
>
> Here's an example that loops over all elements of a 2D Matrix:
>
 import numpy
 M = numpy.array([[1, 1], [2, 3], [5, 8]])
 M
> array([[1, 1],
>[2, 3],
>[5, 8]])
 numrows, numcols = M.shape
 for i in range(numrows):
> ...   for j in range(numcols):
> ...  print M[i, j]
> ...
> 1
> 1
> 2
> 3
> 5
> 8
>
> Oscar

I think what he wants is to replace your print statement with
"""
  if :
  print "Indeces are %d and %d."%(i, j, )
"""

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] index of elements in numpy array

2012-09-13 Thread Dave Angel
On 09/13/2012 04:16 PM, Bala subramanian wrote:
> Friends,
> I have a 2D matrix (a numpy array) and i am looping over each row in
> the matrix. I would like to know how i can find the index of each
> element in a while looping a row. Is there any function in numpy.
>
> Thanks
>

Perhaps you're asking a more general question.  When iterating over a
collection, sometimes you not only want the object, but you also want
the index you might have used to fetch it.

for row in rows:
   dosomething with row

for index, row in enumerate(rows):
   dosomething with row and with index

Now if rows be a list, or whatever numpy decides to call it, then you
can manipulate the particular one with rows[index].



-- 

DaveA

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Musical note on python

2012-09-13 Thread D . V . N . Sarma డి . వి . ఎన్ . శర్మ
Error: "name data undefined"


On Fri, Sep 14, 2012 at 12:33 AM, eryksun  wrote:

> On Thu, Sep 13, 2012 at 11:48 AM, D.V.N.Sarma డి.వి.ఎన్.శర్మ
>  wrote:
> >
> > As far as programming volume is concerned winsound.Beep has only
> frequency
> > and duration. pyaudio module appears to have provision for volume
> control.
>
> You should be able to add a wave header to a raw byte string. For example:
>
>
> import wave
> import winsound
> from cStringIO import StringIO
>
> def get_wave(data):
> f = StringIO()
> w = wave.open(f, 'w')
> w.setnchannels(1) # mono
> w.setsampwidth(2) # 2 bytes
> w.setframerate(48000) # samples/second
> w.writeframes(data)
> return f.getvalue()
>
>
> Then play the sound like this (_untested_):
>
>
> wave_data = get_wave(data)
> windsound.PlaySound(wave_data, winsound.SND_MEMORY)
>
>
>
>
-- 
regards,
Sarma.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Musical note on python

2012-09-13 Thread D . V . N . Sarma డి . వి . ఎన్ . శర్మ
This worked on my computor. Thank you. It will take me sometime to
digest the program.


-- 
regards,
Sarma.

On Fri, Sep 14, 2012 at 12:33 AM, eryksun  wrote:

>
> I've modified my previous script to add simple polyphonic sound. I
> included a basic square wave and a sawtooth wave, plus a random
> polyphonic wave. It's the kind of sound you might hear in a cheesy
> greeting card. Also, since you're looking to use winsound.PlaySound(),
> I changed the byte packing to use a little endian signed short
> (int16). I think that's what Windows wave files use.
>
> My demo below still uses pyaudio, which wraps the cross-platform
> PortAudio library. To me it seems like a better solution than relying
> on the standard library (e.g. the standard lib uses OSS on Linux; I
> don't even have that installed).
>
> Hopefully it performs OK on your computer. Using NumPy arrays would
> speed up the number crunching.
>
>
> import pyaudio
> from math import sin, pi
> from struct import pack
> from random import sample, randrange
>
> def polywave(freqs, amps, f0, fs):
> """create a polyphonic waveform
>
> freqs: sequence of frequencies (Hz)
> amps: sequence of amplitudes
> f0: fundamental frequency (Hz)
> fs: samples/second
>
> output is normalized to the range [-1,1].
> """
> N = int(fs / f0)
> rad_step = 2 * pi / fs  # radians / (Hz * sample)
> wave = [0.0] * N
> for f, a in zip(freqs, amps):
> for n in xrange(N):
> wave[n] += a * sin(rad_step * f * n)
> maxamp = abs(max(wave, key=lambda x: abs(x)))
> return [samp / maxamp for samp in wave]
>
> def packwave(wave, vol=1, duration=None, fs=None):
> """pack a waveform as bytes (int16)
>
> wave: sample sequence, |mag| <= 1
> vol: optional volume scale, |mag| <= 1
> duration: optional loop time (seconds)
> fs: samples/second
>
> fs is required to set duration.
> """
> scale = min(vol * 32767, 32767)
> ncycles = 1
> if not (duration is None or fs is None):
> ncycles = int(round(1.0 * duration * fs / len(wave)))
> data = b''.join(pack(' return data * ncycles
>
> def make_square(num, f0, fs):
> """generate square wave components
>
> num: number of harmonics
> f0: funamental frequency (Hz)
> fs: samples/second
>
> fs/2 is the upper bound.
> """
> stop = min(2*num, int(fs / (2 * f0)))
> freqs = [n * f0 for n in xrange(1, stop, 2)]
> amps = [1.0 / n for n in xrange(1, stop, 2)]
> return freqs, amps
>
> def make_saw(num, f0, fs):
> """generate sawtooth wave components
>
> num: number of harmonics
> f0: funamental frequency (Hz)
> fs: samples/second
>
> fs/2 is the upper bound.
> """
> stop = min(num + 1, int(fs / (2 * f0)))
> freqs = [n * f0 for n in xrange(1, stop)]
> amps = [(-1.0) ** (n + 1) / n for n in xrange(1, stop)]
> return freqs, amps
>
> def make_rand(num, f0, fs):
> """generate wave with random harmonics/amplitudes"""
> ftop = min(fs // 2, 12000)
> nmax = int(ftop / f0)
> num = min(num, nmax)
> freqs = [n * f0 for n in sample(xrange(1, nmax+1), num)]
> amps = [randrange(32768)/32767.0 for n in xrange(num)]
> return freqs, amps
>
> def play(data, stream):
> chunks = (data[i:i+1024] for i in xrange(0, len(data), 1024))
> for chunk in chunks:
> stream.write(chunk)
>
> if __name__ == "__main__":
> from time import sleep
>
> fs = 48000
>
> p = pyaudio.PyAudio()
> stream = p.open(
> format=pyaudio.paInt16,
> channels=1,
> rate=fs,
> frames_per_buffer=fs//4,
> output=True)
>
> # http://en.wikipedia.org/wiki/
> # Equal_temperament#Calculating_absolute_frequencies
>
> note = lambda n: 440 * (2**(1/12.)) ** (-21 + n)
>
> scale = [note(n) for n in range(12)]
> rscale = [note(13-n) for n in range(12)]
> vols = [0.2 + 0.05*n for n in range(len(scale))]
> rvols = list(reversed(vols))
>
> def play_scale(scale, vols, wave_func, master_vol=1):
> duration = 0.5
> nharmonics = 30
> for f0, vol in zip(scale, vols):
> freqs, amps = wave_func(nharmonics, f0, fs)
> wave = polywave(freqs, amps, f0, fs)
> data = packwave(wave, master_vol * vol, duration, fs)
> play(data, stream)
> sleep(0.5)
>
> play_scale(scale, vols, make_square, 0.5)
> play_scale(rscale, rvols, make_saw, 0.5)
> play_scale(scale, vols, make_rand, 0.75)
> play_scale(rscale, rvols, make_rand, 0.75)
>
> stream.clos