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

Re: [pygame] SOund crackle With latest python and pygame ! :-(




Howdy,

I was having similar trouble (mail-thread: Screeching, Howling Garbage in One Ear pygame.sndarray )

Eventually, I got it to go away after using a tone generator rolled-up by Pete.

# From Pete Shinners
"""
Example tone generation program for pygame
Pete Shinners
May 5, 2006
Public Domain
"""
def MakeTone(rate = 2200, length = 2, granularity = None, phones = None, envelope = None, attack = None, filename = None):
    freq, format, stereo = pygame.mixer.get_init ()
    size = int(freq * float(length))
    mult = float(rate) / freq * math.pi * 2
    ramp = Numeric.arange(0, size, 1, Numeric.Float)
    tone = Numeric.sin(ramp * mult)
    samples = FloatToFormat(tone, format, stereo)
    return samples



def FloatToFormat(data, format, stereo):
    if abs(format) == 16:
        if format < 0:
            samples = ((data-0.5) * 0xffff).astype(Numeric.Int16)
        else:
            samples = (data * 0xffff).astype(Numeric.UInt16)
    else:
        if format < 0:
            samples = ((data-0.5) * 0xff).astype(Numeric.Int8)
        else:
            samples = (data * 0xff).astype( Numeric.UInt8)
    if stereo:
        mono = samples
        samples = Numeric.zeros((data.shape[0], 2), mono.typecode())
        samples[:,0] = mono
      samples[:,1] = mono
        #samples[:] = mono[:, Numeric.NewAxis]
    return samples
   
# End from Pete Shinners

Compare to my original:

def tone1(rate = 10, length = 60, granularity = 10, phones = 2, envelope = None, attack = None):
    val = 0
    switch_amplitude = 0
    switch_polarity = 0
    out = []
    for len in range(0,length):
        arr = []
        if switch_amplitude == 0:
            val+=granularity
        else:
            val-=granularity
           
        if abs(val) >= rate or val <= 0:
            switch_amplitude = abs(switch_amplitude-1)
           
        switch_polarity = abs(switch_polarity-1)
       
        for ph in range(0,phones):
            if switch_polarity == 0:
                arr.append(val)
            else:
                arr.append(0)
        out.append(arr)
       
    return Numeric.array(out)

I think the crux of the issue is resolved in his example by the following from FloatToFormat()

if abs(format) == 16:
        if format < 0:
            samples = ((data-0.5) * 0xffff).astype(Numeric.Int16)
        else:
            samples = (data * 0xffff).astype(Numeric.UInt16)
    else:
        if format < 0:
            samples = ((data-0.5) * 0xff).astype(Numeric.Int8)
        else:
            samples = (data * 0xff).astype(Numeric.UInt8)

You can see it's resolving them to appropriate numerical types based on the format value.  I'm going to go out on a limb here and say this might also be platform dependant.

--
Andrew Ulysses Baker
"failrate"