Hey all,
The basic start of my program i'm trying to write is to take user input of note values and create a wav file based upon these values but I'm having problems with parsing the user input and converting it to the particular frequency of that note..
Here is my code so far:
% SHOW INPUT DIALOG AND TAKE USER INPUT..
prompt={'1st Note','2nd Note','3rd Note','4th Note','5th Note','6th Note','7th Note'};
name='Enter Note Values (C-B)..';
num_lines=1;
%list = {'B'};
%options.Interpreter = 'tex';
defaultans={'C','D','E','F','G','A','B'};
answer=inputdlg(prompt,name,[1 50],defaultans);
% TEST IF USER FORGETS AN INPUT..
for x = 1:length(answer)
tf=isempty(answer);
if tf==1
msgbox('You missed a note(s) out..','Error','error','modal');
end
% END IF..
end
% END FOR..
% CONFIGURE INPUT TO VARIABLES..
Note1 = answer{1};
Note2 = answer{2};
Note3 = answer{3};
Note4 = answer{4};
Note5 = answer{5};
Note6 = answer{6};
Note7 = answer{7};
% LOOP THROUGH ANSWERS AND ASSIGN FREQUENCY VALUES..
for x = 1:length(answer)
if answer{x} == 'C'
FreqX = num2str(261.626);
elseif answer{x} == 'D'
FreqX = num2str(293.665);
elseif answer{x} == 'E'
FreqX = num2str(329.628);
elseif answer{x} == 'F'
FreqX = num2str(349.228);
elseif answer{x} == 'G'
FreqX = num2str(391.995);
elseif answer{x} == 'A'
FreqX = num2str(440.000);
elseif answer{x} == 'B'
FreqX = num2str(493.883);
end
% END IF..
end
% END FOR..
msgbox({'Freq1 is: ', FreqX, 'Hz' 'Note1 is: ', Note1});
msgbox({'Freq2 is: ', FreqX, 'Hz' 'Note2 is: ', Note2});
Now although there are no errors, its working as intended. The msgboxes are simple to help me see the results as i build my program but the frequency it displays is always the final one in the if statement.
I could do if statements for EACH of the answer{} array but this would be a lot of code so what would be the best way to iterate through the answers and assign the correct frequency values..
I can't get my head around the best and easiest way..
Any ideas?
Thanks,
Paul

 채택된 답변

Stephen23
Stephen23 2015년 11월 14일
편집: Stephen23 2015년 11월 14일

1 개 추천

Note that you should not use numbered variables, as this invariably leads beginners to dynamic variable naming, which is a very poor programming practice. Instead you should note that these numbers are essentially indices, in which case actually make them real indices. Read this to know why numbered variables are a bad idea:
And this to know why dynamically naming variable is an even worse idea:
Also using if's and loops is slow and inefficient: MATLAB works best when you learn how to write vectorized code, and to not use loops to solve every little task. Try this:
prompt={'1st Note','2nd Note','3rd Note','4th Note','5th Note','6th Note','7th Note'};
name='Enter Note Values (C-B)..';
defaultans={'C','D','E','F','G','A','B'};
answer=inputdlg(prompt,name,[1,50],defaultans);
% These three lines replace all of your loop and elseif statements:
V = 'CDEFGAB';
idx = cellfun(@(c)find(V==c),answer);
frq = [261.626,293.665,329.628,349.228,391.995,440.000,493.883];
out = frq(idx)

댓글 수: 5

Edmund Paul Malinowski
Edmund Paul Malinowski 2015년 11월 16일
편집: Edmund Paul Malinowski 2015년 11월 17일
Hi Stephen, thank you so much for the extensive reply. As a beginner to Matlab its great to have that kind of feedback and be steered down the correct paths before newbie bad habits can form.
I think i understand the 3 lines you've written and i looked into the cellfun function but with how you've coded it, how can i access the various elements in the arrays?
I want to be able to pluck out the various frequencies so i can use them in making sine waves and also the letter that the user entered.
When i change the order of the note letters, the output changes to suit which is awesome but i just need to learn how its done and how to extract say the 5th chosen note letter and its corresponding frequency..
Stephen23
Stephen23 2015년 11월 17일
편집: Stephen23 2015년 11월 17일
I used cellfun and find to generate subscript indices idx, this index is then used to select the frequencies that match the user input notes. This means that the order of V and frq must be the same.
You have the user's selection in the variable answer, and the corresponding frequencies in out. To get the fifth of each you can use subscript indexing:
answer{5}
out(5)
Edmund Paul Malinowski
Edmund Paul Malinowski 2015년 11월 17일
That's awesome, thanks for that Stephen :)
Edmund Paul Malinowski
Edmund Paul Malinowski 2015년 11월 18일
Hey Stephen,
Sorry to bother you again. I now have an actual GUIDE GUI designed with 7 edit text boxes rather than just the original inputdlg. Is there a way i can still use the code you suggested for this? Do i just make the input from these edit boxes answer{1}, answer{2} etc?
Don't worry, I've sussed it :) i used:
answer{1} = get(handles.edit1note,'String');
answer{2} = get(handles.edit2note,'String');
answer{3} = get(handles.edit3note,'String');
answer{4} = get(handles.edit4note,'String');
answer{5} = get(handles.edit5note,'String');
answer{6} = get(handles.edit6note,'String');
answer{7} = get(handles.edit7note,'String');
Although this probably could be shortened somehow but i'm happy with it as it is. I can always refine it if i get time before the hand-in deadline :)

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Programming에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by