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?
How to serialize/deserialize a SoundData object?
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
-
- Citizen
- Posts: 70
- Joined: Fri Jun 20, 2014 1:33 pm
Re: How to serialize/deserialize a SoundData object?
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?
- zorg
- Party member
- Posts: 3449
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: How to serialize/deserialize a SoundData object?
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...
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 True 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.
- 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?
Yes, because it's the reverse of what love does, newSource creates a SoundData for static sources and a Decoder for streaming sources.zorg wrote:Like whether one could skip the newSource part and just create a SoundData from a FileData
-
- Citizen
- Posts: 70
- Joined: Fri Jun 20, 2014 1:33 pm
Re: How to serialize/deserialize a SoundData object?
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.
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.
- zorg
- Party member
- Posts: 3449
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: How to serialize/deserialize a SoundData object?
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...
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 True 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.
-
- Citizen
- Posts: 70
- Joined: Fri Jun 20, 2014 1:33 pm
Re: How to serialize/deserialize a SoundData object?
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.
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.
- zorg
- Party member
- Posts: 3449
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: How to serialize/deserialize a SoundData object?
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 thoughMachineCode 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.
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 True 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.
-
- Citizen
- Posts: 70
- Joined: Fri Jun 20, 2014 1:33 pm
Re: How to serialize/deserialize a SoundData object?
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.
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.
- zorg
- Party member
- Posts: 3449
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: How to serialize/deserialize a SoundData object?
Hmm, could have sworn i've seen a method to refresh... or yeah, on Image objects... that can get modified data from ImageDatas
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.
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 True 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.
Who is online
Users browsing this forum: Ahrefs [Bot], Google [Bot] and 2 guests