How to serialize/deserialize a SoundData object?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
MachineCode
Citizen
Posts: 70
Joined: Fri Jun 20, 2014 1:33 pm

How to serialize/deserialize a SoundData object?

Post by MachineCode »

I want to have a whole lot of short sounds stored in a db or passed around via network sockets. This would need something like binser or bitser to serialize them from a SoundData object after loading or creating them, then restore the SoundData object later on.

Is this easy to to do, or has someone got a way to achieve this?
User avatar
Kingdaro
Party member
Posts: 395
Joined: Sun Jul 18, 2010 3:08 am

Re: How to serialize/deserialize a SoundData object?

Post by Kingdaro »

Ideally, you want to have sounds stored on the client, which are then played on recipient of a specific network message, instead of sending over the entire sound. Is there a reason why you'd need to do this?
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: How to serialize/deserialize a SoundData object?

Post by zorg »

For what it's worth, SoundData can be created from File objects, which can be read, returning a string of bytes.
Alternatively, SoundData itself implements Data's getString method, that returns the whole content as a string
You could (chop up, and) send out these strings to the receiver. (with base64 encoding or unencoded)
Upon receiving them, (put them together, and) you can create a FileData object from the string (again, base64 or raw), then you can use love.audio.newSource to create a new Source from that FileData, get the SoundData object from that... if you need it or would want to serialize it on that end again...

Mind you, i just looked at the wiki and did a step-by-step; There may be some shortcuts one could do, but of them, i wasn't certain (Like whether one could skip the newSource part and just create a SoundData from a FileData, or alternatively, create a SoundData from a string...
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: How to serialize/deserialize a SoundData object?

Post by bartbes »

zorg wrote:Like whether one could skip the newSource part and just create a SoundData from a FileData
Yes, because it's the reverse of what love does, newSource creates a SoundData for static sources and a Decoder for streaming sources.
MachineCode
Citizen
Posts: 70
Joined: Fri Jun 20, 2014 1:33 pm

Re: How to serialize/deserialize a SoundData object?

Post by MachineCode »

Ok - thanks for that. If I use getString on a soundData object (which I could have loaded or synthesized), how do I reconstruct a soundData from this string? Looking on the wiki I can't see the inverse - or are you saying that the soundData:getstring returns a string that can be turned into a file with "love.filesystem.newFileData( contents, name, decoder )" and then passed to love.sound.newSoundData?

Just to explain a bit, I was looking at a way to access a large db of sounds/soundbites from a server. A TerraByte is nothing on a server, but not practical for a client program. Sending down a serialized string that can be reconstructed is possible, but may be inefficient from a network pov. Another way is to compress the audio and reconstruct it at the client, which could also work with the serialized string.

In some cases if quality is not an issue, audio can be severely compressed by locating zero crossings of the first derivative and making an array of points for straight line segments (or simple smoothing). I think this will work OK for low grade speech. Reconstructing this in the client might involve lots of SoundData:setSample( i, sample ) - which hopefully is reasonably low overhead.
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: How to serialize/deserialize a SoundData object?

Post by zorg »

Can't comment on the first paragraph, since i haven't tested it.

As for the third, i wouldn't recommend doing that kind of computation, at least, not in realtime circumstances; calling setSample is relatively slow. (an example: i couldn't do that fast enough to dynamically create a stereo, 44.1kHz, 8bit audio stream, meaning calculating 2*44100*1 numbers per second, though i was able to with a mono signal at 8kHz... coincidentally, telephony codecs like a-law and mu-law work on a rate of 8000 samples per second as well)
That said, if you'd need to decode it only once, then it could work.

Related to the second point, whether or not you decide to compress your data, iirc you'll need to chunk it in smaller pieces when sending it, otherwise luasocket/enet won't send all of it to the client... or at least i remember something like that being talked about in another thread, or on the irc channel... ^^
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
MachineCode
Citizen
Posts: 70
Joined: Fri Jun 20, 2014 1:33 pm

Re: How to serialize/deserialize a SoundData object?

Post by MachineCode »

I will try a few of these ideas and see how they go.

For 8 bit sounds it is possible to represent a sound buffer as a string. It might be possible to have a version of newSoundData that accepts a string as a parameter and initializes the sound data to that. 16 bit sound could be byte pairs in a string. This could be useful for sound effect loops that need to be stored in a compact form.
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: How to serialize/deserialize a SoundData object?

Post by zorg »

MachineCode wrote:I will try a few of these ideas and see how they go.

For 8 bit sounds it is possible to represent a sound buffer as a string. It might be possible to have a version of newSoundData that accepts a string as a parameter and initializes the sound data to that. 16 bit sound could be byte pairs in a string. This could be useful for sound effect loops that need to be stored in a compact form.
It's also possible to do that for 16bit and 32 bit as well though, and even 24bit; in all cases it will be gibberish though :D
But, you can use the FFI to set the data directly, using Data:getPointer on the SoundData, as i was told, since i needed to set bigger than one samplepoint chunks of it myself.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
MachineCode
Citizen
Posts: 70
Joined: Fri Jun 20, 2014 1:33 pm

Re: How to serialize/deserialize a SoundData object?

Post by MachineCode »

OK that sounds promising. I assume that data object you get from Data:getPointer is a byte array or short array depending on the bits parameter when the soundData was created?

If you can efficiently fill a soundData from a string, it might be possible to squeeze a bit more from 8 bit by doing some log compression when encoding the string, then restore to 16 bit samples on decode using FFI. That would give a neat way to store lots of sound samples off client and restore them to a soundData. Each sound could be represented as just a string!

The only thing missing (I think) is a source:refresh() method to update the source to play. I am not sure if it is possible, but that would be the audio equivalent of the relationship between Image and ImageData.

Thanks for all your help guys.
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: How to serialize/deserialize a SoundData object?

Post by zorg »

Hmm, could have sworn i've seen a method to refresh... or yeah, on Image objects... that can get modified data from ImageDatas :3

Well you might have a good solution with this. Queue in the sounddata, and play. Can't loop it though, sadly but i'm gonna experiment a bit with this since something was very off when i used it before.

Also, when you say log compression on string encoding, do you mean compressing 16bit samplepoints into 8 bits? how would you get back the original 16bit fidelity though? I don't think it can be anything but lossless. Telephony log-compression like mu and a-law, like i wrote before, sacrifice enough to be (not even) decent for speech, but not music which has a greater range.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 82 guests