Kyle
Kyle

Reputation: 893

pygame playing sound very slowly

I am working on a project that requires a signal to be created in the program, from scratch. The signal is stored in an array, with each element being a sample. It should be played at 44.1 kHz. Due to other aspects of the project, I am using pygame to accomplish this. Pygame has a feature that allows a Sound object to be created from a numpy array and be played as if it were a wav file. When initializing pygame.mixer, I set the frequency to 44100 Hz, however, the Sound object is playing about 10 kHz.

Is this an error in pygame, or is there something else that needs to be done to accomplish play an array at a given rate?

def test_script(t):
    bin_sig[0:8] = throttle(t)
    bin_sig[8:28] = restofsignal()
    bin_sig[28:32] = checksum(bin_sig)

    print bin_sig
    sig = create_audiosig(bin_sig)*60

    pygame.mixer.init(44100,-16,1,2**16)
    num_ary = numpy.array(sig)
    plt.plot(num_ary)
    plt.savefig('generated_signal.jpg')

    if (sys.argv[1] == 'on'):
        s = pygame.sndarray.make_sound(num_ary)
        s.play()

    plt.show()

The returned plot of the signal enter image description here

There are 60 pulses of length 6835. Played at 44.1 kHz, this should take 9.3 seconds. However, it is taking 37.2 seconds (11020 Hz).

If you need to see more of the code, you can find it here

Upvotes: 0

Views: 463

Answers (1)

Kyle
Kyle

Reputation: 893

I have since solved this problem. However, because when I find forum post with the same problem as me and all I see is "I solved it, thanks for your help," I die a little inside, I am going to post the answer.

When creating a numpy array, apparently it uses a datatype that is 64 bits for the elements. When creating a sound object, it will use the number of bits specified during init() (in this case 16). When it reads the data type from the array, it reads 4 values for each element (4 16 bit values in the 64 bit element). To solve this, specify dtype=numpy.dtype('int16') when calling numpy.array()

numpy.array(sig, dtype=numpy.dtype('int16'))

Upvotes: 1

Related Questions