diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
index 992d0b314bad02d6a9224b21e28acda0e09532c7..095e7fc7f995eff09683030f2b14492c52b09a15 100644
--- a/.vscode/c_cpp_properties.json
+++ b/.vscode/c_cpp_properties.json
@@ -36,7 +36,8 @@
             ],
             "defines": [
                 "WIN32",
-                "__DEBUG__=1"
+                "__DEBUG__=1",
+                "INCLUDE_DSPE_EXAMPLES"
             ],
             "compilerPath": "gcc.exe",
             "cStandard": "c11",
@@ -50,7 +51,8 @@
             ],
             "defines": [
                 "WIN32",
-                "__DEBUG__=1"
+                "__DEBUG__=1",
+                "INCLUDE_DSPE_EXAMPLES"
             ],
             "compilerPath": "gcc.exe",
             "cStandard": "c11",
diff --git a/CHANGELOG b/CHANGELOG
index 766bdcc19125bc3baff146103ddc4a7e271773fb..00975c44a21584c9faf88164aff64be62e740f9a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,9 @@ TODO::
 LAST DONE:
 
 CHANGES:
+- ver. 0.20.006 - <b>2021.05.14</b> Changed: 
+  - Included examples tests in DEBUG compilation for windows (test_hello, test_sound_input)
+  - DSP::u::AudioInput now uses SOUND_object_t (currently just WMM_object_t) for soundcard API
 
 - ver. 0.20.005 - <b>2021.04.21</b> Changed: 
   - Added ALSA tests in main.cpp and Launch configuration for Linux
diff --git a/examples/DSPE_examples.h b/examples/DSPE_examples.h
index 1c7ac473dc47f5d17e553d1aeb6b5cf707292819..5bd1f3c5e2806f862dd60ed578223c15d34de1ec 100644
--- a/examples/DSPE_examples.h
+++ b/examples/DSPE_examples.h
@@ -9,6 +9,7 @@
 #define EXAMPLES_DSPE_EXAMPLES_H_
 
 int test_hello(void);
+int test_sound_input(void);
 
 
 #endif /* EXAMPLES_DSPE_EXAMPLES_H_ */
diff --git a/examples/hello.cpp b/examples/hello.cpp
index 5f1bfaf6e3723c2926aa59e602383e4ed3b3aa0c..2e0fcc5ea9a29f7bf9c58e60b6bca35dd8cb7045 100644
--- a/examples/hello.cpp
+++ b/examples/hello.cpp
@@ -5,12 +5,12 @@
  */
 #include <DSP_lib.h>
 
-#ifndef _DSPE_TEST_
+#ifndef INCLUDE_DSPE_EXAMPLES
 int main(void)
 #else
 #include "DSPE_examples.h"
 int test_hello(void)
