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

Audiosignalanalyse mittels spectrogram, Events ausschneiden

 

bastianj.
Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 06.08.18
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 06.08.2018, 16:12     Titel: Audiosignalanalyse mittels spectrogram, Events ausschneiden
  Antworten mit Zitat      
Hallo zusammen,

als erstes mal Danke ans gesamte Forum!! Habe hier schon unmengen super Infos rausgezogen.

Momentan versuche ich mich an der Analyse von Audiosignalen, welche in .bin Dateien vorliegen. Der Signalverlauf sieht wie folgt aus: Start der Messung, aufzeichnen des Hintergrundrauschens, zu einer unbestimmten Zeit startet ein Prozess und wird aufgezeichnet, der Prozess stoppt, und nach einer unbestimmten Zeit startet dieser erneut.
Das ganze wiederholt sich mehrmals. Anschließend werden die Daten als .bin file abgespeichert. Die SamplingRate beträgt 2 MHz.

Zum einlesen der Dateien und Berechnen der benötigten Variablen sowie dem abspeichern dieser als .mat-file habe ich folgende Funktion geschrieben:

Code:
%Auslesen des .bin Files und zugehörigem Header-file

function micread ()

clear all; close all hidden;

    filename=uigetfile('hier steht ein Pfad*.bin');
   
                fBands=2^10; % number of frequency bands; 2^10 corresponds to 512 bins, as is default for HFMES system
         
                % read information from Header-File
                fileIDtxt=fopen(strcat(filename(1:end-4),'.txt'));                  % open .txt file corresponding to .bin file  
                txtfile=textscan(fileIDtxt,'%s');                                   % reads data from .txt file into a cell array txtfile until it doesnt match with filespec - %s
                tab=str2double(txtfile{1}{6}(9:end));                               % reads out txt file and writes variable as double
                tbis=str2double(txtfile{1}{8}(9:end));                              % reads out txt file and writes variable as double
                T=tbis-tab;
               
                % opens .bin file and read out information
                fileIDbin=fopen(filename);                                          % opens .bin file
                sound=fread(fileIDbin,'int32');                                     % reads 32-bit signed integer array from .bin file and writes in var. sound
                fclose(fileIDbin);                                                  % closes .bin file
               
                % calculate variables
                samplingRate=size(sound,1)/T;  
                splittedname=strsplit(filename,'_');                                % splits string at _ and writes in array var. splittedname
                tinc= 1/samplingRate;                                               % Time increment
               
                % calculate spectrum
                [spectrum,fs,ts]=spectrogram(sound,fBands,0,fBands,samplingRate);   % uses spectrogram function, windowsize fbands=1024 Hamming  Window, 0 noverlap
                [nf,nt]=size(spectrum);
                fVec = linspace(1, samplingRate/2, size(spectrum,1));               % frequency axis;
                tVec= linspace(tab,tbis,nt);                                          % time axis
               
                % Integral over frequency band (besser über ui manuel eingeben?)            
                fLowCut = 100e3;                                                    % lower frequency cutoff
                fHighCut = fVec(end);                                               % upper frequency cutoff
               
                % calculate variables for cropped spectrum
                [~, fLowCut_idx] = min(abs(fVec - fLowCut)); fLowCut_idx = fLowCut_idx(1);
                [~, fHighCut_idx] = min(abs(fVec - fHighCut)); fHighCut_idx = fHighCut_idx(1);

                spectrumCropped = spectrum(fLowCut_idx:fHighCut_idx, :);
                fVecCropped = fVec(fLowCut_idx:fHighCut_idx);
                spectrumIntegral = sum(abs(spectrumCropped));

        % save as .mat File        
        save(filename(1:end-4))
end



Soweit, so gut. Mein Problem nun ist, das ich gerne eine Funktion schreiben würde, die erkennt, wenn der Signalwert über einen gewissen Schwellenwert ansteigt, und das Ereignis bis zum abfallen unter diesen Schwellenwert "ausschneidet" und als .mat file abspeichert. Da je Messung unterschiedlich viele (zwischen 20 und 300) Ereignisse aufgezeichnet werden, würde ich das gerne automatisiert ablaufen lassen.

