How can I save audio wav file without data clipping? - matlab

I am using MATLAB tool for extracting silence part from audio WAV files. After extracting silence part from audio, I want to save new audio as a WAV file.
For this process, I use 'audiowrite' function. However, the program warns to me with this message :
Warning: Data clipped when writing file.
I tried to add 'BitsPerSample' value with single file format(32 bit) and I dont take a message from program with this way. I saved audio files with 32 bit but WAV files should be 16 bit.
How can I fix this problem?
audiowrite(filename,y,fs,'BitsPerSample',32);
Note: I also normalized data and problem is same.
Thanks for your help!
UPDATE:
I want to normalize audio samples as mean 0 and standard deviation or variance 1.Thus, I use z-score normalization technique.
Also,y/max(abs(y)) method is normalized data between -1 and 1. However, mean and variance are not equal to 0 and 1 respectively. These techniques are normalized data with different way.
Actually, My question is that How can I save samples with z score normalization technique without data clipping?

Matlab's audiowrite uses different normalizations for different data types. So if you want to get 16bit audio wav file, you should normalize your data to the [-32768,32767] range and convert your data to int16 type:
y_normalized = intmax('int16') * y/(max(abs(y))*1.001);
audiowrite(filename, int16(y_normalized), fs)
Similarly, for float you should normalize your data to the [-1,+1] range :
y_normalized = y/(max(abs(y)));
audiowrite(filename, y_normalized, fs)

Related

How can I record an audio file in Qt and read it in MATLAB?

I'm recording an audio file in Qt. After that, I have to read the file with MATLAB and analyse it. Qt likes to save audio files in .pcm format (i.e. .wav format without header) and I can't read .pcm audio files with MATLAB (format is not supported).
What is the best solution to transfer audio from Qt to MATLAB?
Firstly, since your .pcm file has no header information, you'll need to know the number of bits per sample you used to create it in Qt. A typical value would be 16 bits per sample, or a data type of int16. Then you can use fread to read the audio waveform from the file like so:
fid = fopen('your_file.pcm', 'r');
audioWaveform = fread(fid, Inf, 'int16');
fclose(fid);
If you then want to do any processing, you will likely need to provide other pieces of information from when you created it in Qt, like the sampling frequency.

Read and represent mp3 files using memmapfile in matlab

I have to analyze bio acoustic audiofiles using matlab. Eventually I want to be able to find anomalies in the audio. That's the reason I need to find a way to represent the audio in a way I can extract and compare features. I'm dealing with mp3 files up to 150 mb. These files are too large for matlab to read in to it's memory. Therefore I want to use the memmapfile() function. I used the following code and a small mp3 file to find out how it actually works.
[testR, ~] = audioread('test.mp3');
testM = memmapfile('test.mp3');
disp(testM.Data);
disp(testR);
The actual values of the testM.Data and testR are different. Audioread() returns a 7483391 x 2 matrix and memmapfile() a 4113874 x 1 matrix.
I'm not really sure how memmapfile() works, I expected this to be equal to each other. Is there a way to read mp3 files in the same format audioread() does using memmapfile()? And what does memmapfile actually return in case of an audio file? Maybe it's also usable in the vector format in the case of anomaly detection?
Thanks in advance!
NOTE: The original files were in wav IMA ADPCM format with sizes from 1.5 up to 2.5 gb. Since Matlab can't deal with that format and the size of the files I converted them to 8bit mp3 files.
I think that the problem is mammapfile by default read data in uint8 format, while audioread function read data in another way.
How you can see here you can specify the format of data when you read it with memmapfile, so try to "play" with different values. From the documentation I read that you can read data in double format, so try to modify the memmapfile data format and audioread data format.
Last thing, memmapfile always organize the data in matrix like "somenumbers x 1", so if you want the original one you need to use something like reshape.
Anyway if you work with big data I suggest you to try with something different instead memmapfile, because it is very very slow

get integer representation of .SPH audio files

