a problem with wavread function - matlab

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);

Related

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?

Using repmat() to equalise the length of two audio files Matlab

Having a slight issue with the repmat() function.
I've got two audio files that I'm using for cross synthesis in Matlab, I want to make the second audio file repeat so it's the same length as the first one.
Currently I'm doing
c = size(y());
rep = y2(1:end,:);
y(1:end,:) = repmat(rep,1, c(1))
Yet it's not making a 1D matrix, any suggestions?
y and y2 are just the y values of each song converted to mono.
Thanks!
I actually managed to solve it myself, turns out I was using them in the wrong order, needed to be repmat(rep c(1), 1)!

Quantization of .wav file

I am attempting to quantize a 16 bit .wav file to a lower bit rate using Matlab. I've opened the file using wavread() but I am unsure of how to proceed from here. I know that somehow I need to "round" each sample value to (for example) a 7 bit number. Here's the code that's reading the file:
[file,rate,bits] = wavread('smb.wav');
file is a 1 column matrix containing the values of each sample. I can loop through each item in that matrix like so:
for i=1 : length(file)
% not sure what to put here..
end
Could you point me in the right direction to quantize the data?
If you have int16 data, varying from -32768 to +32767, it can be as simple as
new_data = int8(old_data./2^8);
That won't even require a for loop.
For scaled doubles it would be
new_data = int8(old_data.*2^7);
The wavread documentation suggests that you might even be able retrieve the data in that format to begin with:
[file,rate,bits] = wavread('smb.wav','int8');
EDIT: Changing the bit rate:
After rereading the question, I realize that you also mentioned a lower bit rate which implies reducing the sample rate, not the quantization of the data. If that is the case, you should look at the documentation for downsample, decimate, and/or resample. They are all built in MATLAB functions that change the bit rate.
downsample(file,2)
would half the bit rate, for example.

basic - Trying to add noise to an Audio file and trying to reduce errors using basic coding such as Repeatition code

We were recently taught the concepts of error control coding - basic codes such as Hamming code, repeatition code etc.
I thought of trying out these concepts in MATLAB. My goal was to compare how an audio file plays when corrupted by noise and in the case when the file is protected by basic codes and then corrupted by noise.
So I opened a small audio clip of 20-30 seconds in MATLAB using audioread function. I used 16 bit encoded PCM wave file.
If opened in 'native' format it is in int16 format . If not it opens in a double format.
I then added two types of noises to it : - AWGN noise (using double format) and Binary Symmetric Channel noise (by converting the int16 to uint16 and then by converting that to binary using dec2bin function). Reconverting back to the original int16 format does add a lot of noise to it.
Now my goal is to try out a basic repeatition code. So what I did was to convert the 2-d audio file matrix which consists of binary data into a 3-d matrix by adding redundancy. I used the following command : -
cat(3,x,x,x,x,x) ;
It created a 3-D matrix such that it had 5 versions of x along the 3rd dimension.
Now I wish to add noise to it using bsc function.
Then I wish to do the decoding of the redundant data by removing the repetition bits using a mode() function on the vector which contains the redundant bits.
My whole problem in this task is that MATLAB is taking too long to do the computation. I guess a 30 second file creates quite a big matrix so maybe its taking time. Moreover I suspect what I am doing is not the most efficient way to do it with regards to the various data types.
Can you suggest a way in which I may improve on the computation times. Are there some functions which can help do this basic task in a better way.
Thanks.
(first post on this site with respect to MATLAB so bear with me if the posting format is not upto the mark.)
Edit - posting the code here :-
[x,Fs] = audioread('sample.wav','native'); % native loads it in int16 format , Fs of sample is 44 khz , size of x is 1796365x1
x1 = x - min(x); % to make all values non negative
s = dec2bin(x); % this makes s as a 1796365x15 matrix the binary stream stored as character string of length 15. BSC channel needs double as the data type
s1 = double(s) - 48; % to get 0s and 1s in double format
%% Now I wish to compare how noise affects s1 itself or to a matrix which is error control coded.
s2 = bsc(s,0.15); % this adds errors with probability of 0.15
s3 = cat(3,s,s,s,s,s) ; % the goal here is to add repetition redundancy. I will try out other efficient codes such as Hamming Code later.
s4 = bsc(s3,0.15);% this step is taking forever and my PC is unresponsive because of this one.
s5 = mode(s4(,,:)) ; % i wish to know if this is a proper syntax, what I want to do is calculate mode along the 3rd dimension just to remove redundancy and thereby reduce error.
%% i will show what I did after s was corrupted by bsc errors in s2,
d = char(s2 + 48);
d1 = bin2dec(d) + min(x);
sound(d1,Fs); % this plays the noisy file. I wish to do the same with error control coded matrix but as I said in a previous step it is highly unresponsive.
I suppose what is mostly wrong with my task is that I took a large sampling rate and hence the vector was very big.

fft on samples of an audio file in 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