From 1b951faae02d0ea595a6e1f37f4a180294576239 Mon Sep 17 00:00:00 2001
From: Marek Blok <Marek.Blok@pg.edu.pl>
Date: Tue, 29 Jun 2021 13:06:58 +0200
Subject: [PATCH] Added Ex4

---
 .gitignore                          |   11 +
 Ex4/.vscode/c_cpp_properties.json   |   65 ++
 Ex4/.vscode/launch.json             |   29 +
 Ex4/.vscode/tasks.json              |   33 +
 Ex4/Ex4_task2.cbp                   |   38 +
 Ex4/Ex4_task2.cpp                   |  128 +++
 Ex4/Makefile                        |   85 ++
 Ex4/Makefile.main                   |   60 ++
 Ex4/matlab/FSDfilter.m              |  142 +++
 Ex4/matlab/SPECgraf.m               | 1436 +++++++++++++++++++++++++++
 Ex4/matlab/ex4_task1.m              |   44 +
 Ex4/matlab/ex4_task1_test.m         |   39 +
 Ex4/matlab/ex4_task2_h_FSD_all.coef |  Bin 0 -> 280 bytes
 Ex4/matlab/getFSD_new.m             |  468 +++++++++
 Ex4/matlab/readaudiofile.m          |  215 ++++
 Ex4/matlab/save_filter_coef.m       |  226 +++++
 Ex4/matlab/test1_11025.wav          |  Bin 0 -> 22094 bytes
 Ex4/matlab/test2_11025.wav          |  Bin 0 -> 22094 bytes
 Ex4/matlab/test_signal.wav          |  Bin 0 -> 16044 bytes
 Ex4/rundot.bat                      |    4 +
 20 files changed, 3023 insertions(+)
 create mode 100644 Ex4/.vscode/c_cpp_properties.json
 create mode 100644 Ex4/.vscode/launch.json
 create mode 100644 Ex4/.vscode/tasks.json
 create mode 100644 Ex4/Ex4_task2.cbp
 create mode 100644 Ex4/Ex4_task2.cpp
 create mode 100644 Ex4/Makefile
 create mode 100644 Ex4/Makefile.main
 create mode 100644 Ex4/matlab/FSDfilter.m
 create mode 100644 Ex4/matlab/SPECgraf.m
 create mode 100644 Ex4/matlab/ex4_task1.m
 create mode 100644 Ex4/matlab/ex4_task1_test.m
 create mode 100644 Ex4/matlab/ex4_task2_h_FSD_all.coef
 create mode 100644 Ex4/matlab/getFSD_new.m
 create mode 100644 Ex4/matlab/readaudiofile.m
 create mode 100644 Ex4/matlab/save_filter_coef.m
 create mode 100644 Ex4/matlab/test1_11025.wav
 create mode 100644 Ex4/matlab/test2_11025.wav
 create mode 100644 Ex4/matlab/test_signal.wav
 create mode 100644 Ex4/rundot.bat

diff --git a/.gitignore b/.gitignore
index 869ff7b..5187057 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,14 @@ Ex3/ex3_task3a.flt
 Ex3/ex3_task3b.flt
 Ex3/ex3_task3b.wav
 Ex3/log_file.txt
