vericule
vericule

Reputation: 285

Playing sounds from buffer in pygame

I am trying to play sound from buffer in pygame. I am using Python 3. I got uncompressed wav file, sound.wav.

I can play it like this and it works fine:

sound = pygame.mixer.Sound(file='/path/to/file/sound.wav')
sound.play()

According to pygame documentation buffer can be Python 3 bytes object, but if I try:

f = open('/path/to/file/sound.wav', 'rb')
data = f.read()
sound = pygame.mixer.Sound(buffer=data)
sound.play()

This code can be run, but sound is deformed.

So, how to use buffer? Documentation is really spare and I couldn't find any examples. I can't play sounds from hard disk because I have many raw audio chunks, which I convert to wav, but saving them on hard disk (and then reading them) is way to slow and inefficient (since I already have them in memory). Thank you for your help.

EDIT: I forgot to mention that I also tried to play raw audio without header. Fortunately thanks to @Andris comment I figure out what pygame means by buffer. I init mixer with pygame.mixer.init(frequency=22050, size=8, channels=1) so I thought that buffer should be in this format. I dumped on disk what was returned by pygame.mixer.Sound(file='/path/to/file/sound.wav').get_raw() and after examination I can say it's raw audio, but with frequency=44100, size=-16.

Upvotes: 2

Views: 5466

Answers (2)

NoneType4Name
NoneType4Name

Reputation: 1

Use ButesIO for it:

import pygame
from io import BytesIO
f=BytesIO(open('data/house_lo.ogg', 'rb').read())
pygame.init()
print(pygame.mixer.Sound(f).get_length())
print(pygame.mixer.Sound(file='data/house_lo.ogg').get_length())

>>> 7.104852676391602
>>> 7.104852676391602

Answer get from GitHub.

Have a nice day.

Upvotes: 0

josch
josch

Reputation: 7144

Here a full example from creating an in-memory buffer filled with audio to then playing it back using pygame:

import pygame
import subprocess

rawdata = subprocess.check_output([
    'sox', '-n', '-b', '16', '-e', 'signed', '-r', '44100',
    '-c', '1', '-t', 'raw', '-', 'synth', '0.1', 'sin', '700'])
pygame.mixer.pre_init(frequency=44100, size=-16, channels=1)
pygame.init()
beep = pygame.mixer.Sound(buffer=rawdata)
pygame.mixer.Sound.play(beep)
pygame.quit()

Notice how the raw audio options given to sox (sample rate 44.1k, 16 bit signed, 1 channel) are the same given to the pygame mixer.

Have fun!

Upvotes: 3

Related Questions