Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

autoconvert to/from floats #23

Open
ssfrr opened this issue Nov 11, 2019 · 2 comments
Open

autoconvert to/from floats #23

ssfrr opened this issue Nov 11, 2019 · 2 comments

Comments

@ssfrr
Copy link
Collaborator

ssfrr commented Nov 11, 2019

Currently LibSndFile.jl avoids making assumptions about type conversions when loading and saving audio files. However, I find almost invariably I end up doing float(load(fname)). Saving is also often inconvenient because saving to wav ends up creating Float64-formatted wav files, which many other tools don't know how to handle, so I end up needing to do save("audio.wav", Fixed{Int16, 15}.(x)), which seems like a ridiculous thing to ask users to do. I'm wondering if we should auto-convert by default (more like WAV.jl). Also some formats (like FLAC) don't every support floating-point samples, so saving to FLAC requires manual conversion to fixed-point, which is annoying.

One way to handle the element type would be to have an eltype=Float64 keyword argument to load, so by default it would auto-convert to Float64, but it would be overridable. eltype=:native or eltype=nothing could be given to get the current behavior of keeping the native element type. Loading integer-typed files as FixedPoint is cute but in practice I've found that floats are much more useful for most processing.

For saving I think I'd default to 24-bit integer types. The API for specifying the type seems a little unclear - I'm not sure whether it's better to use Julia types (e.g. eltype=Fixed{Int16,15} for 16-bit ints) or something like eltype=:int, nbits=16 or something. The latter seems less finicky.

@bafonso
Copy link

bafonso commented Aug 10, 2020

I agree that you should simply convert it to Float32 or Float64 by default having the option such as eltype like you suggest. I have seen people use fixed point arithmetic if they want to develop on embedded devices but I would not say it is the majority of cases people will face. Auto-converting before saving would also remove a lot of headache for users but not sure how to decide default bit depth since we're going to float. In the audio world 24bit is the standard nowadays and people dither down to 16bits if you want to go into CD or distribute in full resolution at 16bits but most people do 24bit anyway to avoid any conversion.

@BenjaminGalliot
Copy link

It seems I encountered a related problem, as explained in this topic.

It seems it is not so obvious, from what I understood from code (LibSndFile and FileIO) to keep some raw data information (like bit depth) at higher level, for example in order to keep the original bit depth before the automatic conversion (typically 24 bit converted to FixedPointNumbers.Q0f31, 32 bit), which is rather useful if you want to save it at same precision as original.

I currently use loadstreaming(myfile) before load(myfile) to get access to sfinfo field, because I did not find a way to read and keep specific data without any redundancy, and even in this case, I need to know the values defined as constants in the h file (like 65539 for WAV 24 bit).

It is rather awkward to open a 24 bit WAV file, do minor processing (like splitting channels into separate files) then save them to have bigger files than original!

My current workaround, as you have seen, is to do

LibSndFile.subformatcode(::Type{LibSndFile.PCM32Sample}) = 0x00000003

But it is not the most convenient because when I will have a 32 bit file, I will need to modify again this function just before saving, so it could be really nice to keep somewhere the raw format information and to add an argument to keep native depth or force it to a specific value, as suggested by @ssfrr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants