fft on samples of an audio file in matlab - matlab

I'm trying to extract information from a sound file in order to use it in a video classification algorithm I'm working on.
My problem is that I don't know how to work exactly with audio files in Matlab.
Below is what I need to accomplish:
open the audio file and get the sampling rate/frequency
I need to work on a window of 2 seconds so I have to loop over the file and get each 2 seconds as a window and then do the ftt (Fast-Fourier-Transform) on each window.
After that it is my turn to use these values to do what I want
any help would be appreciated
Thanks.

Following code may only give you some idea. You may need to determine another fft size, a windowing function like hamming etc.
To read a wav file:
[data, Fs] = wavread('path.wav');
Splitting to 2 sec windows and getting fft:
frameFFT = [];
timeStep = Fs*2;
for i=1:timeStep:length(data)-timeStep
frameFFT = [frameFFT; fft(data(i:i+timeStep-1),1024)];
end

Related

Save Matlab audio output

I need to save the audio output of a script in Matlab but I don't know how to do it. It is a complex sound, with several pauses of silence with different durations, so I cannot simply use audiowrite. Is it possible to record the output? I would like to save exactly what I hear after running the script. It is my first time with sounds in Matlab and I did not find anything online. Thank you for your help.
Represent pauses like sounds with zeros:
signal1 = ...;
pause1 = zeros(length1/fs,1);
signal2 = ...;
pause2 = zeros(length1/fs,1);
and just concatenate all signals in one array:
longSignal = [signal1; pause1; signal2; pause2];
and use audiowrite to save your long signal in a wav file.

How do I control which channel sound is played through using MATLAB?

I'm a novice MATLAB user, so apologies if the question is very basic. I need a .wav sound file to be played in a single, specific channel -- let's say the left channel. As it is, my code reads in the sound file, and I add in a column of zeros to nullify the channel I don't want, like so:
currentDir = pwd;
soundFile = [currentDir '\sound1.wav']; % load the file
[y, Fs] = audioread(soundFile); % read the file in
soundData(:,1) = y(:,1); % keeps sound for the left channel
soundData(:,2) = 0; % nullifies the right channel
sound = audioplayer(soundData,Fs);
play(sound);
As it stands, the code currently produces a sound that is full volume in the left speaker, and half volume (but still very much audible) in the right speaker. I have tried this with at least 20 .wav files, with the same result.
In case it's relevant, this happens even when I write in code that explicitly matches the length of the sound variable in 0s, like so:
[y, Fs] = audioread(soundFile);
silentChannel = zeros(size(y));
soundData(:,1) = y(:,1); % keeps sound for the left channel
soundData(:,2) = silentChannel(:,2); % nullifies the right channel
Does anybody know what I'm doing wrong, or have any thoughts?
Your code is definitely correct and it should only play audio in the left channel. I suspect that the problem is caused by a sound-card/driver issues. Allow me suggest the following troubleshooting steps:
Save your output as a wav file using audiowrite('output.wav', soundData, Fs). Play this using a different audio player, such as Audacity. If you still hear output in both channels, it must be a sound-card/driver issue.
Assuming that you are using a Windows PC (going by the syntax in your file path), make sure all sound enhancements are disabled. How to do this depends on the PC. If there is a third-party app controlling the playback settings, you'd have to use that. Otherwise find the settings shown in the picture below in the Control Panel.
In MatLab the expected method for playing sound is the method sound(data,Fs)
To control the channel the sound emits on, you'll want to know how sound() reads data.
data is a matrix with the columns representing channels, and with the rows holding the samples of the waveform for a given sampling fequency Fs
here is a simple implementation.
function treismanwolfe()
close all
clear all
clc
Fs = 40000;
tau = 2*pi();
t = 0:tau/(Fs-1):tau/2;
left = sin(t).*(sin(t*200)+sin(t*1600));
left= left/max(abs(left));
left = left'; %turn column vector into row
right = sin(t).*(sin(t*800)+sin(t*400));
right= right/max(abs(right));
right = right'; %turn column vector into row
data = [left,right*0]; %multiply either by 0 to nullify
sound(data,Fs); %so you can hear it.
end
I hope this works for you. Enjoy!
When I run your code the audio output is only audible in the left channel as you have specified.
#Austin Kootz' version with the sound()-function is just as good and also produces what you're looking for, but with audioplayer-object you have the ability to stop the playback in the middle of the playback (as you probably know)
Have you tried converting your .wav to another format to see if that makes a change?

Matlab read multiples samples with audioread

I'm trying to read multiple samples from a mp3 file with the function audioread.
let's say I have the following code :
samples = [1, 44100; 50000, 100000; 150000, 200000];
[signal, fe] = audioread(filepath, samples);
t = (1/fe:1/fe:lenght(signal)/fe);
signal = signal(:,1);
How can I make this work ? If samples contain only 1 row, it works just fine, but I have like 80 samples in the same mp3 file to work with.
I've tried this with a for loop, the audioread part works fine, but I don't know how to store the data since the duration of each sample isn't the same, the dimensions of matrices are not consistent and I can't concatenate them in a single matrix.
Plus, I've been told for loops are better avoided whenever possible in Matlab, so I'd like to do this by the rules (but i'll use them if there's no other way ofc).
Finally I'm very new to Matlab so I might miss something very obvious, but cound'nt find out reading through the doc.
Thks for your help :)

Add 1 second of silence to the .wav sound file

I need to create a function in MATLAB, but I'm new to the program so I would appreciate any help from you guys. I've read the other posts here, but unfortunately none have helped me.
Here's the question: How can I add 1 second of silence to both the beginning and the ending of a WAV file with MATLAB?
My current code:
subplot(2,1,1)
[s1,Fs]=wavread('sound.wav');
t=linspace(0,1,Fs);
plot(t,s1)
Thanks!
Step 1: Create a vector of zeros. (size of vector will depend on sampling rate).
silence = zeros(Fs, 1);
finalWav = [silence s1 silence];
Step 2: Concatenate the vectors.
That should do it.
Please note, that I do not have access to Matlab and am not able to test the code.

a problem with wavread function

I wrote a program that record my voice write it and then play it
Fs=11025;
y= wavrecord(2*Fs,Fs,'int16');
wavwrite(y,Fs,'t1.wav');
wavplay(y);
I heard my voice clear
then I want to write another program that reads that file and play it
y=wavread('t1.wav');
wavplay(y);
when I run the second program I didn't hear my voice clear
so how can I read the wav file and then play it without a problem?
The wavwrite you used may assume that the incoming y is of range [-1 +1]. Try to normalize y before calling wavwrite
y_float = double(y)/2^15; %% Normalize int16(y) by 2^15
wavwrite(y_float,Fs, 't1.wav');
In the case that something goes wrong with wavplay reading the floating point y_float, you can convert the read-back signal from floating point to int16 again:
y_float_readback = wavread('t1.wav');
y_int16_readback = int16(y_float_readback*2^15);
wavplay(y_int16_readback);
You may compare y_int16_readback with the original y. They should be identical.
This script works absolutely fine for me using the latest version of matlab. I heard clear audio using both your 1st and 2nd code excerpts.
One thing I noticed is that you record y as 'int16' type and then save it to the wav file. When you load the wav file using wavread, y is stored in the matlab workspace as double precision floating point data by default. If you want y to be loaded in the same format in which you saved it try the following.
y=wavread('t1.wav','native');
wavplay(y);