Help with creating a function

Hi, I am new to Matlab and I am trying to create a function that takes a selected audio signal and segments it into different sections, labelling each section with a variable. I have started to create this function below but when I use it the variables don't appear in the workspace. Have I missed something in the function?
function [a1,a2,a3,a4,a5,a6,a7,a8,a9] = segment(FILE)
x = wavread(FILE);
a1 = x(1:20000);
a2 = x(20000:40000);
a3 = x(40000:60000);
a4 = x(60000:80000);
a5 = x(80000:100000);
a6 = x(100000:120000);
a7 = x(120000:140000);
a8 = x(140000:160000);
a9 = x(16000:180000);
end

13 Comments

A couple comments/questions:
segment.m is a function in the System Identification Toolbox, so if you have that Toolbox in your installation, I would rename your function.
How do you actually call your function? Like this?
[a1,a2,a3,a4,a5,a6,a7,a8,a9] = segment('test.wav');
Does the function throw any errors or warnings when you run it at the command line?
I don't have the System Identification Toolbox installed, although I guess it would be better to rename it anyway. I was calling the function like this. [a1,a2,a3,a4,a5,a6,a7,a8,a9] = segment('test.wav');
I have just done what what you said, and it works. [a1,a2,a3,a4,a5,a6,a7,a8,a9] = segment('test.wav');
Thanks alot for that. I am looking to apply this to several different length audio signals, do you know how I can adapt this function so that it will compute the length and apply the number of variables needed?
How do you want the end of your file to be handled? Meaning, FILE will not be a multiple of 20000 in length always. If you only want to keep segments that are 20000 samples long, you would find out how many segments there are by flooring a simple division and then using a for loop to iterate through each segment. You should store them as an array, where a(1,:) = a1, a(2,:) = a2, etc.
If you do want to keep data at the end of FILE that is less than 20000 points, you can either zero pad FILE until it is a multiple of 20000. If you don't want to zero pad, you will have to use cells rather than an array, where a{1} = a1, a{2} = a2, etc.
If you don't understand I will make a quick implementation for you.
Adam
Adam on 22 Jun 2013
Edited: Adam on 22 Jun 2013
Hi Elliot,
many thanks for your reply. I get the idea but I'm unsure what you mean by zero pad and I'm unsure of how to actually implement it? I would like each signal to be broken into segments that are 20000 in length, but if at the end of the signal there is a 10000 segment remaining I would also need that. I need the function to work like the first code I posted, but also computing the length of the input .wav file and automatically assigning variables to each segment, so I don't have to do it manually as I'm using a few different signals. I'm not sure if that answers your question as to how I want the end of the file to be handled?
By zero padding I mean this: Say your signal is 30,000 points long. Your program would add 10,000 zeros to the end of the signal such that it can be divided into two 20,000 length segments. I am guessing this is not what you want. Here is my quick implementation without zero padding. Let me know if anything does not make sense.
function [a] = segment(FILE)
x = wavread(FILE);
npts = length(x);
pointsPerSegment = 20000;
nsegments = npts/pointsPerSegment;
a = cell(1,ceil(nsegments));
for i = floor(nsegments)
a{i} = x(pointsPerSegment*(i-1)+1:pointsPerSegment*i);
end
a{end} = x(pointsPerSegment*i+1:end);
end
Thanks Elliot,
I'm not sure if does what I want because I don't get any variables in the workspace?
Back to your original question and then the followup makes me think you're not calling the function correctly (or are inside yet another function instead of a script). There's nothing wrong at the function level definition about returning the defined variable(s) so it has to be in what you haven't shown--namely how you're trying to use the function.
And, btw, the idea of creating ten or twelve variables w/ names a1, a2, ..., an is a bad idea...use cell arrays or just colon indexing inside the original array or somesuch instead.
Adam
Adam on 23 Jun 2013
Edited: Adam on 23 Jun 2013
well I am calling the function like this: segment('test.wav');
Ok this does create a 1x5 cell, but I'm confused as the first three columns just contain empty []. Columns 4 and 5 contain around 2000 rows of floating point numbers. What does this represent? And, if the variables are stored in a cell array's is it still possible to use them?
Sorry, change:
for i = floor(nsegments)
to
for i = 1:floor(nsegments)
Adam
Adam on 23 Jun 2013
Edited: Adam on 23 Jun 2013
Thanks Elliot. Do you happen to know if you can use the DWT transform in a function even though it's a function in itself? I am looking to take the outputs of the previous function and use them as the inputs to a new function something like this... (even though I am getting lots of errors)
function [low,high,low1a,low1b,low2c,low2d] = dwtdecomp(y)
[low,high = dwt(y,'haar'); [low1a,low1b] = (high,'haar'); [low1c,low1d] = (low,'haar');
end
...well I am calling the function like this: segment('test.wav');
You haven't assigned the output variable(s) to anything; hence only one will be returned at it will be assigned to the default Matlab variables 'ans' -- again, if this is at the command line or in a script it'll be in the workspace; if this is in another function that you haven't shown then when that function returns, 'ans' locally will vanish into the ether along w/ the results.
Since you say you do get a 1x5 cell, I then presume that you must have been at the command line or a script -- the problem w/ the empty cells is that Elliot as he notes forgot the lower bound on the for loop so only the last element was created. ML by default then created the empty preceding 4 locations.
And, yes, of course, you can address/use a cell array contents; you do have to dereference the cell address to get the content by using the {} ("curlies") instead of plain paren's to do so.
If it were me, for this purpose I'd likely just create an array excepting that the last one is/may be shorter in length which is why Elliot chose the cell--it can handle the case. As I suggested, I'd be more inclined to simply use colon addressing to get the section desired from the original array rather than creating the new variable(s), cell array.
Ahh ok I've got it now, that was really helpful, thanks for explaining that!
But how can I use say B2 for instance as the input of another function that I'm creating
function [d] = testFunction(variable{})
like that?
dpb
dpb on 23 Jun 2013
Edited: dpb on 23 Jun 2013
I suggest reading up in the 'Getting Started' section and then the full documentation on functions to get a better overall handle on the syntax and calling conventions. Also, go to the section on Data Structures and read up on cell arrays and the section on how to address them.
As for passing anything to another function, you just include it in the argument list at the right location as expected by the called function (assuming order association rather than named arguments vis a vis oop methods). You do not include the braces or parens in the function definition.
As for passing the results of a function, sure if it is the type and size that the function is expecting. Note, however, that there's no way to assign multiple outputs from the called function in this context so the returned value "seen" by the called function will be that of the first returned variable only of the function if more than one are possible.

Sign in to comment.

Answers (0)

Categories

Asked:

on 22 Jun 2013

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!