MATLAB: Problem saving and reading an audio file

audioaudio processingaudio steganographyMATLABsteganographywavwav filewavreadwavwrite

Is there any known problems when saving an audio file using a .wav or .flac format and then reading the same audio file?. I keep saving a modified audio and then trying to read it again, but some amplitudes of the signal seem to get modified and I don't have the faintest idea why this is happening. Here's the full description of my problem http://es.mathworks.com/matlabcentral/answers/168025-problem-encoding-and-decoding-a-message-in-an-audio-file
I've already looked all the posts with the 'audio steganography' tag, but none seem of any help.
Thanks.

Best Answer

When you use wavwrite() or audiowrite() then the valid range of data depends upon the data class; see http://www.mathworks.com/help/matlab/ref/wavwrite.html and http://www.mathworks.com/help/matlab/ref/audiowrite.html and data outside that range will be clipped. You would normally get a warning when that happens.
When you wavread() or audioread() then no matter what the datatype that was stored in the file, by default the data is converted to double in the range -1 <= x < 1 . For both routines you can use the option 'native' to request that the same datatype used in the file be returned.
For audiowrite() the default for .wav and .flac files is 16 bits per sample (per channel); for both those formats, the 'quality' option is irrelevant (that is, the compression is lossless)
For wavwrite() the default is 16 bits per channel for floating point data, and up to 24 bits per sample is represented as integer, but 32 bits per channel is represented as floating point with some potential round-off.
Notice that the default is 16 bits per channel, which gives a resolution of 1/65536. As signed integers, half of the range is negative, one value is 0 (which is neither negative or positive) and so (one half minus one sample) are available for positive values. The calculation for converting from floating point to integer should then be (float * 32768) but it leaves open the question of whether you floor() or round() those values into 16 bit integers. If you have a value which is exactly 0.5 then it should result in +16384 being stored, but the slightest bit difference from 0.5 could result in +16383 being stored instead, which would convert back to less than 0.5. To be sure of getting back the same value you stored, you really should use one of the integer sample formats and use the 'native' option when you read the data.