(17 intermediate revisions by the same user not shown)
Line 8: Line 8:
  
 
===Audio Impulse Response===
 
===Audio Impulse Response===
We have seen impulse responses expressed as mathematical functions such as <math>2^{-n}u[n]</math>. Such functions we compute convolutions with in class may model actual impulse responses such as the fading echo heard after clapping in a concert hall or ringing of a gong after being struck. To obtain a good impulse response recording, audio data should include the sound from just after the impulse until it has died away sufficiently. Distortion of the output may result from convolving with an incorrectly recorded impulse response.
+
We have seen impulse responses expressed as mathematical functions such as <math>2^{-n}u[n]</math>. Such functions we compute convolutions with in class may model actual impulse responses such as the fading echo heard after clapping in a concert hall or ringing of a gong after being struck. To obtain a good impulse response recording, audio data should include the sound from just after the impulse until it has died away sufficiently. Distortion of the output may result from convolving with an incorrectly recorded impulse response or by starting the recording of the input audio signal with silence.  
  
  
Line 15: Line 15:
  
 
==The Code==
 
==The Code==
Below are line numbered code listings for the required Matlab functions.
+
Below are line numbered code listings for the required Matlab helper functions.
  
Function for recording audio.  
+
Function for recording X seconds of audio.  
 
<code><syntaxhighlight lang="MATLAB" line='line'>
 
<code><syntaxhighlight lang="MATLAB" line='line'>
 
function [ ] = recordToFile( inFileName, Fs, nbits, seconds )  
 
function [ ] = recordToFile( inFileName, Fs, nbits, seconds )  
Line 30: Line 30:
 
</syntaxhighlight></code>
 
</syntaxhighlight></code>
  
Function for trimming audio from the back end of the audio data
+
Function for trimming X seconds audio from the back end of the audio data
 +
 
 
<code><syntaxhighlight lang="MATLAB" line='line'>
 
<code><syntaxhighlight lang="MATLAB" line='line'>
 
function [ lengthSec ] = trimAudioEnd( inFileName, seconds )
 
function [ lengthSec ] = trimAudioEnd( inFileName, seconds )
Line 48: Line 49:
 
</syntaxhighlight></code>
 
</syntaxhighlight></code>
  
Function for trimming audio from the front end of the audio data
+
Function for trimming X seconds of audio from the front end of the audio data
 +
 
 
<code><syntaxhighlight lang="MATLAB" line='line'>
 
<code><syntaxhighlight lang="MATLAB" line='line'>
function [ outFile, lengthSec ] = trimAudioFront( inFileName, seconds )
+
function [ lengthSec ] = trimAudioFront( inFileName, seconds )
 
%trimAudioFront: cut out the first x seconds of audio, output the  
 
%trimAudioFront: cut out the first x seconds of audio, output the  
 
%file pointer and the length in seconds of audio contained in the file now.
 
%file pointer and the length in seconds of audio contained in the file now.
Line 80: Line 82:
 
end
 
end
 
audiowrite(inFileName,y1,fs);
 
audiowrite(inFileName,y1,fs);
 +
lengthSec = length(y1) / fs;
 
end
 
end
 
</syntaxhighlight></code>
 
</syntaxhighlight></code>
 +
 +
Function to play an audio file supported by Matlab
 +
 +
<code><syntaxhighlight lang="MATLAB" line='line'>
 +
function [ ] = playAudioNormal( inFileName )
 +
%playAudioNormal: playback an audio file at sampling rate with which it was
 +
%sampled
 +
%param inFileName: string name('') of the audio file to play
 +
[y,fs] = audioread(inFileName);
 +
f = audioread(inFileName);
 +
sound(f,fs)
 +
end
 +
</syntaxhighlight></code>
 +
 +
<code><syntaxhighlight lang="MATLAB" line='line'>
 +
function [ ] = convolveAudio(inputAudioFileName, impulseResponseFileName, outputFileName, Fs)
 +
%colvolveAudio: compute the convolution of the audio signals stored in two
 +
%files and create a new audio file containing the output audio signal
 +
 +
%param Fs: the frequency that the input audio signals were sampled at
 +
%param outputFileName: name of the output audio file
 +
%param impulseResponseFileName: name of the trimmed impulse response audio
 +
%file
 +
%param inputAudioFileName: name of the input audio file to the system
 +
x = audioread(inputAudioFileName);
 +
h = audioread(impulseResponseFileName);
 +
