Question: Loading sound from array

10 views
Skip to first unread message

Hrvoje Katic

unread,
Sep 20, 2016, 5:30:04 AM9/20/16
to libaud...@camlorn.net
Hello all,
So, I want to load my sound data directly from memory, and I'm using
load_from_array function for that. However, Libaudioverse expects float
data, while Python's wave module returns wave data as byte string. After
some searching, I found the way on stackoverflow to do proper conversion,
but unfortunately this solution doesn't work for 24-bit or higher wave
data.
So:
def load_sound_data(filename):
waveIO = BytesIO(data[filename])
w = wave.open(waveIO)
sr = w.getframerate()
channels = w.getnchannels()
frames = w.getnframes()
bitrate = w.getsampwidth() * 8
wdata = w.readframes(frames)
fdata = struct.unpack("%ih" % (w.getnframes() * w.getnchannels()), wdata)
fdata = [float(val) / pow(2, 15) for val in fdata]
return (sr, channels, frames, fdata)
And then I say:
sound = load_sound_data('splash.wav')
filenode = libaudioverse.BufferNode(server)
buffer = libaudioverse.Buffer(server)
buffer.load_from_array(sound[0], sound[1], sound[2], sound[3])
filenode.buffer = buffer
filenode.connect(0, filenode.server)
As I expected, it played 16-bit wave data properly, but failed at 24-bit
wave data. Do you have any suggestions on how I can implement better to-float
conversion.
The reason why I want wave data loaded directly into memory is because
I stored all the sounds inside an encrypted zip file, and
decryption/extraction is all done inside memory. This is to prevent
users from accessing sound data and modifying sound files. But as I said,
a proper conversion is required, because wave module has no way of
returning sound data as floats, as far as I know.
Thanks for any help,
Hrvoje
LP,
Hrvoje
Web: www.hrvojekatic.com

Chris Norman

unread,
Sep 20, 2016, 5:40:55 AM9/20/16
to libaud...@camlorn.net
Honestly don't know much about this stuff, would a numpy array be of any
use to you?


Hopefully this helps or something.

Anton Shusharin

unread,
Sep 20, 2016, 6:05:04 AM9/20/16
to libaud...@camlorn.net
You can just use decode_from_array:

def load_sound(filename):
buffer = libaudioverse.Buffer(server)
buffer.decode_from_array(data[filename])
return buffer


20.09.2016 14:30, Hrvoje Katic пишет:

Hrvoje Katic

unread,
Sep 20, 2016, 6:17:53 AM9/20/16
to libaud...@camlorn.net
Aah, thanks, it realy saved my time!

Anton Shusharin <antonshu...@gmail.com> wrote:
You can just use decode_from_array:

def load_sound(filename):
buffer = libaudioverse.Buffer(server)
buffer.decode_from_array(data[filename])
return buffer


20.09.2016 14:30, Hrvoje Katic ?????:
-- You received this message because you are subscribed to the Google Groups "libaudioverse" group.
To unsubscribe from this group and stop receiving emails from it, send an email to libaudiovers...@camlorn.net.
To post to this group, send email to libaud...@camlorn.net.
To view this discussion on the web visit https://groups.google.com/a/camlorn.net/d/msgid/libaudioverse/6dc0f3c4-ea60-535e-a918-52ccc41198ac%40gmail.com.

Austin Hicks

unread,
Sep 22, 2016, 11:20:36 AM9/22/16
to libaud...@camlorn.net
Can I ask, why not just load_from_file?


I mean, if the wave module is involved, this seems like the obvious
choice. I suppose that you might be hooking it up to something custom.
But if you're not, Libaudioverse's support for this is going to probably
be at least 2x faster than Python's wave module followed by a
decode_from_array. Plus, it will use significantly less ram. The
machinery for going from an in-memory array is not about efficiency,
it's about securing sounds.

For completeness's sake, decoding it yourself isn't something I can just
write out, but the general idea is to convert the first bits/8
characters of the string to an integer, divide by the maximum value of
that integer, insert the float into the array, then consider the next
bits/8 characters in the string until there are none left. For 24-bit
audio, this may involve bit shifts: I don't think the struct module
supports such integers natively. Of your options, this will by far be
the slowest. I could easily see how the "obvious" Python code for this
kind of thing could take longer than the duration of the file, on some
machines.

Also, decode_from_array works on ogg or anything else that you can
load_from_file. This is known to be slower to load than is ideal, but
will make your software smaller by a factor of 10 or more if you are
using many wave files.
Reply all
Reply to author
Forward
0 new messages