+
+Ex3-solution
+
+Ex4/out_win_dbg
+Ex4/out_win_rls
+Ex4/out_linux_dbg
+Ex4/out_linux_rls
+
+Ex4/Ex4_task2_dbg.exe
+Ex4/Ex4_task2.dot
+Ex4/log_file.txt
diff --git a/Ex4/.vscode/c_cpp_properties.json b/Ex4/.vscode/c_cpp_properties.json
new file mode 100644
index 0000000..11c576f
--- /dev/null
+++ b/Ex4/.vscode/c_cpp_properties.json
@@ -0,0 +1,65 @@
+{
+    "configurations": [
+        {
+            "name": "Windows-Release",
+            "includePath": [
+                "${workspaceFolder}/**",
+                "${workspaceFolder}/../DSPE_lib_minGW/MinGW-W64_8.1.0/include/**"
+            ],
+            "defines": [
+                "WIN32",
+                "__DEBUG__=0"
+            ],
+            //"compilerPath": "gcc.exe",
+            "cStandard": "c11",
+            "cppStandard": "c++11",
+            "intelliSenseMode": "gcc-x64"
+        },
+        {
+            "name": "Linux-Release",
+            "includePath": [
+                "${workspaceFolder}/**",
+                "${workspaceFolder}/../DSPE_lib_minGW/MinGW-W64_8.1.0/include/**"
+            ],
+            "defines": [
+                "WIN32",
+                "__DEBUG__=0"
+            ],
+            "compilerPath": "gcc.exe",
+            "cStandard": "c11",
+            "cppStandard": "c++11",
+            "intelliSenseMode": "gcc-x64"
+        },
+        {
+            "name": "Windows-Debug",
+            "includePath": [
+                "${workspaceFolder}/**",
+                "${workspaceFolder}/../DSPE_lib_minGW/MinGW-W64_8.1.0/include/**"
+            ],
+            "defines": [
+                "WIN32",
+                "__DEBUG__=1"
+            ],
+            //"compilerPath": "gcc.exe",
+            "cStandard": "c11",
+            "cppStandard": "c++11",
+            "intelliSenseMode": "gcc-x64"
+        },
+        {
+            "name": "Linux-Debug",
+            "includePath": [
+                "${workspaceFolder}/**",
+                "${workspaceFolder}/../DSPE_lib_minGW/MinGW-W64_8.1.0/include/**"
+            ],
+            "defines": [
+                "WIN32",
+                "__DEBUG__=1"
+            ],
+            "compilerPath": "gcc.exe",
+            "cStandard": "c11",
+            "cppStandard": "c++11",
+            "intelliSenseMode": "gcc-x64"
+        }
+],
+    "version": 4
+}
\ No newline at end of file
diff --git a/Ex4/.vscode/launch.json b/Ex4/.vscode/launch.json
new file mode 100644
index 0000000..1a11b37
--- /dev/null
+++ b/Ex4/.vscode/launch.json
@@ -0,0 +1,29 @@
+{
+    // Use IntelliSense to learn about possible attributes.
+    // Hover to view descriptions of existing attributes.
+    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "(gdb) Ex3 — widnows debug run ",
+            "type": "cppdbg",
+            "request": "launch",
+            "program": "${workspaceFolder}/Ex4_task2_dbg.exe",
+            "args": [],
+            "stopAtEntry": false,
+            "cwd": "${workspaceFolder}",
+            "environment": [],
+            "externalConsole": false,
+            "MIMode": "gdb",
+//            "miDebuggerPath": "d:/CodeBlocks_20_03/MinGW/bin/gdb.exe",
+            "setupCommands": [
+                {
+                    "description": "Włącz formatowanie kodu dla gdb",
+                    "text": "-enable-pretty-printing",
+                    "ignoreFailures": true
+                }
+            ],
+            "preLaunchTask": "Build Ex4_task2.cpp"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/Ex4/.vscode/tasks.json b/Ex4/.vscode/tasks.json
new file mode 100644
index 0000000..90f99ae
--- /dev/null
+++ b/Ex4/.vscode/tasks.json
@@ -0,0 +1,33 @@
+{
+    // See https://go.microsoft.com/fwlink/?LinkId=733558
+    // for the documentation about the tasks.json format
+    "version": "2.0.0",
+    // https://code.visualstudio.com/docs/editor/tasks
+    // ${command:cpptools.activeConfigName}
+    "tasks": [
+        {
+            "label": "Build Ex4_task2.cpp",
+            "type": "shell",
+            "command": "make build -f Makefile.main FILE=Ex4_task2 VS_CFG=${command:cpptools.activeConfigName}",
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            },
+            "presentation": {
+                "echo": true
+            },
+            "problemMatcher": "$gcc"
+        },
+        {
+            "label": "Clean Ex4_task2.cpp",
+            "type": "shell",
+            "command": "make clean -f Makefile.main VS_CFG=${command:cpptools.activeConfigName}",
+            "group": "build",
+            "presentation": {
+                "echo": true
+            },
+            "problemMatcher": "$gcc"
+        }
+
+   ]
+}
\ No newline at end of file
diff --git a/Ex4/Ex4_task2.cbp b/Ex4/Ex4_task2.cbp
new file mode 100644
index 0000000..2ee317b
--- /dev/null
+++ b/Ex4/Ex4_task2.cbp
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+	<FileVersion major="1" minor="6" />
+	<Project>
+		<Option title="Ex4_task2" />
+		<Option pch_mode="2" />
+		<Option compiler="gcc" />
+		<Build>
+			<Target title="default">
+				<Option output="Ex4_task2" prefix_auto="1" extension_auto="1" />
+				<Option type="1" />
+				<Option compiler="gcc" />
+			</Target>
+		</Build>
+		<Compiler>
+			<Add option="-std=c++0x" />
+			<Add option="-m32" />
+			<Add option="-g" />
+			<Add option="-DWIN32" />
+			<Add directory="../DSPE_lib_minGW/MinGW-W64_8.1.0/include" />
+			<Add directory="../DSPE_lib_minGW/MinGW-W64_8.1.0/include/dbg" />
+		</Compiler>
+		<Linker>
+			<Add option="-static-libgcc" />
+			<Add option="-m32" />
+			<Add library="DSPE" />
+			<Add library="winmm" />
+			<Add directory="../DSPE_lib_minGW/MinGW-W64_8.1.0/dbg" />
+		</Linker>
+		<Unit filename="Ex4_task2.cpp" />
+		<Extensions>
+			<code_completion />
+			<envvars />
+			<debugger />
+			<lib_finder disable_auto="1" />
+		</Extensions>
+	</Project>
+</CodeBlocks_project_file>
diff --git a/Ex4/Ex4_task2.cpp b/Ex4/Ex4_task2.cpp
new file mode 100644
index 0000000..d47708a
--- /dev/null
+++ b/Ex4/Ex4_task2.cpp
@@ -0,0 +1,128 @@
+/*! Laboratory: Advanced signal processing of digital telecommunications
+ * (Zaawansowane przetwarzanie sygnałów telekomunikacji cyfrowej)
+ *  Ex. 4. task 2.
+ *    Sampling rate conversion with fractional delay filters
+ *
+ * \author Marek Blok
+ * \date 2021.06.29
+ */
+#include <DSP_lib.h>
+
+int main(int argn, char *args[])
+{
+  /*************************************************************/
+  // Log file setup
+  DSP::log.SetLogFileName("log_file.txt");
+  DSP::log.SetLogState(DSP::e::LogState::file | DSP::e::LogState::console);
+
+  DSP::log << DSP::lib_version_string() << endl << endl;
+  /*************************************************************/
+
+/*
+ Idea:
+ - set of filters is read from a file - L filters designed in MATLAB
+ - tests with bandlimited or fullband signals - chirps + spectrograph
+
+ 1. Load table of impulse responses of FSD filters
+
+ 2. Input -> output buffer with callback
+
+ DSP::u::OutputBuffer (unsigned int BufferSize_in, unsigned int NoOfInputs_in, DSPe_buffer_type cyclic, DSP_clock_ptr ParentClock, DSP_clock_ptr NotificationsClock, unsigned int NoOfOutputs_in, DSP::u::buffer_callback_ptr func_ptr, unsigned int CallbackIdentifier=0)
+   If NoOfOutputs_in > 0 NotificationsClock has also the meaning of OutputClock.
+
+ 3. Synchronous clocks >> although itmight be better if the asynchronous clocks were used
+
+*/
+
+
+  DSP::LoadCoef coef_info;
+  long int Fp1, Fp2;
+  unsigned int L, M;
+  unsigned int N_all;
+  DSP::Float_vector h_all;
+
+  if (coef_info.Open("ex4_task2_h_FSD_all.coef", "matlab") == false)
+  {
+  	return -1;
+  }
+  Fp1 = coef_info.Fp;
+
+  // verify L and calculate M
+  DSP::Float_vector tmp;
+  coef_info.Load(tmp, 1);
+  L = (unsigned int)tmp[0]; M = (unsigned int)tmp[1];
+  Fp2 = (Fp1*L)/M;
+
+  // **********************************
+  N_all = coef_info.GetSize(0);
+  coef_info.Load(h_all, 0);
+
+  /*************************************************************/
+
+  DSP::Clock_ptr InputClock;
+  InputClock=DSP::Clock::CreateMasterClock();
+
+
+  DSP::u::FileInput InputSignal(InputClock, "matlab/test_signal.wav", 1U, DSP::e::SampleType::ST_short, DSP::e::FileType::FT_wav);
+  int Fp1_tmp = InputSignal.GetSamplingRate();
+  if (Fp1_tmp != Fp1)
+  {
+    DSP::log << DSP::e::LogMode::Error 
+      << "Sampling rate of the input signal is different from sampling rate from fitler coefficients file (ex4_task2_h_FSD_all.coef)" << endl;
+  }
+
+  DSP::u::SamplingRateConversion FSDresampler(InputClock, L, M, h_all);
+
+  DSP::u::AudioOutput SoundOut(Fp2, 1, 16);
+  DSP::u::FileOutput FileOut_a("ex4_task2.wav", DSP::e::SampleType::ST_short, 1, DSP::e::FileType::FT_wav, Fp2);
+  DSP::u::FileOutput FileOut_b("ex4_task2.flt", DSP::e::SampleType::ST_short, 1, DSP::e::FileType::FT_flt, Fp2);
+
+  DSP::log << "Fp1 = " << Fp1 << ", Fp2 = " << Fp2 << ", L = " << L << ", M = " << M << endl;
+
+  /*************************************************************/
+  // Connections definitions
+  InputSignal.Output("out") >> FSDresampler.Input("in");
+  FSDresampler.Output("out") >> SoundOut.Input("in");
+  FSDresampler.Output("out") >> FileOut_a.Input("in");
+  FSDresampler.Output("out") >> FileOut_b.Input("in");
+
+
+  /////////////////////////////////
+  // check if there are signals
+  // connected to all inputs
+  DSP::Component::CheckInputsOfAllComponents();
+
+  // *********************************** //
+  DSP::Clock::SchemeToDOTfile(InputClock, "Ex4_task2.dot");
+
+  // *********************************** //
+  int SamplesInSegment = 512;
+  __int64 NoOfSamplesProcessed = 0;
+  // 10 seconds
+  #define MAX_SAMPLES_TO_PROCESS 10*Fp1
+  while(NoOfSamplesProcessed < MAX_SAMPLES_TO_PROCESS)
+  {
+
+    // ********************************************************** //
+    DSP::Clock::Execute(InputClock, SamplesInSegment);
+    // ********************************************************** //
+
+    if (InputSignal.GetBytesRead() > 0)
+    {
+        NoOfSamplesProcessed = 0; // Play the whole file
+    }
+    else // Play 200ms more
+    {
+      if (NoOfSamplesProcessed < MAX_SAMPLES_TO_PROCESS - Fp1/5)
+          NoOfSamplesProcessed = MAX_SAMPLES_TO_PROCESS - Fp1/5;
+    }
+
+    NoOfSamplesProcessed += SamplesInSegment;
+    // ********************************************************** //
+  }
+
+  /*************************************************************/
+  DSP::Clock::FreeClocks();
+
+  return 0;
+}
diff --git a/Ex4/Makefile b/Ex4/Makefile
new file mode 100644
index 0000000..c94c79f
--- /dev/null
+++ b/Ex4/Makefile
@@ -0,0 +1,85 @@
+# Run: make Release 
+# Run: make Debug 
+CC=g++
+# comflag = -m32
+# comflag = -m64
+comflag = $(COMFLAG)
+
+DSPElib_DIR = ../../_DSPE_lib_minGW_/$(DSPElib_SUBDIR)
+
+SRC_DIR = .
+SRC_CPP_SUBDIR = .
+
+#DFLAGS         = -DWIN32 -DDEVCPP 
+
+# -D INCLUDE_DSPE_EXAMPLES # TODO: uĹźycie w ramach kompilacji Main.cpp w trybie DEBUG
+ifeq ($(MODE),Release)
+	CFLAGS = $(comflag) -std=c++0x -O3 -Wall -c -fmessage-length=0 -fno-strict-aliasing 
+	LINKER_FLAGS = $(comflag)  -s -static-libgcc -static-libstdc++ $(MISC_LINKER_FLAGS)
+	INCLUDES := -I"$(DSPElib_DIR)/include" -I"$(DSPElib_DIR)/include/rls"
+	DSPElib_FULLDIR = $(DSPElib_DIR)/rls
+	EXE_FILENAME = $(CPP_FILENAME)_rls.exe
+else
+	CFLAGS   = $(comflag) -std=c++0x -O0 -g3 -Wall -c -fmessage-length=0 -W -Wshadow -Wconversion -fstrict-aliasing -fmax-errors=5
+	LINKER_FLAGS   = $(comflag)  -static-libgcc -static-libstdc++ $(MISC_LINKER_FLAGS)
+	INCLUDES := -I"$(DSPElib_DIR)/include" -I"$(DSPElib_DIR)/include/dbg"
+	DSPElib_FULLDIR = $(DSPElib_DIR)/dbg
+	EXE_FILENAME = $(CPP_FILENAME)_dbg.exe
+endif
+# -U__STRICT_ANSI__ jest potrzebne do kompilacji debug_new.cpp, jezeli pominac ten plik to mozna rowniez wyrzucic te opcje
+#CFLAGS_debug   = $(comflag) -std=c++0x -O0 -g3 -Wall -c -fmessage-length=0 -W -Wshadow -Wco#nversion -fstrict-aliasing -U__STRICT_ANSI__
+
+SOURCES_NAMES = 
+SOURCES_NAMES += $(CPP_FILENAME).cpp 
+SOURCES = $(addprefix $(SRC_CPP_SUBDIR)/,$(SOURCES_NAMES))
+
+SOURCES_DBG =
+# SOURCES_DBG += $(SRC_DIR)/Main.cpp
+
+# ################################################# #
+# DEBUG
+OBJECTS 		  := $(SOURCES:%.cpp=$(OUT_DIR)/%.o)
+DEPENDS 		  := $(SOURCES:%.cpp=$(OUT_DIR)/%.d)
+
+# ################################################# #
+-include $(DEPENDS)
+
+all: build
+
+
+# ########################################################################################### #	
+# ########################################################################################### #	
+build: $(SRC_DIR)/$(EXE_FILENAME)
+
+$(SRC_DIR)/$(EXE_FILENAME): $(OBJECTS)
+	@echo $(EXE_FILENAME)
+	$(CC) -L$(DSPElib_FULLDIR) $(OBJECTS) -o"$(SRC_DIR)/$(EXE_FILENAME)" $(LINKER_FLAGS) -lDSPE $(LIBS)
+
+# ########################################################################################### #	
+# ########################################################################################### #	
+# Z podanej listy usuwany $(OUT_DIR_WIN_RLS)/ oraz '.o' zamieniamy na '.cpp'
+$(OBJECTS): $(OUT_DIR)/%.o : %.cpp
+	@echo $(@D) $< $@
+
+	#mkdir -p $(OUT_DIR)/$(SRC_CPP_SUBDIR)
+	mkdir -p $(@D)
+	$(CC) $(DFLAGS) $(CFLAGS) $(INCLUDES) -MMD $< -o $@
+
+
+clean:
+	@echo MODE: $(MODE)
+
+	@if [ -d "$(OUT_DIR)" ]; then \
+		echo "cleaning $(OUT_DIR_DBG) ..."; \
+		#find $(OUT_DIR)/ -name "*.o" -type f -delete; \
+		rm -rf $(OUT_DIR)/*.d; \
+		rm -rf $(OUT_DIR)/*.o; \
+		rm -rf $(OUT_DIR); \
+		echo "cleaned $(OUT_DIR)"; \
+	fi 
+	rm -rf "$(SRC_DIR)/$(EXE_FILENAME)"; \
+	#rm -rf "$(SRC_DIR)/*.gif"; \
+	#rm -rf "$(SRC_DIR)/*.dot"; \
+	
+.PHONY: all build clean
+
diff --git a/Ex4/Makefile.main b/Ex4/Makefile.main
new file mode 100644
index 0000000..cf6c368
--- /dev/null
+++ b/Ex4/Makefile.main
@@ -0,0 +1,60 @@
+# (View > Command Palette) => "Convert Indentation to Tabs"
+
+ifeq ($(VS_CFG),Windows-Debug)
+	MAKEFILE = "Makefile"
+	MODE = Debug
+	COMFLAG = -m64
+	
+	OUT_DIR = ./out_win_dbg
+	DSPElib_SUBDIR = MinGW-W64_8.1.0
+	MISC_LINKER_FLAGS = -static
+	LIBS = -lwinmm -lws2_32
+	DFLAGS = -DWIN32 -DDEVCPP 
+endif
+ifeq ($(VS_CFG),Windows-Release)
+	MAKEFILE = "Makefile"
+	MODE = Release
+	COMFLAG = -m64
+	
+	OUT_DIR = ./out_win_rls
+	DSPElib_SUBDIR = MinGW-W64_8.1.0
+	MISC_LINKER_FLAGS = -static
+	LIBS = -lwinmm -lws2_32
+	DFLAGS = -DWIN32 -DDEVCPP
+endif
+ifeq ($(VS_CFG),Linux-Debug)
+	MAKEFILE = "Makefile"
+	MODE = Debug
+	COMFLAG = 
+	
+	OUT_DIR = ./out_linux_dbg
+	DSPElib_SUBDIR = $(shell gcc -dumpmachine)-gcc_$(shell gcc -dumpversion)
+	MISC_LINKER_FLAGS = 
+	LIBS := -lasound
+	DFLAGS = 
+endif
+ifeq ($(VS_CFG),Linux-Release)
+	MAKEFILE = "Makefile"
+	MODE = Release
+	COMFLAG = 
+	
+	OUT_DIR = ./out_linux_rls
+	DSPElib_SUBDIR = $(shell gcc -dumpmachine)-gcc_$(shell gcc -dumpversion)
+	MISC_LINKER_FLAGS = 
+	LIBS := -lasound
+	DFLAGS = 
+endif
+
+
+
+build: 
+	@echo "Building $(VS_CFG)"
+	@echo $(VS_CFG): $(MODE) // $(MAKEFILE)
+	make build CPP_FILENAME=$(FILE) MODE=$(MODE) COMFLAG=$(COMFLAG) DFLAGS="$(DFLAGS)" LIBS="$(LIBS)" OUT_DIR=$(OUT_DIR) DSPElib_SUBDIR=$(DSPElib_SUBDIR) MISC_LINKER_FLAGS="$(MISC_LINKER_FLAGS)" -f $(MAKEFILE)
+
+clean: 
+	@echo "Cleaning $(VS_CFG)"
+	@echo $(VS_CFG): $(MODE) // $(MAKEFILE)
+	make clean MODE=$(MODE) OUT_DIR=$(OUT_DIR) -f $(MAKEFILE)
+
+
diff --git a/Ex4/matlab/FSDfilter.m b/Ex4/matlab/FSDfilter.m
new file mode 100644
index 0000000..7b941ff
--- /dev/null
+++ b/Ex4/matlab/FSDfilter.m
@@ -0,0 +1,142 @@
+function [h, PE_FSD] = FSDfilter(method, N, delay, voff_typ)
+% delay - total filter delay
+
+switch method
+  case 'LSE'
+    h=LSE(N,delay);
+  case 'LSE2'
+    h=LSE(N,delay,voff_typ);
+  case 'Lagr'
+    h=Lagr(N,delay);
+  case 'window'
+    h=window(N,delay,voff_typ);
+  case 'chebwin'
+    h=window(N,delay,3,voff_typ);
+  case 'offset'
+    h=offset(N,delay,voff_typ);
+  case 'optimal'
+    eval('h=getFSD(N,voff_typ,delay-(N-1)/2);','h=NaN;');
+    
+    if isnan(h)
+      Krok=0;
+      Factor=4;
+      
+      while isnan(h)
+        Krok=Krok+1;
+        krok=Krok; voff=voff_typ;
+        while krok
+          voff=voff+(1/2-voff)/Factor;
+          krok=krok-1;
+        end;
+        eval('[h, PE_FSD, ekst]=getFSD(N,voff,delay-(N-1)/2);','h=NaN;');
+        h=h.';
+      end;
+      
+      while Krok>=0
+        krok=Krok; voff=voff_typ;
+        while krok
+          voff=voff+(1/2-voff)/Factor;
+          krok=krok-1;
+        end;
+        ekst=ekst/ekst(end)*voff;
+        [h, PE_FSD, ekst]=getFSD(N,voff,delay-(N-1)/2, ekst);
+        h=h.';
+        Krok=Krok-1;
+      end;
+    end;
+    
+  case 'optimal2'
+    % rasterless implementation
+    [h, PE_FSD] =getFSD_new(N,voff_typ,delay-(N-1)/2);
+%     eval('h=getFSD_new(N,voff_typ,delay-(N-1)/2);','h=NaN;');
+    
+    if isnan(h)
+      Krok=0;
+      Factor=4;
+      
+      while isnan(h)
+        Krok=Krok+1;
+        krok=Krok; voff=voff_typ;
+        while krok
+          voff=voff+(1/2-voff)/Factor;
+          krok=krok-1;
+        end;
+        eval('[h, PE_FSD, ekst]=getFSD_new(N,voff,delay-(N-1)/2);','h=NaN;');
+        h=h.';
+      end;
+      
+      while Krok>=0
+        krok=Krok; voff=voff_typ;
+        while krok
+          voff=voff+(1/2-voff)/Factor;
+          krok=krok-1;
+        end;
+        ekst=ekst/ekst(end)*voff;
+        [h, PE_FSD, ekst]=getFSD_new(N,voff,delay-(N-1)/2, ekst);
+        h=h.';
+        Krok=Krok-1;
+      end;
+    end;
+end;
+
+function h=Lagr(N,delay)
+
+for n=0:N-1
+  m=0:N-1;
+  m(n+1)=[];
+  h(n+1)=prod((delay-m)./(n-m));
+end;
+
+function h=LSE(N,delay, voff)
+
+n=0:N-1;
+if nargin ==2,
+  h=sinc(n-delay);
+elseif nargin==3
+  alfa=2*voff;
+  for k=0:N-1
+    l=0:N-1;
+    P(k+1,l+1)=alfa*sinc(alfa*(k-l));
+    p(k+1,1)=alfa*sinc(alfa*(k-delay));
+  end;
+  h=inv(P)*p;
+  h = h(:).';
+end;
+
+function h=window(N,delay,typ, Rp)
+n=0:N-1;
+hsinc=sinc(n-delay);
+
+if typ==3
+  wsym=chebwin(N,Rp).';
+else
+  switch typ
+    case 2
+      C=[0.43 -0.5  0.08]; %Blackman
+    case 1
+      C=[0.54 -0.46 0]; %Hamming
+    case 0
+      C=[0.5  -0.5  0]; %Hann
+  end;
+  wsym=C(1)+C(2)*cos(2*pi*n/(N-1))+C(3)*cos(4*pi*n/(N-1));
+end;
+
+h=hsinc.*wsym;
+
+function h=offset(N,delay,typ)
+n=0:N-1;
+hsinc=sinc(n-delay);
+switch typ
+  case 2
+    C=[0.43 -0.5  0.08]; %Blackman
+  case 1
+    C=[0.54 -0.46 0]; %Hamming
+  case 0
+    C=[0.5  -0.5  0]; %Hann
+end;
+
+epsilon=delay-(N-1)/2;
+%wsym=C(1)+C(2)*cos(2*pi*n/(N-1))+C(3)*cos(4*pi*n/(N-1));
+woffset=C(1)+C(2)*cos(2*pi*(n-epsilon)/(N-1))+C(3)*cos(4*pi*(n-epsilon)/(N-1));
+h=hsinc.*woffset;
+
diff --git a/Ex4/matlab/SPECgraf.m b/Ex4/matlab/SPECgraf.m
new file mode 100644
index 0000000..d892ec7
--- /dev/null
+++ b/Ex4/matlab/SPECgraf.m
@@ -0,0 +1,1436 @@
+function varargout = SPECgraf(Akcja, param)
+%cos(cumsum(n/1000))
+
+% \fixed 2017.03.22 psd ==> pwelch
+% \fixed 2012.03.05 finite ==> isfinite
+% \fixed 2006.10.11 dealt with LineStyle/Marker warning
+% \fixed 2005.11.20 dealt with "Warning: Log of zero." in ylim evaluation
+% \fixed 2005.11.20 Placed all in single file
+% \fixed 2005.11.20 Fixed problems with zoom out
+
+if nargin == 0  % LAUNCH GUI
+
+% 	fig = openfig(mfilename,'reuse'); return; %ZapiszFig(1,'specGUI.m')
+  if isempty(findobj(0, 'tag', 'Specgraf_DrawFig')) 
+    
+    fig = Specgraf_DrawFig;
+    set(fig,'tag', 'Specgraf_DrawFig', 'Units', 'pixels');
+    set(fig,'name', 'Spektrogram sygnałów niestacjonarnych (2017.03.22) dr inż. Marek Blok)',...
+      'KeyPressFcn','1;');
+    
+    SPECgraf('Init');
+    SPECgraf('signal');
+    set(fig,'Visible','on');
+%    SPECgraf('per');
+  else
+    SPECgraf('Exit');
+  end
+  return;
+end;
+
+if ~isstr(Akcja) % INVOKE NAMED SUBFUNCTION OR CALLBACK
+  disp('Something''s wrong');
+  return;
+end;
+
+% Generate a structure of handles to pass to callbacks, and store it. 
+fig=findobj(0, 'tag', 'Specgraf_DrawFig');
+hEditN=findobj(fig,'tag', 'N_edit');
+hEditM=findobj(fig,'tag', 'M_edit');
+hEditL=findobj(fig,'tag', 'L_edit');
+hEditK=findobj(fig,'tag', 'K_edit');
+hEditO=findobj(fig,'tag', 'O_edit');
+hEditW=findobj(fig,'tag', 'w_edit');
+hEditX=findobj(fig,'tag', 'x_edit');
+h_real=findobj(fig,'tag', 'real_checkbox');
+h_dB=findobj(fig,'tag', 'dB_checkbox');
+hEditNoise=findobj(fig,'tag', 'Noise_edit');
+hEditName=findobj(fig,'tag', 'Name_edit');
+hMenu=findobj(fig,'tag', 'choose_popupmenu');
+h_det=findobj(fig,'tag', 'detrend_checkbox');
+ha=get(fig, 'UserData');
+Ktory=get(hMenu,'Value');  
+hEdit_dY=findobj(fig,'tag', 'dY_edit');
+
+if strcmp(Akcja, 'Exit')
+  close(fig);
+  return;
+elseif strcmp(Akcja, 'Init')
+  set(hEditX,'UserData','randn(1,L)');
+  set(hEditX,'String','randn(1,L)');
+  set(hEditX,'Max', 2);
+
+  set(hEditW,'UserData','boxcar(M)');
+  set(hEditW,'String','boxcar(M)');
+
+  set(hEditL,'UserData','1000');
+  set(hEditL,'String','1000');
+  set(hEditM,'UserData','100');
+  set(hEditM,'String','100');
+  set(hEditNoise,'UserData','-100');
+  set(hEditNoise,'String','-100');
+  
+%  set(hEditN,'UserData','1');
+%  set(hEditN,'String','1');
+  set(hEditO,'UserData','0');
+  set(hEditO,'String','0');
+
+  set(hEditK,'UserData','256');
+  set(hEditK,'String','256');
+
+  set(hEditName,'String','new');
+  set(hMenu,'String','new');
+
+  set(h_real,'UserData',1);
+  set(h_real,'Value',1);
+
+  set(h_dB,'UserData',0);
+  set(h_dB,'Value',0);
+  
+  set(h_det,'UserData',1);
+  set(h_det,'Value',1);
+  
+  ha(1)=findobj(fig,'tag', 'Signal_re_axes');
+  ha(2)=findobj(fig,'tag', 'Signal_im_axes');
+  ha(3)=findobj(fig,'tag', 'spec_axes');
+  ha(4)=findobj(fig,'tag', 'per_axes');
+%  for ind=[1 2 4], axes(ha(ind)); zoom on; end;
+%  axes(ha(3)); zoom off;
+  
+  set(fig, 'UserData', ha);
+
+  set(hMenu,'UserData', [NaN, NaN, NaN, NaN, NaN, NaN, NaN, 1, -100, 5, -100, 5]); %handles & maximal values
+  set(hEdit_dY,'String','120');
+  return;
+elseif strcmp(Akcja, 'change_name')
+  pom=get(hMenu,'String');
+  pom2=get(hEditName,'String');
+  pom(Ktory,1:length(pom2)+1)=[pom2 0];
+  set(hMenu,'String',pom);
+  set(hMenu, 'Value', Ktory);
+  return;  
+elseif strcmp(Akcja, 'new')
+  pom=get(hMenu,'String');
+  Ktory=size(pom,1)+1;
+  pom(Ktory,1:4)=['new' 0];
+  set(hMenu,'String',pom);
+  
+  
+  pom=get(hEditX,'UserData');
+  pom(Ktory,1:11)=['randn(1,L)' 0];
+  set(hEditX,'UserData',pom);
+  pom=get(hEditW,'UserData');
+  pom(Ktory,1:10)=['boxcar(M)' 0];
+  set(hEditW,'UserData',pom);
+
+  pom=get(hEditL,'UserData');
+  pom(Ktory,1:4)=['100' 0];
+  set(hEditL,'UserData',pom);
+  pom=get(hEditM,'UserData');
+  pom(Ktory,1:4)=['100' 0];
+  set(hEditM,'UserData',pom);
+  pom=get(hEditNoise,'UserData');
+  pom(Ktory,1:5)=['-100' 0];
+  set(hEditNoise,'UserData',pom);
+  
+%  pom=get(hEditN,'UserData');
+%  pom(Ktory,1:2)=['1' 0];
+%  set(hEditN,'UserData',pom);
+  pom=get(hEditO,'UserData');
+  pom(Ktory,1:2)=['0' 0];
+  set(hEditO,'UserData',pom);
+
+  pom=get(hEditK,'UserData');
+  pom(Ktory,1:5)=['256' 0];
+  set(hEditK,'UserData',pom);
+
+  pom=get(hMenu,'UserData');
+  pom(Ktory,1:size(pom,2))=ones(1,size(pom,2))*NaN;
+  set(hMenu,'UserData',pom);
+
+  pom=get(h_real,'UserData');
+  pom(Ktory,1)=1;
+  set(h_real,'Value', pom(Ktory,1));
+  set(h_real,'UserData',pom);
+
+  pom=get(h_det,'UserData');
+  pom(Ktory,1)=1;
+  set(h_det,'Value', pom(Ktory,1));
+  set(h_det,'UserData',pom);
+
+  set(hMenu,'Value', Ktory);
+  
+  SPECgraf('Choose');
+  SPECgraf('signal', Ktory);
+  return;
+elseif strcmp(Akcja, 'delete')
+  pom=get(hMenu,'String');
+  if size(pom,1)==1,
+    %SPECgraf('Reset');
+    return;
+  end;
+  pom(Ktory,:)=[];
+  set(hMenu,'String',pom);
+
+  
+  pom=get(hEditX,'UserData');
+  pom(Ktory,:)=[];
+  set(hEditX,'UserData',pom);
+  pom=get(hEditW,'UserData');
+  pom(Ktory,:)=[];
+  set(hEditW,'UserData',pom);
+
+  pom=get(hEditL,'UserData');
+  pom(Ktory,:)=[];
+  set(hEditL,'UserData',pom);
+  pom=get(hEditM,'UserData');
+  pom(Ktory,:)=[];
+  set(hEditM,'UserData',pom);
+  pom=get(hEditNoise,'UserData');
+  pom(Ktory,:)=[];
+  set(hEditNoise,'UserData',pom);
+  
+%  pom=get(hEditN,'UserData');
+%  pom(Ktory,:)=[];
+%  set(hEditN,'UserData',pom);
+  pom=get(hEditO,'UserData');
+  pom(Ktory,:)=[];
+  set(hEditO,'UserData',pom);
+
+  pom=get(hEditK,'UserData');
+  pom(Ktory,:)=[];
+  set(hEditK,'UserData',pom);
+
+  pom=get(hMenu,'UserData');
+  for ind=1:3,
+    if isfinite(pom(Ktory,ind))
+      delete(pom(Ktory,ind));
+    end
+  end
+  pom(Ktory,:)=[];
+  set(hMenu,'UserData',pom);
+
+  pom=get(h_real,'UserData');
+  pom(Ktory,:)=[];
+  set(h_real,'UserData',pom);
+  
+  pom=get(h_det,'UserData');
+  pom(Ktory,:)=[];
+  set(h_det,'UserData',pom);
+  
+  set(hMenu,'Value', 1);
+  
+%  SPECgraf('signal', Ktory);
+  SPECgraf('Choose');
+  return;
+  
+  
+elseif strcmp(Akcja, 'Choose')
+  %selected new filter response
+  pom=get(hMenu,'String');
+  ind=find(pom(Ktory,:)==0);
+  if isempty(ind)
+    ind=size(pom,2);
+  else
+    ind=ind(1)-1;
+  end
+  set(hEditName,'String',pom(Ktory,1:ind));
+
+  pom=get(hEditX,'UserData');
+  set(hEditX, 'String', pom(Ktory,:));
+  pom=get(hEditW,'UserData');
+  set(hEditW, 'String', pom(Ktory,:));
+
+  pom=get(hEditL,'UserData');
+  set(hEditL, 'String', pom(Ktory,:));
+  pom=get(hEditM,'UserData');
+  set(hEditM, 'String', pom(Ktory,:));
+  pom=get(hEditNoise,'UserData');
+  set(hEditNoise, 'String', pom(Ktory,:));
+  
+%  pom=get(hEditN,'UserData');
+%  set(hEditN, 'String', pom(Ktory,:));
+  pom=get(hEditO,'UserData');
+  set(hEditO, 'String', pom(Ktory,:));
+
+  pom=get(hEditK,'UserData');
+  set(hEditK, 'String', pom(Ktory,:));
+
+  pom=get(h_real,'UserData');
+  set(h_real,'Value', pom(Ktory,1));
+
+  pom=get(h_det,'UserData');
+  set(h_det,'Value', pom(Ktory,1));
+
+%  SPECgraf('signal', Ktory);
+  return;
+  
+elseif strcmp(Akcja, 'signal')
+  if nargin==2,
+    Ktory=param;
+  else
+    %save strings
+    tekst=[get(hEditL, 'String') 0];
+    pom=get(hEditL,'UserData');
+    pom(Ktory,1:max([1; size(pom,2); length(tekst)]))= ...
+       zeros(1, max([1; size(pom,2); length(tekst)]));
+    pom(Ktory,1:length(tekst))=tekst;
+    set(hEditL,'UserData', setstr(pom));
+    
+    tekst=[get(hEditNoise, 'String') 0];
+    pom=get(hEditNoise,'UserData');
+    pom(Ktory,1:max([1; size(pom,2); length(tekst)]))= ...
+       zeros(1, max([1; size(pom,2); length(tekst)]));
+    pom(Ktory,1:length(tekst))=tekst;
+    set(hEditNoise,'UserData', setstr(pom));
+    
+    tekst=get(hEditX, 'String').';
+    tekst=[tekst(:); 0].';
+    pom=get(hEditX,'UserData');
+    pom(Ktory,1:max([1; size(pom,2); length(tekst)]))= ...
+       zeros(1, max([1; size(pom,2); length(tekst)]));
+    pom(Ktory,1:length(tekst))=tekst;
+    set(hEditX,'UserData', setstr(pom));
+    
+    tekst=get(h_real, 'Value');
+    pom=get(h_real,'UserData');
+    pom(Ktory,1)=tekst;
+    set(h_real,'UserData', pom);
+  end;
+
+  pom=get(hMenu,'UserData');
+  hp_re=pom(:,1);
+  hp_im=pom(:,2);
+  hp_spec_t=pom(:,3);
+  hp_spec_t2=pom(:,4);
+  hp_spec=pom(:,5);
+  hp_per=pom(:,6);
+  hp_per2=pom(:,7);
+  max_x=pom(:,8);
+  min_spec=pom(:,9);
+  max_spec=pom(:,10);
+  min_per=pom(:,11);
+  max_per=pom(:,12);
+  
+  %generate signal
+  tekstL=get(hEditL,'UserData');  tekstL=tekstL(Ktory,:);
+  ind=find(tekstL==0);
+  if ~isempty(ind)
+    tekstL=tekstL(1:ind(1)-1);
+  end;
+  eval(['L=' tekstL ';'], 'L=1;')
+
+  n=0:L-1;
+  tekstX=get(hEditX,'UserData');  tekstX=tekstX(Ktory,:);
+  ind=find(tekstX==0);
+  if ~isempty(ind)
+    tekstX=tekstX(1:ind(1)-1);
+  end;
+  eval(['x=' tekstX ';'], 'x=zeros(1,L);')
+
+  Re=get(h_real,'UserData');  Re=Re(Ktory,1);
+  
+  tekstNoise=get(hEditNoise,'UserData');  tekstNoise=tekstNoise(Ktory,:);
+  ind=find(tekstNoise==0);
+  if ~isempty(ind)
+    tekstNoise=tekstNoise(1:ind(1)-1);
+  end;
+  eval(['Noise=' tekstNoise ';'], 'Noise=-300;')
+
+  x=x(:);
+  if length(x)<L;
+    x(L)=0;
+  else
+    x=x(1:L);
+  end;
+  
+  N_lin=10.^(Noise/20);
+  if Re==1
+    x=real(x)+N_lin*randn(size(x));
+  else
+    x=x+N_lin*(randn(size(x))+j*randn(size(x)))/sqrt(2);
+  end;
+  max_x(Ktory)=max(abs([real(x); imag(x)]));
+   
+  %draw signal
+
+  %real part of the signal
+  axes(ha(1));
+  if isnan(hp_re(Ktory))
+    hold on;
+    hp_re(Ktory)=plot(n,real(x), 'Color', 'b');
+    hold off;
+  else
+    set(hp_re(Ktory),'Xdata', n, 'Ydata', real(x));
+  end
+%  set(ha(1), 'Xlim', [-0.5, L-0.5], 'Ylim', [-1.1 1.1]*max(max_x));
+%  eval('zoom reset', 'set(get(ha(1),''ZLabel''),''UserData'',[]);');    
+%  reset(get(ha(1),'ZLabel'));    
+  
+  %imaginary part of the signal
+%  axes(ha(2));
+  if isnan(hp_im(Ktory))
+    hold on;
+    hp_im(Ktory)=plot(n,imag(x), 'Color', 'r');
+    hold off;
+  else
+    set(hp_im(Ktory),'Xdata', n, 'Ydata', imag(x));
+  end
+  set(ha(1), 'Xlim', [-0.5, L-0.5], 'Ylim', [-1.1 1.1]*max(max_x));
+%  set(get(ha(2),'ZLabel'),'UserData',[]);    
+%  reset(get(ha(2),'ZLabel'));    
+%  eval('zoom reset', 'set(get(ha(1),''ZLabel''),''UserData'',[]);');    
+  if L>512
+    set([hp_re, hp_im], 'Marker', '.', 'MarkerSize', 4);
+  else
+    set([hp_re, hp_im], 'LineStyle', '-');
+  end;
+  eval('rmappdata(get(ha(1),''Zlabel''),''ZOOMAxesData'')','set(get(ha(1),''ZLabel''),''UserData'',[])');
+
+  set(hMenu,'UserData', [hp_re, hp_im,  hp_spec_t, hp_spec_t2, hp_spec, hp_per, hp_per2, max_x, min_spec, max_spec, min_per, max_per]);
+
+  %compute and draw periodogram
+  SPECgraf('spec', Ktory)
+%  SPECgraf zoom_on;
+  return;
+  
+elseif strcmp(Akcja, 'spec')
+  if nargin==2,
+    Ktory=param;
+  else
+    %save strings
+    tekst=[get(hEditK, 'String') 0];
+    pom=get(hEditK,'UserData');
+    pom(Ktory,1:max([1; size(pom,2); length(tekst)]))= ...
+       zeros(1, max([1; size(pom,2); length(tekst)]));
+    pom(Ktory,1:length(tekst))=tekst;
+    set(hEditK,'UserData', setstr(pom));
+    
+    tekst=[get(hEditM, 'String') 0];
+    pom=get(hEditM,'UserData');
+    pom(Ktory,1:max([1; size(pom,2); length(tekst)]))= ...
+       zeros(1, max([1; size(pom,2); length(tekst)]));
+    pom(Ktory,1:length(tekst))=tekst;
+    set(hEditM,'UserData', setstr(pom));
+    
+%    tekst=[get(hEditN, 'String') 0];
+%    pom=get(hEditN,'UserData');
+%    pom(Ktory,1:max([1; size(pom,2); length(tekst)]))= ...
+%       zeros(1, max([1; size(pom,2); length(tekst)]));
+%    pom(Ktory,1:length(tekst))=tekst;
+%    set(hEditN,'UserData', setstr(pom));
+    
+    tekst=[get(hEditO, 'String') 0];
+    pom=get(hEditO,'UserData');
+    pom(Ktory,1:max([1; size(pom,2); length(tekst)]))= ...
+       zeros(1, max([1; size(pom,2); length(tekst)]));
+    pom(Ktory,1:length(tekst))=tekst;
+    set(hEditO,'UserData', setstr(pom));
+    
+    tekst=[get(hEditW, 'String') 0];
+    pom=get(hEditW,'UserData');
+    pom(Ktory,1:max([1; size(pom,2); length(tekst)]))= ...
+       zeros(1, max([1; size(pom,2); length(tekst)]));
+    pom(Ktory,1:length(tekst))=tekst;
+    set(hEditW,'UserData', setstr(pom));
+    
+    tekst=get(h_det, 'Value');
+    pom=get(h_det,'UserData');
+    pom(Ktory,1)=tekst;
+    set(h_det,'UserData', pom);
+  end;
+
+  pom=get(hMenu,'UserData');
+  hp_re=pom(:,1);
+  hp_im=pom(:,2);
+  hp_spec_t=pom(:,3);
+  hp_spec_t2=pom(:,4);
+  hp_spec=pom(:,5);
+  hp_per=pom(:,6);
+  hp_per2=pom(:,7);
+  max_x=pom(:,8);
+  min_spec=pom(:,9);
+  max_spec=pom(:,10);
+  min_per=pom(:,11);
+  max_per=pom(:,12);
+  
+  %generate signal
+  tekstK=get(hEditK,'UserData');  tekstK=tekstK(Ktory,:);
+  ind=find(tekstK==0);
+  if ~isempty(ind)
+    tekstK=tekstK(1:ind(1)-1);
+  end;
+  eval(['K=' tekstK ';'], 'K=16;')
+
+  tekstM=get(hEditM,'UserData');  tekstM=tekstM(Ktory,:);
+  ind=find(tekstM==0);
+  if ~isempty(ind)
+    tekstM=tekstM(1:ind(1)-1);
+  end;
+  eval(['M=' tekstM ';'], 'M=16;')
+  if M>K
+    M=K;
+    set(hEditM,'String', num2str(M));
+  end;
+
+%  tekstN=get(hEditN,'UserData');  tekstN=tekstN(Ktory,:);
+%  ind=find(tekstN==0);
+%  if ~isempty(ind)
+%    tekstN=tekstN(1:ind(1)-1);
+%  end;
+%  eval(['N=' tekstN ';'], 'N=16;')
+
+  tekstO=get(hEditO,'UserData');  tekstO=tekstO(Ktory,:);
+  ind=find(tekstO==0);
+  if ~isempty(ind)
+    tekstO=tekstO(1:ind(1)-1);
+  end;
+%   eval(['O=' tekstO ';'], 'O=0;')
+  O=eval(tekstO, '0'); % \Fixed 2005.11.03 
+  O=round(O/100*M); % \Fixed 2005.11.03 nakładkowanie podawane w procentach !!! 
+  
+
+  tekstW=get(hEditW,'UserData');  tekstW=tekstW(Ktory,:);
+  ind=find(tekstW==0);
+  if ~isempty(ind)
+    tekstW=tekstW(1:ind(1)-1);
+  end;
+  eval(['w=' tekstW ';'], 'w=ones(1,M);')
+
+  w=w(:);
+  if length(w)<M;
+    w(M)=0;
+  else
+    w=w(1:M);
+  end;
+  
+  x=get(hp_re(Ktory), 'Ydata')+j*get(hp_im(Ktory), 'Ydata');
+
+%   O=floor(O/100*M); % \Fixed 2005.11.03
+  if O>=M
+    O=M-1;
+    set(hEditO,'String', num2str(O/M*100));
+  end;
+  N = fix((length(x)-O)/(M-O));
+  set(hEditN, 'String', sprintf('%i', N));
+
+%  det_=get(h_det,'UserData');  det_=det_(Ktory,1);
+%  if det_==0,
+%    det='none';
+%  else
+%    det_='linear';
+%  end;
+  
+  [Spec, f, t]=specgram(x, K, 1, w, O);
+  Spec=(abs(Spec).^2)/norm(w)^2;
+%   [Per, f2]=psd(x, K, 1, w, O);
+  [Per, f2]=pwelch(x, w, O, K, 1);
+  Spec=abs(Spec);
+
+  Re=get(h_real,'UserData'); 
+  if ~Re(Ktory,1)
+    f=fftshift(f);
+    f(1:floor(K/2))=f(1:floor(K/2))-1;
+    f2=fftshift(f2);
+    f2(1:floor(K/2))=f2(1:floor(K/2))-1;
+    Spec=[Spec(ceil(K/2):K,:); Spec(1:floor(K/2),:)];
+    Per=fftshift(Per);
+  end
+  
+  min_spec(Ktory)=min([min(Spec(isfinite(Spec))); 0]);
+  max_spec(Ktory)=max([max(Spec(isfinite(Spec))); 0.001]);
+  min_per(Ktory)=min([min(Per(isfinite(Per))); 0]);
+  max_per(Ktory)=max([max(Per(isfinite(Per))); 0.001]);
+  if get(h_dB, 'UserData') %dB
+    Spec=10*log10(Spec);
+    Per=10*log10(Per);
+  end
+  set(get(ha(2),'Ylabel'),'UserData', f);
+  set(get(ha(3),'Ylabel'),'UserData', Spec);
+  set(get(ha(4),'Ylabel'),'UserData', Per);
+  
+  %draw signal
+  axes(ha(2));
+  if length(t)>1
+    t2=t+(t(2)-t(1))/2;
+  else
+    t2=M/2;
+  end;
+  
+  if isnan(hp_spec_t(Ktory))
+    hold on;
+%    hp_spec_t(Ktory)=plot(t2,max(Spec), 'Color', 'k');
+    pomoc=abs(get(hp_re(Ktory),'Ydata')+j*get(hp_im(Ktory),'Ydata'));
+    hp_spec_t(Ktory)=plot(get(hp_re(Ktory),'Xdata'), pomoc, 'Color', 'k');
+    if length(pomoc)>512
+     set(hp_spec_t(Ktory), 'Marker', '.', 'MarkerSize', 4);
+   else
+     set(hp_spec_t(Ktory), 'LineStyle', '-');
+   end;
+    hold off;
+  else
+%    set(hp_spec_t(Ktory),'Xdata', t2, 'Ydata', max(Spec), 'Color', 'k');
+    set(hp_spec_t(Ktory),'Xdata', get(hp_re(Ktory),'Xdata'),...
+                         'Ydata', abs(get(hp_re(Ktory),'Ydata')+j*get(hp_im(Ktory),'Ydata')), 'Color', 'k');
+  end
+  if length(t)==1,
+    set(ha(2),  'Xlim', [t(1)-0.5 t(1)+0.5], 'Ylim', [-1.1 1.1]*max(max_x));
+  else
+    set(ha(2),  'Xlim', [t(1) t(length(t))+(t(2)-t(1))], 'Ylim', [-1.1 1.1]*max(max_x));
+  end;
+%  set(get(ha(2),'ZLabel'),'UserData',[]);    
+%  reset(get(ha(2),'ZLabel'));    
+  eval('rmappdata(get(ha(2),''Zlabel''),''ZOOMAxesData'')','set(get(ha(2),''ZLabel''),''UserData'',[])');
+
+  %spektrogram
+  axes(ha(3));
+  if isnan(hp_spec(Ktory))
+    hold on;
+    hp_spec(Ktory)=image(t2, f, Spec);
+    colormap(hot);
+    hold off;
+  else
+    set(hp_spec(Ktory),'Xdata', t2, 'Ydata', f, 'Cdata', Spec);
+  end
+  if length(t)==1,
+    tlim_=[t(1)-0.5 t(1)+0.5];
+  else
+    tlim_=[t(1) t(length(t))+t(2)-t(1)];
+  end;
+  if all(Re)
+    set(ha(3), 'Ylim', [0 0.5], 'Xlim', tlim_);
+  else
+    set(ha(3), 'Ylim', [-0.5 0.5], 'Xlim', tlim_);
+  end
+%  set(get(ha(3),'ZLabel'),'UserData',[]);    
+%  reset(get(ha(3),'ZLabel'));    
+  eval('zoom reset', 'set(get(ha(3),''ZLabel''),''UserData'',[]);');    
+  
+  axes(ha(4));
+  if isnan(hp_per(Ktory))
+    hold on;
+    hp_per(Ktory)=plot(Per, f2, 'Color', 'k');
+    hold off;
+  else
+    set(hp_per(Ktory),'Ydata', f2, 'Xdata', Per, 'Color', 'k');
+  end
+  set(ha(4), 'Xdir', 'reverse', 'YTick', []); %, 'Xlim', [t(1) t(length(t))], 'Ylim', [-1.1 1.1]*max(max_x));
+  if all(Re)
+    set(ha(4), 'Ylim', [0 0.5]);
+  else
+    set(ha(4), 'Ylim', [-0.5 0.5]);
+  end
+  eval('rmappdata(get(ha(4),''Zlabel''),''ZOOMAxesData'')','set(get(ha(4),''ZLabel''),''UserData'',[])');
+
+  set(hMenu,'UserData', [hp_re, hp_im, hp_spec_t, hp_spec_t2, hp_spec, hp_per, hp_per2, max_x, min_spec, max_spec, min_per, max_per]);
+
+  %  delete
+  if 1
+    pom=get(hMenu,'UserData');
+    hp_=pom(:,[4,7]);
+    hp_=hp_(isfinite(hp_));
+    if length(hp_)>0
+      delete(hp_)
+      pom(:,4)=NaN;
+      pom(:,7)=NaN;
+      set(hMenu,'UserData',pom);
+    end;
+  end
+  
+  SPECgraf('spec_ylim');
+  SPECgraf zoom_on;
+  SPECgraf zoom_off;
+  return;
+  
+elseif strcmp(Akcja, 'dB')
+  pom=get(h_dB, 'UserData');
+  if pom~=get(h_dB, 'Value')
+    pom=get(hMenu,'UserData');
+    hp_spec=pom(:,3);
+    for ind=1:length(hp_spec)
+      sygn=get(get(ha(3),'Ylabel'),'UserData');
+      per=get(get(ha(4),'Ylabel'),'UserData');
+      if get(h_dB, 'Value') %dB
+        sygn=10*log10(sygn);
+        per=10*log10(per);
+      else %lin
+        sygn=10.^(sygn/10);
+        per=10.^(per/10);
+      end;
+      set(get(ha(3),'Ylabel'),'UserData', sygn);
+      set(get(ha(4),'Ylabel'),'UserData', per);
+%      set(hp_spec(ind),'Cdata', sygn);
+    end;
+    set(h_dB, 'UserData', get(h_dB, 'Value'));
+
+    hp_=pom(:,[4 7]);
+    hp_=hp_(isfinite(hp_));
+    if length(hp_)>0
+      delete(hp_)
+      pom(:,4)=NaN;
+      pom(:,7)=NaN;
+      set(hMenu,'UserData',pom);
+    end;
+    SPECgraf('spec_ylim');
+  end
+  return
+  
+elseif strcmp(Akcja, 'spec_ylim')
+  pom=get(hMenu,'UserData');
+  hp_re=pom(:,1);
+  hp_im=pom(:,2);
+  hp_spec_t=pom(:,3);
+  hp_spec=pom(:,5);
+  hp_per=pom(:,6);
+  min_spec=pom(:,9);
+  max_spec=pom(:,10);
+  min_per=pom(:,11);
+  max_per=pom(:,12);
+  if get(h_dB, 'UserData') %dB
+    tekst=get(hEdit_dY,'String');
+    eval(['dY=' tekst ';'], 'dY=120;');
+    if dY<=0, dY=10; end;
+    params_=[min(min_spec) max(max_spec)];
+    ind_params = find(abs(params_) <= eps);
+    if length(ind_params) > 0,
+      params_(ind_params) = NaN*ones(size(ind_params));
+    end
+    ylim_=10*log10(params_);
+    if ~isfinite(ylim_(2))
+      ylim_(2)=0;
+    end
+    ylim_(1)=ylim_(2)-dY;
+    params_=[min(min_per) max(max_per)];
+    ind_params = find(abs(params_) <= eps);
+    if length(ind_params) > 0,
+      params_(ind_params) = NaN*ones(size(ind_params));
+    end
+    ylim_per=10*log10(params_);
+    if ~isfinite(ylim_per(2))
+      ylim_per(2)=0;
+    end
+    ylim_per(1)=ylim_per(2)-dY;
+  else
+    ylim_=[0 max(max_spec)];
+    ylim_per=[0 max(max_per)];
+  end
+  ylim_per(2)=max([ylim_per(2) ylim_(2)]);
+  f=get(get(ha(2),'Ylabel'),'UserData');
+  Spec=get(get(ha(3),'Ylabel'),'UserData');
+  Per=get(get(ha(4),'Ylabel'),'UserData');
+  set(hp_spec_t(Ktory),'Ydata', abs(get(hp_re(Ktory),'Ydata')+j*get(hp_im(Ktory),'Ydata')));
+  set(ha(2),'Ylim', ylim_+(ylim_(2)-ylim_(1))*[-0.1 0.1]);
+  Spec=64*(Spec-ylim_(1))/(ylim_(2)-ylim_(1));
+
+  set(hp_spec(Ktory),'Cdata', Spec);
+  set(hp_per(Ktory),'Xdata', Per, 'Ydata', f);
+  set(ha(4),'Xlim', ylim_per);
+
+  if get(h_dB, 'UserData') %dB
+    set(hp_spec_t(Ktory),'Ydata', 20*log10(abs(get(hp_re(Ktory),'Ydata')+j*get(hp_im(Ktory),'Ydata'))));
+  else
+    set(hp_spec_t(Ktory),'Ydata', abs(get(hp_re(Ktory),'Ydata')+j*get(hp_im(Ktory),'Ydata')));
+  end
+  
+  SPECgraf zoom_on;
+  eval('zoom reset', 'set(get(ha(3),''ZLabel''),''UserData'',[]);');    
+  SPECgraf zoom_off;
+  return
+elseif strcmp(Akcja, 'zoom_on')
+  zoom on;
+%   pom=get(fig, 'WindowButtonDownFcn');
+%   set(fig, 'WindowButtonDownFcn', 'SPECgraf zoom');
+%   set(get(ha(3),'Xlabel'), 'UserData', pom);
+  return;  
+elseif strcmp(Akcja, 'zoom_off')
+  if get(findobj(fig,'tag','checkbox_zoom'),'Value') == 0,
+%     pom = get(get(ha(3),'Xlabel'), 'UserData');
+%     set(fig, 'WindowButtonDownFcn', pom);
+    zoom off;
+    set(fig, 'WindowButtonDownFcn', 'SPECgraf zoom');
+    set(get(ha(3),'Xlabel'), 'UserData', '1;');
+  end
+  return;  
+elseif strcmp(Akcja, 'zoom_spec')
+  if get(findobj(fig,'tag','checkbox_zoom'),'Value') ~= 0,
+    Specgraf zoom_on;
+  else
+    Specgraf zoom_off;
+  end
+elseif strcmp(Akcja, 'zoom')
+%  if strcmp(get(fig,'SelectionType'),'normal') | (gca~=ha(3))
+  pause(0);
+  if (get(gco,'Parent')~=ha(3)) | get(findobj(fig,'tag','checkbox_zoom'),'Value')
+    eval(get(get(ha(3),'Xlabel'), 'UserData'));
+  elseif get(gco,'Parent')==ha(3)
+    pom=get(ha(3), 'CurrentPoint');
+    f_=pom(1,2); t_=pom(1,1);
+
+    pom_=get(hMenu,'UserData');
+    hp_spec_t2=pom_(:,4);
+    hp_spec=pom_(:,5);
+    hp_per2=pom_(:,7);
+    f=get(hp_spec(Ktory), 'Ydata');
+    ind_f=find(abs(f-f_)==min(abs(f-f_))); ind_f=ind_f(1);
+    t=get(hp_spec(Ktory), 'Xdata');
+%    if length(t)>1,
+%      t=t+(t(2)-t(1))/2;
+%    end;
+    ind_t=find(abs(t-t_)==min(abs(t-t_)));
+    ind_t=ind_t(1);
+    set(findobj(fig,'tag', 'text_t_f'),...
+      'ForegroundColor', 'r', 'String', sprintf('n=%i, f=%6.3f', t(ind_t),f(ind_f)));
+
+    Spec=get(get(ha(3),'Ylabel'),'UserData');
+    axes(ha(4));
+    if length(Spec(:,ind_t))>length(f)
+      ind=find(f==0);
+      Spec(ind(1),:)=[];
+    end;
+    if isnan(hp_per2(Ktory))
+      hold on;
+      hp_per2(Ktory)=plot(Spec(:,ind_t),f, 'Color', 'r', 'LineWidth', 2);
+      hold off;
+    else
+      set(hp_per2(Ktory),'Xdata', Spec(:,ind_t), 'Ydata', f);
+    end
+%    pom=get(ha(4), 'Xlim');
+%    pom(2)=max([pom(2) max(Spec(:,ind_t))]);
+%    set(ha(4),'Xlim', pom);
+
+    axes(ha(2));
+    if isnan(hp_spec_t2(Ktory))
+      hold on;
+      hp_spec_t2(Ktory)=plot(t,Spec(ind_f,:), 'Color', 'r', 'LineWidth', 2);
+      hold off;
+      SPECgraf zoom_on;
+      SPECgraf zoom_off;
+    else
+      set(hp_spec_t2(Ktory),'Xdata', t, 'Ydata', Spec(ind_f,:));
+    end
+
+    pom_(Ktory,7)=hp_per2;
+    pom_(Ktory,4)=hp_spec_t2;
+    set(hMenu,'UserData',pom_);
+  end;
+ return;  
+end;
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+function fig_h=Specgraf_DrawFig
+fig_h=figure;
+set(fig_h, ...
+  'Units', 'Normalized',...
+  'Position', [0.1125 0.1188 0.7813 0.7448],...
+  'Color', [1.0000 1.0000 1.0000],...
+  'Name', 'Untitled',...
+  'NumberTitle', 'off',...
+  'Menu', 'none',...
+  'Tag', 'figure1'...
+  );
+h=axes;
+set(h, ...
+  'Units', 'Normalized',...
+  'Position', [0.0330 0.0881 0.2150 0.4867],...
+  'Color', [1.0000 1.0000 1.0000],...
+  'XColor', [0.0000 0.0000 0.0000],...
+  'YColor', [0.0000 0.0000 0.0000],...
+  'FontSize', 10,...
+  'Box', 'on',...
+  'Tag', 'per_axes'...
+  );
+h=axes;
+set(h, ...
+  'Units', 'Normalized',...
+  'Position', [0.2900 0.6350 0.6990 0.1538],...
+  'Color', [1.0000 1.0000 1.0000],...
+  'XColor', [0.0000 0.0000 0.0000],...
+  'YColor', [0.0000 0.0000 0.0000],...
+  'FontSize', 10,...
+  'Box', 'on',...
+  'Tag', 'Signal_im_axes'...
+  );
+h=axes;
+set(h, ...
+  'Units', 'Normalized',...
+  'Position', [0.2880 0.0867 0.7030 0.4867],...
+  'Color', [1.0000 1.0000 1.0000],...
+  'XColor', [0.0000 0.0000 0.0000],...
+  'YColor', [0.0000 0.0000 0.0000],...
+  'FontSize', 10,...
+  'Box', 'on',...
+  'Tag', 'spec_axes'...
+  );
+h=axes;
+set(h, ...
+  'Units', 'Normalized',...
+  'Position', [0.2920 0.8266 0.6980 0.1580],...
+  'Color', [1.0000 1.0000 1.0000],...
+  'XColor', [0.0000 0.0000 0.0000],...
+  'YColor', [0.0000 0.0000 0.0000],...
+  'FontSize', 10,...
+  'Box', 'on',...
+  'Tag', 'Signal_re_axes'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'frame',...
+  'Units', 'Normalized',...
+  'Position', [0.0050 0.7972 0.2400 0.1930],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', '',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'frame2'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'frame',...
+  'Units', 'Normalized',...
+  'Position', [0.0050 0.5916 0.2400 0.2028],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', '',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'frame4'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'text',...
+  'Units', 'Normalized',...
+  'Position', [0.1190 0.6364 0.0280 0.0350],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', '[%]',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'text23'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'checkbox',...
+  'Units', 'Normalized',...
+  'Position', [0.8720 0.0126 0.0660 0.0196],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', 'zoom',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', 'Specgraf zoom_spec',...
+  'Tag', 'checkbox_zoom'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'pushbutton',...
+  'Units', 'Normalized',...
+  'Position', [0.0140 0.0098 0.0660 0.0378],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'Exit',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', 'SPECgraf Exit',...
+  'Tag', 'pushbutton5'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'text',...
+  'Units', 'Normalized',...
+  'Position', [0.4640 0.0028 0.3540 0.0350],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', '',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'text_t_f'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'edit',...
+  'Units', 'Normalized',...
+  'Position', [0.1750 0.0126 0.0750 0.0364],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', 'Edit Text',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', 'SPECgraf(''spec_ylim'')',...
+  'Tag', 'dY_edit'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'text',...
+  'Units', 'Normalized',...
+  'Position', [0.1110 0.0154 0.0620 0.0308],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', 'dY [dB] =',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'text21'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'checkbox',...
+  'Units', 'Normalized',...
+  'Position', [0.9270 0.5748 0.0500 0.0322],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', 'dB',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', 'SPECgraf(''dB'')',...
+  'Tag', 'dB_checkbox'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'pushbutton',...
+  'Units', 'Normalized',...
+  'Position', [0.0660 0.4909 0.0600 0.0420],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'Delete',...
+  'Value', 0,...
+  'Visible', 'off',...
+  'Callback', 'SPECgraf(''delete'')',...
+  'Tag', 'pushbutton4'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'pushbutton',...
+  'Units', 'Normalized',...
+  'Position', [0.0120 0.4909 0.0480 0.0420],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'New',...
+  'Value', 0,...
+  'Visible', 'off',...
+  'Callback', 'SPECgraf(''new'')',...
+  'Tag', 'pushbutton3'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'text',...
+  'Units', 'Normalized',...
+  'Position', [0.1580 0.6769 0.0750 0.0364],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', 'Edit Text',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', 'SPECgraf(''spec'')',...
+  'Tag', 'N_edit'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'text',...
+  'Units', 'Normalized',...
+  'Position', [0.1280 0.6825 0.0300 0.0266],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'N =',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'text18'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'edit',...
+  'Units', 'Normalized',...
+  'Position', [0.0390 0.8014 0.0720 0.0378],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', 'Edit Text',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', 'SPECgraf(''signal'')',...
+  'Tag', 'L_edit'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'text',...
+  'Units', 'Normalized',...
+  'Position', [0.0090 0.8028 0.0290 0.0266],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'L =',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'text17'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'checkbox',...
+  'Units', 'Normalized',...
+  'Position', [0.1290 0.7301 0.1100 0.0252],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'detrend',...
+  'Value', 0,...
+  'Visible', 'off',...
+  'Callback', 'SPECgraf(''spec'')',...
+  'Tag', 'detrend_checkbox'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'edit',...
+  'Units', 'Normalized',...
+  'Position', [0.0400 0.6378 0.0750 0.0364],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', 'Edit Text',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', 'SPECgraf(''spec'')',...
+  'Tag', 'O_edit'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'text',...
+  'Units', 'Normalized',...
+  'Position', [0.0110 0.6378 0.0280 0.0294],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'O =',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'text16'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'edit',...
+  'Units', 'Normalized',...
+  'Position', [0.0520 0.6000 0.1870 0.0336],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', 'Edit Text',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', 'SPECgraf(''spec'')',...
+  'Tag', 'w_edit'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'text',...
+  'Units', 'Normalized',...
+  'Position', [0.0130 0.5986 0.0400 0.0294],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'w[n] =',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'text15'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'edit',...
+  'Units', 'Normalized',...
+  'Position', [0.1670 0.8042 0.0720 0.0364],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', 'Edit Text',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', 'SPECgraf(''signal'')',...
+  'Tag', 'Noise_edit'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'text',...
+  'Units', 'Normalized',...
+  'Position', [0.1190 0.8042 0.0470 0.0266],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'Noise=',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'text14'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'edit',...
+  'Units', 'Normalized',...
+  'Position', [0.0410 0.6769 0.0750 0.0364],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', 'Edit Text',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', 'SPECgraf(''spec'')',...
+  'Tag', 'M_edit'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'text',...
+  'Units', 'Normalized',...
+  'Position', [0.0110 0.6825 0.0300 0.0266],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'M =',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'text13'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'edit',...
+  'Units', 'Normalized',...
+  'Position', [0.1340 0.4909 0.1030 0.0392],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', 'Edit Text',...
+  'Value', 0,...
+  'Visible', 'off',...
+  'Callback', 'SPECgraf(''change_name'')',...
+  'Tag', 'Name_edit'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'popupmenu',...
+  'Units', 'Normalized',...
+  'Position', [0.0120 0.5413 0.2260 0.0294],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', 'Popup Menu',...
+  'Value', 1,...
+  'Visible', 'off',...
+  'Callback', 'SPECgraf(''Choose'')',...
+  'Tag', 'choose_popupmenu'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'checkbox',...
+  'Units', 'Normalized',...
+  'Position', [0.1160 0.9580 0.1110 0.0266],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'real signal',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', 'SPECgraf(''signal'')',...
+  'Tag', 'real_checkbox'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'text',...
+  'Units', 'Normalized',...
+  'Position', [0.0100 0.7622 0.1470 0.0266],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'Spectrograf parameters',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'text10'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'edit',...
+  'Units', 'Normalized',...
+  'Position', [0.0400 0.7259 0.0750 0.0364],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', 'Edit Text',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', 'SPECgraf(''spec'')',...
+  'Tag', 'K_edit'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'text',...
+  'Units', 'Normalized',...
+  'Position', [0.0140 0.7329 0.0240 0.0252],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'K =',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'text9'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'edit',...
+  'Units', 'Normalized',...
+  'Position', [0.0390 0.8462 0.2010 0.1077],...
+  'BackGroundColor', [1.0000 1.0000 1.0000],...
+  'String', 'Edit Text',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', 'SPECgraf(''signal'')',...
+  'Tag', 'x_edit'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'text',...
+  'Units', 'Normalized',...
+  'Position', [0.0130 0.9245 0.0240 0.0252],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'x =',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'text4'...
+  );
+h=uicontrol;
+x=version;
+if (x(1)>='5'),
+  set(h, ...
+    'FontSize', 10);
+end;
+set(h, ...
+  'Style', 'text',...
+  'Units', 'Normalized',...
+  'Position', [0.0120 0.9636 0.1010 0.0238],...
+  'BackGroundColor', [0.9255 0.9137 0.8471],...
+  'String', 'Testing signal',...
+  'Value', 0,...
+  'Visible', 'on',...
+  'Callback', '',...
+  'Tag', 'text2'...
+  );
diff --git a/Ex4/matlab/ex4_task1.m b/Ex4/matlab/ex4_task1.m
new file mode 100644
index 0000000..a38fbca
--- /dev/null
+++ b/Ex4/matlab/ex4_task1.m
@@ -0,0 +1,44 @@
+function ex4_task1
+
+
+N_FSD = 13;
+tau_N = (N_FSD-1)/2;
+
+Fp1 = 8000; Fp2 = 10000;
+
+M = Fp1 / gcd(Fp1,Fp2) 
+L = Fp2 / gcd(Fp1,Fp2)
+
+eps_all = -linspace(-0.5+0.5/L, 0.5-0.5/L, L);
+
+figure(1)
+ha1 = subplot(2,1,1);
+h_all = zeros(1, N_FSD*L);
+n_all = 0:length(h_all)-1; n_all = n_all - (length(n_all)-1)/2;
+for ind = 1:L,
+  epsilon = eps_all(ind);
+  h = FSDfilter('Lagr', N_FSD, tau_N+epsilon);
+%   h = FSDfilter('optimal2', N_FSD, tau_N+epsilon, 0.4);
+  h_all(ind:L:end) = h;
+  set(stem(ha1, n_all, h_all), 'Marker', 'none');
+  pause(0.1)
+  drawnow
+end
+
+K = 16*8192;
+F = linspace(0, L*Fp1, K);
+
+H_all = abs(fft(h_all/L, K));
+figure(11)
+subplot(2,1,1)
+plot(h_all);
+subplot(2,1,2)
+plot(F, 20*log10(H_all));
+set(gca, 'Xlim', [0, L*Fp1/2], 'Ylim', [-100, 3])
+
+
+dane.h{1}  = h_all;
+dane.h{2}  = [L, M];
+dane.Fp = Fp1;
+save_filter_coef('ex4_task2_h_FSD_all', dane, 1);
+
diff --git a/Ex4/matlab/ex4_task1_test.m b/Ex4/matlab/ex4_task1_test.m
new file mode 100644
index 0000000..ec655b8
--- /dev/null
+++ b/Ex4/matlab/ex4_task1_test.m
@@ -0,0 +1,39 @@
+function ex4_task1_test
+
+
+N_FSD = 63;
+tau_N = (N_FSD-1)/2;
+
+% Fp1 = 8000; Fp2 = 10000;
+Fp1 = 16000; Fp2 = 11025;
+
+M = Fp1 / gcd(Fp1,Fp2) 
+L = Fp2 / gcd(Fp1,Fp2)
+
+eps_all = -linspace(-0.5+0.5/L, 0.5-0.5/L, L);
+
+h_all = zeros(1, N_FSD*L);
+for ind = 1:L,
+  epsilon = eps_all(ind);
+  h = FSDfilter('optimal2', N_FSD, tau_N+epsilon, 0.45);
+%   h = FSDfilter('optimal2', N_FSD, tau_N+epsilon, 0.4);
+  h_all(ind:L:end) = h;
+end
+
+K = 16*8192;
+F = linspace(0, L*Fp1, K);
+
+H_all = abs(fft(h_all/L, K));
+figure(11)
+subplot(2,1,1)
+plot(h_all);
+subplot(2,1,2)
+plot(F, 20*log10(H_all));
+set(gca, 'Xlim', [0, L*Fp1/2], 'Ylim', [-100, 3])
+
+
+dane.h{1}  = h_all;
+dane.h{2}  = [L, M];
+dane.Fp = Fp1;
+save_filter_coef('ex4_task2_h_FSD_all', dane, 1);
+
diff --git a/Ex4/matlab/ex4_task2_h_FSD_all.coef b/Ex4/matlab/ex4_task2_h_FSD_all.coef
new file mode 100644
index 0000000000000000000000000000000000000000..b12e93ef7292943bc38b57f86abbe339bd50a6ad
GIT binary patch
literal 280
zcmZQ{kY`|EWMpz=@ZgWJm~olYf&mCVh6wM_tFPX1ZnpET$og+PfkF+xTUf1@EJ(E~
z<6dh0<3gY{NZt2m>ATnNIJw*R@5Vj-HK}_*>Sil7+oT?RVRQ3puPx(YYg>>ypxoYL
z2d?amZE@PCypeMsNZpoBKf6QkAK9In=w|=-Yk@sb2uy?cAaRg9NH0h|NFPW)$Q+Pf
zkhvi9LH2;`1E~Yq4{`^{Js@|1)PdXyaxci;AoqjRf&2sV7s!7ge}dG3{0;Iy6OgmO
I0Vv=A0R9Yf+W-In

literal 0
HcmV?d00001

diff --git a/Ex4/matlab/getFSD_new.m b/Ex4/matlab/getFSD_new.m
new file mode 100644
index 0000000..ab7d7fe
--- /dev/null
+++ b/Ex4/matlab/getFSD_new.m
@@ -0,0 +1,468 @@
+% %poszukiwanie filtru optymalnego o dowolnej długoœci
+%w oparciu o układ równań rzeczywistych
+% w oparciu o phase rotated real error
+%
+%implementacja w oparciu o poszukiwanie ekstremów
+%pomiędzy dwoma kolejnymi punktami ekstremalnymi o tym samym znaku
+% 
+% Wariant bezrastrowy w użyciem interpolacji parabolicznej
+%
+%getFSD_new(N,voff,d); 
+% N - długoœć odpowiedzi impulsowej
+% voff - częstotliwoœć unormowana końca pasma dobrej aproksymacji
+% d - opóŸnienie netto
+
+% 2011.03.01
+function [h, TPEopt, ekst, A, B]=getFSD_new(N, voff, d, K, ekst, force_end);
+
+if nargin < 6,
+  force_end = 0;
+end
+
+if nargin==0,
+  N=4;
+  voff=0.35;
+  d=0.25;
+  K=2048; %DFT length
+elseif nargin==1,
+  voff=0.35;
+  d=0.25;
+  K=2048; %DFT length
+elseif nargin==2
+  d=0.25;
+  K=2048; %DFT length
+elseif nargin==3
+  K=2048; %DFT length
+end;
+
+% df_factor = 10; df_factor_scaling = 1.05;
+df_factor = 20; df_factor_scaling = 1.0;
+df_factor = 4;
+
+% % K = K * 8 * 16;
+% K_ = 8192*2*64;
+
+%   N_LPF(ind)=ceil((-20*log10(sqrt(dp*ds))-13)/(14.6*(vs-vp))+1);
+% N_FSD_est=ceil(-1/8*(PE/(4*(1/2-voff))+3));
+PE_est=-(N*8+3)*(4*(1/2-voff));
+if (PE_est < -140)
+  warning('Peek error estimation based on impulse response length shows that N is so large that it might result in fatal design errors');
+elseif (PE_est < -200)
+  warning('Peek error estimation based on impulse response length shows that N is so large that it probably will result in fatal design errors');
+elseif (PE_est < -275)
+  warning('Peek error estimation based on impulse response length shows that N is so large that it must result in fatal design errors');
+  pause
+end
+
+
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% bez kwantyzacji osi częstotliwoœci
+M_in=round(voff*K)+1; % voff=(M_in-1)/K;
+
+L=(N-1)/2; % bulk delay
+H_L = Hideal(L, voff, K); H_L=conj(H_L);
+Hid = Hideal(L+d, voff, K);
+
+TPEopt=-300;
+if nargin<5
+% 	if rem(N,2)==0
+% 	  v=linspace(0,voff,N/2+1);
+% 	else
+% 	  v=linspace(voff/N,voff,(N+1)/2);
+% 	end;
+%  alfa=0.95;
+%  alfa=0.975;
+  alfa=0.999;
+  if (voff<=0.47)
+    alfa=0.99;
+  end
+%  alfa=0.996;
+%  alfa=0.999;
+	if rem(N,2)==0
+%       '0'
+    x=[0:(N/2-1)];
+    v=[0 cumsum(alfa.^x)];
+    v=v/v(end)*voff;
+	else
+    x=[0:((N-1)/2)];
+    v=cumsum(alfa.^x);
+    v(1)=v(1)/2;
+    v=v/v(end)*voff;
+	end;
+  ekst=(v*K);
+%   ekst=round(v*K);
+end
+
+nn=1:N; A=zeros(N+1,N+1); B=zeros(N+1,1);
+if (rem(N,2)==0) %parzyste
+  N_2=N/2;
+  A(1:N_2,N+1)=zeros(N_2,1);
+  A(((N_2+1):N),N+1)=((-1).^(1:N_2).');
+  A(N+1,(1:(N+1)))=ones(1,N+1);
+  B(N+1)=1;
+else
+  N_2=(N+1)/2;
+  A(1:N_2,N+1)=-((-1).^(1:N_2).');
+  A(((N_2+1):(N+1)),N+1)=0;
+end
+
+% ile = 0;
+koniec = 1;
+while 1,
+%   ile = ile + 1
+  %construct equations  
+  if (rem(N,2)==0) %parzyste
+    v=ekst(2:length(ekst))/K; %N-parzyste
+    for k=1:N_2,
+      A(k,nn)=sin(2*pi*(nn-1-L)*v(k));
+      B(k)=sin(2*pi*v(k)*d);
+      A((N_2+k),nn)=cos(2*pi*(nn-1-L)*v(k));
+      B((N_2+k))=cos(2*pi*v(k)*d);
+    end
+  else
+    v=ekst(1:length(ekst))/K; %N-nieparzyste
+    for k=1:N_2,
+      A(k,nn)=sin(2*pi*(nn-1-L)*v(k));
+      B(k)=sin(2*pi*v(k)*d);
+      A((N_2+k),nn)=cos(2*pi*(nn-1-L)*v(k));
+      B((N_2+k))=cos(2*pi*v(k)*d);
+    end
+  end
+  
+  if any(~isfinite(B)),
+    disp('B isn''t finite');
+    error
+  end
+  if any(~isfinite(A)),
+    disp('A isn''t finite');
+    error
+  end
+  x=A\B; %  x=inv(A)*B;
+  h=x(1:N).';
+  if any(~isfinite(h)),
+    disp('h isn''t finite');
+    plot(20*log10(abs(Error)));
+    error
+  end
+  
+  if any(~isfinite(h)),
+    disp('Impulse response isn''t finite');
+    error
+  end
+  
+  % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  % Error calculation
+  H = fft(h,K);
+  H = H(1:M_in);
+  H_L = H_L(1:M_in);
+  Hid = Hid(1:M_in);
+
+  if (M_in-1)/K < voff,
+    n = 0:length(h)-1;
+    H_off = sum(h.*exp(-i*2*pi*voff*n));
+    Hid_off = exp(-i*2*pi*voff*(L+d));
+    H_L_off = exp(+i*2*pi*voff*L);
+    H = [H, H_off];
+    Hid = [Hid, Hid_off];
+    H_L = [H_L, H_L_off];
+  end
+  
+  Error=H-Hid;
+  Error=Error.*H_L;
+
+  n = 0:length(h)-1;
+  H_off = sum(h.*exp(i*2*pi*voff*(n-L).*n));
+  Hid_off = exp(-i*2*pi*voff*d);
+  
+  % wyznaczenie współczynnika rotacji błędu
+  % => korygujemy błšd tak, żeby na częstotliwoœci 
+  Error_v_off = H_off - Hid_off;
+%   if abs(Error(M_in)) > 0,
+  if abs(Error_v_off) > 0,
+    Err_rot = conj(Error_v_off)/abs(Error_v_off);
+%   Err_rot = conj(Error(M_in))/abs(Error(M_in));
+    Error=Error.*Err_rot;
+  else
+    Err_rot = 1;
+  end
+  if any(~isfinite(Error)),
+    disp('Normalized error isn''t finite');
+    error
+  end
+
+  if force_end == 1;
+    TPEopt = 20*log10(abs(x(N+1)));
+    TPEopt(2) = 20*log10(max(abs(Error)));
+    return;
+  end
+%   plot(20*log10(abs(Error)));
+  
+  % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  % poszukiwanie położenia nowych ekstremów
+%   ekst=Ekstr(real(Error),ekst, N);
+%  ekst=Ekstr_new(h, ekst, Err_rot, d, N);
+  ekst_old = ekst;
+  ekst=Ekstr_new(h, ekst/K, d, N, K, df_factor)*K;
+  df_factor = round(df_factor * df_factor_scaling);
+  if df_factor > 200,
+    df_factor = 200;
+  end
+  
+  if any(~isfinite(ekst)),
+    disp('ekst isn''t finite');
+    error
+  end
+  
+  % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  % wyznaczenie peek error
+  %TPE=max(20*log10(abs(Error(ekst+1)))); 
+  %TPE_H=max(20*log10(abs(Error))); 
+  TPE=20*log10(abs(x(N+1)));
+  if TPEopt<TPE
+    TPEopt=TPE;
+  else
+%     ekst
+    ekst_old - ekst;
+    koniec = koniec - 1;
+    if koniec == 0,
+      break;
+    end
+  end
+end
+
+return
+
+
+%========================================================
+function Hid = Hideal(delay, F, K)
+% delay - opóŸnienie ułamkowe projektowanego filtru
+% F - unormowana częstotliwoœć górna pasma akuratnej aproksymacji
+% K - liczba pršżków transformaty
+% Hid - charakterystyka idealna (K-punktowa)
+
+v=(0:(K-1))/K; v(K/2:K)=v(K/2:K)-1;
+Hid = ones(1,K).*exp(-i*2*pi*v*delay);
+
+%========================================================
+function x=Ekstr(Err, old, N)
+% jeżeli filtr parzystej długoœci to zakładamy, że punkty ekstremalne w 0 i M_in (end)
+% nie ulegajš zmianie
+% jeżeli filtr o nieparzystej długoœci to w zerze napewno nie ma punktu ekstremalnego 
+% oraz punkt ekstremalny w M_in (end) nie ulega zmianie
+
+delta=max(abs(Err(old+1)));
+
+%wyjœciowy zestaw punktów ekstremalnych
+temp=old+1; %parzyste
+if rem(N,2)==1
+  temp=[1 temp]; %nieparzyste
+end
+
+min_max=0;
+for ind=length(temp):-1:3
+  pom=Err(temp(ind-2):temp(ind));
+  if min_max==0
+    [wart, ind_new]=find(pom==min(pom));
+  else
+    [wart, ind_new]=find(pom==max(pom));
+  end
+  if abs(wart)>delta
+    temp(ind-1)=temp(ind-2)+ind_new-1;
+  end
+  min_max=1-min_max;
+end
+
+x=temp-1;
+if rem(N,2)==1
+	x=x(2:length(x));
+end
+
+function f_new = Ekstr_new(h, f_old, d, N, K, df_factor);
+% jeżeli filtr parzystej długoœci to zakładamy, że punkty ekstremalne w 0 i M_in (end)
+% nie ulegajš zmianie
+% jeżeli filtr o nieparzystej długoœci to w zerze napewno nie ma punktu ekstremalnego 
+% oraz punkt ekstremalny w M_in (end) nie ulega zmianie
+L = (N-1)/2;
+n = 0:N-1; n=n(:);
+
+f_old_ = f_old;
+foff = f_old(end);
+H_off = sum(h(:).*exp(-i*2*pi*foff*(n-L)));
+Hid_off = exp(-i*2*pi*foff*d);
+Error_f_off = H_off - Hid_off;
+if abs(Error_f_off) > 0,
+  Err_rot = conj(Error_f_off)/abs(Error_f_off);
+else
+  Err_rot = 1;
+end
+
+for ind = 1:length(f_old),
+  H_off(ind) = sum(h(:).*exp(j*2*pi*f_old(ind)*(n-L).*n));
+end
+Hid_old = exp(-i*2*pi*f_old*d);
+
+Err_old = real((H_off - Hid_old)*Err_rot);
+
+% delta=max(abs(Err(old+1)));
+delta=max(abs(Err_old));
+
+
+do_draw = 0;
+if do_draw == 1,
+  % %   f = linspace(0,0.5, 2048);
+  f = linspace(0,0.5, K); % 2011.02.28
+  
+  E_ = 0;
+  H_ = 0;
+  for n_ = n.',
+    E_ = E_ + Err_rot*(-j)*2*pi* h(n_+1).*(n_-(L+d)).*exp(-j*2*pi*f*(n_-(L+d)));
+    H_ = H_ + Err_rot*h(n_+1).*exp(-j*2*pi*f*(n_-L));
+  end
+
+  H_id = Err_rot*exp(-j*2*pi*f*d);
+
+  figure(5)
+  subplot(3,1,1)
+  plot(f, real(E_));
+  hold on
+  plot(f, imag(E_), 'r');
+  hold off
+  set(gca, 'Xtick', f_old_, 'Xgrid', 'on');
+  subplot(3,1,2)
+  plot(f, abs(H_-H_id), 'k');
+  hold on
+  plot(f, real(H_-H_id), 'b');
+  plot(f, imag(H_-H_id), 'r');
+  hold off
+
+  subplot(3,1,3)
+  plot(f, 20*log10(abs(H_-H_id)), 'k');
+end
+  
+if rem(N, 2) == 1,
+  f_old = [0, f_old]; % 0 must always be included 
+end 
+% find extremas
+% leave point at v_off (maximum)
+f_new = f_old(end);
+
+polarization = -1;
+while length(f_old) > 2,
+  % find extremum between f_start and f_end 
+  f_end = f_old(end);
+  f_start = f_old(end-2);
+
+  fo = f_old(end-1); % old value
+  
+  df = min([(f_end-fo), (fo-f_start)]) / df_factor;
+  
+  fo_new = find_extremum(h, d, Err_rot, [fo-df, fo, fo+df], polarization, do_draw);
+  
+  f_new = [fo_new, f_new];
+  f_old(end) = [];
+  
+  polarization = -polarization;
+end
+if rem(N, 2) == 0,
+  f_new = [f_old(1), f_new]; % include 0
+end
+
+% size(f_old_)
+% size(f_new)
+
+if do_draw == 1,
+  subplot(3,1,2)
+  set(gca, 'Xtick', f_new, 'Xgrid', 'on');
+  subplot(3,1,3)
+  set(gca, 'Xtick', f_new, 'Xgrid', 'on');
+
+  % f_new
+  % 
+  pause
+end
+
+function fo_new = find_extremum(h, d, Err_rot, fs, polarization, do_draw)
+
+N = length(h);
+n = 0:N-1; n = n(:);
+L = (N-1)/2;
+
+f = fs;
+% f = [fs(1), (fs(1)+fs(2))/2, fs(2), (fs(2)+fs(3))/2, fs(3)];
+% f = linspace(fs(1), fs(3), 11);
+
+% E_ = 0;
+H_ = 0;
+for n_ = n.',
+%   E_ = E_ + Err_rot*(-j)*2*pi* h(n_+1).*(n_-(L+d)).*exp(-j*2*pi*f*(n_-(L+d)));
+  H_ = H_ + Err_rot*h(n_+1).*exp(-j*2*pi*f*(n_-L));
+end
+H_id = Err_rot*exp(-j*2*pi*f*d);
+
+E_ = real(H_-H_id) * polarization;
+
+%f(x) = a*x^2+b*x+c
+%delta = b^2 - 4*a*c
+%f_ekstremum = -b/(2*a)
+
+% % y = polyval(a, x)
+% y1 = a*x1^2 + b*x1 + c
+% y2 = a*x2^2 + b*x2 + c
+% y3 = a*x3^2 + b*x3 + c
+
+a = polyfit(f, E_, 2);
+
+fo_new = -a(2)/(2*a(1));
+
+% 
+% if (fo_new < fs(1)) 
+%   fo_new = fs(1);
+% end
+% if (fo_new > fs(3)) 
+%   fo_new = fs(3);
+% end
+
+if (fo_new < fs(1)) || (fo_new > fs(3))
+  ind = find(max(E_) == E_);
+  fo_new = f(ind(1));
+else
+  H_new = 0;
+  for n_ = n.',
+    H_new = H_new + Err_rot*h(n_+1).*exp(-j*2*pi*fo_new*(n_-L));
+  end
+  H_id_new = Err_rot*exp(-j*2*pi*fo_new*d);
+  E_new = real(H_new-H_id_new) * polarization;
+
+  E_ = [E_, E_new];
+  f = [f, fo_new];
+  
+  ind = find(max(E_) == E_);
+  if (fo_new ~= f(ind(1))),
+    fo_new = f(ind(1));
+  end
+
+end
+
+% % if fo_new < fs(1)
+% %   fo_new = fs(1);
+% % end
+% % if fo_new > fs(3)
+% %   fo_new = fs(3);
+% % end
+% % % fo_new
+% % % fo_new;
+
+% do_draw = 1;
+if do_draw == 1,
+  f_ = linspace(fs(1), fs(3), 51);
+  y = polarization * polyval(a,  f_);
+  subplot(3,1,2)
+  hold on
+  plot(f_, y, 'm');
+  hold off
+  max_y = max(abs(y));
+  if max_y == 0, max_y = 1, end;
+  set(gca, 'Ylim', [-1.15, 1.15]*max_y);
+  % % pause
+  % 
+end
diff --git a/Ex4/matlab/readaudiofile.m b/Ex4/matlab/readaudiofile.m
new file mode 100644
index 0000000..825a9a8
--- /dev/null
+++ b/Ex4/matlab/readaudiofile.m
@@ -0,0 +1,215 @@
+function [x, Fs] = readaudiofile(filename, param)
+% [x, Fs] = readaudiofile(filename, param)
+%
+% returns vector x of the size SIZE=[samples channels].
+%  eg. x = x(:,1) + j*x(:,2);
+%
+% special uses:
+%  param == 'size': returns SIZE in x
+%  param == 'cplx': for stereo files returns x as a complex vector instead of matrix 
+%
+%  supported file types:
+%    *.flt
+%    *.wav
+%    *.tape
+% last modification: 2021.03.29
+% Author: Marek Blok
+
+return_cplx = 0;
+if nargin == 1,
+  param = inf;
+else
+  if strcmp(param, 'cplx') == 1,
+    return_cplx = 1;
+    param = inf;
+  end
+end
+
+ind = find(filename == '.');
+if length(ind) == 0,
+  file_type = 'w'; % *.wav
+else
+  ind = ind(end);
+  
+  temp = filename(ind+1:end);
+  
+  file_type = 'u'; % unknown format
+  if strcmp(temp, 'flt') == 1,
+    file_type = 'f'; % two channel floting point
+  elseif strcmp(temp, 'wav') == 1,
+    file_type = 'w'; % *.wav
+  elseif strcmp(temp, 'tape') == 1,
+    file_type = 't'; % *.tape
+  end
+end
+
+switch file_type,
+  case 'w',
+    if strcmp(param, 'size') == 1,
+      if exist('audioread','file') == 0
+        x = wavread(filename, 'size');
+        %  siz = [samples channels].
+      else
+        info = audioinfo(filename);
+        x = [info.TotalSamples, info.NumChannels];
+        Fs = info.SampleRate;
+      end      
+    else
+      if isfinite(param)
+        if exist('audioread','file') == 0
+          [x, Fs] = wavread(filename, param);
+        else
+          if length(param) == 1
+            param = [1, param];
+          end
+          [x, Fs] = audioread(filename, param);
+        end
+      else
+        if exist('audioread','file') == 0
+          [x, Fs] = wavread(filename);
+        else
+          [x, Fs] = audioread(filename);
+        end
+      end
+    end
+    
+  case 't'
+    plik = fopen(filename, 'rb');
+    if plik == -1,
+      error('File does not exist !!!');
+    end
+    
+    header.size = fread(plik, 1, 'uint32', 0) + 4;
+
+    header.fname      = char(fread(plik, 256, 'char', 0).');
+    header.cfg_fname  = char(fread(plik, 256, 'char', 0).');
+    header.sw_rev     = fread(plik, 1, 'uint32', 0);
+    header.hw_rev     = fread(plik, 1, 'uint32', 0);
+    header.file_      = fread(plik, 1, 'uint32', 0);
+    header.tape_type  = fread(plik, 1, 'uint32', 0);
+    header.start_time = fread(plik, 1, 'int32', 0); % time_t
+    header.end_time   = fread(plik, 1, 'int32', 0); % time_t
+    
+    header.total_samples  = fread(plik, 1, 'uint32', 0); 
+    file_length = header.total_samples * 4  + header.size
+    header.current_sample = fread(plik, 1, 'uint32', 0); 
+    header.loop_start     = fread(plik, 1, 'int64', 0); 
+    header.loop_end       = fread(plik, 1, 'int64', 0); 
+    header.loop           = fread(plik, 1, 'int32', 0); 
+    header.group_size_32  = fread(plik, 1, 'uint32', 0); 
+    header.block_size     = fread(plik, 1, 'uint32', 0); 
+    header.block_count    = fread(plik, 1, 'uint32', 0); 
+    header.fifo_size      = fread(plik, 1, 'uint32', 0); 
+
+
+    header.comment      = char(fread(plik, 256, 'char', 0).');
+    header.tmp  = char(fread(plik, 20, 'char', 0).'); % time_t
+    header.status       = fread(plik, 1, 'uint32', 0); 
+    header.timestamps   = fread(plik, 1, 'int32', 0); 
+    header.freq         = fread(plik, 1, 'float', 0); 
+    header.cplx_datarate = fread(plik, 1, 'float', 0); 
+    
+%     ftell(plik)
+    header.reserved = fread(plik, 128, 'uint32', 0);
+%     header.reserved.'
+    
+    header
+    ftell(plik)
+
+    header.sample_type = 2;
+    header.ch_no = 2;
+    header.Fs = NaN;
+    
+    sample_type = 'int16';
+    sample_size = 2;
+
+    header_size = header.size;
+    if strcmp(param, 'size') == 1,
+      fseek(plik, 0, 'eof');
+      size = (ftell(plik) - header_size) / sample_size / header.ch_no; % sizeof(float) *2
+      x = size;
+    else
+      fseek(plik, header_size, 'bof');
+      
+      len = param(1);
+      if length(param) > 1,
+        fseek(plik, sample_size*header.ch_no*(param(1)-1), 'cof');
+        len = param(2) - param(1) + 1;
+      end
+        
+%       x = fread(plik, [header.ch_no, len], sample_type);
+      x = fread(plik, [header.ch_no, len], sample_type, 0);
+      x = x.';
+    end
+    fclose(plik);
+    
+  case 'f'
+    plik = fopen(filename, 'rb');
+    if plik == -1,
+      error('File does not exist !!!');
+    end
+    
+    % 3 B - wersja pliku (w tym typ próbek)
+    % 1 B - liczba kanałów
+    % 4 B - szybkoœć próbkowania
+    header_size = 8;
+    header.ver = fread(plik, 1, 'uint8');
+    header.sample_type = fread(plik, 1, 'uint16');
+    header.ch_no = fread(plik, 1, 'uint8');
+    header.Fs = fread(plik, 1, 'uint32');
+    
+    Fs = header.Fs;
+    
+    switch (header.ver),
+      case 0,
+        switch (header.sample_type),
+          case 0,
+            sample_type = 'float';
+            sample_size = 4;
+          case 1,
+            sample_type = 'uchar';
+            sample_size = 1;
+          case 2,
+            sample_type = 'short';
+            sample_size = 2;
+          case 3,
+            sample_type = 'int';
+            sample_size = 4;
+          otherwise
+            error('Unsupported *.flt sample type !!!');
+        end
+      otherwise
+        error('Unsupported *.flt file version !!!');
+    end
+        
+    
+    if strcmp(param, 'size') == 1,
+      fseek(plik, 0, 'eof');
+      size = (ftell(plik) - header_size) / sample_size / header.ch_no; % sizeof(float) *2
+      x = size;
+    else
+      len = param(1);
+      status = 0;
+      if length(param) > 1,
+        status = fseek(plik, sample_size*header.ch_no*(param(1)-1), 'cof');
+        len = param(2) - param(1) + 1;
+      end
+        
+      if (status == -1)
+        x = [];
+      else
+        x = fread(plik, [header.ch_no, len], sample_type);
+        x = x.';
+      end
+    end
+    
+    fclose(plik);
+  otherwise
+    error('Unsupported file format !!!');
+end
+
+if return_cplx == 1,
+  if length(x(1,:)) == 2,
+    x = x(:,1) + j*x(:,2);
+  end
+end
\ No newline at end of file
diff --git a/Ex4/matlab/save_filter_coef.m b/Ex4/matlab/save_filter_coef.m
new file mode 100644
index 0000000..8cf1f07
--- /dev/null
+++ b/Ex4/matlab/save_filter_coef.m
@@ -0,0 +1,226 @@
+function save_filter_coef(filename, coefficients, file_version) 
+% save_filter_coef(filename, coefficients [, file_version]) 
+% 
+% FIR filter coefficients
+%   coefficients.h
+%    - can be cell vector to store multiple FIR impulse responces
+%    - if any of the impulse responses is complex then all responses will
+%      be stored as complex
+% IIR filter coefficients
+%   coefficients.a
+%   coefficients.b
+% 
+% For file_version >= 1 (default == 0),
+%   coefficients.Fp - sampling frequency
+%
+% This file is a part of Digital Signal Processing Engine
+% 
+% File format (*.coef) - this is open format, for general use
+%  *  (not only for storing coefficients)
+%  
+% File format (*.h) - this is C++ header file for DSPElib with hardcoded *.coef equivalent 
+%
+% \author Marek Blok
+% \date 2020.02.22
+
+if nargin == 2,
+  file_version = 0;
+end
+
+ind = find(filename == '.');
+if length(ind) == 0,
+  filename = [filename, '.coef'];
+end
+
+% detect mode based on file extention
+[PATHSTR,NAME,EXT] = fileparts(filename);
+switch EXT
+  case '.h'
+    mode = 'h-file';
+    plik = fopen(filename, 'wt');
+
+  case '.coef'
+    mode = 'coefs-file';
+    plik = fopen(filename, 'wb');
+
+  otherwise
+    mode = 'unknown-file';
+    error(mode);
+end
+
+switch mode
+  case 'h-file'
+    fprintf(plik, '// save_filter_coef output (hard coded coefficients)\n');
+    fprintf(plik, '#pragma once\n');
+    fprintf(plik, '#include <DSP_lib.h>\n');
+    fprintf(plik, '\n');
+    
+    if isfield(coefficients, 'h'),
+      h = coefficients.h;
+      
+      for ind_h = 0:length(h)-1
+        fprintf(plik, 'DSP_float_vector Farrow_coefs_row_%i = {', ind_h);
+        h_tmp = h{ind_h+1};
+        for ind_p = 0:length(h_tmp)-1,
+          if ind_p > 0
+            fprintf(plik, ', ');
+          end
+          fprintf(plik, '%.15ff', h_tmp(ind_p+1));
+        end
+        %0.1f, 0.2f, 0.1f
+        fprintf(plik, '};\n');
+      end
+      fprintf(plik, '\n');
+      
+      %vector <DSP_float_vector> Farrow_coefs = { coefs_0, coefs_1, coefs_2 };
+      fprintf(plik, 'vector <DSP_float_vector> Farrow_coefs = {');
+      for ind_h = 0:length(h)-1
+        if ind_h > 0
+          fprintf(plik, ', ');
+        end
+        if (ind_h < length(h_tmp)) & (rem(ind_h, 5) == 0)
+          fprintf(plik, '\n    ');
+        end
+        fprintf(plik, 'Farrow_coefs_row_%i', ind_h);
+      end
+      fprintf(plik, '\n  };\n');
+      
+      fprintf(plik, '\n');
+      fprintf(plik, 'const unsigned int p_Farrow = %i; // should be equal to Farrow_coefs[0].size()-1\n', length(h{1})-1);
+      fprintf(plik, 'const unsigned int N_FSD = %i; // should be equal to Farrow_coefs.size()\n', length(h));
+    end
+   
+    if isfield(coefficients, 'b'),
+      fclose all;
+      error('unsupported: coefficients.b');
+    end
+    if isfield(coefficients, 'a'),
+      fclose all;
+      error('unsupported: coefficients.a');
+    end
+    
+  case 'coefs-file'
+    %  *  - (uchar) 1B - file version number
+    fwrite(plik, file_version, 'uchar');
+
+    switch file_version,
+      case 0,
+      case 1,
+        %  *  - (uint) 4B - Sampling frequency
+        if isfield(coefficients, 'Fp'),
+          fwrite(plik, coefficients.Fp, 'uint32');
+        else
+          fclose(plik);
+          error('Input data does not contain Fp');
+        end
+      otherwise,
+        fclose(plik);
+        error('This version of coefficients file is unsupported');
+    end
+
+    if isfield(coefficients, 'h'),
+      isFIR = 1;
+      if iscell(coefficients.h)
+        resp_no = length(coefficients.h);
+    %     if resp_no = 1;
+    %       coefficients.h = coefficients.h{1};
+    %     end
+      else
+        resp_no = 1;
+      end
+      if resp_no == 1,
+        isComplex = any(imag(coefficients.h(:)));
+      else
+        isComplex = false;
+        for ind_resp = 1:resp_no,
+          isComplex = isComplex | any(imag(coefficients.h{ind_resp}(:)));
+        end
+      end
+    else
+      isFIR = 0;
+      isComplex = any(imag(coefficients.a(:))) | any(imag(coefficients.b(:)));
+    end
+
+    %  *  -  data - coefficients data (depends on fle version)
+    %  *  .
+    %  *  Data segment format:
+    %  *  -# (version: 0x00)
+    %  *   -  (uchar) 1B - number of sample dimensions
+    %  *         1 - real, 2 - complex, ...
+    if isComplex,
+      fwrite(plik, 2, 'uchar'); % complex
+    else
+      fwrite(plik, 1, 'uchar'); % real
+    end
+    %  *   -  (uchar) 1B - sample component type
+    %  *    - DSP_FT_float (=1) : C++ float (32bit floating point)
+    %  *    - DSP_FT_short (=2) : C++ short (16bit signed integer)
+    %  *    - DSP_FT_uchar (=3) : C++ unsigned char (8bit unsigned integer with bias (0x80))
+    %  *    - DSP_FT_double (=7) : C++ double (64bit floating point)
+    %  *    - DSP_FT_long_double (=8) : C++ long double (80bit floating point)
+    fwrite(plik, 1, 'uchar');
+
+    %  *   -  (uchar) 1B - number of vectors
+    %  *    -   1 - FIR filter coefficients (one vector)
+    %  *    -   2 - IIR filter coefficients (two vectors)
+    %  *   -  (x number of vectors)
+    %  *    -   (ushort) 2B - number of samples in vector
+    %  *    -   (x number of samples)
+    %  *      -   (x number of sample dimensions)
+    %  *       -    (sample componet type) xB - sample component
+    %  *               e.g. real, imag part
+    if isFIR,
+      fwrite(plik, resp_no, 'uchar');
+
+      if iscell(coefficients.h)
+        for ind_resp = 1:resp_no,
+          N_FIR = length(coefficients.h{ind_resp});
+          fwrite(plik, N_FIR, 'uint16');
+          if isComplex,
+            dane(1:2:2*N_FIR) = real(coefficients.h{ind_resp});
+            dane(2:2:2*N_FIR) = imag(coefficients.h{ind_resp});
+            fwrite(plik, dane, 'float');
+          else
+            fwrite(plik, real(coefficients.h{ind_resp}), 'float');
+          end
+        end
+      else
+        N_FIR = length(coefficients.h);
+        fwrite(plik, N_FIR, 'uint16');
+        if isComplex,
+          dane(1:2:2*N_FIR) = real(coefficients.h);
+          dane(2:2:2*N_FIR) = imag(coefficients.h);
+          fwrite(plik, dane, 'float');
+        else
+          fwrite(plik, real(coefficients.h), 'float');
+        end
+      end
+
+    else
+      fwrite(plik, 2, 'uchar');
+
+      N_a = length(coefficients.a);
+      fwrite(plik, N_a, 'uint16');
+      if isComplex,
+        dane(1:2:2*N_a) = real(coefficients.a);
+        dane(2:2:2*N_a) = imag(coefficients.a);
+        fwrite(plik, dane, 'float');
+      else
+        fwrite(plik, real(coefficients.a), 'float');
+      end
+
+
+      N_b = length(coefficients.b);
+      fwrite(plik, N_b, 'uint16');
+      if isComplex,
+        dane(1:2:2*N_b) = real(coefficients.b);
+        dane(2:2:2*N_b) = imag(coefficients.b);
+        fwrite(plik, dane, 'float');
+      else
+        fwrite(plik, real(coefficients.b), 'float');
+      end
+    end
+
+end
+fclose(plik);
+
diff --git a/Ex4/matlab/test1_11025.wav b/Ex4/matlab/test1_11025.wav
new file mode 100644
index 0000000000000000000000000000000000000000..a47f814892bd68c7eb58e32d6c1502b956d20c9f
GIT binary patch
literal 22094
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
YD$i9(O!0U=1Xq*Co^L63<w0=&2R&51VE_OC

literal 0
HcmV?d00001

diff --git a/Ex4/matlab/test2_11025.wav b/Ex4/matlab/test2_11025.wav
new file mode 100644
index 0000000000000000000000000000000000000000..04b882f23c78f86cdc6f6939b1d3ab256f70bbc5
GIT binary patch
literal 22094
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%0DI
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
UJjn<CJpBg>JUa(m<5-^m1H$3D?*IS*

literal 0
HcmV?d00001

diff --git a/Ex4/matlab/test_signal.wav b/Ex4/matlab/test_signal.wav
new file mode 100644
index 0000000000000000000000000000000000000000..51a5040ccd128813e34dbea06c96952f494151c2
GIT binary patch
literal 16044
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

literal 0
HcmV?d00001

diff --git a/Ex4/rundot.bat b/Ex4/rundot.bat
new file mode 100644
index 0000000..30e8d91
--- /dev/null
+++ b/Ex4/rundot.bat
@@ -0,0 +1,4 @@
+path = "D:\Program Files (x86)\Graphviz\bin";%path%
+
+del Ex4_task2.gif
+dot -Tgif Ex4_task2.dot -oEx4_task2.gif
-- 
GitLab