Help with creating a function
Show older comments
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
Wayne King
on 22 Jun 2013
Edited: Wayne King
on 22 Jun 2013
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?
Adam
on 22 Jun 2013
random09983492
on 22 Jun 2013
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.
random09983492
on 23 Jun 2013
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
Adam
on 23 Jun 2013
dpb
on 23 Jun 2013
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.
random09983492
on 23 Jun 2013
Sorry, change:
for i = floor(nsegments)
to
for i = 1:floor(nsegments)
dpb
on 23 Jun 2013
...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.
Adam
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.
Answers (0)
Categories
Find more on Multidimensional Arrays in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!