[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Sine Waves



I would also suggest looking at more of the Numeric built-ins, such as "fromfunction".
   For example, instead of looping to construct a native python list and then converting to an array, you can do:

arr_float = fromfunction(lambda x, y:(sin(x*freq*(6.28318/sample_rate)*length)*volume), 
                 (sample_rate * length, 2)) 

arr_int = arr_float.astype(Int16)
return arr_int

    This converts using sndarray just fine, although not if you are using NumArray for some reason, you have to be using Numeric.  The "sin" function here is from importing Numeric.  The type conversion is because something complained about using the "int" type coercion inside the lambda.

On 12/11/05, David Tweet <davidtweet@xxxxxxxxx> wrote:
Not limiting the volume argument to something under the threshold for your bit depth is certainly the problem--all those sine wave peaks were getting cut off.  Also, calling pygame.mixer.pre_init with some custom values will let you know for sure what you are working with.  Here a very slightly modified version which gives me a good sounding sine wave output:

import pygame, math
from Numeric import *
SAMPLE_RATE = 22050 ## This many array entries == 1 second of sound.

def SineWave(freq=1000,volume=16000,length=1):

    num_steps = length*SAMPLE_RATE
    s = []
    for n in range(num_steps):
        value = int(math.sin(n * freq * (6.28318/SAMPLE_RATE) * length)*volume)
        s.append( [value,value] )
    x_arr = array(s)
    return x_arr

def SquareWave(freq=1000,volume=100000,length=1):
    length_of_plateau = SAMPLE_RATE / (2*freq)
    s = []
    counter = 0
    state = 1
    for n in range(length*SAMPLE_RATE):
        if state == 1:
            value = volume
        else:
            value = -volume
        s.append( [value,value] )

        counter += 1
        if counter == length_of_plateau:
            counter = 0
            if state == 1:
                state = -1
            else:
                state = 1

    x_arr = array(s)
    return x_arr

def MakeSound(arr):
    return pygame.sndarray.make_sound(arr)

def PlaySquareWave(freq=1000):
    MakeSound(SquareWave(freq)).play()

def PlaySineWave(freq=1000):
    MakeSound(SineWave(freq)).play()


if __name__ == '__main__':
    pygame.init()
    pygame.mixer.pre_init(22050, -16, 2, 1024*2)
    PlaySineWave()
    pygame.time.wait(3000)




On 12/10/05, Peter Nicolai <pnicolai@xxxxxxxxx > wrote:
try limiting the "volume" argument to 32768 or lower (16 bit audio).


On 12/10/05, Kris Schnee < kschnee@xxxxxxxxxx> wrote:
> It's driving me nuts: why is this not producing a sine wave at the
> specified frequency? I get an ugly, rasping beep that doesn't sound at
> all like the sample at
> < http://www.sfu.ca/sonic-studio/handbook/Sine_Wave.html >, and sounds
> like a different frequency than the square waves produced by the
> function below. Calling "SineWave(100)[:220]" seems to show data that
> repeats every 220 cycles, ie. 100 times per second at the specified
> sample rate, yet it still doesn't sound right.
>
> Kris
>
>
>
> import pygame, math
> from Numeric import *
> SAMPLE_RATE = 22050 ## This many array entries == 1 second of sound.
> pygame.init()
>
> def SineWave(freq=1000,volume=100000,length=1):
>      num_steps = length*SAMPLE_RATE
>      s = []
>      for n in range(num_steps):
>          value = int( math.sin (n * freq * (6.28318/SAMPLE_RATE) * length
> )*volume)
>          s.append( [value,value] )
>      x_arr = array(s)
>      return x_arr
>
> def SquareWave(freq=1000,volume=100000,length=1):
>      length_of_plateau = SAMPLE_RATE / (2*freq)
>      s = []
>      counter = 0
>      state = 1
>      for n in range(length*SAMPLE_RATE):
>          if state == 1:
>              value = volume
>          else:
>              value = -volume
>          s.append( [value,value] )
>
>          counter += 1
>          if counter == length_of_plateau:
>              counter = 0
>              if state == 1:
>                  state = -1
>              else:
>                  state = 1
>
>      x_arr = array(s)
>      return x_arr
>
> def MakeSound(arr):
>      return pygame.sndarray.make_sound(arr)
>
> def PlaySquareWave(freq=1000):
>      MakeSound(SquareWave(freq)).play()
>
> def PlaySineWave(freq=1000):
>      MakeSound(SineWave(freq)).play()
>
>



--
David Tweet
__________________
http://davidtweet.com



--
David Tweet
__________________
http://davidtweet.com