WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

GUI Stimmgerät

 

char0n
Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 10.07.09
Wohnort: ---
Version: Matlab 7.6.0 (R2008a)
     Beitrag Verfasst am: 10.07.2009, 16:02     Titel: GUI Stimmgerät
  Antworten mit Zitat      
Hallo,

ich arbeite zur Zeit an einem Projekt in dem eine Soundaufnahme über eine FFT in den Frequenzbereich transformiert wird.
Aus diesem Spektrum soll dann der Ton / die Töne herausgelesen werden, um eine Art Stimmgerät für Instrumente zu realisieren.
Dazu habe ich ein GUI aufgebaut, zu dem ich drei Fragen habe:

1. Wie kann ich in dem Plot von dem Spektrum eine Zoom-Funktion einbauen? Der Plot ist ein Axes-Element das ich wie folgt aufrufe:

Code:
% Frequenzspektrum
     n=length(wave)-1;
     f=0:fs/n:fs;
     wavefft=abs(fft(wave));
     plot(handles.axes2,f,wavefft);
     xlim(handles.axes2,[0 1000]); % Limit bei 1kHz um den Rest auszublenden


2. Um den Ton herauszufinden muss ich die Grundfrequenz "rausfiltern" und mit meiner Tabelle vergleichen.
Die Grundfrequenz wäre im Spektrum der erste hohe Ausschlag.
Gibt es eine Funktion die mir Matlab bieten kann um diese Maxima genau zu bestimmen?
Ich habe schon einen ersten Versuch mit "findpeaks" gestarten, wobei mir das Ergebnis noch nicht ganz gepasst hat, vielleicht gibt es bessere Alternativen?

3. Um die Grundfrequenz zu vergleichen brauche ich eine Tabelle die beim Programmstart geladen wird. In dieser sind dann die Töne passend zu den Frequenzen aufgelistet. Wie lade ich das geschickt rein?
Und vorallem was mich am meisten beschäftigt:
Wie kriege ich ein "if"-Abfrage hin die den Wert aus der Tabelle mit dem realen Wert vergleicht. Der reale Wert hat ja eine gewisse Toleranz die vernachläßigt werden könnte.

Ich habe selbst Erfahrung mit C/C++ und auch mit OOP, aber die Möglichkeiten die mir Matlab bietet überfordern mich grad etwas. =)
Muss mich da so langsam aber sicher reintasten, ich hoffe ihr könnt mir helfen.

Im Anhang ist eine erste Version zu sehen.


edit by steve: Code-Umgebung ergänzt. Bitte zukünftig selbstständig formatieren (Button oben mittig). Danke!

Stimmgeraet.JPG
 Beschreibung:
erste Version meines GUIs

Download
 Dateiname:  Stimmgeraet.JPG
 Dateigröße:  86.4 KB
 Heruntergeladen:  673 mal
Private Nachricht senden Benutzer-Profile anzeigen


char0n
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 10.07.09
Wohnort: ---
Version: Matlab 7.6.0 (R2008a)
     Beitrag Verfasst am: 10.07.2009, 16:23     Titel:
  Antworten mit Zitat      
Frage 1 hat sich gerade geklärt ich habe den Toolbar-Editor entdeckt! Smile
Private Nachricht senden Benutzer-Profile anzeigen
 
steve
Ehrenmitglied

Ehrenmitglied



Beiträge: 2.029
Anmeldedatum: 03.09.07
Wohnort: Wien
Version: R2024a
     Beitrag Verfasst am: 10.07.2009, 16:30     Titel:
  Antworten mit Zitat      
Moin,

willkommen im Forum! Smile

zu 1.:
Du könntest einen Toggle-Button erstellen, der die Zoomfunktion an- und ausschaltet:
Code:
uicontrol('Style','togglebutton','Callback',@my_zoom)

function my_zoom(hObject, eventdata)

if ~get(hObject, 'Value')
    zoom off;
else
    zoom on;
end


zu 2.:
Es gibt die Funktion FIND mit welcher man in Kombination der Funktion MAX das ganze recht einfach erledigen kann:
Code:
f=0:fs/n:fs;
wavefft=abs(fft(wave));
GrundFrequenz = f(find(wavefft,max(wavefft)));


zu 3.:
Ich würde eine Matrix erstellen mit den Tönen in einer Spalte und den zugeörigen Frequenzen in der anderen und diese als .mat-file abspeichern. Dieses kann dann geladen werden und die Werte können genutzt werden. Dein Problem des Vergleichens würde ich so lösen, dass du die Differenz zwischen der Grundfrequenz und den gespeicherten Frequenzen berechnest und dir dann das Minimum der Beträge raussuchst (Kombination von FIND und MIN).
Code:
% erstellen und speichern der Tabelle/Matrix:
FrequenzTabelle = [Frequenzen; Toene];
save('FrequenzTabelle.mat', 'Frequenztabelle');
 