Ich wäre über Anhaltspunkte oder Verweise sehr dankbar. In der Suche habe ich leider nichts passendes gefunden. Da ich relativ unerfahren mit Matlab bin sind mir wahrscheinlich viele Lösungen und Funktionen gar nicht ins Auge gefallen. Daher bitte ich schon mal um Gnade Smile

Vielen Dank schonmal und Beste Grüße
Bastian
Private Nachricht senden Benutzer-Profile anzeigen


Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 06.08.2018, 18:48     Titel: Re: Audiosignalanalyse mittels spectrogram, Events ausschnei
  Antworten mit Zitat      
Hallo bastianj.,

Das "clear all; close all hidden;" ist eine ziemlich brutale Methode erst mal alles aus dem Speicher zu löschen und Matlab zu zwingen, u.a. alle Funktionen neu von der Festplatte zu laden. Am Beginn einer Funktion ist das reine Zeitverschwendung. Auch das Schließen aller Figures ist hier nicht hilfreich. Wieso sollte dieser Code Einfluss auc alle bereits geöffneten GUIs haben?
Leider sieht man diesen "brutalen CLEAR Header" sehr häufig und ich bin immer wieder erstaunt, wer einem so etwas empfehlen. In produktivem Code ist es lediglich ein Schuss ins Knie.

Wenn ich Dich richtig verstehe, hat der gepostete Code nichts mit Deinem Problem zu tun, oder?

Zitat:
Mein Problem nun ist, das ich gerne eine Funktion schreiben würde, die erkennt, wenn der Signalwert über einen gewissen Schwellenwert ansteigt, und das Ereignis bis zum abfallen unter diesen Schwellenwert "ausschneidet" und als .mat file abspeichert.

Das müsstest Du genauer erklären: Welches Signal, welcher Schwellenwert, in welchem Format abspeichern? Was möchtest Du tun, wenn lediglich ein einzelnes Element oberhalb des Schwellenwertes liegt?