y = conv(x,h);
 +
audiowrite(outputFileName, y, Fs);
 +
end
 +
</syntaxhighlight></code>
 +
 +
''[[File:convolution_experiment_src.zip|Download Source Package]]''
 +
 +
===Experiment Procedure===
 +
The overall procedure includes recording my normal voice, recording the impulse response, trimming the impulse response, convolving the two audio signals, and finally playing the output.
 +
 +
Detailed procedure:
 +
* In the command window in Matlab, run the ''recordToFile'' function and record your voice for any length of time.
 +
* Trim the input audio using the ''trimAudioFront'' function until the audio starts at almost exactly the beginning of the audio file.
 +
* Record the impulse response of the cactus cup by calling the ''recordToFile'' function for about 1 second, using a different file name. During the 1 second of recording, hit the bottom of the cup with your hand or finger while holding the cup opening very near your laptop microphone.
 +
* Next, trim the front of the impulse response audio file so that the impulse is just trimmed out. This may take several iterations of using the ''trimAudioFront'' and ''playAudioNormal'' functions.
 +
* Finally, call the ''convolveAudio'' and then listen to your output!
 +
 +
Here is an example of the files I used in the experiment:
 +
 +
[[Media:normal-voice.wav|normal voice]]
 +
 +
[[Media:cup-impulse.wav |cup impulse]]
 +
 +
[[Media:cup-voice-synthesized.wav |synthesized output]] (system output)
 +
 +
[[Media:cup-voice-real.wav |actual output]] (me actually speaking into the cup near the mic)
 +
 +
If you run this experiment in Matlab you will notice that the output file is the combined length of the impulse audio file and the input audio file. This makes sense from what we know about computing DT convolution.
 +
 +
 +
===Convolution Fun: The voice of Bane===
 +
Have some fun experimenting with the procedure and code above, here is my attempt to create a bane voice:
 +
 +
[[Media:Bane-actual.wav|recorded bane voice]]
 +
 +
[[Media:input-bane-quote.wav|my voice]]
 +
 +
[[Media:bane-impulse3.wav |first impulse]]
 +
 +
[[Media:bane-impulse4.wav |second impulse]]
 +
 +
[[Media:bane-voice-imp3.wav |output of first system]]
 +
 +
[[Media:bane-voice-imp3-imp4.wav |output of the second system]]

Latest revision as of 23:57, 2 December 2018

Application of LTI Systems and Convolution in Matlab

Background

Often music groups would like to make their studio recordings sound as if they were played in a live venue. One method to achieve this is to convolve the audio recording with an impulse response taken from the concert venue, or another location with similar acoustics.

Convolution may also be used in the same way to alter your voice which will be demonstrated below. All you need to try out the experiments are a laptop with microphone, Matlab student edition or better, and a couple everyday items.

Audio Impulse Response

We have seen impulse responses expressed as mathematical functions such as $ 2^{-n}u[n] $. Such functions we compute convolutions with in class may model actual impulse responses such as the fading echo heard after clapping in a concert hall or ringing of a gong after being struck. To obtain a good impulse response recording, audio data should include the sound from just after the impulse until it has died away sufficiently. Distortion of the output may result from convolving with an incorrectly recorded impulse response or by starting the recording of the input audio signal with silence.


Voice Effect Experiment

I will demonstrate the procedure for creating voice effects with convolution with a Matlab experiment. I will attempt to make my voice sound as if I am speaking into an empty cactus cup (large plastic cup), by convolving my normal voice with the impulse response of the cup.

The Code

Below are line numbered code listings for the required Matlab helper functions.

Function for recording X seconds of audio.

  1. function [ ] = recordToFile( inFileName, Fs, nbits, seconds ) 
  2. %record audio to a file with specified name, record for specified time, 
  3. %and at the sampling frequency and bit size (8,16,or 24) 
  4. recordObj = audiorecorder(Fs, nbits, 1); 
  5. record(recordObj); 
  6. pause(seconds); 
  7. stop(recordObj); 
  8. audiowrite(inFileName, getaudiodata(recordObj), Fs); 
  9. end