Im GUI dann:
Code:
temp = load('FrequenzTabelle');
FrequenzTabelle = temp.FrequenzTabelle;
ton = Frequenztabelle(2,find(Frequenztabelle(1,:), min(abs(Frequenztabelle(1,:)-GrundFrequenz))));


Ich habe die Codes nicht getestet, sie müssten aber soweit so stimmen - hoffe ich...

Gruß
Alex
_________________

>> I told me to.

____________________________________
Matlab Cheat Sheet
goMatlab-Knigge - dran gehalten?!
Schon in den FAQ gesucht?
Ist vielleicht bei den Skripten oder den Tutorials was für dich dabei?
Private Nachricht senden Benutzer-Profile anzeigen
 
char0n
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 10.07.09
Wohnort: ---
Version: Matlab 7.6.0 (R2008a)
     Beitrag Verfasst am: 10.07.2009, 16:45     Titel:
  Antworten mit Zitat      
Sauber, danke für die schnelle Antwort, ich versuche mich direkt mal daran. Smile

Bin heute doch schon weiter gekommen als gedacht.
Nächstes Ziel wird es sein mehrere Töne aus einer Tonleiter zu erkennen.
Da wirds schwieriger in der Hinsicht die passenden Maxima zu finden.
Private Nachricht senden Benutzer-Profile anzeigen
 
char0n
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 10.07.09
Wohnort: ---
Version: Matlab 7.6.0 (R2008a)
     Beitrag Verfasst am: 10.07.2009, 17:22     Titel:
  Antworten mit Zitat      
Ich versuche grad die Matrix zu erstellen, der zickt aber rum weil Buchstaben und Zahlen nicht in eine Matrix gehören...
Was nu?
Private Nachricht senden Benutzer-Profile anzeigen
 
steve
Ehrenmitglied

Ehrenmitglied



Beiträge: 2.029
Anmeldedatum: 03.09.07
Wohnort: Wien
Version: R2024a
     Beitrag Verfasst am: 10.07.2009, 17:28     Titel:
  Antworten mit Zitat      
Nimm statt einer Matrix ein Cell-Array. Funktioniert im Prinzip genauso, nur dass statt runden geschweifte Klammern genommen werden:
Code:
% erstellen und speichern der Tabelle/Matrix:
FrequenzTabelle = {Frequenzen; Toene};
save('FrequenzTabelle.mat', 'Frequenztabelle');

Code:
temp = load('FrequenzTabelle');
FrequenzTabelle = temp.FrequenzTabelle;
ton = FrequenzTabelle{2}(find(FrequenzTabelle{1}, min(abs(FrequenzTabelle{1}-GrundFrequenz))));


Ich hoffe das funktioniert so, wenn nicht: Bescheid sagen Wink

Gruß
Alex
_________________

>> I told me to.

____________________________________
Matlab Cheat Sheet
goMatlab-Knigge - dran gehalten?!
Schon in den FAQ gesucht?
Ist vielleicht bei den Skripten oder den Tutorials was für dich dabei?
Private Nachricht senden Benutzer-Profile anzeigen
 
char0n
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 10.07.09
Wohnort: ---
Version: Matlab 7.6.0 (R2008a)
     Beitrag Verfasst am: 10.07.2009, 17:30     Titel:
  Antworten mit Zitat      
hm ich verstehe nicht genau wie ich diesen befehl nutzen soll?

Code:
FrequenzTabelle = {Frequenzen; Toene};


Ich habe diese Werte schon in einer excel Datei wenn ich die importiere, teilt matlab die Spalten in zwei Tabellen.

Wo pack ich den Befehl hin? In ein M-File? Weil als Kommando klappt das nicht.
Private Nachricht senden Benutzer-Profile anzeigen
 
char0n
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 10.07.09
Wohnort: ---
Version: Matlab 7.6.0 (R2008a)
     Beitrag Verfasst am: 10.07.2009, 17:36     Titel:
  Antworten mit Zitat      
Hab ein bissel probiert:
Die Schreibweise