An sich sollte das einfach sein:
Code:
x = linspace(0, 10*pi, 1000);
y = sin(x);
thresh = 0.6;
match = [false, y > thresh, false];
ini = strfind(match, [false, true]) + 1;
fin = strfind(match, [true, false]);
for k = 1:numel(ini)
   Block = y(ini(k):y(fin(k));
   save ... ???
end

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
bastianj.
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 06.08.18
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 06.08.2018, 19:16     Titel:
  Antworten mit Zitat      
Hi Jan,

vielen Dank für deine Antwort. Den "Clear Header" zu benutzen wurde mir tatsächlich so gesagt. Dann hau ich den mal wieder raus.

Prinzipiell geht es darum, die Interessanten Bereiche einzeln auswerten zu können. Dazu würde ich diese gerne vom gesamten Signal(verlauf) raustrennen. Ich habe einen dieser Signalverläufe als Bild angehängt, vielleicht wird es damit etwas verständlicher. Da ich gerade in die Materie einsteige, fällt mir eine genaue Definition des Problems noch etwas schwer, wie man erkennen kann Smile

Den Schwellenwert würde gerne über dem Grund rauschen festlegen, ich hoffe das ist verständlich.
Abspeichern würde ich das ausgeschnittene Signal gerne als Matrix aus Amplituden und Zeitwert, ob ich das am besten vor der stft oder danach mache ist mir noch nicht ganz klar. Wobei das abspeichern eig. kein Problem darstellt, wichtig ist eig. nur das "Ausschneiden" für die einzelne Betrachtung.

Ich werde es direkt mal mit deinem Code ausprobieren.

Vielen Dank schonmal
und Beste Grüße

Signal zeit.JPG
 Beschreibung:

Download
 Dateiname:  Signal zeit.JPG
 Dateigröße:  70.96 KB
 Heruntergeladen:  210 mal
Signal frequenz.JPG
 Beschreibung:

Download
 Dateiname:  Signal frequenz.JPG
 Dateigröße:  94.98 KB
 Heruntergeladen:  205 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
bastianj.
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 06.08.18
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 09.08.2018, 23:53     Titel:
  Antworten mit Zitat      
Hallo zusammen,

leider hab Ichs mit deine Methode nicht hinbekommen, ich bleib aber mal dran. Hier mal meine Idee:

Code:
%

filename=uigetfile('irgendeinPfad.bin');
   
samplingRate = 2e6;
    Layertime=45; % delta t bzw. Dauer eines Ereignisses
    thresh=2.1*10^5; Schwellwert ab wann Signal ausgelesen werden soll
    tab=0; Startwert
    tbis=10; Endwert

                        while tab<1000
   
                        fileIDbin=fopen(filename);       % öffne .bin file                                                                    
                        fseek(fileIDbin, tab*samplingRate*4, 0); % suche Startpunkt/index
                        sound=fread(fileIDbin,(tbis-tab)*samplingRate,'int32'); % lese ein bis delta t *samplingRate
                        fclose(fileIDbin); %schließe file
                       
                        index=find(sound>thresh,1,'first'); % suche Index des Schwellenwertes
                       
                        tab=index/(samplingRate*4); % berechne neue Startzeit
                        tbis=tab+Layertime; % berechne neue Endzeit
                        fileIDbin=fopen(filename); % öffne .bin file  
                        fseek(fileIDbin, tab*samplingRate*4, 0); % suche neuen Startpunkt/index
                        sound3=fread(fileIDbin,(tbis-tab)*samplingRate,'int32'); % lese ein bis delta t *samplingRate
                        fclose(fileIDbin); % schließe file
                       

                        TAB=num2str(tab); % tab to string                                        
         TBIS=num2str(tbis);   % tbis to string                                
                        Filename = (filename(1:end-4)); % var. FILENAME without .bin                        
                        Layername=[Filename '_''Time''(' TAB '-' TBIS ')']; % Layername + LayerTime
                        save(Layername);
             
                        tab=tab+Layertime;
                       
                        end
end
                       



Das Problem dabei: Beim ersten einlesen und abspeichern der Sound Variablen habe ich das Signal welches ich "untersuchen" will zunächst als kurzes stück eingeladen und sehe auch das korrekte Signal im plot (siehe Bild "vor").
Beim zweiten durchfaul, bei welchem eig. nur das Signal Sound ab dem Schwellenwert (bis zum Endwert) aufgezeichnet bzw ausgetrennt werden soll, wird leider nicht so ausgelesen/abgespeichert wie ich mir das vorstelle (Bild "nach").
Ich verstehe gerade leider nicht was außer der veränderten Startzeit einen Einfluss auf das Signal hat.

Vielleicht erkennt einer von euch ja auf Anhieb wo mein Denkfehler liegt, ich seh gerade garnix mehr Smile

Beste Grüße
Bastian

nach.JPG
 Beschreibung:

Download
 Dateiname:  nach.JPG
 Dateigröße:  38.58 KB
 Heruntergeladen:  200 mal
vor.JPG
 Beschreibung:

Download
 Dateiname:  vor.JPG
 Dateigröße:  46.86 KB
 Heruntergeladen:  208 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
bastianj.
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 06.08.18
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 10.08.2018, 01:13     Titel:
  Antworten mit Zitat      
Oh habs gefunden Smile da war wohl eine 4 zuviel Smile

Dennoch läuft es leider nicht wie gewollt. Werde morgen mehr dazu schreiben.

Grüße
Bastian
Private Nachricht senden Benutzer-Profile anzeigen
 
bastianj.
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 06.08.18
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 15.08.2018, 20:43     Titel:
  Antworten mit Zitat      
Hallo zusammen,

ich habe mich nun dazu entschlossen das ganze nicht über die Zeit, sondern über einen Wertevergleich "ausschneiden" zu lassen. Dabei wird zunächst ein kurzer Ausschnitt des Signals (der sicher aus rauschen besteht) eingelesen und der zugehörige Maximalwert wird ermittelt.
Anschließend wird diesem zur Sicherheitwert noch ein bestimmter Wert hinzugefügt ("Threshhold").
Dann wird ein kurzer ausschnitt des Signals eingelesen und der Maximalwert ermittelt, mit dem Maximalwert des Rauschens verglichen. Wenn der Signalwert über dem des Rauschens liegt, wird die zugehörige Zeit abgespeichert, wenn nicht wird das nächste stück eingelesen usw.
Hier der zugehörige Code:

Code:

function [Timecut]=batch()

filename=uigetfile('hier steht ein pfad*.bin');


% Input UI for cutting variables thresh, dt, tint, tbis (for further explanation see help of variables)
[cuttingvariables] = inputdlg({'set threshhold (for threshmax=maxnoise+thresh:', 'set starting time tstart:','set time interval tint','set end time tbis'},...
    'Input of Time Values for read out starting time of samples', [1 75;1 75; 1 75; 1 75]);

% get variables from cuttingvariables array and change to double
thresh =cuttingvariables(1,1);
thresh =str2double(thresh{1});
tstart =cuttingvariables(2,1);
tstart=str2double(tstart{1});
tint=cuttingvariables(3,1);
tint=str2double(tint{1});
tbis =cuttingvariables(4,1);
tbis =str2double(tbis{1});

% set vars
samplingRate = 2e6;
i=1;
j=1;
othresh=false;      % test if max of sound intervall is over thresh+maxnoise
Timecut=zeros(1100,2);
dt=tstart;

% calc max. noise
fileIDbin=fopen(filename);
noisestart=(0.1*samplingRate*4);
fseek(fileIDbin, noisestart, -1);
dtnoise=1*samplingRate;
noise=fread(fileIDbin,dtnoise ,'int32');
fclose(fileIDbin);
maxnoise=max(noise);
threshmax=maxnoise+thresh;

% calculate time variables (not needed)
tinc= 1/samplingRate;                                                   % Time increment
tsteps=[0:tinc:(tint-tinc)];                                            % Array of 0:T in timesteps of samplingrate

% open file
fileIDbin=fopen(filename);

% create Batch
while dt < tbis
    flagtime=dt*samplingRate*4; % set time for fseek to set flag
    fseek(fileIDbin, flagtime, -1); % set flag, start from 0-position
    dtsound=tint*samplingRate; % dtsound to avoid calculation in brackets sound...
    sound=fread(fileIDbin,dtsound ,'int32'); % read sound from flag (fseek) to flag+tinc
    smax=max(sound);
   
    if smax > threshmax && othresh == false
       
        othresh = true;
       
        Timecut(i,1)= (dt-tint-tstart)*samplingRate;
        i=i+1;
       
    end
   
    if smax < threshmax && othresh == true
       
        othresh = false;
        Timecut(j,2)= (dt-tstart)*samplingRate;
        j=j+1;
       
    end
   
    % set new dt
    dt=dt+tint;
   
% show (no need)
    disp(i)
    disp(j)
    disp(smax)
    disp(dt)
 
end

% close file
fclose(fileIDbin);

% write xls file
excel='Zeiten.xlsx';
xlswrite(excel,Timecut);
save('filename')

end
 


Grundsätzlich funktioniert das auch ungefähr so, wie ich mir das vorstelle. Leider gibt es aber immer mal wieder Probleme. Manchmal wird die Zeit des Signals nicht richtig erkannt, schint wohl an meinem Kriterium des "Maxwertvergleichs" zu liegen.

Meine Frage ist daher, ob jemand eine bessere Möglichkeit kennt, um die Funktion "robuster" zu machen. Ich bin mir bewusst, dass es nicht die ideale Lösung ist, die Werte anhand des Maximalwertes von Rauschen und Signal zu ermitteln, aber mir fällt leider momentan nix besseres ein.

Beste Grüße
Bastian
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



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.