Function for trimming X seconds audio from the back end of the audio data

  1. function [ lengthSec ] = trimAudioEnd( inFileName, seconds )
  2. %trimAudioEnd: truncate audio file by x seconds, output the 
  3. %file pointer and the length in seconds of audio contained in the file now.
  4. %param inFileName: the name of the audiofile
  5. %param seconds: seconds of audio to trim from the end
  6. [y,fs] = audioread(inFileName);
  7. if mod(seconds*fs, 1) ~= 0
  8.     error('sample frequency times seconds must be an integer')
  9. end
  10. samples = [1, length(y) - (seconds*fs)];
  11. [y1,fs] = audioread(inFileName, samples);
  12. audiowrite(inFileName, y1, fs);
  13. lengthSec = length(y1) / fs;
  14. end

Function for trimming X seconds of audio from the front end of the audio data

  1. function [ lengthSec ] = trimAudioFront( inFileName, seconds )
  2. %trimAudioFront: cut out the first x seconds of audio, output the 
  3. %file pointer and the length in seconds of audio contained in the file now.
  4. %param inFileName: string that is the name of the audio file
  5. %param seconds rational floating point amount of time, must be a multiple
  6. %of the frequency at which the input audio was sampled
  7.  
  8. %error checking
  9. [y,fs] = audioread(inFileName);
  10. if mod(seconds*fs, 1) ~= 0
  11.     error('sample frequency times seconds must be an integer')
  12. end
  13. %steps:
  14. %1. flip the audio data in y array
  15. %2. write data to the inFile
  16. %3. call trimAudioEnd on the aufio file
  17. %4. flip the data of the trimmed file back
  18.  
  19. y_copy = y;
  20. for k = 1:length(y)
  21.     y(k) = y_copy(length(y) - (k-1));
  22. end
  23. audiowrite(inFileName, y, fs);
  24. trimAudioEnd(inFileName,seconds);
  25. [y1,fs] = audioread(inFileName);
  26. y1_copy = y1;
  27. for k = 1:length(y1)
  28.     y1(k) = y1_copy(length(y1) - (k-1));
  29. end
  30. audiowrite(inFileName,y1,fs);
  31. lengthSec = length(y1) / fs;
  32. end

Function to play an audio file supported by Matlab

  1. function [ ] = playAudioNormal( inFileName )
  2. %playAudioNormal: playback an audio file at sampling rate with which it was
  3. %sampled
  4. %param inFileName: string name('') of the audio file to play
  5. [y,fs] = audioread(inFileName);
  6. f = audioread(inFileName);
  7. sound(f,fs)
  8. end
  1. function [ ] = convolveAudio(inputAudioFileName, impulseResponseFileName, outputFileName, Fs)
  2. %colvolveAudio: compute the convolution of the audio signals stored in two
  3. %files and create a new audio file containing the output audio signal
  4.  
  5. %param Fs: the frequency that the input audio signals were sampled at
  6. %param outputFileName: name of the output audio file
  7. %param impulseResponseFileName: name of the trimmed impulse response audio
  8. %file
  9. %param inputAudioFileName: name of the input audio file to the system
  10. x = audioread(inputAudioFileName);
  11. h = audioread(impulseResponseFileName);
  12. y = conv(x,h);
  13. audiowrite(outputFileName, y, Fs);
  14. end

File:Convolution experiment src.zip

Experiment Procedure

The overall procedure includes recording my normal voice, recording the impulse response, trimming the impulse response, convolving the two audio signals, and finally playing the output.

Detailed procedure:

  • In the command window in Matlab, run the recordToFile function and record your voice for any length of time.
  • Trim the input audio using the trimAudioFront function until the audio starts at almost exactly the beginning of the audio file.
  • Record the impulse response of the cactus cup by calling the recordToFile function for about 1 second, using a different file name. During the 1 second of recording, hit the bottom of the cup with your hand or finger while holding the cup opening very near your laptop microphone.
  • Next, trim the front of the impulse response audio file so that the impulse is just trimmed out. This may take several iterations of using the trimAudioFront and playAudioNormal functions.
  • Finally, call the convolveAudio and then listen to your output!

Here is an example of the files I used in the experiment:

normal voice

cup impulse

synthesized output (system output)

actual output (me actually speaking into the cup near the mic)

If you run this experiment in Matlab you will notice that the output file is the combined length of the impulse audio file and the input audio file. This makes sense from what we know about computing DT convolution.


Convolution Fun: The voice of Bane

Have some fun experimenting with the procedure and code above, here is my attempt to create a bane voice:

recorded bane voice

my voice

first impulse

second impulse

output of first system

output of the second system

Alumni Liaison

Questions/answers with a recent ECE grad

Ryne Rayburn