I am trying to train a neural network using audio files that are originally in .SPH format. I need to get integers that represent the amplitude of the sound waves for neural net, so I used sox to convert the files to .wav format by calling sox infile.SPH outfile.wav remix 1-2 (remix for converting 2 channels into 1), and then tried to use
[y, Fs, nbits, opts] = wavread('outfile.wav') in matlab to get the integer representation.
However, matlab threw Data compression format (CCITT mu-law) is not supported.
So I used sox infile.SPH -b 16 -e signed-integer -c 1 outfile.wav
which I think puts the wave file in a linear format instead of mu-law. But now matlab threw another error: Invalid Wave File. Reason: Cannot open file.
My audio files are in 8000 Hz u-law single or dual channels, and all in 8-bit, I think (8-bit for single for sure).
Is there a way to get the integer representation out of the audio files using matlab or any other programs? Either u-law or linear is fine, unless one would be better for neural net training. Preferably 8 bit, since the source files are in 8-bit.
I don't really understand .SPH. For the uncompressed ones (and ignore headers), are the files storing amplitudes (guess it has to somehow)? Can I extract numbers out of those files directly without bothering with waves? Are the signals stored in a sequential fashion such that it would make sense to split the audio files?
I am new to audio processing in general, so any pointers would be appreciated!
You need to clearly identify the main task: feeding the neural net with vectors or matrix. So the first step is to work on the audio file (without matlab!) in order to have wav files. The second step is the neural net setting/training with matlab.
I would try to decompress 'sph' files, then convert them into 'wav' (for example see the instructions here and here).
Finally, using sox in a command/terminal window is better than using it in the matlab console.

How does MATLAB read and interpret binary digits from a .bin file?

I have a binary file with .bin extension. This file is created by a data acquisition software. Basically a "measurement computing" 16-bit data-acquisition hardware is receiving signals from a transducer(after amplified by an amplifier) and sending this to PC by a USB. A program/software then is generating a .bin file corresponding received serial data from data aq. hardware. There are several ways to read this .bin file and plot the signal in MATLAB.
When I open this .bin file with a hexeditor I can see the ASCII or ones and zeros (binary). The thing is I don't know how to interpret this knowledge. There are 208000 bytes in the file obtained in 16 seconds. I was thinking each 2 bytes corresponds to a sample since the DAQ device has 16 bit resolution. So I thought for example a 16-bit data such as 1000100111110010 is converted by MATLAB to a corresponding voltage level. But I tried to open two different .bin files with different voltage levels such as 1V and 9V and still teh numbers do not seem to be related what I think.
How does MATLAB read and interpret binary digits from a .bin file?
Thnx,
Assuming your .bin file is literally just a dump of the values recorded, you can read the data using fread (see the documentation for more info):
fid = fopen('path_to_your_file', 'r');
nSamples = 104000;
data = fread(fid, nSamples, 'int16');
fclose(fid);
You will also need to know, however, whether this data is signed or unsigned - if it's unsigned you can use 'uint16' as the third argument to fread instead. You should also find out if it's big-endian or little-endian... You should check the original program's source code.
It's a good idea to record the sample rate at which you make acquisitions like this, because you'll be hard pressed to do anything but trivial analysis on it afterwards without knowing this information. Often this kind of data is stored in .wav files, so that both the data and its sample rate (and the bit depth, in fact) are stored in the file. That way you don't need a separate bit of paper to go along with your file (also, reading .wav files in MATLAB is extremely easy).

How can I get into a wav file to change the sample rate?

I have a wav file pulled up in MATLAB, and I can see it's sample rate. All I need to do is change this 1 number. Everything else in the file will remain uncahnged. (The resulting sound would play at a different speed but would have an identical array of sample data.)
The reason I need to do this is because MATLAB seems to freak out when I tell it to open something sampled at anything other than 8k. All I need MATLAB for is to edit the file, so the sample rate really doesn't matter at all, since I'll be putting it back into a wav file when I'm done. So I either need to be able to change the value in the wav file that stores the sample rate, or to get MATLAB to change the sample rate it prefers from 8k to the sample rate that my files were recorded at.
if you just want to change the sampling frequency, here is the code, but it would distort the original wav file. If you decrease the sampling frequency, then the beat and music would be very slow.
Code:
[y, fs, nbits]=wavread('stego_lab');
fs2=11025;
wavwrite(y,fs2,nbits,'stego2_lab.wav');
sound(y,fs2,nbits)
you can hear it but the samples will remain the same.
Hope it helps.
There is the SOX tool, which should help you in that respect, and it comes on almost any platform - http://sox.sourceforge.net
There is also libsndrate, libsamplerate, libsndfile and others, that might have executables too.
Try this solution
[x,fs] = wavread('infile.wav');
<br>[p,q] = rat(16000/fs) % to convert to 16k sample rate</br>
<br>y = resample(x,p,q); % signal package require
wavwrite(x,16000,'outfile.wav');