-#endif // _DSPE_TEST_
+#endif // INCLUDE_DSPE_EXAMPLES
 {
   DSP::Clock_ptr MasterClock;
   string tekst;
diff --git a/examples/sound_input.cpp b/examples/sound_input.cpp
index f1f1bc5c187a872a2f70d40390d59ef0404fd4ff..e15d363e1afee5af3f9895d1ae5731608e7b50b1 100644
--- a/examples/sound_input.cpp
+++ b/examples/sound_input.cpp
@@ -5,12 +5,12 @@
  */
 #include <DSP_lib.h>
 
-#ifndef _DSPE_TEST_
+#ifndef INCLUDE_DSPE_EXAMPLES
 int main(void)
 #else
 #include "DSPE_examples.h"
 int test_sound_input(void)
-#endif // _DSPE_TEST_
+#endif // INCLUDE_DSPE_EXAMPLES
 {
   DSP::Clock_ptr MasterClock, AudioInClock;
   string tekst;
diff --git a/src/Main.cpp b/src/Main.cpp
index d18918ac15e631b58c7d3a805e5ec0936d86714b..2b929e35bf3faeda3abd3f8e32b4f7b92504cc9a 100644
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -2931,9 +2931,8 @@ int main(int argc, char*argv[])
   DSP::log.SetLogState(DSP::e::LogState::console | DSP::e::LogState::file);
   DSP::log.SetLogFileName("DSPElib_test_log.txt");
 
-  DSP::log << "test ALSA" << endl;
-
   #ifdef ALSA_support_H
+    DSP::log << "test ALSA" << endl;
     test_ALSA();
     return 0;
   #endif // ALSA_support_H
@@ -2952,6 +2951,16 @@ int main(int argc, char*argv[])
   //! \TODO test also DSP::f::LPF_LS
   DSP::log << DSP::e::LogMode::pause << "Finished SolveMatrix test" << endl;
 
+#ifdef INCLUDE_DSPE_EXAMPLES
+  DSP::log << "Starting test_sound_input" << endl;
+  test_sound_input();
+  DSP::log << DSP::e::LogMode::Error << "Finished test_sound_input" << endl;
+
+  DSP::log << "Starting test_hello" << endl;
+  test_hello();
+  DSP::log << DSP::e::LogMode::Error << "Finished test_hello" << endl;
+#endif // INCLUDE_DSPE_EXAMPLES
+
   DSP::log << "Starting SymbolMapper test" << endl;
   test_SymbolMapper();
   DSP::log << DSP::e::LogMode::pause << "Finished SymbolMapper test" << endl;
@@ -2960,12 +2969,6 @@ int main(int argc, char*argv[])
   test_ZPSTC_cw_3();
   DSP::log << "Finished test_ZPSTC_cw_3" << DSP::e::LogMode::pause << endl;
 
-#ifdef INCLUDE_DSPE_EXAMPLES
-  DSP::log << "Starting test_hello" << endl;
-  test_hello();
-  DSP::log << DSP::e::LogMode::Error << "Finished test_hello" << endl;
-#endif // INCLUDE_DSPE_EXAMPLES
-
   DSP::log << "Starting test_1" << endl;
   test_1(argc, argv);
   DSP::log << DSP::e::LogMode::pause << "Finished test_1" << endl;
diff --git a/src/Makefile.linux b/src/Makefile.linux
index b7524fb5a32ef0a37b878f880b01b3137aeb2b3f..bb16c0b9281101061af641e25dcaa040bf244533 100644
--- a/src/Makefile.linux
+++ b/src/Makefile.linux
@@ -23,7 +23,7 @@ INCLUDES_RLS := -I./src/include -I./src/include/rls
 LIBS := -lasound
 
 # \TODO is DEVCPP ok or is it unnecessary
-DFLAGS         = -DLINUX -DDEVCPP 
+DFLAGS         = -DLINUX -DDEVCPP -DINCLUDE_DSPE_EXAMPLES
 CFLAGS_release = $(comflag) -std=c++0x -O3 -Wall -c -fmessage-length=0 -fno-strict-aliasing 
 CFLAGS_debug   = $(comflag) -std=c++0x -O0 -g3 -Wall -c -fmessage-length=0 -W -Wshadow -Wconversion -fstrict-aliasing -fmax-errors=5
 # -U__STRICT_ANSI__ jest potrzebne do kompilacji debug_new.cpp, je�eli pomin�� ten plik to mo�na r�wnie� wyrzuci� t� opcj�
diff --git a/src/Makefile.win b/src/Makefile.win
index 295ad8175c528e1e3693b860bf2458f9215f1ec5..bb7bcb6ce710fb66128a904a3c3889fa9841a236 100644
--- a/src/Makefile.win
+++ b/src/Makefile.win
@@ -11,6 +11,7 @@ com_ver = MinGW-W64_8.1.0
 INSTALL_DIR_ROOT = ../_DSPE_lib_minGW_
 
 SRC_DIR = ./src
+SRC_EXAMPLES_DIR = ./examples
 SRC_CPP_SUBDIR = $(SRC_DIR)/cpp
 
 OUT_DIR_RLS = ./out_win_rls
@@ -21,7 +22,7 @@ INCLUDES_DBG := -I"$(SRC_DIR)/include" -I"$(SRC_DIR)/include/dbg"
 INCLUDES_RLS := -I"$(SRC_DIR)/include" -I"$(SRC_DIR)/include/rls"
 LIBS := -lwinmm -lws2_32
 
-DFLAGS         = -DWIN32 -DDEVCPP 
+DFLAGS         = -DWIN32 -DDEVCPP -DINCLUDE_DSPE_EXAMPLES
 # -D INCLUDE_DSPE_EXAMPLES # TODO: uĹźycie w ramach kompilacji Main.cpp w trybie DEBUG
 CFLAGS_release = $(comflag) -std=c++0x -O3 -Wall -c -fmessage-length=0 -fno-strict-aliasing 
 CFLAGS_debug   = $(comflag) -std=c++0x -O0 -g3 -Wall -c -fmessage-length=0 -W -Wshadow -Wconversion -fstrict-aliasing -fmax-errors=5
@@ -36,7 +37,10 @@ SOURCES_NAMES += DSP_DOT.cpp DSP_modules_misc.cpp DSP_IO.cpp DSP_logstream.cpp W
 SOURCES = $(addprefix $(SRC_CPP_SUBDIR)/,$(SOURCES_NAMES))
 
 SOURCES_DBG =
-SOURCES_DBG += $(SRC_DIR)/Main.cpp
+SOURCES_DBG += $(SRC_DIR)/Main.cpp 
+
+SOURCES_EXAMPLES_DBG =
+SOURCES_EXAMPLES_DBG += $(SRC_EXAMPLES_DIR)/hello.cpp $(SRC_EXAMPLES_DIR)/sound_input.cpp 
 
 # ################################################# #
 # Just sockets
@@ -56,12 +60,14 @@ DEPENDS_SOCKETS_Release := $(DEPENDS_SOCKETS:%.cpp=$(OUT_DIR_RLS)/%.d)
 
 # ################################################# #
 # DEBUG
-OBJECTS_Debug 		  := $(SOURCES:%.cpp=$(OUT_DIR_DBG)/%.o)
-DEPENDS_Debug 		  := $(SOURCES:%.cpp=$(OUT_DIR_DBG)/%.d)
-OBJECTS_Debug 		  += $(SOURCES_DBG:%.cpp=$(OUT_DIR_DBG)/%.o)
-DEPENDS_Debug 		  += $(SOURCES_DBG:%.cpp=$(OUT_DIR_DBG)/%.d)
-OBJECTS_SOCKETS_Debug := $(SOURCES_SOCKETS:%.cpp=$(OUT_DIR_DBG)/%.o)
-DEPENDS_SOCKETS_Debug := $(SOURCES_SOCKETS:%.cpp=$(OUT_DIR_DBG)/%.d)
+OBJECTS_Debug 		   := $(SOURCES:%.cpp=$(OUT_DIR_DBG)/%.o)
+DEPENDS_Debug 		   := $(SOURCES:%.cpp=$(OUT_DIR_DBG)/%.d)
+OBJECTS_Debug 		   += $(SOURCES_DBG:%.cpp=$(OUT_DIR_DBG)/%.o)
+DEPENDS_Debug 		   += $(SOURCES_DBG:%.cpp=$(OUT_DIR_DBG)/%.d)
+OBJECTS_EXAMPLES_Debug := $(SOURCES_EXAMPLES_DBG:%.cpp=$(OUT_DIR_DBG)/%.o)
+DEPENDS_EXAMPLES_Debug := $(SOURCES_EXAMPLES_DBG:%.cpp=$(OUT_DIR_DBG)/%.d)
+OBJECTS_SOCKETS_Debug  := $(SOURCES_SOCKETS:%.cpp=$(OUT_DIR_DBG)/%.o)
+DEPENDS_SOCKETS_Debug  := $(SOURCES_SOCKETS:%.cpp=$(OUT_DIR_DBG)/%.d)
 
 # SRC_DBG_SUBDIR = nvwa
 # SOURCES_MISC_Debug += debug_new.cpp
@@ -72,7 +78,8 @@ OBJECTS_MISC_Debug :=
 -include $(DEPENDS_Release)
 -include $(DEPENDS_SOCKETS_Release)
 -include $(DEPENDS_Debug)
--include $(DEPENDS_SOCKETS_Debug)
+-include $(DEPENDS_SOCKETS_Release)
+-include $(DEPENDS_EXAMPLES_Debug)
 
 all: Debug Release
 
@@ -101,11 +108,11 @@ $(OBJECTS_Release) $(OBJECTS_SOCKETS_Release): $(OUT_DIR_RLS)/%.o : %.cpp
 
 # ########################################################################################### #	
 # ########################################################################################### #	
-# Debug: $(OUT_DIR_DBG)/libDSPE.a $(OUT_DIR_DBG)/libDSPEsockets.a
+# Debug: $(OUT_DIR_DBG)/libDSPE.a $(OUT_DIR_DBG)/libDSPEsockets.a $(OUT_DIR_DBG)/libDSPEexamples.a
 Debug: $(OUT_DIR_DBG)/DSPElib.exe
 
-$(OUT_DIR_DBG)/DSPElib.exe: $(OUT_DIR_DBG)/libDSPE.a $(OUT_DIR_DBG)/libDSPEsockets.a 
-	$(CC) -L"$(OUT_DIR_DBG)" "$(OUT_DIR_DBG)/src/Main.o" -o"$(OUT_DIR_DBG)/DSPElib.exe" $(LINKER_FLAGS_debug) -lDSPE -lDSPEsockets  $(LIBS)
+$(OUT_DIR_DBG)/DSPElib.exe: $(OUT_DIR_DBG)/libDSPE.a $(OUT_DIR_DBG)/libDSPEsockets.a $(OUT_DIR_DBG)/libDSPEexamples.a
+	$(CC) -L"$(OUT_DIR_DBG)" "$(OUT_DIR_DBG)/src/Main.o" -o"$(OUT_DIR_DBG)/DSPElib.exe" $(LINKER_FLAGS_debug) -lDSPE -lDSPEsockets -lDSPEexamples  $(LIBS)
 
 $(OUT_DIR_DBG)/libDSPE.a: $(OBJECTS_Debug) $(OBJECTS_MISC_Debug)
 	@echo Preparing lib file $@
@@ -116,8 +123,13 @@ $(OUT_DIR_DBG)/libDSPEsockets.a:  $(OBJECTS_SOCKETS_Debug)
 	ar rc $@  $(OBJECTS_SOCKETS_Debug)
 	ranlib $@
 
+$(OUT_DIR_DBG)/libDSPEexamples.a:  $(OBJECTS_EXAMPLES_Debug)
+	@echo Preparing lib file $@
+	ar rc $@  $(OBJECTS_EXAMPLES_Debug)
+	ranlib $@
+
 # Z podanej listy usuwany $(OUT_DIR_RLS)/ oraz '.o' zamieniamy na '.cpp'
-$(OBJECTS_Debug) $(OBJECTS_SOCKETS_Debug) $(OBJECTS_MISC_Debug): $(OUT_DIR_DBG)/%.o : %.cpp
+$(OBJECTS_Debug) $(OBJECTS_EXAMPLES_Debug) $(OBJECTS_SOCKETS_Debug) $(OBJECTS_MISC_Debug): $(OUT_DIR_DBG)/%.o : %.cpp
 	@echo $(@D) $< $@
 	
 	mkdir -p $(@D)
diff --git a/src/cpp/DSP_IO.cpp b/src/cpp/DSP_IO.cpp
index a356b67c064d05481daac179906fbf850b8abcf2..dea7ebd1549971a91c01dc98e6f485026e85b8ac 100644
--- a/src/cpp/DSP_IO.cpp
+++ b/src/cpp/DSP_IO.cpp
@@ -3513,58 +3513,58 @@ inline void CDirectXInput::SourceDescription(TStringList *Text)
       switch (result)
       {
         case MMSYSERR_ALLOCATED:
-          DSP::log << DSP::e::LogMode::Error << "DSP_AudioCheckError" << DSP::e::LogMode::second <<
+          DSP::log << DSP::e::LogMode::Error << "DSP::f::AudioCheckError" << DSP::e::LogMode::second <<
             "Specified resource is already allocated." << endl;
           break;
         case MMSYSERR_BADDEVICEID:
-          DSP::log << DSP::e::LogMode::Error << "DSP_AudioCheckError" << DSP::e::LogMode::second <<
+          DSP::log << DSP::e::LogMode::Error << "DSP::f::AudioCheckError" << DSP::e::LogMode::second <<
             "Specified device identifier is out of range." << endl;
           break;
         case MMSYSERR_NODRIVER:
-          DSP::log << DSP::e::LogMode::Error << "DSP_AudioCheckError" << DSP::e::LogMode::second <<
+          DSP::log << DSP::e::LogMode::Error << "DSP::f::AudioCheckError" << DSP::e::LogMode::second <<
             "No device driver is present." << endl;
           break;
         case MMSYSERR_NOMEM:
-          DSP::log << DSP::e::LogMode::Error << "DSP_AudioCheckError" << DSP::e::LogMode::second <<
+          DSP::log << DSP::e::LogMode::Error << "DSP::f::AudioCheckError" << DSP::e::LogMode::second <<
             "Unable to allocate or lock memory." << endl;
           break;
         case WAVERR_BADFORMAT:
-          DSP::log << DSP::e::LogMode::Error << "DSP_AudioCheckError" << DSP::e::LogMode::second <<
+          DSP::log << DSP::e::LogMode::Error << "DSP::f::AudioCheckError" << DSP::e::LogMode::second <<
             "Attempted to open with an unsupported waveform-audio format." << endl;
           break;
         case WAVERR_SYNC:
-          DSP::log << DSP::e::LogMode::Error << "DSP_AudioCheckError" << DSP::e::LogMode::second <<
+          DSP::log << DSP::e::LogMode::Error << "DSP::f::AudioCheckError" << DSP::e::LogMode::second <<
             "The device is synchronous but waveOutOpen was called without using the WAVE_ALLOWSYNC flag." << endl;
           break;
         case MMSYSERR_INVALFLAG:
-          DSP::log << DSP::e::LogMode::Error << "DSP_AudioCheckError" << DSP::e::LogMode::second <<
+          DSP::log << DSP::e::LogMode::Error << "DSP::f::AudioCheckError" << DSP::e::LogMode::second <<
             "Invalid flag" << endl;
           break;
         case MMSYSERR_NOERROR:
           return false;
-          //printf("DSP_AudioCheckError: ");
+          //printf("DSP::f::AudioCheckError: ");
           //printf("No error.");
           //printf("\n"); getchar();
           break;
         case MMSYSERR_INVALHANDLE:
-          DSP::log << DSP::e::LogMode::Error << "DSP_AudioCheckError" << DSP::e::LogMode::second <<
+          DSP::log << DSP::e::LogMode::Error << "DSP::f::AudioCheckError" << DSP::e::LogMode::second <<
             "Specified device handle is invalid." << endl;
           break;
         case WAVERR_UNPREPARED:
-          DSP::log << DSP::e::LogMode::Error << "DSP_AudioCheckError" << DSP::e::LogMode::second <<
+          DSP::log << DSP::e::LogMode::Error << "DSP::f::AudioCheckError" << DSP::e::LogMode::second <<
             "The data block pointed to by the pwh parameter hasn't been prepared." << endl;
           break;
         case MMSYSERR_HANDLEBUSY:
-          DSP::log << DSP::e::LogMode::Error << "DSP_AudioCheckError" << DSP::e::LogMode::second <<
+          DSP::log << DSP::e::LogMode::Error << "DSP::f::AudioCheckError" << DSP::e::LogMode::second <<
             "Handle busy." << endl;
           break;
         case WAVERR_STILLPLAYING:
-          DSP::log << DSP::e::LogMode::Error << "DSP_AudioCheckError" << DSP::e::LogMode::second <<
+          DSP::log << DSP::e::LogMode::Error << "DSP::f::AudioCheckError" << DSP::e::LogMode::second <<
             "There are still buffers in the queue." << endl;
           break;
         default:
           {
-            DSP::log << DSP::e::LogMode::Error << "DSP_AudioCheckError" << DSP::e::LogMode::second
+            DSP::log << DSP::e::LogMode::Error << "DSP::f::AudioCheckError" << DSP::e::LogMode::second
               << "Unknown error " << WAVERR_BASE << " " << result << endl;
           }
           break;
@@ -3606,260 +3606,260 @@ uint32_t DSP::f::GetAudioBufferSize(const unsigned long &SamplingFreq, const DSP
   return size;
 }
 
-#ifdef WINMMAPI
-
-  //! \bug allow user to select number of internal buffers
-  void CALLBACK DSP::u::AudioInput::waveInProc_short(HWAVEIN hwi, UINT uMsg,
-    uint32_t dwInstance, uint32_t dwParam1, uint32_t dwParam2)
-  {
-    UNUSED_ARGUMENT(hwi);
-    UNUSED_ARGUMENT(dwParam1);
-    UNUSED_ARGUMENT(dwParam2);
-
-    MMRESULT result;
-    DSP::u::AudioInput *Current;
-    short *temp16;
-    DSP::Float_ptr Sample;
-    unsigned int ind;
-  #ifdef __DEBUG__
-    #ifdef AUDIO_DEBUG_MESSAGES_ON
-      stringstream tekst;
-    #endif
-  #endif
+//#ifdef WINMMAPI
 
-    Current = AudioObjects[dwInstance];
+  // //! \bug allow user to select number of internal buffers
+  // void CALLBACK DSP::u::AudioInput::waveInProc_short(HWAVEIN hwi, UINT uMsg,
+  //   uint32_t dwInstance, uint32_t dwParam1, uint32_t dwParam2)
+  // {
+  //   UNUSED_ARGUMENT(hwi);
+  //   UNUSED_ARGUMENT(dwParam1);
+  //   UNUSED_ARGUMENT(dwParam2);
 
-    switch (uMsg)
-    {
-  #ifdef __DEBUG__
-  #ifdef AUDIO_DEBUG_MESSAGES_ON
-      case WIM_OPEN:
-        DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
-          << "WIM_OPEN(" << (int)dwInstance << ")" << endl;
-        break;
-      case WIM_CLOSE:
-        DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
-          << "WIM_CLOSE(" << (int)dwInstance << ")" << endl;
-        break;
-  #endif
-  #endif
+  //   MMRESULT result;
+  //   DSP::u::AudioInput *Current;
+  //   short *temp16;
+  //   DSP::Float_ptr Sample;
+  //   unsigned int ind;
+  // #ifdef __DEBUG__
+  //   #ifdef AUDIO_DEBUG_MESSAGES_ON
+  //     stringstream tekst;
+  //   #endif
+  // #endif
 
-      case WIM_DATA:
-  #ifdef __DEBUG__
-  #ifdef AUDIO_DEBUG_MESSAGES_ON
-        DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
-          << "WIM_DATA(" << (int)dwInstance << ")" << endl;
-  #endif
-  #endif
+  //   Current = AudioObjects[dwInstance];
 
-        if (Current->StopRecording)
-          return;
-        else
-        {
-          if (Current->EmptyBufferIndex == Current->CurrentBufferIndex)
-          {
-  #ifdef __DEBUG__
-  #ifdef AUDIO_DEBUG_MESSAGES_ON
-            DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second << "All buffers had been used - skipping input audio frame" << endl;
-  #endif
-  #endif
-            result=waveInUnprepareHeader(Current->hWaveIn,
-              &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
-            DSP::f::AudioCheckError(result);
-            // ignore data
-
-            //add put back into recording queue
-            result=waveInPrepareHeader(Current->hWaveIn,
-              &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
-            DSP::f::AudioCheckError(result);
-            result=waveInAddBuffer(Current->hWaveIn,
-              &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
-            DSP::f::AudioCheckError(result);
-
-            Current->NextBufferInd++; Current->NextBufferInd %= 2; //just two buffers
-          }
-          else
-          { //copy audio frame to buffer form audio frame NextBufferInd
-            if (Current->waveHeaderIn[Current->NextBufferInd].dwFlags & WHDR_DONE)
-            {
-              //copy data
-              result=waveInUnprepareHeader(Current->hWaveIn,
-                &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
-              DSP::f::AudioCheckError(result);
-
-              Sample=Current->InBuffers[Current->EmptyBufferIndex].data();
-              // ************************************************** //
-              // Converts samples format to the one suitable for the audio device
-              #ifdef __DEBUG__
-                if (Current->InSampleType != DSP::e::SampleType::ST_short)
-                {
-                  DSP::log << "DSP::u::AudioInput::waveInProc_short" << DSP::e::LogMode::second << "Current->InSampleType != DSP::e::SampleType::ST_short" << endl;
-                }
-              #endif
+  //   switch (uMsg)
+  //   {
+  // #ifdef __DEBUG__
+  // #ifdef AUDIO_DEBUG_MESSAGES_ON
+  //     case WIM_OPEN:
+  //       DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
+  //         << "WIM_OPEN(" << (int)dwInstance << ")" << endl;
+  //       break;
+  //     case WIM_CLOSE:
+  //       DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
+  //         << "WIM_CLOSE(" << (int)dwInstance << ")" << endl;
+  //       break;
+  // #endif
+  // #endif
 
-              temp16=(short *)(Current->WaveInBuffers[Current->NextBufferInd].data());
-              for (ind=0; ind<Current->InBufferLen; ind++)
-              {
-                *Sample = (DSP::Float)(*temp16) / SHRT_MAX;
-                Sample++;
-                temp16++;
-              }
-              Current->EmptyBufferIndex++; Current->EmptyBufferIndex %= DSP::NoOfAudioInputBuffers;
+  //     case WIM_DATA:
+  // #ifdef __DEBUG__
+  // #ifdef AUDIO_DEBUG_MESSAGES_ON
+  //       DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
+  //         << "WIM_DATA(" << (int)dwInstance << ")" << endl;
+  // #endif
+  // #endif
 
-              //add put back into recording queue
-              result=waveInPrepareHeader(Current->hWaveIn,
-                &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
-              DSP::f::AudioCheckError(result);
-              result=waveInAddBuffer(Current->hWaveIn,
-                &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
-              DSP::f::AudioCheckError(result);
+  //       if (Current->StopRecording)
+  //         return;
+  //       else
+  //       {
+  //         if (Current->EmptyBufferIndex == Current->CurrentBufferIndex)
+  //         {
+  // #ifdef __DEBUG__
+  // #ifdef AUDIO_DEBUG_MESSAGES_ON
+  //           DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second << "All buffers had been used - skipping input audio frame" << endl;
+  // #endif
+  // #endif
+  //           result=waveInUnprepareHeader(Current->hWaveIn,
+  //             &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
+  //           DSP::f::AudioCheckError(result);
+  //           // ignore data
 
-              Current->NextBufferInd++; Current->NextBufferInd %= 2; //just two buffers
-            }
-            else
-            {
-  #ifdef __DEBUG__
-  #ifdef AUDIO_DEBUG_MESSAGES_ON
-              DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second << "Wrong audio frame ready or other unexpected error" << endl;
-  #endif
-  #endif
-            }
-          }
-        }
-        break; // WIM_DATA
-    }
-  }
+  //           //add put back into recording queue
+  //           result=waveInPrepareHeader(Current->hWaveIn,
+  //             &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
+  //           DSP::f::AudioCheckError(result);
+  //           result=waveInAddBuffer(Current->hWaveIn,
+  //             &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
+  //           DSP::f::AudioCheckError(result);
 
-  //! \bug allow user to select number of internal buffers
-  void CALLBACK DSP::u::AudioInput::waveInProc_uchar(HWAVEIN hwi, UINT uMsg,
-    uint32_t dwInstance, uint32_t dwParam1, uint32_t dwParam2)
-  {
-    UNUSED_ARGUMENT(hwi);
-    UNUSED_ARGUMENT(dwParam1);
-    UNUSED_ARGUMENT(dwParam2);
+  //           Current->NextBufferInd++; Current->NextBufferInd %= 2; //just two buffers
+  //         }
+  //         else
+  //         { //copy audio frame to buffer form audio frame NextBufferInd
+  //           if (Current->waveHeaderIn[Current->NextBufferInd].dwFlags & WHDR_DONE)
+  //           {
+  //             //copy data
+  //             result=waveInUnprepareHeader(Current->hWaveIn,
+  //               &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
+  //             DSP::f::AudioCheckError(result);
+
+  //             Sample=Current->InBuffers[Current->EmptyBufferIndex].data();
+  //             // ************************************************** //
+  //             // Converts samples format to the one suitable for the audio device
+  //             #ifdef __DEBUG__
+  //               if (Current->InSampleType != DSP::e::SampleType::ST_short)
+  //               {
+  //                 DSP::log << "DSP::u::AudioInput::waveInProc_short" << DSP::e::LogMode::second << "Current->InSampleType != DSP::e::SampleType::ST_short" << endl;
+  //               }
+  //             #endif
+
+  //             temp16=(short *)(Current->WaveInBuffers[Current->NextBufferInd].data());
+  //             for (ind=0; ind<Current->InBufferLen; ind++)
+  //             {
+  //               *Sample = (DSP::Float)(*temp16) / SHRT_MAX;
+  //               Sample++;
+  //               temp16++;
+  //             }
+  //             Current->EmptyBufferIndex++; Current->EmptyBufferIndex %= DSP::NoOfAudioInputBuffers;
+
+  //             //add put back into recording queue
+  //             result=waveInPrepareHeader(Current->hWaveIn,
+  //               &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
+  //             DSP::f::AudioCheckError(result);
+  //             result=waveInAddBuffer(Current->hWaveIn,
+  //               &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
+  //             DSP::f::AudioCheckError(result);
+
+  //             Current->NextBufferInd++; Current->NextBufferInd %= 2; //just two buffers
+  //           }
+  //           else
+  //           {
+  // #ifdef __DEBUG__
+  // #ifdef AUDIO_DEBUG_MESSAGES_ON
+  //             DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second << "Wrong audio frame ready or other unexpected error" << endl;
+  // #endif
+  // #endif
+  //           }
+  //         }
+  //       }
+  //       break; // WIM_DATA
+  //   }
+  // }
 
-    MMRESULT result;
-    DSP::u::AudioInput *Current;
-    uint8_t *temp8;
-    DSP::Float_ptr Sample;
-    unsigned int ind;
-  #ifdef __DEBUG__
-    #ifdef AUDIO_DEBUG_MESSAGES_ON
-      stringstream tekst;
-    #else
-      UNUSED_DEBUG_ARGUMENT(uMsg);
-    #endif
-  #endif
+  // //! \bug allow user to select number of internal buffers
+  // void CALLBACK DSP::u::AudioInput::waveInProc_uchar(HWAVEIN hwi, UINT uMsg,
+  //   uint32_t dwInstance, uint32_t dwParam1, uint32_t dwParam2)
+  // {
+  //   UNUSED_ARGUMENT(hwi);
+  //   UNUSED_ARGUMENT(dwParam1);
+  //   UNUSED_ARGUMENT(dwParam2);
 
-    Current = AudioObjects[dwInstance];
+  //   MMRESULT result;
+  //   DSP::u::AudioInput *Current;
+  //   uint8_t *temp8;
+  //   DSP::Float_ptr Sample;
+  //   unsigned int ind;
+  // #ifdef __DEBUG__
+  //   #ifdef AUDIO_DEBUG_MESSAGES_ON
+  //     stringstream tekst;
+  //   #else
+  //     UNUSED_DEBUG_ARGUMENT(uMsg);
+  //   #endif
+  // #endif
 
-    switch (uMsg)
-    {
-  #ifdef __DEBUG__
-  #ifdef AUDIO_DEBUG_MESSAGES_ON
-      case WIM_OPEN:
-        DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
-          << "WIM_OPEN(" << (int)dwInstance << ")" << end;
-        break;
-      case WIM_CLOSE:
-        DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
-          << "WIM_CLOSE(" << (int)dwInstance << ")" << endl;
-        break;
-  #endif
-  #endif
+  //   Current = AudioObjects[dwInstance];
 
-      case WIM_DATA:
-  #ifdef __DEBUG__
-  #ifdef AUDIO_DEBUG_MESSAGES_ON
-        DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
-          << "WIM_DATA(" << (int)dwInstance << ")" << endl;
-  #endif
-  #endif
+  //   switch (uMsg)
+  //   {
+  // #ifdef __DEBUG__
+  // #ifdef AUDIO_DEBUG_MESSAGES_ON
+  //     case WIM_OPEN:
+  //       DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
+  //         << "WIM_OPEN(" << (int)dwInstance << ")" << end;
+  //       break;
+  //     case WIM_CLOSE:
+  //       DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
+  //         << "WIM_CLOSE(" << (int)dwInstance << ")" << endl;
+  //       break;
+  // #endif
+  // #endif
 
-        if (Current->StopRecording)
-          return;
-        else
-        {
-          if (Current->EmptyBufferIndex == Current->CurrentBufferIndex)
-          {
-  #ifdef __DEBUG__
-  #ifdef AUDIO_DEBUG_MESSAGES_ON
-            DSP::log << "DSP::u::AudioInput::waveInProc"  << DSP::e::LogMode::second << "All buffers had been used - skipping input audio frame" << endl;
-  #endif
-  #endif
-            result=waveInUnprepareHeader(Current->hWaveIn,
-              &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
-            DSP::f::AudioCheckError(result);
-            // ignore data
-
-            //add put back into recording queue
-            result=waveInPrepareHeader(Current->hWaveIn,
-              &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
-            DSP::f::AudioCheckError(result);
-            result=waveInAddBuffer(Current->hWaveIn,
-              &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
-            DSP::f::AudioCheckError(result);
-
-            Current->NextBufferInd++; Current->NextBufferInd %= 2; //just two buffers
-          }
-          else
-          { //copy audio frame to buffer form audio frame NextBufferInd
-            if (Current->waveHeaderIn[Current->NextBufferInd].dwFlags & WHDR_DONE)
-            {
-              //copy data
-              result=waveInUnprepareHeader(Current->hWaveIn,
-                &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
-              DSP::f::AudioCheckError(result);
-
-              Sample=Current->InBuffers[Current->EmptyBufferIndex].data();
-              // ************************************************** //
-              // Converts samples format to the one suitable for the audio device
-              #ifdef __DEBUG__
-                if (Current->InSampleType != DSP::e::SampleType::ST_uchar)
-                {
-                  DSP::log << "DSP::u::AudioInput::waveInProc_uchar" << DSP::e::LogMode::second << "Current->InSampleType != DSP::e::SampleType::ST_uchar" << endl;
-                }
-              #endif
+  //     case WIM_DATA:
+  // #ifdef __DEBUG__
+  // #ifdef AUDIO_DEBUG_MESSAGES_ON
+  //       DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
+  //         << "WIM_DATA(" << (int)dwInstance << ")" << endl;
+  // #endif
+  // #endif
 
-              temp8=(uint8_t *)(Current->WaveInBuffers[Current->NextBufferInd].data());
-              for (ind=0; ind<Current->InBufferLen; ind++)
-              {
-                *Sample = (DSP::Float)(*temp8 - 128) / 128;
-                Sample++;
-                temp8++;
-              }
-              Current->EmptyBufferIndex++; Current->EmptyBufferIndex %= DSP::NoOfAudioInputBuffers;
+  //       if (Current->StopRecording)
+  //         return;
+  //       else
+  //       {
+  //         if (Current->EmptyBufferIndex == Current->CurrentBufferIndex)
+  //         {
+  // #ifdef __DEBUG__
+  // #ifdef AUDIO_DEBUG_MESSAGES_ON
+  //           DSP::log << "DSP::u::AudioInput::waveInProc"  << DSP::e::LogMode::second << "All buffers had been used - skipping input audio frame" << endl;
+  // #endif
+  // #endif
+  //           result=waveInUnprepareHeader(Current->hWaveIn,
+  //             &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
+  //           DSP::f::AudioCheckError(result);
+  //           // ignore data
 
-              //add put back into recording queue
-              result=waveInPrepareHeader(Current->hWaveIn,
-                &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
-              DSP::f::AudioCheckError(result);
-              result=waveInAddBuffer(Current->hWaveIn,
-                &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
-              DSP::f::AudioCheckError(result);
+  //           //add put back into recording queue
+  //           result=waveInPrepareHeader(Current->hWaveIn,
+  //             &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
+  //           DSP::f::AudioCheckError(result);
+  //           result=waveInAddBuffer(Current->hWaveIn,
+  //             &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
+  //           DSP::f::AudioCheckError(result);
 
-              Current->NextBufferInd++; Current->NextBufferInd %= 2; //just two buffers
-            }
-            else
-            {
-  #ifdef __DEBUG__
-  #ifdef AUDIO_DEBUG_MESSAGES_ON
-              DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second << "Wrong audio frame ready or other unexpected error" << endl;
-  #endif
-  #endif
-            }
-          }
-          break;
-        }
+  //           Current->NextBufferInd++; Current->NextBufferInd %= 2; //just two buffers
+  //         }
+  //         else
+  //         { //copy audio frame to buffer form audio frame NextBufferInd
+  //           if (Current->waveHeaderIn[Current->NextBufferInd].dwFlags & WHDR_DONE)
+  //           {
+  //             //copy data
+  //             result=waveInUnprepareHeader(Current->hWaveIn,
+  //               &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
+  //             DSP::f::AudioCheckError(result);
+
+  //             Sample=Current->InBuffers[Current->EmptyBufferIndex].data();
+  //             // ************************************************** //
+  //             // Converts samples format to the one suitable for the audio device
+  //             #ifdef __DEBUG__
+  //               if (Current->InSampleType != DSP::e::SampleType::ST_uchar)
+  //               {
+  //                 DSP::log << "DSP::u::AudioInput::waveInProc_uchar" << DSP::e::LogMode::second << "Current->InSampleType != DSP::e::SampleType::ST_uchar" << endl;
+  //               }
+  //             #endif
+
+  //             temp8=(uint8_t *)(Current->WaveInBuffers[Current->NextBufferInd].data());
+  //             for (ind=0; ind<Current->InBufferLen; ind++)
+  //             {
+  //               *Sample = (DSP::Float)(*temp8 - 128) / 128;
+  //               Sample++;
+  //               temp8++;
+  //             }
+  //             Current->EmptyBufferIndex++; Current->EmptyBufferIndex %= DSP::NoOfAudioInputBuffers;
+
+  //             //add put back into recording queue
+  //             result=waveInPrepareHeader(Current->hWaveIn,
+  //               &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
+  //             DSP::f::AudioCheckError(result);
+  //             result=waveInAddBuffer(Current->hWaveIn,
+  //               &(Current->waveHeaderIn[Current->NextBufferInd]), sizeof(WAVEHDR));
+  //             DSP::f::AudioCheckError(result);
+
+  //             Current->NextBufferInd++; Current->NextBufferInd %= 2; //just two buffers
+  //           }
+  //           else
+  //           {
+  // #ifdef __DEBUG__
+  // #ifdef AUDIO_DEBUG_MESSAGES_ON
+  //             DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second << "Wrong audio frame ready or other unexpected error" << endl;
+  // #endif
+  // #endif
+  //           }
+  //         }
+  //         break;
+  //       }
 
-    }
-  }
-#endif // WINMMAPI
+  //   }
+  // }
+//#endif // WINMMAPI
 
-unsigned long DSP::u::AudioOutput::Next_CallbackInstance=0;
-unsigned long DSP::u::AudioInput::Next_CallbackInstance =0;
-std::vector<DSP::u::AudioOutput *> DSP::u::AudioOutput::AudioObjects;
-std::vector<DSP::u::AudioInput  *> DSP::u::AudioInput::AudioObjects;
+// unsigned long DSP::u::AudioOutput::Next_CallbackInstance=0;
+// unsigned long DSP::u::AudioInput::Next_CallbackInstance =0;
+// std::vector<DSP::u::AudioOutput *> DSP::u::AudioOutput::AudioObjects;
+// std::vector<DSP::u::AudioInput  *> DSP::u::AudioInput::AudioObjects;
 
 DSP::u::AudioOutput::AudioOutput(void)
   : DSP::Block()
@@ -3943,16 +3943,14 @@ void DSP::u::AudioOutput::Init(unsigned long SamplingFreq,
 //    //! \bug in Debug mode this callback does nothing so it would be better just not use it
 //    Callback = (DWORD_PTR)(&DSP::u::AudioOutput::waveOutProc);
 //  #endif
-  Current_CallbackInstance=Next_CallbackInstance;
-  Next_CallbackInstance++;
-  AudioObjects.resize(Current_CallbackInstance+1);
-  AudioObjects[Current_CallbackInstance]=this;
-
-  StopPlaying = false;
+  // Current_CallbackInstance=Next_CallbackInstance;
+  // Next_CallbackInstance++;
+  // AudioObjects.resize(Current_CallbackInstance+1);
+  // AudioObjects[Current_CallbackInstance]=this;
 
   audio_outbuffer_size = DSP::f::GetAudioBufferSize(SamplingFreq, DSP::e::AudioBufferType::output);
 
-  snd_object.select_device_by_number(WaveOutDevNo); // use default device
+  snd_object.select_output_device_by_number(WaveOutDevNo); // use default device
   snd_object.open_PCM_device_4_output(NoOfInputs, BitPrec, SamplingFreq, audio_outbuffer_size);
 
   OutBufferLen=NoOfInputs*audio_outbuffer_size;
@@ -3991,6 +3989,57 @@ DSP::u::AudioInput::AudioInput(
   OutputExecute_ptr = &OutputExecute;
 }
 
+bool DSP::u::AudioInput::SOUND_object_callback(const DSP::e::SampleType &InSampleType, const std::vector<char> &wave_in_raw_buffer) {
+  if (EmptyBufferIndex != CurrentBufferIndex) {
+    DSP::Float_ptr Sample;
+    unsigned int ind;
+
+    //  reading sound card input buffer
+    Sample=InBuffers[EmptyBufferIndex].data();
+    // ************************************************** //
+    // Converts samples format from the one used in the audio device
+    switch (InSampleType) {
+      case DSP::e::SampleType::ST_short: {
+          short *temp16;
+
+          temp16=(short *)(wave_in_raw_buffer.data());
+          for (ind=0; ind<InBufferLen; ind++)
+          {
+            *Sample = (DSP::Float)(*temp16) / SHRT_MAX;
+            Sample++;
+            temp16++;
+          }
+        }
+        break;
+
+      case DSP::e::SampleType::ST_uchar: {
+          uint8_t *temp8;
+          
+          temp8=(uint8_t *)(wave_in_raw_buffer.data());
+          for (ind=0; ind<InBufferLen; ind++)
+          {
+            *Sample = (DSP::Float)(*temp8 - 128) / 128;
+            Sample++;
+            temp8++;
+          }
+        }
+        break;
+
+      default:
+    #ifdef __DEBUG__
+        DSP::log << "DSP::u::AudioInput::waveInProc_short" << DSP::e::LogMode::second << "Unsupported Current->InSampleType" << endl;
+    #endif
+        break;
+    }
+    EmptyBufferIndex++; EmptyBufferIndex %= DSP::NoOfAudioInputBuffers;
+
+    return true;
+  }
+  else {
+    return false;
+  }
+  return false;
+}
 
 /* Inputs and Outputs names:
  *   - Output:
@@ -4009,19 +4058,19 @@ void DSP::u::AudioInput::Init(DSP::Clock_ptr ParentClock,
   unsigned long ind;
   string temp;
 
-  #ifdef WINMMAPI
-    MMRESULT result;
-    DWORD_PTR Callback;
-  //Rezerwacja pamici dla formatu WAVE
-  //  WAVEFORMATEX wfx; //to wymaga korekty
-    PCMWAVEFORMAT wfx;
-  #elif defined(ALSA_support_H)
-    UNUSED_ARGUMENT(WaveInDevNo);
-    ALSA_object_t ALSA_object;
+  // #ifdef WINMMAPI
+  //   MMRESULT result;
+  //   DWORD_PTR Callback;
+  // //Rezerwacja pamici dla formatu WAVE
+  // //  WAVEFORMATEX wfx; //to wymaga korekty
+  //   PCMWAVEFORMAT wfx;
+  // #elif defined(ALSA_support_H)
+  //   UNUSED_ARGUMENT(WaveInDevNo);
+  //   ALSA_object_t ALSA_object;
 
-  #else
-    UNUSED_ARGUMENT(WaveInDevNo);
-  #endif
+  // #else
+  //   UNUSED_ARGUMENT(WaveInDevNo);
+  // #endif
 
   SetNoOfOutputs(OutputsNo);
   SetName("AudioInput", false);
@@ -4046,117 +4095,53 @@ void DSP::u::AudioInput::Init(DSP::Clock_ptr ParentClock,
   RegisterOutputClock(ParentClock);
   my_clock = ParentClock;
 
-  Current_CallbackInstance=Next_CallbackInstance;
-  Next_CallbackInstance++;
-  AudioObjects.resize(Current_CallbackInstance+1);
-  AudioObjects[Current_CallbackInstance]=this;
-  StopRecording = false;
+  // Current_CallbackInstance=Next_CallbackInstance;
+  // Next_CallbackInstance++;
+  // AudioObjects.resize(Current_CallbackInstance+1);
+  // AudioObjects[Current_CallbackInstance]=this;
+  // StopRecording = false;
 
-  switch (BitPrec)
-  {
-    case 8:
-      InSampleType=DSP::e::SampleType::ST_uchar;
-      #ifdef WINMMAPI
-        Callback = (DWORD_PTR)(&DSP::u::AudioInput::waveInProc_uchar);
-      #endif
-      break;
-    case 16:
-      InSampleType=DSP::e::SampleType::ST_short;
-      #ifdef WINMMAPI
-        Callback = (DWORD_PTR)(&DSP::u::AudioInput::waveInProc_short);
-      #endif
-      break;
-    default:
-      InSampleType=DSP::e::SampleType::ST_short;
-      #ifdef WINMMAPI
-        Callback = (DWORD_PTR)(&DSP::u::AudioInput::waveInProc_short);
-      #endif
-      BitPrec=16;
-      break;
-  }
+  // switch (BitPrec)
+  // {
+  //   case 8:
+  //     InSampleType=DSP::e::SampleType::ST_uchar;
+  //     #ifdef WINMMAPI
+  //       Callback = (DWORD_PTR)(&DSP::u::AudioInput::waveInProc_uchar);
+  //     #endif
+  //     break;
+  //   case 16:
+  //     InSampleType=DSP::e::SampleType::ST_short;
+  //     #ifdef WINMMAPI
+  //       Callback = (DWORD_PTR)(&DSP::u::AudioInput::waveInProc_short);
+  //     #endif
+  //     break;
+  //   default:
+  //     InSampleType=DSP::e::SampleType::ST_short;
+  //     #ifdef WINMMAPI
+  //       Callback = (DWORD_PTR)(&DSP::u::AudioInput::waveInProc_short);
+  //     #endif
+  //     BitPrec=16;
+  //     break;
+  // }
 
   audio_inbuffer_size = DSP::f::GetAudioBufferSize(SamplingFreq, DSP::e::AudioBufferType::input);
 
-  #ifdef WINMMAPI
-    //Wypeniamy struktur wfx
-    wfx.wf.wFormatTag=WAVE_FORMAT_PCM;
-    wfx.wf.nChannels=(uint16_t)NoOfOutputs;
-    wfx.wf.nSamplesPerSec=(UINT)SamplingFreq;
-    wfx.wBitsPerSample=BitPrec;
-    wfx.wf.nAvgBytesPerSec=wfx.wf.nSamplesPerSec*(wfx.wBitsPerSample/8);
-    wfx.wf.nBlockAlign=(uint16_t)(wfx.wf.nChannels*(wfx.wBitsPerSample/8));
-
-    if (waveInGetNumDevs() <= WaveInDevNo)
-      result=waveInOpen(&hWaveIn,
-        WAVE_MAPPER, //&DeviceID,
-        (WAVEFORMATEX *)(&wfx),
-        Callback,
-        Current_CallbackInstance, //CallbackInstance,
-        CALLBACK_FUNCTION | WAVE_FORMAT_DIRECT //| WAVE_MAPPED //CALLBACK_NULL
-        );
-    else
-      result=waveInOpen(&hWaveIn,
-        WaveInDevNo, //&DeviceID,
-        (WAVEFORMATEX *)(&wfx),
-        Callback,
-        Current_CallbackInstance, //CallbackInstance,
-        CALLBACK_FUNCTION | WAVE_FORMAT_DIRECT //| WAVE_MAPPED //CALLBACK_NULL
-        );
-    if (DSP::f::AudioCheckError(result) == false)
-    { // no errors
-      waveHeaderIn.resize(2);
-      WaveInBufferLen=wfx.wf.nBlockAlign*audio_inbuffer_size;
-      WaveInBuffers.resize(2);
-      /*! \bug <b>2006.08.13</b> when 8bit audio stream is created initial values should be 0x80 or 0x79 not 0x00
-       */
-      WaveInBuffers[0].clear(); WaveInBuffers[0].resize(WaveInBufferLen, 0);
-      WaveInBuffers[1].clear(); WaveInBuffers[1].resize(WaveInBufferLen, 0);
-
-      InBufferLen=NoOfOutputs*audio_inbuffer_size;
-      for (ind = 0; ind < DSP::NoOfAudioInputBuffers; ind++)
-      {
-        InBuffers[ind].clear();
-        InBuffers[ind].resize(InBufferLen);
-      }
-      EmptyBufferIndex=0;
-      CurrentBufferIndex=DSP::NoOfAudioInputBuffers-1;
-      BufferIndex=InBufferLen;
-
-      waveHeaderIn[0].lpData=(char *)(WaveInBuffers[0].data());
-      waveHeaderIn[0].dwBufferLength=InBufferLen*(BitPrec/8); //sizeof(short);
-      waveHeaderIn[0].dwFlags= 0; // WHDR_BEGINLOOP | WHDR_ENDLOOP;
-      waveHeaderIn[0].dwLoops=0;
-
-      result=waveInPrepareHeader(hWaveIn,
-        &(waveHeaderIn[0]), sizeof(WAVEHDR));
-      DSP::f::AudioCheckError(result);
-    //  waveHeaderIn[0].dwFlags= WHDR_DONE; // WHDR_BEGINLOOP | WHDR_ENDLOOP;
-
-      waveHeaderIn[1].lpData=(char *)(WaveInBuffers[1].data());
-      waveHeaderIn[1].dwBufferLength=InBufferLen*(BitPrec/8); //sizeof(short);
-      waveHeaderIn[1].dwFlags= 0; // WHDR_BEGINLOOP | WHDR_ENDLOOP;
-      waveHeaderIn[1].dwLoops=0;
-
-      result=waveInPrepareHeader(hWaveIn,
-        &(waveHeaderIn[1]), sizeof(WAVEHDR));
-      DSP::f::AudioCheckError(result);
-    //  waveHeaderIn[1].dwFlags= WHDR_DONE; // WHDR_BEGINLOOP | WHDR_ENDLOOP;
-    }
-    else
-    { // error creating audio object
-      waveHeaderIn.clear(); WaveInBufferLen=0;
-      WaveInBuffers.clear();
-
-      InBufferLen=0;
-      for (ind = 0; ind < DSP::NoOfAudioInputBuffers; ind++)
-      {
-        InBuffers[ind].clear();
-      }
-      EmptyBufferIndex=0; CurrentBufferIndex=0;
-      BufferIndex=0;
+  snd_object.select_input_device_by_number(WaveInDevNo); // use default device
+  snd_object.register_input_callback_object(this, SOUND_object_callback); // use default device
+  if (snd_object.open_PCM_device_4_input(NoOfOutputs, BitPrec, SamplingFreq, audio_inbuffer_size) > 0) {
+    InBufferLen=NoOfOutputs*audio_inbuffer_size;
+    for (ind = 0; ind < DSP::NoOfAudioInputBuffers; ind++)
+    {
+      InBuffers[ind].clear();
+      InBuffers[ind].resize(InBufferLen);
     }
+    EmptyBufferIndex=0;
+    CurrentBufferIndex=DSP::NoOfAudioInputBuffers-1;
+    BufferIndex=InBufferLen;
 
-  #else
+  }
+  else
+  { // error creating audio object
 
     InBufferLen=0;
     for (ind = 0; ind < DSP::NoOfAudioInputBuffers; ind++)
@@ -4165,12 +4150,7 @@ void DSP::u::AudioInput::Init(DSP::Clock_ptr ParentClock,
     }
     EmptyBufferIndex=0; CurrentBufferIndex=0;
     BufferIndex=0;
-
-  #endif
-
-  IsRecordingNow = false; //wait until data requested
-
-  NextBufferInd=0; //its overridden in Execute()
+  }
 }
 
 
@@ -4183,9 +4163,9 @@ DSP::u::AudioOutput::~AudioOutput()
 
   if (OutBufferLen != 0)
   { // if device was opened successfully
-    StopPlaying=true;
+    snd_object.stop_playback();
 
-    snd_object.close_PCM_device();
+    snd_object.close_PCM_device_output();
 
     // #ifdef WINMMAPI
     //   result = waveOutReset(hWaveOut);
@@ -4229,60 +4209,23 @@ DSP::u::AudioOutput::~AudioOutput()
   // *************************** //
   // Free local resourses
   // 3) remove this audio object from the list
-  if (AudioObjects.size() > 0)
-  {
-    AudioObjects.erase(AudioObjects.begin() + Current_CallbackInstance);
-  }
-  Next_CallbackInstance--;
+  // if (AudioObjects.size() > 0)
+  // {
+  //   AudioObjects.erase(AudioObjects.begin() + Current_CallbackInstance);
+  // }
+  // Next_CallbackInstance--;
 }
 
 DSP::u::AudioInput::~AudioInput()
 {
-  #ifdef WINMMAPI
-    MMRESULT result;
-  #endif
   unsigned long ind;
 
   if (InBufferLen != 0)
   { // if device was opened successfully
-    StopRecording=true;
-
-    #ifdef WINMMAPI
-      result = waveInReset(hWaveIn);
-      DSP::f::AudioCheckError(result);
-      result=waveInUnprepareHeader(hWaveIn,
-        &(waveHeaderIn[0]), sizeof(WAVEHDR));
-      DSP::f::AudioCheckError(result);
-      result=waveInUnprepareHeader(hWaveIn,
-        &(waveHeaderIn[1]), sizeof(WAVEHDR));
-      DSP::f::AudioCheckError(result);
-
-      #ifdef AUDIO_DEBUG_MESSAGES_ON
-        DSP::log << "DSP::u::AudioInput" << DSP::e::LogMode::second << "Closing DSP::u::AudioInput" << endl;
-      #endif
-      result=waveInClose(hWaveIn);
-      while (result==WAVERR_STILLPLAYING)
-      {
-      //    #ifdef WINBASEAPI
-        DSP::f::Sleep(100);
-      //    #else
-      //      sleep(100);
-      //    #endif
-        #ifdef AUDIO_DEBUG_MESSAGES_ON
-          DSP::log << "DSP::u::AudioInput" << DSP::e::LogMode::second << "Closing DSP::u::AudioInput" << endl;
-        #endif
-        result=waveInClose(hWaveIn);
-      }
-      DSP::f::AudioCheckError(result);
-    #endif
+    // StopRecording=true;
+    snd_object.stop_recording();
 
-    // 2) Free buffers
-    WaveInBuffers[0].clear();
-    WaveInBuffers[1].clear();
-    WaveInBuffers.clear();
-    #ifdef WINMMAPI
-      waveHeaderIn.clear();
-    #endif
+    snd_object.close_PCM_device_input();
 
     for (ind=0; ind<DSP::NoOfAudioInputBuffers; ind++)
       InBuffers[ind].clear();
@@ -4291,11 +4234,11 @@ DSP::u::AudioInput::~AudioInput()
   // *************************** //
   // Free local resourses
   // 3) remove this audio object from the list
-  if (AudioObjects.size() > 0)
-  {
-    AudioObjects.erase(AudioObjects.begin() + Current_CallbackInstance);
-  }
-  Next_CallbackInstance--;
+  // if (AudioObjects.size() > 0)
+  // {
+  //   AudioObjects.erase(AudioObjects.begin() + Current_CallbackInstance);
+  // }
+  // Next_CallbackInstance--;
 }
 
 void DSP::u::AudioOutput::FlushBuffer(void)
@@ -4473,10 +4416,7 @@ bool DSP::u::AudioInput::OutputExecute(OUTPUT_EXECUTE_ARGS)
 {
   UNUSED_DEBUG_ARGUMENT(clock);
 
-  #ifdef WINMMAPI
-    MMRESULT result;
-  #endif
-    unsigned int ind;
+  unsigned int ind;
 
   if (DSP_THIS->InBufferLen == 0)
   { // no audio device opened
@@ -4498,7 +4438,7 @@ bool DSP::u::AudioInput::OutputExecute(OUTPUT_EXECUTE_ARGS)
 
 
   // if no input buffer is ready return false (system will later return here)
-  if (DSP_THIS->IsRecordingNow == true)
+  if (DSP_THIS->snd_object.is_device_recording() == true)
   { // but must check if data ready
     if ((((DSP_THIS->CurrentBufferIndex + 1) % DSP::NoOfAudioInputBuffers) == DSP_THIS->EmptyBufferIndex)
         && (DSP_THIS->BufferIndex == DSP_THIS->InBufferLen))
@@ -4553,39 +4493,22 @@ bool DSP::u::AudioInput::OutputExecute(OUTPUT_EXECUTE_ARGS)
   else
   { // starts recording
     // using both buffers
-    #ifdef WINMMAPI
-      #ifdef AUDIO_DEBUG_MESSAGES_ON
-        DSP::log << "DSP::u::AudioInput::Execute" << DSP::e::LogMode::second << "Starting recording using two wave buffers" << endl;
-      #endif
+    DSP_THIS->snd_object.start_recording();
 
-      result=waveInAddBuffer(DSP_THIS->hWaveIn,
-            &(DSP_THIS->waveHeaderIn[0]), sizeof(WAVEHDR));
-      DSP::f::AudioCheckError(result);
-      result=waveInAddBuffer(DSP_THIS->hWaveIn,
-            &(DSP_THIS->waveHeaderIn[1]), sizeof(WAVEHDR));
-      DSP::f::AudioCheckError(result);
-
-      DSP_THIS->NextBufferInd = 0; //first buffer first
-      DSP_THIS->EmptyBufferIndex = 2; //simulate two full buffers
-      for (ind = 0; ind < DSP_THIS->EmptyBufferIndex; ind++) {
-        memset(DSP_THIS->InBuffers[ind].data(), 0, DSP_THIS->InBufferLen*sizeof(DSP::Float));
-      }
-      DSP_THIS->BufferIndex = 0;
-
-      result=waveInStart(DSP_THIS->hWaveIn);
-      DSP::f::AudioCheckError(result);
-      DSP_THIS->IsRecordingNow = true;
-      //now just wait for buffer to fill up
-      // which should call waveInProc
-
-
-      //We cannot wait until input buffers fill-up, some other processing
-      // blocks like DSP::u::AudioOutput might wait for their time
-      /*! _bug if there are no DSP::u::AudioOutput blocks nothing
-       * will stop boost in processing speed
-       *
-       * we might want to simulated two full input buffers
-       */
+    //DSP_THIS->NextBufferInd = 0; //first buffer first
+    DSP_THIS->EmptyBufferIndex = 2; //simulate two full buffers
+    for (ind = 0; ind < DSP_THIS->EmptyBufferIndex; ind++) {
+      memset(DSP_THIS->InBuffers[ind].data(), 0, DSP_THIS->InBufferLen*sizeof(DSP::Float));
+    }
+    DSP_THIS->BufferIndex = 0;
+
+    //We cannot wait until input buffers fill-up, some other processing
+    // blocks like DSP::u::AudioOutput might wait for their time
+    /*! _bug if there are no DSP::u::AudioOutput blocks nothing
+      * will stop boost in processing speed
+      *
+      * we might want to simulated two full input buffers
+      */
   //    #ifdef AUDIO_DEBUG_MESSAGES_ON
   //      DSP::log << "DSP::u::AudioInput::Execute", "Audio recording started !!!");
   //    #endif
@@ -4598,8 +4521,6 @@ bool DSP::u::AudioInput::OutputExecute(OUTPUT_EXECUTE_ARGS)
   //    }
   //    return true;
 
-    #endif
-
     // program will return to this function and then output should be dealt with
     DSP::Clock::InputNeedsMoreTime[DSP_THIS->my_clock->MasterClockIndex] = true;
     return false;
@@ -5872,3 +5793,76 @@ bool DSP::f::SaveVector(const string &filename, const DSP::Complex_vector &vecto
 }
 
 
+//unsigned long DSP::WMM_object_t::Next_CallbackInstance=0;
+std::vector<DSP::SOUND_object_t *> DSP::SOUND_object_t::CallbackSoundObjects;
+
+const DSP::SOUND_object_t * DSP::SOUND_object_t::get_CallbackSoundObject(const long int &instance_number) {
+  return (CallbackSoundObjects[instance_number]);
+}
+
+DSP::SOUND_object_t::SOUND_object_t() {
+  AudioOutput_object = NULL;
+  AudioInput_object = NULL;
+
+  Current_CallbackInstance=get_free_CallbackInstance();
+  CallbackSoundObjects[Current_CallbackInstance]=this;
+}
+
+DSP::u::AudioInput *DSP::SOUND_object_t::get_input_callback_object() {
+  return AudioInput_object;
+}
+
+bool DSP::SOUND_object_t::input_callback_call(const DSP::e::SampleType &InSampleType, const std::vector<char> &wave_in_raw_buffer) {
+  return (AudioInput_object->*AudioInput_callback)(InSampleType, wave_in_raw_buffer);
+}
+
+unsigned long DSP::SOUND_object_t::get_free_CallbackInstance(void) {
+  bool is_free_slot_available = false;
+  unsigned long free_slot_index;
+
+  for (unsigned int ind = 0; ind < CallbackSoundObjects.size(); ind++) {
+    if (CallbackSoundObjects[ind] == NULL) {
+      is_free_slot_available = true;
+      free_slot_index = ind;
+      break;
+    }
+  }
+
+  if (is_free_slot_available == false) {
+    CallbackSoundObjects.push_back(NULL);
+    free_slot_index = (unsigned long)(CallbackSoundObjects.size()-1);
+  }
+
+  return free_slot_index;
+}
+
+
+DSP::u::AudioOutput *DSP::SOUND_object_t::get_output_callback_object() {
+  return AudioOutput_object;
+}
+
+bool DSP::SOUND_object_t::output_callback_call() {
+  return (AudioOutput_object->*AudioOutput_callback)();
+}
+
+bool DSP::SOUND_object_t::register_input_callback_object(DSP::u::AudioInput *callback_object, bool(DSP::u::AudioInput::*cp)(const DSP::e::SampleType &, const std::vector<char> &)) {
+  if (is_input_callback_supported() == true) {
+    AudioInput_object = callback_object;
+    AudioInput_callback = cp;
+    return true;
+  }
+  return false;
+}
+
+long int DSP::SOUND_object_t::get_current_CallbackInstance() {
+  return Current_CallbackInstance;
+}
+
+DSP::SOUND_object_t::~SOUND_object_t() {
+  if (CallbackSoundObjects.size() > 0)
+  {
+    //CallbackObjects.erase(CallbackObjects.begin() + Current_CallbackInstance);
+    CallbackSoundObjects[Current_CallbackInstance] = NULL;
+  }
+}
+
diff --git a/src/cpp/WMM_support.cpp b/src/cpp/WMM_support.cpp
index f53a2bc1bace805fe4288b6ca7d4d80facd1b4a7..75d984294fb6492627864868da865f15538d5b18 100644
--- a/src/cpp/WMM_support.cpp
+++ b/src/cpp/WMM_support.cpp
@@ -8,19 +8,31 @@
 
 #include <DSP_lib.h> // for logging 
 
-DSP::WMM_object_t::WMM_object_t()
+DSP::WMM_object_t::WMM_object_t() : DSP::SOUND_object_t()
 {
-  is_device_openned = false;
+  is_device_input_open = false;
+  WaveInDevNo = UINT_MAX;
+  is_device_output_open = false;
   WaveOutDevNo = UINT_MAX;
 
-  NextBufferInd=0;
+  NextBufferOutInd=0;
+  StopPlayback = false;
   IsPlayingNow = false;
+
+  NextBufferOutInd = 0;
+  StopRecording = false;
+  IsRecordingNow = false;
 };
+
 DSP::WMM_object_t::~WMM_object_t()
 {
-  if (is_device_openned) {
-    close_PCM_device();
+  if (is_device_input_open) {
+    close_PCM_device_input();
+  }
+  if (is_device_output_open) {
+    close_PCM_device_output();
   }
+
 }
 
 void CALLBACK DSP::WMM_object_t::waveOutProc(HWAVEOUT hwo, UINT uMsg,
@@ -44,20 +56,20 @@ void CALLBACK DSP::WMM_object_t::waveOutProc(HWAVEOUT hwo, UINT uMsg,
   switch (uMsg)
   {
     case WOM_OPEN:
-      DSP::log << "DSP::u::AudioOutput::waveOutProc" << DSP::e::LogMode::second
+      DSP::log << "DSP::WMM_object_t::waveOutProc" << DSP::e::LogMode::second
         << "WOM_OPEN(" << (int)dwInstance << ")" << endl;
       break;
     case WOM_CLOSE:
-      DSP::log << "DSP::u::AudioOutput::waveOutProc" << DSP::e::LogMode::second
+      DSP::log << "DSP::WMM_object_t::waveOutProc" << DSP::e::LogMode::second
         << "WOM_CLOSE(" << (int)dwInstance << ")" << endl;
       break;
     case WOM_DONE:
-      DSP::log << "DSP::u::AudioOutput::waveOutProc" << DSP::e::LogMode::second
+      DSP::log << "DSP::WMM_object_t::waveOutProc" << DSP::e::LogMode::second
         << "WOM_DONE(" << (int)dwInstance << ")" << endl;
 
-      if (Current->StopPlaying)
+      if (Current->StopPlayback)
       {
-        DSP::log << "DSP::u::AudioOutput::waveOutProc" << DSP::e::LogMode::second << "StopPlaying is set" << endl;
+        DSP::log << "DSP::WMM_object_t::waveOutProc" << DSP::e::LogMode::second << "StopPlayback is set" << endl;
         return;
       }
       else
@@ -66,7 +78,7 @@ void CALLBACK DSP::WMM_object_t::waveOutProc(HWAVEOUT hwo, UINT uMsg,
         for (ind=0; ind < DSP_NoOfAudioOutputBuffers; ind++)
           AllDone &= (Current->waveHeaderOut[ind].dwFlags & WHDR_DONE);
         if (AllDone)
-          DSP::log << "DSP::u::AudioOutput::waveOutProc" << DSP::e::LogMode::second << "All buffers had been used - nothing to play" << endl;
+          DSP::log << "DSP::WMM_object_t::waveOutProc" << DSP::e::LogMode::second << "All buffers had been used - nothing to play" << endl;
       }
       break;
   }
@@ -113,21 +125,138 @@ void DSP::WMM_object_t::log_driver_data() {
 
 //    Callback = (DWORD_PTR)(&DSP::u::AudioOutput::waveOutProc);
 
-bool DSP::WMM_object_t::select_device_by_number(const unsigned int &device_number) {
+unsigned int DSP::WMM_object_t::select_output_device_by_number(const unsigned int &device_number) {
   WaveOutDevNo = device_number;
 
   return WaveOutDevNo;
 }
 
+unsigned int DSP::WMM_object_t::select_input_device_by_number(const unsigned int &device_number) {
+  WaveInDevNo = device_number;
+
+  return WaveInDevNo;
+}
+
+bool DSP::WMM_object_t::stop_playback(void) {
+  StopPlayback = true;
+  //! \TODO can we do more ?
+
+  return true;
+}
+
+bool DSP::WMM_object_t::stop_recording(void) {
+  StopRecording = true;
+  //! \TODO can we do more ?
+
+  return true;
+}
+
 bool DSP::WMM_object_t::is_device_playing(void) {
   return IsPlayingNow;
 }
 
+bool DSP::WMM_object_t::is_device_recording(void) {
+  return IsRecordingNow;
+}
+
+long DSP::WMM_object_t::open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_inbuffer_size) {
+  if (is_device_input_open)
+  {
+    DSP::log << "DSP::WMM_object_t::open_PCM_device_4_input" << DSP::e::LogMode::second << "Device has been already opened: closing device before reopening" << endl;
+    close_PCM_device_input();
+  }
+
+  DWORD_PTR Callback;
+  switch (no_of_bits)
+  {
+    case 8:
+      InSampleType=DSP::e::SampleType::ST_uchar;
+      break;
+    case 16:
+      InSampleType=DSP::e::SampleType::ST_short;
+      break;
+    default:
+      InSampleType=DSP::e::SampleType::ST_short;
+      no_of_bits=16;
+      break;
+  }
+  Callback = (DWORD_PTR)(&DSP::WMM_object_t::waveInProc);
+
+  //Wypeniamy struktur wfx
+  wfx.wf.wFormatTag=WAVE_FORMAT_PCM;
+  wfx.wf.nChannels=(uint16_t)no_of_channels;
+  wfx.wf.nSamplesPerSec=(UINT)sampling_rate;
+  wfx.wBitsPerSample=(uint16_t)no_of_bits;
+  wfx.wf.nAvgBytesPerSec=wfx.wf.nSamplesPerSec*(wfx.wBitsPerSample/8);
+  wfx.wf.nBlockAlign=(uint16_t)(wfx.wf.nChannels*(wfx.wBitsPerSample/8));
+
+  if (waveInGetNumDevs() <= WaveInDevNo)
+    result=waveInOpen(&hWaveIn,
+      WAVE_MAPPER, //&DeviceID,
+      (WAVEFORMATEX *)(&wfx),
+      Callback,
+      get_current_CallbackInstance(), //CallbackInstance,
+      CALLBACK_FUNCTION | WAVE_FORMAT_DIRECT //| WAVE_MAPPED //CALLBACK_NULL
+      );
+  else
+    result=waveInOpen(&hWaveIn,
+      WaveInDevNo, //&DeviceID,
+      (WAVEFORMATEX *)(&wfx),
+      Callback,
+      get_current_CallbackInstance(), //CallbackInstance,
+      CALLBACK_FUNCTION | WAVE_FORMAT_DIRECT //| WAVE_MAPPED //CALLBACK_NULL
+      );
+
+  if (DSP::f::AudioCheckError(result) == false)
+  { // no errors
+    is_device_input_open = true;
+
+    waveHeaderIn.resize(2);
+    WaveInBufferLen=wfx.wf.nBlockAlign*audio_inbuffer_size;
+    WaveInBuffers.resize(2);
+    /*! \bug <b>2006.08.13</b> when 8bit audio stream is created initial values should be 0x80 or 0x79 not 0x00
+      */
+    WaveInBuffers[0].clear(); WaveInBuffers[0].resize(WaveInBufferLen, 0);
+    WaveInBuffers[1].clear(); WaveInBuffers[1].resize(WaveInBufferLen, 0);
+
+    waveHeaderIn[0].lpData=(char *)(WaveInBuffers[0].data());
+    waveHeaderIn[0].dwBufferLength=no_of_channels*audio_inbuffer_size*(no_of_bits/8); //sizeof(short);
+    waveHeaderIn[0].dwFlags= 0; // WHDR_BEGINLOOP | WHDR_ENDLOOP;
+    waveHeaderIn[0].dwLoops=0;
+
+    result=waveInPrepareHeader(hWaveIn,
+      &(waveHeaderIn[0]), sizeof(WAVEHDR));
+    DSP::f::AudioCheckError(result);
+  //  waveHeaderIn[0].dwFlags= WHDR_DONE; // WHDR_BEGINLOOP | WHDR_ENDLOOP;
+
+    waveHeaderIn[1].lpData=(char *)(WaveInBuffers[1].data());
+    waveHeaderIn[1].dwBufferLength=no_of_channels*audio_inbuffer_size*(no_of_bits/8); //sizeof(short);
+    waveHeaderIn[1].dwFlags= 0; // WHDR_BEGINLOOP | WHDR_ENDLOOP;
+    waveHeaderIn[1].dwLoops=0;
+
+    result=waveInPrepareHeader(hWaveIn,
+      &(waveHeaderIn[1]), sizeof(WAVEHDR));
+    DSP::f::AudioCheckError(result);
+    //  waveHeaderIn[1].dwFlags= WHDR_DONE; // WHDR_BEGINLOOP | WHDR_ENDLOOP;
+
+    IsRecordingNow = false;
+    NextBufferInInd = 0;
+
+    return 1; //! \TODO check this also foroutput
+  }
+
+  // error creating audio object
+  waveHeaderIn.clear(); WaveInBufferLen=0;
+  WaveInBuffers.clear();
+
+  return -1;
+}
+
 long DSP::WMM_object_t::open_PCM_device_4_output(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size) {
-  if (is_device_openned)
+  if (is_device_output_open)
   {
     DSP::log << "DSP::WMM_object_t::open_PCM_device_4_output" << DSP::e::LogMode::second << "Device has been already opened: closing device before reopening" << endl;
-    close_PCM_device();
+    close_PCM_device_output();
   }
 
   switch (no_of_bits)
@@ -173,6 +302,8 @@ long DSP::WMM_object_t::open_PCM_device_4_output(const int &no_of_channels, int
 
   if (DSP::f::AudioCheckError(result) == false)
   { // everything  is ok
+    is_device_output_open = true;
+
     waveHeaderOut.resize(DSP::NoOfAudioOutputBuffers);
     WaveOutBufferLen=wfx.wf.nBlockAlign*audio_outbuffer_size;
     WaveOutBuffers.resize(DSP::NoOfAudioOutputBuffers);
@@ -206,12 +337,47 @@ long DSP::WMM_object_t::open_PCM_device_4_output(const int &no_of_channels, int
   return sampling_rate;
 }
 
-long DSP::WMM_object_t::open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size) {
-  return -1;
-}
+bool DSP::WMM_object_t::close_PCM_device_input(void) {
+  result = waveInReset(hWaveIn);
+  DSP::f::AudioCheckError(result);
+  result=waveInUnprepareHeader(hWaveIn,
+    &(waveHeaderIn[0]), sizeof(WAVEHDR));
+  DSP::f::AudioCheckError(result);
+  result=waveInUnprepareHeader(hWaveIn,
+    &(waveHeaderIn[1]), sizeof(WAVEHDR));
+  DSP::f::AudioCheckError(result);
+
+  #ifdef AUDIO_DEBUG_MESSAGES_ON
+    DSP::log << "DSP::u::AudioInput" << DSP::e::LogMode::second << "Closing DSP::u::AudioInput" << endl;
+  #endif
+  result=waveInClose(hWaveIn);
+  while (result==WAVERR_STILLPLAYING)
+  {
+  //    #ifdef WINBASEAPI
+    DSP::f::Sleep(100);
+  //    #else
+  //      sleep(100);
+  //    #endif
+    #ifdef AUDIO_DEBUG_MESSAGES_ON
+      DSP::log << "DSP::u::AudioInput" << DSP::e::LogMode::second << "Closing DSP::u::AudioInput" << endl;
+    #endif
+    result=waveInClose(hWaveIn);
+  }
+  DSP::f::AudioCheckError(result);
 
+  is_device_input_open = false;
 
-bool DSP::WMM_object_t::close_PCM_device(void) {
+  // 2) Free buffers
+  WaveInBuffers[0].clear();
+  WaveInBuffers[1].clear();
+  WaveInBuffers.clear();
+
+  waveHeaderIn.clear();
+
+  return true;
+}
+
+bool DSP::WMM_object_t::close_PCM_device_output(void) {
   result = waveOutReset(hWaveOut);
   DSP::f::AudioCheckError(result);
   
@@ -236,6 +402,8 @@ bool DSP::WMM_object_t::close_PCM_device(void) {
   }  
   DSP::f::AudioCheckError(result);
 
+  is_device_output_open = false;
+
   // 2) Free buffers
   WaveOutBuffers.clear();
   #ifdef WINMMAPI
@@ -246,9 +414,47 @@ bool DSP::WMM_object_t::close_PCM_device(void) {
     DSP::log << "WMM PCM sound closed" << endl;
   #endif
 
+  is_device_input_open = false;
+  NextBufferOutInd=0;
+  StopPlayback = false;
+  IsPlayingNow = false;
+
   return true; // device has been closed
 }
 
+bool DSP::WMM_object_t::start_recording(void) {
+  #ifdef AUDIO_DEBUG_MESSAGES_ON
+    DSP::log << "DSP::u::AudioInput::Execute" << DSP::e::LogMode::second << "Starting recording using two wave buffers" << endl;
+  #endif
+
+  if (get_input_callback_object() == NULL) {
+    DSP::log << DSP::e::LogMode::Error << "DSP::WMM_object_t::start_recording" << DSP::e::LogMode::second << "No AudioInput object registered for callbacks" << endl;
+    return false;
+  }
+
+  result=waveInAddBuffer(hWaveIn, &(waveHeaderIn[0]), sizeof(WAVEHDR));
+  DSP::f::AudioCheckError(result);
+  result=waveInAddBuffer(hWaveIn, &(waveHeaderIn[1]), sizeof(WAVEHDR));
+  DSP::f::AudioCheckError(result);
+  NextBufferInInd = 0;
+
+  result=waveInStart(hWaveIn);
+  DSP::f::AudioCheckError(result);
+  IsRecordingNow = true;
+  //now just wait for buffer to fill up
+  // which should call waveInProc
+
+  return true;
+}
+
+bool DSP::WMM_object_t::is_input_callback_supported(void) {
+  return true;
+}
+
+bool DSP::WMM_object_t::is_output_callback_supported(void) {
+  return false;
+}
+
 
 long DSP::WMM_object_t::append_playback_buffer(DSP::Float_vector &float_buffer) {
   uint8_t *temp8;
@@ -265,10 +471,10 @@ long DSP::WMM_object_t::append_playback_buffer(DSP::Float_vector &float_buffer)
 
   while (1)
   {
-    if (waveHeaderOut[NextBufferInd].dwFlags & WHDR_DONE)
+    if (waveHeaderOut[NextBufferOutInd].dwFlags & WHDR_DONE)
     {
       result=waveOutUnprepareHeader(hWaveOut,
-        &(waveHeaderOut[NextBufferInd]), sizeof(WAVEHDR));
+        &(waveHeaderOut[NextBufferOutInd]), sizeof(WAVEHDR));
       DSP::f::AudioCheckError(result);
 
       DSP::Float_ptr Sample=float_buffer.data();
@@ -277,7 +483,7 @@ long DSP::WMM_object_t::append_playback_buffer(DSP::Float_vector &float_buffer)
       switch (OutSampleType)
       {
         case DSP::e::SampleType::ST_uchar:
-          temp8=(uint8_t *)(WaveOutBuffers[NextBufferInd].data());
+          temp8=(uint8_t *)(WaveOutBuffers[NextBufferOutInd].data());
           for (ind=0; ind<float_buffer.size(); ind++)
           {
             if (*Sample < 0)
@@ -296,7 +502,7 @@ long DSP::WMM_object_t::append_playback_buffer(DSP::Float_vector &float_buffer)
           }
           break;
         case DSP::e::SampleType::ST_short:
-          temp16=(short *)(WaveOutBuffers[NextBufferInd].data());
+          temp16=(short *)(WaveOutBuffers[NextBufferOutInd].data());
           for (ind=0; ind<float_buffer.size(); ind++)
           {
             if (*Sample < 0)
@@ -318,12 +524,12 @@ long DSP::WMM_object_t::append_playback_buffer(DSP::Float_vector &float_buffer)
       }
 
       result=waveOutPrepareHeader(hWaveOut,
-        &(waveHeaderOut[NextBufferInd]), sizeof(WAVEHDR));
+        &(waveHeaderOut[NextBufferOutInd]), sizeof(WAVEHDR));
       DSP::f::AudioCheckError(result);
 
       if (IsPlayingNow == false)
       {
-        if (NextBufferInd == 1)
+        if (NextBufferOutInd == 1)
         {
           for (ind=0; ind < DSP::NoOfAudioOutputBuffers-1; ind++) //one spare buffer
           {
@@ -338,11 +544,11 @@ long DSP::WMM_object_t::append_playback_buffer(DSP::Float_vector &float_buffer)
       else
       {
         result=waveOutWrite(hWaveOut,
-          &(waveHeaderOut[NextBufferInd]), sizeof(WAVEHDR));
+          &(waveHeaderOut[NextBufferOutInd]), sizeof(WAVEHDR));
         DSP::f::AudioCheckError(result);
       }
-      NextBufferInd++;
-      NextBufferInd %= DSP::NoOfAudioOutputBuffers;
+      NextBufferOutInd++;
+      NextBufferOutInd %= DSP::NoOfAudioOutputBuffers;
 
       break;
     }
@@ -357,4 +563,93 @@ long DSP::WMM_object_t::append_playback_buffer(DSP::Float_vector &float_buffer)
   }
 
   return long(float_buffer.size());
-}
\ No newline at end of file
+}
+
+
+//! \bug allow user to select number of internal buffers
+void CALLBACK DSP::WMM_object_t::waveInProc(HWAVEIN hwi, UINT uMsg,
+  uint32_t dwInstance, uint32_t dwParam1, uint32_t dwParam2)
+{
+  UNUSED_ARGUMENT(hwi);
+  UNUSED_ARGUMENT(dwParam1);
+  UNUSED_ARGUMENT(dwParam2);
+
+  MMRESULT result;
+//  DSP::u::AudioInput *Current;
+  DSP::WMM_object_t *Current;
+#ifdef __DEBUG__
+  #ifdef AUDIO_DEBUG_MESSAGES_ON
+    stringstream tekst;
+  #endif
+#endif
+
+//  Current = CallbackObjects[dwInstance]->AudioInput_object;
+  Current = (DSP::WMM_object_t *)(DSP::SOUND_object_t::get_CallbackSoundObject(dwInstance));
+  assert(Current);
+
+  switch (uMsg)
+  {
+#ifdef __DEBUG__
+#ifdef AUDIO_DEBUG_MESSAGES_ON
+    case WIM_OPEN:
+      DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
+        << "WIM_OPEN(" << (int)dwInstance << ")" << endl;
+      break;
+    case WIM_CLOSE:
+      DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
+        << "WIM_CLOSE(" << (int)dwInstance << ")" << endl;
+      break;
+#endif
+#endif
+
+    case WIM_DATA:
+#ifdef __DEBUG__
+#ifdef AUDIO_DEBUG_MESSAGES_ON
+      DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second
+        << "WIM_DATA(" << (int)dwInstance << ")" << endl;
+#endif
+#endif
+      if (Current->StopRecording)
+        return;
+      else
+      {
+        if (Current->waveHeaderIn[Current->NextBufferInInd].dwFlags & WHDR_DONE)
+        {
+          result=waveInUnprepareHeader(Current->hWaveIn,
+            &(Current->waveHeaderIn[Current->NextBufferInInd]), sizeof(WAVEHDR));
+          DSP::f::AudioCheckError(result);
+        
+          if (Current->input_callback_call(Current->InSampleType, Current->WaveInBuffers[Current->NextBufferInInd]) == false)
+          //if (Current->EmptyBufferIndex == Current->CurrentBufferIndex)
+          {
+            // ignore data
+#ifdef __DEBUG__
+#ifdef AUDIO_DEBUG_MESSAGES_ON
+            DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second << "All buffers had been used - skipping input audio frame" << endl;
+#endif
+#endif
+          }
+
+          //add put back into recording queue
+          result=waveInPrepareHeader(Current->hWaveIn,
+            &(Current->waveHeaderIn[Current->NextBufferInInd]), sizeof(WAVEHDR));
+          DSP::f::AudioCheckError(result);
+          result=waveInAddBuffer(Current->hWaveIn,
+            &(Current->waveHeaderIn[Current->NextBufferInInd]), sizeof(WAVEHDR));
+          DSP::f::AudioCheckError(result);
+
+          Current->NextBufferInInd++; Current->NextBufferInInd %= 2; //just two buffers
+        }
+        else
+        {
+#ifdef __DEBUG__
+#ifdef AUDIO_DEBUG_MESSAGES_ON
+            DSP::log << "DSP::u::AudioInput::waveInProc" << DSP::e::LogMode::second << "Wrong audio frame ready or other unexpected error" << endl;
+#endif
+#endif
+        }
+      }
+      break; // WIM_DATA
+  }
+}
+
diff --git a/src/include/DSP_IO.h b/src/include/DSP_IO.h
index 76cb695a23034dd8da0476a1e82c740607f016f6..faf93e23f0ae6fa898cdf53729cc9efdf786ac11 100644
--- a/src/include/DSP_IO.h
+++ b/src/include/DSP_IO.h
@@ -717,19 +717,23 @@ class DSP::u::AudioInput : public DSP::Source
   private:
     DSP::T_WAVEchunk WAVEchunk;
     #ifdef WINMMAPI
-      HWAVEIN hWaveIn;
+      // HWAVEIN hWaveIn;
+      DSP::WMM_object_t snd_object;
     #endif
 
-    //! Index of the buffer which is expected to filled next
-    short NextBufferInd;
-    //! Type of samples in WaveInBuffers
-    DSP::e::SampleType InSampleType;
-    #ifdef WINMMAPI
-      std::vector<WAVEHDR> waveHeaderIn;
-    #endif
-    uint32_t WaveInBufferLen;  // in bytes
-    //! Buffers for audio samples prepared for playing
-    std::vector<std::vector<char>> WaveInBuffers;
+    //! Called by SOUND_object_t when new data buffer is ready
+    bool SOUND_object_callback(const DSP::e::SampleType &InSampleType, const std::vector<char> &wave_in_raw_buffer);
+
+    // //! Index of the buffer which is expected to filled next
+    // short NextBufferInd;
+    // //! Type of samples in WaveInBuffers
+    // DSP::e::SampleType InSampleType;
+    // #ifdef WINMMAPI
+    //   std::vector<WAVEHDR> waveHeaderIn;
+    // #endif
+    // uint32_t WaveInBufferLen;  // in bytes
+    // //! Buffers for audio samples prepared for playing
+    // std::vector<std::vector<char>> WaveInBuffers;
 
     //! size of the buffers used internally with WMM driver
     uint32_t audio_inbuffer_size;
@@ -764,28 +768,28 @@ class DSP::u::AudioInput : public DSP::Source
               char BitPrec=16,
               unsigned int WaveInDevNo=UINT_MAX); // use WAVE_MAPPER
 
-    // indicates whether the recording started yet
-    bool IsRecordingNow;
+    // // indicates whether the recording started yet
+    // bool IsRecordingNow;
 
-    bool StartAudio(void);
-    bool StopAudio(void);
-    bool StopRecording;
+    // bool StartAudio(void);
+    // bool StopAudio(void);
+    // bool StopRecording;
     //! (returns number of samples read per channel)
     uint32_t GetAudioSegment(void);
 
-    static unsigned long Next_CallbackInstance;
-    unsigned long Current_CallbackInstance;
-    //! Addresses of audio object connected with CallbackInstances;
-    /*! Current callback instanse is also the index to this array
-     */
-    static std::vector<DSP::u::AudioInput *> AudioObjects;
+    // static unsigned long Next_CallbackInstance;
+    // unsigned long Current_CallbackInstance;
+    // //! Addresses of audio object connected with CallbackInstances;
+    // /*! Current callback instance is also the index to this array
+    //  */
+    // static std::vector<DSP::u::AudioInput *> AudioObjects;
 
-    #ifdef WINMMAPI
-      static void CALLBACK waveInProc_uchar(HWAVEIN hwi, UINT uMsg,
-        uint32_t dwInstance, uint32_t dwParam1, uint32_t dwParam2);
-      static void CALLBACK waveInProc_short(HWAVEIN hwi, UINT uMsg,
-        uint32_t dwInstance, uint32_t dwParam1, uint32_t dwParam2);
-    #endif
+    // #ifdef WINMMAPI
+    //   static void CALLBACK waveInProc_uchar(HWAVEIN hwi, UINT uMsg,
+    //     uint32_t dwInstance, uint32_t dwParam1, uint32_t dwParam2);
+    //   static void CALLBACK waveInProc_short(HWAVEIN hwi, UINT uMsg,
+    //     uint32_t dwInstance, uint32_t dwParam1, uint32_t dwParam2);
+    // #endif
 
     static bool OutputExecute(OUTPUT_EXECUTE_ARGS);
 
@@ -863,16 +867,16 @@ class DSP::u::AudioOutput : public DSP::Block
 
     //bool IsPlayingNow;
 
-    bool StartAudio(void);
-    bool StopAudio(void);
-    bool StopPlaying;
+    // bool StartAudio(void);
+    // bool StopAudio(void);
+    // bool StopPlaying;
 
-    static unsigned long Next_CallbackInstance;
-    unsigned long Current_CallbackInstance;
-    //! Addresses of audio object connected with CallbackInstances;
-    /*! Current callback instanse is also the index to this array
-     */
-    static std::vector<DSP::u::AudioOutput *> AudioObjects;
+    // static unsigned long Next_CallbackInstance;
+    // unsigned long Current_CallbackInstance;
+    // //! Addresses of audio object connected with CallbackInstances;
+    // /*! Current callback instanse is also the index to this array
+    // */
+    //static std::vector<DSP::u::AudioOutput *> AudioObjects;
 
     //! (returns number of samples read per channel)
     uint32_t GetAudioSegment(void);
diff --git a/src/include/DSP_lib.h b/src/include/DSP_lib.h
index d89b1f4e1ca42b3fc9c7f767cca699242e4cf1bc..5b12ff075154758f898a4e8fcf477d9eb941b4b4 100644
--- a/src/include/DSP_lib.h
+++ b/src/include/DSP_lib.h
@@ -11,7 +11,7 @@
 
 #define DSP_VER_MAJOR 0
 #define DSP_VER_MINOR 20
-#define DSP_VER_BUILD 5 // !!! without zeroes before, else this will be treated as octal number
+#define DSP_VER_BUILD 6 // !!! without zeroes before, else this will be treated as octal number
 #define DSP_VER_YEAR  2021
 #define DSP_VER       DSP_VER_MAJOR.DSP_VER_MINOR.DSP_VER_BUILD
 
diff --git a/src/include/DSP_types.h b/src/include/DSP_types.h
index c6b5e3d859e9efccf2c2f50bf2ba3d04868da90f..76880e79d3ac8b2929e54c6cf604f099b6cb934d 100644
--- a/src/include/DSP_types.h
+++ b/src/include/DSP_types.h
@@ -529,28 +529,79 @@ namespace DSP {
 
 
 namespace DSP {
+  namespace u {
+    class AudioInput;
+    class AudioOutput;
+  }
+
     //! Base class for classes implementing sound card support for DSP::u::AudioInput and DSP::u::AudioOutput 
     /*! \TODO  convert WMM support in DSP::u::AudioInput and DSP::u::AudioOutput into support through WMM_object_t
      */
-    class SOUND_object_t {
+  class SOUND_object_t {
+    private:
+      DSP::u::AudioInput * AudioInput_object;
+      bool (DSP::u::AudioInput::*AudioInput_callback)(const DSP::e::SampleType &InSampleType, const std::vector<char> &wave_in_raw_buffer);
+      DSP::u::AudioOutput * AudioOutput_object;
+      bool (DSP::u::AudioOutput::*AudioOutput_callback)(void);
+
+      //static unsigned long Next_CallbackInstance;
+      unsigned long Current_CallbackInstance;
+      static std::vector<DSP::SOUND_object_t *> CallbackSoundObjects;
+      static unsigned long get_free_CallbackInstance(void);
 
     public:
       virtual void log_driver_data() = 0;
 
-      virtual bool select_device_by_number(const unsigned int &device_number=UINT_MAX) = 0;
+      virtual unsigned int select_input_device_by_number(const unsigned int &device_number=UINT_MAX) = 0;
+      virtual unsigned int select_output_device_by_number(const unsigned int &device_number=UINT_MAX) = 0;
 
       virtual long open_PCM_device_4_output(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size) = 0;
       virtual long open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size) = 0;
-      virtual bool close_PCM_device(void) = 0;
+      virtual bool close_PCM_device_input(void) = 0;
+      virtual bool close_PCM_device_output(void) = 0;
 
       //! returns true is the playback is on
       virtual bool is_device_playing(void) = 0;
+      //! initializes playback stopping
+      virtual bool stop_playback(void) = 0;
+      //! returns true is the sound capture is on
+      virtual bool is_device_recording(void) = 0;
+      //! returns true is the sound capture is on
+      virtual bool stop_recording(void) = 0;
 
       //! \note values stored in float_buffer might be altered
-      long append_playback_buffer(DSP::Float_vector &float_buffer);
-
-      virtual ~SOUND_object_t() {};
-    };
+      virtual long append_playback_buffer(DSP::Float_vector &float_buffer)=0;
+      //! Starts sound capture
+      virtual bool start_recording(void) = 0;
+
+
+      long int get_current_CallbackInstance();
+      static const DSP::SOUND_object_t * get_CallbackSoundObject(const long int &instance_number);
+
+      // https://stackoverflow.com/questions/8865766/get-a-pointer-to-objects-member-function
+      /*! Returns false if callbacks are not supported of recording
+       */
+      virtual bool is_input_callback_supported(void) = 0;
+      /*! Returns false if callbacks are not supported
+       * \TODO define when it will be called and what for?
+       */
+      bool register_input_callback_object(DSP::u::AudioInput *callback_object, bool(DSP::u::AudioInput::*cp)(const DSP::e::SampleType &, const std::vector<char> &));
+      DSP::u::AudioInput *get_input_callback_object();
+      bool input_callback_call(const DSP::e::SampleType &InSampleType, const std::vector<char> &wave_in_raw_buffer);
+
+      /*! Returns false if callbacks are not supported of playback
+       */
+      virtual bool is_output_callback_supported(void) = 0;
+      /*! Returns false if callbacks are not supported
+       * \TODO define when it will be called and what for?
+       */
+      bool register_output_callback_object(DSP::u::AudioOutput *callback_object, bool(DSP::u::AudioOutput::*cp)());
+      DSP::u::AudioOutput *get_output_callback_object();
+      bool output_callback_call();
+
+      SOUND_object_t();
+      virtual ~SOUND_object_t();
+  };
 }
 
 
diff --git a/src/include/WMM_support.h b/src/include/WMM_support.h
index 5706e99e88c2c54ebeaef4e4d21d3bce2bab37d0..c16f8c0bc331f390daba0057dbd8c441c114ce19 100644
--- a/src/include/WMM_support.h
+++ b/src/include/WMM_support.h
@@ -22,12 +22,13 @@
 namespace DSP {
     class WMM_object_t : public DSP::SOUND_object_t {
     private:
-      bool is_device_openned;
+      bool is_device_input_open;
+      bool is_device_output_open;
 
+      HWAVEIN  hWaveIn;
       HWAVEOUT hWaveOut;
 
       MMRESULT result;
-      DWORD_PTR Callback;
 
       //Rezerwacja pamięci dla formatu WAVE
       //  WAVEFORMATEX wfx; //to wymaga korekty
@@ -42,36 +43,64 @@ namespace DSP {
       //! Type of samples in WaveOutBuffers
       DSP::e::SampleType OutSampleType;
       //! Index of the buffer which must be used next time
-      unsigned long NextBufferInd;
-      
+      unsigned long NextBufferOutInd;
+         
+      bool StopPlayback;
       bool IsPlayingNow;
 
       static void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg,
         uint32_t dwInstance, uint32_t dwParam1, uint32_t dwParam2);
 
 
+      unsigned int WaveInDevNo; // device numer used in next open operations
+
+      //! Index of the buffer which is expected to filled next
+      short NextBufferInInd;
+      //! Type of samples in WaveInBuffers
+      DSP::e::SampleType InSampleType;
+      std::vector<WAVEHDR> waveHeaderIn;
+      uint32_t WaveInBufferLen;  // in bytes
+      //! Buffers for audio samples prepared for playing
+      std::vector<std::vector<char>> WaveInBuffers;
+
+      static void CALLBACK waveInProc(HWAVEIN hwi, UINT uMsg, uint32_t dwInstance, uint32_t dwParam1, uint32_t dwParam2);
+
+      bool StopRecording;
+      // indicates whether the recording started yet
+      bool IsRecordingNow;
+
     public:
 
         //! log basic WMM information
         void log_driver_data();
 
         // returns false if device is already opened
-        bool select_device_by_number(const unsigned int &device_number=UINT_MAX);
+        unsigned int select_input_device_by_number(const unsigned int &device_number=UINT_MAX);
+        unsigned int select_output_device_by_number(const unsigned int &device_number=UINT_MAX);
 
         //! opens default PCM device for playback and returns selected sampling rate on success or negative error code
         long open_PCM_device_4_output(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size);
         //! opens default PCM device for capture and returns selected sampling rate on success or negative error code
-        long open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_outbuffer_size);
+        long open_PCM_device_4_input(const int &no_of_channels, int no_of_bits, const long &sampling_rate, const long &audio_inbuffer_size);
 
-        bool close_PCM_device(void);
+        bool close_PCM_device_input(void);
+        bool close_PCM_device_output(void);
 
+        bool stop_playback(void);
+        bool stop_recording(void);
         //! returns true is the playback is on
         bool is_device_playing(void);
+        //! returns true is the playback is on
+        bool is_device_recording(void);
+
+        bool is_input_callback_supported(void);
+        bool is_output_callback_supported(void);
 
         //void get_params(snd_pcm_uframes_t &frames, unsigned int &period_time);
         //snd_pcm_sframes_t pcm_writei(const void *buffer, snd_pcm_uframes_t &frames);
         //! \note values stored in float_buffer might be altered
         long append_playback_buffer(DSP::Float_vector &float_buffer);
+        bool start_recording(void);
 
         //! object constructor \TODO check use of virtual in constructor and destructor
         WMM_object_t();