From 9ab782d3943fd19cdce64af067a0974df2adcc65 Mon Sep 17 00:00:00 2001 From: Marek Blok <Marek.Blok@pg.edu.pl> Date: Fri, 9 Apr 2021 11:51:57 +0200 Subject: [PATCH] Improvements + EN --- .gitignore | 10 +- Cw1/.vscode/launch.json | 6 +- Cw1/.vscode/tasks.json | 6 +- Cw1/Cw1_zad3.cpp | 129 -------- Cw1/{Cw1_zad3.cbp => Ex1_task3.cbp} | 6 +- Cw1/Ex1_task3.cpp | 125 ++++++++ Cw1/Makefile | 6 +- Cw1/Makefile.main | 2 +- Cw1/{zad_1_syg_1.wav => ex_1_sig_1.wav} | Bin Cw1/{zad_1_syg_2.wav => ex_1_sig_2.wav} | Bin Cw1/matlab/design_task_2.m | 28 ++ Cw1/matlab/design_zad_2.m | 28 -- Cw1/matlab/{cw1_zad2.coef => ex1_task2.coef} | Bin Cw1/matlab/{fileread.m => readaudiofile.m} | 16 +- Cw1/matlab/readme.txt | 4 +- Cw1/matlab/save_filter_coef.m | 302 ++++++++++++------- Cw1/rundot.bat | 4 +- 17 files changed, 371 insertions(+), 301 deletions(-) delete mode 100644 Cw1/Cw1_zad3.cpp rename Cw1/{Cw1_zad3.cbp => Ex1_task3.cbp} (87%) create mode 100644 Cw1/Ex1_task3.cpp rename Cw1/{zad_1_syg_1.wav => ex_1_sig_1.wav} (100%) rename Cw1/{zad_1_syg_2.wav => ex_1_sig_2.wav} (100%) create mode 100644 Cw1/matlab/design_task_2.m delete mode 100644 Cw1/matlab/design_zad_2.m rename Cw1/matlab/{cw1_zad2.coef => ex1_task2.coef} (100%) rename Cw1/matlab/{fileread.m => readaudiofile.m} (93%) diff --git a/.gitignore b/.gitignore index d6ba61b..de23a0c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ -Cw1/Cw1_zad3_dbg.exe -Cw1/Cw1_zad3_rls.exe -Cw1/Cw1_zad3.dot -Cw1/Cw1_zad3.gif -Cw1/cw1_zad3.wav +Cw1/Ex1_task3_dbg.exe +Cw1/Ex1_task3_rls.exe +Cw1/Ex1_task3.dot +Cw1/Ex1_task3.gif +Cw1/ex1_task3.wav Cw1/log_file.txt Cw1/out_win_dbg Cw1/out_win_rls diff --git a/Cw1/.vscode/launch.json b/Cw1/.vscode/launch.json index 70221b6..c36eb40 100644 --- a/Cw1/.vscode/launch.json +++ b/Cw1/.vscode/launch.json @@ -5,10 +5,10 @@ "version": "0.2.0", "configurations": [ { - "name": "(gdb) Cw1 â debug run ", + "name": "(gdb) Ex1 â debug run ", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/Cw1_zad3_dbg.exe", + "program": "${workspaceFolder}/Ex1_task3_dbg.exe", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", @@ -23,7 +23,7 @@ "ignoreFailures": true } ], - "preLaunchTask": "Build Cw1" + "preLaunchTask": "Build Ex1_task3.cpp" }, { "name": "(gdb) Launch", diff --git a/Cw1/.vscode/tasks.json b/Cw1/.vscode/tasks.json index 87f7221..48a340b 100644 --- a/Cw1/.vscode/tasks.json +++ b/Cw1/.vscode/tasks.json @@ -6,9 +6,9 @@ // ${command:cpptools.activeConfigName} "tasks": [ { - "label": "Build Cw1", + "label": "Build Ex1_task3.cpp", "type": "shell", - "command": "make build -f Makefile.main VS_CFG=${command:cpptools.activeConfigName}", + "command": "make build -f Makefile.main FILE=Ex1_task3 VS_CFG=${command:cpptools.activeConfigName}", "group": { "kind": "build", "isDefault": true @@ -19,7 +19,7 @@ "problemMatcher": "$gcc" }, { - "label": "Clean Cw1", + "label": "Clean Ex1_task3.cpp", "type": "shell", "command": "make clean -f Makefile.main VS_CFG=${command:cpptools.activeConfigName}", "group": "build", diff --git a/Cw1/Cw1_zad3.cpp b/Cw1/Cw1_zad3.cpp deleted file mode 100644 index 1c4986d..0000000 --- a/Cw1/Cw1_zad3.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/*! Laboratorium: Zaawansowane przetwarzanie sygnaĹĂłw telekomunikacji cyfrowej - * Äw. 1. zad. 3. - * - wczytanie z pliku odpowiedzi impulsowej filtru - * (skrypt generujÄ cy plik danych: ./matlab/design_zad_2.m - * - klasyczny interpolator L = 2 - * - * \author Marek Blok - * \date 2018.03.01 - */ -#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() << std::endl << std::endl; - /*************************************************************/ - - DSP::LoadCoef coef_info; - int N_LPF; - DSP::Float_vector h_LPF; - - // wczytanie wspó³czynnikĂłw z pliku matlab/cw1_zad2.coef - coef_info.Open("cw1_zad2.coef", "matlab"); - N_LPF = coef_info.GetSize(0); // odczytanie liczby wspó³czynnikĂłw pierwszeego wektora (indeksowanie od zera) - if (N_LPF < 1) - { - DSP::log << DSP::e::LogMode::Error << "No filter coefficients: aboarding" << std::endl; - return -1; - } - else - { - // wczytanie N_LPF wspó³czynnikĂłw do tablicy h_LPF - coef_info.Load(h_LPF); - } - /*************************************************************/ - - DSP::Clock_ptr MasterClock; - // Pozyskanie wskazania do g³ównego zegara algorytmu - MasterClock=DSP::Clock::CreateMasterClock(); - - long int Fp1, Fp2; - - // ŸrĂłdÂło prĂłbek: plik ./test.wav (bie¿šcy katalog) - DSP::u::WaveInput AudioIn(MasterClock, "test.wav", "."); - // odczytanie szybkoĹci prĂłbkowania pliku powišzanego z bloczkiem AudioIn - Fp1 = AudioIn.GetSamplingRate(); - - Fp2 = 2*Fp1; - // dwukrotny zeroinserter z wejĹciem pracujšcym w rytm zegara MasterClock - DSP::u::Zeroinserter Zeroinserter(MasterClock, 2U); - // przykÂład dodania tekstu do domyslnej nazwy bloczka (dla pliku *.dot) - Zeroinserter.SetName("x2"); - - // filtr typu FIR o rzeczywistych wspó³czynnikach odpowiedzi impulsowej (tutaj filtr interpolacyjny) - // dÂługoĹĂŚ odpowiedzi impulsowej N_LPF, prĂłbki odpowiedzi impulsowej w tablicy h_LPF - DSP::u::FIR InterpFIR(h_LPF); - - // wyjĹcie na kartĂŞ dŸwiĂŞkowš - szybkoĹĂŚ prĂłbkowania Fp2 (mono/16bit) - DSP::u::AudioOutput SoundOut(Fp2, 1, 16); - // zapis do pliku *.wav (mono/16bit, szybkosĂŚ prĂłbkowania Fp2) - DSP::u::FileOutput FileOut("cw1_zad3.wav", DSP::e::SampleType::ST_short, 1, DSP::e::FileType::FT_wav, Fp2); - - /*************************************************************/ - // Definicje po³šczeĂą pomiĂŞdzy bloczkami - // wyjĹcie "out" bloczka AudioIn ³šczymy w wejĹciem "in" bloczka Zeroinserter - AudioIn.Output("out") >> Zeroinserter.Input("in"); - // wyjĹcie "out" bloczka Zeroinserter ³šczymy w wejĹciem "in" bloczka InterpFIR - Zeroinserter.Output("out") >> InterpFIR.Input("in"); - // wyjĹcie "out" bloczka InterpFIR ³šczymy w wejĹciem "in" bloczka SoundOut - InterpFIR.Output("out") >> SoundOut.Input("in"); - // wyjĹcie "out" bloczka InterpFIR ³šczymy w wejĹciem "in" bloczka FileOut - // Uwaga: jedno wyjĹcie moÂżna pod³šczyĂŚ do kilku wejĹĂŚ ale nie moÂżna - // pod³šczyĂŚ kilku wyjĹĂŚ do jednego wejĹcia - InterpFIR.Output("out") >> FileOut.Input("in"); - - - ///////////////////////////////// - // sprawdzenie, czy do wszystkich wejsĂŚ, wszystkich bloczkĂłw pod³šczone sš sygnaÂły wejsciowe - DSP::Component::CheckInputsOfAllComponents(); - - // *********************************** // - // Zapis schematu zaimplementowanego algorytmu do pliku *.dot - // (przetworzenie do pliku *.gif skryptem rundot.bat) - DSP::Clock::SchemeToDOTfile(MasterClock, "Cw1_zad3.dot"); - - // *********************************** // - // przetwarzany w blokach po SamplesInSegment prĂłbek wejsciowych - int SamplesInSegment = 512; - - // licznik przetworzonych prĂłbek wejsciowych - __int64 NoOfSamplesProcessed = 0; - - // Maksymalna liczba przetwarzanych prĂłbek wejsciowych (10 sekund) - #define MAX_SAMPLES_TO_PROCESS 10*Fp1 - - while(NoOfSamplesProcessed < MAX_SAMPLES_TO_PROCESS) - { - - // ********************************************************** // - // uruchom zaimplementowany algorytm na SamplesInSegment cykli zegara MasterClock - DSP::Clock::Execute(MasterClock, SamplesInSegment); - // ********************************************************** // - - if (AudioIn.GetBytesRead() > 0) - { // resetuj licznik przetworzonych prĂłbek jeÂżeli udaÂło siĂŞ odczytaĂŚ prĂłbki z pliku - // - wymusza przetworzenie caÂłego pliku wejsciowego - NoOfSamplesProcessed = 0; - } - else // Play 200ms more - { // jeÂżeli nie odczytano prĂłbek z pliku wejsciowego to przetwĂłrz jeszcze tylko 1/5 sekundy - if (NoOfSamplesProcessed < MAX_SAMPLES_TO_PROCESS - Fp1/5) - NoOfSamplesProcessed = MAX_SAMPLES_TO_PROCESS - Fp1/5; - } - - NoOfSamplesProcessed += SamplesInSegment; - // ********************************************************** // - } - - /*************************************************************/ - // Zwolnienie zarezerwowanych zasobĂłw - DSP::Clock::FreeClocks(); - /*************************************************************/ - - return 0; -} diff --git a/Cw1/Cw1_zad3.cbp b/Cw1/Ex1_task3.cbp similarity index 87% rename from Cw1/Cw1_zad3.cbp rename to Cw1/Ex1_task3.cbp index 4d61cab..37f8ce3 100644 --- a/Cw1/Cw1_zad3.cbp +++ b/Cw1/Ex1_task3.cbp @@ -2,12 +2,12 @@ <CodeBlocks_project_file> <FileVersion major="1" minor="6" /> <Project> - <Option title="Cw1_zad3" /> + <Option title="Ex1_task3" /> <Option pch_mode="2" /> <Option compiler="gcc" /> <Build> <Target title="default"> - <Option output="Cw1_zad3" prefix_auto="1" extension_auto="1" /> + <Option output="Ex1_task3" prefix_auto="1" extension_auto="1" /> <Option type="1" /> <Option compiler="gcc" /> </Target> @@ -27,7 +27,7 @@ <Add library="winmm" /> <Add directory="../DSPElib/CodeBlocks-m32_TDM_5.1.0/dbg" /> </Linker> - <Unit filename="Cw1_zad3.cpp" /> + <Unit filename="Ex1_task3.cpp" /> <Extensions> <code_completion /> <envvars /> diff --git a/Cw1/Ex1_task3.cpp b/Cw1/Ex1_task3.cpp new file mode 100644 index 0000000..17321af --- /dev/null +++ b/Cw1/Ex1_task3.cpp @@ -0,0 +1,125 @@ +/*! Laboratory: Advanced signal processing of telecommunication signals + * (Zaawansowane przetwarzanie sygnaĹĂłw telekomunikacji cyfrowej) + * Ex. 1. task 3. + * - impulse response loaded from file + * (data generated with script: ./matlab/design_task_2.m) + * - classical interpolator L = 2 + * + * \author Marek Blok + * \date 2021.04.09 + */ +#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() << std::endl << std::endl; + /*************************************************************/ + + DSP::LoadCoef coef_info; + int N_LPF; + DSP::Float_vector h_LPF; + + // loading coefficients from file matlab/ex1_task2.coef + coef_info.Open("ex1_task2.coef", "matlab"); + N_LPF = coef_info.GetSize(0); // read number of coefficients of first vector (index starts form zero) + if (N_LPF < 1) + { + DSP::log << DSP::e::LogMode::Error << "No filter coefficients: aborting" << std::endl; + return -1; + } + else + { + // Load coefficients to h_LPF vector + coef_info.Load(h_LPF); + } + /*************************************************************/ + + DSP::Clock_ptr MasterClock; + // Get pointer to algorithm's master clock + MasterClock=DSP::Clock::CreateMasterClock(); + + long int Fp1, Fp2; + + // Source of samples: file ./DSPElib.wav (current folder) + DSP::u::WaveInput AudioIn(MasterClock, "DSPElib.wav", "."); + // get sampling rate associated with block AudioIn + Fp1 = AudioIn.GetSamplingRate(); + + Fp2 = 2*Fp1; + // two-fold zeroinserter with input working at rate of MasterClock + DSP::u::Zeroinserter Zeroinserter(MasterClock, 2U); + // example of appending text to the default block's name (for file *.dot) + Zeroinserter.SetName("x2"); + + // FIR filter with real valued impulse response coefficients (here an interpolation filter) + // uses samples from vector h_LPF + DSP::u::FIR InterpFIR(h_LPF); + + // output to the soundcard - sampling rate Fp2 (mono/16bit) + DSP::u::AudioOutput SoundOut(Fp2, 1, 16); + // write to file *.wav (mono/16bit, sampling rate Fp2) + DSP::u::FileOutput FileOut("ex1_task3.wav", DSP::e::SampleType::ST_short, 1, DSP::e::FileType::FT_wav, Fp2); + + /*************************************************************/ + // Blocks connection definitions + // connecting output "out" of block AudioIn with input "in" of Zeroinserter block + AudioIn.Output("out") >> Zeroinserter.Input("in"); + // connecting output "out" of Zeroinserter to input "in" of InterpFIR + Zeroinserter.Output("out") >> InterpFIR.Input("in"); + // connecting output "out" of InterpFIR to input "in" of SoundOut + InterpFIR.Output("out") >> SoundOut.Input("in"); + // connecting output "out" of InterpFIR to input "in" of FileOut + InterpFIR.Output("out") >> FileOut.Input("in"); + // Note: one output can be connected to many inputs but many outputs cannot be conneted to one input + + + ///////////////////////////////// + // Checking if all inputs of all blocks have attached input signals + DSP::Component::CheckInputsOfAllComponents(); + + // *********************************** // + // Saving the scheme of the implemented algorithm to the * .dot file + // (this file can be converted to *.gif using script rundot.bat + // adapt paths in batch file if necessary) + DSP::Clock::SchemeToDOTfile(MasterClock, "Ex1_task3.dot"); + + // *********************************** // + // processing in batches of SamplesInSegment input samples + int SamplesInSegment = 512; + + // counter storing number of input samples processed + int64_t NoOfSamplesProcessed = 0; + + // Maksimum number of input samples to process (200 miliseconds) + #define MAX_SAMPLES_TO_PROCESS Fp1/5 + + while(NoOfSamplesProcessed < MAX_SAMPLES_TO_PROCESS) + { + + // ********************************************************** // + // run the implemented algorithm for the SamplesInSegment of the MasterClock clock cycles + DSP::Clock::Execute(MasterClock, SamplesInSegment); + // ********************************************************** // + + if (AudioIn.GetBytesRead() > 0) + { // reset processed samples counter on successful input file read + // - forces processing of the whole input file + NoOfSamplesProcessed = 0; + } + + NoOfSamplesProcessed += SamplesInSegment; + // ********************************************************** // + } + + /*************************************************************/ + // Releasing reserved resources + DSP::Clock::FreeClocks(); + /*************************************************************/ + + return 0; +} diff --git a/Cw1/Makefile b/Cw1/Makefile index c1b0952..c94c79f 100644 --- a/Cw1/Makefile +++ b/Cw1/Makefile @@ -18,19 +18,19 @@ ifeq ($(MODE),Release) 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 = Cw1_zad3_rls.exe + 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 = Cw1_zad3_dbg.exe + 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 += Cw1_zad3.cpp +SOURCES_NAMES += $(CPP_FILENAME).cpp SOURCES = $(addprefix $(SRC_CPP_SUBDIR)/,$(SOURCES_NAMES)) SOURCES_DBG = diff --git a/Cw1/Makefile.main b/Cw1/Makefile.main index cb3fad5..cf6c368 100644 --- a/Cw1/Makefile.main +++ b/Cw1/Makefile.main @@ -50,7 +50,7 @@ endif build: @echo "Building $(VS_CFG)" @echo $(VS_CFG): $(MODE) // $(MAKEFILE) - make build MODE=$(MODE) COMFLAG=$(COMFLAG) DFLAGS="$(DFLAGS)" LIBS="$(LIBS)" OUT_DIR=$(OUT_DIR) DSPElib_SUBDIR=$(DSPElib_SUBDIR) MISC_LINKER_FLAGS="$(MISC_LINKER_FLAGS)" -f $(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)" diff --git a/Cw1/zad_1_syg_1.wav b/Cw1/ex_1_sig_1.wav similarity index 100% rename from Cw1/zad_1_syg_1.wav rename to Cw1/ex_1_sig_1.wav diff --git a/Cw1/zad_1_syg_2.wav b/Cw1/ex_1_sig_2.wav similarity index 100% rename from Cw1/zad_1_syg_2.wav rename to Cw1/ex_1_sig_2.wav diff --git a/Cw1/matlab/design_task_2.m b/Cw1/matlab/design_task_2.m new file mode 100644 index 0000000..aca9338 --- /dev/null +++ b/Cw1/matlab/design_task_2.m @@ -0,0 +1,28 @@ +function h=design_task_2 + +%interpolation filter +Fp1 = 22050; % input sampling rate +Fp2 = 44100; % output sampling rate +L = 2; % interpolation ratio (Fp2/Fp1) + +% passband ripples +/-0.1 dB, out of band attenuation -96dB +dp = 10.^(0.1/20)-1; +ds = 10.^(-96/20); + +% transition band 10-12kHz, filter works at rate equal to Fp2 +c = firpmord( [10000 12000], [1 0], [dp ds], Fp2, 'cell'); +h = firpm(c{:}); +N= length(h) + +figure(1) +plot(h) +% pause + +figure(2) +freqz(h,1, 8*2048, L*Fp1) + +% writing filter coefficients to file +dane.h = L*h; +dane.Fp = Fp1; +save_filter_coef('ex1_task2', dane); + diff --git a/Cw1/matlab/design_zad_2.m b/Cw1/matlab/design_zad_2.m deleted file mode 100644 index d489173..0000000 --- a/Cw1/matlab/design_zad_2.m +++ /dev/null @@ -1,28 +0,0 @@ -function h=design_zad_2 - -%interpolation filter -Fp1 = 22050; % wejciowa szybkoć próbkowania -Fp2 = 44100; % wyjciowa szybkoć próbkowania -L = 2; % krotnoć interpolacji (Fp2/Fp1) - -% zafalowanie w pasmie +/-0.1 dB, tłumienie poza pasmem -96dB -dp = 10.^(0.1/20)-1; -ds = 10.^(-96/20); - -% Pasmo przejciowe 10-12kHz, filtr pracujšcy na szybkoci Fp2 -c = firpmord( [10000 12000], [1 0], [dp ds], Fp2, 'cell'); -h = firpm(c{:}); -N= length(h) - -figure(1) -plot(h) -% pause - -figure(2) -freqz(h,1, 8*2048, L*Fp1) - -% zapisanie współczynników filtru do pliku -dane.h = L*h; -dane.Fp = Fp1; -save_filter_coef('cw1_zad2', dane); - diff --git a/Cw1/matlab/cw1_zad2.coef b/Cw1/matlab/ex1_task2.coef similarity index 100% rename from Cw1/matlab/cw1_zad2.coef rename to Cw1/matlab/ex1_task2.coef diff --git a/Cw1/matlab/fileread.m b/Cw1/matlab/readaudiofile.m similarity index 93% rename from Cw1/matlab/fileread.m rename to Cw1/matlab/readaudiofile.m index 850c7b1..3a87be2 100644 --- a/Cw1/matlab/fileread.m +++ b/Cw1/matlab/readaudiofile.m @@ -1,5 +1,5 @@ -function [x, Fs] = fileread(filename, param) -% [x, Fs] = fileread(filename, param) +function [x, Fs] = readaudiofile(filename, param) +% [x, Fs] = audiofileread(filename, param) % % returns vector x of the size SIZE=[samples channels]. % eg. x = x(:,1) + j*x(:,2); @@ -12,7 +12,7 @@ function [x, Fs] = fileread(filename, param) % *.flt % *.wav % *.tape -% last modification: 2018.03.05 +% last modification: 2021.03.29 % Author: Marek Blok return_cplx = 0; @@ -46,22 +46,26 @@ end switch file_type, case 'w', if strcmp(param, 'size') == 1, - if exist('audioread','file') ~= 2 + 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') ~= 2 + 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') ~= 2 + if exist('audioread','file') == 0 [x, Fs] = wavread(filename); else [x, Fs] = audioread(filename); diff --git a/Cw1/matlab/readme.txt b/Cw1/matlab/readme.txt index 143af97..30b97d5 100644 --- a/Cw1/matlab/readme.txt +++ b/Cw1/matlab/readme.txt @@ -1,2 +1,2 @@ -wavread('../cw1_zad3.wav') -fileread('../cw1_zad3.wav') \ No newline at end of file +audioread('../ex1_task3.wav') +readaudiofile('../ex1_task3.wav') \ No newline at end of file diff --git a/Cw1/matlab/save_filter_coef.m b/Cw1/matlab/save_filter_coef.m index 6931fa1..8cf1f07 100644 --- a/Cw1/matlab/save_filter_coef.m +++ b/Cw1/matlab/save_filter_coef.m @@ -10,147 +10,217 @@ function save_filter_coef(filename, coefficients, file_version) % coefficients.a % coefficients.b % -% For table of vectors see FIR filter coefficients above. -% % 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 2008.03.19 +% \date 2020.02.22 if nargin == 2, file_version = 0; end -% /*! File format (*.coef) - this is open format, for general use -% * (not only for storing coefficients) -% * ind = find(filename == '.'); if length(ind) == 0, filename = [filename, '.coef']; end -plik = fopen(filename, 'wb'); -% * - (uchar) 1B - file version number -fwrite(plik, file_version, 'uchar') +% detect mode based on file extention +[PATHSTR,NAME,EXT] = fileparts(filename); +switch EXT + case '.h' + mode = 'h-file'; + plik = fopen(filename, 'wt'); -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'); + case '.coef' + mode = 'coefs-file'; + plik = fopen(filename, 'wb'); + + otherwise + mode = 'unknown-file'; + error(mode); 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}(:))); +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 - end -else - isFIR = 0; - isComplex = any(imag(coefficients.a(:))) | any(imag(coefficients.b(:))); -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'); -% * - 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'); + 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 - fwrite(plik, real(coefficients.h{ind_resp}), 'float'); + 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 - else - N_FIR = length(coefficients.h); - fwrite(plik, N_FIR, 'uint16'); + + % * - data - coefficients data (depends on fle version) + % * . + % * Data segment format: + % * -# (version: 0x00) + % * - (uchar) 1B - number of sample dimensions + % * 1 - real, 2 - complex, ... if isComplex, - dane(1:2:2*N_FIR) = real(coefficients.h); - dane(2:2:2*N_FIR) = imag(coefficients.h); - fwrite(plik, dane, 'float'); + fwrite(plik, 2, 'uchar'); % complex else - fwrite(plik, real(coefficients.h), 'float'); + fwrite(plik, 1, 'uchar'); % real 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 + % * - (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/Cw1/rundot.bat b/Cw1/rundot.bat index 1aacf51..5e24fef 100644 --- a/Cw1/rundot.bat +++ b/Cw1/rundot.bat @@ -1,4 +1,4 @@ path = "D:\Program Files (x86)\Graphviz\bin";%path% -del Cw1_zad3.gif -dot -Tgif Cw1_zad3.dot -oCw1_zad3.gif +del Ex1_task3.gif +dot -Tgif Ex1_task3.dot -oEx1_task3.gif -- GitLab