Code:
Tabelle{440,'a'';110,'A'}


klappt leider nicht weil die Töne wie folgt unterschieden werden:
A1 A a a' a'' a''
Private Nachricht senden Benutzer-Profile anzeigen
 
steve
Ehrenmitglied

Ehrenmitglied



Beiträge: 2.029
Anmeldedatum: 03.09.07
Wohnort: Wien
Version: R2024a
     Beitrag Verfasst am: 10.07.2009, 17:39     Titel:
  Antworten mit Zitat      
Dann brauchst du diese Zeile gar nicht. Du hast dann also schon zwei Variablen, eine mit den Frequenzen und eine mit den Tonbezeichnungen? Das eine wird dann wahrscheinlich eine "normale" Matrix sein und das andere bereits ein Cell-Array?

Dann probiere mal folgendes:
Code:
% "Frequenzen" enthält die Frequenzen und "Toene" die zugehörigen Töne (ich gehe davon aus das das ein Cell-Array ist)
ton = Toene{find(Frequenzen, min(abs(Frequenzen-GrundFrequenz)))};


Gruß
Alex
_________________

>> I told me to.

____________________________________
Matlab Cheat Sheet
goMatlab-Knigge - dran gehalten?!
Schon in den FAQ gesucht?
Ist vielleicht bei den Skripten oder den Tutorials was für dich dabei?
Private Nachricht senden Benutzer-Profile anzeigen
 
char0n
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 10.07.09
Wohnort: ---
Version: Matlab 7.6.0 (R2008a)
     Beitrag Verfasst am: 10.07.2009, 17:43     Titel:
  Antworten mit Zitat      
steve hat Folgendes geschrieben:
Dann brauchst du diese Zeile gar nicht. Du hast dann also schon zwei Variablen, eine mit den Frequenzen und eine mit den Tonbezeichnungen? Das eine wird dann wahrscheinlich eine "normale" Matrix sein und das andere bereits ein Cell-Array?


Das ist korrekt, habe zwei Variablen eine mit Werten die andere mit den Namen.
Private Nachricht senden Benutzer-Profile anzeigen
 
steve
Ehrenmitglied

Ehrenmitglied



Beiträge: 2.029
Anmeldedatum: 03.09.07
Wohnort: Wien
Version: R2024a
     Beitrag Verfasst am: 10.07.2009, 17:46     Titel:
  Antworten mit Zitat      
Dann bin ich mal gespannt ob der Code oben funktioniert... Wink
_________________

>> I told me to.

____________________________________
Matlab Cheat Sheet
goMatlab-Knigge - dran gehalten?!
Schon in den FAQ gesucht?
Ist vielleicht bei den Skripten oder den Tutorials was für dich dabei?
Private Nachricht senden Benutzer-Profile anzeigen
 
char0n
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 10.07.09
Wohnort: ---
Version: Matlab 7.6.0 (R2008a)
     Beitrag Verfasst am: 10.07.2009, 17:55     Titel:
  Antworten mit Zitat      
Zurück zu Punkt 2:

Code:
GrundFrequenz = f(find(wavefft,max(wavefft)));


Klappt leider nicht und gibt folgende Fehlermeldung raus:

Code:
Error in ==> Stimmgeraet at 23
GrundFrequenz = f(find(wavefft,max(wavefft)));


Die Funktion scheint nicht mit den Fließkommazahlen klar zu kommen.
Private Nachricht senden Benutzer-Profile anzeigen
 
steve
Ehrenmitglied

Ehrenmitglied



Beiträge: 2.029
Anmeldedatum: 03.09.07
Wohnort: Wien
Version: R2024a
     Beitrag Verfasst am: 10.07.2009, 18:12     Titel:
  Antworten mit Zitat      
Welche Fehlermeldung gibt er denn aus, denn du hast nur gepostet wo der Fehler auftritt Wink
_________________

>> I told me to.

____________________________________
Matlab Cheat Sheet
goMatlab-Knigge - dran gehalten?!
Schon in den FAQ gesucht?
Ist vielleicht bei den Skripten oder den Tutorials was für dich dabei?
Private Nachricht senden Benutzer-Profile anzeigen
 
char0n
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 10.07.09
Wohnort: ---
Version: Matlab 7.6.0 (R2008a)
     Beitrag Verfasst am: 10.07.2009, 18:15     Titel:
  Antworten mit Zitat      
ups... Smile

Code:
??? Error using ==> find
Second argument must be a positive scalar integer.


Error in ==> Stimmgeraet at 24
GrundFrequenz = f(find(wavefft,max(wavefft)));
Private Nachricht senden Benutzer-Profile anzeigen
 
steve
Ehrenmitglied

Ehrenmitglied



Beiträge: 2.029
Anmeldedatum: 03.09.07
Wohnort: Wien
Version: R2024a
     Beitrag Verfasst am: 10.07.2009, 19:29     Titel:
  Antworten mit Zitat      
AHHHHHHHH Evil or Very Mad

Code:
GrundFrequenz = f(find(isequal(wavefft,max(wavefft))));


so sollte es aber klappen Wink
_________________

>> I told me to.

____________________________________
Matlab Cheat Sheet
goMatlab-Knigge - dran gehalten?!
Schon in den FAQ gesucht?
Ist vielleicht bei den Skripten oder den Tutorials was für dich dabei?
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen

Gehe zu Seite 1, 2  Weiter

Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.