python-soundfile
python-soundfile copied to clipboard
Support more features of the sf_command() interface
Especially SFC_SET_NORM_DOUBLE, SFC_SET_NORM_FLOAT (as needed in #20), but probably others, too.
See http://www.mega-nerd.com/libsndfile/command.html for reference.
As I mentioned in issue #20, I see no benefit to disabling normalization when writing a floating-point array to a PCM file. This would degrade PySoundFile's clean abstraction and add unnecessary complexity. If a Python user wants to PySoundFile to interpret a floating-point in_array as integer values, it can be accomplished by passing in_array.astype(np.int16) instead.
Very interesting, yes.
SFC_SET_SCALE_FLOAT_INT_READ looks interesting as well.
I just had a closer look ...
There are a few commands that give global information, namely SFC_GET_LIB_VERSION and SFC_GET*FORMAT*.
We're already providing the FORMAT stuff with available_formats() and similar functions.
We'd only have to add one function, e.g. named get_lib_version() or libsndfile_version() (any other suggestions for a function name?).
All the rest give information about an existing SNDFILE object:
SFC_GET_LOG_INFO
SFC_GET_CURRENT_SF_INFO
SFC_GET_NORM_DOUBLE
SFC_GET_NORM_FLOAT
SFC_SET_NORM_DOUBLE
SFC_SET_NORM_FLOAT
SFC_SET_SCALE_FLOAT_INT_READ
SFC_SET_SCALE_INT_FLOAT_WRITE
SFC_CALC_SIGNAL_MAX
SFC_CALC_NORM_SIGNAL_MAX
SFC_CALC_MAX_ALL_CHANNELS
SFC_CALC_NORM_MAX_ALL_CHANNELS
SFC_GET_SIGNAL_MAX
SFC_GET_MAX_ALL_CHANNELS
SFC_SET_ADD_PEAK_CHUNK
SFC_SET_ADD_HEADER_PAD_CHUNK
SFC_UPDATE_HEADER_NOW
SFC_SET_UPDATE_HEADER_AUTO
SFC_FILE_TRUNCATE
SFC_SET_RAW_START_OFFSET
SFC_SET_DITHER_ON_WRITE
SFC_SET_DITHER_ON_READ
SFC_GET_DITHER_INFO_COUNT
SFC_GET_DITHER_INFO
SFC_GET_EMBED_FILE_INFO
SFC_SET_CLIPPING
SFC_GET_CLIPPING
SFC_GET_INSTRUMENT
SFC_SET_INSTRUMENT
SFC_GET_LOOP_INFO
SFC_GET_BROADCAST_INFO
SFC_SET_BROADCAST_INFO
SFC_GET_CHANNEL_MAP_INFO
SFC_SET_CHANNEL_MAP_INFO
SFC_RAW_DATA_NEEDS_ENDSWAP
SFC_WAVEX_SET_AMBISONIC
SFC_WAVEX_GET_AMBISONIC
SFC_SET_VBR_ENCODING_QUALITY
SFC_TEST_IEEE_FLOAT_REPLACE
SFC_SET_ADD_DITHER_ON_WRITE
SFC_SET_ADD_DITHER_ON_READ
Needless to say, those are a lot.
I don't think it's a good idea to provide each single one of them as a method or property of SoundFile.
What about having an attribute (e.g. called SoundFile.command) that itself has all the information as properties?
E.g.:
f = sf.open(...)
f.command.vbr_encoding_quality = 0.8
Any other suggestions for an attribute name?
properties, settings, info, ...?
I do not want to simply copy this stuff from sndfile. PySoundFile should be as useful and pythonic as possible. The fact that it is implemented using sndfile is an implementation detail that we should not expose unless necessary.
Thus, I would like to implement these commands in ways that make sense for PySoundFile, and not as a generic "command interface" that just defers to libsndfile.
Ideas:
SFC_GET_LIB_VERSIONasSoundFile.__sndversion__.SFC_GET_LOG_INFOas content of the exception ifsf_open*fails.SFC_CALC_SIGNAL_MAXasSoundFile.max()(similarly for the otherCALCcommands).SFC_SET_NORM_*,SFC_SET_SCALE_*,SFC_GET/SET_CLIPPINGare probably more easily dealt with on the Numpy side, so we should skip them.SFC_GET_*_FORMAT_*are already implemented asSoundFile.format_infoSFC_UPDATE_HEADER_NOWcould be integrated inSoundFile.flush()SFC_FILE_TRUNCATEasSoundFile.truncate()SFC_GET_LOOP_INFOandSFC_GET_INSTRUMENTin a specialSoundFile.midiproperty.SFC_SET_VBR_ENCODING_QUALITYas a special keyword argument for ogg files only.
Of course, this will add a lot of complexity to the library, the tests, and the documentation.
But I would rather not support some of these, than doing something like SoundFile.send_command("VBR_ENCODING_QUALITY", 0.9). After all, if the user really wants to do this, he can always sf._snd.sf_command(soundfile._file, sf._snd.SFC_SET_VBR_ENCODING_QUALITY, 0.9, 4).
Since libsndfile 1.0.27 the the new commands SFC_GET_CUE_COUNT, SFC_GET_CUE, SFC_SET_CUE are available, see https://github.com/erikd/libsndfile/commit/9ea30b4c19f56112a10030da7bede2c1c6a0f36d and http://www.mega-nerd.com/libsndfile/command.html.
This might be useful, see also http://stackoverflow.com/q/20011239.